传单绘制“无法读取未定义的属性'启用'"向geoJSON层添加控件 [英] Leaflet Draw "Cannot read property 'enable' of undefined" adding control to geoJSON layer

查看:123
本文介绍了传单绘制“无法读取未定义的属性'启用'"向geoJSON层添加控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对从数据库中加载的多边形使用传单的编辑功能.当我单击传单的编辑"按钮时,出现错误
Cannot read property 'enable' of undefined

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

由于要素组扩展了图层组,因此您可以遍历图层 并将其分别添加到用于 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对象这一事实有关?
将多边形添加到地图,绑定其弹出窗口并为它们分配自定义颜色可以完美地实现FYI.

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 = '&copy; <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 图层(例如,使用其

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/如何编辑现有层使用传单

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(实际上是 Leaflet GeoJSON图层组),然后将其添加到您的Hazards功能组中,从头开始将后者设为GeoJSON图层组,然后
  • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData 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
}

  • 您可以直接构建传单多边形,并将其添加到您的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 your Hazards 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"};
        }
      }
      

      这篇关于传单绘制“无法读取未定义的属性'启用'"向geoJSON层添加控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆