Select to view content in your preferred language

Can't zoom to feature from Datagrid

4062
26
Jump to solution
06-09-2014 05:37 AM
RyanSellman
Deactivated User
I have a find task in my application that returns features that are points, lines and polygons.  I can get the search to populate the datagrid but I am having problems with my onRowClickHandler function and zooming to those features from the datagrid.  I've been searching through the forums and see that zooming to a point from the datagrid has been an issue for others, but I can't find a solution that works for me.  Here is some code that shows the findtask and what I have for the onRowClickHandler function.

I get the error: "Uncaught TypeError: Cannot read property 'getExtent' of undefined" when the onRowClickHandler function is fired.


findDistrictTask = new FindTask("http://summitgis.summitoh.net:6080/arcgis/rest/services/DOES/MapServer/");          map.on("load", function () {             findDistrictParams = new FindParameters();             findDistrictParams.returnGeometry = true;             findDistrictParams.layerIds = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];             findDistrictParams.searchFields = ["NAME, UNAME, PUMPID, PIPEID, PlantID, Name"];             findDistrictParams.outSpatialReference = map.spatialReference;         });          function doDoesDistrictFind() {             findDistrictParams.searchText = dom.byId("doesDistrictText").value;             findDistrictTask.execute(findDistrictParams, showResults);         }           function showResults(results) {             var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]));             var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 1);             var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NONE, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]));             map.graphics.clear();             var dataForGrid = [];             arrayUtils.map(results, function (result) {                 var graphic = result.feature;                 dataForGrid.push([result.layerName, result.foundFieldName, result.value]);                 switch (graphic.geometry.type) {                 case "point":                     graphic.setSymbol(markerSymbol);                     break;                 case "polyline":                     graphic.setSymbol(lineSymbol);                     break;                 case "polygon":                     graphic.setSymbol(polygonSymbol);                     break;                 }                 map.graphics.add(graphic);             });             var data = {                 items: dataForGrid             };             var store = new ItemFileReadStore({                 data: data             });              var grid = registry.byId("grid");              grid.setStore(store);             grid.on("rowclick", onRowClickHandler);              map.centerAndZoom(center, zoom);         }          function onRowClickHandler(evt) {             var clickedFeature = evt.grid.getItem(evt.rowIndex).OBJECTID;             var selectedFeature = arrayUtils.filter(map.graphics.graphics, function (graphic) {        return ((graphic.attributes) && graphic.attributes.OBJECTID === clickedFeature);       });        var featureExtent = selectedFeature.geometry.getExtent();    var screenpoint = map.toScreen(selectedFeature.geometry.getExtent().getCenter());    var mappoint = map.toMap(screenpoint);        map.centerAt(mappoint);                 if (selectedFeature.geometry.declaredClass == 'esri.geometry.Point') {                 map.centerAt(selectedFeature.geometry);             } else {                 var featureExtent = selectedFeature.geometry.getExtent();                 var screenpoint = map.toScreen(selectedFeature.geometry.getExtent().getCenter());                 var mappoint = map.toMap(screenpoint);                 map.centerAt(mappoint);             }       } 


Does anyone have any idea what I am doing wrong or a way to zoom to all feature types from a datagrid?  Thanks in advance!!!
0 Kudos
26 Replies
TimWitt
Deactivated User
When it finds lines or points does it highlight them?
0 Kudos
RyanSellman
Deactivated User
Yes, the found points and lines are highlighted on the map with the correct assigned symbology.

Thanks again for helping me with this!
0 Kudos
LuciHawkins
Frequent Contributor
Hey,

This is the onRowClickHandler that I use: 
function onRowClickHandler(evt) {
var clickedObjectf = grid.getItem(evt.rowIndex).OBJECTID;
var selectedObjectf;
var distance = 50;
dojo.forEach(map.graphics.graphics, function(graphicf) {
  if ((graphicf.attributes) && graphicf.attributes.OBJECTID === clickedObjectf) {
   selectedObjectf = graphicf;
   return;
  }
});
if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point'){
   var PointExtent = new esri.geometry.Extent({
   "xmin" : selectedObjectf.geometry.x - distance,
   "ymin" : selectedObjectf.geometry.y - distance,
   "xmax" : selectedObjectf.geometry.x + distance,
   "ymax" : selectedObjectf.geometry.y + distance,
   "spatialReference" : {
    "wkid" : 102100
    }
   });
   map.setExtent(PointExtent);
}
else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon'){
   var selectedParcel = selectedObjectf.geometry.getExtent();
   map.setExtent(selectedParcel);
}
}


It sets a different extent based upon whether the selected object in the row is a point or a polygon.  You can add another "else if" for polyline similar to:

else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polyline'){
   var selectedStreet = selectedObjectf.geometry.getExtent();
   map.setExtent(selectedStreetl);
}


Thanks,

Luci
0 Kudos
RyanSellman
Deactivated User
Luci,

Thank you for your response!  I tried implementing something very similar before but kept getting the error:
Uncaught TypeError: Cannot read property 'geometry' of undefined". 

When I use the code you suggested, I get the same exact error in Chrome. 

In firebug, I get:
"TypeError: selectedObjectf is undefined". 

I have to be missing something small.  Any thoughts??

Thank you!
0 Kudos
LuciHawkins
Frequent Contributor
Are you using Legacy or AMD?  Did you define point, polygon, and polyline.  

AMD Style:
require(["...whatever else you are defining, "esri/geometry/Point", "esri/geometry/Polyline", "esri/geometry/Polygon",....end of your define"], function(....etc..., Point, Polyline, Polygon, ....etc..){


Legacy Style:

dojo.require("esri.geometry.Point");
dojo.require("esri.geometry.Polyline");
dojo.require("esri.geometry.Polygon");


Thanks,

Luci
0 Kudos
RyanSellman
Deactivated User
That may be my issue.  I am using AMD and have defined "esri/geometry/point" but not polyline or polygon.  Going to make the change now - hopefully that's it!

Thank you!!
0 Kudos
RyanSellman
Deactivated User
I am sorry to pester but I am still getting an error.  I have no clue whats going on.  I defined point, polyline and polygon and added the onRowClickHandler function you use but get the following message in Chome Dev Tools:

Uncaught TypeError: Cannot read property 'getItem' of undefined

Here is the find task I am using along with the code you suggested:

findDistrictTask = new FindTask("http://summitgis.summitoh.net:6080/arcgis/rest/services/DOES/MapServer/");

          map.on("load", function () {
              findDistrictParams = new FindParameters();
              findDistrictParams.returnGeometry = true;
              findDistrictParams.layerIds = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
              findDistrictParams.searchFields = ["NAME, UNAME, PUMPID, PIPEID, PlantID, Name"];
              findDistrictParams.outSpatialReference = map.spatialReference;
          });

          function doDoesDistrictFind() {
              findDistrictParams.searchText = dom.byId("doesDistrictText").value;
              findDistrictTask.execute(findDistrictParams, showResults);
          }


          function showResults(results) {
              if (results.length > 0) {
                  map.graphics.clear();
                  var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]));
                  var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 1);
                  var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NONE, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]));

                  var dataForGrid = [];

                  arrayUtils.map(results, function (result) {
                      var graphic = result.feature;
                      dataForGrid.push([result.layerName, result.foundFieldName, result.value]);
                      switch (graphic.geometry.type) {
                      case "point":
                          graphic.setSymbol(markerSymbol);
                          break;
                      case "polyline":
                          graphic.setSymbol(lineSymbol);
                          break;
                      case "polygon":
                          graphic.setSymbol(polygonSymbol);
                          break;
                      }
                      map.graphics.add(graphic);
                      return result.feature.attributes;
                  });
                  var data = {
                      items: dataForGrid
                  };
                  var store = new ItemFileReadStore({
                      data: data
                  });

                  var grid = registry.byId("grid");

                  grid.setStore(store);
                  grid.on("rowclick", onRowClickHandler);

                  map.centerAndZoom(center, zoom);
              } else {
                  alert("No Utility Feature found!  Please enter a valid UNAME, PIPEID, Plant ID, PUMPID or Name.");
              }
          }

          //end does district search

          function onRowClickHandler(evt) {
              var clickedObjectf = grid.getItem(evt.rowIndex).OBJECTID;
              var selectedObjectf;
              var distance = 50;
              dojo.forEach(map.graphics.graphics, function (graphicf) {
                  if ((graphicf.attributes) && graphicf.attributes.OBJECTID === clickedObjectf) {
                      selectedObjectf = graphicf;
                      return;
                  }
              });
              if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') {
                  var PointExtent = new esri.geometry.Extent({
                      "xmin": selectedObjectf.geometry.x - distance,
                      "ymin": selectedObjectf.geometry.y - distance,
                      "xmax": selectedObjectf.geometry.x + distance,
                      "ymax": selectedObjectf.geometry.y + distance,
                      "spatialReference": {
                          "wkid": 102100
                      }
                  });
                  map.setExtent(PointExtent);
              } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') {
                  var selectedParcel = selectedObjectf.geometry.getExtent();
                  map.setExtent(selectedParcel);
              }
          }


The graphics for all 3 feature types are drawing in the correct place and attributes are populating the grid, I just can't get the zoom to work.

Any idea why is doesn't like "getItem"

Ryan
0 Kudos
KenBuja
MVP Esteemed Contributor
It looks like a matter of scope. You declare the variable grid in the function "showResults"

 var grid = registry.byId("grid");


Since this is declared locally within that function, it isn't visible to other functions (like "onRowClickHandler")

You'll have to either declare the variable globally, or declare it again within "onRowClickHandler"
0 Kudos
RyanSellman
Deactivated User
Ken,

Thanks very much for the comment and insight.  It is appreciated as I continue to learn.

So, I made the adjustment to the onROwClickHandler function as shown here:

function onRowClickHandler(evt) {
     var grid = registry.byId("grid");
              var clickedObjectf = grid.getItem(evt.rowIndex).OBJECTID;
              var selectedObjectf;
              var distance = 50;
              dojo.forEach(map.graphics.graphics, function (graphicf) {
                  if ((graphicf.attributes) && graphicf.attributes.OBJECTID === clickedObjectf) {
                      selectedObjectf = graphicf;
                      return;
                  }
              });
              if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') {
                  var PointExtent = new esri.geometry.Extent({
                      "xmin": selectedObjectf.geometry.x - distance,
                      "ymin": selectedObjectf.geometry.y - distance,
                      "xmax": selectedObjectf.geometry.x + distance,
                      "ymax": selectedObjectf.geometry.y + distance,
                      "spatialReference": {
                          "wkid": 102100
                      }
                  });
                  map.setExtent(PointExtent);
              } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') {
                  var selectedParcel = selectedObjectf.geometry.getExtent();
                  map.setExtent(selectedParcel);
              }
          }


Still getting the same issue with 'getItem'

What's odd to me, is when I add the function from this sample on the API site, it works. 

function onRowClickHandler(evt) {
          var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).PARCELID;
          var selectedTaxLot = arrayUtils.filter(map.graphics.graphics, function (graphic) {
            return ((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId);
          });
          if ( selectedTaxLot.length ) {
            map.setExtent(selectedTaxLot[0].geometry.getExtent(), true);
          }
        }


When just a polygon is returned to the grid it works, just a line, it works.  But when there is a combination of features (a point and a polygon/a point and a line) returned to the grid, nothing works at all.  The presence of a point feature disables the function from working at all.
0 Kudos
KenBuja
MVP Esteemed Contributor
You may not notice, but there is a difference between those two functions in the way the grid is referenced. The one from the sample gets the grid from the evt passed into it

function onRowClickHandler(evt) {
    var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).PARCELID;


Have you tried that with your version?

function onRowClickHandler(evt) {
    //var grid = registry.byId("grid");
    var clickedObjectf = evt.grid.getItem(evt.rowIndex).OBJECTID;
0 Kudos