Adresse auslesen von "nominatim" funktioniert nicht richtig!

Hi,

ich programmiere zur Zeit an einem Script, das aus einer Datenbank eine Adresse liest. Dann soll im ersten Schritt versucht werden, die genaue Adresse automatisch mittels “nominatim” zu lokalisieren. Im zweiten Schritt wird die Karte mit dem gefundenen Standort (nadel.png) aufgebaut. Sollte der gefundene Standort nicht mit dem gewünschten Standort genau übereinstimmen, kann man dies korrigieren, indem man mit der Maus über die Karte fährt. Die Koordinaten werden dabei angezeigt. Mit einem Mausklick, wird dann die eventuell korrigierte Position übernommen. Soweit die Theorie. Leider gibt es in der Praxis einige Probleme:

  1. Die Koordinaten z.B. zur Adresse “40721 Hilden,Gerresheimer Str. 40” werden falsch wiedergegeben bzw. auf der Karte angezeigt.

  2. Wie kann ich die Koordinaten in einer Datei auf meinem Server speichern? Ich dachte dabei, die Koordinaten z.B. in einem Formularfeld darzustellen und dann per php auszulesen und zu speichern. Aber wie bekomme ich die Koordinaten in das Formularfeld?

Ich hoffe, Ihr könnt mir helfen. Ich bin leider ratlos!!! :frowning:


<?php
$adresse="40721 Hilden,Gerresheimer Str. 40";
$pos = file_get_contents('http://nominatim.openstreetmap.org/search?format=json&q='.$adresse);
$pos2 = json_decode($pos);
$lat=$pos2[0]->lat;
$lon=$pos2[0]->lon;
?>
<style type="text/css">.olControlAttribution { bottom: 3px!important; }</style>
<script src="OpenLayers/OpenLayers.js">
</script><script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js">
</script>
<div id="map" style="width:750px;height:510px;"></td></tr></table></div>'
<script type="text/javascript" src="OpenLayers/OpenLayers_Map_minZoom_maxZoom_Patch.js"></script>
<script type="text/javascript" src="OpenLayers/my_panzoombar.js"></script>
<script type="text/javascript">
var map;
function showMap()
{
map = new OpenLayers.Map("map",
{
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0399,
units: "m",
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
controls: [],
minZoom:12,
maxZoom:18
});
map.addControl (new OpenLayers.Control.LayerSwitcher());
map.addControl (new OpenLayers.Control.Navigation());
map.addControl (new OpenLayers.Control.MousePosition());
map.addControl (new OpenLayers.Control.PanZoomBar({minZoom: 12}));
OpenLayers.Marker.defaultIcon = function () {
    return new OpenLayers.Icon ("symbole/nadel.png", {w:35, h:41}, {x: -10, y:-30});
};
var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik (updated weekly)");
var layerTah = new OpenLayers.Layer.OSM.Osmarender("Tiles@Home");
map.addLayers([layerMapnik]);
map.setCenter(new OpenLayers.LonLat(<?php echo $lon; ?>,<?php echo $lat; ?>).transform(new OpenLayers.Projection("EPSG:4326"),
new OpenLayers.Projection("EPSG:900913")), 14);
map.addLayer(new OpenLayers.Layer.Markers("Standort"));
var marker = new OpenLayers.Marker(map.getCenter());
marker.events.register("mousedown", marker, function(evt)
{
OpenLayers.Event.stop(evt);
}
);
map.layers[map.layers.length-1].addMarker(marker);
}
showMap();
</script>
</div>
</body>
</html>

Moins,

Ruf einmal die URL direkt auf: kein Treffer.

Dann lass die Hausnummer weg: Treffer.

Du kannst Deinen Code so modifizieren, dass er bei einer Fehlanzeige die Suche ohne Hausnummer wiederholt.

Gruß Wolf

Hi Wolf,

danke für die Antwort. Leider ändert aber das weglassen der Hausnummer nichts am Ergebnis. Der gefundene Standort stimmt nicht überein. Auch die Koordinaten ändern sich nicht. Hmm. Kann es sein, das Nomination das nächst gelegene Gewerbe anzeigt (fixe Idee!)?

Nahmd,

Wozu wild spekulieren?

Lass Dir die Ergebnisse der einzelnen Rechenschritte anzeigen:


<?php
$adresse="Gerresheimer Straße, 40721 Hilden";
echo "<p>Adresse: ",htmlspecialchars($adresse),"</p>\n";

$url = "http://nominatim.openstreetmap.org/search?format=json&q=" . rawurlencode($adresse);
echo "<p>Url: ",htmlspecialchars($url),"</p>\n";

$response = file_get_contents($url);
echo "<p>Response: ",htmlspecialchars($response),"</p>\n";

$parsed = json_decode($response);
echo "<p>Parsed:</p>\n";
var_dump ($parsed);

$result0 = $parsed[0];
echo "<p>Result[0]:</p>\n";
var_dump ($result0);

$lat=$result0->lat;
$lon=$result0->lon;

echo "<p>Lat: ", htmlspecialchars($lat), "</p>\n";
echo "<p>Lon: ", htmlspecialchars($lon), "</p>\n";

echo "<p><a href='http://www.openstreetmap.org/?mlat={$lat}&mlon={$lon}&zoom=14'>$lat, $lon</a></p>\n";

?>

Gruß Wolf

Hi Wolf,

ich glaube, jetzt hab ichs. War eigentlich ziemlich einfach. Vielen Dank :slight_smile: Hast Du evtl. auch eine Idee zu meiner zweiten Frage?


<?php
function umlaute($text)
{
$search  = array ('ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß');
$replace = array ('ae', 'oe', 'ue', 'Ae', 'Oe', 'Ue', 'ss');
$str2  = str_replace($search, $replace, $text);
return $str2;
}
$adresse=umlaute("Gerresheimer Straße, 40721 Hilden"); // Konvertieren von Umlauten
$url = "http://nominatim.openstreetmap.org/search?format=json&q=" . rawurlencode($adresse);
$response = file_get_contents($url);
$parsed = json_decode($response);
$result0 = $parsed[0];
$lat=$result0->lat;
$lon=$result0->lon;
echo "<p>Lat: ", $lat, "</p>\n";
echo "<p>Lon: ", $lon, "</p>\n";
echo "<p><a href='http://www.openstreetmap.org/?mlat={$lat}&mlon={$lon}&zoom=14'>$lat, $lon</a></p>\n";
?>

Nahmd,

So.

Du schuldest uns allen nach Fertigstellung eine allgemeinverständliche Beschreibung samt Anleitung zum Selbermachen.
Und mir eine Tüte Gummibären.

Gruß Wolf

Hi Wolf,

noch einmal meinen Dank für Deine Hilfe. Ohne Dich, hätte ich es nicht geschafft. Wollte Dir eigentlich einen ganzen Karton Gummibärchen geben. Aber die passen nicht durch den Monitor. Aber mir fällt schon noch eine Möglichkeit ein :wink:

Hier noch einmal das Projekt. Ich hatte das Problem, das ich aus einer Adresse die Koordinaten ermitteln wollte. Mittels Nominatim, geht das ganz gut. Aber da die meisten Objekte nicht durch die Hausnummer zu finden sind, wird die Position nur geschätzt. Es ist also meistens eine manuelle Anpassung notwendig. Und das soll mein Script nun bewerkstelligen.

Zuerst wird per Nominatim die Straße ermittelt und auf der Karte angezeigt. Sollte das tatsächliche Ziel vom gefundenen Standort abweichen, kann dies mittels eines Mausklicks auf den neues Standort korrigiert werden.

Jetzt habe ich aber noch einen Verbesserungsvorschlag: Klickt man mit der Maus auf den neuen Standort, sollte die Standort Grafik (nadel.png) am neuen Standort erscheinen. Aber leider bin ich ein absoluter Javascript Laie. Irgendeine Idee, wie man das machen kann? Damit wäre der Script dann vollendet :slight_smile:


<?php
function umlaute($text)
{
$search  = array ('ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß');
$replace = array ('ae', 'oe', 'ue', 'Ae', 'Oe', 'Ue', 'ss');
$str2  = str_replace($search, $replace, $text);
return $str2;
}
$adresse=umlaute("Königstr. 13, 14109 Berlin");
$pos = file_get_contents('http://nominatim.openstreetmap.org/search?format=json&q='.rawurlencode($adresse));
$pos2 = json_decode($pos);
$lat=$pos2[0]->lat;
$lon=$pos2[0]->lon;
?>
<style type="text/css">.olControlAttribution { bottom: 3px!important; }</style>
<script src="OpenLayers/OpenLayers.js">
</script><script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js">
</script>
<div id="map" style="width:750px;height:510px;"></td></tr></table></div>
<script type="text/javascript" src="OpenLayers/OpenLayers_Map_minZoom_maxZoom_Patch.js"></script>
<script type="text/javascript" src="OpenLayers/my_panzoombar.js"></script>
<script type="text/javascript">
var map;
function showMap()
{
map = new OpenLayers.Map("map",
{
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0399,
units: "m",
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
controls: [],
minZoom:12,
maxZoom:18
});
map.addControl (new OpenLayers.Control.LayerSwitcher());
map.addControl (new OpenLayers.Control.Navigation());
map.addControl (new OpenLayers.Control.MousePosition());
map.addControl (new OpenLayers.Control.PanZoomBar({minZoom: 12}));
OpenLayers.Marker.defaultIcon = function () {
    return new OpenLayers.Icon ("symbole/nadel.png", {w:35, h:41}, {x: -10, y:-30});
};
var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik (updated weekly)");
var layerTah = new OpenLayers.Layer.OSM.Osmarender("Tiles@Home");
map.addLayers([layerMapnik]);
map.setCenter(new OpenLayers.LonLat(<?php echo $lon; ?>,<?php echo $lat; ?>).transform(new OpenLayers.Projection("EPSG:4326"),
new OpenLayers.Projection("EPSG:900913")), 16);
map.addLayer(new OpenLayers.Layer.Markers("Standort"));
	map.addControl (new OpenLayers.Control ({

		draw: function (px) {
			this.handler = new OpenLayers.Handler.Click (this, {click: this.onclick}, {});
			this.activate();
		},

		onclick: function (ev) {
			var lonLat=this.map.getLonLatFromViewPortPx(ev.xy).
				transform(this.map.getProjectionObject(),this.map.displayProjection);
			document.getElementById('lat').value = lonLat.lat;
			document.getElementById('lon').value = lonLat.lon;
		}
	}));
var marker = new OpenLayers.Marker(map.getCenter());
marker.events.register("mousedown", marker, function(evt)
{
OpenLayers.Event.stop(evt);
}
);
map.layers[map.layers.length-1].addMarker(marker);
}
showMap();
</script>
</div>
<form action="http://www.openstreetmap.org/">
<p>
<input id="lat" name="mlat" value="<?php echo $lat; ?>">
<input id="lon" name="mlon" value="<?php echo $lon; ?>">
<button type="submit">weiter geht´s</button>
</p>
</form>
</body>
</html>


Nahmd,

Und ich nach Verzehr nicht mehr durchs Heilbronner Törle.

Du benutzt diese Methode aus der Marker-Klasse.

Eine Zeile Code. Die bekommst Du hin. Ein Objekt im Browser per JS zu bewegen ist ein erstes JS-Erfolgserlebnis und ein paar Minuten Nachdenken und Probieren wert. Du musst ja nicht gleich übertreiben.

Gruß Wolf

Yipi, es klappt. War doch ziemlich einfach :slight_smile:

Hier die vollständige funktion:


		onclick: function (ev) {
			var lonLat=this.map.getLonLatFromViewPortPx(ev.xy).
				transform(this.map.getProjectionObject(),this.map.displayProjection);
				marker.moveTo(ev.xy);
			document.getElementById('lat').value = lonLat.lat;
			document.getElementById('lon').value = lonLat.lon;
		}

kleiner Nachtrag:

Solange man die Karte nicht scrollt, wird der Marker korrekt gesetzt. Scrollt man die Karte jedoch, wird der Marker nicht gesetzt. Erst wenn man nach dem scrollen den Zoomfaktor ändert, klappt die Positionierung wieder!!! :roll_eyes:

Mist! War ein blödes Besispiel.
Mea culpa. Ich hätte zuerst die beiden Bezugssysteme erklären müssen.


onclick: function (ev) {

        var lonLat=this.map.getLonLatFromViewPortPx(ev.xy);

        marker.moveTo (this.map.getLayerPxFromLonLat(lonLat));

        lonLat.transform(this.map.getProjectionObject(),this.map.displayProjection);

        document.getElementById('lat').value = lonLat.lat;
        document.getElementById('lon').value = lonLat.lon;
}

Gruß Wolf

Hi Wolf,

super, jetzt klappt es einwandfrei. Nochmals vielen Dank.

Hatte mir heute schon die Nacht umdie Ohren geschlagen um eine Lösung zu finden. Aber das ist für einen Javascript Laien gar nicht so einfach :slight_smile: