Avoid requery on feature layer?

642
6
05-24-2012 01:46 PM
RexBradford
New Contributor II
I have a layer of country polygons that I am color-coding based on dynamic metrics.  My problem is not one of functionality but performance - the country polygons are requeried every time I want to change the color-coding symbols (fill color) associated with them.

The layer is created with code like this:

 var countryLayer = new esri.layers.FeatureLayer(urltools.fixServerURL(layerInfo.url), { 
       id: layerID, 
       mode: esri.layers.FeatureLayer.MODE_ONDEMAND, // neither ONDEMAND nor SNAPSHOT works as I'd like
//       mode: esri.layers.FeatureLayer.MODE_SNAPSHOT, 
       opacity: 0.75,
       outFields: ["*"] });


When I want to update the map to change the color-coding of countries, after some computation I assign new symbols with code like this:

    // Go thru all countries, computing the color for each and changing its symbol    
    for (var ic = 0; ic < mapLayers.countryCodeList.length; ic++) {
        var ccode = mapLayers.countryCodeList[ic];
        var csym = csymNoData;
        var val = mapData.currDataView.cntryVals[ccode]
        var index = _getRangeIndexForData(val);
        if (index >= 0)
            csym = options.cranges[index].csym;
//        console.log("cntry: " + ccode + " val: " + cntryVals[ccode] + " color: " + csym.r + "," + csym.g + "," + csym.b);
        mapLayers.countrySymbols[ccode] = new esri.symbol.SimpleFillSymbol().setColor(csym);
        mapLayers.renderer.removeValue(ccode);
        mapLayers.renderer.addValue({value: ccode, symbol: mapLayers.countrySymbols[ccode],
            label: "Label: " + ccode, description: "Description: " + ccode});
    }


Nothing is updated unless I call refresh(), but that causes a refetch over the internet tubing:

    mapLayers.countryLayer.refresh();


Is there a way for me to dynamically update the country colors without continually refetching the same unchanging boundary data?

Thanks,

Rex Bradford
Direct Relief International
0 Kudos
6 Replies
derekswingley1
Frequent Contributor
Are you using countryLayer.setRenderer() to update your symbology?

Also, you should be seeing http 304s and very small response sizes when your feature layer fetches a URL more than once. Are you not seeing 304s?
0 Kudos
RexBradford
New Contributor II
Are you using countryLayer.setRenderer() to update your symbology?

Also, you should be seeing http 304s and very small response sizes when your feature layer fetches a URL more than once. Are you not seeing 304s?


I am using a UniqueValueRenderer, which I'm not sure is the right thing here (as opposed to a class breaks renderer)

   mapLayers.renderer = new esri.renderer.UniqueValueRenderer(defSymbol, "ISO_2DIGIT");
.....
        mapLayers.countrySymbols[ccode] = defSymbol;
        mapLayers.renderer.addValue({value: ccode, symbol: mapLayers.countrySymbols[ccode],
            label: "Label: " + ccode, description: "Description: " + ccode});
.....
countryLayer.setRenderer(mapLayers.renderer);


And then to update I am creating new symbols (as needed, I reuse symbols across the country feature graphics), and assigning them with removeValue() and addValue(), one per country:

        mapLayers.renderer.removeValue(ccode);
        mapLayers.renderer.addValue({value: ccode, symbol: mapLayers.countrySymbols[ccode],
            label: "Label: " + ccode, description: "Description: " + ccode});


But nothing changes onscreen until I do a refresh(), which shows up in Firebug as a full 200 OK weighing in at 310.6K every time in my case.  If it's relevant, I have a longish definition expression, to get just the few dozen countries I want.

dojo.io.script.jsonp_dojoIoScript_Countries_generalized_boundaries_10._jsonpCallback({"displayFieldName":"CNTRY_NAME","fieldAliases":{"OBJECTID":"OBJECTID","FIPS_CNTRY":"FIPS_CNTRY","GMI_CNTRY":"GMI_CNTRY","ISO_2DIGIT":"ISO_2DIGIT","ISO_3DIGIT":"ISO_3DIGIT","ISO_NUM":"ISO_NUM","CNTRY_NAME":"CNTRY_NAME","LONG_NAME":"LONG_NAME","ISOSHRTNAM":"ISOSHRTNAM","UNSHRTNAM":"UNSHRTNAM","LOCSHRTNAM":"LOCSHRTNAM","LOCLNGNAM":"LOCLNGNAM","STATUS":"STATUS","POP2007":"POP2007","SQKM":"SQKM","SQMI":"SQMI","LAND_SQKM":"LAND_SQKM","COLORMAP":"COLORMAP","Shape_Length":"Shape_Length","Shape_Area":"Shape_Area"},"geometryType":"esriGeometryPolygon","spatialReference":{"wkid":102100},"fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID"},{"name":"FIPS_CNTRY","type":"esriFieldTypeString","alias":"FIPS_CNTRY","length":2},{"name":"GMI_CNTRY","type":"esriFieldTypeString","alias":"GMI_CNTRY","length":3},{"name":"ISO_2DIGIT","type":"esriFieldTypeString","alias":"ISO_2DIGIT","length":2},{"name":"ISO_3DIGIT","type":"esriFieldTypeString","alias":"ISO_3DIGIT","length":3},{"name":"ISO_NUM","type":"esriFieldTypeInteger","alias":"ISO_NUM"},{"name":"CNTRY_NAME","type":"esriFieldTypeString","alias":"CNTRY_NAME","length":40},{"name":"LONG_NAME","type":"esriFieldTypeString","alias":"LONG_NAME","length":40},{"name":"ISOSHRTNAM","type":"esriFieldTypeString","alias":"ISOSHRTNAM","length":45},{"name":"UNSHRTNAM","type":"esriFieldTypeString","alias":"UNSHRTNAM","length":55},{"name":"LOCSHRTNAM","type":"esriFieldTypeString","alias":"LOCSHRTNAM","length":43},{"name":"LOCLNGNAM","type":"esriFieldTypeString","alias":"LOCLNGNAM","length":74},{"name":"STATUS","type":"esriFieldTypeString","alias":"STATUS","length":60},{"name":"POP2007","type":"esriFieldTypeDouble","alias":"POP2007"},{"name":"SQKM","type":"esriFieldTypeDouble","alias":"SQKM"},{"name":"SQMI","type":"esriFieldTypeDouble","alias":"SQMI"},{"name":"LAND_SQKM","type":"esriFieldTypeInteger","alias":"LAND_SQKM"},{"name":"COLORMAP","type":"esriFieldTypeInteger","alias":"COLORMAP"},{"name":"Shape_Length","type":"esriFieldTypeDouble","alias":"Shape_Length"},{"name":"Shape_Area","type":"esriFieldTypeDouble","alias":"Shape_Area"}],"features":[{"attributes":{"OBJECTID":45,"FIPS_CNTRY":"HA","GMI_CNTRY":"HTI","ISO_2DIGIT":"HT","ISO_3DIGIT":"HTI","ISO_NUM":332,"CNTRY_NAME":"Haiti","LONG_NAME":"Republic of Haiti","ISOSHRTNAM":"Haiti","UNSHRTNAM":"Haiti","LOCSHRTNAM":"Haiti","LOCLNGNAM":"Republique d'Haiti","STATUS":"UN Member State","POP2007":8706497,"SQKM":27949.040000000001,"SQMI":10791.120000000001,"LAND_SQKM":27560,"COLORMAP":1,"Shape_Length":1588233.8414093608,"Shape_Area":30535891711.168987},"geometry":{"rings":[[[-8138691.4058999997,2228889.4081000015],[-8143052.1421000008,2227346.691300001],[-8166800.5819000006,2228429.5656000003],[-8168223.4750999995,2228560.7611999996],[-8171701.7705000006,2229758.7012999989],[-8174006.0781999994,2231285.5639999993],[-8176108.8989000004,2233223.0943000019],[-8176882.1333000008,2234109.7089000009],[-8178118.7673000004,2236079.8148999996],[-8177746.4166999999,2239890.4375],[-8177515.6500000004,2241421.2894000001],[-8172861.5009000003,2251686.2349000014],[-8171423.4733000007,2253117.0102999993],[-8169707.0177999996,2253330.0311000012],[-8166151.9309,2253461.2608999982],[-8164728.0485999994,2253198.7824000008],[-8162967.1977999993,2253790.4800999984],[-8158421.3593000006,2255565.7047999986],[-8156813.2332000006,2256322.1193999983],[-8147567.7117999997,2261516.6174000017],[-8143546.9486999996,2263818.8687000014],[-8130065.1437999997,2262668.2435000017],[-8124653.0252999999,2262898.5216999985],[-8114851.9170999993,2264015.8933000006],[-8109037.9069999997,2265167.6732000001],[-8106008.0074000005,2266089.1838999987],[-8103873.6676000003,2266252.8614000008],[-8102328.4677000009,2266187.1123000011],[-8091258.1801999994,2263588.5791999996],[-8089990.1391000003,2263161.254999999],[-8079506.9760999996,2259344.7490999997],[-8075116.8482000008,2254743.6314000003],[-8069889.9625000004,2251785.1594000012],[-8050348.2651000004,2244949.2298000008],[-8038010.0671999995,2246313.8137999997],[-8037831.9442999996,2242847.0227999985],[-8036216.8202,2242124.5170000009],[-8025856.9715999998,2240186.0751999989],[-8021466.9930000007,2239989.2802999988],[-8012869.9920000006,2240317.2135000005],[-7994842.3673,2238936.8476000018],[-7987638.9985000007,2238214.4714000002],[-7986957.9513000008,2237426.6327],[-7985674.6451999992,2235883.0824000016],[-7985288.1492999997,2235060.7963000014],[-7985536.0658,2232172.0879999995],[-7985814.3629999999,2228921.6827000007],[-7985503.6696000006,2226919.1374999993],[-7984545.3142000008,2223998.1931999996],[-7984081.7654999997,2222882.2571999989],[-7983587.9666000009,2221766.3865999989],[-7982473.7699999996,2219732.1966999993],[-7982103.4162000008,2218550.9468999989],[-7980711.9300999995,2213695.683699999],[-7980681.5307,2212219.5797999986],[-7981345.4466999993,2202429.8465999998],[-7984236.6175999995,2197366.2901999988],[-7986587.4668000005,2188616.4857000001],[-7983340.0688000005,2185308.1530000009],[-7981175.3296000008,2183408.7291000001],[-7980248.3813000005,2182688.3081],[-7978515.8024000004,2181901.7043000013],[-7977186.0855,2181541.5086000003],[-7973724.0628999993,2180821.3150999993],[-7973738.1896000002,2178938.3376000002],[-7974326.1910999995,2173946.3467999995],[-7974914.1740000006,2171065.6356000006],[-7976536.4453999996,2169003.6919],[-7987173.4528999999,2157257.5456999987],[-7990235.7300000004,2149753.1471999995],[-7983471.6502,2140608.7206999995],[-7982566.8343000002,2130259.4646000005],[-7982627.6143999994,2129084.7065000013],[-7983370.3189000003,2125491.3227000013],[-7984406.7347999997,2121850.5126999989],[-7985194.9729999993,2120528.8786000013],[-7985690.8992999997,2120267.135400001],[-7987854.5000999998,2120136.8068999983],[-7988966.6998999994,2119745.6689000018],[-7989987.8322000001,2119190.1530999988],[-7991596.8354000002,2116644.3407000005],[-7995369.5701000001,2111292.2038999982],[-7996266.2496000007,2110541.4360999987],[-7998677.8789000008,2109855.8957000002],[-8004058.6276999991,2108909.7298000008],[-8005232.466,2109415.8687999994],[-8006578.4370000008,2111104.2533],[-8011726.5342999995,2110736.9235999994],[-8012747.5360000003,2110182.5645999983],[-8015344.4167999998,2107995.6638999991],[-8014663.3695999999,2107017.6506999992],[-8009345.3044000007,2101700.0179000013],[-8003562.6827000007,2095308.2358999997],[-8002372.5715999994,2093473.8691000007],[-8004645.6215000004,2090989.0848000012],[-
etc. etc. etc. - goes on for a long time
0 Kudos
derekswingley1
Frequent Contributor
Class breaks or unique value doesn't make a difference.

Once you've modified your renderer, apply it to your feature layer using setRenderer (and comment out your call to refresh()). Please let us know if that works.
0 Kudos
RexBradford
New Contributor II
Class breaks or unique value doesn't make a difference.

Once you've modified your renderer, apply it to your feature layer using setRenderer (and comment out your call to refresh()). Please let us know if that works.


Hmm, nope, it doesn't send out any sort of query nor refresh the countries visually.

    // Go thru all countries, computing the color for each and changing its symbol    
    for (var ic = 0; ic < mapLayers.countryCodeList.length; ic++) {
        var ccode = mapLayers.countryCodeList[ic];
        var csym = csymNoData;
        var val = mapData.currDataView.cntryVals[ccode];
        var index = _getRangeIndexForData(val);
        if (index >= 0)
            csym = options.cranges[index].csym;
//        console.log("cntry: " + ccode + " val: " + cntryVals[ccode] + " color: " + csym.r + "," + csym.g + "," + csym.b);
        mapLayers.countrySymbols[ccode] = new esri.symbol.SimpleFillSymbol().setColor(csym);
        mapLayers.renderer.removeValue(ccode);
        mapLayers.renderer.addValue({value: ccode, symbol: mapLayers.countrySymbols[ccode],
            label: "Label: " + ccode, description: "Description: " + ccode});
    }

    mapLayers.countryLayer.setRenderer(mapLayers.renderer);
//    mapLayers.countryLayer.refresh();
0 Kudos
derekswingley1
Frequent Contributor
I looked into this a bit more and using setRenderer() doesn't cause the features to re-draw. Calling refresh() does the job, but as you noted it re-qureies the service. In cases where you're using 10.0 or 10.1, this shouldn't be a concern because the server should return a 304 in 100 or so milliseconds. If your server isn't quickly returning 304s, you could use centerAt and pass in the map's current center so that the map doesn't actually move but it does re-draw the features with the new renderer:
map.centerAt(map.extent.getCenter());


Working example using this workaround:  http://jsfiddle.net/FePUD/
0 Kudos
RexBradford
New Contributor II
I looked into this a bit more and using setRenderer() doesn't cause the features to re-draw. Calling refresh() does the job, but as you noted it re-qureies the service. In cases where you're using 10.0 or 10.1, this shouldn't be a concern because the server should return a 304 in 100 or so milliseconds. If your server isn't quickly returning 304s, you could use centerAt and pass in the map's current center so that the map doesn't actually move but it does re-draw the features with the new renderer:
map.centerAt(map.extent.getCenter());


Working example using this workaround:  http://jsfiddle.net/FePUD/


Thanks very much - this workaround works like a charm and is basically instantaneous (avoids the server roundtrip).

Rex Bradford
Direct Relief International
0 Kudos