AnsweredAssumed Answered

Using Snapping with Graphic Layers (select by Feature Layers)

Question asked by 96213@charlottenc.gov_charlotte on Mar 26, 2018
Latest reply on Apr 9, 2018 by 96213@charlottenc.gov_charlotte

EDIT: I believe using the selectByFeatureLayers is ultimately what I need to leverage. If I can get this to enforce snapping, then I'll be able to get there on my own. I'm currently testing in the esri sandbox. Below is my app's source code.

 

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Layer in a map service - [ON-DEMAND]</title>

  <link rel="stylesheet" href="https://js.arcgis.com/3.23/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.23/esri/css/esri.css" />

  <script src="https://js.arcgis.com/3.23/"></script>
  <script>
    var map;

    require([
      "esri/InfoTemplate",
      "esri/map",
      "esri/layers/FeatureLayer",
      "esri/symbols/SimpleFillSymbol",
      "esri/symbols/SimpleLineSymbol",
      "esri/tasks/query",
      "esri/toolbars/draw",
      "dojo/dom",
      "dojo/on",
      "dojo/parser",
      "dojo/_base/array",
      "esri/Color",
      "dijit/form/Button",
      "dojo/domReady!"
    ],
      function (
        InfoTemplate, Map, FeatureLayer, SimpleFillSymbol, SimpleLineSymbol,
        Query, Draw, dom, on, parser, arrayUtil, Color
      ) {

        parser.parse();

        var selectionToolbar, featureLayer;

        map = new Map("map", {
          basemap: "topo",
          center: [-80.8431, 35.2271],
          zoom: 15
        });

        map.on("load", initSelectToolbar);

        var fieldsSelectionSymbol =
          new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
          new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));

//        var content = "<b>Street Name</b>: ${WHOLESTNAME}" +
//                     "<br><b>Street Range</b>: ${FULL_NAME}" +
//                     "<br><b>Length</b>: ${SHAPE.STLength}";
  //      var infoTemplate = new InfoTemplate("${WHOLESTNAME}", content);

        featureLayer = new FeatureLayer("http://maps.ci.charlotte.nc.us/arcgis/rest/services/NBS/StreetAdoption/MapServer/2",
          {
            mode: FeatureLayer.MODE_ONDEMAND,
           // infoTemplate: infoTemplate,
            outFields: ["*"]
          });

        featureLayer.on("selection-complete", sumMilage);
        featureLayer.on("selection-clear", function () {
          dom.byId('messages').innerHTML = "<i>No Selected Roads</i>";
        });
        map.addLayer(featureLayer);

        on(dom.byId("selectFieldsButton"), "click", function () {
          selectionToolbar.activate(Draw.POLYLINE);
        });

        on(dom.byId("clearSelectionButton"), "click", function () {
          featureLayer.clearSelection();
        });

        function initSelectToolbar (event) {
          selectionToolbar = new Draw(event.map);
          var selectQuery = new Query();

          on(selectionToolbar, "DrawEnd", function (geometry) {
            selectionToolbar.deactivate();
            selectQuery.geometry = geometry;
            featureLayer.selectFeatures(selectQuery,
              FeatureLayer.SELECTION_NEW);
          });
        }

        function sumMilage (event) {
          var milageSum = 0;
          //summarize the cumulative gas production to display
          arrayUtil.forEach(event.features, function (feature) {
            milageSum += feature.attributes.STLength;
          });
          dom.byId('messages').innerHTML = "<b>Total Length of Segments Requested: " +
                                            milageSum + " Miles Selected </b>";
        }
      });
  </script>
</head>

<body class="claro">
  <button id="selectFieldsButton" data-dojo-type="dijit/form/Button">Select Roads</button>
  <button id="clearSelectionButton" data-dojo-type="dijit/form/Button">Clear Selection</button><br>
  <div id="map" style="position: relative; width:100%; height:500px; border:1px solid #000;"></div>
  <span id="messages"></span>
</body>

</html>

 

Robert Scheitlin, GISP, any ideas?

 

Hello!

 

I'm looking to implement, what I imagined, would be a fairly straightforward workflow. End goal: to allow a user in a web app to select contiguous highway segments and return/pass the overlain segments ObjectIDs. The segments must, however, be longer than five miles. 

 

I've run into some issues though. I first tried building a Geoprocessing service that could handle this, but was not able to configure the service to run optimally with our data (executing summary-statistics and if/then branch logic on the service has a lot of overhead), so I turned to JS.

 

I first tried using the measurement widget in JS with snapping enabled. I got to the point where users could select contiguous roadways that would snap to features (I'd prefer they trace (i.e. non-linear features), but this will do for now). However I wasn't able to pass these linear geometries so that they could be used for an identify task so I tried something else.

 

I then tried to use the draw widget to create a linear feature, export its length after each vertex was added (not ideal) and then pass those geometries as well. No luck there either.

 

After I get this up and running, I know the next hurdle will be to apply a threshold for identify functions. Since roads intersect, if I select a straight segment, the perpendicular roads that cross that feature will also be returned. But I'm not there yet.

 

Any and all help is welcome and appreciated!

Outcomes