Archiv » CakePHP » Umkreissuche - OpenGeoDB und...

Umkreissuche - OpenGeoDB und CakePHP

Benötigt wird ein Controller und Model für die Geokoordinaten (z.B. OpenGeoDB) und ein Model und Controller mit Firmen (Firmenname, PLZ, Land, Längengrad, Breitengrad) Über die GeoDB ließe sich auch anhand der Postleitzahl direkt die Umkreissuche durchführen. Bei diesem Beispiel gehen wir davon aus, dass die OpenGeoDB nicht alle Postleitzahlengebiete beinhaltet und die Firmen die Längen- und Breitengrade mitliefern.
  1. <?php
  2.  
  3. // input zipcode ##$this->data["Company"]["Companyplz"]##
  4. // find Company with zipcode from posted form
  5. $geo_coordinates = $this->Geolocator->find('first', array('conditions' => array('Geolocator.zipcode LIKE' => trim($this->data["Company"]["Companyplz"]).'%'),
  6. 'fields' => array('lon','lat','city','state')));
  7.  
  8. // mysql-Ausgabefelder für Umkreissuche mit Längen- und Breitengrad der Firma
  9. $fields = array('Company.*', 'Geolocation.land',
  10. 'ACOS(SIN(RADIANS(lat)) * SIN(RADIANS('.$geo_coordinates["Geolocation"]["lat"].'))
  11. + COS(RADIANS(lat)) * COS(RADIANS('.$geo_coordinates["Geolocation"]["lat"].')) * COS(RADIANS(lon)
  12. - RADIANS('.$geo_coordinates["Geolocation"]["lon"].'))
  13. ) * 6380 AS `distance`');
  14.  
  15. // Bedingungen für die Umkreissuche
  16. $conditions = array('(ACOS(
  17. SIN(RADIANS(lat)) * SIN(RADIANS('.$geo_coordinates["Geolocation"]["lat"].'))
  18. + COS(RADIANS(lat)) * COS(RADIANS('.$geo_coordinates["Geolocation"]["lat"].')) * COS(RADIANS(lon)
  19. - RADIANS('.$geo_coordinates["Geolocation"]["lon"].'))
  20. ) * 6380 AND Geolocation.zipcode = Company.zipcode) ||
  21. (Company.zipcode='.trim($this->data["Company"]["Companyplz"]).' AND Geolocation.zipcode='.trim($this->data["Company"]["Companyplz"]).')');
  22.  
  23. // Sortiere Umkreissuche-Ergebnise aufsteigend nach Distanz (Kilometer)
  24. $orderby = array('distance' => 'ASC');
  25.  
  26. // mySQL-Query für die gesamte Umkreissuche mit einer max. Distanz von 200km
  27. $CompanyResults = $this->Geolocation->find('all', array('conditions' => $conditions,
  28. 'fields' => $fields,
  29. 'order' => $orderby,
  30. 'group' => array('distance HAVING distance <200'),
  31. 'limit' => 100));
  32.  
  33. /*
  34. Ergebnisse der $CompanyResults (print_r):
  35. Array
  36. (
  37. [0] => Array
  38. (
  39. [Factory] => Array
  40. (
  41. [id] => 7
  42. [company] => Musterfirma
  43. [street] => Musterstraße 3
  44. [zipcode] => 22111
  45. [city] => Hamburg
  46. [longitude] => 9.9623374
  47. [latitude] => 53.5494149
  48. )
  49.  
  50. [Geolocator] => Array
  51. (
  52. [land] => Deutschland
  53. )
  54.  
  55. [0] => Array
  56. (
  57. [distance] => 93.0386003085903
  58. )
  59.  
  60. )
  61. )
  62. */
  63.  
  64. ?>