Geographic Information Systems Asked by Andre M on March 18, 2021
Is there a way to constrain a marker so that when it is dragged, it moves along a given polyline in Leaflet JS?
In my page I have route that is presented as a Polyline and a Marker. I want to be able to drag the marker along the line to be able to display information about that part of the route.
Looking at the documentation here, it is not clear how I would go about that:
https://leafletjs.com/reference-1.6.0.html#marker
Note, I am using leaflet by means of vue2leaflet, though a solution that works for standard leaflet JS would be okay.
The vue ‘template’:
<l-map
class="leaftlet-map"
:zoom="map.zoom"
:center="map.center"
@update:zoom="zoomUpdated"
@update:center="centerUpdated"
@update:bounds="boundsUpdated"
>
<l-tile-layer :url="map.url" :attribution="map.attribution" />
<l-marker
v-if="positionMarker"
:lat-lng="positionMarker.center"
draggable
@move="markerMoved"
/>
<l-polyline
v-if="polyline.latlngs && polyline.latlngs.length > 0"
:lat-lngs="polyline.latlngs"
:color="polyline.color"
/>
</l-map>
This is a quick hack just to test the concept. Since img
element is draggable by itself, L.divIcon
is used for draggable marker so that draggable="false"
attribute could be set. For keeping marker glued to polyline, polyline method closestLayerPoint
is used to locate closest point to mouse position on polyline.
CSS:
html, body {
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
.leaflet-div-icon {
border: none;
background-color: transparent;
}
HTML:
<div id="map"></div>
<div style="display:none;">
<img id="icon" draggable="false" src="lib/leaflet/1.6/images/marker-icon.png">
</div>
JS:
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors',
});
var map = L.map('map').addLayer(osm);
var path = L.polyline([[43, 1],[43, 1.5],[43.5, 2],[44, 3],[43.5, 4]], {
color: 'red',
opacity: 1.0
}).addTo(map);
map.fitBounds(path.getBounds());
var myIcon = L.divIcon({
html: document.getElementById('icon'),
iconSize: [25, 41],
iconAnchor: [12.5, 41],
});
var myMarker = L.marker([43, 1], {icon: myIcon}).addTo(map);
myMarker.on({
mousedown: function () {
map.on('mousemove', function (e) {
map.dragging.disable();
var point = path.closestLayerPoint(map.latLngToLayerPoint(e.latlng))
myMarker.setLatLng(map.layerPointToLatLng(point));
});
}
});
map.on('mouseup',function(e){
map.removeEventListener('mousemove');
map.dragging.enable();
});
Answered by TomazicM on March 18, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP