Mehrere KML-Layer

Hallo zusammen,

ich bin aktuell dabei, mir eine Karte zu erstellen, auf der ich meine eigenen POIs mittels KML als Vektor-Layer darstelle. Das funktioniert soweit auch.

Ich möchte das ganze jetzt insofern verändern, als dass für jede im Ordner befindliche KML-Datei ein eigener einblendbarer Layer entsteht.

Da ich in JavaScript nicht wirklich fit bin und Arrays insgesamt nicht so meine Stärke sind, würde ich mich freuen, wenn mir jemand ein Codebeispiel zeigen oder einen Programmiervorschlag geben könnte.

Hier mein bisheriger JS-Code:

    map = new OpenLayers.Map("mapdiv");
    map.addLayer(new OpenLayers.Layer.OSM("Local Tiles", "tiles/${z}/${x}/${y}.png", {numZoomLevels: 19, alpha: true, isBaseLayer: true}));
       
	var kml = new OpenLayers.Layer.Vector("KML", {
			strategies: [new OpenLayers.Strategy.Fixed()],
			protocol: new OpenLayers.Protocol.HTTP({
				url: "kml/test.kml",
				format: new OpenLayers.Format.KML({
					extractStyles: true, 
					extractAttributes: true,
					maxDepth: 2
				})
			})
		});

    
	map.addLayer(kml);
    

    var lonLat = new OpenLayers.LonLat( 7.21495 ,50.54819 )
          .transform(
            new OpenLayers.Projection("EPSG:4326"), 
            map.getProjectionObject() 
          );
    var zoom=17;
    map.setCenter (lonLat, zoom);  
    
    
    
    
  
    var controls = {
      selector: new OpenLayers.Control.SelectFeature(kml, { onSelect: createPopup, onUnselect: destroyPopup })
    };

    function createPopup(feature) {
      feature.popup = new OpenLayers.Popup.FramedCloud("pop",
          feature.geometry.getBounds().getCenterLonLat(),
          null,
          '<div class="markerContent">'+feature.attributes.description+'</div>',
          null,
          true,
          function() { controls['selector'].unselectAll(); }
      );

      map.addPopup(feature.popup);
    }

    function destroyPopup(feature) {
      feature.popup.destroy();
      feature.popup = null;
    }
    
    map.addControl(controls['selector']);
    controls['selector'].activate();

Vielen Dank bereits vorab!

Moin,

ich würde heute nicht mehr auf KML-Layer sondern auch GeoJSON setzen, und wenn Du nun erst anfängst könnte das mit Leaflet für Dich alles viel einfacher sein als sich noch mit dem alten OpenLayers einzuarbeiten.
Hier ein schönes Beispiel: http://bmcbride.github.io/bootleaf/
Und der Quelltext dazu: https://github.com/bmcbride/bootleaf

LG,

-moenk

Hallo moenk,

danke für die Links.
Ich habe im Betrieb jedoch eine Anwendung, die mit Openlayers arbeitet.
Es besteht jedoch die Möglichkeit eigenen JavaScript-Code mit einzubinden.
Daher bin ich an Openlayers gebunden.
Da eine andere Anwendung wiederum Geodatensätze in Form von KML-Dateien exportieren kann, wollte ich entsprechend genau diese Form wählen.

Im absoluten Notfall würde ich es auch mit GeoJSON versuchen. Dann müsste ich die Inhalte der KML-Dateien halt irgendwie möglichst geschmeidig umwandeln und dann das gleiche Problem (“Einlesen mehrerer Files”), für GeoJSON versuchen zu lösen.

Sollte also einer ein Beispiel oder einen Code-Vorschlag für das Einbinden mehrerer vorher nicht konkret bestimmbarer KML-Dateien haben, wäre das für mich die 1A-Lösung.

Gruß

Bali

Statt

var kml = new OpenLayers.Layer.Vector("KML",  ..... url: "kml/test.kml" ... ;
map.addLayer(kml);

kannst du auch einfach

map.addLayer(new OpenLayers.Layer.Vector("KML",  ..... url: "kml/test.kml" ... );

schreiben.

Und für viele KML-Layer dann einfach

map.addLayer(new OpenLayers.Layer.Vector("KML",  ..... url: "kml/test.kml" ... );
map.addLayer(new OpenLayers.Layer.Vector("KML",  ..... url: "kml/nochtesttest.kml" ... );
map.addLayer(new OpenLayers.Layer.Vector("KML",  ..... url: "kml/drittertest.kml" ... );
map.addLayer(new OpenLayers.Layer.Vector("KML",  ..... url: "kml/viertertest.kml" ... );

Damit hast Du aber die Vorgabe “für jede im Ordner befindliche KML-Datei” nurt halb erfüllt. Darum kann sich aber Javascript oder Openlayers oder Leaflet nicht kümmern, wei die laufen im Browser und wissen nicht, was im Ordner auf deinem Server liegt. Da kann man sicher was kompliziertes basteln (beim Server nachsehen, was im Verzeichnis liegt und dann in JS eine Schleife bauen), oder was einfaches serverseitiges: Eine kleine Schleife in PHP. die für jede Dateie eine dieser Zeilen oben erzeugt.

Grüße, Max

Hi Max,

vielen Dank schonmal!

Hatte zwischenzeitlich noch weiter gegoogelt und bin dabei auf diese Codeschnipsel hier (http://osgeo-org.1560.x6.nabble.com/Feature-select-doesn-t-work-with-multiple-KML-files-td3921067.html) gestoßen.
Ich hatte daraus geschlossen, dass es zumindest im selben Ordner möglich sein sollte alle Dateien des gleichen Typs in einen Array einzulesen.
Ich habe es aber leider nicht umgesetzt bekommen.

Wenn ich das falsch verstanden haben und es nur ein geringer Aufwand sein sollte, wäre es super nett, wenn du oder jemand anderes mir zeigen könnte, wie man deinen Vorschlag im Zusammenspiel mit einer PHP-Schleife umsetzen könnte.

Da werden alle Dateien aus einem Verzeichnis geholt, aber man weiss schon vorher wie die heissen, nämlich relation_“+canals…+”.kml und was in “canals” steht, muss man ebenfalls vorher wissen.

Hier habe ich drei KML-Dateien mit Häusern, Wegen und Cafes in einem Verzeichnis. Der Quelltext des php-Progrämmchens ist im wesentlichen aus dem Manual geklaut. Da sieht man auch gleich, warum das nicht soo gut ist. Klugerweise würde man die unscheinbaren Cafe-Icons über allen anderen Layrn darstellen. Weil das Verzeichnis aber willkürlich sortiert ist, liegen die unter den massiven Häusern und veschwinden.

Grüße, Max

Moin,

sag doch gleich dass Du eine alten Software einsetzen musst. Ich meine mich zu erinnern, dass man nur einen KML-Layer zur Zeit interaktiv haben kann. Du kannst also weitere KML-Layer der Karte adden aber nur den aktiven abfragen. Ich meine das hier http://www.mauerkarte.de/ so umgangen zu sein dass ich die Layer als Parameter aus einer Navigation aufgerufen habe, ist aber schon ein paar Jahre her.

LG,

-moenk

Stimmt… Man kommt hier erst mal nur an die Popups für die Wege ran. Die für Häuser gibts erst, wenn der Layer mit den Wegen weg ist. Bei den Häusern und Cafe leuchtet das dem Nutzer ein, bei anderen Kombinationen ist er ratlos…

Grüße, Max

Nö, stimmt nicht: Man kann ein SelectFeature auch an viele Layer binden. (PHP dazu, da muss aber noch was gemacht werden, z.B. wenn im Verzeichnis 0 kml-Dateien liegen…)

Danke euch Beiden,
hab alle Beispiele mal durchprobiert.

Da ich in der Anwendung leider keinen Zugriff auf den Server, sondern lediglich auf das Html-Dokument habe, muss ich auf die PHP-Variante leider verzichten.
Ich habe es jetzt doch mit einem Array gemacht, da die KML-Datei-Bezeichnungen logisch aufsteigen, sodass ich einfach Hülsen verwenden kann.

@Max: Lässt sich dein letztes Beispiel auch lokal (ohne Server) ausführen?

Kannst probieren, wennst dir die html-Datei und die vier kml-Datein runterlädtst: http://geo.dianacht.de/tests/kml3/kml3.zip
Kann aber auch sein, dass Dein Browser kein Javascript von der lokalen Festplatte ausführt oder so…

Allerdings gibts dann kein Auslesen des Verzeichnisses, nur vorher bekannte und in die html-Datei getippte kml-Dateien werden dargestellt.

Grüße, Max

Super, jetzt läuft’s ganz herzlichen Dank mal wieder!

Hallo nochmal,

jetzt hab ich doch nochmal eine Frage.

Ich würde gerne die leeren Hülsen nicht alle als bereits hinzugefügte Layer in meinem Switcher angezeigt bekommen.
Ich habe versucht die jeweilige KML-Datei auf Inhalte zu prüfen, um davon abhängig zu machen, ob ich den Layer hinzufüge.

Ich hatte u.a. hier (http://forum.openstreetmap.org/viewtopic.php?pid=506771) bereits gelesen, dass das Laden der KML asynchron im Hintergrund läuft, habe es aber bislang trotzdem nicht geschafft, diese Prüfung umzusetzen.

Vielleicht kann mir da doch nochmal jemand einen Tipp geben.

Danke und Gruß

Bali

Du könntest vorher nachsehen, od der Link zur kml-Datei existiert… (glaub ich… selbst noch nie probiert…)

Die verlinkte Prüfung funktioniert leider so nicht.
Das Problem scheint darin zu liegen, dass eine nicht vorhandene Datei (anders als eine nicht vorhandene Website) kein Ergebnis zurück liefert.

Folgende Fehlermeldung kommt beim Versuch, den Code auszuführen zustande.

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied

Irgendeine Idee, wie man das umgehen kann
oder
wie ich die jeweilige KML-Datei nicht auf Existenz, sondern auf Inhalte prüfen könnte?

Ich habe das Problem jetzt lösen können. :slight_smile:

Gemäß dem Beispiel auf: http://www.w3schools.com/dom/tryit.asp?filename=try_dom_getattribute

habe mir eine loadxmldoc.js mit folgendem Inhalt angelegt:

function loadXMLDoc(dname) 
{
if (window.XMLHttpRequest)
  {
  xhttp=new XMLHttpRequest();
  }
else
  {
  xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xhttp.open("GET",dname,false);
xhttp.send();
return xhttp.responseXML;
}

Meine KML konnte ich dann wie folgt auf Inhalt prüfen und den Layer in Abhängigkeit des Prüfergebnisses hinzufügen:

xmlDoc=loadXMLDoc("kml/test.kml");

x=xmlDoc.getElementsByTagName('name');

if (x[0] != undefined)
{
map.addLayer(kml_1);
}

Wichtig ist einzig, dass die KML-Datei (hier: (“kml/test.kml”) in jedem Fall als leere Hülse bereits vorhanden ist. Sonst kann die Seite aufgrund folgenden Fehlers nicht geladen werden:

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied

Vielen Dank für die viele Hilfe - insbesondere an Max.