MapView goto not working for queryFeatures() result?

2124
2
Jump to solution
01-04-2019 03:58 PM
VincentLantaca1
New Contributor III

I am trying to write code that will query from a FeatureLayer using queryFeatures() and then call MapView goTo to zoom to that result. I am verifying that the query matches the attributes of the expected attributes when I query for a single objectid, but MapView goTo doesn't work when I try to zoom to the Graphics from the query.

However, if I create my own Graphics manually, it works as expected.

I have created an example with two buttons demonstrating my issue below. One button "workingButton" correctly zooms to some manually created Graphics. The other "notWorkingButton" tries to zoom to the result of a query, but doesn't work.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Street Sweeping Routes</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

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

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

  <script>
    var app = {};


    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/widgets/Legend",
      "esri/PopupTemplate",
      "esri/Graphic",
      "dojo/domReady!"
    ], function(
      Map, MapView, FeatureLayer, Legend, PopupTemplate, Graphic
    ) {
      
      var fields = [
      {
        name: "OBJECTID",
        alias: "OBJECTID",
        type: "oid"
      },
      {
        name: "Street_seg",
        alias: "Street_seg",
        type: "integer"
      },
      {
        name: "Route",
        alias: "Route",
        type: "string"
      },
      {
        name: "Miles",
        alias: "Miles ",
        type: "double"
      },
      {
        name: "Drive_time",
        alias: "Drive_time",
        type: "double"
      },
      {
        name: "Av_side",
        alias: "Av_side",
        type: "string"
      },
      {
        name: "Low_addr",
        alias: "Low_addr",
        type: "integer"
      },
      {
        name: "High_addr",
        alias: "High_addr",
        type: "integer"
      },
      {
        name: "St_prefix",
        alias: "St_prefix",
        type: "string"
      },
      {
        name: "St_name",
        alias: "St_name",
        type: "string"
      },
      {
        name: "St_type",
        alias: "St_type",
        type: "string"
      },
      {
        name: "St_suffix",
        alias: "St_suffix",
        type: "string"
      },
      {
        name: "Mode",
        alias: "Mode",
        type: "string"
      },
      {
        name: "Meander",
        alias: "Meander",
        type: "smallinteger"
      },
      {
        name: "LoopNum",
        alias: "LoopNum",
        type: "integer"
      },
      {
        name: "ServiceDay",
        alias: "ServiceDay",
        type: "smallinteger"
      },
      {
        name: "ID",
        alias: "ID",
        type: "double"
      },
      {
        name: "Street_ID",
        alias: "Street_ID",
        type: "double"
      },
      {
        name: "ServiceSeq",
        alias: "ServiceSeq",
        type: "integer"
      },
      {
        name: "Day",
        alias: "Day",
        type: "string"
      },
      {
        name: "Schedule",
        alias: "Schedule",
        type: "string"
      },
      {
        name: "Shape",
        alias: "Shape",
        type: "geometry"
      },
      {
        name: "Shape.STLength()",
        alias: "Shape.STLength()",
        type: "double"
      }
      ];

      pTemplate = new PopupTemplate({
        content: [{
          type: "fields",
          fieldInfos: [{
            fieldName: "OBJECTID",
            label: "OBJECTID",
          },{
            fieldName: "Street_seg",
            label: "Street_seg",
          },{
            fieldName: "Route",
            label: "Route",
          },{
            fieldName: "Miles",
            label: "Miles ",
          },{
            fieldName: "Drive_time",
            label: "Drive_time",
          },{
            fieldName: "Av_side",
            label: "Av_side",
          },{
            fieldName: "Low_addr",
            label: "Low_addr",
          },{
            fieldName: "High_addr",
            label: "High_addr",
          },{
            fieldName: "St_prefix",
            label: "St_prefix",
          },{
            fieldName: "St_name",
            label: "St_name",
          },{
            fieldName: "St_type",
            label: "St_type",
          },{
            fieldName: "St_suffix",
            label: "St_suffix",
          },{
            fieldName: "Mode",
            label: "Mode",
          },{
            fieldName: "Meander",
            label: "Meander",
          },{
            fieldName: "LoopNum",
            label: "LoopNum",
          },{
            fieldName: "ServiceDay",
            label: "ServiceDay",
          },{
            fieldName: "ID",
            label: "ID",
          },{
            fieldName: "Street_ID",
            label: "Street_ID",
          },{
            fieldName: "ServiceSeq",
            label: "ServiceSeq",
          },{
            fieldName: "Day",
            label: "Day",
          },{
            fieldName: "Schedule",
            label: "Schedule",
          },{
            fieldName: "Shape",
            label: "Shape",
          },{
            fieldName: "Shape.STLength()",
            label: "Shape.STLength()",
          }
          ]
        }]
      });

      var defaultSym = {
        type: "simple-line", // autocasts as new SimpleLineSymbol()
        color: "#EBEBEB",
        width: 3,
        style: "solid"
      };

      /*****************************************************************
       * Set a size visual variable on the renderer. Size visual variables
       * create continuous ramps that map low data values to small icons
       * and high data values to large icons. Features
       * with data values in between the min and max data values are assigned
       * a size proportionally between the min and max sizes specified in
       * `minSize` and `maxSize` or `stops`.
       *****************************************************************/

      var renderer = {
        type: "unique-value",
        defaultSymbol: defaultSym,
        field: "Schedule",
        uniqueValueInfos: [
          {
            value: "First Monday of the month",
            label: "First Monday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [252, 32, 32, 0.5] // fourth value is opacity (from 0 to 1)
            }
          },{
            value: "Second Monday of the month",
            label: "Second Monday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [252, 93, 35, 0.5]
            }
          },{
            value: "First Tuesday of the month",
            label: "First Tuesday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [255, 240, 38, 0.5]
            }
          },{
            value: "Second Tuesday of the month",
            label: "Second Tuesday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [113, 255, 43, 0.5]
            }
          },{
            value: "First Wednesday of the month",
            label: "First Wednesday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [42, 255, 156, 0.5]
            }
          },{
            value: "Second Wednesday of the month",
            label: "Second Wednesday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [41, 233, 255, 0.5]
            }
          },{
            value: "First Thursday of the month",
            label: "First Thursday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [40, 90, 255, 0.5]
            }
          },{
            value: "Second Thursday of the month",
            label: "Second Thursday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [118, 40, 255, 0.5]
            }
          },{
            value: "First Friday of the month",
            label: "First Friday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [168, 40, 255, 0.5]
            }
          },{
            value: "Second Friday of the month",
            label: "Second Friday of the month",
            symbol: {
              style: "solid",
              type: 'simple-line',
              width: 3,
              color: [255, 40, 233, 0.5]
            }
          }
        ]
      };

      app.pLineLayer = new FeatureLayer({
        url: "https://giswebservices.ci.salinas.ca.us/arcgis/rest/services/PublishedServices/CurrentSweeperRoutes/...",
        outFields: ["*"],
        fields: fields,
        renderer: renderer,
        popupTemplate: pTemplate,
        minScale: 0,
        maxScale: 0
      });

      var map = new Map({
        basemap: "dark-gray",
        layers: [app.pLineLayer]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-121.6555, 36.6777],
        zoom: 13
      });

      console.log(app.pLineLayer);
      selectGraphic = null;

      /******************************************************************
       *
       * Add layers to layerInfos on the legend
       *
       ******************************************************************/

      var legend = new Legend({
        view: view,
        layerInfos: [
        {
          layer: app.pLineLayer,
          title: "Street Sweeping"
        }]
      });

      view.ui.add(legend, "top-right");

      $('#workingButton').click(function(){

        // First create a line geometry (this is the Keystone pipeline)
        var polyline = {
          type: "polyline", // autocasts as new Polyline()
          paths: [
            [-111.30, 52.68],
            [-98, 49.5],
            [-93.94, 29.89]
          ]
        };

        // Create a symbol for drawing the line
        var lineSymbol = {
          type: "simple-line", // autocasts as SimpleLineSymbol()
          color: [150, 150, 255],
          width: 4
        };

        // Create an object for storing attributes related to the line
        var lineAtt = {
          Name: "Keystone Pipeline",
          Owner: "TransCanada",
          Length: "3,456 km"
        };

        polylineGraphic = new Graphic({
          geometry: polyline,
          symbol: lineSymbol,
          attributes: lineAtt,
          popupTemplate: { // autocasts as new PopupTemplate()
            title: "{Name}",
            content: [{
              type: "fields",
              fieldInfos: [{
                fieldName: "Name"
              }, {
                fieldName: "Owner"
              }, {
                fieldName: "Length"
              }]
            }]
          }
        });

        console.log("working polyline", polyline);
        console.log("working graphic", polylineGraphic);

        view.when(function(){
          view.goTo({
            target: polylineGraphic,
            animate: true
          }).then(function(){
            view.popup.open({
              features: [polylineGraphic],
              location: polylineGraphic.geometry.paths[0][0]
            });
          });
        });
      });


      $('#notWorkingButton').click(function(){
        queryParams = app.pLineLayer.createQuery();
        queryParams.where = "OBJECTID = 1709";
        app.pLineLayer.queryFeatures(queryParams).then(function(results){
          console.log("FeatureSet:", results);
          // go to that graphic
          view.when(function(){
            view.goTo({
              target: results.features[0], // Graphic object
              zoom: 20
            });
          });
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <input type="submit" id="workingButton" value="working">
  <input type="submit" id="notWorkingButton" value="not working">
</body>

</html>
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Vincent,

   Your query results need to be in the same spatial reference as the view. So you need to add outSpatialReference to queryParams

The spatial reference for the returned geometry. If not specified, the geometry is returned in the spatial reference of the queried layer.
      $('#notWorkingButton').click(function(){
        queryParams = app.pLineLayer.createQuery();
        queryParams.where = "OBJECTID = 1709";
        queryParams.outSpatialReference = view.spatialReference;
        app.pLineLayer.queryFeatures(queryParams).then(function(results){
          console.log("FeatureSet:", results);
          // go to that graphic
          view.when(function(){
            view.goTo({
              target: results.features[0], // Graphic object
              zoom: 20
            });
          });
        });
      });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

2 Replies
RobertScheitlin__GISP
MVP Emeritus

Vincent,

   Your query results need to be in the same spatial reference as the view. So you need to add outSpatialReference to queryParams

The spatial reference for the returned geometry. If not specified, the geometry is returned in the spatial reference of the queried layer.
      $('#notWorkingButton').click(function(){
        queryParams = app.pLineLayer.createQuery();
        queryParams.where = "OBJECTID = 1709";
        queryParams.outSpatialReference = view.spatialReference;
        app.pLineLayer.queryFeatures(queryParams).then(function(results){
          console.log("FeatureSet:", results);
          // go to that graphic
          view.when(function(){
            view.goTo({
              target: results.features[0], // Graphic object
              zoom: 20
            });
          });
        });
      });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
BlairJones
New Contributor III

Wouldn't it be nice if esri would mention in the API document that for graphic, geometry, etc. the spatial reference needs to be the same?