1
votes

I'm using Leafletjs library to create a visual sales module for my application. I can add marker with OnMapClick event but not with data coming from service.

    function onMapClick(e) {

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

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

            }
        }
    }

Adding markers on map in AddMarkerToMap function.

    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;
    }

In my code field is a JSON object coming from OData service and it contains lat,lng informations of markers that saved previously. Why markers added dynamically not shown on map ?

1
Why don't you load lat lng from pointToLayer callback function, it gives feature and geometry, you should reference from there. - Downhillski
I think problem is about geojsonFeature. Because I deleted L.geoJson block and added marker with only addto(map) it worked. Do you have any idea about this ? @Zhenyang - user5126784

1 Answers

1
votes

There are a few things don't make too much sense here:

  1. Since you are using a service to load the feature, you should define the related events inside a service because it is async and there is no return.
  2. addTo(map) should apply after the marker is created. The default pointToLayer callback only gives an option to utilize the feature attributes and geometry for you to create like infowindows, you should not use it for return a marker. A walkaround is as in below code -- you just consider it as a xhr call and get the data, and use if for only getting data and then use the response for the visualization. But Better way is to use native XHR call or Ajax call to get the data, and then use your addMarker function.

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;
    }