 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
 |
|
 |
12-25-2009, 08:43 AM
|
#1 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
PHP GeoLocation
Hi guys,
trying to work out the following
I have created a list of GeoLocations and I would like to create a simple system that tells me if a person is inside the area of the GeoLocation I have set for e.g.
If a person it in the area of
144.30'39.82/-38.16'22.00 by with of 144.31'12.99/-38.16'16.20
by
144.30'41.77/-38.16'37.09 by with of 144.31'12.74/-38.16'33.05
so if a person is in that area I want to show that info.
I have the script that collects the GeoLocation but not away to know if a person is in an area.
EDIT: Here is the picture of the area I want.

Last edited by russellharrower : 12-25-2009 at 10:32 AM.
|
|
|
|
12-25-2009, 10:38 AM
|
#2 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
What I was thinking would be an if statement something like
<?php
if($user >144.39.82/38.22.0 && $user < 144.12.99/38.16.20)
{
echo "your in the area."
}
|
|
|
|
12-25-2009, 11:41 AM
|
#3 (permalink)
|
|
The Contributor
Join Date: Apr 2005
Location: Kent, UK
Posts: 54
Thanks: 0
|
You'd have to test the latitude and the longitude separately, and use >= and <=
|
|
|
|
12-25-2009, 01:07 PM
|
#4 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
Can I ask what the difference between > and >=
|
|
|
|
12-25-2009, 01:10 PM
|
#5 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
Also I noticed you said "You'd have to test the latitude and the longitude separately"
Can I ask what about the diagonal line at the bottom? is their away a PHP script would know what numbers go their to make that line? Sorry I am not sure how to make that sound any clearer.
|
|
|
|
12-25-2009, 01:29 PM
|
#6 (permalink)
|
|
The Contributor
Join Date: Apr 2005
Location: Kent, UK
Posts: 54
Thanks: 0
|
> means greater than
>= means greater than or equal too
< less than
<= less than or equal to
need those >= etc to get places on any of the boundary lines.
If you have the $lat and $long as separate variables from the geolocation info, and you also have
$lowerLat - the bottom of the box
$upperLat - the top of the box
$westernLong - left side
$easternLong - right side
for your box limits (assuming you have collected these values for your box from somewhere else)
then it's
if ( $lat>=$lowerLat and $lat<=$upperLat and $long>=$westernLong and $long<=$eastermlong)
{
echo "in the box";
and whatever else you want;
}
else
{
echo "out the box";
and whatever else you want;
}
|
|
|
|
12-25-2009, 07:17 PM
|
#7 (permalink)
|
|
Wizard
Join Date: Sep 2007
Posts: 1,298
Thanks: 17
|
Its not quite that simple since he is not working with a rectangle. You can only check for bounds like that when all the lines are either parallel or perpendicular to the graph's axis. Since your are working with a four sides poligon, you have to check against the equation of each line. What he needs is to find if a given point is within any four points. This has come down to a math problem. Since I am not very familiar with GPS (and want to use small non-decimal numbers) we will be doing this on a standard graph.
When you are given four points on a graph, you can make four lines to form a four-sided poligon out of it. See the graph below. Given the points, you need to make a graph out of them. The first thing you need to do is find which points will compose the bottom, left, top and right lines, the points will meet the following criteria:
Bottom points: The two points with the lowest Y
Left points: The two points with the lowest X
Top points: The two points with the highest Y
Right points: The two points with the highest X
Given the points (-2,-1), (2,0), (-2,4), (2,3), (2,0), that would be
Bottom: (-2,-1) and (2,0)
Left: (-2,-1) and (-2,4)
Top: (-2,4) and (2,3)
Right: (2,3) and (2,0)
Now that we have our points, we can get the graph, if you'll remember algebra, the equation for a line is "y=mx+b" or y = slope(x)+y-intercept. So what we need to find is the slope and the y-intercept. To find the slope, use (y2-y1)/(x2-x1), to find the Y intercept set X and Y to either of the two points and solve. This would give us the following:
Bottom: y=(1/4)x+(1/2)
Left: x=-2
Top: y=3
Right: x=2
Shortcut: If the line is top or bottom and both Y are the same, its equation is y=(Y point), if the line is right or left and both X are the same, the equation is x=(X point).
Now that we have our boundaries, we can check against them. This works the same way:
Code:
if xPoint >(left function of Y) AND xPoint < (right function of Y) AND yPoint > (bottom function of X) AND yPoint < (top function of X)
It is in
else
It is not in
end if
I don't have time to elaborate further, I'll do that sometime tonight.Most of this was just teaching the algebra behind it, once you know that the process is really simple.
|
|
|
|
|
The Following User Says Thank You to Village Idiot For This Useful Post:
|
|
12-26-2009, 04:38 AM
|
#8 (permalink)
|
|
The Wanderer
Join Date: Aug 2009
Posts: 18
Thanks: 1
|
Quote:
Originally Posted by russellharrower
Hi guys,
trying to work out the following
I have created a list of GeoLocations and I would like to create a simple system that tells me if a person is inside the area of the GeoLocation I have set for e.g.
If a person it in the area of
144.30'39.82/-38.16'22.00 by with of 144.31'12.99/-38.16'16.20
by
144.30'41.77/-38.16'37.09 by with of 144.31'12.74/-38.16'33.05
so if a person is in that area I want to show that info.
I have the script that collects the GeoLocation but not away to know if a person is in an area.
EDIT: Here is the picture of the area I want.

|
Try this, I worked with something like this once with graph dimensions once. I dont remember it exactly, but from how I've always consider it was to imagine it as a square. So point 1, 2, 3, and 4 are the cases...
PHP Code:
if( (144.30.39.82 <= -38.16.22.00) && /*Point #1*/ (144.31.12.99 <= -38.16.16.20) && /*Point #2*/ (144.30.41.77 <= -38.16.37.09) && /*Point #3*/ (144.31.12.74 <= -38.16.33.05) /*Point #4*/ ) { print("You are within this area"); }
|
|
|
|
12-26-2009, 05:07 PM
|
#9 (permalink)
|
|
Wizard
Join Date: Sep 2007
Posts: 1,298
Thanks: 17
|
Quote:
Originally Posted by Jarod B
Try this, I worked with something like this once with graph dimensions once. I dont remember it exactly, but from how I've always consider it was to imagine it as a square. So point 1, 2, 3, and 4 are the cases...
PHP Code:
if( (144.30.39.82 <= -38.16.22.00) && /*Point #1*/ (144.31.12.99 <= -38.16.16.20) && /*Point #2*/ (144.30.41.77 <= -38.16.37.09) && /*Point #3*/ (144.31.12.74 <= -38.16.33.05) /*Point #4*/ ) { print("You are within this area"); }
|
As I explained in my previous post, that is not a rectangle so you can not do that. You have to check it against the equation of each line opposed to the points themselves. Cheking it your way also only works when the rectangle's sides are either perpendicular or parallel with the axis.
|
|
|
|
12-27-2009, 05:02 AM
|
#10 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
Quote:
Originally Posted by Village Idiot
Its not quite that simple since he is not working with a rectangle. You can only check for bounds like that when all the lines are either parallel or perpendicular to the graph's axis. Since your are working with a four sides poligon, you have to check against the equation of each line. What he needs is to find if a given point is within any four points. This has come down to a math problem. Since I am not very familiar with GPS (and want to use small non-decimal numbers) we will be doing this on a standard graph.
When you are given four points on a graph, you can make four lines to form a four-sided poligon out of it. See the graph below. Given the points, you need to make a graph out of them. The first thing you need to do is find which points will compose the bottom, left, top and right lines, the points will meet the following criteria:
Bottom points: The two points with the lowest Y
Left points: The two points with the lowest X
Top points: The two points with the highest Y
Right points: The two points with the highest X
Given the points (-2,-1), (2,0), (-2,4), (2,3), (2,0), that would be
Bottom: (-2,-1) and (2,0)
Left: (-2,-1) and (-2,4)
Top: (-2,4) and (2,3)
Right: (2,3) and (2,0)
Now that we have our points, we can get the graph, if you'll remember algebra, the equation for a line is "y=mx+b" or y = slope(x)+y-intercept. So what we need to find is the slope and the y-intercept. To find the slope, use (y2-y1)/(x2-x1), to find the Y intercept set X and Y to either of the two points and solve. This would give us the following:
Bottom: y=(1/4)x+(1/2)
Left: x=-2
Top: y=3
Right: x=2
Shortcut: If the line is top or bottom and both Y are the same, its equation is y=(Y point), if the line is right or left and both X are the same, the equation is x=(X point).
Now that we have our boundaries, we can check against them. This works the same way:
Code:
if xPoint >(left function of Y) AND xPoint < (right function of Y) AND yPoint > (bottom function of X) AND yPoint < (top function of X)
It is in
else
It is not in
end if
I don't have time to elaborate further, I'll do that sometime tonight.Most of this was just teaching the algebra behind it, once you know that the process is really simple.
|
First of all I want to thank you all,
But need to ask, (cos my math teacher did not teach us algebra, Can you make a small PHP example please.
Cos I don't understand the xPoint>(left function ...
I would be very greatful.
Thanks
|
|
|
|
12-27-2009, 05:55 AM
|
#11 (permalink)
|
|
That guy
Join Date: Sep 2009
Location: San Antonio, TX
Posts: 24
Thanks: 0
|
X == Horizontal, and Y == Vertical. :P
|
|
|
|
12-27-2009, 11:07 AM
|
#12 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,381
Thanks: 5
|
I have a function which determines whether a point is within a polygon (of any shape) based on decimal lat/lon pairs (rather than degrees, mins, seconds as you appear to be using) if that might be of any use?
|
|
|
|
12-28-2009, 07:57 PM
|
#13 (permalink)
|
|
Wizard
Join Date: Sep 2007
Posts: 1,298
Thanks: 17
|
Quote:
Originally Posted by russellharrower
First of all I want to thank you all,
But need to ask, (cos my math teacher did not teach us algebra, Can you make a small PHP example please.
Cos I don't understand the xPoint>(left function ...
I would be very greatful.
Thanks
|
You would probably be better off going on Google and looking up tutorials on mathematical functions than having me explaining it. But here is basically what I am doing (this is not all technically mathematically correct, but it is an easy way to get the job done). Function of Y means that you replace all the X variables in the equation with the given variable. Function of X means that you replace all the Y variables with the given value. As it ends up, I didn't give you any values to plug in, so that example wouldn't work.
You actually stuck me with some inspiration to write a script for this. Its been a long time since I've wrote anything in PHP so that was actually rather fun. The issue I've faced many times is that I know how to do most common tasks, this was actually a problem solving challenge so I did really enjoy making this.
PHP Code:
<? class point { function __construct($xParam,$yParam) { $this->x=$xParam; $this->y=$yParam; }
public $x; public $y; };
class equation { function __construct($point1,$point2,$debug=false) { //Find the slope of the two points //If the line is horizontal if(($point2->y-$point1->y) == 0) { if($debug==true) $slope=0; $this->isHorizontal = true; $this->isVertical = false; $this->y=$point2->y; } //If the line is vertical else if(($point2->x-$point1->x) == 0) { if($debug==true) $slope=0; $this->isVertical = true; $this->isHorizontal = false; $this->x=$point2->x; } else { if($debug==true) $slope = ($point2->y-$point1->y)/($point2->x-$point1->x); //Since vertical lines have no y intercept and horosontal lines don't need one to be stated, we only need to compute this if the line is at an angle $yInt=$point1->y-($slope*$point1->x); $this->isVertical = false; $this->isHorizontal = false; } $this->m = $slope; $this->b = $yInt; } public function solveForY($xParam) { if($this->isHorizontal == true) { return $this->y; } return $this->m*$xParam+$this->b; } public function solveForX($yParam) { //echo "x=$this->x m=$this->m yParam=$yParam b=$this->b "; if(isVertical == true) { return $this->x; } return ($yParam-$this->b)/$this->m; }
public $m; public $b; private $isVertical; private $isHorizontal; public $x; public $y; };
function isPointIn4Lines(&$pTopLine, &$pRightLine, &$pBottomLine, &$pLeftLine, &$testPoint) { if( $testPoint->y < $pTopLine->solveForY($testPoint->x) &&// If the point lies below the top point $testPoint->y > $pBottomLine->solveForY($testPoint->x) &&// if the point lies above the bottom point $testPoint->x > $pLeftLine->solveForX($testPoint->y) && // if the point lies right of the left line $testPoint->x < $pRightLine->solveForX($testPoint->y) // If the point lies left of the right line ) { return "true"; } return "false"; }
//Application time $point1 = new point(-2,3); $point2 = new point(-2,0); $point3 = new point(3,-4); $point4 = new point(3,3);
$testPoint1 = new point(1,1); $testPoint2 = new point(-1,-2);
//I don't feel like writing up a sorting function, you know how do ID them so do that yourself. $topLeft = $point1; $topRight = $point4; $bottomLeft = $point2; $bottomRight = $point3;
//Generate the lines $topLine = new equation($topLeft,$topRight,true); $rightLine = new equation($topRight,$bottomRight,true); $bottomLine = new equation($bottomLeft,$bottomRight,true); $leftLine = new equation($bottomLeft,$topLeft,true);
echo isPointIn4Lines($topLine,$rightLine,$bottomLine,$leftLine,$testPoint1) . " and " . isPointIn4Lines($topLine,$rightLine,$bottomLine,$leftLine,$testPoint2); //will output "true and false"
?>
What this does it based off of four points, generates four lines. Then it tests to see if the given test points are within these four lines.
|
|
|
|
12-30-2009, 04:08 AM
|
#14 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
Quote:
Originally Posted by Salathe
I have a function which determines whether a point is within a polygon (of any shape) based on decimal lat/lon pairs (rather than degrees, mins, seconds as you appear to be using) if that might be of any use?
|
If you could that would be great.
thanks
|
|
|
|
12-30-2009, 09:47 AM
|
#15 (permalink)
|
|
The Contributor
Join Date: Jul 2009
Posts: 80
Thanks: 13
|
I found a script that works the way I needed it to, I thought I would post it below for anyone else.
{code}
<?php
class pointLocation {
var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices
function pointLocation() {
}
function pointInPolygon($point, $polygon, $pointOnVertex = true) {
$this->pointOnVertex = $pointOnVertex;
// Transform string coordinates into arrays with x and y values
$point = $this->pointStringToCoordinates($point);
$vertices = array();
foreach ($polygon as $vertex) {
$vertices[] = $this->pointStringToCoordinates($vertex);
}
// Check if the point sits exactly on a vertex
if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) {
return "inside";
}
// Check if the point is inside the polygon or on the boundary
$intersections = 0;
$vertices_count = count($vertices);
for ($i=1; $i < $vertices_count; $i++) {
$vertex1 = $vertices[$i-1];
$vertex2 = $vertices[$i];
if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary
return "boundary";
}
if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) {
$xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal)
return "boundary";
}
if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
$intersections++;
}
}
}
// If the number of edges we passed through is even, then it's in the polygon.
if ($intersections % 2 != 0) {
return "inside";
} else {
return "outside";
}
}
function pointOnVertex($point, $vertices) {
foreach($vertices as $vertex) {
if ($point == $vertex) {
return true;
}
}
}
function pointStringToCoordinates($pointString) {
$coordinates = explode(" ", $pointString);
return array("x" => $coordinates[0], "y" => $coordinates[1]);
}
}
/*** Example ***/
//$pointLocation = new pointLocation();
//$points = array("30 19", "0 0", "10 0", "30 20", "11 0", "0 11", "0 10", "30 22", "20 20");
//$polygon = array("10 0", "20 0", "30 10", "30 20", "20 30", "10 30", "0 20", "0 10", "10 0");
//foreach($points as $key => $point) {
// echo "$key ($point) is " . $pointLocation->pointInPolygon($point, $polygon) . "<br>";
//}
{/code}
|
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|