x

Eigene LiveMap bauen - Position mit Echtzeit und Funktionalitäten


  1. Eigene LiveMap bauen - Position mit Echtzeit und Funktionalitäten · KapitanRamius (Gast) · 05.09.2014 11:39 · [flux]

    Hallo ihr,

    folgendes ist mein Ziel:

    eine LiveMap.

    Eine LiveMap auf der die aktuellen Positionsdaten von verschiedensten Dingen angezeigt werden.

    Anforderungen:

    Die zugrunde liegende Karte soll Openstreetmap sein.

    die Dinge brauchen individuelle Symbole als Markierungen, damit diese ihren Typ und/oder Zustand widerspiegeln.

    Wenn ich ein solches Symbol anklicke sollen Funktionalitäten ausgelöst werden, ein anzeigen eines Info-Popups ist nicht ausreichend. Zum Beispiel soll ein Klicken auf ein solches Symbol das Auslesen der Datenbank und das füllen von einem Menü mit den Zusatzinformationen aus der Datenbank angestoßen werden.

    Die Positionen der Symbole der einzelnen Dinge sollen sich automatisch auf der Karte den neuen Informationen anpassen. Ohne, dass sich die Karte neu lädt, verschiebt oder den Zoom verändert.

    Es sollen damit mehrere hundert Dinge dargestellt werden.

    Technik:

    ich verwende zum verwalten der Positionsdaten eine PostgreSQL-Datenbank.

    Das Projekt ist eine dynamische Java Webapplikation.

    Die Dinge deren Position ich gerne visualisieren möchte, liefern stetig ihre GPS-Daten an die Datenbank.

    Eine Java-Bean soll diese auslesen und der Openstreetmap bereitstellen.

    Die eingesetzte Technik für Bean/Xhtml ist JSF 2.1

    Bisherige erfolge:

    ich habe es geschafft, dass ich die Positionsdaten aus der Datenbank durch eine Bean laden kann und diese einer Map übergebe. Ich habe die Daten somit direkt als eine Liste von Variablen in die xhtml geschrieben, welche dann vom JavaScript interpretiert wird:

    haltestellenVectorLayer␣=␣new␣OpenLayers.Layer.Vector("Haltestellen");
    map.addLayer(haltestellenVectorLayer);
    //var␣iconUrl␣=␣'http://localhost:10080/osm/resources/img/logo/Bus.png';
    var␣iconUrl␣=␣"";
    var␣anzahlHaltestellen␣=␣haltestellen.length;
    for␣(var␣i␣=␣0;␣i␣<␣anzahlHaltestellen;␣i++)
    {
    if␣((haltestellen[i]["title"]␣!=␣null)␣&&␣(haltestellen[i]["title"]␣!=␣"null"))
    {
    var␣info␣=␣haltestellen[i]["description"]␣+␣"</br>"␣+␣haltestellen[i]["adresse"];
    var␣title␣=␣haltestellen[i]["title"];
    var␣haltestelleUebernehmen␣=␣"</br></br><input␣id='haltestelleUebernehmen'␣type='submit'␣onclick='haltestelleAuswaehlen("␣+␣title␣+␣");'␣value='Auswählen'␣/></br></br><input␣id='haltestelleRoute'␣type='submit'␣onClick='haltestelleRouteAnzeigen("␣+␣title␣+␣");'␣value='Route␣anzeigen'␣/>";
    if(title␣==␣haltestellenr)
    {
    iconUrl␣=␣iconUrlHaltestelleEinstieg;
    setzeLabelEntfernung(haltestellenr);
    }
    else
    {
    iconUrl␣=␣iconUrlHaltestelle;
    }
    
    var␣desc␣=␣fuegeEntfernungHinzu(latHaltestelle,␣lonHaltestelle,␣info)␣+␣"</br>Wabe:</br>"␣+␣wabe␣+"</br>"␣+␣"</br>Linien:</br>"␣+␣linien␣+␣haltestelleUebernehmen;
    haltestellenVectorLayer.addFeatures(erstelleVectorLayerFeature(lonHaltestelle,␣latHaltestelle,␣title,␣desc,␣iconUrl));
    }
    }
    

    Das klappt wunderbar, ist aber auch wunderbar statisch. Denn diese Daten werden immer nur dann geladen wenn sich die Seite Aufbaut. Ein späteres „refreshen“ der xhtml führt immer zu neu laden der Karte was ich vermeiden möchte.

    Eine andere Lösung war es, eine andere externe Datei dafür zu nehmen. Denn die lässt sich einfach auslesen:

    <html><body>
    <input␣type="button"␣name="Text␣1"␣value="Manuelle␣Refresh"
    onclick=refresher()␣>
    <div␣id="mapdiv"␣height="500px"></div>
    <script␣src="http://www.openlayers.org/api/OpenLayers.js"></script>
    <script>
    
    function␣clickMe(text)
    {
    alert(text);
    }
    
    var␣map;
    var␣pois;
    
    window.open(testi());
    
    var␣aktiv␣=␣window.setInterval("refresher()",␣5000);
    
    function␣refresher()
    {
    pois.clearFeatures();
    testi2();
    }
    
    function␣testi()
    {
    map␣=␣new␣OpenLayers.Map("mapdiv");
    map.addLayer(new␣OpenLayers.Layer.OSM());
    
    pois␣=␣new␣OpenLayers.Layer.Text(␣"My␣Points",
    {␣location:"./textfile.txt",
    projection:␣map.displayProjection
    });
    map.addLayer(pois);
    
    var␣lonLat␣=␣new␣OpenLayers.LonLat(␣10.0381,␣53.5744␣)
    .transform(
    new␣OpenLayers.Projection("EPSG:4326"),
    map.getProjectionObject()
    );
    var␣zoom=11;
    map.setCenter␣(lonLat,␣zoom);
    
    }
    
    function␣testi2()
    {
    pois␣=␣new␣OpenLayers.Layer.Text(␣"My␣Points␣Extra",
    {␣location:"./textfile.txt",
    projection:␣map.displayProjection
    });
    map.addLayer(pois);
    }
    
    </script>
    </body></html>
    

    Auf gut geklappt. Jedoch flackern die Symbole manchmal wenn die Daten erneuert werden. Das ist auf die Dauer ein wenig anstrengend. Weiterhin habe ich bisher nur die Möglichkeit beim Klick auf ein Symbol ein Popupenster erscheinen zu lassen. Ich würde aber lieber gleich eine Funktionalität starten. Sei es Java Sript oder direkt eine Methode von der Bean.
    Auch empfinde ich es als unnötigen aufwand, die externe Datei stets mit den aktuellen Daten zu versehen um sie dann wieder auslesen zu können. Lieber wäre mir, ich könnte durch die Bean die Informationen regelmäßig aus der Datenbank holen und der Karte so zur Verfügung stellen.
    Und durch das aktualisieren werden geöffnete PopUps geschlossen.

    Was ich gerne erreichen würde:

    GPS Sender
    GPS Sender → Datenbank ↔ Bean ↔ xhtml mit OSM.Karte
    GPS Sender

    Mein ehrgeiziges Ziel ist so etwas wie dieses absolut geniale Fundstück:

    http://server03.fassisystem.de/egb/web/

    Ich habe mich durch unzählige Beispiele gearbeitet und immer wieder verschiedenste Brocken Code aufgeschnappt. Allerdings musste ich auch immer wieder feststellen, dass diese einzelnen Code-Schnipsel selten mit einander harmonisieren und nie alle Anforderungen von mir erfüllen.

    Hat jemand von euch eine Idee? Oder ein hilfreiches Tutorial zur Hand?

    Vielen Dank!