GPS coordinates: 1km square around a point - javascript

I was hoping someone out there could provide me with an equation to calculate a 1km square (X from a.aaa to b.bbb, Y from c.ccc to c.ccc) around a given point, say lat = 53.38292839 and lon = -6.1843984? I'll also need 2km, 5km and 10km squares around a point.
I've tried googling around to no avail... It's late at night and was hoping someone might have quick fix handy before I delve into the trigonometry...
I'll be running all this in Javascript, although any language is fine.

If the world were a perfect sphere, according to basic trigonometry...
Degrees of latitude have the same linear distance anywhere in the world, because all lines of latitude are the same size. So 1 degree of latitude is equal to 1/360th of the circumference of the Earth, which is 1/360th of 40,075 km.
The length of a lines of longitude depends on the latitude. The line of longitude at latitude l will be cos(l)*40,075 km. One degree of longitude will be 1/360th of that.
So you can work backwards from that. Assuming you want something very close to one square kilometre, you'll want 1 * (360/40075) = 0.008983 degrees of latitude.
At your example latitude of 53.38292839, the line of longitude will be cos(53.38292839)*40075 = [approx] 23903.297 km long. So 1 km is 1 * (360/23903.297) = 0.015060 degrees.
In reality the Earth isn't a perfect sphere, it's fatter at the equator. And the above gives a really good answer for most of the useful area of the world, but is prone to go a little odd near the poles (where rectangles in long/lat stop looking anything like rectangles on the globe). If you were on the equator, for example, the hypothetical line of longitude is 0 km long. So how you'd deal with a need to count degrees on that will depend on why you want the numbers.

Here is something from my notes to be used on Android with its decimal GPS.
Lat Long:
NY City 40N 47 73W 58 40.783333 73.966667
Wash DC 38N 53 77W 02 38.883333 77.033333
yields = 209 miles !! VERY CLOSE
Distance (miles) (x) = 69.1 (lat2-lat1)
Distance(miles) (y) = 53.0 (long2 - long1)
As crow flys sqrt (x2 + y2) ... duh!#
delta(LAT) / Mile = .014472
delta(LONG) / Mile = .018519
Using a box as approximation
To find someone within 100 miles (100 north / 100 south, 100 E / 100 W)
From 0,0
-14.472 / + 14.472 , -18.519 / 18.519

A simpler way of generating a gps square given the centre would be to use the indirect Vincenty algorithm.The Javascript code here shows how to do it http://www.movable-type.co.uk/scripts/latlong.html.
Creating a square using a circle isn't to hard. Squares are equal distance to each point. So given a centre point, distance from the centre, change the bearing from 0 or any number depending on rotation of the square and increment by 90 degrees or PI/2 radians. By incrementing by 90 degrees each time and you will up with a square in circular space.
I use this myself for generating GPS points around a centre point with a given distance
.---.
--/-
--0--
-/--
.---.

TL;DR
10 km = 0.08999 radius from a certain geopoint. This calculation is only based on latitude values and applies only to geopoints with WGS84 projection.
More details
If you want a more accurate answer you must have to calculate it by building a function of some sort. However it still don't guarantee because people even quarrel for the degrees of error. Taking altitude into account, mercator or not, etc.
Caution
The value above is just a rule of a thumb so don not use it for critical applications.
Reference
GIS StackExchange, How do I calculate the bounding box for given a distance and latitude/longitude, answer by David the Australian developer

Related

Applying offsets to latitude/longitude results in large distance errors

I am trying to develop a "divide and conquer" algorithm to determine squares of latitude and longitude.
I wish to start with an 800 mile x 800 mile box around the UK. Then divide this into four squares, and then recursively repeating this process until the squares are 25 miles square. This will then be used to filter out unwanted results from a proximity search in a database of locations.
However, the algorithm I have which applies an offset to a lat/long (see below code), is giving me problems. I have tried other ones, too, but with much the same results. I think it may be my understanding of applying a coordinate system to a sphere.
I would expect that with a starting point, moving east 800 miles, then moving west 800 miles would result in being returned to (approx) the same location. However, this is not the case:
var coord =
{
lat : 60.678413562308236,
lng : -12.5
};
// Apply a distance and bearing to a set of coords.
var addOffset = function(coord, distance, angle)
{
// Earth Radius
//var radius = 6378.14; // KM
var radius = 3958.8; // Miles
// Degrees to Radians
var lat = coord.lat * (Math.PI/180);
var lng = coord.lng * (Math.PI/180);
var bearing = angle * (Math.PI/180);
var lat2 = Math.asin(Math.sin(lat)*Math.cos(distance/radius) + Math.cos(lat)*Math.sin(distance/radius)*Math.cos(bearing));
var lng2 = lng + Math.atan2(Math.sin(bearing)*Math.sin(distance/radius)*Math.cos(lat), Math.cos(distance/radius)-Math.sin(lat)*Math.sin(lat2));
// back to degrees
lat2 = lat2 * (180/Math.PI);
lng2 = lng2 * (180/Math.PI);
return { lat : lat2, lng : lng2};
}
console.log("start");
console.log(coord);
console.log("Move 800 miles east");
coord = addOffset(coord, 800, 90.0) // East
console.log(coord);
console.log("Move 800 miles west");
coord = addOffset(coord, 800, 270.0) // West
console.log(coord);
Further, when "walking" an 800 mile square around the UK, and plotting the points on a Google Map, I get big problems! The below is starting north-west, going south 800 miles, then going east 800 miles, then north 800 miles, then west 800 miles. As you can see, it's gone quite wrong:
Here's a fiddle (couldn't work out how to get the map working on a code snippet here):
https://jsfiddle.net/leetaylor/aoxnsqeu/6/
Could anyone explain where I'm going wrong? Is it possible to divide up geography into squares using lat/longs?
The problem is that your addOffset doesn't do what you think it does. Quoting the source site
Given a start point, initial bearing, and distance, this will
calculate the destina­tion point and final bearing travelling along
a (shortest distance) great circle arc.
My emphasis. So when you say you want an initial bearing of East, you aren't calculating where you end up if you go east; instead, you're calculating where you end up if you follow the great circle that going east to start with puts you on. If you start from a point in the northern hemisphere and head east or west using this rule, you will curve south towards the equator, exactly as you can see happening in your map.
Note that the due-north and due-south lines are perfect, because lines of longitude are great circles.
Now, since you just want lat-long 'squares', you don't need trigonometry at all - just move along lines of latitude and longitude. This means that the top and bottom edge of each 'square' won't actually be the same length, but at temperate latitudes like the UK it shouldn't be too bad.

How to get get lat lng X kilometer away from center of circle

I am creating list of circles on my map using a loop. The circle radius may differ for each loop.
The logic should not overlap two circles. For this I need the following :-
Start with lat lng (circle center) and draw a circle.
Move radius*2 kilometer ahead and get the center point for second circle and so on.
Problem :
I am facing problem in the second step given above. How should I calculate the next point(Circle center) in row ? The input that I have is center point of first circle and radius.
Any suggestions?
The approximate conversions are:
Latitude: 1 deg = 110.574 km
Longitude: 1 deg = 111.320*cos(latitude) km
This doesn't fully correct for the Earth's polar flattening -- for that you'd probably want a more complicated formula using the WGS84 reference ellipsoid (the model used for GPS). But the error is probably negligible for your purposes.
Source: http://en.wikipedia.org/wiki/Latitude
So you can calculate the distance you need to move on the map and the latitude, Longitude for the next point on the map.
However there is a library (I have never used it, nut hope it helps)
http://www.jstott.me.uk/jcoord/

ol3 - calculate real meters in epgs 3857

I use ol3 as a map service.
I have made a linestring with two points with coordinates : [[0,0],[0,1000]] and calculated the distance using the vincenty formula. This resulted in 1000 meter, what is accurate.
But when i made another linestring for example [[4052627,3971934],[4052627,3972934]] vincenty distance was around 850 meters.
I dont know what i forgot here. Any way to correct that? I want to calculate epgs:3857 meters (units) for a given real distance.
You can use ol.sphere.haversineDistance:
var c1 = [4052627, 3971934];
var c2 = [4052627,3972934];
var wgs84Sphere = new ol.Sphere(6378137);
var length = wgs84Sphere.haversineDistance(
ol.proj.transform(c1, 'EPSG:3857', 'EPSG:4326'),
ol.proj.transform(c2, 'EPSG:3857', 'EPSG:4326'));
// 833.12 m
Distances are tricky. The fact that the map units of a coordinate system are in meters (as epsg:3857) doesn't mean that you can measure distances in meters directly. See https://en.wikipedia.org/wiki/List_of_map_projections, and look how many of those have the "equidistant" property.
I suggest you use turf.js to calculate accurate geodetic distances: http://turfjs.org/static/docs/module-turf_distance.html
After alot of search I've found this PDF document:
Web Mercator:
Non-Conformal, Non-Mercator
There is something called Point Scale Factor - according to the way web Mercator is projected - which has tow values, not one like normal Mercator , North/South Scale Factor and East/West Scale Factor.
in my program I've ignored the East/West Scale Factors because it's to much small.
Once I've calculated the scale factor the real distance is almost equal to scale_factor * epgs_3857_distence

Query database values based on user's location

How can I perform a query on the database as per the user's location value? The application was developed with HTML5, CSS, Javascript, PHP has a database with columns as in the below table.
On the html webpage the users geo coordinates are collected and are to be compared with the values in the database to find the nearest place to the user with the places in the database.
Please let me know how to achieve this. Any examples / samples will be appreciated.
There is a question that compares the capabilities of various spatial databases, GIS: PostGIS/PostgreSQL vs. MySql vs. SQL Server?, where Postgis comes out a pretty clear winner over MySQL.
Whether you use MySQL or Postgis, you would be much better off, if you can, storing your latitude and longitude values as a geometry/geography (Point), as the functions that can be used to find things nearby, ST_Distance, ST_Distance_Sphere and the more obscure <-> operator, see Find n Nearest Neighbors for given Point using PostGIS? (for example usage) work directly on geometry/geography columns. Even more importantly, you can add a spatial index, which these functions need to work properly, which will outperform searches on separately indexed latitude and longitude columns by a large margin (this will depend on table size, but will grow as table size grows),
In Postgis, you can convert lat and lon to a geometry with:
alter table mytable add column geom (Geometry, 4326);
update mytable set geom = ST_SetSRID(ST_MakePoint(lon, lat), 4326)
create index ix_spatial_mytable_geom on mytable using gist(geom);
At this point, you will be able to very efficient queries to find points near other points, using any of the examples in the above links.
You can do similar things in MySQL, although, it does not support a spatial reference system, ie, the 4326 above, which means lat/lon, and it lacks a ST_MakePoint function, so you would need to use STGeomFromText and concatenate the lat/lon together to make a POINT. It also does everything in planar coordinates, as Claudio and others have stated, which is not an issue with Postgis.
I apologize for a long and somewhat tangential answer, but having done various migrations between databases on large amounts of data (MySQL, SQL Server and Postgres/GIS) and made lots of mistakes on the way, I hope I can set you off in the right direction (and add a bit of future proofing, if you want to start using some other spatial functionality, which Postigs has in spades).
For a rough measure I would try something like the following (only Euclidean geometry, it doesn't take into account the Earth curvature or problems like this).
First you could compute the difference between the user's coordinates and the coordinates of places in the database. Like this:
distLat = abs(userLat - placeLat)
distLong = abs(userLong - placeLong)
Then I would compute the distance between the two points using Pythagora's theorem. So:
distance = squareRoot(distLat * distLat + distLong * distLong)
You can compare the distances of all places in the database and take the minimum, which teoreticaly is the place nearest to the user's position.
If you use MySQL I think that a query like this should work:
SELECT * FROM places ORDER BY MIN(SQRT((p.latitude - userLatitude) * (p.latitude - userLatitude) + (p.longitude - userLongitude) * (p.longitude - userLongitude))) LIMIT 1
Beware that this query could be very slow depending on how many places you have, because it needs to read all the rows in the table and compute the distance for each one. Indexes have no effects.
Anyway, for this kind of problems you should better use GIS or databases with good geospatial extensions. MySQL geospatial extension is not very powerful, even in MySQL 5.6. It has a ST_DISTANCE function but still uses Euclidean geometry which is not very accurate for calculation on a spherical surface like the Earth. Anyway, if you use MySQL 5.6, I think that it should be better to use the ST_DISTANCE function, which is for sure much more optimized than doing calculations "manually" in the query.
See also this article for a deep explanation and more examples: http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc
EDIT
As requested by the OP, I add more details on how to deal with negative coordinates.
Negative coordinates are generally not a big issue. I will try to explain this with some examples.
Take for example the coordinates of the Brooklyn bridge: 40.704391, -73.994675.
With the above formula, the distance of the Brooklyn bridge from the Statue of Liberty is:
sqrt((40.704391 - 40.689167)^2 + (-73.994675 - -74.044444)^2) = 0.052045399
Now consider the distance between the Statue of Liberty and the Brooklyn Bowl (coordinates 40.7179666, -73.9670125), that is:
sqrt((40.7179666 - 40.689167)^2 + (-73.9670125 - -74.044444)^2) = 0.082613886
As you can see the distance of the Brooklyn Bowl from the Statue of Liberty is bigger than the distance of the Brooklyn Bridge. It is correct since the Brooklyn Bowl is 4 miles away from the Statue of Liberty, while the Brooklyn Bridge is only 1 mile away from it.
In this example both the two points has a negative longitude. But the formula works even if one of the two has positive coordinates. For example, the distance between the Statue of Liberty and the Tour Eiffel (Paris, coordinates 48.858360, 2.294460), is:
sqrt((48.858360 - 40.689167)^2 + (2.294460 - -74.044444)^2) = 76.77476134
Then calculate also the distance between the Statue of Liberty and the Colosseum (Rome, coordinates 41.890238, 12.492242):
sqrt((41.890238 - 40.689167)^2 + (12.492242 - -74.044444)^2) = 86.54502063
As you can see it works, the distance of the Colosseum is bigger since it is about 8000km away from the Statue of Liberty, while the Tour Eiffel is about 800 km closer.
The only issue I see is when you have to calculate the distance between two places that are in the far east and in the far west respectively. The above formula will give you a very high distance, but actually the they could be very close. Take for example Anchorage, a city in Alaska (coordinates 61.252240, -149.896769), and Beringovskij, a city in the very east of Russia (coordinates 63.049797, 179.310011). They have a distance of only about 1500 km but with the above formula you get:
sqrt((61.252240 - 63.049797)^2 + (-149.896769 - 179.310011)^2) = 329.2116875
Definitely a too high value for only 1500 km: I would expect something less than 50.
The problem is that the formula calculates the distance taking the central meridian as a reference point, that is the meridian with a 0 degrees latitude. This is good until the distance is "no more that half the Earth".
I think that a solution could be to calculate two distances.
The first with a reference point of 0 degrees: it is what the above formula does.
The second with a reference point of 180 degrees. It's like calculating the distance on a world map shifted by 180 degrees, like this: http://www.bouwman.com/world/Formilab-180.html.
And then take the minimum of these two distances.
Thus the formula becomes a little more complex:
distance = squareRoot(min((userLat - placeLat)^2, (userLat - placeLat - 360)^2) + (userLong - placeLong)^2)
Note that we subtract 360 because it is the distance between the degree -180 and the degree 180.
With this new formula we get correct results for places that are more then 180 degrees away from each other, and we get also the same result given by the previous formula when comparing places that are less then 180 degrees away from each other. The calculate distance Anchorage - Beringovskij is now: 30.84564166.
Of course, as I have already said, this is not an exact method for calculating distances. You can take a look at this article for more "scientific" techniques: https://en.wikipedia.org/wiki/Geographical_distance :D

How to find area of given coordinates? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How to find area of given coordinates?
Requirements:
I have a polygon coordinates on a map then we want to find area of polygon in hectares and acres
Coordinates are in decimal degrees area should be in decimal degrees
we can convert hectares and acres kindly replay me
Coordinates are
(10.072642780669105,76.3268655538559),(10.078051232146612,76.32986962795258]),(10.073530110959743,76.33390367031097)
Code
arr=[ [10.075854059674523, 76.32832467556],
[10.079825860518895, 76.33338868618011],
[10.076234340596953, 76.33806645870209],
[10.07065684212598, 76.33806645870209],
[10.068924417668397, 76.33175790309906] ];
var sum=0;
for(var i=0,l=arr.length-1;i<l;i++){ sum+=(arr[i][0]*arr[i+1][1]-arr[i+1][0]*arr[i][1]); }
alert('The Area of Ploygon is:'+(sum/2));
It's quite complex and is not exactly math.
If you want to get real world result not some math theory you have to notice that earth is not sphere - look for WGS 84 in Google.
One of algorithms that can be implemented quite fast is Montecarlo:
Find the minimum bounding box of polygon (for small areas you can handle earth as flat surface)
Calculate area of MBB as for rectangle S = a*b
Get N random points inside the rectangle
Find M = points inside the polygon
Surface of your polygon is S*M/N
Increasing N gives you higher accuracy.
You should easy find algorithms for resolving each step (finding distance from one geo point to other geo point, checking if point x/y is inside of figure)
The polygon area code compares favorably with another math site where the problem is explained under 2-D polygons.
The problem is you have squared degrees.
Well, for small patches of land the Earth can be considered flat, and for converting squared degrees to hectares or acres or square meters you need to know how long a degree is.
At the Equator, a degree on Earth is 1/360th of the circumference of Earth which is 2*Pi*Rearth or ~40000km.
1 degree is approximately 1/360th of 40000 km = approximately 111 km per degree.
1km is 1000m. 1 km^2 = 10^6 m^2. But 1 hectrare = 10000 m^2, so 1km^2 is 100 hectares.
A squared degree will be approximately (111^2 km^2) (100 hectares/km^2) ~= 1232100 hectares
Ah, but I cheated, this only works near the Equator.
The Earth is a little bit fatter than 40000 km around, and also a degree of longitude becomes shorter as you get near the pole. Degrees of latitude N or S are always 1/360th of the way around the Earth from pole to pole, but degrees of longitude are widest at the equator and become narrower as cos(latitude).
Ideally you need a library to do the conversion for you.
It actually depends on where you are in the world and how precise you want to be. Bear in mind that land is neither flat nor necessarily aligned with the underlying sphereoid.
The company I work for sprays bracken from the air and produces maps of where the spraying occurred plotted on Ordnance survey maps accurate to a metre or two.
In the UK you may find these useful, they detail the complexity of these conversions which I'm not even going to try to summarise here.
http://www.ordnancesurvey.co.uk/business-and-government/help-and-support/navigation-technology/os-net/surveying.html
http://www.ordnancesurvey.co.uk/docs/support/guide-coordinate-systems-great-britain.pdf
It appears the Ordnance Survey don't have the old conversion paper that I learned from on their site but I found a copy here.
http://www.fgg.uni-lj.si/~/mkuhar/Zalozba/TM_projection.pdf

Categories