geoxml3 - Google Maps with KML layer control

2019-09-14 23:14发布

问题:

I'm using geoxml3 to display KML files on Google Maps. I made script with which different KML layers can be turned on and off. Although every layer turns on as expected, when trying to turn off one layer, turns off another.

var G = google.maps;
var layers = new function() {this.data = [
{id:'japan',url:'kvadrati.kml'},
{id:'d1',   url:'Didzis_21.03-03.04.kml'},
{id:'d2',   url:'Didzis_04.04-17.04.kml'},
... ]};

function toggle() {for (var i=0; i<layers.data.length; i++) {
if (this.id == layers.data[i].id) {
if (layers.data[i].parsed) {
if (layers.data[i].on)
{geo.hideDocument(geo.docs[i]); layers.data[i].on = false}
else {geo.showDocument(geo.docs[i]); layers.data[i].on = true}}
else {geo.parse(layers.data[i].url); layers.data[i].parsed = true; layers.data[i].on = true}}
};};

function initialize() {
var options = {
   center:new G.LatLng(34.9, 137.3), 
   zoom:10, 
   mapTypeId:G.MapTypeId.TERRAIN, 
   scaleControl:true, 
   overviewMapControl:true, 
   mapTypeControlOptions:{style:G.MapTypeControlStyle.DROPDOWN_MENU}
};
map = new G.Map(document.getElementById('map'), options);
geo = new geoXML3.parser({
             map:map, 
             zoom:false, 
             singleInfoWindow:true, 
             infoWindowOptions:{maxWidth:100}, 
             processStyles:true, 
             markerOptions:{shadow:''}
      });
var el = document.getElementsByTagName('input');
for (var i=0; i<el.length; i++) {
    el[i].type = 'checkbox'; 
    G.event.addDomListener(el[i], 'click', toggle)};
};
G.event.addDomListener(window, 'load', initialize);

I'm sure that problem is in function toggle() where appears:

geo.[show/hide]Document(geo.docs[i]);

Test it here. It takes quite a long time to load a layer because they are in uncompressed (KML) format. I read that geoxml3 should support KMZ files, I even copied every file from this example but it wasn't working for me. Anybody knows why so?

回答1:

Finally I got the right code where function toggle() is:

function toggle() {
for (var i=0; i<layers.length; i++) {
var x = layers[i];
var xurl = './layers/' + x.url;
if (this.id == x.id)
{if (x.render)
{for (var n=0; n<geo.docs.length; n++)
{var y = geo.docs[n];
if (y.url == xurl)
{if (x.on) {geo.hideDocument(y); x.on = false} else {geo.showDocument(y); x.on = true}}
}}
else {geo.parse(xurl); x.render = true; x.on = true}}}};

Quite crazy function, many if statements but I guess it can't be any simpler or cleaner than this.

EDIT:

function toggle() {var x = this;
if (x.r) {(x.on) ? geo.hideDocument(geo.docs[x.n]) : geo.showDocument(geo.docs[x.n])}
else {geo.parse(x.href); x.r = true; x.n = geo.docs.length}; x.on = !x.on};

Removed layers array as it wasn't necessary, now I'm using href from anchor tags to parse a layer, not clicking input but a elements. So the script turned out really short.



回答2:

You have an issue with the geo.showDocument, the argument you are passing (geo.docs is not indiced in the same way as your layers.data array, and you can't have a rational result that way. You should find another way to tell geoxml3 which document to hide, based for example on the url property of each cell of the geo.docs array, which will more consistently match the layers.data array.

For the KMZ parsing question, you need to use another branch of the geoxml3 library, checking out with svn this address: http://geoxml3.googlecode.com/svn/branches/kmz . It is still in development, so bugs are not excluded.