Aufgabenstellung: Ich weiß, wo ich mich befinde (Lat / Long, ist ja aus den Smartphones easy herauszubekommen) und habe einen Radius in km, in dem ich POI’s mit der Open Streemap API suchen möchte.
Problem: Die OSM API bietet keine (mir bekannte) Möglichkeit, um meinen aktuellen Standort herum eine Radius-Suche in km auszuführen, sondern hätte gern eine Bounding Box angegeben, die die Ecken der Box als Geo-Koordinaten angibt – siehe hier:
1 | http://www.overpass-api.de/api/xapi?node[bbox=8.62,49.85,8.68,49.89][amenity=fast_food|pub][@meta] |
Dabei spezifiziert der Parameter bbox die Lat/Long-Koordinaten in der Reihenfolge links, oben, rechts, unten.
Dazu erstmal zum Verständnis:
- Der Breitengrad (Latitude) gibt die Nord-Südachse an, “50″ ist nördlicher als “49″
- Der Längengrad (Longitude) gibt die Ost-Westachse an, “5″ ist westlicher als “6″
Berechnung
Nun haben wir also den eigenen Standort, wissen über Lat/Long Bescheid und wollen die Eckpunkte für die oben angesprochene Bounding Box errechnen. Aufbauend auf diesem Artikel habe ich folgende PHP-Funktion gebaut:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | $lat = 49.869059; $lon = 8.645318; $radius = 1.5; /** * lat (breitengrad = nord -> sued): 50 ist noerdlicher als 49 * lon (längengrad = west -> ost): 5 ist westlicher als 6 */ function getBoundingBox($lat, $lon, $radius) { $earth_radius = 6371; $maxLat = $lat + rad2deg($radius/$earth_radius); $minLat = $lat - rad2deg($radius/$earth_radius); $maxLon = $lon + rad2deg($radius/$earth_radius/cos(deg2rad($lat))); $minLon = $lon - rad2deg($radius/$earth_radius/cos(deg2rad($lat))); return array ( "center" => array("lat" => $lat, "lon" => $lon), "nw" => array("lat" => $maxLat, "lon" => $minLon), "ne" => array("lat" => $maxLat, "lon" => $maxLon), "sw" => array("lat" => $minLat, "lon" => $minLon), "se" => array("lat" => $minLat, "lon" => $maxLon) ); } $coords = getBoundingBox($lat, $lon, $radius); print_r($coords); /* Array ( [center] => Array ( [lat] => 49.869059 [lon] => 8.645318 ) [nw] => Array ( [lat] => 49.882548824089 [lon] => 8.6243885076019 ) [ne] => Array ( [lat] => 49.882548824089 [lon] => 8.6662474923981 ) [sw] => Array ( [lat] => 49.855569175911 [lon] => 8.6243885076019 ) [se] => Array ( [lat] => 49.855569175911 [lon] => 8.6662474923981 ) ) */ |
Somit haben wir schonmal die Eckpunkte für den Radius 1,5km um unseren Mittelpunkt ausgerechnet.
Darstellen der Eckpunkte auf einer Google Map
Zur Verifikation der errechneten Eckpunkte muss Quick&Dirty eine googlemap herhalten (inspiriert von hier).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" /> <script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> <script> function init() { var markers = []; <?php foreach ($coords as $desc => $latlong) { ?> markers.push({ 'lat' : <?php echo $latlong['lat']; ?>, 'lon' : <?php echo $latlong['lon']; ?>, 'desc' : "<?php echo $desc; ?>" }); <?php } ?> var map = new google.maps.Map(document.getElementById("map_canvas"), { zoom: 11, center: new google.maps.LatLng(<?php echo $coords['center']['lat'] . "," . $coords['center']['lon']; ?>), mapTypeId: google.maps.MapTypeId.ROADMAP }); for (var i = 0; i < markers.length; i++) { new google.maps.Marker({ position: new google.maps.LatLng(markers[i].lat, markers[i].lon), map: map, title: markers[i].desc }); } } window.onload = init; </script> </head> <body> <div id="map_canvas"></div> </body> </html> |
Sieht doch gut aus. Somit haben wir unsere Bounding Box Koordinaten auch visuell dargestellt und können die OSM API damit füttern.
Und hier nochmal der komplette Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | <?php $lat = 49.869059; $lon = 8.645318; $radius = 1.5; /** * lat (breitengrad = nord -> sued): 50 ist noerdlicher als 49 * lon (längengrad = west -> ost): 5 ist westlicher als 6 */ function getBoundingBox($lat, $lon, $radius) { $earth_radius = 6371; $maxLat = $lat + rad2deg($radius/$earth_radius); $minLat = $lat - rad2deg($radius/$earth_radius); $maxLon = $lon + rad2deg($radius/$earth_radius/cos(deg2rad($lat))); $minLon = $lon - rad2deg($radius/$earth_radius/cos(deg2rad($lat))); return array ( "center" => array("lat" => $lat, "lon" => $lon), "nw" => array("lat" => $maxLat, "lon" => $minLon), "ne" => array("lat" => $maxLat, "lon" => $maxLon), "sw" => array("lat" => $minLat, "lon" => $minLon), "se" => array("lat" => $minLat, "lon" => $maxLon) ); } $coords = getBoundingBox($lat, $lon, $radius); ?> <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" /> <script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> <script> function init() { var markers = []; <?php foreach ($coords as $desc => $latlong) { ?> markers.push({ 'lat' : <?php echo $latlong['lat']; ?>, 'lon' : <?php echo $latlong['lon']; ?>, 'desc' : "<?php echo $desc; ?>" }); <?php } ?> var map = new google.maps.Map(document.getElementById("map_canvas"), { zoom: 11, center: new google.maps.LatLng(<?php echo $coords['center']['lat'] . "," . $coords['center']['lon']; ?>), mapTypeId: google.maps.MapTypeId.ROADMAP }); for (var i = 0; i < markers.length; i++) { new google.maps.Marker({ position: new google.maps.LatLng(markers[i].lat, markers[i].lon), map: map, title: markers[i].desc }); } } window.onload = init; </script> </head> <body> <div id="map_canvas"></div> </body> </html> |

Pingback: Open Streetmap API Tutorial: Umkreissuche | davblog: webdev and stuff