Archive

Posts Tagged ‘PHP’

Calculating Point in Polygon in PHP

September 2nd, 2009 simon No comments

Having recently developed a GIS application which reads data in and identifies the area within which it resides, we struggled to find an existing PHP solution, so developed our own. For those of you who need to calculate whether a location exists within a polygon, here it is:

The polygons are to be defined within the ‘areas’ table:

CREATE TABLE `areas` (
`id` int(8) NOT NULL auto_increment,
`area_code` varchar(10) NOT NULL,
`country` varchar(250) NOT NULL,
`longitude` varchar(25500) NOT NULL,
`latitude` varchar(25500) NOT NULL,
`polyset_id` int(8) NOT NULL default ‘0′,
PRIMARY KEY  (`id`)
)

The class:

<?php
class PointInPolygon
{

/* Point in Polygon
* Copyright Blue Lobster IT 2009
* www.bluelobster.co.uk
*/

//Queries the area table to distinguish which area the point is in.
static function CheckPoint($Longitude, $Latitude)
{
//searches areas table for all areas
$sqlPip = “SELECT * FROM areas”;
$qryPip = mysql_query($sqlPip) or die(mysql_error());
$numPip = mysql_num_rows($qryPip);

//begin process

if ($numPip > 0) {

$return = 0;
for ($i = 0; $i < $numPip; $i++) {
$rsPip = mysql_fetch_array($qryPip);
$arrLon = explode(’,',$rsPip['longitude']);
$arrLat = explode(’,',$rsPip['latitude']);
if (count($arrLon) == count($arrLat)) {
if (PointInPolygon::IsPointInPolygon(count($arrLon), $arrLon, $arrLat, $Longitude, $Latitude) == true) {
$return = $rsPip['id'];
break;
}
}else{
echo(”error: lon/lat irregularities\n\n”);
print_r($arrLon);
print_r($arrLat);
echo(”\n\n”);
}
}
}else{
echo(”fixme: error”);
}
return $return;
}

//$nvert            = Number of vertices in the polygon. Whether to repeat the first vertex at the end is discussed below.
//$vertx, $verty    = Arrays containing the x- and y-coordinates of the polygon’s vertices.
//$testx, $testy    = X- and y-coordinate of the test point.

private static function IsPointInPolygon($nvert, $vertx, $verty, $testx, $testy)
{
$i;
$j;
$c = false;
for ($i = 0, $j = $nvert-1; $i < $nvert; $j = $i++) {
if (
(($verty[$i]>$testy) != ($verty[$j]>$testy)) &&
($testx < ($vertx[$j]-$vertx[$i]) * ($testy-$verty[$i]) / ($verty[$j]-$verty[$i]) + $vertx[$i])
){
$c = !$c;
}
}
return $c;
}
}

?>

Categories: September Tags: , , ,