Получение полного адреса и геокодирования на основе названия места / магазина и города, сохраненного в csv - PullRequest
0 голосов
/ 18 июня 2019

У меня есть CSV-файл с 2 полями, store_name и city. В городе может быть несколько магазинов.
Я хочу вывод csv с 5 полями, store_name, city, address, latitude, longitude.

Например, если одна запись csv равна Starbucks, Chicago, я хочу, чтобы вывод csv содержал всю информацию в 5 полях (упомянутых выше) как:
Starbucks, Chicago, "200 S Michigan Ave, Chicago, IL 60604, USA", 41.8164613, -87.8127855
Starbucks, Chicago, "8 N Michigan Ave, Chicago, IL 60602, USA", 41.8164613, -87.8127855
и так далее для остальных результатов.

Я пытался проработать это через GeoPy с помощью Nomanitim, прежде чем заставить его работать с Google Maps API. Хотя я не знаю, как лучше подойти к этому. Обратите внимание, что в исходном csv существует миллион таких записей, но покупка ключа API не является проблемой, если он работает.

Я пробовал только геокодирование с Nominatim, используя панд, но это создает только один результат в выходных csv для каждой записи. Я хочу получить каждый результат, как описано в примере выше. Не уверен, как это реализовать.

from geopy.geocoders import Nominatim
import csv, sys
import pandas as pd
import keys

in_file = str(sys.argv[1])
out_file = str('gc_' + in_file)
timeout = int(sys.argv[2])

nominatim = Nominatim(user_agent=your_key_here, timeout=timeout)

def gc(address):
    name = str(address['store_name'])
    city = str(address['city'])
    add_concat = name + ", " + city
    location = nominatim.geocode(add_concat)
    if location != None:
        print(f'geocoded record {address.name}: {city}')
        located = pd.Series({
            'lat': location.latitude,
            'lng': location.longitude,
        })
    else:
        print(f'failed to geolocate record {address.name}: {city}')
        located = pd.Series({
            'lat': 'null',
            'lng': 'null',
        })
    return located

print('opening input.')
reader = pd.read_csv(in_file, header=0)
print('geocoding addresses.')
reader = reader.merge(reader.apply(lambda add: gc(add), axis=1), left_index=True, right_index=True)
print(f'writing to {out_file}.')
reader.to_csv(out_file, encoding='utf-8', index=False)
print('done.')

1 Ответ

1 голос
/ 18 июня 2019

Вы можете использовать reverse geocoding для этой цели. Согласно официальной документации здесь , это способ преобразования географических координат в удобочитаемый адрес.

Я использовал приведенную ниже функцию в одном из своих проектов, и она все еще работает. Вы, вероятно, можете изменить его в соответствии с вашими требованиями.

import requests

GCODE_URL = 'https://maps.googleapis.com/maps/api/geocode/json?'
GCODE_KEY = 'YOUR API KEY' 

def reverse_gcode(location):
    location = str(location).replace(' ','+')
    nav_req = 'address={}&key={}'.format(location,GCODE_KEY)
    request = GCODE_URL + nav_req
    result = requests.get(request)
    data = result.json()
    status = data['status']

    geo_location = {}
    if str(status) == "OK":
       sizeofjson = len(data['results'][0]['address_components'])
       for i in range(sizeofjson):
           sizeoftype = len(data['results'][0]['address_components'][i]['types'])
           if sizeoftype == 3:
              geo_location[data['results'][0]['address_components'][i]['types'][2]] = data['results'][0]['address_components'][i]['long_name']

           else:
              if data['results'][0]['address_components'][i]['types'][0] == 'administrative_area_level_1':
                 geo_location['state'] = data['results'][0]['address_components'][i]['long_name']

              elif data['results'][0]['address_components'][i]['types'][0] == 'administrative_area_level_2':
                   geo_location['city'] = data['results'][0]['address_components'][i]['long_name']
                   geo_location['town'] = geo_location['city']

               else:
                   geo_location[data['results'][0]['address_components'][i]['types'][0] ]= data['results'][0]['address_components'][i]['long_name']

       formatted_address = data['results'][0]['formatted_address']
       geo_location['lat'] = data['results'][0]['geometry']['location']['lat']
       geo_location['lang']= data['results'][0]['geometry']['location']['lng']
       geo_location['formatted_address']=formatted_address

       return geo_location

print(reverse_gcode("Starbucks, Chicago"))

Вывод будет в формате json, выглядит примерно так:

{'street_number': '8', 'town': 'Cook County', 'locality': 'Chicago', 'city': 'Cook County', 'lat': 41.882413, 'neighborhood': 'Chicago Loop', 'route': 'North Michigan Avenue', 'lang': -87.62468799999999, 'postal_code': '60602', 'country': 'United States', 'formatted_address': '8 N Michigan Ave, Chicago, IL 60602, USA', 'state': 'Illinois'}
...