I'm making an API for an iPhone app. Put simply, I have locations stored in a database (Lat/long). When a user send a request for points within, let's say, a five (5) mile radius, I'll need to make use of an algorithm to only give me those points from a MySQL database.
How can I convert miles to minutes in a coordinate? IE, with the tapering nature of longitude in mind, how much do I add to coordinates I'm searching through to compare to the users location?
2 What's a good formula to take into account the way longitude/latitude changes as you go to different points of Earth?
Thanks :)
You never mentioned how you stored the data, so I can't give you the actual code. Here's just something I came up with:
Import all the data into some efficient database. Optimize it to be efficient at pulling up coordinates within a certain X/Y range
Select all the coordinates within a 10x10 mile square. Import them into an array
Use a foreach to go through that array and use the distance formula (distance=sqrt((x-x)^2+(y-y)^2)). If within 5 miles, add it to another array. If not, ignore it.
I don't know how efficient this would be with thousands of coordinates in a small location; you might have to fine tune it (for example, try a smaller box first if you're finding the closest location).
I do have to agree with Darren that Google Maps API might be better suited, although I haven't used it before.
Related
The Problem
I have lists of GPS coordinates, these coordinates correspond to houses in the same area of a town/city. Each list of coordinates will have a team assigned to it. I would like the team to visit every house in the list, so I would like each team member to visit the roughly the same amount of houses
So I would like to assign an equal sized subset of this list to each team member. So the clusters obviously need to group coordinates close together. I know because I need equal sized clusters that they won't be perfect, but it is more important to me that they are of the same size.
The Setup
I think in Python I could use k-means-constrained, so that I can declare a min & max size of my clusters, but I cannot find anything similar in PHP. I also cannot wrap my head around adapting standard k-means to do what I want.
I know I will not get perfect clusters, but it is more important to me that they are all of roughly equal size, than how good the clusters are.
Question
If someone has implemented something to do what I want could you please link me, as I haven't found anything similar in PHP. Or maybe I am looking at the problem in the wrong way, so if anyone has any suggestions they would be very welcome.
Thanks.
I am using Google Maps to display locations stored in a MySQL database containing name, latitude and longitude information. An AJAX request is sent and the map is updated with all the locations. So far, so good.
Users have the ability to filter the locations by drawing polylines on the map to create a bounding box. The idea is that only locations within this bounding box are returned and they can draw whatever shape they want.
All the points used to draw the shape are returned a list of coordinates. Where I am struggling is taking the list of coordinates and finding everything within them. Can I achieve this with an SQL query? Is it even possible?
I have seen examples of returning locations within x radius from one set of coordinates and also a square box, but I have no idea how to take that further and get everything within a potentially infinite set of coordinates.
You should transform the shape the user enters into a polygon. Then you transform all locations within a square around this polygon into the same coordinate system.
Using a solution describe in the wikipedia page for point-in-polygon problems you will be able to find all locations within this shape and remap them to coordinates in your sql database and then into locations.
There are however similar question which might help you find a proper solution to your problem. See:
How can I determine whether a 2D Point is within a Polygon?
Point in Polygon Algorithm
I am looking for a method, preferably in PHP, to analyze a group of polygons to detect the outer boundaries of the group.
Specifically, this is for a Google Maps v3 application that renders territories. Each polygon in the territory is a ZIP Code. I'm trying to detect and draw only the territory boundary. Here's a mock-up of what I'm trying to accomplish:
The challenges I face in solving this problem:
ZIP Codes within each territory can be (and often are) non-contiguous (see the red and green territories in the example above).
ZIP Codes are not necessarily convex, so a convex hull technique wouldn't work (maybe I'm wrong?)
Although it looks like it in the image above, vertices are rarely truly redundant from one ZIP to another. Each lat/lon coordinate (i.e. each vertex of the polygon) has 10 decimal points of precision. I have already tried and rejected a rounding technique as it never produced a clean data set that still resembled the original shape.
On the positive side, these territories never change once they're established. Therefore, this process can be run offline to calculate and store the resulting territory polysets.
Clarification:
My data is stored at the ZIP Code level. Each ZIP Code is defined by one or more large sets of lat/lon coordinates. Each lat/lon coordinate defines a single vertex in the Google Maps polygon. As with the bigger territories, each ZIP Code may or may not be convex, and it may or may not be a single contiguous polygon. The larger territory is simply stored as a list of ZIP Codes; no polygonal data is stored for territories--which is the problem I'm trying to solve here.
Many thanks in advance for any pointers in the right direction.
It sounds like you have a list of which zip codes relate to which territories. You also have a polygon for each zip code.
If this is the case, then the solution is fairly straightforward. The key observation/assumption is that bordering zip codes should share edges, which need to be removed. If this isn't the case, then the following is a moot point.
For each territory:
Create a dictionary that is keyed to the sorted edge, and which it's item is a list of polygons with that edge. Then go through the polygons in the territory and fill out the dictionary. This may be tricky as you need to ensure that Edge(A,B) is the same as Edge(B,A), which could be done by sorting the points in the edge.
Once you've gone through all of the polygons, you'll end up with essentially a table of edges and which polygon they are associated with. Convert this table into a graph, ignoring all edges that are in two or more polygons, although the "or more" is probably not possible. The result should be an undirected cyclic graph, that you should be able to extract the territory polygon from the graph using an algorithm similar to depth-first search.
The performance should be O(N), where N is the total number of edges/vertices.
I'm trying to figure out how to build a statistical map for my web app. Here's what I've got:
I have a MySQL database of zip codes, and each zip code has latitude & longitude.
I have users who have declared what zip code they live in.
I even have a haversine query which will show how many users exist within, for example, 25 miles of a given latitude/longitude, based on their zip code.
My question is this: Using this information, how could I approach building a statistical map for a web application using PHP?
I would be fine with using just a US map or even a North American map for now, but I'm just not sure how to build that map. Some options I've considered:
Show a colored dot on the map, larger or smaller depending on the number of users near that location. I'm not sure how to do this, though, especially if those dots were to overlap!
Show individual "pushpins" where the users are. Seems like this could get out of hand if my user base grows significantly
So back to my question. If I had 300 users in Dallas, 4,000 in NYC, 45 users in Detroit, 403 in Chicago... how would I be able to represent that on a map -- and also how would I draw that map in a web application built on PHP?
You are trying to build a three-dimensional (probably even more dimensions) data display.
Your dimensions are:
X-Location
Y-Location
The value at every location
This really does not define anything about the visual appearance, though.
A simple approach might be to calculate the absolute number of users per state and then color the state on the map according to some scale. You also might calculate the percentage of users living in a state compared to the absolute number and color that instead.
A different approach would be to put a dot for every user on the map, and if this dot was printed before, to change it's color instead, e.g. make it brighter.
In the end, it really depends on what your actual data is and if your approach on visualizing it displays some significant information - but this can only be confirmend after you see it.
As you are looking for a web application have you considered Google Maps. Factor 1. can be implemented using the MarkerClusterer library. A DEMO showing this. The data from your database can be loaded using AJAX.
I'm trying to find something, preferably F/OSS, that can generate a Google Maps overlay from KML and/or KMZ data.
We've got an event site we're working on that needed to accommodate ~16,000 place markers last year and will likely have at least that many again this year. Last year, the company that had done the site just fed the KML data directly to the gMaps API and let it place all of the markers client side. Obviously, that became a performance nightmare and tended to make older browsers "freeze" (or at least appear frozen for several minutes at a time).
Ideally this server side script would take the KML, the map's lat/lon center, and the map zoom level and appropriately merge all of the visible place markers into a single GIF or PNG overlay.
Any guidance or recommendations on this would be greatly appreciated.
UPDATE 10/8/2008 - Most of the information I've come across here and other places would seem to indicate that lessening the number of points on the map is the way to go (i.e. using one marker to represent several when viewing from a higher altitude/zoom level). While that's probably a good approach in some cases, it won't work here. We're looking for the visual impact of a US map with many thousand markers on it. One option I've explored is a service called PushPin, which when fed (presumably) KML will create, server side, an overlay that has all of the visible points (based on center lat/lon and zoom level) rendered onto a single image, so instead of performing several thousand DOM manipulations client side, we merge all of those markers into a single image server side and do a single DOM manipulation on the client end. The PushPin service is really slick and would definitely work if not for the associated costs. We're really looking for something F/OSS that we could run server side to generate that overlay ourselves.
You may want to look into something like Geoserver or Mapserver. They are Google map clones, and a lot more.
You could generate an overlay that you like, and Geoserver(I think mapserver does as well) can give you KML, PDF, png, and other output to mix your maps, or you could generate the whole map by yourself, but that takes time.
Not sure why you want to go to a GIF/PNG overlay, you can do this directly in KML. I'm assuming that most of your performance problem was being caused by points outside the user's current view, i.e. the user is looking at New York but you have points in Los Angeles that are wasting memory because they aren't visible. If you really have 16,000 points that are all visible at once for a typical then yes you'll need to pursue a different strategy.
If the above applies, the procedure would be as follows:
Determine the center & extent of the map
Given that you should be able to calculate the lat/long of the upper left and lower right corners of the map.
Iterate through your database of points and check each location against the two corners. Longitude needs to be greater (signed!) than the upper left longitude and less than the lower right longitude. Latitude needs to be less than the upper left latitude (signed!) and greater than the lower right latitude. Just simple comparisons, no fancy calculations required here.
Output the matching points to a temporary KML for the user.
You can feed KML directly into Google Maps and let it map it, or you can use the Javascript maps API to load the points via KML.
It might not solve your exact problem here, but for related issues you might also look into the Google Static Maps API. This allows you to create a static image file with placemarkers on it that will load very quickly, but won't have the interactivity of a regular Google map. Because of the way the API is designed, however, it can't handle anywhere near 16,000 points either so you'd still have to filter down to the view.
I don't know how fare you are with your project but maybe you can take a look at GeoDjango? This modified Django release includes all kinds of tools to store locations; convert coordinates and display maps, the easy way. Offcourse you need some Python experience and a server to run it on, but once you've got the hang of Django it works fast and good.
If you just want a solution for your problem try grouping your results at lower zoom levels, a good example of this implementation can be found here.
This is a tough one. You can use custom tilesets with Google Maps, but you still need some way to generate the tiles (other than manually).
I'm afraid that's all I've got =/
OpenLayers is a great javascript frontend to multiple mapping services or your own map servers. Version 2.7 was just released, which adds some pretty amazing features and controls.