feat: add snap to polylines#3342
Open
int-72h wants to merge 3 commits into
Open
Conversation
Add snap-to-point support on the frontend using Leaflet.Snap (makinacorpus). uMap uses Leaflet.Editable rather than Leaflet.Draw, so the library's Draw hooks are unused; instead a MarkerSnap handler is attached to the markers Editable exposes (dragged vertices, dragged point features, and markers being placed). - Vendor leaflet-geometryutil + leaflet-snap into vendors/snap/ and load them as classic scripts after Leaflet.Editable. - New `snapDistance` setting (default 15px, 0 disables), overridable per map and via the `?snapDistance=` querystring. - Construct MarkerSnap without the marker arg to avoid the removed L.Handler.MarkerDrag, and re-apply the snapped latlng on commit since Editable overwrites a placed marker with the raw click position. - Exclude the edited feature from guide layers (Leaflet.Snap's own self-exclusion relies on Leaflet.Draw internals Editable lacks). - Fix asNumber() in setPropertiesFromQueryString: it wrote to an undefined `name` and had no presence guard, so Number querystring overrides never applied. - Add integration tests covering snapping and the disabled case. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The initial snapping only attached MarkerSnap to markers/vertices the user drags, so drawing a new line or polygon never snapped — the main behaviour people expect (à la Google My Maps) was missing, making it feel weak and intermittent. Snap the raw map pointer events instead: registered at editor setup, the handler runs before Leaflet.Editable's own mousemove/mouseup listeners and, since Leaflet shares one event object across a fire, rewriting `latlng` makes both the live rubber-band and the committed vertex/marker snap onto existing features. Marker placement now goes through this path too (dropping the previous commit-time reapply hack); MarkerSnap is kept only for dragging existing geometry, where the position comes from the icon rather than the event. Guide layers are cached per drawing session. Paths currently being edited are excluded: Leaflet.Editable stamps a circular `__vertex` back-reference on their latlngs and the snap library's closest() JSON-serializes the geometry, which would otherwise throw. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The placed coordinate already snaps for every drawn vertex, but only points after the first get visual feedback: the rubber-band line bends onto the target as you hover. The first vertex has no rubber-band, so within the snap radius it snapped silently with no cue — making it feel like the starting point doesn't snap at all. Draw a small circle at the snapped position whenever the pointer is within snapDistance of a feature during drawing (mousemove included), so the first vertex gets the same feedback as the rest, à la Google My Maps. The indicator is hidden when the pointer leaves snap range and when drawing ends. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Author
|
It all seems to be reasonably sane; though one may want to trim back the comments? |
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.
This PR adds snap functionality when drawing and editing maps. It closes #2159.
I've used Claude to write most of it, as a result I'm marking the PR as a draft until I'm confident it hasn't pumped out complete slop. I'll let it explain what it's done:
Snap to existing features while editing
Adds snap-to-feature when drawing and editing maps (à la Google My Maps), using the
makinacorpus/Leaflet.Snaplibrary adapted to uMap's Leaflet.Editable stack.Behaviour
MarkerSnap.snapDistancesetting (default 15px,0disables; per-map and?snapDistance=override).Changes
leaflet-snap+leaflet-geometryutil(package.json,vendorsjs.sh,js.html).umap.controls.js;snapDistanceinschema.js/help.js.setPropertiesFromQueryStringasNumberwrote to an undefined var and lacked a presence guard.test_snap.py.Notes
0for opt-in.🤖 Generated with Claude Code