【问题标题】:Cannot add marker dynamically with leaflet无法使用传单动态添加标记
【发布时间】:2015-11-16 01:31:31
【问题描述】:

我正在使用 Leafletjs 库为我的应用程序创建一个可视化销售模块。我可以使用 OnMapClick 事件添加标记,但不能使用来自服务的数据。

    function onMapClick(e) {

        var newPosition = e.latlng;
        var field = GetFieldInfo();
        if (field) {
            if (bounds.contains(newPosition)) {

                AddMarkerToMap(e.latlng.lat, e.latlng.lng, field);

            }
        }
    }

在 AddMarkerToMap 函数中在地图上添加标记。

    function AddMarkerToMap(_lat, _lng, field) {

        var lat = JSON.parse(_lat);
        var lng = JSON.parse(_lng);
        var geojsonFeature = {
            "type": "Feature",
            "properties": {},
            "geometry": {
                "type": "Point",
                "coordinates": [lat, lng]
            }
        }

        var newMarker;

        L.geoJson(geojsonFeature, {

            pointToLayer: function (feature, latlng) {

                newMarker = CreateMarker(lat, lng, field);

                return newMarker;
            }
        }).addTo(map);

        var lastValidPosition;
        newMarker.on("drag", function (event) {
            var latLng = newMarker.getLatLng();
            if (bounds.contains(latLng)) {
                lastValidPosition = latLng;
            } else {
                if (lastValidPosition) {
                    newMarker.setLatLng(lastValidPosition);
                }
            }
        }, newMarker);
        var popupContent = CreatePopupContent(field);
        newMarker.bindPopup(popupContent);

        newMarker.on("popupopen", onPopupOpen);
    }


    function CreateMarker(lat, lng, field) {
        var position = [lat, lng];
        var newMarker;

            newMarker = new customFieldMarker(position, {
                icon: L.icon({
                    iconUrl: 'Sources/css/images/Outside-Chartreuse.png',
                    iconSize: [48, 48], // size of the icon
                    iconAnchor: [24, 48], // point of the icon which will correspond to marker's location
                    popupAnchor: [0, -48],
                }),

                draggable: "true",
                options: {
                    field: field
                }
            });

        return newMarker;
    }

在我的代码中,field 是一个来自 OData 服务的 JSON 对象,它包含以前保存的标记的 lat、lng 信息。为什么动态添加的标记没有显示在地图上?

【问题讨论】:

  • 你为什么不从pointToLayer回调函数加载lat lng,它给出了特征和几何,你应该从那里参考。
  • 我认为问题是关于 geojsonFeature。因为我删除了 L.geoJson 块并添加了只有 addto(map) 的标记,所以它起作用了。你对此有什么想法吗? @Zhenyang

标签: javascript jquery leaflet


【解决方案1】:

这里有几件事没有太大意义:

  1. 由于您使用服务来加载功能,因此您应该在服务中定义相关事件,因为它是异步的并且没有返回。
  2. addTo(map) 应该在创建标记后应用。默认的pointToLayer 回调只提供了一个选项,可以利用要素属性和几何图形来创建类似信息窗口,您不应该使用它来返回标记。绕行如下代码 - 您只需将其视为 xhr 调用并获取数据,并使用 if 仅获取数据,然后将响应用于可视化。但更好的方法是使用原生 XHR 调用或 Ajax 调用来获取数据,然后使用您的 addMarker 函数。

function AddMarkerToMap(lat, lng, field) {

  var newMarker = CreateMarker(lat, lng, field);

  newMarker.addTo(map);

  var lastValidPosition;
  newMarker.on("drag", function(event) {
    var latLng = newMarker.getLatLng();
    if (bounds.contains(latLng)) {
      lastValidPosition = latLng;
    } else {
      if (lastValidPosition) {
        newMarker.setLatLng(lastValidPosition);
      }
    }
  }, newMarker);
  var popupContent = CreatePopupContent(field);
  newMarker.bindPopup(popupContent);

  newMarker.on("popupopen", onPopupOpen);

  return newMarker;

}

function LoadFields() {

    var selectedFloor = $("#cmbFloors").val();
    if (selectedFloor && selectedFloor !== "0") {
      var serviceURL = "http://localhost/VisualSalesModuleWeb/FakeOrganizationData.svc";
      var ODataURL = serviceURL + "/ProductSet?$format=json&$filter=new_projectfloorid eq guid'" + selectedFloor + "'";

      $.ajax({
        type: "GET",
        url: ODataURL,
        dataType: 'json',
        async: false,
        contentType: "application/json; charset=utf-8",
        beforeSend: function(XMLHttpRequest) {
          //ShowDialog();
          XMLHttpRequest.setRequestHeader("Accept", "application/json");
        },
        success: function(data, textStatus, XmlHttpRequest) {
          var fields = data.value;

          for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            var lat = JSON.parse(field.Lattitude);
            var lng = JSON.parse(field.Longitude);
            AddMarkerToMap(lat, lng, field);
          }
        },
        error: function(XmlHttpRequest, textStatus, errorObject) {
          alert("OData Execution Error Occurred");
        },
        complete: function() {
          //HideDialog();
        }
      });
    }
    function GetAllMarkers() {

        var allMarkersObjArray = [];
        var allMarkersGeoJsonArray = [];

        $.each(map._layers, function (ml) {
            //console.log(map._layers)
            if (map._layers[ml].feature) {

                allMarkersObjArray.push(this)
                allMarkersGeoJsonArray.push(JSON.stringify(this.toGeoJSON()))
            }
        })
      
        return allMarkersObjArray;
    }

【讨论】:

  • 感谢您的回答,我清楚地理解我的错误。但现在我遇到了另一个错误。此代码向地图添加标记,但在 L.geoJson 上出现错误,例如“无法设置未定义的属性'特征'”@Zhenyang
  • 只是返回一些东西 -- return newMarker;
  • 另外我建议你重新组织你的AddMarkerToMap函数,因为你决定使用L.GeoJSON,它所接受的参数对于函数本身的含义非常混乱。我建议你只使用原生 xhr 或 ajax 调用来获取 json 数据,然后包装你的回调。
  • 我返回了 newMarker 但现在它没有向地图添加标记。我正在通过 ajax 调用获取我的数据,它的成功事件正在循环我的数据。循环正在调用 AddMarkerToMap 函数。 @郑阳
  • 你能用你的新逻辑更新上面的脚本吗?
猜你喜欢
  • 2018-02-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
  • 2011-12-12
  • 2019-08-30
相关资源
最近更新 更多