Distance between street and point, if latitude and longitude - php

I have 3 latitudes and longitude:
x :
1.000000000
1.000000000
y :
2.000000000
2.000000000
z :
3.000000000
3.000000000
I need to calculate the smallest distance between Z and the line formed by X -> Y, PLEASE HELP
PHP code that solve my problem until now:
function calc ($a, $ay, $b, $by,$c, $cy) {
$a = array($a, $ay, 0);// i use 0 altitude always
$b = array($b, $by, 0);
$c = array($c, $cy, 0);
$ab = array(
(($a[1] * $b[2]) - ($b[1] * $a[2])),
(($a[2] * $b[0]) - ($b[2] * $a[0])),
(($a[0] * $b[1]) - ($b[0] * $a[1]))
);
$normal = pow(pow($ab[0],2)+pow($ab[1],2)+pow($ab[2],2),0.5);
$d = array(
($ab[0]/$normal),
($ab[1]/$normal),
($ab[2]/$normal)
);
$e_ = (($d[0] * $c[0]) + ($d[1] * $c[1]) + ($d[2] * $c[2]));
$e = acos($e_);
$res = pi()/2 - $e;
$res = $res * 6378.1;
return $res;
}

we need to do some spherical geometry here. If we were just working in the plane the question would be easy https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line things are trickier on a sphere.
First what do we mean by the line formed by X -> Y. We probably mean a great circle https://en.wikipedia.org/wiki/Great_circle
for example the equator.
Assume for a moment that the points X, Y were on the equator, then the distance between Z and the equator would be proportional to the latitude of Z.
One way to solve the problem would be to rotate our points so that X and Y lie on the equator and then find the latitude of Z. A procedure for doing this is (set up axis so x-axis is out through 0,0, the y-axis is due east and the z-axis due north)
Rotate around z-axis X -> X1, Y->Y1, Z->Z1 so the longitude of X1 is zero.
Rotate around y-axis X1 -> X2, Y1->Y2, Z1->Z2 so the latitude of X2 is zero.
Rotate around the z-axis X2->X3, Y2->Y3, Z2->Z3 so the latitude of Y3 is zero
We now have both X3 and Y3 on the equator and can find the latitude of Z3. The actual distance will be radius-of-earth * latitude-of-Z3-in-radians
Curiously #abiessu comment is not actually correct the great circle through 1N 1E and 2N 2E does not quite run through 3N 3E. I make the distance 14cm.
An easier way to calculate this is to find the cross product of X and Y, W=X ^ Y. This vector is the normal to the plane through X, Y and the center of the sphere. Now find the dot product W . Z this is angle-between-W-and-Z * len(W) * len(Z). So divide the dot product by the two lengths to give a and find pi/2-a the angle of inclination of Z above the plane. Multiply this by the radius to get the distance.
Taking the example of points at 1N 1E take points on the unit sphere
a 1.0N 1.0E (0.999695, 0.017450, 0.017452 )
b 2.0N 2.0E (0.998782, 0.034878, 0.034899 )
c 3.0N 3.0E (0.997261, 0.052264, 0.052336 )
a^b (0.000000, -0.017458, 0.017439 )
d=unit(a^b) (0.000011 , -0.707484, 0.706730 )
d . c 0.000022543731833669922
e = acos(d . c) = 1.570773783063061 in radians
pi/2 - e = 0.000022543731835522607
0.14378617602014673km distance on earth with radius 6378.1km

Related

Get Random XYZ on surface of Sphere from Sphere Loc and Radius

I am trying to get random X Y Z coordinates on the surface of a sphere, based on the spheres center in X Y Z, and it's radius in PHP. Currently, my system is just purely random, hoping for a position on the planets center. I'm inept in math so please bear with me (dyscalculia and dyslexia).
Right now I have just random chaos as follows (note randint is a custom function that checks for rand_int, mt_rand and rand and uses the newest.
$nx = randint( abs( $poo['x'] - $max_distance_x ), abs( $poo['x'] + $max_distance_x ) );
$ny = randint( abs( $poo['y'] - $max_distance_y ), abs( $poo['y'] + $max_distance_y ) );
$nz = randint( abs( $poo['z'] - $max_distance_z ), abs( $poo['z'] + $max_distance_z ) );
but I have the planet radius $pradius, and planet XYZ center array $poo poo(x, y, z), and I think I can get random surface X Y Z, just not sure. I've looked at other languages but am having trouble understanding anything to port.
Update
Based on the two methods provided in an answer I have come up with the following two functions. However both to not function correctly.
The following function only produces craters (points) on the top of the planetoid (north pole), even though it should be calculating from planetoid center at it's radius.
function basic_spheroid_point( $cx, $cy, $cz, $r ) {
$x = randint(-$r, $r);
$y = randint(-$r, $r);
$z = randint(-$r, $r);
$dx = $x - $cx;
$dy = $y - $cy;
$dz = $z - $cz;
$dd = sqrt( ( $dx * $dx ) + ( $dy * $dy ) + ( $dz * $dz ) );
if ( $dd > $r )
return basic_spheroid_point( $cx, $cy, $cz, $r );
$dx = $r * $dx / $dd;
$dy = $r * $dy / $dd;
$dz = $r * $dz / $dd;
return array( $cx + $dx, $cy + $dy, $cz + $dz );
}
This function bunches craters at the North Pole of the planet, though there is also global coverage craters so it is working partially.
function uniform_spheroid_point($cx, $cy, $cz, $r) {
$ap = randint( 0, 359 );
$aq = randint( 0, 359 );
$dx = $r* cos( $ap ) * cos( $aq );
$dy = $r * sin( $aq );
$dz = $r * sin( $ap ) * cos( $aq );
return array( $cx + $dx, $cy + $dy, $cz + $dz );
}
You're currently selecting a point at random from the interior of a parallelepiped with side lengths 2*max_distance_x, 2*max_distance_y and 2*max_distance_z. Let us assume that these are all the same and equivalent to the radius r of the sphere on whose surface you'd like to randomly select points. Then, your method would select randomly from a cube of side length 2r. Essentially none of your random points will actually be on the surface of the sphere of radius r when selected in this way.
However - given a point in the cube, what you can do is this:
calculate the vector from the center point to your random point (the "delta"). For example, if your center point is 100,100,100 and your radius is 100 and you randomly pick point 50,100,150, the vector you're looking for is -50,0,50.
calculate the length of the vector from step 1. This uses the formula for the distance between two points, extended so that it contemplates the point's three coordinates: sqrt(dx^2 + dy^2 +dz^2). For example, our distance is sqrt((-50)^2 + 0^2 + 50^2) = sqrt(2500 + 0 + 2500) = 50sqrt(2).
scale the vector from step 1 by a factor equal to r/d where d is the vector's length as determined in step 2. For our example, we will scale the vector by a factor of r/d = 100/(50sqrt(2)) = 2/sqrt(2) = sqrt(2). This gives -50sqrt(2), 0, 50sqrt(2).
Now, add the scaled vector from step 3 to the center point to get a point on the surface of the sphere of radius r. In our example, the point on the surface of the sphere is 100-50sqrt(2), 100, 100+50sqrt(2).
Now the only issue with this is that some points are more likely to be chosen than others. The reason for this is that some points on the surface of the sphere have more of the cube outside them than other points do. Specifically, a point of the sphere lying on the bounding cube has no points further outside it, but the point on the sphere that intersects a line connecting the center of the cube and one of its corners has a lot of space outside the sphere). To get a truly uniform distribution of points, you'd need to exclude any points selected at random which do not lie inside or on the surface of the sphere. If you do that, you will get a uniform distribution of points by the above method. Because the volume of the cube is 8r^3 and the volume of the sphere is 4/3pir^3, and because 4/3pi ~ 4, you have about a 50% chance at each draw of getting a point that you have to throw away. On average, you'd expect to get one good point in every two draws. You should not typically need many random draws to get a good one, but it is technically unbounded.
If you want to make sure every random draw is a good one, I might suggest selecting two angles uniformly at random from 0 to 360 degrees. Then, use those angles to identify a point on the sphere. So, for instance, suppose you first draw angle p and then angle q. Angle p can determine the plain from which the point will be taken. This plane will intersect the sphere in a circular cross section. Angle q can then determine which point on this intersected circle is returned as the random point. Suppose these angles give point (x', y', z'). Well...
y' = r*sin(q) … since nothing else determines the y coordinate except q
x' = r*cos(p)*cos(q)
z' = r*sin(p)*cos(q)
This has the advantage of not needing to reject any random samples, and the disadvantage of requiring relatively more costly trigonometric operations.
EDIT: Pseudocode for each method
Method 1:
RandomPointOnSphere(centerX, centerY, centerZ, radius)
1. x = random(-radius, radius)
2. y = random(-radius, radius)
3. z = random(-radius, radius)
4. dx = x - centerX
5. dy = y - centerY
6. dz = z - centerZ
7. dd = sqrt(dx*dx + dy*dy + dz*dz)
8. if dd > radius then return RandomPointOnSphere(centerX, centerY, centerZ, radius)
9. dx = radius * dx / dd
10. dy = radius * dy / dd
11. dz = radius * dz / dd
12. return (centerX + dx, centerY + dy, centerZ + dz)
Method 2:
RandomPointOnSphere(centerX, centerY, centerZ, radius)
1. angleP = random(0, 359)
2. angleQ = random(0, 359)
3. dx = radius* cos(angleP) * cos(angleQ)
4. dy = radius * sin(angleQ)
5. dz = radius * sin(angleP) * cos(angleQ)
6. return (centerX + dx, centerY + dy, centerZ + dz)

Finding Points in a Rectangle or Circle with mysql

I have a mysql database table with a list points with their Co-ordinates (x,y)
I want to find the list of points which fall inside the rectangle. This would have been simple had any one side of the rectangle been aligned parallel or perpendicular to any axis. But is not. Which means the rectangle is rotated.
I also have to find the points inside a circle.
Known Data for Rectangle
-Coordinates for all the four points
Known Data for Circle
-Co-ordinates for the center and the radius.
How do I query the mysql table to find the points falling in the rectangle and the circle?
If it matters then the front end I am using is PHP.
A rectangle can be defined by two points representing the opposing corners, eg: A(x,y) and B(x,y). If you have a point C(x,y) that you want to test to see if it is inside the rectangle then:
IF( (Cx BETWEEN Ax AND Bx) AND (Cy BETWEEN Ay AND By) ) THEN
point C is in the rectangle defined by points A and B
ELSE
nope
ENDIF
A circle can be defined by a single point C(x,y) and a radius R. If the distance D between the center and the point P(x,y) is less than the radius R, then it is inside the circle:
And of course you remember the Pythagorean Theoreom, right?
C² = A² + B² SO C = SQRT(A² + B²)
So:
D = SQRT( ABS(Cx - Px)² + ABS(Cy - Py)²)
IF( D <= R ) THEN
point P is inside the circle with center C and radius R
ELSE
nope
ENDIF
edit:
The algorithm for checking if a point is within a polygon is a bit more complex than what I'd prefer to write in a SQL query or stored procedure, but it is entirely possible. It's worth noting that it runs in constant-time and is very lightweight. [requires roughly 6 arithmetic ops and maybe 2 or 3 logic ops for each point in the poly]
To pare down the number calculations required you can simply write your select to get points within a rough bounding box before procesing them further:
WHERE
x BETWEEN MIN(x1,x2,x3,x4) AND MAX(x1,x2,x3,x4)
AND
y BETWEEN MIN(y1,y2,y3,y4) AND MAX(y1,y2,y3,y4)
Assuming the columns containing the x and y values are indexed this might use a few less CPU cycles than simply doing the math, but it's debatable and I'm inclined to call it a wash.
As for the circle you can't possibly get more efficient than
WHERE
SQRT( POW(ABS($Cx - x),2) + POW(ABS($Cy - y),2) ) < $radius
You're far too concerned with the perceived cost of these calculations, just write the code and get it working. This is not the stage to be performing such niggling optimizations.
One thing to add to #Sammitch's answer is, calculating haversine distance in case you are looking at latitudes and longitudes on world map (distance calculation on a spherical surface, since Earth is a sphere ;) https://en.wikipedia.org/wiki/Haversine_formula)
Here's a vanilla Javascript example for calculating that:
function calculateHaversineDistance(lat1x, lon1, lat2x, lon2) {
var R = 6371; // km
var dLat = toRad(lat2x-lat1x);
var dLon = toRad(lon2-lon1);
var lat1 = toRad(lat1x);
var lat2 = toRad(lat2x);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function toRad(x) {
return x * Math.PI / 180;
}
EDIT->
Here's a php version I wrote:
function toRad($x) {
return $x * pi() / 180;
}
function calculateHaversineDistance($lat1, $lon1, $lat2, $lon2) {
$R = 6371; // km
$dLat = $this->toRad($lat2-$lat1);
$dLon = $this->toRad($lon2-$lon1);
$lat1 = $this->toRad($lat1);
$lat2 = $this->toRad($lat2);
$a = sin($dLat/2) * sin($dLat/2) +
sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
return $R * $c;
}

LinearRing with direction KML

I have a database with points (coordinates) and headings (direction/azimuths). I would like to create pie shaped sectors(LinearRing) pointing in the headings direction in kml. Anyone has any suggestions on how to build this using php?
Ok, php is not my strength. Here is pseudo-code, which might help you (*).
"On a sphere of radius r, compute points on a great circle at specified azimuths and ranges. PHI, LAMBDA, PHI0, LAMBDA0, and AZ are angles in radians, and RNG is a distance having the same units as R."
INPUT: phi0, lambda0, az, rng, r
OUTPUT: phi,lambda
rng = rng / r; // Convert the range to an angle on the sphere (in radians).
epsilon = 1.7453e-07; // Set tolerance
if(phi0 >= pi / 2 - epsilon) // starting at north pole
az = pi;
if(phi0 <= epsilon - pi / 2) // starting at south pole
az = 0;
// Calculate coordinates of great circle end point using spherical trig.
phi = asin( sin(phi0) * cos(rng) + cos(phi0) * sin(rng) * cos(az) );
lambda = lambda0 + atan2( sin(rng) * sin(az) , cos(phi0) * cos(rng) - sin(phi0) * sin(rng) * cos(az) );
phi0 and lambda0 are your initial coordinates and az your heading. Vary az +/- a certain range in order to obtain points, which form the circle segment of the pie. The rest should be straight-forward.
(*) Source: http://mind.cog.jhu.edu/courses/680/octave/Installers/Octave/Octave.OSX10.6/Applications/MATLAB_R2009b.app/toolbox/map/map/private/greatcirclefwd.m

How do I check if a longitude/latitude point is within a range of coordinates?

I have a number of longitude and latitude coordinates that make up a polygonal zone. I also have a longitude and latitude coordinate to define the position of a vehicle. How do I check that the vehicle is located within the polygonal zone?
This is essentially the Point in polygon problem on a sphere. You can modify the ray casting algorithm so that it uses arcs of great circles instead of line segments.
for each pair of adjacent coordinates that make up your polygon, draw a great circle segment between them.
Choose a reference point that is not inside the polygonal zone.
draw a great circle segment that begins at the reference point and ends at the vehicle point. Count how many times this segment crosses over a segment of your polygon. If the total number of times is odd, the vehicle is within the polygon. If even, the vehicle is outside of the polygon.
Alternatively, if the coordinates and vehicle are sufficiently close together, and not anywhere near the poles or international date line, you can pretend the earth is flat and use longitude and lattitude as simple x and y coordinates. That way, you can use the ray casting algorithm with simple line segments. This is preferable if you are not comfortable with non-euclidean geometry, but you'll have some distortion around the borders of your polygons since the arcs will be distorted.
EDIT: A little more on geometry on a sphere.
A great circle can be identified by the vector that lies perpendicular to the plane the circle lies on (AKA, the normal vector)
class Vector{
double x;
double y;
double z;
};
class GreatCircle{
Vector normal;
}
Any two lattitude/longitude coordinates that aren't antipodal share exactly one great circle. To find this great circle, convert the coordinates to lines that pass through the center of the earth. The cross product of those two lines is the normal vector of the coordinate's great circle.
//arbitrarily defining the north pole as (0,1,0) and (0'N, 0'E) as (1,0,0)
//lattidues should be in [-90, 90] and longitudes in [-180, 180]
//You'll have to convert South lattitudes and East longitudes into their negative North and West counterparts.
Vector lineFromCoordinate(Coordinate c){
Vector ret = new Vector();
//given:
//tan(lat) == y/x
//tan(long) == z/x
//the Vector has magnitude 1, so sqrt(x^2 + y^2 + z^2) == 1
//rearrange some symbols, solving for x first...
ret.x = 1.0 / math.sqrt(tan(c.lattitude)^2 + tan(c.longitude)^2 + 1);
//then for y and z
ret.y = ret.x * tan(c.lattitude);
ret.z = ret.x * tan(c.longitude);
return ret;
}
Vector Vector::CrossProduct(Vector other){
Vector ret = new Vector();
ret.x = this.y * other.z - this.z * other.y;
ret.y = this.z * other.x - this.x * other.z;
ret.z = this.x * other.y - this.y * other.x;
return ret;
}
GreatCircle circleFromCoordinates(Coordinate a, Coordinate b){
Vector a = lineFromCoordinate(a);
Vector b = lineFromCoordinate(b);
GreatCircle ret = new GreatCircle();
ret.normal = a.CrossProdct(b);
return ret;
}
Two great circles intersect at two points on the sphere. The cross product of the circles forms a vector that passes through one of those points. The antipode of that vector passes through the other point.
Vector intersection(GreatCircle a, GreatCircle b){
return a.normal.CrossProduct(b.normal);
}
Vector antipode(Vector v){
Vector ret = new Vector();
ret.x = -v.x;
ret.y = -v.y;
ret.z = -v.z;
return ret;
}
A great circle segment can be represented by the vectors passing through the segment's start and end points.
class GreatCircleSegment{
Vector start;
Vector end;
Vector getNormal(){return start.CrossProduct(end);}
GreatCircle getWhole(){return new GreatCircle(this.getNormal());}
};
GreatCircleSegment segmentFromCoordinates(Coordinate a, Coordinate b){
GreatCircleSegment ret = new GreatCircleSegment();
ret.start = lineFromCoordinate(a);
ret.end = lineFromCoordinate(b);
return ret;
}
You can measure the arc size of a great circle segment, or the angle between any two vectors, using the dot product.
double Vector::DotProduct(Vector other){
return this.x*other.x + this.y*other.y + this.z*other.z;
}
double Vector::Magnitude(){
return math.sqrt(pow(this.x, 2) + pow(this.y, 2) + pow(this.z, 2));
}
//for any two vectors `a` and `b`,
//a.DotProduct(b) = a.magnitude() * b.magnitude() * cos(theta)
//where theta is the angle between them.
double angleBetween(Vector a, Vector b){
return math.arccos(a.DotProduct(b) / (a.Magnitude() * b.Magnitude()));
}
You can test if a great circle segment a intersects a great circle b by:
find the vector c, the intersection of a's whole great circle and b.
find the vector d, the antipode of c.
if c lies between a.start and a.end, or d lies between a.start and a.end, then a intersects with b.
//returns true if Vector x lies between Vectors a and b.
//note that this function only gives sensical results if the three vectors are coplanar.
boolean liesBetween(Vector x, Vector a, Vector b){
return angleBetween(a,x) + angleBetween(x,b) == angleBetween(a,b);
}
bool GreatCircleSegment::Intersects(GreatCircle b){
Vector c = intersection(this.getWhole(), b);
Vector d = antipode(c);
return liesBetween(c, this.start, this.end) or liesBetween(d, this.start, this.end);
}
Two great circle segments a and b intersect if:
a intersects with b's whole great circle
b intersects with a's whole great circle
bool GreatCircleSegment::Intersects(GreatCircleSegment b){
return this.Intersects(b.getWhole()) and b.Intersects(this.getWhole());
}
Now you can construct your polygon and count how many times your reference line passes over it.
bool liesWithin(Array<Coordinate> polygon, Coordinate pointNotLyingInsidePolygon, Coordinate vehiclePosition){
GreatCircleSegment referenceLine = segmentFromCoordinates(pointNotLyingInsidePolygon, vehiclePosition);
int intersections = 0;
//iterate through all adjacent polygon vertex pairs
//we iterate i one farther than the size of the array, because we need to test the segment formed by the first and last coordinates in the array
for(int i = 0; i < polygon.size + 1; i++){
int j = (i+1) % polygon.size;
GreatCircleSegment polygonEdge = segmentFromCoordinates(polygon[i], polygon[j]);
if (referenceLine.Intersects(polygonEdge)){
intersections++;
}
}
return intersections % 2 == 1;
}

latitude / longitude formula in php solution for determining a NSWE corners from a central point

lat/long outward distance approx 800ft on each side from center.
I have a central point of:
Latitude:38.6806353
Longitude:-96.5001029
I am trying to resolve a formula with php how to get the latitude / longitude to the NWSE corners approx 800ft outward from a center point.
So I would end up with a result similar to (but not correct):
Central:
38.6806353 -96.5001029
N: 38.6806353 -96.5001029
W: 38.6806353 -96.5001029
S: 38.6806353 -96.5001029
E: 38.6806353 -96.5001029
I've been trying to reverse engineer a few Javascripts that I found, but having absolutly no luck.
Is there a php Class available that does this math or similar that would require minor revisions? I can't find one thus far...
I found this function and I've been toying with it. I can get a nice array output like:
Array ( [0] => -112.35301079549 [1] => 36.105603064867 [2] => -112.25722008867 [3] => 36.105603064867 )
But I can't get a N W S E coordinates set to generate? Anyone know what I am doing wrong with this? I need 4 sets of values instead of two like:
N: 38.6806353 -96.5001029
W: 38.6806353 -96.5001029
S: 38.6806353 -96.5001029
E: 38.6806353 -96.5001029
<?php function getBoundingBox($lon_degrees,$lat_degrees,$distance_in_miles) {
$radius = 3963.1; // of earth in miles
// bearings
$due_north = 0;
$due_south = 180;
$due_east = 90;
$due_west = 270;
// convert latitude and longitude into radians
$lat_r = deg2rad($lat_degrees);
$lon_r = deg2rad($lon_degrees);
// find the northmost, southmost, eastmost and westmost corners $distance_in_miles away
// original formula from
// http://www.movable-type.co.uk/scripts/latlong.html
$northmost = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_north));
$southmost = asin(sin($lat_r) * cos($distance_in_miles/$radius) + cos($lat_r) * sin ($distance_in_miles/$radius) * cos($due_south));
$eastmost = $lon_r + atan2(sin($due_east)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));
$westmost = $lon_r + atan2(sin($due_west)*sin($distance_in_miles/$radius)*cos($lat_r),cos($distance_in_miles/$radius)-sin($lat_r)*sin($lat_r));
$northmost = rad2deg($northmost);
$southmost = rad2deg($southmost);
$eastmost = rad2deg($eastmost);
$westmost = rad2deg($westmost);
// sort the lat and long so that we can use them for a between query
if ($northmost > $southmost) {
$lat1 = $southmost;
$lat2 = $northmost;
} else {
$lat1 = $northmost;
$lat2 = $southmost;
}
if ($eastmost > $westmost) {
$lon1 = $westmost;
$lon2 = $eastmost;
} else {
$lon1 = $eastmost;
$lon2 = $westmost;
}
return array($lon1,$lat1,$lon2,$lat1);
}
?>
I noticed that $due_north, $due_south, etc are in degrees but you have sin($due_east) without a conversion of $due_east to radians.
For 90 deg bearing (east), θ= pi/2 (90 deg), d/R will be 800ft / 5280 ft/mi / 3959 miles (radius of earth in miles), lat1/lon1 are your center point lat/lon in radians.
east_lat = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(θ))
east_lon = lon1 + atan2(sin(θ)*sin(d/R)*cos(lat1), cos(d/R)−sin(lat1)*sin(lat2))
Convert back to degrees then repeat for the other 3 corners.
The comment in your code references the website:
http://www.movable-type.co.uk/scripts/latlong.html
Go to the section Destination point given distance and bearing from start point. You can check your calculations with the calculator on the web page.
The bounding box must satisfy some conditions you didn't mentioned. For example Google Maps uses a z curve and 21 zoom level to subdivide the map into smaller tiles. I don't know how big is a single tile in distance but I use the script from John Brafford to convert from geo coordinate to WGS84 Datum. There is also a method to return the bounding box of a tile. You can find the script here: http://bafford.com/software/aggregate-map-tools/GlobalMapTiles.php.txt.

Categories