Durch Klick auf Karte Koordinate in Textfeld

Hallöchen,

bin absoluter neu hier und auch absoluter Neuling auf der OSM Ebene.

Ich habe diesen Beitrag auch im Dev Forum geschrieben, da ich aber nicht weiss, wieviele dort so lesen, schreibe ich auch noch mal hier.

Ich benötige ein Snippet / Script o.ä., mit dessen Hilfe es mir möglich ist, per Klick auf Karte die entsprechende Koordinate in ein Textfeld zu packen.
Denke, das Ganze löppt per Javascript, nur habe ich davon keinen blassen Schimmer.

Daher meine Frage an euch: Hat jemand irgendwo mal ein Snippet oder möglicherweise fertiges Script gesehen?

Würde mich über Feedback freuen.

Beste Grüße aus Wilhelmshaven,

Boris

Hallo, also das ermitteln der Koordinaten ist nur eine Option die man anschalten muss. Openstreetmap.DE nutzt das:
http://www.openstreetmap.de/karte.html?lon=10.30000&lat=51.30000&zoom=5

Wie man das an Javascript weiterreicht weiß ich leider nicht. Such doch mal in der OPENLAYERs Docs, so heißt die UI die OSM hier nutzt.

Würde es nicht reichen, wenn die Koordinaten z.b. unten Rechts angezeigt werden? Dies wäre über openlayers.org recht einfach gemacht. Siehe dieses Beispiel

Versuchs doch mal damit:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Koordinaten Click Beispiel</title>
<meta http-equiv="content-type" content="text/html;charset={{charset}}" />
<meta http-equiv="content-script-type" content="text/javascript" />
<meta http-equiv="content-style-type" content="text/css" />
<meta http-equiv="content-language" content="de" />

<!-- Externe Scripte -->
<!-- OpenLayers API (stellt die OpenLayers Funktionen bereit) -->
<script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"></script>
<!-- OpenStreetMap Klassen (ermöglicht das einfache Einbinden der OSM-Karten) -->
<script type="text/javascript" src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script type="text/javascript">
    //<![CDATA[


// Hilfsfunktionen
function jumpTo(lon, lat, zoom) {
    var x = Lon2Merc(lon);
    var y = Lat2Merc(lat);
    map.setCenter(new OpenLayers.LonLat(x, y), zoom);
    return false;
}
 
function Lon2Merc(lon) {
    return 20037508.34 * lon / 180;
}
 
function Lat2Merc(lat) {
    var PI = 3.14159265358979323846;
    lat = Math.log(Math.tan( (90 + lat) * PI / 360)) / (PI / 180);
    return 20037508.34 * lat / 180;
}

var map;

/*
 * Die Erstellung der Karte, sobald die Seite fertig geladen ist.
 */
function drawmap() {
    OpenLayers.Lang.setCode('de');
    
    map = new OpenLayers.Map('map', {
        projection: new OpenLayers.Projection("EPSG:900913"),
    displayProjection: new OpenLayers.Projection("EPSG:4326"),
    controls: [
        new OpenLayers.Control.MouseDefaults(),
        new OpenLayers.Control.Attribution()],
    maxExtent:
    new OpenLayers.Bounds(-20037508.34,-20037508.34,
                                    20037508.34, 20037508.34),
    numZoomLevels: 18,
    maxResolution: 156543,
    units: 'meters'
    });

    // Noch mehr Kontrollelemente hinzufügen..
    map.addControl(new OpenLayers.Control.LayerSwitcher());
    map.addControl(new OpenLayers.Control.PanZoomBar());

    // Position und Zoomstufe der Karte
    lon = 9;
    lat = 49;
    zoom = 6; 

    // Layer hinzufügen (OpenStreetMap Mapnik)
    layer_layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
    map.addLayer(layer_layerMapnik)

    // An die richtige Stelle springen..
    jumpTo(lon,lat,zoom);


    // Click Control zur Karte hinzufügen
    click = new OpenLayers.Control.Click();
    map.addControl(click);

    // Aktivieren (kann auch mit click.deactivate() wieder deaktiviert werden)
    click.activate();
}

/*
 * ClickHandler zum Marker-Koordinaten Auswählen
 */
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
                defaultHandlerOptions: {
                    'single': true,
                    'double': false,
                    'pixelTolerance': 0,
                    'stopSingle': false,
                    'stopDouble': false
                },

                initialize: function(options) {
                    this.handlerOptions = OpenLayers.Util.extend(
                        {}, this.defaultHandlerOptions
                    );
                    OpenLayers.Control.prototype.initialize.apply(
                        this, arguments
                    ); 
                    this.handler = new OpenLayers.Handler.Click(
                        this, {
                            'click': this.trigger
                        }, this.handlerOptions
                    );
                }, 

                trigger: function(e) {
            // In GPS Koordinaten umwandeln
            var lonlat = map.getLonLatFromViewPortPx(e.xy).transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
            
            // Die Werte in die Textfelder schreiben
            document.getElementById("lat").value = lonlat.lat;
            document.getElementById("lon").value = lonlat.lon;
                }

            });

//]]>
    </script>
</head>
<body onload="drawmap();">
    <!-- Karte (CSS könnte auch ausgelagert werden) -->
    <div id="map" style="width:400px;height:400px;"></div>
    <!-- Beispielformularfelder (sollte natürlich noch richtig in ein Formular) -->
    Lat: <input type="text" value="" id="lat" />
    Lon: <input type="text" value="" id="lon" />
</body>
</html>

Ich fürchte du hast nur die Beispielliste verlinkt, nicht das ausgewählte Beispiel (die Seite nutzt Frames).

@dt

Das war doch schonmal supi :slight_smile:

Wie könnte man es realisieren (bitte anfängerkonform beschreiben), dass bei Klick 1 zwei Textfelder (Lat, Lng) gefüllt werden und bei Klick zwei weitere zwei Textfelder mit den Daten der Koordinate zwei? Und diese beiden Punkte dann zu einem Rechteck verbinden? Ich weiss, ist jetzt ein wenig Brainstorming, aber wie gesagt, ich habe von JavaScript überhaupt keinen Schimmer. Nach meiner Klausurenphase wollte ich mir mal vornehmen, etwas mehr darüber zu lernen, aber das ist leider noch ein wenig hin.

http://openlayers.org/dev/examples/ Such da mal nach “draw”

Vielleicht wäre es sinnvoll wenn du mal beschreiben würdest, wofür du das brauchst.

Eigentlich schnell erklärt.

Auf einer Karte soll der User die Möglichkeit haben, zwei Koordinaten auszuwählen, die dann zu einem Rechteck verbunden werden. Dieses Rechteck soll dann einen geographischen Zaun (Geofence) darstellen. Die beiden ausgewählten Koordinaten sollen dann in 4 Textfeldern landen, damit bei einem Klick auf einen Button die Werte in einer Datenbank gespeichert werden. So soll der User einen Alarm erhalten, wenn sich etwas aus dieser Zelle herausbewegt.

bravo Fred… jetzt sehe ich das erst, dass da noch was an mich gerichtet war… sorry, dass ich nicht antwortete… habe das voll übersehen.
gut, was ich meinte, war http://www.openlayers.org/dev/examples/mouse-position.html

aber wie dt2 schon um 18:41 erwähnte: um was geht’s überhaupt? wenn man nur dir koordinaten sehen will, reicht das eigentlich schon. will man diese aber weiter verwenden, gibt es viel bessere lösungen. aber man müsste wissen, um was es geht…

Eigentlich schnell erklärt.

Auf einer Karte soll der User die Möglichkeit haben, zwei Koordinaten auszuwählen, die dann zu einem Rechteck verbunden werden. Dieses Rechteck soll dann einen geographischen Zaun (Geofence) darstellen. Die beiden ausgewählten Koordinaten sollen dann in 4 Textfeldern landen, damit bei einem Klick auf einen Button die Werte in einer Datenbank gespeichert werden. So soll der User einen Alarm erhalten, wenn sich etwas aus dieser Zelle herausbewegt.

Was für “bessere” Lösungen gäbe es denn? Bin wirklich für jeden Tip dankbar :wink:

Ich denke, Du benötigst sowas wie in der Exportfunktion von OSM.org.
Gehe mal auf: http://www.openstreetmap.org/export/
Klicke dort auf “Einen anderen Kartenausschnitt manuell auswählen”, dann kann man einen Rahmen auf der Karte ziehen und die Koordinaten davon werden links ausgegeben…

Japs und die nutzen IMHO die vorgefertigten Funktionen aus der OpenLayers Lib und zapfen die MouseRelease Events an um die Werte in die Boxen zu schreiben.

Und genau das ist es, was ich gesucht habe.

Habe mir sämtliche Dateien unter Beachtung der Pfade auf die lokale Platte gezogen und versucht, die Seite einmal aufzurufen, mit dem Ergebnis, dass die Seite nicht mal ansatzweise so aussieht, wie die Seite, die von euch verlinkt wurde.
Es sieht fast aus, als fehlt bei mir ein CSS, habe das Ganze nochmal überprüft, aber es ist alles identisch.

Woran kann das nun liegen?

Oder wie kann ich die Funktion, die OSM dort verwendet, auf meine Karte anwenden? Ohne großen Schnickschnack?
Über nen Dreizeiler wird man das Vorhaben wohl leider nicht lösen können.

Ich bekomme es nicht mal geschissen, eine Linie aufs Papier bzw. auf die Karte zu bringen.

Kann mir jemand sagen, an welche Stelle hier was müsste?

Ein kleines Beispiel würde mir schon reichen.


<head>
    <title>OpenStreetMap</title>
 
    <!-- bring in the OpenLayers javascript library
         (here we bring it from the remote site, but you could
         easily serve up this javascript yourself) -->
    <!--Meiner<script src=\"OpenLayers.js\"></script> -->
          
          <script src=\"OpenLayers.js\" type=\"text/javascript\"></script>

    <!-- bring in the OpenStreetMap OpenLayers layers.
         Using this hosted file will make sure we are kept up
         to date with any necessary changes -->
    <!--Meiner<script src=\"OpenStreetMap.js\"></script>  -->
    <meta http-equiv=\"refresh\" content=\"30; URL=show_map.php\">
 
     <script src=\"http://openstreetmap.org/openlayers/OpenStreetMap.js\"></script>
             

    <script type=\"text/javascript\">
        // Start position for the map (hardcoded here for simplicity,
        // but maybe you want to get from URL params)
        var lat=$ergebnis1
        var lon=$ergebnis2
        var zoom=16
    

 

 
 
 
        var map; //complex object of type OpenLayers.Map
    
        //Initialise the 'map' object
        function init() {       
            map = new OpenLayers.Map (\"map\", {
                controls:[ 
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.LayerSwitcher(),
                    new OpenLayers.Control.Attribution()],
                maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
                            maxResolution: 156543.0399,
                numZoomLevels: 13,
                units: 'm',
                projection: new OpenLayers.Projection(\"EPSG:900913\"),
                displayProjection: new OpenLayers.Projection(\"EPSG:4326\")
            } );
 
       
            // Define the map layer
            // Note that we use a predefined layer that will be
            // kept up to date with URL changes
            // Here we define just one layer, but providing a choice
            // of several layers is also quite simple
            // Other defined layers are OpenLayers.Layer.OSM.Mapnik, OpenLayers.Layer.OSM.Maplint and OpenLayers.Layer.OSM.CycleMap
            layerMapnik = new OpenLayers.Layer.OSM.Mapnik(\"Mapnik\");
            map.addLayer(layerMapnik);
            layerTilesAtHome = new OpenLayers.Layer.OSM.Osmarender(\"Osmarender\");
            map.addLayer(layerTilesAtHome);
            layerCycleMap = new OpenLayers.Layer.OSM.CycleMap(\"CycleMap\");
            map.addLayer(layerCycleMap);
            layerMarkers = new OpenLayers.Layer.Markers(\"Markers\");
            map.addLayer(layerMarkers);
 
            var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection(\"EPSG:4326\"), map.getProjectionObject());
            map.setCenter (lonLat, zoom);
 
            var size = new OpenLayers.Size(40,40);
            var size2 = new OpenLayers.Size(35,35);

            var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
            var offset2 = new OpenLayers.Pixel(-(size2.w/2), -size2.h);
                        var icon2 = new OpenLayers.Icon('../images/centerPoi.gif',size2,offset2);
            
            //Anfang
var markers = new OpenLayers.Layer.Markers( \"Markers\" );
map.addLayer(markers);

var size = new OpenLayers.Size(10,17);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon4 = new OpenLayers.Icon('Ol_icon_red_example.png',size,offset);
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(lon,lat),icon4));

            //ende
            
            
            
            
            
                        layerMarkers.addMarker(new OpenLayers.Marker(lonLat,icon2));
                        
        }
    </script>


</head>

Den Code von openstreetmap.org verstehe ich auch nicht wirklich. Aber ich hab mal was zusammengebaut, das so ähnlich funktioniert. Dabei wird das Rechteck allerdings vom Mittelpunkt aus gezeichnet. Ich weiß nicht wie man das Verhalten ändern kann, außer OpenLayers.Handler.Box zu benutzen, bei dem es bei mir allerdings zu Fehlern in OpenLayers kommt (entweder ein Bug in OpenLayers oder ich mache was falsch).


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
<title>Rechteck Beispiel</title>
<meta http-equiv="content-type" content="text/html;charset={{charset}}" />
<meta http-equiv="content-script-type" content="text/javascript" />
<meta http-equiv="content-style-type" content="text/css" />
<meta http-equiv="content-language" content="de" />

<!-- Externe Scripte -->
<!-- OpenLayers API (stellt die OpenLayers Funktionen bereit) -->
<script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"></script>
<!-- OpenStreetMap Klassen (ermöglicht das einfache Einbinden der OSM-Karten) -->
<script type="text/javascript" src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script type="text/javascript">
    //<![CDATA[


// Hilfsfunktionen
function jumpTo(lon, lat, zoom) {
    var x = Lon2Merc(lon);
    var y = Lat2Merc(lat);
    map.setCenter(new OpenLayers.LonLat(x, y), zoom);
    return false;
}
 
function Lon2Merc(lon) {
    return 20037508.34 * lon / 180;
}
 
function Lat2Merc(lat) {
    var PI = 3.14159265358979323846;
    lat = Math.log(Math.tan( (90 + lat) * PI / 360)) / (PI / 180);
    return 20037508.34 * lat / 180;
}

var map;

/*
 * Die Erstellung der Karte, sobald die Seite fertig geladen ist.
 */
function drawmap() {
    OpenLayers.Lang.setCode('de');
    
    map = new OpenLayers.Map('map', {
        projection: new OpenLayers.Projection("EPSG:900913"),
    displayProjection: new OpenLayers.Projection("EPSG:4326"),
    controls: [
        new OpenLayers.Control.MouseDefaults(),
        new OpenLayers.Control.Attribution()],
    maxExtent:
    new OpenLayers.Bounds(-20037508.34,-20037508.34,
                                    20037508.34, 20037508.34),
    numZoomLevels: 18,
    maxResolution: 156543,
    units: 'meters'
    });

    // Noch mehr Kontrollelemente hinzufügen..
    map.addControl(new OpenLayers.Control.LayerSwitcher());
    map.addControl(new OpenLayers.Control.PanZoomBar());

    // Position und Zoomstufe der Karte
    lon = 9;
    lat = 49;
    zoom = 6; 

    // Layer hinzufügen (OpenStreetMap Mapnik)
    layer_layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
    map.addLayer(layer_layerMapnik);
    layer_vectors = new OpenLayers.Layer.Vector("Zeichnungen", { displayInLayerSwitcher: false } );
    map.addLayer(layer_vectors);

    // An die richtige Stelle springen..
    jumpTo(lon,lat,zoom);

    polyOptions = {sides: 4, snapAngle: 45};
    polygonControl = new OpenLayers.Control.DrawFeature(
        layer_vectors,
        OpenLayers.Handler.RegularPolygon,
        {handlerOptions: polyOptions}
    );
    // Handler Funktion die reagiert wenn das Rechteck hinzugefügt wurde
    polygonControl.featureAdded = function(feature) {
        var a = feature.geometry.getBounds().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")).toArray();
        polygonControl.deactivate();
        document.getElementById("left").value = a[0];            
        document.getElementById("bottom").value = a[1];
        document.getElementById("right").value = a[2];
        document.getElementById("top").value = a[3];
    }
    map.addControl(polygonControl);
}

/*
 * Funktion die das Zeichnen aktiviert.
 */
function selectBox() {
    layer_vectors.destroyFeatures();
    polygonControl.activate();
}


//]]>
    </script>
</head>
<body onload="drawmap();">
    <!-- Karte (CSS könnte auch ausgelagert werden) -->
    <div id="map" style="width:400px;height:400px;"></div>
    <!-- Beispielformularfelder (sollte natürlich noch richtig in ein Formular) -->
    Left: <input type="text" value="" id="left" />
    Top: <input type="text" value="" id="top" />
    Right: <input type="text" value="" id="right" />
    Bottom: <input type="text" value="" id="bottom" />
    <a href="javascript:selectBox()">Click to select new box</a>
</body>
</html>

Gruß

dt2, du bist mein Meister :wink:

Das ist nun exakt das, was ich gesucht habe.
Habe mir den Code mal genauer angeschaut und ich kann sagen: Hätte ich mir das selber erarbeitet, wäre ich Monate in Charge gewesen.

Falls ich dir mal im Gegenzuge einen Gefallen tun kann, so lass es mich wissen.

Nochmals vielen Dank und beste Grüße,

Boris

Ich weiß ja wie das ist, ich kämpfe auch immer ein bisschen mit JavaScript und OpenLayers. Was du noch beachten solltest, das Rechteck kann man nun auch um 45° drehen, d.h. die Boundingbox ist dann eventuell nicht so, wie du es wolltest. Ich weiß allerdings auch nicht ob/wie man das verhindern kann.

Gruß

Ich kämpfe nicht nur mit Javascript, wir duellieren uns :wink:
Naja, ich habe noch nie mit JS gearbeitet, bin gerne immer bereit, mich mit neuen Dingen zu befassen. Aber bei der Funktion, die du mir gebastelt hast, wäre ich mit nicht vorhandenem Wissen gescheitert. In Sachen VB.NET und PHP bin ich recht fit. Aber mit JS? Ney :wink:

Übrigens, das mit dem drehbaren Rechteck ist, auch wenn es gar nicht von dir beabsichtigt war, ne super Sache. So kann der User seinen geographischen Zaun statt “gerade” auch um 45° gedreht anlegen. Bzw. ist ja eigentlich ein Quadrat, hast du n Tip, wie man daraus ein “echtes” Rechteck machen kann?

Hmm ihr solltet euch vlt. mal das neue Buch zu Openlayers besorgen, dass ist echt hübsch und mit vielen Beispielen!
Aber keine Angst, Webentwicklung war bisher auch nicht so meins :wink:

Ich weiß aber nicht so recht, ob das dann funktioniert. Wie berechnest du, ob etwas noch im “Zaun” liegt? Bei einem so gedrehten Quadrat müsste man das doch eventuell anders machen?

Ich weiß nicht wie man daraus ein Rechteck machen kann.