I have a database full of map Locations (Latitude, Longitude), is there a way I could do a SQL query to return me all points around a certain location?
Right now I basically grab everything in the database and loop through each one and check the distance using
Location.distanceBetween(startPoint.latitude, startPoint.longitude,endPoint.latitude,endPoint.longitude, results);
and keeping items that are within the set distance but there could be a lot of points to loop through.
So is there anyway to do this in an SQL statement?
You can use a WHERE clause expression to filter on angular distance r from an origin (x0, y0). Since SQLite doesn't have a square root function, you'll have to use the squared distance:
SELECT ... FROM ...
WHERE (Latitude-x0)*(Latitude-x0) + (Longitude-y0)*(Longitude-y0) < r*r;
The only place this won't work well is near the poles or the prime meridian. It's also a planar approximation to the sphere, so it will only work for values of r that are quite small. Finally, it scales latitude and longitude equally, so the selected region looks more and more elliptical the farther away the origin is from the equator.
You will have to convert linear distance (e.g., "within 30 meters") to latitude/longitude differences. This is a rather complex subject because the Earth is not a perfect sphere. However, for rough calculations you can use the approximation that 1 nautical mile = 1852 meters = 1 arc minute of longitude at the equator. Since lines of longitude get closer together as the latitude moves away from the equator, you will need to use some trig to figure out what value of r to use at a given latitude. For more info on this problem see this thread or this one, or search the web for "convert meters to latitude longitude".
I have a database full of map Locations (Latitude, Longitude), is there a way I could do a SQL query to return me all points around a certain location?
You can easily check a square region.
Using very simplified latitude / longitude coordinates say you're at [25.86, 57.03] and you wanted everything in the "neighborhood" (+/- .05) you can use a query like this:
SELECT * FROM Coords WHERE (latitude BETWEEN 25.81 AND 25.91) AND (longitude BETWEEN 56.98 AND 57.08);
You can also use the SQLite R*Tree extension.
An R-Tree is a special index that is designed for doing range queries. R-Trees are most commonly used in geospatial systems where each entry is a rectangle with minimum and maximum X and Y coordinates.
The source code to the SQLite R*Tree module is included as part of the SQLite3 amalgamation but is disabled by default. To enable the R*Tree module, simply compile with the SQLITE_ENABLE_RTREE C-preprocessor macro defined.
Related
I am facing a problem I don't how to do that. Suppose I have 20 users in the city so I want to find the nearest user to me with in a range of 5 kilometres. Actually, I am building an app using firebase where I can find the nearest blood donor. How can I find it? Need suggestion. if I add 5 kilometres to latitude and longitude from all side. Is it possible and Am I on the right track? if yes so how would I add 5 kilometres to latitude and longitude?
You can use the geodesy library to calculate distances between locations.
https://pub.dev/packages/geodesy
num distance = geodesy.distanceBetweenTwoGeoPoints(l1, l2);
Note -- since the earth's surface is not flat (although some still believe that) you cannot use simple euclidian geometry to calculate the distance.
I have an ever increasing list of places identified by lat/long stored in my database. Now at the UI front there is a screen with a place auto-complete textbox means if I type a location there a drop down will appear with places and when I select the place the camera will move there. Also it is required that I display locations nearby (locations as stored in my database). Now the question is how to do this? I can use
SphericalUtil.computeDistanceBetween()
But the problem is I can't fetch all lat/long from my database and calculate distance without hampering performance.
You would need to compute the distances in your database. There are two basic options:
Implement your own distance method in your database:
If your positions are close to each other and close to the test lat/lng you can use Pythagoras's theorem (a ver basic approach that will not be correct in all the cases)
To address all the possible cases you can implement yor own haversine formula (the haversine formula gives great-circle distances between two points on a sphere from their longitudes and latitudes and is used to compute distances in the SphericalUtil.computeDistanceBetween() method).
Use a GIS database. You can use SpatiaLite for Android and use the ST_Distance function to filter your positions:
SELECT *
FROM yourtable
WHERE ST_DISTANCE(Geometry, MakePoint(yourXcoordinate, yourYcoordinate)) < yourdistance
I have a SQLite database which stores latitude and longitude. I have to find if the users current location is between the Latitude and Longitude(Which is stored in Database) or not.
I been looking for a while to find a solution for this problem but couldn't get it. Most of them are related with the distance calculation.
How to find the current location(obtained in the app) is between the Latitude and Longitude(Which is stored in SQLite Database)?
I am not sure if you exactly want but what i think
what you have : two geographical point (two pair of attitude and longitude )
what you want : calculate the adjoining regions covered between the two geo points , and check if the user is within that are
for that what you can do is :
1 : suppose the two points are diameteric terminals of a circle and search if the user is within this circle , like this Image
this approach might make you search a little irrelavant region
2 : suppose the two point are two ends of a straight line , consider a distance , say 50 km , on both sides , and search the 100 km wide strip from point A to point B
like this Image
Assume you have two locations a and b and your current location c.
C
/ \
A---B
You can use the dotproduct to calculate if c is between a and b:
If the dotproduct of two vectors is >0, the degrees between these vectors is <90°.
Know you need two calculations like this:
if(Vector(AB) * Vector(AC) > 0 && Vector(BC) * Vector(BA) > 0)
// your location is between
You can also look here and here for more details.
I have a SQLite database in Android with a table that contains longitude, latitude and other columns.. now I want to get all records that have the distance smaller or equal to a given distance.
For example, I know my current coordinates(lat,long) and I want to get from my table all records that are at the maximum distance of 10km from me.
I found some links on stack but nothing too solid. Is there someone that knows an optimized solution for this problem?
I have thought that I could get all records that have latitude smaller than my lat + distance and greater than my lat - distance and longitude smaller than my long + distance and greater than long - distance. After this query I should check for some unwanted records since the query is not returning only the wanted records..
Is this a good idea?
You probably want to do this in two parts,
1) Run a query where you find all records that are within a certain value + or - of the current lat/lng of your location, the where clause might look like:
where (#latitude > (lat - .001) and #latitude > (lat - .001)) and
(#longitude> (lng- .001) and #longitude> (longitude- .001))
2) with the rough results from above, use the great circle/haversine method to determine what the actual distance between each location is (great circle/haversinse is already part of the android maps api).
Just for the record, it can be useful.
I don't know what you are trying to do, or if you have a backend or a server. But, if you DO have a server which stores these locations, you can (and should) use MongoDB to store it. It has a great support for geospatial information.
Here is an example of how you do what you want using MongoDB: http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-Querying
I have a data set of different locations, and want to show the nearest locations (within 5 km).
How can I determine the minimum/maximum of latitude and longitude?
f.e.: I need to fill my car up, and am looking for all gas stations in my neighborhood so I can go to the nearest. How do I do this on an Android phone?
I'd like to avoid iterating through all of the locations as well, because I've got about 2500 locations and rising. Any suggestions on that?
Thank you guys in advance for the advice on this!
Update:
Thank you for the feedback you guys gave me, I solved my issue by iterating through all locations on the server and using the Google Distance Matrix API to calculate the distances: http://code.google.com/intl/nl/apis/maps/documentation/distancematrix/
Simplifying, latitude is the angle over/under the equator, longitude is angle right/left of greenwich meridian.
So to calculate (on average) how much for example 1º latitude is, you convert it to radians (multiply by PI/180), and then multiply by Earth's mean radius (6,371.0 km).
For your question, the process is the inverse one: take 5 km and convert it to degrees:
Divide it by Earth's radius
Multiply by 180/PI
This way you will get delta degrees, that is, how much degrees are 5 kms (on average, if you want exactitude, you will need the exact Earth radius differentials over those 5 kms) with which you can build a circle around the given location (just like a compass would).
All the calcuations give and methods are approximations but well within tolerances for what you require.
The earth circumference is approx 40076000 metres.
the distance traveled per degree of latitude is allways the same and is simply a proportion of the earth circ.
the distance travel per degree in longitude however changes depending upon your latitude ( this rings on the glode get smaller nearer the poles ).
so for a given distance m, the corresponing Latitude and Longitude values are
earthcirc = 40076000;
// at Lat and Lon for distance m (in meters)
LatDelta = (m * 360) / earthcirc;
LonDelta = (m * 360) / abs(eathcirc*cos(lat));
This gives you your square lat long deltas for a simple search of your data. but on fingin a candidate your should then do a full distance calc as the corner of the square is quite a bit more than 5 KM away.
distance between 2 lat/longs
distLat = (lat1-lat2) * earthcirc) / 360;
distLong = (long1-long2) * earthcirc * cos((lat1+lat2)/2) / 360;
dist = sqrt( sqr(distLat) + sqr(distLong) );
I know most compilers/languages use radians for cos/sin functions but its easire to explain in degrees.
as for searching your data the simplest way is to order in be either lat or long then you can do a binary search to find the possible location to check instead of a full scan. There are better ways to order the data ( quad trees ) but for 2500 ish entries i wouldnt bother
There are two issues here, 1) how to calculate the distance between two pairs of lat/lon and 2) how to find the point with shortest distance to a given point.
There are formulas on the net, some more accurate than others, for example http://www.movable-type.co.uk/scripts/latlong.html
This is a (geo) spatial indexing problem (http://en.wikipedia.org/wiki/Spatial_index#Spatial_Index ). You can use for example a quad tree with lat/lng as X/Y (I assume your points are not too close to the polars, which complicate things but still doable). The quad tree let you find in Log(N) time the neighborhood of your car without having to iterate over all points.
Not exact code but hopefully it will help.