Distance Between Two GEO Locations [duplicate] - javascript

This question already has answers here:
How to find distance from the latitude and longitude of two locations?
(12 answers)
Closed 8 years ago.
I have two GEO locations. How can I calculate the distance between them?

If you use the Google Maps API v3 you can calculate the distance as follows:
Include the Google Maps JavaScript file with the geometry library:
http://maps.google.com/maps/api/js?sensor=true&libraries=geometry
The distance can be measured now by using the computeDistanceBetween() method:
var from = new google.maps.LatLng(49.004, 8.456);
var to = new google.maps.LatLng(49.321, 8.789);
var dist = google.maps.geometry.spherical.computeDistanceBetween(from, to);

This page has JavaScript code for computing the distance of two geographical locations, if that is what you're after.

GPS coordinates are geographical coordinates on the WGS84 spheroid. Under this model, Vincenty's formulae gives results of sub-millimeter accuracy. For most applications, that's either overkill or actually deceptive, as the earth's surface is not modelled by WGS84 to that scale.
You can compare the accurracy of various methods of distance computation on this page (broken link; check the source code instead). As you can see, the spherical and the differential approximations (the latter uses the Pythagorean theorem with the correct local metric) are inaccurate for a lot of cases.
Of the remaining methods, the first one uses the spheroid's mean radius to convert from geographical to geocentrical latitude, whereas the second one uses the cosine rule to get more accurate results in case of 'small' distances (where the definition of 'small' mainly depends on the difference in latitude).
A seperate script containing only these two methods can be found here, which provides a function called distance() and expecting four arguments: the two latitudes, the difference in longitude (all in radians) and a boolean flag indicating whether the distance is 'small'.

It depends on what level of accuracy you want.
You could work it out by basic triangle trigonomoetry - ie work out the difference between their longitude, that's one side; then the diff between their latitude, that's the second. Now you can calculate the third side (ie the actual distance between the two) easily enough with basic junior school maths.
However, that method ignores the curvature of the earth's surface, so if you need to take that into account, you'll need to start getting a bit more clever. But you won't need to worry about that unless the distances are quite large or you need an very high degree of accuracy. For most purposes the basic trig method is fine.
The other point, of course is that these methods give you a straight-line measurement. This may be what you want, but you may also want to know the distance to travel - ie on the road. This is completely different, as you'd need to have an accurate map of all the relevant roads. If this is what you need, it might be easier to delegate to Google's maps service (or one of several other similar alternatives).

Related

Polyline simplification

I am trying to understand this code.
What I understand is that the code tries to refine the geometry based on a tolerance. Basically it checks if the distance between two points is less than the tolerance or not, and retains/removes the points accordingly.
I have a query though. Points are in lat-long format. The code simply calculates a square of the Euclidean distance(simple square formula we all know). Isn't this a wrong approach as lat-long based distance is different from Euclidean distance?
Second, what is the unit of tolerance? In this test, the tolerance value of 5 is used. How does this value fit in here?
What I understand is that code tries to refine the geometry based on tolerance. Basically it checks if distance between two points is less than tolerance or not, and retains/removes the points accrdingly.
Yes, that's a first step, in the second step it tries to find consecutive lines that are (basically) in line and merges them.
I have a query though. Points are in lat-long format. Code simply calculates square of the Euclidean distance(simple square formula we all know). Isn't this a wrong approach as lat-long based distance are different from Euclidean distance?
(c) 2017, Vladimir Agafonkin
Simplify.js, a high-performance JS polyline simplification library
The code doesn't claim to be suitable for for lat-lng coordinates. Although they look like 2d-coordinates, they represent points in a 3d space; I don't see that the code was made for that.
On the other hand, it shouldn't be too complicated to rewrite it to 3d-space. And all you'd have to do then is to convert your lat-lng points into 3d-coordiantes
Second, what is the unit of tolerance? In test, tolerance value of 5 is used. How does this value fit in here?
pixels, miles, doesn't matter. The same unit as the points that you pass.

Leaflet get sub-polyline with specific start and end point

I want to get a "sub-Polyline" of a given polyline that is determined by a certain start and end point (in meters).
For example I have a polyline that is 500 meters (build using 30 coordinates (not seperated in same spaces)) and I want to color the line between meter 200 and 300 in a different color. Is it possible using Leaflet functions?
Take a look at the LineStringSelect plugin here: https://github.com/w8r/L.Control.LineStringSelect
With the demo (click in 2 different locations on the polyline):
https://w8r.github.io/L.Control.LineStringSelect
So basically you are asking "If I have a polyline and a distance value, what is the point along the polyline with the desired length-distance to the line's starting point"?
This algorithm has been covered a multitude of times, e.g.:
http://www.postgis.org/docs/ST_Line_Interpolate_Point.html, http://www.postgis.org/docs/ST_Line_Substring.html
http://turfjs.org/docs/#along
https://github.com/IvanSanchez/Leaflet.Polyline.SnakeAnim
The algorithm is always the same: divide the polyline/linestring into segments, measure length of each segment, locate the point, apply direct interpolation in the segment that the point is in.
Keep in mind that geometry in a 2D cartesian plane is different than geometry in the surface of a geoid, particularly when it comes to measuring distances. Do a bit of research on GeographicLib and its methods for manipulating geodesic lines.
To your question «Is it possible using Leaflet functions?», the answer is «no, Leaflet does not implement this algorithm». The easiest way for you should be to read the source code of the mentioned Leaflet plugins in the answers, or use the along() method from the Turf library.

How to draw a rectangular area on a large google map and query database to find locations/points that exist inside the rectangle?

I've got an application where I would like to present the end user with a google map and allow them to select an area of the map with a simple rectangular drawing tool and then have all of the locations stored in the client's database that fall in that rectangular selection area show up as points on the map...
I have a simple understanding of google maps and can get google maps to plot all the locations on the database w/o a problem... my problem comes in allowing the end user to draw the rectangle. Not sure how to implement this.
Can someone explain or link me to an example of how it's done?
Looks like this question was asked (and answered) a few months before Google posted about the new drawing tools in v3 API ...
I have to say that using the API's drawing tools gives a better user experience than #rcravens solution. Here's a very specific implementation that lets you "select" an area on the map by drawing a rectangle or polygon, and then checking to see if a marker is inside the shape: http://jsfiddle.net/JsAJA/306/.
Interesting question. I love the google maps api. Here is a jsFiddle with your solution:
http://jsfiddle.net/JsAJA/2/
You will have to query your database for points between the minimum/maximum lat and lngs. Hope this helps.
Bob
P.S. Note that this breaks the natural user experience of google maps. The map is no longer dragged when you mouse down. It needs a better user experience.
You might be interested in learning about Csquares, which encodes lat,lon into a text string which can be inserted into an indexed column.
I have ported the public domain Csquare encoding logic to Java and Javascript.
Let me know if you want it.
http://www.cmar.csiro.au/csquares/csq-faq.htm#10
EXCERPT
What is c-squares, and what purpose does it serve?
C-squares stands for "Concise Spatial Query and Representation System" and is a method of indexing the geographic location of objects or observational data on the surface of the earth, in a simple alphanumeric format suitable for subsequent querying by any text-based system or search engine.
. . .
In addition, c-squares can be defined at a flexible range of scales, from 10 x 10 degrees (approx. 1000 km) through 5 x 5 degrees (500 km), 1 x 1 degrees (100 km), 0.5 x 0.5 degrees (50 km), 0.1 x 0.1 degrees (10 km) and so on, as fine as the user requires.
Who can benefit from using c-squares?
Anyone interested in the storage, exchange, and retrieval of data or information with a geographic component, who does not wish to go to the level of sophistication of a fully fledged geographic information system (GIS) merely to be able to search their data holdings by geographic location...
Why not simply store, and quote, latitude and longitude values with a particular data item?
Individual values of latitude and longitude can be, and in most cases would continue to be, stored with particular data items (georeferenced objects). C-squares provides an additional level of functionality over and above these "native" values, in several respects:
(i) the system reduces latitude and longitude (2 dimensional variable) to a single dimensional variable, for easy indexing and subsequent searching
(ii) the system reduces redundancy for multi-point data which occur within a single square (a single code indicating "data present" replaces multiple individual values, for metadata-level information)...

Google maps - Near positions

On my website members are tagging photo position on Google maps API. Longitude and latitude are saved in database (SQL).
Does anyone know how to find tagged photos that are in radius 100km of tagged photo?
Let say that latitude and longitude are 46.03765154061627 | 14.5404052734375. Is there any kind of math formula that would check 100km radius position or any other way?
Thank you!
You could calculate the great-circle distance between two points. Luckily this is relatively easy with the haversine formula, assuming a spherical representation of the earth. You may want to read further and check out the JavaScript implementation at Calculate distance, bearing and more between Latitude/Longitude points by Chris Veness.
If you will only have a handful of photos, you can simply calculate the great-circle distance from the user submitted point to each photo point. Then simply sort the result list by the distance, and filter only the photos with a distance below the 100km threshold.
However, if you will be having many photos, you should probably consider filtering these from the database. You could use a database with geo-spatial indexing capabilities. For example MySQL, PostgreSQL and SQL Server 2008 all have geo-spatial features (either natively or via extensions), which include spatial indexing and implementations of the haversine formula.
Google Maps API includes methods for handling Latitude and Longitude coordinates. If you're dealing with a small number of coordinates it would be easy to use its GLatLng class and call the distanceFrom method.
You can also use the GLatLngBounds, which is designed to see if certain coordinates are within a defined rectangular boundary.
to define a circle of 100km radius may be a bit complex (great circle calculation, distance between two points, etc.) ... it's easier to define a "square shape" of 100km (or 200km) length with your point (M) in the middle:
without being too scientific, asuming
the earth is a sphere (I know it isn't, but ...)
the circumference at aequator is ca. 40.000km - so a 100km portion (of longitude) is aequivalent to 0,9 angle degrees
neglecting the fact that for latitude this is varying the closer you come to the poles
rounding the 0.9 to 1 degree
we can say that you want to search for pictures in an area where its picture coords (P) meet the criteria
lon(M)-1 <= lon(P) <= lon(M)+1
lat(M)-1 <= lat(P) <= lat(M)+1
(all in degrees). I would think that - for a WEB service - this is accurate enough and very easy to implement.

map geo coordinates (lat, lng) to map (x, y)

I have the geo-coordinates (latidute & longitude) of some cities and would like to get the x,y coordinates so can plot them into a map.
The map is a standart one, just like http://www.wordtravels.com/images/map/Spain/Fuerteventura_map.jpg for example.
I tried several formular I found, but none seems to really work :(. Simple javascript code or ruby would be best :)
There are many ways to approach this problem with varying degrees of precision. However, they all boil down to performing a projection that corresponds with that of your map.
If you know that your map is of the Mercator projection variety, then the lat/long coordinates can simply be treated as X/Y, scaled and translated appropriately. That is, you would find a simple ax+b and cy+d that do the job.
If your map is not Mercator-projection (as it probably isn't if it tries to get the scale consistent, as this one appears to do) then your best bet is to assume it's an "earth-tangent" projection. (This works out OK for small landmasses.) In that case, you need to first project the Lat/Long into a three-dimensional coordinate system.
z=sin(lat)
x=cos(lat)*sin(long)
y=cos(lat)*cos(long)
Positive z points to the north pole. Positive y points to 0, 0, and positive x points to lat 0 long 90 (east) and positive lat/long are north and east. Of course you must convert to radians first.
All of this assumes a spherical Earth, which isn't exactly true but it's close enough unless you're firing long-range mortar rounds.
Anyway, once you have your XYZ, then you'll need to rotate and scale for the map. To rotate around the Z axis, just subtract the base longitude before you project into three dimensions. Do this to center your map on zero-longitude for easiest math.
Once you've done this, you'll only need to rotate the globe forward until your original map is face-front. Do this with a 2-d rotation in the y-z axis. Use http://en.wikipedia.org/wiki/Coordinate_rotations_and_reflections to figure that part out.
Finally, your x,z coordinates are going to line up pretty well with your map's x,y coordinates, for an appropriate scale/translate as described earlier.
in addition to the above answers, there is the open source proj4js library which performs transforms between various map projections. it is used internally by OpenLayers for this kind of thing, and supports a number of popular projections and coordinate systems.
perhaps this will help, i've done a implementation for the US using just javascript.
demo/code: http://the55.net/_11/sketch/us_map
Use the Google Maps API, you can overlay your jpg on the map and position it correctly.
Here is an example
http://code.google.com/apis/maps/documentation/javascript/examples/overlay-hideshow.html
and here is the api page about overlays
http://code.google.com/apis/maps/documentation/javascript/overlays.html
You won't find it easy unless you're working on a very small scale (and close to the Equator). Wikipedia's Geographic coordinate system is a good start...
The easier path could be to make use of something like web mapping and stick with your latitudes and longitudes.

Categories