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
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);
},
Wow-Thanks Robert. That is a really great start. I'll try it and will update you.
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);
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.
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,
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.