I have created a PhoneGap app so it's database is using HTML Storage. I have a table of locations which include their lat and long. I then have the users current location and need to find the closest 3 locations.
How would I go about this mathematically? Will I need to convert the lat long values or can they be directly comparable?
In my opinion the easiest way to do that is convert the distance between the coordinates to kms and then loop through the coordinates you have and figure out which ones you want. It's simple math, you can read more about it here if you want.
getDistanceBetweenCoordinates:function(lat1,lng1,lat2,lng2){
var distance = (3958*3.1415926*Math.sqrt((lat2-lat1)*(lat2-lat1) + Math.cos(lat2/57.29578)*Math.cos(lat1/57.29578)*(lng2-lng1)*(lng2-lng1))/180);
//console.log("distance:" + distance);
return Number(distance);
}
Related
I explain my issue in below image (I'm sorry I speak English not well).
I'm using Google Maps Directions API to calculate directions between start point and destination and there is a place between them (you see in the map). How can I know that place is on route?
The only way I can think of (and I have used this method) is thus:
When you make a directions request, you receive a DirectionsResult object.
If you drill down into that result you can get latitudes and longitudes.
If you are using the JavaScript API, for example:
// Every step is about 22 LatLngs per mile; we'll try one LatLng per 3
// miles or so:
var specRoute = directionResult.routes[0].legs[0].steps[i];
for (var j = 0; j < specRoute.path.length; j = j + 171) {
var lattotal = latarr.push(specRoute.path[j].lat());
var lngtotal = lngarr.push(specRoute.path[j].lng());
}
In this example I am formatting arrays of lats and lngs to be compared to a lot of other lats and lngs in a php file elsewhere. It sounds like you only need to check one latlng so it should be simpler.
What I did thereafter (and what you could do) is to determine how close to the path your point is required to be, and write some logic to check. You could do that with straight latitude and longitude numbers, or convert to another distance measurement (miles, meters, etc).
There is a negative aspect in that you will have to deal with converging longitude lines the farther north you go (in the Northern hemisphere).
I used a regression fit workaround but there is probably a better way.
There may also be a better method for doing this, but this is the only way I could think of on past projects.
Suppose a service like Foursquare, I want to save the location of a check-in. Should I save this as latitude-longitude or the address/area name such as 123 Portmill St, NY 12345 or SoHo, NY.
In the first case, I can have users type an address and my service looks up and stores lat-long information. By doing this my service can search check-ins within a polygon-boundary.
While on the second case, I can store location as a bucket and avoid redundant information such as (lat,long) = (100000.1,100000.1), (100000.2,100000.2) which are very close together and can even be considered the same location.
I don't think I've completely understood the nuances of what you're trying to do, but computers usually work better with numbers like latitude and longitude rather than human-readable text information. For example, with the text address, how would you ensure consistency, e.g. dealing with extra spaces, ZIP+4 codes rather than just shorter zip codes etc etc.
I guess it's just my instinct that latitude and longitude might be better than text. Where I live in the UK, there are a lot of examples where towns and cities have two roads of the same name, so I do think that there are likely to be more pitfalls with storing text instead of latitude/longitude.
How about this. I'd store 3 columns in the database, namely (Latitude, Longitude, TextLocation), but it's the pair (Latitude, Longitude) that's regarded as the key of the table. The TextLocation is just the last known result from the reverse geocoder when the geocoder was asked for the text corresponding to the given (Latitude, Longitude).
When a new position arrives, (New_Latitude, New_Longitude), I'd search the database to find all closest rows in the database. To calculate distance of (New_Latitude, New_Longitude) to (Latitude, Longitude), I'd use the following code
float LatDiff = New_Latitude - Latitude;
float LongDiff = New_Longitude - Longitude;
float CosNewLat = Math.cos(New_Latitude);
float ConversionFac = 6371000 * Math.PI / 180; // 6371000 is earth radius in metres
float Dist_metres = ConversionFac * Math.sqrt(LatDiff*LatDiff + LongDiff*LongDiff*CosNewLat*CosNewLat);
Then for each of the closest points to (New_Latitude, New_Longitude), I'd update the TextLocation in the database using reverse geocoding. If the new position doesn't match the current reverse geocoding for any of the existing locations, I'd add it into the database.
Part of my thinking here is that even storing 3 columns which includes a column of text, the database is still going to be tiny compared to modern storage capacities.
I would like to query for all possible streetnames within a radius of 500 meters of a given point.
Multiple posts are reffering to the google store locator example using the Haversine formula or some version of it.
But I also came across some posts that have a much more simplified solution.
They just treat the points as x,y coordinates by adding to the lat and long variables as seen below.
I was wandering if this would be the fastest way to query mysql without getting really complicated and still get a good result. I don't have a lot of data yet, so I want to know if I am on the right track.
Are there any disadvantages or inaccuracy's by using this method?
What I don't get is how this can be a radius like range, it looks more like a one directional
query?
Distance = 0.1; // Range in degrees (0.1 degrees is close to 11km)
LatN = lat + Distance;
LatS = lat - Distance;
LonE = lon + Distance;
LonW = lon - Distance;
...Query DB with something like the following:
SELECT *
FROM table_name
WHERE
(store_lat BETWEEN LatN AND LatS) AND
(store_lon BETWEEN LonE AND LonW)
You might want to ask this question on the GIS site. I've used this answer myself for similar problems. I can see how your proposed solution might be faster, but note your four points are describing a square not a circle so it would not be considered a "radius".
You could use ElasticSearch for that, MySQL will be always slower than ES.
In my project I have to find [latitude, longitude] coordinate(s) from one point in distance of 500 meters (this could be any random coordinate or an array of coordinates around my point). How can I do this?
Note: I need this in order to find multiple paths between points different from shortest one which is returned us via Google Maps Directions Api..So using my method I will define the center of the road from A to B and then find some coordinates below and above that center position and use this as another waypoint to go from A to B - I guess this might help me to find multiple paths...
Any suggestions from GIS professionals?
EDIT: UTM conversion is the most preferable one for such calculations, and I've created UTM Java class if anyone needs..
If I understand your question right you have a known point in Lat/Long and you need calculate the Lat/Long of another point or points 500m away from your starting point.
If this is what you are doing, you have several options most of which involve specialist GIS APIs. However, I'm guesing you're a programmer/mathematician rather than a Geographer so, you may prefer to opt for using the Haversine formula. You can find a discussion on this topic here plus the formula.
One caveat is that the distamce you are working with (500m is quite small) and the Earth is far from being a perfect sphere or even a slightly flattened spheroid. It is locally "lumpy" and that can put your calculation out. If you need more accuracy you will have to account for these imperfections by using an appropriate local Datum (model of the Earth - there are many e.g. see EPSG list) and to do that you will probably need to start using the GIS libraries as the maths gets very detailed otherwise.
This is the code used by google map (SphericalUtil.java)
// from SphericalUtil.java
// compile 'com.google.maps.android:android-maps-utils:0.4.4'
public static LatLng computeOffset(LatLng from, double distance, double heading) {
distance /= 6371009.0D; //earth_radius = 6371009 # in meters
heading = Math.toRadians(heading);
double fromLat = Math.toRadians(from.latitude);
double fromLng = Math.toRadians(from.longitude);
double cosDistance = Math.cos(distance);
double sinDistance = Math.sin(distance);
double sinFromLat = Math.sin(fromLat);
double cosFromLat = Math.cos(fromLat);
double sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * Math.cos(heading);
double dLng = Math.atan2(sinDistance * cosFromLat * Math.sin(heading), cosDistance - sinFromLat * sinLat);
return new LatLng(Math.toDegrees(Math.asin(sinLat)), Math.toDegrees(fromLng + dLng));
}
to use it, you just have to enter the centerLatLng, the distance in meters, and the heading in degrees from centerLatLng.
you can change the formula to the language of your preference.
I have to calculate distances between map points as part of a project I am doing. The map points are provided in OSGB36 co-ordinates, e.g. 508800 / 181100 (being easting and northing). I have come across many functions to calculate the distance between 2 lat / longs and so would like to convert to these using VBA within an MS Access database.
Does anyone know how I can do this?
Thanks,
Steve
Rectilinear coordinates like this actually need nothing more than
http://en.wikipedia.org/wiki/Pythagorean_theorem
to calculate distances.
$d = sqrt(pow($e1-$e2,2)+pow($n1-$n2,2));
Where $d is the answer in meters. $e1,$n1 and $e2,$n2 are your easting/northings of the two points.