load map and 'goto' specific feature (polyline)

1594
6
Jump to solution
11-07-2021 07:47 AM
AwesomeEvan
Occasional Contributor

Hey I'm simply looking to load a map and pan/zoom to a feature.

Here is the actual page. https://data.orangeville.ca/Apps/CrossingGuards/index.html?objectid=1

I'm looking for help to get the inline map to 'goto' or pan and zoom a feature based on object id

I'm getting the objectid from a url parameter using

        var getUrlParameter = function getUrlParameter(sParam) {  
          var sPageURL = decodeURIComponent(window.location.search.substring(1)),  
            sURLVariables = sPageURL.split('&'),  
            sParameterName,  
            i;  
        
          for (i = 0; i < sURLVariables.length; i++) {  
            sParameterName = sURLVariables[i].split('=');  
        
            if (sParameterName[0] === sParam) {  
              return sParameterName[1] === undefined ? true : sParameterName[1];  
            }  
          }  
        };   

 

and calling it using >>> getUrlParameter('objectid')

 

also the map has 4 layers, the one to search is layer 3 of 4 called 'Crossing Guards VIEW'

 

here is my codepen code just for the map for testing, with the api key removed... 

 

<!--

To run this demo, you need to replace 'YOUR_API_KEY' with an API key from the ArcGIS Developer dashboard.

Sign up for a free account and get an API key.

https://developers.arcgis.com/documentation/mapping-apis-and-services/get-started/

 --><html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <title>ArcGIS API for JavaScript Tutorials: Display a map</title>

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

    <link rel="stylesheet" href="https://js.arcgis.com/4.21/esri/themes/light/main.css">
    <script src="https://js.arcgis.com/4.21/"></script>

    <script>
      require(["esri/config","esri/WebMap", "esri/views/MapView","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,WebMap, MapView, ScaleBar, Legend) {

        esriConfig.apiKey = "API_KEY_HERE";

      const webmap = new WebMap({
        portalItem: {
          id: "4170f5e65bd8409896a906264e4c2c87"
        }
      });

        const view = new MapView({
          map: webmap,
          container: "viewDiv" // Div element
        });

const scalebar = new ScaleBar({
        view: view
      });

      view.ui.add(scalebar, "bottom-left");        

        var parcelExtent = response.features[0].geometry.extent.clone().expand(0.5);
view.goTo(parcelExtent);
        
        
      });
    </script>

  </head>
  <body>
    <div id="viewDiv"></div>
  </body>
</html>

 

 

thanks for any assistance

0 Kudos
2 Solutions

Accepted Solutions
MichaelBoschert
New Contributor III

Why don't you use the map and additionally add the layer? After zooming in or any other action just  remove the layer again.

View solution in original post

AwesomeEvan
Occasional Contributor

Awesome that was enough advice to get me there... here's what worked for me... it adds the layer to the map, zooms to it, then removes it... which also creates a better user experience because it doesn't snap back the map everytime you try to pan or zoom away...

 

      require(["esri/config","esri/Map","esri/WebMap", "esri/views/MapView","esri/layers/FeatureLayer","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,Map,WebMap, MapView, FeatureLayer, ScaleBar, Legend) {
        esriConfig.apiKey = "YOUR_KEY_HERE";

        const webmap = new WebMap({
          portalItem: {
            id: "4170f5e65bd8409896a906264e4c2c87"
          }        
        });
      

        const view = new MapView({
          map: webmap,
          container: "viewDiv" // Div element
        });


        const layer = new FeatureLayer({
          // URL to the service
          url: "https://services3.arcgis.com/pCmV4YWmyIH9CmGq/ArcGIS/rest/services/Crossing_Guards_VIEW/FeatureServer/0",
          definitionExpression: "OBJECTID = " + getUrlParameter('objectid')

        });
        view.map.add(layer);

        const scalebar = new ScaleBar({
        view: view        
        });

        view.ui.add(scalebar, "bottom-left");        

        view.whenLayerView(layer).then(function(layerView){
          layerView.watch("updating", function(val){
            // wait for the layer view to finish updating
            if(!val){
              layerView.queryExtent().then(function(response){
                // go to the extent of all the graphics in the layer view
                view.goTo({target:response.extent, zoom: 17});
                view.map.remove(layer);
              });              
            }
          });
        });


        
      });

 

View solution in original post

0 Kudos
6 Replies
MichaelBoschert
New Contributor III

Hey,

@AwesomeEvan 

1. Add the Layer to map while using a definitionExpression
2. Wait for the LayerView and use the queryExtent Function

view.whenLayerView(layer).then(function(layerView) {
              layerView.watch("updating", function(val) {
                if (!val) {
                  layerView.queryExtent().then(function(response) {
                  view.goTo(response.extent);
                  });
                }
              });
            });

 

0 Kudos
AwesomeEvan
Occasional Contributor

So, I had this solution previously, however there is then only the one layer on the map...

The reason I'm trying to add the whole map is because I want all the layers and stylings from it. Then zoom to the one feature in the specific layer using the url parameter value.

Any suggestions for this setup?

 

 

Otherwise, I can just add the other layers to the map as well, but then styling them also just seems like way more effort than if I would just query and zoom on an existing layer in the map.

0 Kudos
MichaelBoschert
New Contributor III

Why don't you use the map and additionally add the layer? After zooming in or any other action just  remove the layer again.

AwesomeEvan
Occasional Contributor

Awesome that was enough advice to get me there... here's what worked for me... it adds the layer to the map, zooms to it, then removes it... which also creates a better user experience because it doesn't snap back the map everytime you try to pan or zoom away...

 

      require(["esri/config","esri/Map","esri/WebMap", "esri/views/MapView","esri/layers/FeatureLayer","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,Map,WebMap, MapView, FeatureLayer, ScaleBar, Legend) {
        esriConfig.apiKey = "YOUR_KEY_HERE";

        const webmap = new WebMap({
          portalItem: {
            id: "4170f5e65bd8409896a906264e4c2c87"
          }        
        });
      

        const view = new MapView({
          map: webmap,
          container: "viewDiv" // Div element
        });


        const layer = new FeatureLayer({
          // URL to the service
          url: "https://services3.arcgis.com/pCmV4YWmyIH9CmGq/ArcGIS/rest/services/Crossing_Guards_VIEW/FeatureServer/0",
          definitionExpression: "OBJECTID = " + getUrlParameter('objectid')

        });
        view.map.add(layer);

        const scalebar = new ScaleBar({
        view: view        
        });

        view.ui.add(scalebar, "bottom-left");        

        view.whenLayerView(layer).then(function(layerView){
          layerView.watch("updating", function(val){
            // wait for the layer view to finish updating
            if(!val){
              layerView.queryExtent().then(function(response){
                // go to the extent of all the graphics in the layer view
                view.goTo({target:response.extent, zoom: 17});
                view.map.remove(layer);
              });              
            }
          });
        });


        
      });

 

0 Kudos
KenBuja
MVP Esteemed Contributor

Is your response geometry a point? The goTo method won't zoom to its extent, since a point doesn't have an extent. You'll have to set the scale for the zoom.

view.goTo({
  target: geometry,
  scale: yourScale,
});
0 Kudos
MichaelBoschert
New Contributor III

Hey @KenBuja 

no, my response is a area...

Thanks for the supplement.

0 Kudos