[PYTHON] Obtenez l'adresse à partir de la latitude et de la longitude

Nous publierons un programme qui recherche des polygones contenant certaines coordonnées en utilisant les données de polygones publiées. Obtenir une adresse à partir de la latitude et de la longitude s'appelle le géocodage inversé.

Si vous ne disposez pas de données polygonales, le géocodage inversé est également fourni par l'API Google Maps, etc. et il est facile à utiliser. Si vous disposez de données polygonales et que vous souhaitez effectuer un géocodage inversé, vous pouvez également utiliser la fonction SIG d'une base de données telle que MySQL.

Cette fois, il s'agit d'un programme Python lorsque vous souhaitez déterminer quelle ville, quartier, ville ou village au Japon appartient à un grand nombre de coordonnées. Même un petit programme fish qui génère un index à chaque fois a beaucoup de coordonnées, donc il a fallu moins de temps pour s'exécuter que lors de l'utilisation de MySQL 5.6.

Avantages de l'utilisation de MySQL:

Démérite:

――Vous avez besoin de données de polygones qui correspondent au niveau d'adresse souhaité (les polygones de niveau d'adresse peuvent ne pas être facilement disponibles)

Raison de son implémentation en Python:

――Vous n'avez pas besoin d'être aussi détaillé que le niveau d'adresse --Lorsque vous accédez à la base de données, le montant est trop important pour terminer (bien sûr, l'API est également difficile) --La source des données de zone utilisées pour le classement est claire

Bibliothèques requises

Pip install rtree shapely` `` seul peut ne pas fonctionner car il y a des bibliothèques dépendantes. Veuillez donc lire chaque document pour l'installation.

Correspondance des adresses à partir de la latitude et de la longitude

Vous pouvez écrire ceci en utilisant rtree et galbé.

revgeocoder.py


# -*- coding: utf-8 -*-

import collections
from shapely.geometry import Polygon, Point
from rtree import index

Area = collections.namedtuple('Area', ['area_id', 'polygon'])


class ReverseGeocoder():
    def __init__(self):
        self.idx = index.Index()

    def insert_from_iterator(self, itr):
        '''(id, Polygon)Créer un Rtree à partir d'un itérateur qui retourne

        Polygon.Rtree créé en fonction de l'id et du polygone liés.

        Args:
            itr: (id, Polygon)Itérateur qui retourne
        '''
        for i, (area_id, polygon) in enumerate(itr):
            obj = Area(area_id=area_id, polygon=polygon)
            self.idx.insert(i, polygon.bounds, obj)

    def contains(self, lat, lon):
        '''Point(lat, lon)Zone de polygone comprenant_Renvoie id.

S'il correspond à deux polygones ou plus, il est trié et renvoyé par ordre croissant de superficie.
(Lorsqu'une zone a une relation d'inclusion, il est préférable de sélectionner celle avec la zone la plus petite.
Cependant, en réalité, il y a un chevauchement entre Polygon et Polygon ... )
        '''
        result = []
        point = Point(lat, lon)
        for hit in self.idx.intersection(point.bounds, objects=True):
            if hit.object.polygon.contains(point):
                result.append(hit.object)
        if len(result) > 1:
            result.sort(key=lambda x: (x.polygon.area, x.area_id))
        return [r.area_id for r in result]

    def __repr__(self):
        return '<ReverseGeocoder contains {} polygons>'.format(self.idx.count(self.idx.bounds))

Comment utiliser

Lorsque vous utilisez les données de limite qui peuvent être téléchargées depuis e-stat, cela ressemble à ceci.

findcity.py


# -*- coding: utf-8 -*-

import glob
import fiona
from shapely.geometry import Polygon, shape
from revgeocoder import ReverseGeocoder


def parse_shapefile(shapefile):
    '''(area_id, Polygon, name)Générateur qui retourne'''
    with fiona.open(shapefile, 'r') as source:
        for obj in source:
            #Données polygonales
            polygon = shape(obj['geometry'])

            #Adresse de la zone
            names = []
            for prop in ['KEN_NAME', 'GST_NAME', 'CSS_NAME', 'MOJI']:
                if obj['properties'][prop] is not None:
                    names.append(obj['properties'][prop])
            name = ''.join(names)

            #Générer un identifiant unique (KEN+ CITY + SEQ_NO2)
            area_id = int(''.join(map(str, (obj['properties']['KEN'], obj['properties']['CITY'], obj['properties']['SEQ_NO2']))))

            yield area_id, polygon, name


def main():
    shapefiles = glob.glob('data/japan-shape/A002005212010DDSWC3520*/*.shp')
    print('Shapefiles:', shapefiles)

    #Faire un index
    rgeocoder = ReverseGeocoder()
    id2name = {}
    def gen(shapefile):
        for area_id, polygon, name in parse_shapefile(shapefile):
            id2name[area_id] = name
            yield area_id, polygon

    for shapefile in shapefiles:
        rgeocoder.insert_from_iterator(gen(shapefile))

    # test
    area_id = rgeocoder.contains(132.257269, 34.108815)[0]
    print(area_id, id2name[area_id])

    return rgeocoder


if __name__ == '__main__':
    rgeocoder = main()

Exemple d'exécution:

$ python findcity.py
Shapefiles: ['data/japan-shape/A002005212010DDSWC35208/h22ka35208.shp', 'data/japan-shape/A002005212010DDSWC35207/h22ka35207.shp', 'data/japan-shape/A002005212010DDSWC35201/h22ka35201.shp', 'data/japan-shape/A002005212010DDSWC35203/h22ka35203.shp', 'data/japan-shape/A002005212010DDSWC35206/h22ka35206.shp', 'data/japan-shape/A002005212010DDSWC35202/h22ka35202.shp', 'data/japan-shape/A002005212010DDSWC35204/h22ka35204.shp']
35208602 6-chome, Sofucho, ville d'Iwakuni, préfecture de Yamaguchi

Comparaison avec d'autres bibliothèques similaires

Recommended Posts

Obtenez l'adresse à partir de la latitude et de la longitude
Obtenir une adresse à partir d'un code postal
Obtenez des informations de localisation (latitude et longitude) à partir de l'adresse. Géocodage en Python ~ Géocodeur et pydams ~
Trouvez la distance (en tenant compte de la rondeur de la terre) de la latitude et de la longitude.
Trouvez le waypoint à partir de la latitude et de la longitude (en tenant compte de la rondeur de la terre).
Télécharger les tuiles de l'Institut géographique à partir de la latitude et de la longitude
Comment obtenir la valeur en pixels du point à partir de l'image satellite en spécifiant la latitude et la longitude
Donnez les données de séquence de points de latitude et de longitude et essayez d'identifier la route à partir des données d'OpenStreetMap
Comment obtenir des abonnés et des abonnés de Python à l'aide de l'API Mastodon
Obtenez l'adresse IP du client avec Django
Recevez les publications wordpress de la semaine dernière
[Python] Obtenez la couleur principale de la capture d'écran
Récupérez uniquement le texte du formulaire Django.
[GPS] Calculez la distance, l'angle azimutal et l'angle d'élévation à partir de la latitude et de la longitude GPS à l'aide de pyproj
Récupérer le contenu de git diff depuis python
Obtenez le module lui-même et ajoutez des membres de manière dynamique
Obtenez les distances de latitude et de longitude en mètres avec QGIS
Obtenir uniquement la partie adresse de la carte réseau (eth0)
Obtenez des tweets populaires de la chronologie Twitter, listez-les et diplômé de Tsui Abolition
Passez un tableau de PHP à PYTHON et effectuez un traitement numpy pour obtenir le résultat
Obtenez le titre de Yahoo News et analysez les sentiments
[Python] Récupérez le texte de la loi à partir de l'API e-GOV law
Récupérer le code retour d'un script Python depuis bat
[Version 2020] Grattage et traitement du texte d'Aozora Bunko
Obtenez les points de latitude et de longitude à proximité avec la bibliothèque Geoindex de Python
Environ 200 données de latitude et de longitude pour les hôpitaux de Tokyo
Obtenez des commentaires et des abonnés avec l'API de données YouTube
Recevoir des e-mails de Gmail et étiqueter avec Python3
[Django 2.2] Trier et obtenir la valeur de la destination de la relation
Récupérer des fichiers depuis Linux en utilisant paramiko et scp [Python]
YOLP: extraire la latitude et la longitude avec l'API Yahoo! Geocoder.
[Linux] [C / C ++] Comment obtenir la valeur d'adresse de retour d'une fonction et le nom de fonction de l'appelant
Obtenez la version GNOME
Obtenir le type MIME
Récupérer une image d'une page Web et la redimensionner
Remarque DJango: depuis le début (Simplification et fractionnement d'URLConf)
Obtenez votre fréquence cardiaque à partir de l'API fitbit en Python!
Obtenez et créez des nœuds ajoutés et mis à jour dans la nouvelle version
Les débutants acquièrent des informations sur les balises Qiita et visualisent et considèrent le TOP10.
Obtenez le type MIME en Python et déterminez le format de fichier
Mettre en œuvre la recherche d'emplacement par latitude et longitude à l'aide de Redis et redis-py
Recherchez le pandas.DataFrame avec une variable et obtenez la ligne correspondante.
Obtenez la valeur tout en spécifiant la valeur par défaut de dict en Python
Comment obtenir toutes les clés et valeurs du dictionnaire
J'ai essayé d'obtenir diverses informations de l'API codeforces
Fabriquez un thermomètre BLE et obtenez la température avec Pythonista3
Obtenez la météo en utilisant l'API et laissez Raspberry Pi parler!
Je veux obtenir des informations de fstab à la destination de la connexion ssh et exécuter la commande
[Affichage de la carte] Affichez une carte à partir de l'adresse enregistrée par l'utilisateur à l'aide de l'API JavaScript de Google Maps et de l'API de géocodage!
Obtenez des informations de l'Agence météorologique et informez Slack des avertissements météorologiques dans les 23 quartiers de Tokyo
Pour obtenir une adresse IP locale par programme
Obtenez l'adresse IP du client avec Django
Obtenez votre propre adresse IP en Python
Convertir l'adresse IP en décimal
Obtenir une adresse à partir d'un code postal
Comment obtenir une adresse IP lorsque Tornado + nginx
Obtenez un environnement local pour DynamoDB avec Docker
Traduire la plage d'adresses IP en un autre sous-réseau 1: 1
Obtenez l'adresse à partir de la latitude et de la longitude