Feature selection on tiled map service using ArcGIS Javascript API 3.17

2466
7
08-29-2016 04:21 AM
DharmaRajan
Occasional Contributor

My feature class has around 80,000 point features. So I've used tiled map service and generated the cached tiles for fast rendering on client browser. I'm using ArcGIS Javascript API 3.17. Now I want to add select features option on map. I feel that adding feature layer for selection option alone will slowdown the data rendering on client browser. Please help how can I implement feature selection in my applicaiton. Thanks

0 Kudos
7 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Dharma,

You can add the feature layer using MODE_SELECTION.  In selection mode, features are retrieved from the server only when they are selected.

FeatureLayer | API Reference | ArcGIS API for JavaScript 3.17 

0 Kudos
DharmaRajan
Occasional Contributor

Thanks a lot Jake

0 Kudos
DharmaRajan
Occasional Contributor

Hi Jake,

If I add feature layer,  will all point features display twice? because all points are already visible from tiled service.

0 Kudos
JakeSkinner
Esri Esteemed Contributor

You can set a selection symbol for the feature layer so only graphics are displayed when a feature is selected.  Example:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Select Features</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.17/esri/css/esri.css">

    <style>
      html, body, #mapDiv {
        padding:0;
        margin:0;
        height:100%;
      }
    </style>

    <script src="http://js.arcgis.com/3.17/"></script>
    <script>
      var map, tb, polygon;

      require([
        "esri/map", "esri/toolbars/draw", "esri/layers/FeatureLayer", "esri/tasks/query",
        "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleMarkerSymbol",
        "esri/graphic", "esri/geometry/Polygon",
        "dojo/_base/Color", "dojo/dom", "dojo/on", "dojo/_base/array", "dojo/domReady!"
      ], function(
        Map, Draw, FeatureLayer, Query,
        SimpleFillSymbol, SimpleLineSymbol, SimpleMarkerSymbol,
        Graphic, Polygon,
        Color, dom, on, array
      ) {
        map = new Map("mapDiv", {
          basemap: "streets",
          center: [-81.792107, 26.150807],
          zoom: 8
        });
        map.on("load", initToolbar);

        var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0",{
            mode: FeatureLayer.MODE_SELECTION
        });

        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE,
          12,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL,
            new Color([247, 34, 101, 0.9]),
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol);

        map.addLayer(featureLayer);


       var fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL,
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
            new Color([255,0,0]), 2)
        );


        function initToolbar() {
          tb = new Draw(map);
          tb.on("draw-end", addGraphic);
          //map.disableMapNavigation();
          tb.activate(Draw.FREEHAND_POLYGON);
        }

        function addGraphic(evt) {
          map.graphics.clear()

          map.graphics.add(new Graphic(evt.geometry, fillSymbol));

          polygon = new Polygon(evt.geometry)

          var query = new Query();
          query.geometry = polygon.getExtent();

          featureLayer.queryFeatures(query, selectInBuffer);
        }

        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];

          for (var i = 0; i < features.length; i++) {
            feature = features[i];
            if(polygon.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;

          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(features, index){
              for(var i = 0; i < features.length; i++){
                  console.log(features[i].geometry.x + ", " + features[i].geometry.y)
              }
          })
        }

      });
    </script>
  </head>

  <body>

    <div id="mapDiv"></div>

  </body>
</html>
DharmaRajan
Occasional Contributor

Thanks a lot Jake. Your code will help me lot.

0 Kudos
by Anonymous User
Not applicable

Hi,

you can use one tile layer with display and one featureless layer,

which contains only data not symbol and label.  

Please check!

DharmaRajan
Occasional Contributor

Thanks avinash. But I'm having 100 tile layers and each has different service end point. So have to use separate feature layer for each tile layer? My requirement is, let users to select the features on map. At selection end, I have to show the attributes of the selected features.