Latitude and Longitude to Address
Question: I have about 8000 + Latitudes and Longitudes. I need to extract(reverse code),
them to location, possibly city.

Initially I checked with Google Maps, but according to their terms we should
not hit their services with our scripts.

Even the OpenStreetMaps doesnt allow us to hit their servers repeatedly. They
have some time limit.

So, I downloaded the latitudes and logitudes for locations. I wrote a python
script,

    
    
    import tabular as tb
    import csv
    
    
    
    citiesLatLongData = tb.tabarray(SVfile="D:/latitude-longitude/citieslatlong.csv")
    
    allData = tb.tabarray(SVfile="C:/Users/User/Desktop/alldata.csv")
    
    latlonglocs = {'a1':"Car Nicobar",'a2':"Port Blair",'a3':"Hyderabad",'a4':"Kadapa",'a5':"Puttaparthi",
    'a6':"Rajahmundry",'a7':"Tirupati",'a8':"Vijayawada",'a9':"Vishakhapatnam",'a10':"Itanagar",
    'a11':"Dibrugarh",'a12':"Dispur",'a13':"Guwahati",'a14':"North Lakhimpur",'a15':"Silchar",
    'a16':"Gaya",'a17':"Patna",'a18':"Chandigarh",'a19':"Raipur",'a20':"Silvassa",
    'a21':"Daman",'a22':"Bawana",'a23':"New Delhi",'a24':"Mormugao",'a25':"Panaji",
    'a26':"Ahmedabad",'a27':"Bhavnagar",'a28':"Bhuj",'a29':"Gandhinagar",'a30':"Jamnagar",
    'a31':"Kandla",'a32':"Rajkot",'a33':"Vadodara",'a34':"Hisar",'a35':"Bilaspur",
    'a36':"Dharamsala",'a37':"Kulu",'a38':"Shimla",'a39':"Jammu",'a40':"Srinagar",'a41':"Jamshedpur",
    'a42':"Ranchi",'a43':"Bangalore",'a44':"Belgaum",'a45':"Bellary",'a46':"Hubli Dharwad",
    'a47':"Mandya",'a48':"Mangalore",'a49':"Mysore",'a50':"Cochin",'a51':"Kozhikode",
    'a52':"Thiruvananthapuram",'a53':"Bingaram Island ",'a54':"Kavaratti",'a55':"Bhopal",'a56':"Gwalior",
    'a57':"Indore",'a58':"Jabalpur",'a59':"Khandwa",'a60':"Satna",'a61':"Ahmadnagar",
    'a62':"Akola",'a63':"Aurangabad",'a64':"Jalna",'a65':"Kolhapur",'a66':"Mumbai",
    'a67':"Nagpur",'a68':"Nasik",'a69':"Pimpri",'a70':"Pune",'a71':"Solapur",
    'a72':"Imphal",'a73':"Shillong",'a74':"Aizawl",'a75':"Kohima",'a76':"Bhubaneswar",
    'a77':"Jharsuguda",'a78':"Karaikal",'a79':"Mahe",'a80':"Pondicherry",'a81':"Yanam",
    'a82':"Amritsar",'a83':"Pathankot",'a84':"Jaipur",'a85':"Jodhpur",'a86':"Kota",
    'a87':"Udaipur",'a88':"Gangtok",'a89':"Chennai",'a90':"Coimbatore",'a91':"Madurai",
    'a92':"Nagercoil",'a93':"Thiruchendur",'a94':"Thiruvannaamalai",'a95':"Thoothukudi",
    'a96':"Tiruchirappalli",'a97':"Tirunelveli",'a98':"Vellore",'a99':"Agartala",
    'a100':"Agra",'a101':"Allahabad",'a102':"Bareilly",'a103':"Gorakhpur",'a104':"Jhansi",
    'a105':"Kanpur",'a106':"Lucknow",'a107':"Varanasi",'a108':"Dehradun",'a109':"Pantnagar",
    'a110':"Kolkata",'a111':"Siliguri"}
    
    
    
    latlongs = {'a1':[9.15,92.8167],'a2':[11.6667,92.7167],'a3':[17.45,78.4667],'a4':[14.4833,78.8333],
                'a5':[14.1333,77.7833],'a6':[16.9667,81.7667],'a7':[13.65,79.4167],'a8':[16.5333,80.8],
                'a9':[17.7,83.3],'a10':[27.0833,93.5667],'a11':[27.4833,95.0167],'a12':[26.0833,91.8333],
                'a13':[26.1667,91.5833],'a14':[27.2333,94.1167],'a15':[24.8167,92.8],'a16':[24.75,84.95],
                'a17':[25.6,85.1],'a18':[30.7333,76.75],'a19':[21.2333,81.6333],'a20':[20.2833,73],
                'a21':[20.4167,72.85],'a22':[28.7833,77.0333],'a23':[28.5667,77.1167],'a24':[15.3833,73.8167],      
                'a25':[15.3833,73.8167],'a26':[23.0333,72.6167],'a27':[21.75,72.2],'a28':[23.25,69.6667],
                'a29':[23.3333,72.5833],'a30':[22.4667,70.0667],'a31':[23.0333,70.2167],'a32':[22.3,70.7833],
                'a33':[22.3,73.2667],'a34':[29.1667,75.7333],'a35':[31.25,76.6667],'a36':[32.2,76.4],
                'a37':[31.9667,77.1],'a38':[31.1,77.1667],'a39':[32.7,74.8667],'a40':[34.0833,74.8167],
                'a41':[22.8167,86.1833],'a42':[23.3167,85.3167],'a43':[12.9833,77.5833],'a44':[15.85,74.6167],
                'a45':[15.15,76.85],'a46':[15.35,75.1667],'a47':[12.55,76.9],'a48':[12.9167,74.8833],
                'a49':[12.3,76.65],'a50':[9.95,76.2667],'a51':[11.25,75.7667],'a52':[8.46667,76.95],
                'a53':[10.9167,72.3333],'a54':[10.5833,72.65],'a55':[23.2833,77.35],'a56':[26.2333,78.2333],
                'a57':[22.7167,75.8],'a58':[23.2,79.95],'a59':[21.8333,76.3667],'a60':[24.5667,80.8333],
                'a61':[19.0833,74.7333],'a62':[20.7,77.0667],'a63':[19.85,75.4],'a64':[19.8333,75.8833],
                'a65':[16.7,74.2333],'a66':[19.1167,72.85],'a67':[21.1,79.05],'a68':[19.8933,73.8],
                'a69':[18.55,73.8167],'a70':[18.5333,73.8667],'a71':[17.6667,75.9],'a72':[24.7667,93.9],
                'a73':[25.55,91.85],'a74':[23.6667,92.6667],'a75':[25.6667,94.1167],'a76':[20.25,85.8333],
                'a77':[21.5833,84.08333],'a78':[10.95,79.7833],'a79':[11.7,75.5333],'a80':[11.9333,79.8833],
                'a81':[16.7333,82.2167],'a82':[31.6333,74.8667],'a83':[32.2833,75.65],'a84':[26.8167,75.8],
                'a85':[29.1667,75.7333],'a86':[25.15,75.85],'a87':[24.5667,73.6167],'a88':[27.3333,88.6167],
                'a89':[13,80.1833],'a90':[11.0333,77.05],'a91':[9.83333,78.0833],'a92':[8.16667,77.4333],
                'a93':[8.48333,78.1167],'a94':[12.2167,79.0667],'a95':[8.78333,78.1333],'a96':[10.7667,78.7167],
                'a97':[8.73333,77.7],'a98':[12.9167,79.15],'a99':[23.8833,91.25],'a100':[27.15,77.9667],
                'a101':[25.45,81.7333],'a102':[28.3667,79.4],'a103':[26.75,83.3667],'a104':[29.1667,75.7333],
                'a105':[26.4,80.4],'a106':[26.75,80.8833],'a107':[25.45,83],'a108':[30.3167,78.0333],
                'a109':[29.0833,79.5],'a110':[22.65,88.45],'a111':[26.6333,88.3167]
                }
    
    for eachOne in allData:
        for eachTwo in latlongs:
            eachOne_Coordinates_Latitude = eachOne['COORDINATES-Latitude']
            latlongs_eachTwo_Latitude_Plus  = int(latlongs[eachTwo][0]) + 0.18
            latlongs_eachTwo_Latitude_Minus = int(latlongs[eachTwo][0]) - 0.18
    
            eachOne_Coordinates_Longitude = eachOne['COORDINATES-Longitude']
            latlongs_eachTwo_Longitude_Plus = int(latlongs[eachTwo][1]) + 0.18
            latlongs_eachTwo_Longitude_Minus = int(latlongs[eachTwo][1]) - 0.18
    
            if ( (eachOne_Coordinates_Latitude < latlongs_eachTwo_Latitude_Plus) and (latlongs_eachTwo_Latitude_Plus > latlongs_eachTwo_Latitude_Minus) ) and ( (eachOne_Coordinates_Longitude < latlongs_eachTwo_Longitude_Plus)  and (eachOne_Coordinates_Longitude > latlongs_eachTwo_Longitude_Minus) ):
                someDict.setdefault((eachOne_Coordinates_Latitude,eachOne_Coordinates_Longitude),[]).append(latlongs[eachTwo])
    
    
    for each in someDict:
        print each,':', min(someDict[each])
    

**MY PROBLEM:** As you know, the latitudes and longitudes that we get from
external sources does not exactly match with the latitudes and longitudes that
we have. I heard somewhere that they wont match and there will be some error
percentage or something.

I need some guidance from anyone. I request someone to please point me in the
right direction or if you know any packages or scripts that does this.

I would be extremely thankful to you.


Answer: This sounds a lot like a "Closest point problem". You have N points (cities)
and M locations (your 8000 coordinates). For each of the M locations, you want
to categorize the location by its closest city. There are a number of
solutions for the [Nearest Neighbor
Search](http://en.wikipedia.org/wiki/Closest_point_query), but the simplest
one is a linear search:

    
    
    function getClosestCity(Coordinate location){
        bestCity = cities[0];
        foreach(city in cities){
            if (distance(bestCity.location, location) < distance(city.location, location)){
                bestCity = city;
            }
        }
        return bestCity;
    }
    

