The simple version of this question is...
Can I trigger a specific layers popup / click response using a feature.geometry point?
The more involved version is as follows...
I have some simple maps, MyWatershed, Council Districts, etc. Currently the user opens the map, enters their address, and then has to click on the map to find out what watershed or council district they are in. I would like to circumvent that. I want the user to enter their address and then wherever that dot / popup (titled "Location") shows up, instead of showing it... trigger a click event / popup for a specific layer at that point.
I found the place in the Geocoder widget where this event gets fired...
/widgets/Geocoder/Widget.js : line 238
if (feature) {
this.map.infoWindow.setTitle("Location");
this.map.infoWindow.setContent(content || null);
this.map.infoWindow.show(feature.geometry);
} else if (extent) {
this.map.setExtent(extent);
}
I "believe" that I can interrupt the this.map.infoWindow.show command, and step in and fire off a click even at feature.geometry instead. Still researching but if anyone has a better direction, please advise!
Solved! Go to Solution.
Brian,
Try this:
console.info(content);
// First thing we need to do is convert the feature.geometry to a "mapPoint" object
var mpPt = feature.geometry;
console.log( "Map Point is set." );
this.map.centerAndZoom(mpPt,16);
console.log( "Center and Zoom" );
// Once we have the "mapPoint" object we convert it to a "screenPoint" object
setTimeout(lang.hitch(this, function(){
var scrPt = map.toScreen(mpPt);
this.map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });
}), 500);
It looks like someone has figured this out.
https://community.esri.com/message/395853#395853
Thomas Rippetoe wrote:
You can 'value add' a 'mapPoint' and/or 'screenPoint' objects to the click event. I think 'mapPoint' might be the object you are looking for. I have done something like this (I am pretty sure that i am not doing 'screenPoint' correctly - that's why i am using mapPoint):
var scrPt = new Point(-122, 45.6);
var mpPt = new Point(-122, 45.6);
map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });
So now I just need to find a way to convert feature.geometry to either a ScreenPoint or a MapPoint.
Brain,
Here is a sample using just JS API (not WAB stuff).
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Popup</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.11/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css">
<style>
html, body, #map {
padding: 0;
margin: 0;
height: 100%;
}
/* Change color of icons to match bar chart and selection symbol */
.esriPopup.dark div.titleButton,
.esriPopup.dark div.titlePane .title,
.esriPopup.dark div.actionsPane .action {
color: #A4CE67;
}
/* Additional customizations */
.esriPopup.dark .esriPopupWrapper {
border: none;
}
.esriPopup .contentPane {
text-align: center;
}
.esriViewPopup .gallery {
margin: 0 auto;
}
#search {
display: block;
position: absolute;
z-index: 2;
top: 20px;
left: 74px;
}
</style>
<script src="http://js.arcgis.com/3.11/"></script>
<script>
var map;
require([
"esri/map", "dojo/dom", "esri/geometry/Point",
"esri/dijit/Popup", "esri/dijit/PopupTemplate",
"esri/layers/FeatureLayer", "esri/dijit/Geocoder",
"esri/symbols/SimpleFillSymbol", "esri/Color",
"dojo/dom-class", "dojo/dom-construct", "dojo/on",
"dojox/charting/Chart", "dojox/charting/themes/Dollar",
"dojo/domReady!"
], function(
Map, dom, Point,
Popup, PopupTemplate,
FeatureLayer, Geocoder,
SimpleFillSymbol, Color,
domClass, domConstruct, on,
Chart, theme
) {
//The popup is the default info window so you only need to create the popup and
//assign it to the map if you want to change default properties. Here we are
//noting that the specified title content should display in the header bar
//and providing our own selection symbol for polygons.
var fill = new SimpleFillSymbol("solid", null, new Color("#A4CE67"));
var popup = new Popup({
fillSymbol: fill,
titleInBody: false
}, domConstruct.create("div"));
//Add the dark theme which is customized further in the <style> tag at the top of this page
domClass.add(popup.domNode, "dark");
map = new Map("map", {
basemap: "gray",
center: [-98.57, 39.82],
zoom: 4,
infoWindow: popup
});
var template = new PopupTemplate({
title: "Boston Marathon 2013",
description: "{STATE_NAME}: {Percent_Fi} of starters finished",
fieldInfos: [{ //define field infos so we can specify an alias
fieldName: "Number_Ent",
label: "Entrants"
},{
fieldName: "Number_Sta",
label: "Starters"
},{
fieldName: "Number_Fin",
label: "Finishers"
}],
mediaInfos:[{ //define the bar chart
caption: "",
type:"barchart",
value:{
theme: "Dollar",
fields:["Number_Ent","Number_Sta","Number_Fin"]
}
}]
});
var featureLayer = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/FeatureServer/0",{
mode: FeatureLayer.MODE_ONDEMAND,
outFields: ["*"],
infoTemplate: template
});
map.addLayer(featureLayer);
geocoder = new Geocoder({
map: map,
autoNavigate: false
}, "search");
geocoder.startup();
on(geocoder, "find-results", function(results){
console.info(results.results);
var mpPt = results.results.results[0].feature.geometry;//new Point(-122, 45.6);
var scrPt = map.toScreen(mpPt);
map.emit("click", { bubbles: true, cancelable: true, screenPoint: scrPt, mapPoint: mpPt });
});
});
</script>
</head>
<body class="claro">
<div id="search"></div>
<div id="map"></div>
</body>
</html>
Okay Robert,
So I've modified /widgets/Geocoder/Widget.js : Line 239 as follows:
/widgets/Geocoder/Widget.js : Line 239
// First thing we need to do is convert the feature.geometry to a "mapPoint" object
var mpPt = feature.geometry;
// Once we have the "mapPoint" object we convert it to a "screenPoint" object
var scPt = this.map.toScreen(mpPt);
// The click event requires a screenpoint and a mappoint in order to fire.
// Now we fire that event.
this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } );
What I'm getting is a dual hit.
http://maps.cityoftulsa.org/jsdev/citycouncil/
If you type in an address, like mine, 4740 E 5th Pl in Tulsa, Ok it pops up two districts. But now that I'm zoomed in, if I do the same address search then I get just one. Ugh!
I wonder if zooming to that point FIRST would correct this situation.
Brain,
Using your site and that address I only get one district...
I don't have enough facepalms for this.
Thanks for testing it Robert...
I'm thinking that after I get this cleaned up and make a settings page this would be a great upgrade for the Geocoder.
But we are getting dual councils popup for various addresses.
When I check out the Screenpoint and Mappoint variables I'm getting some distinctly different looking coords.
I'm almost certain that my duplicate council issues are coming from the two points being registered.
Maybe if I zoomed first and the generated the scPt and mpPt?
I am looking around for how to zoom to a feature.geometry, so once I get that figured out I'll do that THEN run the mpPt and scPt and emit.
Brain,
Are you sure that the geocoded address is not returning two different locations? I would put:
console.info(content);
at line 239 and see if you are getting two results from the Geocoder
Great idea. I hadn't even considered that.
Just ran that code and I'm getting a single address.
Ugh!
My Code
console.info(content); // First thing we need to do is convert the feature.geometry to a "mapPoint" object var mpPt = feature.geometry; console.log( "Map Point is set." ); this.map.centerAndZoom(mpPt,16); console.log( "Center and Zoom" ); // Once we have the "mapPoint" object we convert it to a "screenPoint" object var scPt = this.map.toScreen(mpPt); // The click event requires a screenpoint and a mappoint in order to fire. // Now we fire that event. // this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } ); this.map.emit( "click", { bubble: true, cancelable: true, screenPoint: scPt, mapPoint: mpPt } )
If I am already zoomed in to an area then the same address only gives me ONE Council...
But when zoomed out I get two for any address close to a border.
I was trying this on our Watershed map with similar results. Close to the border? Two results...
I had thought I could just adjust the bubble method to false, and fix it but I haven't read the documentation on it and it didn't do what I thought it did... lol...