Je vais résumer un package appelé folium qui est pratique pour gérer les informations géographiques en Python.
folium est une bibliothèque qui encapsule une bibliothèque JavaScript appelée Leaflet en Python.
Vous pouvez facilement créer un fichier HTML contenant une carte interactive en suivant la procédure. Sur JupyterLab, la carte s'affiche à l'écran simplement en affichant l'objet Carte.
Cette entrée est écrite sur le Jupyter Lab. Si vous exécutez le code de cette entrée dans l'ordre dans JupyterLab, vous obtiendrez le même résultat (devrait).
import sys
import folium
print(f"""Python
{sys.version}
folium
{folium.__version__}""")
Python
3.7.3 (default, Mar 27 2019, 16:54:48)
[Clang 4.0.1 (tags/RELEASE_401/final)]
folium
0.10.1
Définissez les constantes utilisées ci-dessous.
#Latitude et longitude de Toranomon Hills
office_lat = 35.66687568
office_lng = 139.74947495
Pour afficher une carte sur Jupyter, évaluez simplement folium.Map. Vous pouvez également le cracher dans un fichier HTML avec Map.save.
fmap1 = folium.Map(
location=[office_lat, office_lng],
tiles = "OpenStreetMap",
zoom_start = 20, #Grossissement 1 à 20 lors du dessin
width = 800, height = 800 #Taille de la carte
)
fmap1 #Ou fmap1.save("1.html")
«tiles» est
Vous pouvez choisir.
Placez un marqueur. Les fenêtres contextuelles peuvent être enregistrées pour les marqueurs.
fmap2 = folium.Map(
location=[office_lat, office_lng],
zoom_start=20
)
folium.Marker([office_lat, office_lng], popup="Datawise est là").add_to(fmap2)
fmap2
Passez une liste de (lat, lng) à PolyLine et tracez une ligne de pliage
import itertools as it
#Le sommet de la place centrée sur les collines de Toranomon
sq = [
(office_lat + dy * pow(10, -3), office_lng + dx * pow(10, -3))
for dx, dy in it.product([-1, 1], [-1, 1])
]
fmap3 = folium.Map(location=[office_lat, office_lng], zoom_start=20)
folium.PolyLine(locations=sq).add_to(fmap3)
fmap3
Vous pouvez dessiner des polygones avec Polygon.
sw, nw, se, ne = sq
fmap4 = folium.Map(location=[office_lat, office_lng], zoom_start=20)
folium.Polygon(
locations=[sw, se, ne, nw], #Sommets polygonaux
color="red", #Couleur de la ligne
weight=10, #Épaisseur de ligne
fill=True, #Remplir
fill_opacity=0.5 #Transparence (1=Opacité)
).add_to(fmap4)
fmap4
En principe, si vous avez un tel outil, vous pouvez visualiser les informations des données appropriées sur la carte ..., mais en pratique c'est ennuyeux (peut-être) de gérer le polygone avec une liste de sommets. ..
GeoJSON est défini comme un standard pour exprimer des formes sur une carte, et il peut également être géré par folium.
Utilisez la bibliothèque geojson pour travailler avec GeoJSON.
GeoJSON mourra si vous ne lisez pas attentivement les spécifications. J'ai passé plusieurs heures à remarquer les points suivants ... Il n'est pas exagéré de dire que j'ai écrit cette entrée parce que je voulais la transmettre à mes collègues.
--Dans GeoJSON, les coordonnées sont représentées par (longitude, latitude) au lieu de (latitude, résidence) (en face de folium) --La liste passée à geojson.Polygon doit commencer et se terminer par la même valeur --geordinates dans geojson.Polygon reçoit "liste de (longitude, latitude)" au lieu de "liste de (longitude, latitude)" [^ 1]
Pour plus de détails, utilisez le code ci-dessous ...
import geojson as gj
# (lat、lng)Liste de
#Point 1.Le premier et le dernier élément ont la même valeur
lat_lng = [sw, se, ne, nw, sw]
#Point 2. (lng, lat)Convertir en
def swap(p):
return p[1], p[0]
lng_lat = list(map(swap, lat_lng))
#Point 3.Faites une liste de la liste de (lng, lat)
lng_lat2 = [lng_lat]
poly5 = gj.Polygon(lng_lat2)
fmap5 = folium.Map(location=[office_lat, office_lng], zoom_start=20)
folium.GeoJson(poly5).add_to(fmap5)
fmap5
Je ne l'ai pas étudié en détail, mais si cela ne fonctionne pas, enregistrez-le au format HTML → ouvrez-le dans un navigateur et regardez les erreurs JS, etc. Il peut y avoir des informations.
Dans GeoJSON, une collection de plusieurs objets est représentée par un FeatureCollection. Avec FeatureCollection, vous pouvez en dessiner plusieurs à la fois. (En fait, folium.GeoJson s'attend à ce qu'un FeatureCollection en tant que GeoJSON soit passé, mais lorsque quelque chose d'autre est passé, il est converti en interne en FeatureCollection)
def slide(poly, i):
"""
Une fonction qui décale un peu les polygones
"""
vtx = poly["coordinates"][0] # gj.Les coordonnées du polygone sont une liste de sommets"Liste de"
vtx2 = [
(lng + i * pow(10, -3), lat + i * pow(10, -3))
for lng, lat in vtx
]
return gj.Polygon([vtx2]) # gj.Le polygone coodinate est (omis)
fmap6 = folium.Map(location=[office_lat, office_lng], zoom_start=16)
polys6 = [slide(poly5, i) for i in range(-2, 3)]
fc6 = gj.FeatureCollection(polys6)
folium.GeoJson(fc6).add_to(fmap6)
fmap6
Il semble que cela fonctionne bien ci-dessus, mais cela fait quelque chose de mal avec la spécification GeoJSON. Spécifications FeatureCollection Ci-dessus, les fonctionnalités FeatureCollection doivent être une liste d'objets avec type = "feature". .. D'un autre côté, si vous regardez les "fonctionnalités" de fc6
fc6["features"]
[{"coordinates": [[[139.746475, 35.663876], [139.748475, 35.663876], [139.748475, 35.665876], [139.746475, 35.665876], [139.746475, 35.663876]]], "type": "Polygon"},
{"coordinates": [[[139.747475, 35.664876], [139.749475, 35.664876], [139.749475, 35.666876], [139.747475, 35.666876], [139.747475, 35.664876]]], "type": "Polygon"},
{"coordinates": [[[139.748475, 35.665876], [139.750475, 35.665876], [139.750475, 35.667876], [139.748475, 35.667876], [139.748475, 35.665876]]], "type": "Polygon"},
{"coordinates": [[[139.749475, 35.666876], [139.751475, 35.666876], [139.751475, 35.668876], [139.749475, 35.668876], [139.749475, 35.666876]]], "type": "Polygon"},
{"coordinates": [[[139.750475, 35.667876], [139.752475, 35.667876], [139.752475, 35.669876], [139.750475, 35.669876], [139.750475, 35.667876]]], "type": "Polygon"}]
C'est difficile à voir, mais les "fonctionnalités" de fc6 sont un tableau d'objets avec type = "Polygon". (Je pense que l'exemple ci-dessus a fonctionné parce que folium a fait du bon travail, j'en suis sûr)
Vous pouvez obtenir le bon objet GeoJSON en écrivant:
fmap7 = folium.Map(location=[office_lat, office_lng], zoom_start=16)
fc7 = gj.FeatureCollection(
features=[
gj.Feature(
geometry=p,
id=i
) for i, p in enumerate(polys6)
]
)
folium.GeoJson(fc7).add_to(fmap7)
fmap7
Pour changer le format de Polygon, passez style_function à folium.GeoJson. Le résultat de l'application de style_function à chaque fonction est utilisé comme format lors du dessin de cette fonction.
fmap8 = folium.Map(location=[office_lat, office_lng], zoom_start=16)
folium.GeoJson(
fc7,
style_function=lambda feature: {
"fillColor": "red",
"color": "black",
"weight": 10 / (feature["id"] + 1),
"fillOpacity": feature["id"] * 0.2
}).add_to(fmap8)
fmap8
[^ 1]: Ce japonais est difficile à comprendre, je vais donc le compléter. Dans GeoJSON, les points sur la carte sont représentés par une liste de longueur 2 [longitude, latitude]. Puisqu'un polygone est représenté par plusieurs points (= chaque sommet), la circonférence extérieure du polygone est représentée par une liste contenant plusieurs [longitude, latitude]. Je pensais que cela pourrait représenter un polygone, mais le polygone de GeoJSON peut également représenter un polygone avec des trous. Un polygone perforé est représenté par une liste dans laquelle le premier élément est une liste qui représente la circonférence extérieure, et le deuxième élément et les suivants sont une liste qui représente la circonférence du trou intérieur. En raison des spécifications GeoJSON, il est nécessaire de préparer une liste qui ne contient qu'une seule liste qui représente la circonférence extérieure (c'est une liste qui comprend plusieurs listes de longueur 2 appelées [longitude, latitude]) même s'il n'y a pas de trous. Par exemple, pour définir un quadrilatère avec quatre points [0,0], [0,1], [1,1], [1,0] comme sommets, [[0,0], [0] , 1], [1,1], [1,0]] «, pas une liste de sommets» [[[0,0], [0,1], [1,1], [1,0 Vous devez avoir une liste de listes de sommets appelées]]]
.
Recommended Posts