Saturday 31 August 2019

How to register onclick handler for *all* KML feaures in OpenLayers?


I'm a newbie using OpenLayers with JQuery to display vector data from KML files. I'm creating the layer like this:


newlayer = new OpenLayers.Layer.Vector( layerid, {

projection: MAPVAR.displayProjection,
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: layerurl,
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true,
maxDepth: 2
})
})

});

I want to avoid using these vector features with the OpenLayers.Control.SelectFeature control. Instead i would like to have each svg feature respond to a click event and pop open their own individual windows with the attributes.


I'm having trouble figuring out how to add the onclick function to ALL the vector features loaded.


For example, I can attache a function to the KML layer's "loadend" event and add the onclick function doing the following:


$('g[id$=vroot] > *').css("cursor", "pointer")
$('g[id$=vroot] > *').click(function(evt){ $w = $.WM_open(); $w.find('.windowcontent').append("SUCKER"); });

But this will only apply the handler to those vector elements in the view extent and not the ones that are waiting to be rendered in the HTML. I'm not sure how to access the unrendered ones -- they are in the DOM.


I've come up with really stupid stupid work around to this problem, but I know there has to be a better way.



Is there some way I can dynamically create the "onclick" handler for each svg feature when they are getting parsed? Would that require me to subclass OpenLayers.Layers.Vector or OpenLayers.Formats.KML? Does anyone have an example? Or recommendation on other ways?


thx mazery




I still have not solved adding the onclick handler to the features. But i was able to override OpenLayers.Format.KML parseData() to add a pointer cursor to the feature styles before the loadend runs on the KML layer (additions demarcated with * EDITS *).


var FormatErmaKml = OpenLayers.Class(OpenLayers.Format.KML, { 
parseData: function (data, b) {
typeof data == "string" && (data = OpenLayers.Format.XML.prototype.read.apply(this, [data]));
for (var c = ["Link", "NetworkLink", "Style", "StyleMap", "Placemark"], d = 0, e = c.length; d < e; ++d) {
var f = c[d];
var g = this.getElementsByTagNameNS(data, "*", f);

if (g.length != 0) switch (f.toLowerCase()) {
case "link":
case "networklink":
this.parseLinks(g, b);
break;
case "style":
this.extractStyles && this.parseStyles(g, b);
break;
case "stylemap":
this.extractStyles && this.parseStyleMaps(g, b);

break;
case "placemark":
this.parseFeatures(g, b)
}

}
**** EDITS BEGIN ****
for(var count = 0; count < this.features.length; ++count){
f = this.features[count];
f.style.cursor = "pointer";

}
**** END EDITS ****
return this.features
},});

Any ideas on adding the onclick handler for each feature are welcomed.


thx mazery



Answer



I believe i found the solution.


SOLUTION DEMONSTRATION



It will:



  1. change the cursor for your feature to cursor:wait using jquery.

  2. It will change the svg fill color of the feature using jquery.

  3. And best of all it's efficient and will NOT trigger anything or disrupt anything else as far as my tests have shown.


Use a regular click Handler (EXAMPLE1, EXAMPLE2) and use the e.target to get the object on the map. If it returns a vector feature great, if not, ignore. It can work for all your layers or you can check the returned feature to see if it belongs to a layer you want it to trigger on.


I used Example #1 and replaced the latlon alert for this:


    if (e.target._featureId) {
var feature = vectorLayer.getFeatureById(e.target._featureId);

$(e.target).css('fill', '#000000');
$(e.target).css('cursor', 'wait');
$("div#info").append("You just clicked on " + feature.id + "
");
}

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...