bforbhavin

Snapping and tracing to highlight linear features

Discussion created by bforbhavin on Feb 12, 2018

Is there any example to snap and trace linear features then highlight the segments which have been overlapped on the trace?

 

I tried to use SnappingManager class and Draw Polyline tool but it doesn't work perfectly. e.g. If I trace using polyline drawing tool on linear features (with snapping enabled on the map) and query at feature layer by passing snapped geometry to find out intersected (or overlapped) segment of the polyline feature layer then it doesn't give the result. If the trace is very perfect then I would get the result.

 

Considering that the trace will not be perfect always and there is some tolerance applies. In that case, I tried to use buffer query. Then it ends up in extra highlights of linear feature on the map. See the following code and suggest if there is better way to implement this scenario.

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title></title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.17/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.17/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      #map{ margin: 0; padding: 0; }
      #controls {
        position: absolute;
        height: 80px;
        font-family: arial;
        bottom: 10px;
        margin: 5px;
        padding: 5px;
        z-index: 40;
        background: #fff;
        color: #444;
        width: 440px;
        left: 10px;
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; }
      .label { display: inline-block; width: 140px; }
    </style>

    <script src="http://js.arcgis.com/3.17/"></script>
    <script>
      var app = {};

      require([
        "dojo/parser", "dojo/promise/all", "dojo/_base/connect",
        "esri/Color", "dojo/_base/array", "dojo/dom",
        "esri/config", "esri/map", "esri/geometry/Extent",
        "esri/symbols/SimpleFillSymbol", "esri/layers/ArcGISDynamicMapServiceLayer",
  'esri/tasks/GeometryService', 'esri/tasks/ProjectParameters',
        "esri/tasks/query", "esri/tasks/QueryTask", "esri/dijit/Popup",
  'esri/layers/FeatureLayer',
  'esri/dijit/InfoWindow',
  "dojo/dom-construct",
  'esri/graphicsUtils',
  "dijit/form/Button",
  'esri/toolbars/draw',
  'esri/symbols/SimpleLineSymbol',
  'esri/symbols/SimpleMarkerSymbol',
  'esri/SnappingManager',
  'esri/layers/GraphicsLayer',
  'esri/graphic',
  'esri/tasks/BufferParameters',
  'esri/geometry/geometryEngine',
        "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
        "dojo/domReady!"
      ], function(
        parser, all, connect,
        Color, arrayUtils, dom,
        esriConfig, Map, Extent,
        SimpleFillSymbol, ArcGISDynamicMapServiceLayer,
  GeometryService, ProjectParameters,
        Query, QueryTask, Popup, FeatureLayer, InfoWindow, domConstruct, graphicsUtils, Button, Draw, SimpleLineSymbol, SimpleMarkerSymbol, SnappingManager, GraphicsLayer, Graphic,
  BufferParameters, geometryEngine
      ) {
        // create layout dijits
        parser.parse();
        // specify proxy for request with URL lengths > 2k characters
        esriConfig.defaults.io.proxyUrl = "/proxy/";

        var vMap = new Map("map", {
   basemap: 'gray'
   }),
   
   vMapServiceUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer",
   
   vDynamicLayer = new ArcGISDynamicMapServiceLayer(vMapServiceUrl, {
   'id': 'AGSDynamicMapServiceLayer'
   }),
   vDrawToolbar,
   vMyButton;
       
  vMap.addLayer(vDynamicLayer);

  vMyButton = new Button({
   label: "Click me!",
   onClick: function(){
   
    var vFeatureLayer = new FeatureLayer(vMapServiceUrl + '/1', {
     outFields: ['*'],
     opacity: 0,
     autoGeneralize: false
    });
    
    vMap.addLayer(vFeatureLayer);
    
    
    vMap.enableSnapping({
     snapPointSymbol: new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([255,0,0]), 1),new Color([0,255,0,0.25])),
     tolerance: 30,
     alwaysSnap: true,
     layerInfos: [{
      'layer': vFeatureLayer
     }]
    });
     
    vDrawToolbar = new Draw(vMap);
    vDrawToolbar.on('draw-complete', drawComplete);
    vDrawToolbar.activate(Draw.POLYLINE);
    
   }
  }, "progButtonNode").startup();
  
  vMap.on('layer-add-result', function(layer) {
   if (layer.layer.id == 'AGSDynamicMapServiceLayer') {
    var vGeometryService = new GeometryService("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer"),
     vProjectParameters = new ProjectParameters();
     
    vProjectParameters.geometries = [layer.layer.initialExtent];
    vProjectParameters.outSR = vMap.spatialReference;
    vGeometryService.project(vProjectParameters, function (geometry) {
     vMap.setExtent(geometry[0], true);
    });
   }
  });
  
  function drawComplete(evt) {
   
   addGraphic(evt.geometry, true);
   
   //perform buffer search
   var vGeometryService = new GeometryService("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer"),
    vBufferParameters = new BufferParameters();
    
   vBufferParameters.distances = [(vMap.extent.getWidth() / vMap.width) * 5];
   vBufferParameters.geometries = [evt.geometry];
   vBufferParameters.outSpatialReference = vMap.spatialReference;
   vGeometryService.buffer(vBufferParameters, function(bufferGeometries){
    var vQuery = new Query();
    
    vQuery.geometry = bufferGeometries[0];
    vQuery.outFields = ['*'];
    vQuery.returnGeometry = true;
    vQuery.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
    vQuery.where = '1=1';
    
    
    var vQueryTask = new QueryTask(vMapServiceUrl + '/1');
    vQueryTask.execute(vQuery, function(results){
     var vFeatures = results.features;
     for (var i = 0; i < vFeatures.length; i++) {
      //use geometry engine to intersect the feature geometry
      var vIntersectedGeometry = geometryEngine.intersect(vFeatures[i].geometry, bufferGeometries[0]);
      addGraphic(vIntersectedGeometry);
     }
     
     vDrawToolbar.deactivate();
    });
   });
   
   function addGraphic(geometry, isSnap) {
    var vColor = new Color([0,255,197]),
     vSize = 4;
    
    if (isSnap) {
     vColor = new Color([200,176,23]);
     vSize = 10;
    }
    var vGraphic = new Graphic(geometry, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, vColor, vSize)),
     vGraphicsLayer;
   
    if (vMap.getLayer('measurelayer') == null) {
     vGraphicsLayer = new GraphicsLayer({
      'id': 'measurelayer'
     });
    } else {
     vGraphicsLayer = vMap.getLayer('measurelayer');
    }
    vGraphicsLayer.add(vGraphic);
    vMap.addLayer(vGraphicsLayer);
   }
  }
      });
    </script>
  </head>
 
  <body class="tundra">
    <div data-dojo-type="dijit.layout.BorderContainer"
         data-dojo-props="design:'headline',gutters:false"
         style="width: 100%; height: 100%; margin: 0;">
      <div id="map"
           data-dojo-type="dijit.layout.ContentPane"
           data-dojo-props="region:'center'">
       
        <div id="controls">
          <h3>Polyline drawing tool</h3>
          <div id="results">
   <button id="progButtonNode" type="button"></button>
  </div>
        </div>
  
      </div>
    </div>
  </body>
</html>

Outcomes