views:

318

answers:

1

HI, I was wondering if anyone had any ideas about how to implement functionality where given an array of locations ( for e.g. branches) it will list the nearest one or list all withing a 5 mile radius etc?

A: 

When you say "locations", what do you mean exactly? Street addresses? GPS coordinates?

If you have GPS coordinates (or can convert an address to coords), you can always calculate the Euclidean distance or the (more accurate) great-circle distance between two points. Caculate the distance between the current location and each potential destination, then sort the list by shortest distance.

You didn't mention if you were using the Google Maps API, but here's some additional info in case you are. You can store two points as objects of type GLatLng and use object1.distanceFrom(object2) to calculate this. You can also create a GLatLngBounds object representing a rectangular region on the map and use GLatLngBounds.containsLatLng(latlng:GLatLng) to see if a geographical point lies within that region.

Edit: What typically happens in the case you mention below is when a user enters a post code, the "current location" is taken to be the geographic center of that post code (you would probably have to get this info from the authority who assigns post codes in your area). If you are in the UK, this site has a free list of postcodes and their coordinates. Searching for a postal code in Google Maps will take you to the center of that postcode; if you need to build your own list of post codes and coordinates, you can probably create a script that will iterate through all valid post codes and use Google maps to look them up and turn them into GPS coordinates.

To turn an address into coordinates, you want to do what is called geocoding. Google Maps has an API for this, and there are other resources that can provide you this functionality. For some examples, try this page. What resource you use largely depends on where you are, as most of this information is localized. You didn't mention much about your project (platform, language, etc), but at the bottom of that page is a section called "Geocoding Helper Libraries" that may have the functionality you need rolled into a pre-built package. In particular the GeoKit library (Ruby language) has a handful of examples on the front page of their website, including several that look like they do exactly what you are wanting to do.

EDIT: I got the following code from the code generator at WebRPC:

/**
 * Copyright WebRPC
 * available under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 * http://www.gnu.org/licenses/gpl.txt
 */
public class Client
{
    public static void Main(string[] args)
    {
        // make the call
        XPathDocument doc = new XPathDocument(@"http://maps.google.com/maps/geo?q=New+York&output=xml&key=ABQIAAAAuXdMTY5VIU1FvkgOOP1dNBTsILMTMKRV-aJhd94IQkaJhVJ0YBS2qNSZGm8TaefqbXBT6lUXeMZ6tA");

        // print the outputs
        XPathNavigator nav = doc.CreateNavigator();
        XPathNodeIterator coord = nav.Select( "/kml/Response/Placemark/Point/coordinates" );
        while ( coord.MoveNext() )
            System.Console.WriteLine( coord.Current );
        XPathNodeIterator accuracy = nav.Select( "/kml/Response/Placemark/AddressDetails/@Accuracy" );
        while ( accuracy.MoveNext() )
            System.Console.WriteLine( accuracy.Current );
    }
}

You should be able to modify this C# code to suit your needs. Specifically, in the call to new XPathDocument, change the part of the string that reads ?q=New+York to whatever address or postal code you need (for example, using ?q=1060+West+Addison%2C+Chicago%2C+IL will retrieve information for Wrigley Field in Chicago, or using ?q=LS11+0ES%2C+UK will get info for a postal code in Leeds). To format an address from a regular text string, change spaces to '+' and turn all other non-alphanumeric characters into their ASCII equivalent (such as '%2C' for a comma).

The next few lines retrieve the information from the server and parse it in various ways. Of interest here is the field /kml/Response/Placemark/Point/coordinates in the returned data. This string will contain your latitude and longitude coordinates for the location you specified above.

Now, this should give you enough information to create a C# function that is able to turn an address or post code into a pair of coordinates. The hard part is done, but two steps remain. First, you will want to use this to generate coordinates for each address in your database (store these in the database with the addresses for best results). Now, when a user enters an address, call your C# function again to generate a set of coordinates for her location. Now that you have coordinates for everything, you can find the distance between two coordinates by using one of the two distance-calculating functions I linked to at the top of the post. Run down your list of branches, calculate the distance from the user to each, and sort that list to find the branches with the shortest distance values.

bta
HI,I have post codes and street addresses of locations (branches) and what I would like to do is if a user enters a post code ( his home address) then I would like to list the nearest branches with a description of how far they are away approximately.I have seen this done in many large store websites and wanted to do somehting similar.
Rubans
Not enough room here to reply, see edit above.
bta
HI, If I don't use google maps, how could I do this?My location list is around 18000, so if a was to enter a post code, how would it work out the list of nearest locations and their distance?
Rubans
If you have the option to use Ruby-language code, I would recommend the GeoKit library (link above). If you store your location list in a database, you use something like their examples labeled "Order by distance from the center of a zipcode" or "Find near an address".
bta
To reduce the amount of work you have to do for every address, you can also store the state/province/county/region that each of your branches is in. When a user enters an address, it can limit its search to branches within that same region.
bta
In terms of technology I will be using asp.net c# but I assume I have to get a hostig company that will also support Ruby, I have never used it before so not familiar with it.
Rubans
In that case, look at the last helper library listed, "WebRPC". The link takes you to a site where you can use an online form to test using Google's geocoder, and when you have something that works it can generate code for you in C#. For example, I entered my ZIP code or address in the first "value" blank on the "Input tab", and the output generated includes my geographical coordinates. The C# code that it generates looks easy to modify so you can use it to look up any generic location.
bta
Doesn't seem to work for me, when I enter anything other than NewYork, the repsonse always seems to include NewYork.Am I doing it correct?
Rubans
On the "Input" tab, on the first row (name="q"), change the "Value" field from "New York" to whatever you want. The output pane won't update until you hit the "Call Service" button.
bta
That's what I'm doing but doesn't seem to make a difference however I do understand what you mean, so how can I use this to tie in with my list of locations to get a sorted list of locations within say 5 miles, for e.g.Appreciate your help.
Rubans
(See code I will post above momentarily)
bta
Thanks bta, will try it out.
Rubans