Select to view content in your preferred language

Can't zoom to feature from Datagrid

4057
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
1 Solution

Accepted Solutions
RyanSellman
Deactivated User
Okay so I think I got it working...part of the problem was that my onRowClickHandler function couldn't handle point features, but as indicated above, the suggestions for this function still didn't get things working. The showResults function was the larger part of the problem. Initially, the info being pushed to the datagrid was the resulting layer name, found field name and found value. I wanted to employ this method since I am searching a service with multiple layers and returning all records to one datagrid - so a search could potentially return results from multiple layers if the criteria isn't specific enough. For some reason, the onRowClickHandler function couldn't get at the geometry of each feature returned. Here is the code that had been giving me issues:

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.");
              }
          }


I adjusted it with the below code, and now the onRowClickHandler routine (provided to me by Luci) is working for all feature types.

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 items = arrayUtils.map(results, function (result) {
                      var graphic = result.feature;
                      
                      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 = {
        identifier: "OBJECTID",
        label: "OBJECTID",
                      items: items
                  };
                  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.");
              }
          }


Now, displaying attributes in a useful way in the datagrid will be the next challenge.

Thanks to all for helping me tackle this! It is much appreciated!

Ryan

View solution in original post

0 Kudos
26 Replies
TimWitt
Deactivated User
Ryan,

maybe this example can help?

Tim
0 Kudos
LixianDai
Deactivated User
Point does not have a .getExtent; try to separate different geometry type when you want to zoom.
0 Kudos
RyanSellman
Deactivated User
Tim,

Many thanks for your quick response and help.  I made changes where I saw fit to my code per your example.  I no longer get the, "Uncaught TypeError: Cannot read property 'getExtent' of undefined" that I was seeing before.  However, when I click on a row nothing happens.  Moreover, I see no errors in the console when firing the onRowClickHandler function.  Any ideas?  I am sorry to pester!

Here is my updated code:
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 feature found");
   }
        }

        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);
   
  });
  
   if (selectedFeature.length) {
    map.setExtent(selectedFeature[0].geometry.getExtent(), true);
    }
   } 
   
0 Kudos
RyanSellman
Deactivated User
Lixian,

Thanks for your response and note.  I am aware that Point does not have a .getExtent and thought I handled it in the code I initially posted:

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);
            }
   
  }


Do you see a reason why the above code wouldn't work?

Thanks!!!
0 Kudos
TimWitt
Deactivated User
Ryan,

can you post your full code?
0 Kudos
RyanSellman
Deactivated User
Absolutely, but beware - I am super new to JavaScript and the API.  This is my first app.

Thanks again!
0 Kudos
TimWitt
Deactivated User
Does your application find something and populates the grid, but when you click on the grid it won't zoom?
0 Kudos
RyanSellman
Deactivated User
Yes, that is correct. In the application, there are two findtasks, one searching for parcels, the other searches many utility layers in one map service.  Each task successfully pushes data to one datagrid.  In the current state of the application (with the code you suggested), when I click on a row nothing happens and I get no errors in firebug or google dev tools
0 Kudos
RyanSellman
Deactivated User
Tim,

After copying and pasting your onRowClickHandler() function shown here,

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


I can now zoom to polygon features but not lines or points.  I must have made a typo when I first implemented your suggestions earlier. 

Now, when I click on a feature that's either a line or a point, I get the following error:

"Uncaught TypeError: Cannot read property 'toJson' of null "

Attached is the updated app.

Thanks!
0 Kudos