How to divide a map into circles of a given radius? - google-maps

Folks,
How can I take a state and divide it into areas that are 50 miles in radius?
Perhaps there's a better way to solve my problem: I have a list of 700 locations with unique city names. Some cities are less than 50 miles apart. I need to reduce that list to the minimal number of locations that are no more than 50 miles away and that basically cover the nearby cities in the list. This way I can find the center radius ZIP code of each of the location on the reduced list and then search for "stores within 50 miles", which should return all 700 locations.
Update: I have 5000 products and 700 stores in different cities. I need to check inventory for ALL products. The site where I check it only shows inventory in stores that are within 50 miles of a given city. That mean that I need to make 3,500,000 requests. Hence, I am looking for a way to reduce 700 stores to a smaller number.

A simple algorithm which would work but is far from optimal. This starts with a list of candidate towns
Pick a town at random, draw a circle around that point
Remove all towns inside the circle
Repeat until there are no towns left
You could run it a few times to see if some runs produce significantly fewer resulting circles.

You can concatenate the binary value from the x- and y co-oordinates. Instead of a straight line it orders the points along a z-curve. Then you can compute the upper bounds with the mostsignificant bits. The z-curve is often use in mapping applications:http://msdn.microsoft.com/en-us/library/bb259689.aspx.

Related

Finding intersecting areas in MySQL spatial db

In a MySQL database, how do I find circular areas that fall entirely or partially within a certain distance from another point? There are plenty of examples to find points within a certain radius, but not circular areas that intersect that certain radius.
I have a list of contractors that service certain areas (point and radius). Customers need to be able to find these contractors based on a distance from them.
I think you are looking for ST_Buffer, which will buffer a geometry by a certain distance. In your case this will turn your point into a circle, and you can then use ST_Intersects to find intersecting circles representing contractor areas.
Something like:
Select id from contractor c where intersects(c.geom, st_buffer(point, radius));
where obviously you need to provide values for point and a radius.

Dealing with clusters when searching for points on map using mysql

I've found various questions with solutions similar to this problem but nothing quite on the money so far. Very grateful for any help.
I have a mysql (v.5.6.10) database with a single table called POSTS that stores millions upon millions of rows of lat/long points of interest on a map. Each point is classified as one of several different types. Each row is structured as id, type, coords:
id an unsigned bigint + primary key. This is auto incremented for each new row that is inserted.
type an unsigned tinyint used to encode the type of the point of interest.
coords a mysql geospatial POINT datatype representing the lat/long of the point of interest.
There is a SPATIAL index on 'coords'.
I need to find an efficient way to query the table and return up to X of the most recently-inserted points within a radius ("R") of a specific lat/long position ("Position"). The database is very dynamic so please assume that the data is radically different each time the table is queried.
If X is infinite, the problem is trivial. I just need to execute a query something like:
SELECT id, type, AsText(coords) FROM POSTS WHERE MBRContains(GeomFromText(BoundingBox, Position))
Where 'BoundingBox' is a mysql POLYGON datatype that perfectly encloses a circle of radius R from Position. Using a bounding box is, of course, not a perfect solution but this is not important for the particular problem that I'm trying to solve. I can order the results using "ORDER BY ID DESC" to retrieve and process the most-recently-inserted points first.
If X is less than infinite then I just need to modify the above to:
SELECT id, type, AsText(coords) FROM POSTS WHERE MBRContains(GeomFromText(BoundingBox, Position)) ORDER BY id DESC LIMIT X
The problem that I am trying to solve is how do I obtain a good representative set of results from a given region on the map when the points in that region are heavily clustered (for example, within cities on the map search region). For example:
In the example above, I am standing at X and searching for the 5 most-recently-inserted points of type black within the black-framed bounding box. If these points were all inserted in the cluster in the bottom right hand corner (let's assume that cluster is London) then my set of results will not include the black point that is near the top right of the search region. This is a problem for my application as I do not want users to be given the impression that there are no points of interest outside any areas where points are clustered.
I have considered a few potential solutions but I can't find one that works efficiently when the number of rows is huge (10s of millions). Approaches that I have tried so far include:
Dividing the search region into S number of squares (i.e., turning it into a grid) and searching for up to x/S points within each square - i.e., executing a separate mysql query for each square in the grid. This works OK for a small number of rows but becomes inefficient when the number of rows is massive as you need to divide the region into a large number of squares for the approach to work effectively. With only a small number of squares, you cannot guarantee that each square won't contain a densely populated cluster. A large number of squares means a large number of mysql searches which causes things to chug.
Adding a column to each row in the table that stores the distance to the nearest neighbour for each point. The nearest neighbour distance for a given point is calculated when the point is inserted into the table. With this structure, I can then order the search results by the nearest neighbour distance column so that any points that are in clusters are returned last. This solution only works when I'm searching for ALL points within the search region. For example, consider the situation in the diagram shown above. If I want to find the 5 most-recently-inserted points of type green, the nearest neighbour distance that is recorded for each point will not be correct. Recalculating these distances for each and every query is going to be far too expensive, even using efficient algorithms like KD trees.
In fact, I can't see any approach that requires pre-processing of data in table rows (or, put another way, 'touching' every point in the relevant search region dataset) to be viable when the number of rows gets large. I have considered algorithms like k-means / DBSCAN, etc. and I can't find anything that will work with sufficient efficiency given the use case explained above.
Any pearls? My intuition tells me this CAN be solved but I'm stumped so far.
Post-processing in that case seems more effective. Fetch last X points of a given type. Find if there is some clustering, for example: too many points too close together, relative to the distance of your point of view. Drop oldest of them (or these which are very close - may be your data is referencing a same POI). How much - up to you. Fetch next X points and see if there are some of them which are not in the cluster, or you can calculate a value for each of them based on remoteness and recentness and discard points according to that value.

Find all points reachable in given time by car

I have a list of about 3000 points (lon,lat) and I need to create an application to find for any given position on map (lon, lat) all points from this list, which are reachable in 10 minutes by car.
I can easily calculate this task for distance in metres, eg. all points inside a circle, but I need to do it using duration in minutes, not distance in metres.
Which part of Google Maps API should I use?
It looks like you'll need to use the Google Distance Matrix. However, because of the limits, you'll probably need to get crafty with filtering the list of possible locations before sending the request.
100 elements per query.
100 elements per 10 seconds.
2,500 elements per 24 hour period.
You are trying to create a isochrone map
I would suggest something like this (a v2 example by Marcelo). The original is gone, here is a copy, and a version ported to the v3 API.
Start by drawing a circle (or not, but conceptually) with a radius that is greater that 10 minutes driving time (10 miles should work). Find all the points in your database in that circle (that are less than the radius/10 miles from the center point).
This should narrow down your points to a manageable number. Use the DistanceMatrix to further refine the number, eliminating those that are within the circle but greater than 10 minutes away.
proof of concept
uses the places search for locations, pares down the results to those in a 10 mile radius, then sends those results to the DirectionsMatrix, discarding any results with a duration of greater than 10 minutes.

Unsure of what to do with multiple latitudes

I'm creating a webapp where I want to do a search by radius based on latitude and longitude. However, if a user enters just they're city and state, a lot of cities will match multiple zipcodes, which in turn will match multiple latitude and longitude points. My question is, what is the recommended way to deal with multiple latitudes? Is taking the average an option? I assumed that would violate principles of distance calculation..
Typically a radius based search is done when you only have one latitude /longitude point. Otherwise, if you have multiple points then they are bound to form a polygon. You can then do bounds calculations to determine if a given point is within the boundaries of the polygon. You could also set a threshold distance outside of the polygon.

Which of these would be safer/better to run?

I have 451 cities with coordinates. Now I want to calculate the distance between each city and then order some results by that distance. Now I have 2 options:
I can run a loop that would calculate distance for every possible combination of cities and storing them into a table, which would result in roughly 200k rows.
Or, I can leave the cities without pre-calculating and then, when results are displayed (about 30 per page), and calculate the distance for each city separately.
I don't know which would be better for performance, but I would prefer going for option one, in which case I have another concern: Is there a way I could get out as little rows as possible? Currently, I would count the possibilities as 451^2, but I think I could divide that by 2, since the distance in case of City1-City2 is the same as City2-City1.
Thanks
If your table of cities is more or less static, then you should definitely per-calculate all distances and store them in a separate table. In this case you will have (451^2/2) rows (just make sure thet id of City1 is always lower then id of City2 (or another way round, doesn't really matter)).
Normally the cost of a single MySQL query is quite high and the cost of mathematical operations really low. Especially if the scale of your map is small and the required precision is low, so you can calculate with a fixed distance between degrees, you will be faster with calculating.
Furthermore you would have a problem if the number of cities rises because of a change in your project and therefore the number of combinations you'd have to store in the DB exceeds the limits.
So you'd probably better off without pre-calculating.