OpenStreetMaps POIs dynamisch erzeugen

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!
Status
Es sind keine weiteren Antworten möglich.

Lok33

Neues Mitglied
3 August 2010
16
0
0
#1
Hellow,

ich habe ein sehr nerviges Problemchen, wie am Threadthema bereits erkennbar, handelt es sich um ein Problem mit OpenStreetMaps / OpenLayers.. mal wieder. Ich arbeite gerade mit PhP auf Serverseite ( derzeit mit XAMPP simuliert ) und Javascript.

Ich möchte gerne auf einem bereits bestehenden map-Layer einen weiteren Layer für POIs ( Points of Interest ) auflegen, auf welchem ich über Ajax selbige projeziere. Ich habe diesbezüglich 2 Tutorials gefunden:

1. Openlayers POI layer example - OpenStreetMap Wiki

2. OpenLayers Dynamic POI - OpenStreetMap Wiki

Zweiteres ist vermutlich eher, was ich suche ( der Screenshot deutet zumindest das richtige an ), aber ich steige dort beim besten Willen nicht durch und die Links führen auch ins Nirvana :/.

Ersteres habe ich soweit einmal probiert und es hat geklappt. Dabei wird txt-file geschrieben, in welches die Punkte nacheinander in bestimmter Reihenfolge ihrer Angaben ( Längen / Breitengrad,Bild,etc... ) eingetragen werden und dann von der Funktion ausgelesen und bearbeitet werden. Ich habe das ganze mal mit Ajax "dynamisch" gemacht, aber hmmmm:

Meine Probleme an der Stelle sind 2erlei:

Erstens möchte ich eigentlich ungern immer eine txt-Datei erstellen müssen wo ich den Kram reinlade. Ich habe schonmal versucht, die Textdatei zu "simulieren", indem ich einen großen String gebaut habe, der mMn die Restriktionen für das txt-file eingehält.

(Wir befinden uns in dem für die Bearbeitung der AJAX-Funktion zuständigen PHP-Script)

$text = "lat lon title description icon iconSize iconOffset \n"

Das ist zunächst die nötige Definition der POI-Tabelle.
Dann konkatiniere ich diesen String mit einem kompletten Datensatz eines POIs, sprich:

$text .= $POI['Latitude']." ".$POI['Longitude']." Title One ".$POI['Content']." Ol_icon_blue_example.png 24,24 0,-24\n"

Damit klappts aber leider nicht >.<
Wenn ich das ganze so in ne txt file reinschreibe, gehts.... aber es könnte womöglich auch daran liegen, dass die Funktion für die Darstellung der Pois als Übergabeparameter NUR ein txtfile akzeptiert.... mein Ajax-call sieht so aus:

$.ajax({
type: "POST",
url: "showPOIsOnMap.php",
data: service,
success: function(poisformap){
alert(poisformap);
var pois = new OpenLayers.Layer.Text( "My Points",
{ location:poisformap,
projection: map.displayProjection
});
map.addLayer(pois);
},
error: function(poisformap){
alert("POI to map -> fail!")
}
});

ich übergehe jetzt mal den Punkt "data" und den rest, denn an der Stelle "alert(poisformap);" kommt das gewünschte raus... wenn ich da nochmal ein Wort drüber verlieren sollte, bitte anmerken.
Der wirklich spassige Teil ist der teil mit dem Aufruf zur Darstellung der POIs auf der Karte "new OpenLayers.Layer.Text". Hier übergebe ich der function mal NICHT das Textfile, sondern mal den konkatinierten String und HIER ist das Problem: es geht nicht... hat jemand dazu einen Denkanstoß, einen Ansatz oder gar eine Lösung?

Mein zweiteres Problem ist: Wenn ich das mit dem Textfile mache, so muss ich den Ajax-Call 2mal losschicken, dann erst kriege ich die POIs angezeigt :/... also das ist jetzt ne dumme Vermutung, aber ich habe mir gedacht, dass die Ajax-Funktion fertig ist, ehe das txt-file steht und ich daher noch nix zurück bekomme... und er das dann bestehende file beim 2ten mal tatsächlich laden kann... wobei die ajax-funktion ja eigentlich erst dann anspringt, wenn alles geladen ist.. oder?... aber naja... ich bin n nap und daher will ich da mal nichts vom Zaun reissen. Ich hoffe, mir kann jemand helfen, ich hab gerade irgendwie keinen anderne PLan, auch wenn ich weiter nach Tutorials forste...

Vielen Dank

Lok33
 

mermshaus

Senior HTML'ler
11 August 2009
5.369
38
48
www.ermshaus.org
#2
aber es könnte womöglich auch daran liegen, dass die Funktion für die Darstellung der Pois als Übergabeparameter NUR ein txtfile akzeptiert
Der Parameter erwartet eine URL.

Ich glaube, Ajax ist hier nicht sinnvoll, da OpenLayers benötigte Daten selbst nachladen kann.

Code:
<?php // Dateiname: poi.php

if (isset($_GET['poi'])) {
    $headers = array(
        'lat', 'lon',
        'title',
        'description',
        'icon', 'iconSize', 'iconOffset');
    $poi1 = array(
        '48.9459301', '9.6075669',
        'Title One',
        'Description one<br>Second line.<br><br>(click again to close)',
        'Ol_icon_blue_example.png', '24,24', '0,-24');
    $poi2 = array(
        '48.9899851', '9.5382032',
        'Title Two',
        'Description two.',
        'Ol_icon_red_example.png', '16,16', '-8,-8');

    echo implode("\t", $headers) . "\n"
       . implode("\t", $poi1) . "\n"
       . implode("\t", $poi2) . "\n";
    exit;
}

?>
<html><body>
  <div id="mapdiv"></div>
  <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
  <script>
    map = new OpenLayers.Map("mapdiv");
    map.addLayer(new OpenLayers.Layer.OSM());

    var pois = new OpenLayers.Layer.Text( "My Points",
                    { location:"./poi.php?poi",
                      projection: map.displayProjection
                    });
    map.addLayer(pois);

    //Set start centrepoint and zoom
    var lonLat = new OpenLayers.LonLat( 9.5788, 48.9773 )
          .transform(
            new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
            map.getProjectionObject() // to Spherical Mercator Projection
          );
    var zoom=11;
    map.setCenter (lonLat, zoom);
  </script>
</body></html>
 

Lok33

Neues Mitglied
3 August 2010
16
0
0
#3
Hi,

vieeelsten Dank für die Antwort, das klappt tatsächlich... okay, das mit der URL muss ich jetzt nochmal nachvollziehen, ich hab mit sowas noch nie grossartig gearbeitet, aber da steige ich hoffentlich noch dahinter.

Bei der Ajax-Sache hast du natürlich recht. Es würde ja reichen, beim einreichen von einem POI Satz die karte zunächst zu leeren und dann die POIs reinzuladen, macht nur Sinn.
Okay, ich werde mal versuchen, das in mein Progrämmle einzubinden.

Vielen Dank für die Hilfe :)

lok33
 

Lok33

Neues Mitglied
3 August 2010
16
0
0
#4
Hellow, isch bins nochmal,

ich habe das jetzt soweit schonmal reingestellt, es funktioniert auch im Grunde. Was ich jetzt allerdings machen möchte ist, dass das ganze teil dynamisch ist. Es ist jetzt insoweit dynamisch, also dass ich dem php file parameter übergeben kann und er diese lädt. Allerdings löscht er noch nicht die vorherigen, sondern erstellt ja quasi jedes mal einen neuen - macht ja auch sinn, ich gebe ihm nirgendwo den befehl, den alten zu löschen. Das ist jetzt das erste problem: ich weiss nicht, wie ich diesen layer lösche und erst dann einen weitere hinzufüge.. habe sachen probiert wie

if(pois){
pois.destroy;
}

var pois = new OpenLayers.Layer.Text( "My Points",
{ location:"./poi.php?services="+services,
projection: map.displayProjection
});
map.addLayer(pois);


Das bringt allerdings nicht viel... Was genau behandle ich da falsch? ich finde leider auf

OpenLayers.Layer.Text - OpenLayers

nicht allzuviel, was die funktionen machen :/

Wichtiger ist eigentlich noch: Es ist schonmal super, dass es so geht, aber gibt es eine Möglichkeit, folgendes zu tun:

Ich klicke nen Button, dann werden der Funktion "OpenLayers.Layer.Text" X parameter übergeben, mit welchen sie mit dem php-file Dinge aus der Datenbank lädt und diese in den layer einfügt.

Ich klicke den Button erneut mit 2 weiteren parametern Y und die funktion bearbeitet NUR noch die neuen Parameter, also (Y-X) und lädt diese in den Layer?

Ich will also quasi durchgehend nur einen einzigen layer haben auf welchem ich Punkte entfernen und hinzufügren kann, das ganze sehr sparsam. Ist diese Art der Bearbeitung möglich? Wenn ja, wäre es nett, wenn man mir sagen könnte, welche Komponenten dann nötig sind.

Vielen Dank im Voraus und schon bis hierhin!
 

mermshaus

Senior HTML'ler
11 August 2009
5.369
38
48
www.ermshaus.org
#5
Edit: Das hier ist teilweise falsch (siehe #7).

So dürftest du einen Layer von der Map entfernen können:

- OpenLayers.Map - OpenLayers

Das Hinzufügen eines neuen Layers dürfte klar sein.

Das Layer-Objekt wäre wohl das hier:

Code:
new OpenLayers.Layer.OSM()
Wenn du das einer Variable zuweist, bevor du es der Map hinzufügst, kannst du nach dem Entfernen des Layers vielleicht hier noch destroy() aufrufen. Ich kann aber nicht sagen, ob das notwendig ist.

So sollte es zumindest klappen.

Schöner wäre es eventuell, wenn du die "Placemarks"/POI-Objekte auf dem OSM-Layer direkt editieren könntest. Dazu habe ich aber bislang keine API finden können (habe aber auch nicht lange gesucht).
 
Zuletzt bearbeitet:

Lok33

Neues Mitglied
3 August 2010
16
0
0
#6
Hey mermshaus,
danke nochmal für den Link, ich schaue mir nochmal an, wie das klappt mit den layern. Ich habs mit dem destroy ja mal probiert, aber das war vermutlich falsch, zumindest WIE ich es benutzt habe... .

Du hast allerdings recht, es wäre viel besser, wenn ich direkt mit den POIs an sich arbeiten könnte anstelle nur mit einem Layer, auf welchem x POIs zusammengefasst sind. Habe aber ebenfalls keine möglichkeit gefunden, die POIs eines Layers anzusprechen... vllt findet sich ja doch noch etwas. Vielen Dank für die Hilfe :)
 

mermshaus

Senior HTML'ler
11 August 2009
5.369
38
48
www.ermshaus.org
#7
Sorry, ich merke gerade, ich habe die Objekthierarchie falsch interpretiert. Die lautet wohl:

Code:
Map
 +-- Layer (OSM)    # die Kartengrafiken
 +-- Layer (Text)   # die POI-Marker
Das heißt, der OSM-Layer sollte nicht verändert werden, da er nicht die Marker enthält, sondern die Kartengrafik. Du musst vermutlich doch mit OpenLayers.Layer.Text arbeiten.

- OpenLayers.Layer.Text - OpenLayers

Die Methoden dort sehen recht vielversprechend aus. clearFeatures() müsste wohl alle Marker löschen, mit loadText() könnten sich neue Daten reinladen lassen.
 

Lok33

Neues Mitglied
3 August 2010
16
0
0
#8
Hey,

kein Thema, ich habs mir durchgelesen und habe auch gemerkt, dass da was nicht stimmen konnte ;) Aber im Grunde musste man ja nicht viel ändern.

So, wie ich es verstehe habe,erstelle ich durch einen Aufruf "map = new OpenLayers.Map("basicMap");" einen basis-layer, auf welchem ich andere aufsetzen kann. Dann habe ich genau wie du interpretiert, dass ich einen layer für die Kartendaten habe, in meinem Fall:

var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);

Die gesamte Prozedur ist ja quasi aus dem OSM-Tutorial genommen, wenn wir uns errinnern:

function init() {
map = new OpenLayers.Map("basicMap");
var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);

map.setCenter(new OpenLayers.LonLat(<?php echo($user->Longitude);?>,<?php echo($user->Latitude);?>) // Center of the map
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
), 15 // Zoom level
);
}

Dann füge ich an einer Stelle einen weiteren layer "pois" hinzu:

pois = new OpenLayers.Layer.Text( "My Points",
{location:"./poi.php?"+services, //I dont understand how this one works...
projection: map.displayProjection
});
map.addLayer(pois);

Jetzt müsste mein Basis-Layer "map" über 2 weitere Layer verfügen: "mapnik" und "pois"

Das bestätigt sich auch darin, dass ich mal den "mapnik"-layer in der init()-Funktion NICHT privat gemacht habe ( also das "var mapnik =..." in ein "mapnik = ..." geändert habe und dann irgendwo auf knopfdruck mal eine funktion ausgelöst habe, die sagt:

map.removeLayer(mapnik);

Daraufhin hat sich das gesamte Kartenmaterial aufgelöst und ich hatte eine schöne weisse Fläche :D Nutzlos, aber weiss!

Ich kann also EINEN Layer mit "map.removeLayer(pois)" zerstören, wenn ich den Aufruf der "OpenLayers.Layer.Text"-Funktion in der variable "pois" speichere. Allerdings nur einen, da ja durch den erneuten aufruf ein neues object mit altem Namen kreiert wird und das alte Object dann quasi unerreichbar wird. Ich habe mir jetzt gedacht, dass ich folgendes mache:

Ich schmeisse jeden einzelnen neuen layer auf die karte (mit der "OpenLayers.Layer.Text"-funktion) und pushe diesen dann in einen array "POILayers". Ich hoffe, dass ich dann hinterher, wenn ich alle Layer löschen möchte für jedes objekt im array durchlaufe und dieses mit .removeLayer(i) zerstöre. Das war jetzt zumindest so mein Plan... Das müsste umsetzbar sein, oder?

btw sorry für den hässlichen code :/
 
Zuletzt bearbeitet:
Status
Es sind keine weiteren Antworten möglich.