Leaflet Draw and Leaflet Snap with geojson polygon layers - leaflet

I'm trying to enable snapping (using Leaflet Snap)in a Leaflet application I'm creating. I'm using Leaflet Draw. Existing layers are read in from a database in geojson. I add these to the guideLayers and I add newly created features there too. It's not working. Has anyone successfully been able to create something like this? That is, been able to create a new polygon and snap to existing polygons in leaflet (geojson layers)? Thanks Dan.
Add geojson to guideLayers code:
function renderLta(_ltas,ltaLayerName) {
L.geoJSON([_ltas.geoJson], {
name:_ltas.id,
areaName:_ltas.localThreatAreaName,
areaDescription:_ltas.localThreatAreaDescription,
style: function (feature) {
return _getLtaStyle(1);
},
onEachFeature: function onEachFeature(feature, layer) {
ltaLayerName.addLayer(layer);
guideLayers.push(layer);
layer.on('click', function(e) {
if(selectedFeature) {
selectedFeature.editing.disable();
// Has there been a change? Does the user need to save?
// get layer again and redraw
drawnItems.removeLayer(selectedFeature);
selectedFeature.addTo(map_lta);
}
selectedFeature = e.target;
e.target.editing.enable();
drawnItems.addLayer(e.target);
});
}
});
ltaLayerName.addTo(map);
Add new layer/data to guideLayers code:
map.on(L.Draw.Event.CREATED, function(event) {
var layer = event.layer;
var content = getPopupContent(layer);
if (content !== null) {
layer.bindPopup(content);
}
drawnItems.addLayer(layer);
guideLayers.push(layer);
});
DrawControl Code:
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems,
poly : {
allowIntersection : false
}
},
draw: {
polyline: false,
polygon : { showArea: true, allowIntersection : false, guideLayers: guideLayers, snapDistance: 500 },
circle: false,
rectangle: false,
marker: false,
circlemarker: false
}
});
map_lta.addControl(drawControl);
drawControl.setDrawingOptions({
polygon: { guideLayers: guideLayers, snapDistance: 50 },
});

You can use the following library to draw and snap https://www.npmjs.com/package/#geoman-io/leaflet-geoman-free packages
and for more functionalities which are not present in above mentioned package you can use this one especially for polylines
https://www.npmjs.com/package/leaflet-linestring-editor

I gave up on the leaflet draw library and snap, and used leaflet-geoman library instead. Snapping working perfectly.

Related

Get all polygon or layer details after polygon draw in leaflet draw

I am trying to get the layer details of the map which are already overlay on the map. When leaflet draw is created I want to get the layer details (Not the polygon coordinates created by leaflet draw plugin) so that I can use them.
I am able to get the coordinates of drawn polygon but that's not what I want.
var draw_layer = new L.FeatureGroup();
mymap.addLayer(draw_layer);
var drawControlFull = new L.Control.Draw({
draw: {
polygon: {
allowIntersection: false, // Restricts shapes to simple polygons
drawError: {
color: '#e1e100', // Color the shape will turn when intersects
message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
},
shapeOptions: {
color: '#97009c'
}
},
// disable toolbar item by setting it to false
polyline: false,
circle: false,
rectangle: false,
marker: false,
circlemarker: false
},
edit: {
featureGroup: draw_layer,
remove: true
}
});
mymap.addControl(drawControlFull);
mymap.on(L.Draw.Event.CREATED, function (e) {
var type = e.layerType, layer = e.layer;
if(type === 'polygon'){
var _ajax_cords = [];
var _coords = layer.getLatLngs()[0];
$.each(_coords,function(ind,val){
var _te_co = {x : val.lat, y : val.lng};
_ajax_cords.push(_te_co);
});
}
//if (type === 'polygon') {layer.bindPopup('A popup!');}draw_layer.addLayer(layer);
});
Well I can get the marker detail as I get lot of posts on that but didn't see a post how to get the polygon details.
Any help on this is much appreciable

Can I use Leaflet Draw to add layers to overlay layers?

Is it possible to add a "target overlay" for Leaflet Draw toolbar?
For example I could have two overlays such as Areas and Points of interest.
Now, I would like to add markers only to Points of Interest overlay and polygons on Areas overlay.
I've been trying to figure out that is it somehow possible to programmatically activate overlays or assign overlay for different draw toolbars but nothing seems to help.
All new layers are added to same overlay since I can't figure out which overlay toolbar is used.
And at least console log value of events don't seem to help and I cannot figure out that which toolbar was used (I could use it to force addLayer to use certain overaly), I cannot get anything regarding the target layer etc.
var poiLayer = new L.FeatureGroup();
var areaLayer = new L.FeatureGroup();
var options = {
polygon: {
allowIntersection: false,
drawError: {
color: "#e1e100",
message: "<strong>Lines of a polygon cannot overlap!</strong>"
},
shapeOptions: {
color: "#FF5656"
}
},
polygon: {
allowIntersection: false,
drawError: {
color: "#e1e100",
message: "<strong>Lines of a polygon cannot overlap!</strong>"
},
shapeOptions: {
color: "#FF5656"
}
},
edit: {
featureGroup: areaLayer,
poly: {
allowIntersection: false
},
poly: {
allowIntersection: false
},
poly: {
allowIntersection: false
}
},
draw: {
featureGroup: areaLayer,
name: "dafuq2",
polygon: {
allowIntersection: false,
showArea: true
},
},
name: "namne123123123"
};
//same for the poiLayer
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
var drawControl2 = new L.Control.Draw(options2);
map.addControl(drawControl2);
map.on(L.Draw.Event.CREATED, function(e) {
console.log(e);
});

leaflet.draw does not cancel properly

In the code snippet below, I have setup the leaflet.draw plugin. Works fine for adding features (lines, markers, polygons). Works fine for editing and deleting. But the cancel operation does not work (nor does the simple intersection test, but I can live without that). Any idea what I did wrong to setup the plugin?
(Chrome V44, leaflet 1.0 Beta 2, leaflet.draw (0.2.4-dev) (seems to also fail in leaflet '0.7.7').
Here is the error:
Uncaught TypeError: Cannot read property '0' of undefined
L.Polyline.L.Path.extend._projectLatlngs # leaflet-src.js:5535
L.Polyline.L.Path.extend._projectLatlngs # leaflet-src.js:5547
L.Polyline.L.Path.extend._projectLatlngs # leaflet-src.js:5547
L.Polyline.L.Path.extend._project # leaflet-src.js:5519
L.SVG.L.Renderer.extend._updatePath # leaflet-src.js:6042
L.Path.L.Layer.extend.redraw # leaflet-src.js:5130
L.Polyline.L.Path.extend.setLatLngs # leaflet-src.js:5411
L.EditToolbar.Edit.L.Handler.extend._revertLayer # leaflet.draw-src.js:2759
(anonymous function) # leaflet.draw-src.js:2716
L.LayerGroup.L.Layer.extend.eachLayer # leaflet-src.js:4865
L.EditToolbar.Edit.L.Handler.extend.revertLayers # leaflet.draw-src.js:2715
L.EditToolbar.L.Toolbar.extend.disable # leaflet.draw-src.js:2578handler # leaflet-src.js:6953
and here is the code I use to setup the leaflet.draw
var theMap;
var mapLayer;
var carLayer;
var drawLayer;
var drawControl;
var trackerButton;
....
this.setupDraw();
theMap = L.map('mapCanvas', {
center: mCityCenter,
zoom: 20,
layers: [osmLight, mapLayer, carLayer, drawLayer]
});
theMap.on("draw:created", this.addDrawing);
....
this.setupDraw = function () {
drawLayer = new L.FeatureGroup();
drawControl = new L.Control.Draw({
draw: {
polygon: {
allowIntersection: false, // Restricts shapes to simple polygons
showArea: true,
drawError: {
color: '#e1e100', // Color the shape will turn when intersects
message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
}
}
},
edit: {
featureGroup: drawLayer
}
});
}
this.addDrawing = function (e) {
var type = e.layerType;
var layer = e.layer;
if (type === 'marker') { }
drawLayer.addLayer(layer);
}
That version of Leaflet.draw plugin is not compatible with the version of Leaflet you are using.
Be sure to read docs for the plugin, it states you should be using Leaflet.js 0.7.
Leaflet.draw: https://github.com/Leaflet/Leaflet.draw
Leaflet.JS: http://leafletjs.com/reference.html
From the Leaflet.draw github page: "Leaflet.draw 0.2.3+ requires Leaflet 0.7.x."
As of today there does appear to be a fork of Leaflet.draw that is being developed against Leaflet 1.0 RC: https://github.com/Leaflet/Leaflet.draw/tree/leaflet-master

style a geojson point like a POI with leaflet/mapbox

I am using mapbox.js to render a mapbox map. I am trying to load geojson from my server that contain either a country polygon or a city coordinates (lon,lat).
I have been able to style the country polygons but not the city points/markers.
I am not able to modify the geojson to use mapbox simplestyle
Here is the code executed when the page loads (I changed the mapbox map ID):
var southWest = L.latLng(-90, -360), northEast = L.latLng(90, 360);
var bounds = L.latLngBounds(southWest, northEast);
var map = L.mapbox.map('map', 'MapboxMapID', { zoomControl: false, infoControl: true, detectRetina: true, maxBounds: bounds, minZoom: 2, legendControl: {position: 'topright'}});
new L.Control.Zoom({ position: 'bottomright' }).addTo(map);
map.fitBounds(bounds);
var locationsGroup = L.featureGroup().addTo(map);
and then when the user selects a country or city with a selectbox:
$("#select2-search-up").on("change", function (e) {
if (e.added) {
var location = L.mapbox.featureLayer().loadURL('/citiesCountriesID/' + e.added.id).on('ready', function(featLayer) {
this.eachLayer(function(polygon) {
polygon.setStyle({
stroke:false, fillColor:'red', fillOpacity:0.2
});
});
});
locationsGroup.addLayer(location);
} else {
locationsGroup.eachLayer(function (layer) {
if (layer._geojson[0]._id == e.removed.id) {
locationsGroup.removeLayer(layer);
}
});
}
});
Ideally I would like to display a different icon that the standard marker, but I could do with a small red square
Thank you for your inputs
In this example I did some circle markers but I'm pretty sure you can do other basic svg shps or your own .png pretty easy. http://bl.ocks.org/mpmckenna8/db2eef40314fe24e9177
This example from Mapbox also shows how to use a icon from their icon Library which has a lot of choices also. https://www.mapbox.com/mapbox.js/example/v1.0.0/l-mapbox-marker/
It might also help to see some of your geojson structure to see why it can't use simplestyle
In my bl.ocks example I loaded each of the geojson datasets separately
var begin = L.geoJson(start,{
pointToLayer:function(feature, latlng){
return L.circleMarker(latlng,{
radius:9,
fillColor: "orange",
fillOpacity:.7
})
}
})
Is how I set up my circles and I set a different L.geoJson to the other data which I left as the default markers.

Load geoJson in MapBox for editing with Leaflet.Draw

I try to load geoJson data in Mapbox and edit it with the plugin Leaflet.Draw
Here is an example : fiddle
var featureGroup = L.featureGroup().addTo(map);
var geojson = {
"type": "FeatureCollection",
"features": [ ........... ]
}
L.geoJson(geojson).addTo(featureGroup);
When i click to the edit button, i have an error :
Uncaught TypeError: Cannot read property 'enable' of undefined
Object seems to be editable but i can't modify it.
What is the correct way to add geojson object in mapbox draw layer ?
I have found the solution :
L.geoJson(geojson, {
onEachFeature: function (feature, layer) {
featureGroup.addLayer(layer);
}
});
Here is working example using CoffeeScript:
drawnItems = new L.FeatureGroup()
map.addLayer drawnItems
layers = L.geoJson geojson
layers.eachLayer (layer) => drawnItems.addLayer layer
I had to do the following to get mine to work (in addition to the above answers):
L.geoJson(geojson, {
onEachFeature: function (feature, layer) {
if (layer.getLayers) {
layer.getLayers().forEach(function (l) {
featureGroup.addLayer(l);
})
} else {
featureGroup.addLayer(layer);
}
}
});
This was for a geojson that was a "Feature" type.