Feat/mapcontrol plugin#115
Open
BhattaraiSijan wants to merge 23 commits into
Open
Conversation
…-IMPACT/MMGIS into feat/mapcontrol-plugin
Standalone React component + pure helpers + themeable SCSS, mounted by a bus-only wrapper. Adds per-feature configure toggles.
slesaad
reviewed
Jun 8, 2026
Member
There was a problem hiding this comment.
can you use the skill i shared to make this component align with the reusable components pattern?
Collaborator
Author
There was a problem hiding this comment.
Refractored to monorepo pattern in this
slesaad
reviewed
Jun 9, 2026
Member
There was a problem hiding this comment.
some of the files in this folder can be shared between tools, see current development branch for pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds MapControl, a floating toolbar over the map with four features. Each can be
enabled/disabled per-mission from the Configure page.
The plugin is bus-only: the React component is MMGIS-independent and a thin wrapper
translates its callbacks into
mmgisAPIcalls. Map operations that didn't exist yet areadded in core (
Map_.js) and exposed over the event bus so any future plugin can reuse them.Geocode search
On each keystroke we hit the Nominatim API with the URL-encoded query — debounced 300ms,
only firing for queries ≥2 chars,
limit=5. No API key or backend (public endpoint). Onselecting a result we reorder Nominatim's bbox (
[min_lat,max_lat,min_lon,max_lon]) intoLeaflet order (
[[S,W],[N,E]]), fly to it viamap:fitBounds, and drop a pin viamap:createLayer.Basemap switching
Styles come from
msv.basemap.styles[]in the mission config (configurable per mission);if none are defined we fall back to provider defaults, which differ by engine (Leaflet →
raster XYZ tiles, deck.gl → vector style JSON). The active style is matched against
msv.basemap.style. On select we callmap:setBasemap, which calls the engine'ssetBasemapStyle()— deck.gl swaps the vector style in place; Leaflet rebuilds the tilelayer (handling
mapbox://, raw{z}/{x}/{y}templates, and an OSM fallback).Measure
We subscribe to
map:click/map:mousemove, collect two points, and draw the line +endpoints as a vector layer via
map:createLayer. Distance is computed with Turf; thelabel is positioned by projecting the segment midpoint via
map:latLngToContainerPoint.Zoom
map:zoomIn/map:zoomOut, clamped to the engine's min/max zoom.Core changes (beyond the plugin)
New
map:*handlers inMap_.js, also exposed as documented methods onmmgisAPI:setBasemap/getBasemap/getBasemapStyles,zoomIn/zoomOut,latLngToContainerPoint, and themap:click/map:mousemoveevent streams.Two supporting changes were required:
LeafletAdaptergained runtime basemap tile rendering (it hadnone before);
DeckGLAdaptergainedsetStyleand normalized{lat,lng}pointer-eventemission.
new missions get a default
view.Dependency on #90 (imapengine-drawing)
Vector overlays (the measure line and the search pin) are drawn via
map:createLayer/map:removeLayer, which are provided by #90. We deliberately do not define our ownoverlay channels — an earlier version added
map:addOverlay/map:removeOverlay, whichcollided by name with #90's (their
addOverlayis a different operation: an HTML elementanchored at a point). Using
map:createLayeris the operation we actually need and removesthe duplication. Until #90 merges these two features no-op (guarded, no crash); the rest of
the plugin is self-contained.
Known limitation / future work
MapControl is a floating overlay, not a docked panel, so it bypasses the normal panel-mount
path: it self-mounts at bundle load by polling for the map container and rendering into a
position:fixedlayer ondocument.body. This works but should be replaced by a proper"floating tool" mount path in the Modern layout so overlays don't have to self-mount.
Testing
Manual only:
handlers) and switching restyles the map on both engines.