0

I have a geoJSON polygon in my map and I want to update its color after changing the values by getting a JSON value. So I wrote the below code which changes the property value successfully.

var map = L.map('map').setView([1.3096622448984000, 103.7689017333800], 10);

    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
            '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="http://mapbox.com">Mapbox</a>',
        id: 'mapbox.light'
    }).addTo(map);
    map.doubleClickZoom.disable();




    // get color depending on population density value
    function getColor(d) {
        return  d > 2000 ? '#000080' :
                d > 100  ? '#6fdc6f' :
                d > 500  ? '#6fdc6f' :
                d > 100  ? '#6fdc6f' :
                d > 50   ? '#6fdc6f' :
                d > 20   ? '#6fdc6f' :
                d > 10   ? '#6fdc6f' :
                           '#FFEDA0';

    }

    function style(feature) {
        return {
            weight: 2,
            opacity: 1,
            color: '#999',
            fillOpacity: 0.7,
            fillColor: getColor(feature.properties.state1)
        };
    }

    var geojson = L.geoJson(campus, {
        style: style,
    }).addTo(map);

    function highlightFeature(e) {
    var layer = e.target;

    layer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });


    if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        layer.bringToFront();
    }

    info.update(layer.feature.properties);

    }
function resetHighlight(e) {
    geojson.resetStyle(e.target);
     info.update();
}
function zoomToFeature(e) {
    map.fitBounds(e.target.getBounds());
    map.doubleClickZoom.disable();
}


function searchText(e,feature)
{
     var layer = e.target;
     var search = {
            'zone': layer.feature.properties.name,
            'zone_id':layer.feature.id
             };
                $.ajax({
                    type: "POST",
                    contentType : 'application/json; charset=utf-8',
                    dataType : 'json',
                    url: "http://posturl/",
                    data: JSON.stringify(search), // Note it is important
                    success :function(result) {
                     // do what ever you want with data
                     //  alert("suc");

                   },
                    error:function(error){
                     //alert("success");
                      }
                });
 }


var lastClickedLayer;

function onMapClick(e,feature) {


    var layer = e.target;

    $("#grid_name").html(layer.feature.properties.name);


    searchText(e,feature);





}



function mapupdatecolor(startDate,endDate,e){
     console.log(endDate);
    $.getJSON('http://dataurl', function(data) {
        console.log(data);
        for (i = 0; i <24; i++) { 

            console.log("1 time state1 in console--"+campus['features'][i]['properties']['state1']);
            campus['features'][i]['properties']['state1']=data[i].state1;
            console.log("2 time state1 in console after change--"+campus['features'][i]['properties']['state1']);

        }


        geojson.resetStyle(e.target);
        //data is the JSON string
    });


}


function onEachFeature(feature, layer) {



    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
        //click: zoomToFeature
        click:onMapClick

    });

}

geojson = L.geoJson(campus, {
    style: style,
    onEachFeature: onEachFeature
}).addTo(map);

var info = L.control();

info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
    this.update();
    return this._div;
};


// method that we will use to update the control based on feature properties passed
info.update = function (props) {
    this._div.innerHTML = '<h4><b>Zones<b></h4>' +  (props ?
        '<b>' + props.name + '</b><br />'  
        : 'Hover over a zone');


};


info.addTo(map);

The campus variable will be in another script as

var campus = {


        "type":"FeatureCollection","features":[
            {
                        "type": "Feature",
                        "id":"87",
                        "properties": {
                            "name": "CHANGI POINT(SOUTH)",
                            "state1":"10"
                        },
                        "geometry": {
                            "type": "MultiPolygon",
                            "coordinates": [
                                [
                                    [
                                        [103.981,1.32749],[103.986,1.32528],[103.986,1.32528],[103.986,1.3251],[103.986,1.32508],[103.99,1.32301],[103.995,1.32166],[104.001,1.32121],[104.005,1.32192],[104.01,1.32296],[104.017,1.32545],[104.026,1.32538],[104.033,1.32558],[104.033,1.31493],[104.031,1.31479],[104.028,1.31473],[104.028,1.31731],[104.028,1.31954],[104.023,1.31957],[104.023,1.31506],[104.019,1.31509],[104.011,1.31456],[104.004,1.31003],[104.001,1.30937],[103.991,1.31284],[103.983,1.31127],[103.983,1.31238],[103.985,1.31369],[103.984,1.31591],[103.982,1.3163],[103.976,1.31493],[103.975,1.31596],[103.976,1.32187],[103.976,1.32439],[103.976,1.32623],[103.976,1.32666],[103.977,1.32676],[103.977,1.32748],[103.978,1.32787],[103.979,1.32797],[103.979,1.32792],[103.981,1.32749]
                                        ]

                                        ]
                            ]
                        }

                    }

]};

So I also add the geojson.resetStyle(layer) to change the color of the polygon.Iam triggering the event in (another script)

     clickApply: function(e) {
    var startDate = $('#reportrange').data('daterangepicker').startDate._d;
    var endDate = $('#reportrange').data('daterangepicker').endDate._d;

    var start_date = new Date(startDate);
    var end_date=new Date(endDate);
    var start = moment(start_date).format("YYYY-MM-DD HH:mm:ss");
    var end = moment(end_date).format("YYYY-MM-DD HH:mm:ss");







    mapupdatecolor(start,end,e);




    this.hide();
    this.element.trigger('apply.daterangepicker', this);

}

The state1 properties is updated but the color is only not changing.

     1 time state1 in console--100
     2 time state1 in console after change--2137
     1 time state1 in console--9
     2 time state1 in console after change--1951
     1 time state1 in console--30
     2 time state1 in console after change--1592

I get the error in

fillColor: getColor(feature.properties.state1)

cannot read property properties

I am new to Javascript.

  • maybe try this: map.setPaintProperty('my-layer', 'fill-color', '#faafee') from the Mapbox GL documentation: mapbox.com/mapbox-gl-js/api/#Map#setPaintProperty – the_darkside Dec 12 '16 at 8:47
  • @the_darkside this did not work.Can u suggest a leaflet solution? – joker21 Dec 12 '16 at 10:45
  • What event is calling mapupdatecolor? You need to trace that to ensure that the event has a layer property and that it is getting assigned correctly on the given event. – MappaGnosis Dec 12 '16 at 17:18
  • @MappaGnosis I updated the question.This how I call the mapupdatecolor. – joker21 Dec 13 '16 at 3:28
1

By the looks of it, since the event being fired is from your datepicker code, the 'e' in question will not relate to any given layer in Leaflet. That is why you were getting the error you originally mentioned. I notice the reported error is now something else however.

Based on what I see and what you have said I THINK this is your problem:

You have created a layer-group called campus from some other geojson data. Now you want to update the the value state1 in its attributes based on the AJAX call. However, campus will not have any objects called features. The top-level objects in campus will be layers Leaflet created out of the original geojson data. To update each marker (layer) in the campus layer-group you must either accumulate references to them when you first make the campus object, or you need to wipe it out and replace with updated geojson data 9which could be risky if you don't have a complete set of features in your AJAX call (shown).

So you could try revising your code along the lines of the following semi-pseudo code:

var campusPolys = {};  //create an empty associative array
var campus = L.geoJSON(null, {
    onEachFeature: onEachFeature
}).addTo(map);

function onEachFeature(feature, layer) {
    layer['properties'] = feature.properties;  //assumes a unique 'id'
    campusPolys[feature.properties.id] = layer;  //add this feature to accumulation of references
};

//you get the original geojson data from somewhere...
campus.addData(originalGeojson);

//Now we do your AJAX call (I've skipped all those console logs for brevity)
 function mapupdatecolor(startDate,endDate,e){
    $.getJSON('http://dataurl', function(data) {
        for (var key in data) { 
            campusPolys[data[key]]['properties']['state1']=data[key].state1;
        }
        geojson.resetStyle(campus);
    });
}

In the above code I am assuming that each feature has a unique id and that this id relates to each object key in the data JSON. This is a safer way of doing things that hoping that the order of your features and the data from the AJAX call will necessarily match every time. The above is not plug-and-play code. You'll need to adapt it to fit your existing code.

  • I think I am already doing as you said.As you thought "the problem is the 'e' in question will not relate to any given layer in Leaflet. That is why you were getting the error you originally mentioned." So currently my state1 properties are updating.But the color is not only changing,which means geojson.resetStyle(campus); is not working.So how to trigger this function? – joker21 Dec 14 '16 at 6:18
  • The color changes when I hover over the map in the zone because I call the function geojson.resetStyle(campus); when hovering over the map.So basically I want to know how to call the function mapudatecolor in date range picker(where I do not have the 'e')? – joker21 Dec 14 '16 at 6:25
  • I also edited the question wuth my full code for better exploration – joker21 Dec 14 '16 at 7:35
0

Instead of

geojson.resetStyle(campus);

I used the below code inside my mapupdatecolor function and worked like a charm

map.removeLayer(L.geoJson);

        var geojson = L.geoJson(campus, {
            style: style,
             onEachFeature: onEachFeature
        }).addTo(map);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.