I have a CSVLayer that I loaded into a web application.
The data that I want to display within the infowindow of that CSVLayer is too large to display nicely in the existing map window.
Therefore when I click on a point within that CSVLayer, I need to execute some code that re-centers the map such that the entire infowindow is displayed within the map.
The problem that I have is that I cannot figure out how to create a click event on just the CSVlayer.
Currently I have a click event triggered on the map as a whole.. which does the recentering for me, but this proved problematic if I end up clicking on any other part of the map. In those cases, there is no infowindow to open and the map will still be forced to re-center.
Below is my code for this application.
<script src="http://js.arcgis.com/3.15/"></script>
<script>
var map, kml, csv;
require(["esri/map", "esri/layers/KMLLayer", "esri/layers/CSVLayer", "esri/renderers/SimpleRenderer", "esri/InfoTemplate", "esri/urlUtils", "esri/symbols/PictureMarkerSymbol", "esri/geometry/Point", "esri/SpatialReference", "esri/geometry/webMercatorUtils", "esri/geometry/screenUtils", "esri/geometry/ScreenPoint", "dojo/dom", "dojo/_base/array", "dojo/domReady!"], function(Map, KMLLayer, CSVLayer, SimpleRenderer, InfoTemplate, urlUtils, PictureMarkerSymbol, Point, SpatialReference, webMercatorUtils, screenUtils, ScreenPoint, dom, array) {
map = new Map("map", {
basemap : "hybrid",
center : [-83.71, 36.05],
zoom : 8
});
map.on("load", function() {
map.infoWindow.set('anchor', 'bottom-right');
map.infoWindow.resize(625, 425);
map.on("mouse-move", showCoordinates);
map.on("mouse-drag", showCoordinates);
});
var kmlUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/kml/RiversLakes.kml";
kml = new KMLLayer(kmlUrl);
map.addLayer(kml);
dojo.connect(kml, 'onLoad', function(lyr) {
var layers = lyr.getLayers();
dojo.forEach(layers, function(lyr) {
lyr.setInfoTemplate(null);
});
});
urlUtils.addProxyRule({
proxyUrl : "/proxy/proxy.php",
urlPrefix : "www.srh.noaa.gov"
});
var template = new InfoTemplate("${name}", "<iframe src=${fcstlink} class="fcst"></iframe>");
var csvUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/js_local/riverpoints.csv";
csv = new CSVLayer(csvUrl, {
copyright : "weather.gov",
infoTemplate : template
});
var logo = new PictureMarkerSymbol("http://www.srh.noaa.gov/images/mrx/surf.png", 20, 20);
var renderer = new SimpleRenderer(logo);
csv.setRenderer(renderer);
csv.attr('sites', 'sites');
map.addLayer(csv);
dojo.connect(map.infoWindow, "onHide", centerMap);
map.on("click", mapClickAction);
function showCoordinates(evt) {
var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
var sp = screenUtils.toScreenGeometry(map.extent, 800, 550, evt.mapPoint);
dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3) + "<br>" + sp.x + " " + sp.y;
}
function centerMap(){
map.graphics.clear();
map.centerAt([-83.71, 36.05]);
return;
}
function mapClickAction(evt) {
var screenX = evt.screenPoint.x;
var screenY = evt.screenPoint.y;
var newScreenX = screenX + 225;
var newScreenY = screenY + 250;
var newScreenCenter = screenUtils.toMapPoint(map.extent, 800, 550, new ScreenPoint(newScreenX, newScreenY));
map.centerAt(newScreenCenter);
}
});
</script>
Solved! Go to Solution.
Instead of using the map's click event, use the CSVLayer's click event
Instead of using the map's click event, use the CSVLayer's click event
Ken...
Thanks for the reply. I was trying to access the CSVlayer click event but could not get it to work.
Stupid question but I get access to the map click event via
map.on("click", mapClickAction);
How do I get access to the CSVLayer object click event?
The syntax would be
csv.on("click", mapClickAction);
A couple other observations about your code. You're using dojo.connect in a few places. You should replace those with on
dojo.connect(kml, 'onLoad', function(lyr) { kml.on("load", function(lyr) {
and
dojo.connect(map.infoWindow, "onHide", centerMap); map.infoWindow.on("hide", centerMap);
Ken,
Thank you so much for the help. That was the solution. I appreciate your time.
I made the changes from
- dojo.connect(kml, 'onLoad', function(lyr) {
- var layers = lyr.getLayers();
- dojo.forEach(layers, function(lyr) {
- lyr.setInfoTemplate(null);
- });
- });
to
kml.on("load", function(lyr) { var layers = lyr.getLayers(); dojo.forEach(layers, function(lyr) { lyr.setInfoTemplate(null); }); });
and when I try to set the InfoTemplate to null so that it does not show up when a user clicks on the map...
It is now causing the entire kml shape to no longer display.
With the kml.on("load", function... the map looks like
With the dojo connect function the kml layer appears without the ability to click on that layer and have an info window display.
In the interest of coding this up properly with .on instead of dojo.connect... can anyone tell me what is going wrong?
I appreciate the help thus far.
I'm glad to help. Please remember to mark the original question as answered.
As for your new question,the "load" event function is returning a different object than the "onLoad" event function.
This is what is returned from the "load" event.
And this is what's returned from the "onLoad" event.
You have to use the syntax "var layers = lyr.layer.getLayers();" in your "load" function to get the same object.
kml.on('load', function (lyr) { var layers = lyr.layer.getLayers(); dojo.forEach(layers, function (lyr) { lyr.setInfoTemplate(null); }); });
Ken.. thanks again.
I did run into a recurrence of the original problem. Now when I click on the csv points... I cannot get them to execute the click event that I had set up.
Was wondering if you could see what might be going wrong.
It is almost as if the csv layer is "beneath" the kml layer and therefore cannot have the csv.on("click", mapFcstAction) called.
The map.infowindow.on("hide", centerMap) call seems to work fine.
Kind of spinning my wheels right now with this.
Eric
map = new Map("map", { basemap : "hybrid", center : [-83.71, 36.05], zoom : 8 }); map.on("load", function() { map.infoWindow.set('anchor', 'bottom-right'); map.infoWindow.resize(625, 425); }); map.infoWindow.on("hide", centerMap); urlUtils.addProxyRule({ proxyUrl : "/proxy/proxy.php", urlPrefix : "www.srh.noaa.gov" }); var template = new InfoTemplate("${name}", "<iframe src=${fcstlink} class="fcst"></iframe>"); var csvUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/js_local/riverpoints.csv"; csv = new CSVLayer(csvUrl, { copyright : "weather.gov", infoTemplate : template }); var logo = new PictureMarkerSymbol("http://www.srh.noaa.gov/images/mrx/surf.png", 20, 20); var renderer = new SimpleRenderer(logo); csv.setRenderer(renderer); map.addLayer(csv); csv.on("click", mapFcstAction); var kmlUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/kml/RiversLakes.kml"; kml = new KMLLayer(kmlUrl); map.addLayer(kml); kml.on('load', function(lyr) { var layers = lyr.layer.getLayers(); array.forEach(layers, function(l) { l.setInfoTemplate(null); }); }); function centerMap() { alert("CENTER"); map.graphics.clear(); map.centerAt([-83.71, 36.05]); } function mapFcstAction(evt) { alert("FCST"); map.infoWindow.show(evt.screenPoint); var screenX = evt.screenPoint.x; var screenY = evt.screenPoint.y; var newScreenX = screenX + 225; var newScreenY = screenY + 250; var newScreenCenter = screenUtils.toMapPoint(map.extent, 800, 550, new ScreenPoint(newScreenX, newScreenY)); map.centerAt(newScreenCenter); }
This is strange. I've tried adding in the CSVLayer after the KMLLayer, but the KMLLayer always appears on top. Even this code leaves the KMLLayer on top of the CSVLayer
kml.on("load", function() { map.addLayer(csv); })
I can't understand this, because according to the documentation, a two layers have different inheritance. The KMLLayer inherits directly from Layer
|_esri/layers/KMLLayer
while the CSVLayer inherits from GraphicsLayer
esri/layers/Layer
|_esri/layers/GraphicsLayer
|_esri/layers/FeatureLayer
|_esri/layers/CSVLayer
Now a GraphicsLayer will always be on top of a Dynamic or Tiled layer, but I can't find any information about where a KMLLayer fits into this hierarchy.
I think you should start a new question to get some more knowledgeable people involved.
Thanks Ken... I followed up with another question this morning. This one really has me stumped... especially when it seemed to work fine using the old style dojo.connect.
You should move your other question to the ArcGIS API for JavaScript space to get more focused attention. I hadn't noticed that this discussion was in the more generic Developers space...or I would have suggested you move this one also.