Dichtstbijzijnde adressen zoeken via geo-coördinaten in PHP

Hoe vind je adressen in een straal om een bepaald adres heen, bijvoorbeeld in een omtrek van 20 kilometer van een opgegeven adres of postcode. Ben Brown heeft dit uitgeplozen voor PHP/MySQL

Zet eerst, voor elk adres dat je wilt kunnen weergeven, de coördinaten in de MySQL-database. Via Google Maps kun je van een postcode of adres de geografische coördinaten vinden. Je kunt dit omzetten met PHP automatiseren.

Ga dus uit van een latitude en een longutude van het beginadres en geef de maximale afstand tot dit punt (in km of mijl)
Bijvoorbeeld:

$lat = 30.240685;
$long = -97.768829;
$distance = 20;

Bereken met de functie getBoundingBox de waardes waarbinnen de latitude en de longitude moeten vallen

list($lat1,$lat2,$lon1,$lon2) = getBoundingBox($lat,$long,$distance);

En vergelijk de waarden met die van de adressen uit de database.

$sql = "SELECT * FROM zipcodes WHERE latitude between $lat1 and $lat2 AND longitude between $lon1 and $lon2";
//  enz....

Aanpassing in getBoundingBox: de radius en de invoer van de afstand is nu in kilometer i.v.p. mijl. Dit maakt voor de berekening verder niet uit.

function getBoundingBox($lat_degrees,$lon_degrees,$distance_in_miles) {
 // getBoundingBox
 // hacked out by ben brown <ben@xoxco.com>
 // http://xoxco.com/clickable/php-getboundingbox

 // given a latitude and longitude in degrees (40.123123,-72.234234) and a distance in miles
 // calculates a bounding box with corners $distance_in_miles away from the point specified.
 // returns $min_lat,$max_lat,$min_lon,$max_lon 

 //$radius = 3963.1; // of earth in miles
 $radius = 6730.0; // of earth in km

 // bearings
 $due_north = 0;
 $due_south = 180;
 $due_east = 90;
 $due_west = 270;

 // convert latitude and longitude into radians
 $lat_r = deg2rad($lat_degrees);
 $lon_r = deg2rad($lon_degrees);

 // find the northmost, southmost, eastmost and westmost corners $distance_in_miles away
 // original formula from
 // http://www.movable-type.co.uk/scripts/latlong.html
 $northmost  = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_north));
 $southmost  = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_south));

 $eastmost = $lon_r + atan2(sin($due_east)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));
 $westmost = $lon_r + atan2(sin($due_west)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));

 $northmost = rad2deg($northmost);
 $southmost = rad2deg($southmost);
 $eastmost = rad2deg($eastmost);
 $westmost = rad2deg($westmost);

 // sort the lat and long so that we can use them for a between query
 if ($northmost > $southmost) {
   $lat1 = $southmost;
   $lat2 = $northmost;
 } else {
   $lat1 = $northmost;
   $lat2 = $southmost;
 }

 if ($eastmost > $westmost) {
   $lon1 = $westmost;
   $lon2 = $eastmost;
 } else {
   $lon1 = $eastmost;
   $lon2 = $westmost;
 }

 return array($lat1,$lat2,$lon1,$lon2);
 }

Bronnen

Advertisements

Author: Rian Rietveld

WordPress Engineer focussing on accessibility

4 thoughts on “Dichtstbijzijnde adressen zoeken via geo-coördinaten in PHP”

  1. Deze functie werkt engisinds, maar niet juist. Wanneer ik zoek op een plaatsnaam (waarbij ik daar de lat en lang uit een datbase haal) missen veel omliggende plaatsen die ook binnen het bereik liggen.

    Zie overigens ook het commentraar wat er in de bron staat:

    “Find the closest location near your adress”

    crmalibu,

    I tested this:

    http://xoxco.com/clickable/php-getboundingbox

    It is not usable. A box consists of 4 points. That script returns 2. And the 2 points it returns are not even on the same line with the original point. If I go a distance out of 1 mile, I would assume that I could draw a straight line between the three points–the original and the two new points. But it doesn’t.

    Like

  2. Ter info: de straal van de aarde is ca. 6370 in Belgie en Nederland; hier staan 2 cijfertjes van plaats gewisseld: 6730 is iets teveel.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s