Beiträge: 28
Registriert seit: Dec 2014
Status:
Abwesend
|
[PHP]Radius-Suche anhand Lat/Lan/Plz
Hallo ihr lieben,
da ich für ein aktuelles Projekt eine Lat/Lan/Plz-Umkreis-Suche gebraucht habe aber ich leider nichts brauchbares gefunden habe, habe ich mir schnell eine geschrieben.
Diese teile ich liebend gerne mit euch:
Die Klasse
<?php class GeoLocation { /** * @var $_db */ private $_db;
/** * @var string $dbhost */ private $dbhost = '';
/** * @var string $dbuser */ private $dbuser = '';
/** * @var string $dbpass */ private $dbpass = '';
/** * @var string $dbdb */ private $dbdb = '';
/** * @var $file */ private $file;
/** * GeoLocation constructor. */ public function __construct($file) { try { $this->_db = new PDO(sprintf('mysql:host=%s;dbname=%s', $this->dbhost, $this->dbdb), $this->dbuser, $this->dbpass); } catch (PDOException $e) { die($e->getMessage()); }
$this->file = $file; }
/** * Read datas from Files * @return array|bool */ private function getDataFromTabFile() {
if (file_exists($this->file)) { $handle = fopen($this->file, 'r'); $data = []; while (($row = fgetcsv($handle, 0, "\t")) !== false) { $data[] = $row; }
// Remove first Row from File unset($data[0]);
return $data; }
return false; }
/** * Create Table * Insert Data from .tab File into Database */ public function insertDataIntoDatabase() { if ($this->getDataFromTabFile()) { $data = $this->getDataFromTabFile(); } else { die('No Data found.'); }
if (is_array($data)) { foreach ($data AS $key => $value) { $ascii = $value[2]; $name = $value[3]; $zip = $value[7]; $lat = $value[4]; $lon = $value[5];
self::createEmptyTable();
$stmt = $this->_db->prepare('INSERT INTO geo_locations (ascii, name, lat, lon, zip) VALUES (:ascii, :name, :lat, :lon, :zip)'); $stmt->execute( [ ':ascii' => $ascii, ':name' => $name, ':lat' => $lat, ':lon' => $lon, ':zip' => $zip, ] ); if($stmt) { echo 'Success: All datas successfull imported'; } }
} }
/** * @return bool */ private function createEmptyTable() { $stmt = $this->_db->prepare('CREATE TABLE `geo_locations` (`ascii` text CHARACTER SET utf8 NOT NULL,`name` text CHARACTER SET utf8 NOT NULL,`lat` text CHARACTER SET utf8 NOT NULL,`lon` text CHARACTER SET utf8 NOT NULL,`zip` text CHARACTER SET utf8 NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=ascii;'); return $stmt->execute(); }
/** * @param $lat * @param $lon * @param $dist * * @return array|string */ public function getCitysFromLatAndLon($lat, $lon, $dist) { $stmt = $this->_db->prepare("SELECT lat, lon, zip, ascii, name, (6371 * acos( cos( radians( :lat ) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians( :lon ) ) + sin( radians( :lat ) ) * sin( radians( lat ) ) ) ) AS distance FROM geo_locations HAVING distance <= :dist ORDER BY distance ASC"); $stmt->execute(array( ':lat' => $lat, ':lon' => $lon, ':dist' => $dist )); if($stmt->rowCount() > 0) { return $stmt->fetchAll(PDO::FETCH_ASSOC); } else { return 'Failed: no data found'; } } }
Die .tab Datei
http://www.fa-technik.adfc.de/code/opengeodb/DE.tab
Und so funktionierts
$geo = new GeoLocation('Pfad/zur/.tab);
/** * Einmal durchlaufen lassen, anschließend die Zeile löschen oder auskommentieren, sonst wird euch bei jedem Seitenaufruf die Tabelle neuaufgebaut */ $geo->insertDataIntoDatabase();
$lat = ''; $lon = ''; $dist = 5; print_r($geo->getCitysFromLatAndLon($lat, $lon, $dist));
Vielleicht konnte ich ja dem einen oder anderen damit helfen.
Viel Spaß damit.
Liebe Grüße
|
|