Find the nearest geo positions - google-maps

I am looking for a way to get the nearly geo positions from one geo position. I can calculate the difference from two position, but I need to find all geo positions from a point with a radius of 10-20 miles. I find a similaire on flickr:
http://m.flickr.com/#/nearby/
Anybody an idear how it works? They must convert a latitude and longitude to a unique value and must find all entries nearly this position or something else.
Thanks for help!

You might use Voronoi Diagrams, but probably pre-sorting your data by each coordinate (separately) and then finding an intersection of point sets which lay nearby for each of coordinates would solve your problem easier.
A point location data structure can be built on top of the Voronoi diagram in order to answer nearest neighbor queries, where one wants to find the object that is closest to a given query point. Nearest neighbor queries have numerous applications.

You can use a kd-Tree. Some time ago I tried this one and it worked quite well:
https://github.com/jmhodges/kdtree2

Use a (point-)quad tree, or k-d tree, or if the number of points is not high, you even could use a brute force search.
Do not use voronoi diagrams. They are one of the most complex algos to implement.

Related

Given a user's lat lng, how to find the nearest lat lng from a database of thousands of lat lng?

I have data of locations of thousands of sensors in MySQL. I want to identify the sensor closest to the user's location and show that specific sensor's data. All the location data is available as lat lng.
I understand that one approach can be to find displacements between the origin and all the sensors using Haversine formula and select the one with the shortest distance. The problem here is that there are tens of thousands of sensors.
Any suggestions/leads?
Spatial index allows efficient query of points within any specific distance. The problem of course is one might not know the search radius needed in specific case. Unfortunately, a large radius causes inefficient queries, and a small radius might result in no match at all.
A possible solution is to search with increasing radius, until the search returns some results, and then find the closest result among those.
This article describes this solution for BigQuery, would require some adaptation for MySQL script dialect:
https://mentin.medium.com/nearest-neighbor-using-bq-scripting-373241f5b2f5
Not the MySQL answer you are looking for but Postgresql's popular PostGIS extension has an inbuilt K Nearest Neighbor operator class). Also, see its documentation. It works great!
Also, I am aware of this Go library that allows you to do KNN in memory after building a Quadtree with your sensor locations.
For only thousands, a simple bounding box with two 2-column indexes may be fast enough.
For better speed, see SPATIAL indexing.
For details on those two solutions, plus two faster ones, see Find Nearest

Is there any MySQL function to directly get 5 closest coordinates to a given coordinate from database?

I am working with PHP and use MySQL for database. I need a way, to get 5 closest coordinates to a given coordinate from database, which is very fast and at least 80-90% accurate. I have researched a lot. I found havershine formula, spherical law of cosines, bounding square method to compare min and max latitude-longitude values with coordinate in database and other methods which use trigonometric math functions. But all these formulas take a long to return result in database with thousands of entries. Does MySQL provide any function to do it fast?
See this similar question on the GIS Stack site. The performance of your ultimate solution will depend on how many targets are in the reference table you are searching and if you can limit the distance you are interested in (such as closest 5 within 30 miles). I don't think you can reliably optimize the process; you need to calculate the distance for all coordinates in your reference table.

Indexing based on Peano-hilbert curve?

I have a x,y,z 3D points stored in MySQL,
I would like to ask the regions, slices or point neighbours.
Are there way to index the points using Peano-Hilbert curves to accelerate the queries?
Or are there more efficient way to store the 3D data in the MySQL?
thanks Arman.
I've personally never went this far, but I used a Z-curve to store 2D points. This worked quite well, and didn't feel the need to try to implement the hilbert curve for better results.
This should allow you to quickly filter out points that certainly are not close by. In an absolute worst case scenario you still need to scan more than 25% of your table to find points within an area.
The way to go about it is to split the x y z in binary and stitch them together into a single value using the curve. I wish I had a SQL script ready, but I just have one for the 2d z-curve which is a much much easier to do.
Edit:
Sorry you might already know all this already and really just looking for SQL samples, but I have some additions:
I'm not sure the 25% worst case scan is true as well for 3D planes. It might be higher, don't have the brainpower right now to tell you ;).
This type of Curve will help you find ranges of where you need to search. If you have 2 coordinates, you can convert these to the hilbert-curve number to find out which section of your table you need to look for items that do exactly match your query.
You might be able to extend this concept to find neighbours, but in order to use the curve you are still 'stuck' to look in ranges.
You can probably take the algorithm to create a geohash, and extend it to 3 coordinates. Basically, you define would have a world cube of possible 3d points, and then as you add more bits, you narrow down the cube. You then consistently define it so that the lower left hand corner has the smallest value, and you can perform range checks like:
XXXXa < the_hash < XXXXz

Get polygons close to a lat,long in MySQL

Does anyone know of a way to fetch all polygons in a MySQL db within a given distance from a point? The actual distance is not that important since it's calculated for each found polygon later, but it would be a huge optimization to just do that calculation for the polygons that are "close".
I've looked at the MBR and contains functions but the problem is that some of the polygons are not contained within a bounding box drawn around the point since they are very big, but some of their vertices are still close.
Any suggestions?
A slow version (without spatial indexes):
SELECT *
FROM mytable
WHERE MBRIntersects(mypolygon, LineString(Point(#X - #distance, #Y - #distance), Point(#X + #distance, #Y + #distance))
To make use of the spatial indexes, you need to denormalize your table so that each polygon vertex is stored in its own record.
Then create the SPATIAL INDEX on the field which contains the coordinates of the vertices and just issue this query:
SELECT DISTINCT polygon_id
FROM vertices
WHERE MBRContains(vertex, LineString(Point(#X - #distance, #Y - #distance), Point(#X + #distance, #Y + #distance))
The things will be much more easy if you store UTM coordinates in your database rather than latitude and longitude.
I don't think there's a single answer to this. It's generally a question of how to organize your data so that it makes use of the spacial locality inherent to your problem.
The first idea that pops into my head would be to use a grid, assign each point to a square, and check select the square the point is in, and those around it. If we're talking infinite grids, then use a hash-value of the square, this would give you more points than needed (where you have collisions), but will still reduce the amount by a bunch. Of course this isn't immediately applicable to polygons, it's just a brainstorm. A possible approach that might yield too many collisions would be to OR all hashed values together and select all entries where the hashes ANDed with that value is non-zero (not sure if this is possible in MySQL), you might want to use a large amount of bits though.
The problem with this approach is, assuming we're talking spherical coordinates (lat, long generally does) are the singularities, as the grid 'squares' grow narrower as you approach the poles. The easy approach to this is... don't put any points close to the poles... :)
Create a bounding box for all of the polygons and (optionally storing these results in the database will make this a lot faster for complex polygons). You can then compare the bounding box for each polygon with the one round the point at the desired size. Select all the polygons which have intersecting bounding boxes.

Calculate longitude/latitude

Given the following input:
known longitudes/latitudes of 1..n locations
known distance between locations 1..n and another location "m"
How can I calculate the longitude/latitude of the location "m"?
This sounds like a basic latitude-longitude triangulation question. The common approaches are outlined in a Yahoo! Answers topic here. There are likely libraries to do this in many languages. A google search for "latitude longitude triangulation" plus your language of choice will likely reveal some existing code to use. "Geocoding" is another common task rolled into similar libraries, so that may be another useful keyword.
Edit: As others have mentioned, "trilateration" seems to be the best term. However, depending on your data and requirements, there are simpler approximation solutions that may satisfy your requirements.
The Yahoo! Answers post is quoted below for convenience:
"For larger distances, spherical
geometry. For relatively small ones,
treat the earth as flat, and the
coordinates as xy coordinates. For the
distances to work with the degrees of
the coordinates, you will have to use
the cosine function to convert from
one to the other. (While degrees of
latitude are about 69 miles all over
the earth, degrees of longitude vary
from the same at the equator to 0 at
the poles.)
You have the center points of three
circles and the radius of those
circles. They are supposed to
intersect at one point, so you can
treat them in pairs to find the
intersection points of each and throw
out the ones that don't match
http://mathworld.wolfram.com/Circle-CircleIntersection.html."
(mike1942f)
Trilateration is what you want. This only requires 3 of your reference points, however the rest can be used to increase accuracy if you want to get really clever.
The trickiest part is working with long/lat as opposed to Cartesian coordinates, especially as the earth is not a perfect sphere.
This is a trilateration problem. In your case, you have multiple points of reference, so you can minimize the sum of squared-errors between the given distances and those corresponding to the optimal position of m.