Skip to content

Commit

Permalink
Implement two polyhood tables and add shortcut for extreme values
Browse files Browse the repository at this point in the history
This patch implements the two tables created in the previous patch.

Exploiting the new structure, we can redesign the polyhood check
to check whether the point is within a square defined by the
extreme values of the coordinates, i.e. the latitude is smaller
than the one of the southmost vertex etc.

Although this is an extra check, it is much faster if we can skip
a lot of full polygon checks. Since we expect mostly "normal"
hoods and only few routers in polyhoods, this should be the case.

Signed-off-by: Adrian Schmutzler <[email protected]>
  • Loading branch information
adschm committed Nov 9, 2018
1 parent 30de835 commit d5f1ffd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
8 changes: 8 additions & 0 deletions function.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ class pointLocation {
// Original version: https://gist.github.com/jeremejazz/5219848
// Modified by Adrian Schmutzler, 2018.

function excludePolygon($point, $minlon, $maxlon, $minlat, $maxlat) {
// exclude polygon if LAT/LNG of point is smaller than minimum lat/lng of all vertices
// or bigger than maximum ...

// returning TRUE means exclusion, so polygon should NOT be used
return ($point[0] < $minlon or $point[0] > $maxlon or $point[1] < $minlat or $point[1] > $maxlat);
}

function pointInPolygon($point, $polygon, $pointOnVertex = true) {

// Support both string version "lng lat" and array(lng,lat)
Expand Down
36 changes: 31 additions & 5 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,52 @@

// First only retrieve list of polyids
try {
$rc = db::getInstance()->prepare("SELECT polyid, hoodid, lat, lon FROM polyhood");
$rc = db::getInstance()->prepare("
SELECT polyhoods.polyid, hoodid, MIN(lat) AS minlat, MIN(lon) AS minlon, MAX(lat) AS maxlat, MAX(lon) AS maxlon
FROM polyhoods INNER JOIN polygons ON polyhoods.polyid = polygons.polyid
GROUP BY polyid, hoodid
"); // This query will automatically exclude polyhoods being present in polyhoods table, but without vertices in polygons table
$rc->execute();
} catch (PDOException $e) {
exit(showError(500, $e));
}

// Write polygon data into array
// Set up all polygons, but do it without vertex coordinates
$polystore = array();
while($row = $rc->fetch(PDO::FETCH_ASSOC)) {
$polystore[$row['polyid']] = $row;
$polystore[$row['polyid']]['data'] = array(); // prepare array for vertex coordinates
}

// Now query the coordinates, all in one query
try {
$rc = db::getInstance()->prepare("SELECT polyid, lat, lon FROM polygons");
$rc->execute();
} catch (PDOException $e) {
exit(showError(500, $e));
}

// Write polygon coordinates into array
while($row = $rc->fetch(PDO::FETCH_ASSOC)) {
if(!isset($polystore[$row['polyid'])) {
$polystore[$row['polyid']] = array('hoodid'=>$row['hoodid'],'data'=>array());
debug('Database inconsistent: No polyhood defined for ID '.$row['polyid']);
continue; // Skip those orphaned vertex entries
}
$polystore[$row['polyid']]['data'][] = array($row["lon"],$row["lat"]);
debug('lon: '.$row["lon"].' lat: '.$row["lat"]);
}

// Interpret polygon data
foreach($polystore as $polyid => $polygon) {
foreach($polystore as $polygon) {
// First check whether point coordinates are outside the most extreme values for lat/lng
$exclude = $pointLocation->excludePolygon($point, $polygon['minlon'], $polygon['maxlon'], $polygon['minlat'], $polygon['maxlat']);
if ($exclude) {
debug("polygon #" . $polygon['polyid'] . " excluded<br>");
continue;
}
// Now really check whether point is inside polygon
$inside = $pointLocation->pointInPolygon($point, $polygon['data']);
debug("point in polygon #" . $polyid. ": " . $inside . "<br>");
debug("point in polygon #" . $polygon['polyid'] . ": " . $inside . "<br>");
if ($inside) {
debug("PolyHood gefunden...");
try {
Expand Down

0 comments on commit d5f1ffd

Please sign in to comment.