Friday, 19 May 2017

Making a GeoJSON layer editable with the Leaflet.Editable plugin



I'm new to Leaflet and the Leaflet.Editable plugin, but I'd like to make GeoJSON layer editable. When I mean "editable", I mean a user can stretch the polygons at will.


Here is a good example of what I'd like.


My current code is as follows:


var map = L.map('mapid', {editable: true}).setView([39.08344, -77.6497145], 13);

L.tileLayer('Some Valid Tile Layer',
{
attribution: 'Myself',
maxZoom: 18
}).addTo(map);


$.ajax({

url: 'http://127.0.0.1:8000/static/map/geoJSON/elementary_boundaries.geojson',
dataType: 'json',
success: function(data){

console.log('The data was received');
L.geoJson(data, {


onEachFeature: function(feature, layer){
layer.enableEdit(); // incorrect, but code would go here

}
}).addTo(map);

},

failure: function(data){
console.log('The data wasn\'t received');

}

});

I don't fully understand features vs layers, and I fully don't understand leaflet's geometry construction flow, so I'm sure my problem is elementary.



Answer



I fixed my problem, though I'm not sure if my solution is the most "ideal" way.


I'm going to give some insight into what I learned and some of this may be wrong, so please let me know so this post can be as accurate as possible.


The Leaflet.Editable plugin only works consistently with Leaflet Vector Layers. These are the classes of Polyline, Polygon, Rectangle, Circle, and Marker. When you use L.GeoJSON, you're creating a different kind of Layer.


The solution is to read the GeoJSON file and instead of making a GeoJSON layer, make a Layer of the Vector variety.



The GeoJSON I used had a type of FeatureCollection. So parse the file and covert each feature into a Polygon class. The code is below


var map = L.map('mapid', {editable: true}).setView([39.08344, -77.6497145], 13);

L.tileLayer('A Valid Tile Layer',
{
attribution: 'Myself',
maxZoom: 18
}).addTo(map);

$.ajax({


url: 'http://127.0.0.1:8000/static/map/geoJSON/elementary_boundaries.geojson',
dataType: 'json',
success: function(data){

var latLong = [];
var thisTime = true;
data.features.forEach(function(currentFeature){

currentFeature.geometry.coordinates[0].forEach(function(locationArray){


locationArray.forEach(function(location){

latLong.push([location[1] , location[0]]);
});
});

var polygon = L.polygon(latLong).addTo(map);
polygon.enableEdit();
latLong = [];

});
},

failure: function(data){
console.log('The data wasn\'t received');
}

});

The following part is necessary because GeoJSON specification requires that coordinates to be in [longitude, latitude] and Leaflet (or OpenStreetMap, can't remember) requires [latitude, and longitude]



    currentFeature.geometry.coordinates[0].forEach(function(locationArray){

locationArray.forEach(function(location){

latLong.push([location[1] , location[0]]);
});
});

I had a GeoJSON file of over 250,000 lines, so maybe the plugin works differently for large files, but this solution solved my problem.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...