How to get get name of hospital or street in particular area when draw polyline through Javascript ArcGIS Api?

328 views Asked by At

Actually I am using ArcGIS API for JavaScript 4.7. I want to get name of hospital or street in particular area when draw polyline . How to achieve that ?

Suppose I draw a area through polyline. In this area there are some hospital or street ..etc . Now I need the name of hospitals or street within that area.

the result look like :- [street1,street2, ...] , [hospital1,hospital2, ...]

Update error :-esri.layers.graphics.QueryEngine", message: "Unsupported query" details: undefined} this error appear when try to collect hospital name in selected area the user can draw multi polygon,polyline

 require([
  "esri/views/MapView",
  "esri/Map",
   "esri/Basemap",
"esri/layers/TileLayer",
"esri/layers/MapImageLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/geometryEngine",
"esri/widgets/CoordinateConversion",
"esri/geometry/support/webMercatorUtils",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/config",
"esri/core/urlUtils",
"esri/widgets/Search",
"esri/tasks/Locator",
"esri/layers/FeatureLayer",
"esri/widgets/Expand",
"dojo/domReady!" 

], function (
MapView, Map, Basemap, TileLayer, MapImageLayer,
SketchViewModel,
 geometryEngine,
 CoordinateConversion, 
 webMercatorUtils,
 Graphic, GraphicsLayer, esriConfig, 
 urlUtils,Search,Locator,FeatureLayer,Expand
  ) {

const  hospitals =new FeatureLayer({
    url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/Feat


  ureServer/0',
    renderer: {
      type: 'simple',
      symbol: {
        type: 'text',
        color: 'green',
        text: '\ue687',
        font: {
          size: 16,
          family: 'CalciteWebCoreIcons'
        },
        haloColor: 'white',
        haloSize: 2
      }
    },
    outFields: ['*']
  });
  var tempGraphicsLayer = new GraphicsLayer();
  var saveGraphicsLayer = new GraphicsLayer();    
  var updateGraphic;
  let hospitalsLayerView = null;
  let highlight = null;
             
    var myMap;

     myMap = new Map({
        basemap: "streets", //satellite
        layers: [hospitals,tempGraphicsLayer, saveGraphicsLayer]
    });


  view = new MapView({
    center: [-75.1683665, 39.951817],// [54.49, 24.41] long, lat
    container: "viewDiv",
    map: myMap,
    zoom: 14
  });
   var ccWidget = new CoordinateConversion({
    view: view
});

 const searchWidget = new Search({
sources: [{
    locator: new Locator({ url: 
  "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"}),
  countryCode:"AE",
  singleLineFieldName: "SingleLine",
  name: "Custom Geocoding Service",
  localSearchOptions: {
    minScale: 300000,
    distance: 50000
  },
  placeholder: "Find a place",
  maxResults: 3,
  maxSuggestions: 6,
  suggestionsEnabled: true,
  minSuggestCharacters: 0
 }],
 view: view,
 includeDefaultSources: false
 });

view.ui.add(searchWidget, {
           position: "top-right",
           index: 1
            });

view.ui.add(ccWidget, "bottom-left");
view.ui.add("topbar", "top-right");
var pointSymbol = { // symbol used for points
    type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
    style: "square",
    color: "#8A2BE2",
    size: "16px",
    outline: { // autocasts as new SimpleLineSymbol()
        color: [255, 255, 255],
        width: 3 // points
    }
}
var polylineSymbol = { // symbol used for polylines
    type: "simple-line", // autocasts as new SimpleLineSymbol()
    color: "#8A2BE2",
    width: "4",
    style: "dash"
}
var polygonSymbol = { // symbol used for polygons
    type: "simple-fill", // autocasts as new SimpleFillSymbol()
    color: "rgba(138,43,226, 0.8)",
    style: "solid",
    outline: {
        color: "white",
        width: 1
    }
}

var polygonBoundrySymbol = { // symbol used for polygons
    type: "simple-line", // autocasts as new SimpleFillSymbol()
    color: "red"
}    
  
let drawBoundry = function(){
    let boundryJson = $v('P0_USER_LIMITS');
    if(boundryJson){
        let boundry = Graphic.fromJSON(JSON.parse(boundryJson));            
        boundry.symbol = polygonBoundrySymbol;

        tempGraphicsLayer.add(boundry);
        return boundry;
    }         
}


view.when(function () {
    $('.esri-view-root').on('click', '.esri-print__export-button', 
    function(e){

        e.preventDefault();
        saveExportedImg();
    });

    // create a new sketch view model
    var sketchViewModel = new SketchViewModel({
        view: view,
        layer: tempGraphicsLayer,
        pointSymbol: pointSymbol,
        polylineSymbol: polylineSymbol,
        polygonSymbol: polygonSymbol
    });
    
    hospitals.when(function () {
    view.whenLayerView(hospitals).then(function (layerView){
      hospitalsLayerView = layerView;
    })
  })
  .catch(errorCallback);
       sketchViewModel.on("draw-complete", addGraphic);
    sketchViewModel.on("update-complete", addGraphic);
    sketchViewModel.on("update-cancel", addGraphic);
    sketchViewModel.on("vertex-add", addGraphic);

    function addGraphic(evt) {
       // console.log ('graphic.geometry',evt.geometry)
        //let currentGraphic = popActiveGraphic(tempGraphicsLayer);
        let currentGraphic = saveGraphicsLayer.graphics.items.pop();
        selectFeatures(evt.geometry);
        var geometry = evt.geometry;
        var vertices = evt.vertices;
        var symbol;
        var attr = {
            Name: "Selected Area",
            X: $v('P24_X'),
            Y: $v('P24_Y')
        };
        // Choose a valid symbol based on return geometry
        switch (geometry.type) {
            case "point":
                symbol = pointSymbol;
                break;
            case "polyline":
                symbol = polylineSymbol;
                break;
            default:
                symbol = polygonSymbol;
                break;
        }

        geometry =  webMercatorUtils.webMercatorToGeographic(geometry)

            var within = true;
        //}
                    
        if(within){
            
            let graphic = new Graphic({
                    geometry: geometry,
                    symbol: symbol,
                    //attributes: attr,
                    popupTemplate: {
                        title: "{Name}",
                        content: [{
                            type: "fields",
                            fieldInfos: [{
                                fieldName: "X"
                            }, {
                                fieldName: "Y"
                            }]
                        }]
                   }
            });                          
            tempGraphicsLayer.add(graphic);
            if(currentGraphic){
               geometry.rings.forEach( ring => 
  currentGraphic.geometry.addRing(ring));
                   graphic = currentGraphic;                    
            }                 
            var saveObj = graphic.toJSON();                           
            $x('P24_JSON').value = JSON.stringify(saveObj);
            saveGraphicsLayer.add(graphic);
        } else {
            apex.message.alert('&G_MAP_BOUNDRY_MSG.');
        }
        updateGraphic = null;
    }
    

    window.loadGraphic = function(polygon){
        if(polygon===undefined || polygon === ''){
            console.error('no polygon');
        } else {
            
            
            var graphic = Graphic.fromJSON(JSON.parse(polygon));  
            if (graphic.geometry){
               addMultiGraph(graphic);
               view.center.longitude = graphic.geometry.centroid.longitude;
               view.center.latitude = graphic.geometry.centroid.latitude;
               view.center = [graphic.geometry.centroid.longitude, 
 graphic.geometry.centroid.latitude];
               view.zoom = 12;
            }
        }
        
    }
    
    loadGraphic($v('P24_JSON')); 
    
    // *************************************
    // activate the sketch to create a point
    // *************************************
    var drawPointButton = document.getElementById("pointButton");
    drawPointButton.onclick = function () {
        // set the sketch to create a point geometry
        sketchViewModel.create("point");
        setActiveButton(this);
    };
    // ****************************************
    // activate the sketch to create a polyline
    // ****************************************
    var drawLineButton = document.getElementById("polylineButton");
    drawLineButton.onclick = function () {
        // set the sketch to create a polyline geometry
        sketchViewModel.create("polyline");
        setActiveButton(this);
    };
    // ***************************************
    // activate the sketch to create a polygon
    // ***************************************
    var drawPolygonButton = document.getElementById("polygonButton");
    drawPolygonButton.onclick = function () {
        // set the sketch to create a polygon geometry
        sketchViewModel.create("polygon");
        setActiveButton(this);
    };
    // ***************************************
    // activate the sketch to create a rectangle
    // ***************************************
    var drawRectangleButton = document.getElementById(
        "rectangleButton");
    drawRectangleButton.onclick = function () {
        // set the sketch to create a polygon geometry
        sketchViewModel.create("rectangle");
        setActiveButton(this);
    };

    document.getElementById("resetBtn").onclick = function () {
       sketchViewModel.reset();
      tempGraphicsLayer.removeAll();
      saveGraphicsLayer.removeAll();
      setActiveButton();
      drawBoundry();
    };

    function setActiveButton(selectedButton) {
        // focus the view to activate keyboard shortcuts for sketching
        view.focus();
        var elements = document.getElementsByClassName("active");
        for (var i = 0; i < elements.length; i++) {
            elements[i].classList.remove("active");
        }
        if (selectedButton) {
            selectedButton.classList.add("active");
        }
    }
    // ************************************************************************************
    // set up logic to handle geometry update and reflect the update on "tempGraphicsLayer"
    // ************************************************************************************
    function setUpClickHandler() {
        view.on("click", function (evt) {
            view.hitTest(evt).then(function (response) {
                var results = response.results;
                // Found a valid graphic                    
                if (results.length && results[results.length - 1]
                    .graphic) {
                    // Check if we're already editing a graphic
                    if (!updateGraphic) {
                        // Save a reference to the graphic we intend to update
                        updateGraphic = results[results.length - 1].graphic;
                        // Remove the graphic from the GraphicsLayer
                        // Sketch will handle displaying the graphic while being updated
                        tempGraphicsLayer.remove(updateGraphic);
                        sketchViewModel.update(updateGraphic.geometry);
                    }
                }
            });
        });
    } 
    
function selectFeatures(geometry) {
    
    if (hospitalsLayerView) {
        
   let query = hospitals.createQuery();
   query.returnGeometry = true;
  query.outFields = ["*"];
     hospitalsLayerView.queryFeatures(query)
        .then(function (results) {
            console.log ('results.features',results.features);
          const graphics = results.features;
          if (highlight) {
            highlight.remove();
          }
          highlight = hospitalsLayerView.highlight(graphics);
         console.log ('hospitL',graphics.map(g => 
g.attributes.HOSPITAL_NAME).join(','));
          // namesDiv.innerHTML = graphics.map(g => 
      g.attributes.HOSPITAL_NAME).join(',');
        }).catch(errorCallback);
        
    }
  }
  
    function errorCallback(error) {
    console.log('error:', error);
  }
            // ************************************************************************************
    // returns graphic object if drawn on the map to contcat new graphics to it
    // ************************************************************************************
    function popActiveGraphic(graphicsLayer){            
        let length = graphicsLayer.graphics.length;
        let count = 0;
        if($v('P0_USER_LIMITS').length > 0){
            count++;
        }
        if(length > count){ //active drawing detected
            let result = graphicsLayer.graphics.items[length-1];
            graphicsLayer.remove(result);
            return result;
        }
    }
});
});

Thanks,

1

There are 1 answers

1
cabesuon On BEST ANSWER

Well, here I made an example for you merging some ArcGIS examples.

Just select the hospitals using a polygon. The selected hospitals are highlighted and the names display in the text section.

In your case do the same thing with any other layer you want to query to get features data.

<html>

<head>
  <meta charset='utf-8'>
  <meta name='viewport' content='initial-scale=1, maximum-scale=1, user-scalable=no'>
  <title>Select Feature With Polygon</title>
  <style>
    html,
    body {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 400px;
      width: 100%;
    }
    #namesDiv {
      margin: 10px;
      height: 200px;
      width: 100%;
      font-style: italic;
      font-weight: bold;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 16px;
      color: green;
      overflow: auto;
    }
  </style>

  <link rel='stylesheet' href='https://js.arcgis.com/4.15/esri/css/main.css'>
  <script src='https://js.arcgis.com/4.15/'></script>

  <script>
    require([
      'esri/Map',
      'esri/views/MapView',
      'esri/layers/FeatureLayer',
      'esri/layers/GraphicsLayer',
      'esri/widgets/Sketch/SketchViewModel',
      'esri/Graphic',
      'esri/widgets/Expand'
    ], function (
      Map,
      MapView,
      FeatureLayer,
      GraphicsLayer,
      SketchViewModel,
      Graphic,
      Expand
    ) {
      let hospitalsLayerView = null;
      let highlight = null;

      const hospitals = new FeatureLayer({
        url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/FeatureServer/0',
        renderer: {
          type: 'simple',
          symbol: {
            type: 'text',
            color: 'green',
            text: '\ue687',
            font: {
              size: 16,
              family: 'CalciteWebCoreIcons'
            },
            haloColor: 'white',
            haloSize: 2
          }
        },
        outFields: ['*']
      });

      const polygonGraphicsLayer = new GraphicsLayer();

      const map = new Map({
        basemap: 'streets',
        layers: [hospitals, polygonGraphicsLayer]
      });

      const view = new MapView({
        container: 'viewDiv',
        map: map,
        center: [-75.1683665, 39.951817],
        zoom: 14
      });

      const sketchViewModel = new SketchViewModel({
        view: view,
        layer: polygonGraphicsLayer,
        pointSymbol: {
          type: 'simple-marker',
          color: [255, 255, 255, 0],
          size: '1px',
          outline: {
            color: 'gray',
            width: 0
          }
        }
      });

      sketchViewModel.on('create', function (event) {
        if (event.state === 'complete') {
          polygonGraphicsLayer.remove(event.graphic);
          selectFeatures(event.graphic.geometry);
        }
      });

      hospitals.when(function () {
        view.whenLayerView(hospitals).then(function (layerView){
          hospitalsLayerView = layerView;
        })
      })
      .catch(errorCallback);

      const namesDiv = document.getElementById('namesDiv');

      view.ui.add('select-by-polygon', 'top-left');
      const selectButton = document.getElementById('select-by-polygon');

      selectButton.addEventListener('click', function () {
        clearUpSelection();
        sketchViewModel.create('polygon');
      });

      function selectFeatures(geometry) {
        view.graphics.removeAll();
        if (hospitalsLayerView) {
          const query = {
            geometry: geometry,
            outFields: ['*']
          };

          hospitalsLayerView
            .queryFeatures(query)
            .then(function (results) {
              const graphics = results.features;
              if (highlight) {
                highlight.remove();
              }
              highlight = hospitalsLayerView.highlight(graphics);
              namesDiv.innerHTML = graphics.map(g => g.attributes.HOSPITAL_NAME).join(',');
            })
            .catch(errorCallback);
        }
      }

      function clearUpSelection() {
        view.graphics.removeAll();
        namesDiv.innerHTML = null;
      }

      function errorCallback(error) {
        console.log('error:', error);
      }

    });
  </script>
</head>

<body>
  <div id='viewDiv'>
    <div
      id="select-by-polygon"
      class="esri-widget esri-widget--button esri-widget esri-interactive"
      title="Select hospitals by polygon"
    >
      <span class="esri-icon-checkbox-unchecked"></span>
    </div>
  </div>
  <div id="namesDiv"></div>
</body>

</html>