How can I select a polygon from a layer which intersect the seach result?

1040
6
10-16-2017 07:44 PM
AnnCrystal
New Contributor II

I am trying to search an address using a custom geocoding service which has an additional field of parcelpin. Instead of showing the result as a location point, I want to select and zoom to the feature having the corresponding parcelpin in the parcel layer. What is the best strategy? Should I use a geometry service or a simple query will serve the purpose?

My only confusion is how to incorporate it to the search widget. If anybody has done this, please share the sample or at least some pointers for a start.

Thanks

-Ann

0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Emeritus

Ann,

   I do something similar in my Parcel Viewer web site and the way to do it is a queryTask using the search widgets result geometry.

In the Search Widget.js file find the _onSelectResult function:

      _onSelectResult: function(e) {
        var result = e.result;
        if (!(result && result.name)) {
          return;
        }
        var dataSourceIndex = e.sourceIndex;
        var sourceResults = this.searchResults[dataSourceIndex];
        var dataIndex = 0;
        var that = this;

        var getGraphics = function(layer, fid) {
          var graphics = layer.graphics;
          var gs = array.filter(graphics, function(g) {
            return g.attributes[layer.objectIdField] === fid;
          });
          return gs;
        };
        var showPopupByFeatures = function(features) {
          var location = null;
          that.map.infoWindow.setFeatures(features);
          if (features[0].geometry.type === "point") {
            location = features[0].geometry;
          } else {
            location = features[0].geometry.getExtent().getCenter();
          }
          that.map.infoWindow.show(location, {
            closetFirst: true
          });
        };

        for (var i = 0, len = sourceResults.length; i < len; i++) {
          if (jimuUtils.isEqual(sourceResults[i], result)) {
            dataIndex = i;
            break;
          }
        }
        query('li', this.searchResultsNode)
          .forEach(lang.hitch(this, function(li) {
            html.removeClass(li, 'result-item-selected');
            var title = html.getAttr(li, 'title');
            var dIdx = html.getAttr(li, 'data-index');
            var dsIndex = html.getAttr(li, 'data-source-index');

            if (title === result.name &&
              dIdx === dataIndex.toString() &&
              dsIndex === dataSourceIndex.toString()) {
              html.addClass(li, 'result-item-selected');
            }
          }));

        var layer = this.map.getLayer(e.source._featureLayerId);

        if (layer && this.config.showInfoWindowOnSelect) {
          var gs = getGraphics(layer, e.result.feature.__attributes[layer.objectIdField]);
          if (gs.length > 0) {
            showPopupByFeatures(gs);
          } else {
            var handle = on(layer, 'update-end', lang.hitch(this, function() {
              if (this.domNode) {
                var gs = getGraphics(layer, e.result.feature.__attributes[layer.objectIdField]);
                if (gs.length > 0) {
                  showPopupByFeatures(gs);
                }
              }

              if (handle && handle.remove) {
                handle.remove();
              }
            }));
            this.own(handle);
          }
        }
        //publish select result to other widgets
        this.publishData({
          'selectResult': e
        });
//Now do your query of parcels layer
        var parcelpin = result.feature.attributes["your parcel pin field name"];
        var queryParams = new Query();
        queryParams.where = "your parcel pin field name = " + parcelpin;
        queryParams.returnGeometry = true;
        queryParams.outSpatialReference = this.map.spatialReference;
        queryParams.outFields = ["*"];

        var queryTask = new QueryTask(your layer url);
        queryTask.execute(queryParams, lang.hitch(this, this._onSearchFinish),
          lang.hitch(this, this._onSearchError));
...
      _onSearchFinish: function (results) {
        array.forEach(results.features, lang.hitch(this, function(gra){
          //if you want to do something other than zoom to the parcel
          //you would work with the parcel result here
        }
        var gExt = graphicsUtils.graphicsExtent(results.features);
        if (gExt) {
          this.map.setExtent(gExt.expand(1.5), true);
        }
      },
      
      _onSearchError: function (error) {
        console.debug(error);
      },


‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
AnnCrystal
New Contributor II

Wow-Thanks Robert. That is a really great start. I'll try it and will update you.

0 Kudos
AnnCrystal
New Contributor II

Hi Robert:

If my map is a webmap from portal, how can I use a layer from the webmap to do the query task as in the "your layer url"  for quert task? Thanks


        var queryTask = new QueryTask(your layer url);
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ann,

  When you created that web map you had to add layers to it from AGOL or your ArcGIS Server, so you just need to know the url of the layer you are interested in.

0 Kudos
AnnCrystal
New Contributor II

Sorry, I didn't ask the question correctly:( So, evenif I am using a webmap, I can use the rest url of that weblayer directly for query task ? 

I was thinking that I should loop thru the webmap and pass the layer id of parcel layer to querytask as it's a web map and that the selection has to be done on the parcel layer in that webmap. As always, Thanks for your help,

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ann,

   Yes, you would use the rest url here. The code I provided does not select the parcel it just zooms to it as the comment in the _onSearchFinish function states.