1. Import
This commit is contained in:
266
html/include/pnpoly.inc.php
Normal file
266
html/include/pnpoly.inc.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
/*=======================================================================
|
||||
*
|
||||
* pnpoly.inc.php
|
||||
*
|
||||
* Autor: Carsten Annacker
|
||||
*
|
||||
=======================================================================*/
|
||||
|
||||
include_once("../include/dbglobal.inc.php");
|
||||
include_once("../include/caglobal.inc.php");
|
||||
include_once("../include/global.inc.php");
|
||||
|
||||
/*
|
||||
* Test der pnpoly Funktion:
|
||||
* Die PLZ-Mittelpunkte werden gegen die PLZ-Polygone geprüft
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
set_time_limit(300);
|
||||
$sqlQuery = "SELECT srvp_plz, srvp_longitude, srvp_latitude FROM serviceplz ORDER BY srvp_plz" ;
|
||||
$res = mysql_query($sqlQuery) or reportDie ($sqlQuery);
|
||||
|
||||
while ($row = mysql_fetch_array($res, MYSQL_ASSOC)):
|
||||
echo "\n<br>\n<br>" . $row["srvp_plz"] . ": ";
|
||||
echo "(" . $row["srvp_longitude"] . ", " . $row["srvp_latitude"] . "): ";
|
||||
if (isInZipcodeArea($row["srvp_longitude"], $row["srvp_latitude"], $row["srvp_plz"]))
|
||||
echo "IN";
|
||||
else
|
||||
echo "OUT";
|
||||
endwhile;
|
||||
mysql_free_result($res);
|
||||
*/
|
||||
|
||||
define ("MAX_SEARCH_RADIUS", 5); // in km
|
||||
define ("MAX_SEARCHES" , 10); // max. Anzahl der Umkreissuchen
|
||||
define ("GEO_EARTH_RADIUS" , 6371.0); // in km
|
||||
//define ("DATABASE" , "phoenix_special");
|
||||
define ("TBL_PLZ" , "phoenix_special.plz_geodb");
|
||||
define ("FLD_BREITE" , "plzg_breite");
|
||||
define ("FLD_LAENGE" , "plzg_laenge");
|
||||
define ("FLD_PLZ_CODE" , "plzg_code");
|
||||
|
||||
/*
|
||||
* Test der findZipcodeArea Funktion:
|
||||
* Willkürliche Punkte finden
|
||||
*
|
||||
*/
|
||||
/*
|
||||
$pointLong = 13.734444;
|
||||
$pointLat = 51.077499;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 9.974722;
|
||||
$pointLat = 53.562500;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 9.956100;
|
||||
$pointLat = 53.586899;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 9.946900;
|
||||
$pointLat = 53.580002;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 9.966400;
|
||||
$pointLat = 53.568100;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 8.859259;
|
||||
$pointLat = 53.140369;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 8.703900;
|
||||
$pointLat = 53.179699;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 13.398333;
|
||||
$pointLat = 52.529167;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 13.404722;
|
||||
$pointLat = 52.520557;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 13.448611;
|
||||
$pointLat = 52.509445;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 13.660000;
|
||||
$pointLat = 53.100361;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
$pointLong = 0.0;
|
||||
$pointLat = 0.0;
|
||||
echo "($pointLong, $pointLat): " . findZipcodeArea($pointLong, $pointLat) . "<br>";
|
||||
*/
|
||||
/*
|
||||
* PLZ-Bereich finden, in dem der spezifizierte Punkt liegt
|
||||
*
|
||||
*/
|
||||
|
||||
getDb2Connection(); // Try to connect request server because of performance
|
||||
|
||||
function findZipcodeArea($pointLong, $pointLat)
|
||||
{
|
||||
// global $dbhost, $dblogin, $dbpassword;
|
||||
global $db2;
|
||||
|
||||
trace_execution_time_start();
|
||||
// $mysqlLink = mysql_connect($dbhost, $dblogin, $dbpassword)
|
||||
// or reportDie (mysql_error($mysqlLink));
|
||||
// mysql_select_db(DATABASE, $mysqlLink)
|
||||
// or reportDie (mysql_error($mysqlLink));
|
||||
$max_search_radius = 0;
|
||||
$plz_sql = "";
|
||||
// Umkreissuche über die umliegenden PLZ-Bereiche.
|
||||
// Der Suchradius wird erhöht, wenn kein Bereich gefunden wurde,
|
||||
// solange bis er gefunden wird (irgendwo musser ja sein).
|
||||
do {
|
||||
$max_search_radius += MAX_SEARCH_RADIUS;
|
||||
if ($plz_sql != "")
|
||||
$plz_sql_clause = " AND " . FLD_PLZ_CODE . " NOT IN ($plz_sql)";
|
||||
$sqlQuery = "SELECT " . FLD_PLZ_CODE . " AS plz FROM " /* . DATABASE . "." */ . TBL_PLZ . " WHERE " .
|
||||
"(ACOS((SIN(" . deg2rad($pointLat) . ")*SIN(RADIANS(" . FLD_BREITE . "))) + " . "(COS(" . deg2rad($pointLat) . ")*COS(RADIANS(" . FLD_BREITE . "))*COS(RADIANS(" . FLD_LAENGE . ")-" .
|
||||
deg2rad($pointLong) . "))) * " . GEO_EARTH_RADIUS . ") < " . $max_search_radius . $plz_sql_clause;
|
||||
// $res = mysql_query($sqlQuery, $mysqlLink) or reportDie ("Error in query: '$sqlQuery': " . mysql_error($mysqlLink));
|
||||
$res = $db2->query($sqlQuery);
|
||||
if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlQuery': " . $res->getMessage());
|
||||
$i = 0;
|
||||
// while ($row = mysql_fetch_array($res, MYSQL_ASSOC)):
|
||||
while ($row = $res->fetch_assoc()):
|
||||
//echo "$max_search_radius: " . $row["plz"] . "<br>";
|
||||
if (isInZipcodeArea($pointLong, $pointLat, $row["plz"])) {
|
||||
writeLog(trace_execution_time_stop() . " " . $row["plz"] . " (" . sprintf("%-13s", $pointLong) . ", " . sprintf("%-13s", $pointLat) . "), \$max_search_radius =" . sprintf("%2s", $max_search_radius) . " Km, \$plz_sql = $plz_sql");
|
||||
return $row["plz"];
|
||||
}
|
||||
if ($plz_sql != "")
|
||||
$plz_sql .= ",";
|
||||
$plz_sql .= "'" . $row["plz"] . "'";
|
||||
endwhile;
|
||||
// mysql_free_result($res);
|
||||
$res->free();
|
||||
} while($max_search_radius < MAX_SEARCH_RADIUS * MAX_SEARCHES);
|
||||
writeLog(trace_execution_time_stop() . " " . "*****" . " (" . sprintf("%-13s", $pointLong) . ", " . sprintf("%-13s", $pointLat) . "), \$max_search_radius =" . sprintf("%2s", $max_search_radius) . " Km, \$plz_sql = $plz_sql");
|
||||
// mysql_close($mysqlLink);
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Testen ob der Punkt in $pointDeg (Array von Länge, Breite) im PLZ-Bereich zipcode liegt
|
||||
*
|
||||
*/
|
||||
function isInZipcodeArea($pointLong, $pointLat, $zipcode)
|
||||
{
|
||||
global $db2;
|
||||
|
||||
$plzp_polygons = $db2->getOne("SELECT plzp_polygons FROM phoenix_special.plz_polygon WHERE plzp_code = '$zipcode'");
|
||||
$polygons = explode("|", $plzp_polygons);
|
||||
foreach($polygons as $polygon) {
|
||||
$polygonPointsX = array();
|
||||
$polygonPointsY = array();
|
||||
// $polygonPointsCnt = 0;
|
||||
$points = explode(",", $polygon);
|
||||
foreach($points as $point) {
|
||||
list($plzp_x_deg, $plzp_y_deg) = explode(" ", $point);
|
||||
array_push ($polygonPointsX, $plzp_x_deg);
|
||||
array_push ($polygonPointsY, $plzp_y_deg);
|
||||
// $polygonPointsCnt++;
|
||||
}
|
||||
// echo "<br>cn_PnPoly: ";
|
||||
// if (cn_PnPoly($polygonPointsX, $polygonPointsY, $pointDeg[0], $pointDeg[1]))
|
||||
// echo "IN<br>";
|
||||
// else
|
||||
// echo "OUT<br>";
|
||||
// echo "pnpoly: ";
|
||||
if (pnpoly($polygonPointsX, $polygonPointsY, $pointLong, $pointLat))
|
||||
return true;
|
||||
// echo "IN<br>";
|
||||
// else
|
||||
// echo "OUT<br>";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Quelle: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
*
|
||||
* Original C-code:
|
||||
*
|
||||
* int pnpoly(int npol, float *xp, float *yp, float x, float y)
|
||||
* {
|
||||
* int i, j, c = 0;
|
||||
* for (i = 0, j = npol-1; i < npol; j = i++) {
|
||||
* if ((((yp[i]<=y) && (y<yp[j])) ||
|
||||
* ((yp[j]<=y) && (y<yp[i]))) &&
|
||||
* (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
|
||||
*
|
||||
* c = !c;
|
||||
* }
|
||||
* return c;
|
||||
* }
|
||||
*/
|
||||
function pnpoly($px, $py, $x, $y)
|
||||
{
|
||||
|
||||
$npol = count($px);
|
||||
$c = false;
|
||||
for ($i = 0, $j = $npol - 1; $i < $npol; $j = $i++) {
|
||||
if (((($py[$i] <= $y) && ($y < $py[$j])) ||
|
||||
(($py[$j] <= $y) && ($y < $py[$i]))) &&
|
||||
($x < ($px[$j] - $px[$i]) * ($y - $py[$i]) / ($py[$j] - $py[$i]) + $px[$i]))
|
||||
$c = !$c;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Quelle: http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
|
||||
*
|
||||
* Original C-code:
|
||||
*
|
||||
* // cn_PnPoly(): crossing number test for a point in a polygon
|
||||
* // Input: P = a point,
|
||||
* // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
|
||||
* // Return: 0 = outside, 1 = inside
|
||||
* // This code is patterned after [Franklin, 2000]
|
||||
* int cn_PnPoly( Point P, Point* V, int n )
|
||||
* {
|
||||
* int cn = 0; // the crossing number counter
|
||||
*
|
||||
* // loop through all edges of the polygon
|
||||
* for (int i=0; i<n; i++) { // edge from V[i] to V[i+1]
|
||||
* if (((V[i].y <= P.y) && (V[i+1].y > P.y)) // an upward crossing
|
||||
* || ((V[i].y > P.y) && (V[i+1].y <= P.y))) { // a downward crossing
|
||||
* // compute the actual edge-ray intersect x-coordinate
|
||||
* float vt = (float)(P.y - V[i].y) / (V[i+1].y - V[i].y);
|
||||
* if (P.x < V[i].x + vt * (V[i+1].x - V[i].x)) // P.x < intersect
|
||||
* ++cn; // a valid crossing of y=P.y right of P.x
|
||||
* }
|
||||
* }
|
||||
* return (cn&1); // 0 if even (out), and 1 if odd (in)
|
||||
*
|
||||
* }
|
||||
*
|
||||
*/
|
||||
/*
|
||||
function cn_PnPoly($px, $py, $x, $y)
|
||||
{
|
||||
$n = count($px) - 1;
|
||||
$cn = 0; // the crossing number counter
|
||||
|
||||
// loop through all edges of the polygon
|
||||
for ($i = 0; $i < $n; $i++) { // edge from V[i] to V[i+1]
|
||||
if ((($py[$i] <= $y) && ($py[$i + 1] > $y)) // an upward crossing
|
||||
|| (($py[$i] > $y) && ($py[$i + 1] <= $y))) { // a downward crossing
|
||||
// compute the actual edge-ray intersect x-coordinate
|
||||
$vt = (float)($y - $py[$i]) / ($py[$i + 1] - $py[$i]);
|
||||
if ($x < $px[$i] + $vt * ($px[$i + 1] - $px[$i])) // $x < intersect
|
||||
++$cn; // a valid crossing of y=$y right of $x
|
||||
}
|
||||
}
|
||||
return ($cn % 2); // 0 if even (out), and 1 if odd (in)
|
||||
}
|
||||
*/
|
||||
|
||||
function writeLog($log_text) {
|
||||
// echo "[" . date("Y-m-d H:i:s O") . "] " . $log_text . "\n";
|
||||
$today = getdate();
|
||||
$fileHandle = @fopen("../log/pnpoly_" . $today['year'] . sprintf("%02d", $today['mon']) . ".log", 'a');
|
||||
@fwrite($fileHandle, "[" . date("Y-m-d H:i:s") . "] " . $log_text . "\n");
|
||||
@fclose($fileHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user