传单绘制“无法读取未定义的属性‘启用’"向 geoJSON 层添加控制
我正在尝试对从数据库加载的多边形使用传单的编辑功能.当我单击传单的编辑按钮时,我收到错误无法读取未定义的属性启用"
I am trying to use leaflet's edit function on polygons that I loaded from my database. When I click on leaflet's edit button I get the error
Cannot read property 'enable' of undefined
这个帖子描述了一个类似的问题,用户ddproxy说
This thread describes a similar problem, and user ddproxy said
由于FeatureGroup扩展了LayerGroup,你可以遍历图层呈现并将它们单独添加到用于Leaflet.draw"
"Since FeatureGroup extends LayerGroup You can walk through the layers presented and add them individually to the FeatureGroup used for Leaflet.draw"
我很困惑他所说的穿过"是什么意思,我以为我正在添加一个图层组,所以我不确定我会穿过什么.这是否与我将多边形添加为 geoJSON 对象这一事实有关?
将多边形添加到地图,绑定它们的弹出窗口,并为它们分配自定义颜色,仅供参考.
I am confused what he means by "walk through", I thought I was adding a layer group, so i'm not sure what I would be walking through. Does this have to do with the fact that i'm adding the polygons as a geoJSON object?
Adding the polygons to the map, binding their popups, and assigning them custom colors works perfectly FYI.
以下是相关代码:
<script>
window.addEventListener("load", function(event){
//other stuff
loadHazards();
});
//next 6 lines siply add map to page
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
var osmAttrib = '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib})
var map = new L.Map('map', { center: new L.LatLng(39.255467, -76.711964), zoom: 16 })
osm.addTo(map);
var drawnItems = L.featureGroup().addTo(map);
var Hazards = L.featureGroup().addTo(map);
L.control.layers({
'osm': osm.addTo(map)
},
{
'drawlayer': drawnItems,
"Hazards" : Hazards,
"Tickets": Tickets
},
{
position: 'topleft', collapsed: false
}
).addTo(map);
map.addControl(new L.Control.Draw({
edit: {
featureGroup: Hazards,
poly: {
allowIntersection: false
}
},
draw: {
polygon: {
allowIntersection: false,
showArea: true
},
rectangle:false,
circle:false,
circlemarker:false
}
}));
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
</script>
还有 loadHazards() 函数:
And the loadHazards() function:
function loadHazards(){
$.ajax({
type: 'GET',
url:'/loadPolygonFromDatabase',
success : function(polygons){
polygons = JSON.parse(polygons);
var toAdd = [];
for (i in polygons){
var item = {
"type" : "Feature",
"properties":{
"category":"",
"description":"",
"ID":""
},
"geometry" : {
"type":"Polygon",
"coordinates":[],
}
};
item["geometry"]["coordinates"][0] = polygons[i]["coordinates"];
item["properties"]["category"] = polygons[i]["category"];
item["properties"]["description"] = polygons[i]["description"];
item["properties"]["ID"] = polygons[i]["ID"];
toAdd.push(item);
}
//Add information to popup
var layerGroup = L.geoJSON(toAdd, {
onEachFeature: function (feature, layer) {
layer.bindPopup( '<h1>' + feature.properties.category + '</h1>'
+ '<p>' + feature.properties.description + '</p>');
layer.id = feature.properties.ID;
},
style: function(feature){
switch (feature.properties.category) {
case 'Rabid_Beavers': return {color: "#663326"};
case 'Fire': return {color: "#ff0000"};
case 'Flood': return {color: "#0000ff"};
}
}
}).addTo(Hazards);
}
});
}
提前致谢!
推荐答案
不幸的是,Leaflet.draw 插件不处理嵌套层组(功能组/GeoJSON 层组相同).
Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).
这就是你参考的Leaflet.draw #398问题的意思:他们建议遍历您的 Layer/Feature/GeoJSON 层组的 child 层(例如,使用他们的 eachLayer
方法).如果子图层是非组图层,则将其添加到您的可编辑要素组.如果是另一个嵌套组,则再次循环遍历其自己的子层.
That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer
method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.
查看该帖子中提出的代码:
See the code proposed in that post:
https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet
var geoJsonGroup = L.geoJson(myGeoJSON);
addNonGroupLayers(geoJsonGroup, drawnItems);
// Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
function addNonGroupLayers(sourceLayer, targetGroup) {
if (sourceLayer instanceof L.LayerGroup) {
sourceLayer.eachLayer(function(layer) {
addNonGroupLayers(layer, targetGroup);
});
} else {
targetGroup.addLayer(sourceLayer);
}
}
在您的情况下,您还可以使用 2 个其他解决方案重构您的代码:
In your very case, you can also refactor your code with 2 other solutions:
- 而不是构建您的
layerGroup
(实际上是一个 LeafletGeoJSON 图层组),然后将其添加到您的Hazards
功能组中,从头开始将后者设为 GeoJSON 图层组,然后addData
用于您的每个功能(item
):李>
- Instead of building your
layerGroup
(which is actually a Leaflet GeoJSON Layer Group) first and then add it into yourHazards
Feature Group, make the latter a GeoJSON Layer Group from the beginning, andaddData
for each of your single Features (item
):
var Hazards = L.geoJSON(null, yourOptions).addTo(map);
for (i in polygons) {
var item = {
"type" : "Feature",
// etc.
};
// toAdd.push(item);
Hazards.addData(item); // Directly add the GeoJSON Feature object
}
- 您可以直接构建一个 Leaflet Polygon 并将其添加到您的
Hazards
图层/功能组中: - Instead of building a GeoJSON Feature Object (
item
) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into yourHazards
Layer/Feature Group:
for (i in polygons) {
var coords = polygons[i]["coordinates"];
var style = getStyle(polygons[i]["category"]);
var popup = ""; // fill it as you wish
// Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
var itemLayer = L.polygon(coords, style).bindPopup(popup);
itemLayer.id = polygons[i]["ID"];
itemLayer.addTo(Hazards);
}
function getStyle(category) {
switch (category) {
case 'Rabid_Beavers': return {color: "#663326"};
case 'Fire': return {color: "#ff0000"};
case 'Flood': return {color: "#0000ff"};
}
}
相关文章