I made a code below for creating shapes with some informations. I can edit thoose informations until my map is open. But after update geojson by "Export features to local file" and page reload, shapes remain unclickable and to correct the informations I have to delete some shapes and recreate them with proper parameters.
Question:
Is it possible to edit the shape's data each time I just open my page? Like I can edit the shapes itself by "Edit layers" button?
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="crossorigin=""/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://code.jquery.com/jquery-1.10.2.js" integrity="sha256-it5nQKHTz+34HijZJQkpNBIHsjpV8b6QzMJs9tmOBSo=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#mapid { height: 100% }
</style>
<!--Add draw plugin -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
</script>
<!--Load plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
<style>
#export{
position: absolute;
top:600px;
//right:1800px;
z-index:1000;
background:white;
color:black;
padding:6px;
border-radius:4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size:12px;
text-decoration:none;
}
#export {
top:370px;
}
</style>
</head>
<body>
<a href='#' id='export'>Export Features to local file</a>
<div id="mapid"></div>
<script>
var features = "https://api.npoint.io/4fefc36933cc5c22cee4";
var cities = L.layerGroup();
var mbAttr = 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr}),
sat = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',{
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}),
OSM = L.tileLayer('https://maps.jakdojade.pl/osm/{z}/{x}/{y}.png');
Topo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png');
var map = L.map('mapid', {
center: [49.9225,18.99195],
//drawControl: true,
zoom: 8,
layers: [streets, cities]
});
var baseLayers = {
"Podstawowa": streets,
"Satelitarna": sat,
"OSM": OSM,
"Topo": Topo,
};
//SVG2
//SVG2
L.control.layers(baseLayers, {collapsed:false, position:'topleft'}).addTo(map);
</script>
<script>
var featureGroup = new L.GeoJSON.AJAX(features, {
}).addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup,
}
}).addTo(map);
map.on('draw:created', function (event) {
var layer = event.layer,
feature = layer.feature = layer.feature || {};
feature.type = feature.type || "Feature";
var props = feature.properties = feature.properties || {};
featureGroup.addLayer(layer);
addPopup(layer);
});
var openLayer;
function addPopup(layer){
let popupContent =
'<form>' +
'Link:<br><input type="text" id="input_link"><br>' +
'Cena:<br><input type="text" id="input_cena"><br>' +
'Area:<br><input type="text" id="input_area"><br>' +
'Image:<br><input type="text" id="input_image"><br>' +
'</form>';
layer.on("popupopen", function (e) {
var _layer = e.popup._source;
if(!_layer.feature){
_layer.feature = {
properties: {}
};
}
document.getElementById("input_link").value = _layer.feature.properties.link || "";
document.getElementById("input_cena").value = _layer.feature.properties.cena || "";
document.getElementById("input_area").value = _layer.feature.properties.area || "";
document.getElementById("input_image").value = _layer.feature.properties.image || "";
document.getElementById("input_link").focus();
openLayer = _layer;
});
layer.on("popupclose", function (e) {
openLayer = undefined;
});
layer.bindPopup(popupContent).openPopup();
};
L.DomEvent.on(document,"keyup",function(){
if(openLayer){
link = document.getElementById("input_link").value;
cena = document.getElementById("input_cena").value;
area = document.getElementById("input_area").value;
image = document.getElementById("input_image").value;
openLayer.feature.properties.link = link;
openLayer.feature.properties.cena = cena;
openLayer.feature.properties.area = area;
openLayer.feature.properties.image = image;
openLayer.feature.properties.N = 1;
}
})
document.getElementById('export').onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData = 'text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(data));
// Create export
document.getElementById('export').setAttribute('href', 'data:' + convertedData);
document.getElementById('export').setAttribute('download','sl.geojson');
};
</script>
</body>
</html>
Of course, I did it quickly, so you have to adapt to your own code. I removed L.GeoJSON.AJAX but nothing prevents you from continuing to use it, I advise you not to ;)
var features = "https://api.npoint.io/4fefc36933cc5c22cee4";
var cities = L.layerGroup();
var mbAttr =
'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
mbUrl =
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw";
var streets = L.tileLayer(mbUrl, {
id: "mapbox/streets-v11",
tileSize: 512,
zoomOffset: -1,
attribution: mbAttr,
});
var map = L.map("mapid", {
center: [49.9225, 18.99195],
zoom: 8,
});
streets.addTo(map);
// add layers to map
async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (err) {
console.error(err);
}
}
fetchData(features).then((geoJsonData) => {
const feature = L.geoJSON(geoJsonData, {
onEachFeature: function(feature, layer) {
layer.on("mouseover", function(e) {
e.target.setStyle({
color: "red",
weight: 2,
});
});
layer.on("mouseout", function(e) {
e.target.setStyle({
color: "#3388ff",
weight: 2,
});
});
addPopup(layer);
},
}).addTo(map);
});
// --------------------------------------------------
// draw section
let drawnItems = L.featureGroup().addTo(map);
map.addControl(
new L.Control.Draw({
edit: {
featureGroup: drawnItems,
poly: {
allowIntersection: false,
},
},
draw: {
polygon: {
allowIntersection: false,
showArea: true,
},
},
})
);
map.on(L.Draw.Event.CREATED, function(event) {
let layer = event.layer;
let feature = (layer.feature = layer.feature || {});
let type = event.layerType;
feature.type = feature.type || "Feature";
let props = (feature.properties = feature.properties || {});
props.type = type;
if (type === "circle") {
props.radius = layer.getRadius();
}
drawnItems.addLayer(layer);
addPopup(layer);
});
var openLayer;
function addPopup(layer) {
let popupContent = `
<form>Link:<br>
<input type="text" id="input_link" value="${
layer.feature.properties.link || ""
}"><br>
Cena:<br><input type="text" id="input_cena" value=${
layer.feature.properties.cena || ""
}><br>
Area:<br><input type="text" id="input_area" value=${
layer.feature.properties.area || ""
}><br>
Image:<br><input type="text" id="input_image" value=${
layer.feature.properties.image || ""
}><br>
</form>`;
layer.on("popupopen", function(e) {
var _layer = e.popup._source;
if (!_layer.feature) {
_layer.feature = {
properties: {},
};
}
// document.getElementById("input_link").value =
// _layer.feature.properties.link || "";
// document.getElementById("input_cena").value =
// _layer.feature.properties.cena || "";
// document.getElementById("input_area").value =
// _layer.feature.properties.area || "";
// document.getElementById("input_image").value =
// _layer.feature.properties.image || "";
// document.getElementById("input_link").focus();
// openLayer = _layer;
});
layer.on("popupclose", function(e) {
openLayer = undefined;
});
layer.bindPopup(popupContent).openPopup();
}
L.DomEvent.on(document, "keyup", function() {
if (openLayer) {
link = document.getElementById("input_link").value;
cena = document.getElementById("input_cena").value;
area = document.getElementById("input_area").value;
image = document.getElementById("input_image").value;
openLayer.feature.properties.link = link;
openLayer.feature.properties.cena = cena;
openLayer.feature.properties.area = area;
openLayer.feature.properties.image = image;
openLayer.feature.properties.N = 1;
}
});
document.getElementById("export").onclick = function(e) {
// Extract GeoJson from featureGroup
var data = featureGroup.toGeoJSON();
// Stringify the GeoJson
var convertedData =
"text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
// Create export
document
.getElementById("export")
.setAttribute("href", "data:" + convertedData);
document.getElementById("export").setAttribute("download", "sl.geojson");
};
html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0
}
#mapid {
height: 100%
}
#export {
position: absolute;
top: 600px;
z-index: 1000;
background: white;
color: black;
padding: 6px;
border-radius: 4px;
font-family: 'Helvetica Neue';
cursor: pointer;
font-size: 12px;
text-decoration: none;
}
#export {
top: 370px;
}
<link href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" rel="stylesheet" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<a href='#' id='export'>Export Features to local file</a>
<div id="mapid"></div>
You can add the option to modify fields (form) only when you click the edit button.
map.on(L.Draw.Event.EDITED, function (event) {
let layers = event.layers;
layers.eachLayer(function (layer) {
addPopup(layer);
});
});