J'ai ma propre application Python (intentionnelle) que je pense créer. Pour cela, il est préférable d'avoir une carte affichée. C'est comme une étude pour ça. J'espère que cela aide quelqu'un.
Il semble y avoir un moyen d'utiliser openstreetmap et le module de fond de carte, le folium, le fichier shp et le logiciel SIG, mais je ne semblais pas trouver cela difficile ou adapté pour moi. Après tout, j'ai décidé d'utiliser google map car c'était plus facile que je ne le pensais lorsque j'ai vérifié l'API google static map et que la photographie aérienne convient à mon objectif. Il semble que la carte de l'Institut géographique puisse être gérée de la même manière, donc c'est comme ...
En ce qui concerne la conversion entre latitude / longitude et projection Web Mercator, NOTE DE TRAIL L'explication de l'auteur était facile à comprendre. Il y a certaines choses que je n'ai pas entièrement comprises sur la conversion des coordonnées, etc., mais ce point peut devenir apparent au fur et à mesure que le développement progresse.
import os
os.mkdir("maptiles")
for d in range(22):
os.mkdir("maptiles/z%02d"%d)
En regardant ça comme ça, c'est peut-être Akan de mettre un long bâton dessus ... Je ferai attention dans les prochains messages.
AMAP.py
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import urllib
import os
#WIN_W=480
#WIN_H=260
WIN_W=1280
WIN_H=960
# gg*:googleMap, other:cyberjapandata:Institut national de recherche foncière
map_type_name = ["gghybrid","ggsatellite","ggroadmap", "std","ort_old10","gazo1","seamlessphoto"]
TILE_W = [640,640,640,256,256,256,256]
TILE_H = [640,640,640,256,256,256,256]
min_zoom=[ 0, 0, 0, 2,10,10, 2]
max_zoom=[21,21,21,18,17,17,18]
fmt=["png","png","png", "png", "png","jpg","jpg"]
#Vous pouvez voir différentes cartes en modifiant la définition de la table
##ort:2007-, airphoto:2004-, gazo4:1988-1990, gazo3:1984-1986, gazo2:1979-1983, gazo1:1974-1978
##ort_old10:1961-1964, ort_USA10:1945-1950
#map_type_name = ["ort","airphoto","gazo4","gazo3","gazo2","gazo1","ort_old10","ort_USA10"]
#TILE_W = [256,256,256,256,256,256,256,256]
#TILE_H = [256,256,256,256,256,256,256,256]
#min_zoom=[14, 5,10,10,10,10,10,10]
#max_zoom=[18,18,17,17,17,17,17,17]
#fmt=["jpg","png","jpg","jpg","jpg","jpg","png","png"]
#Gare de Tokyo
HOME_LON=139.767052
HOME_LAT= 35.681167
HOME_ZOOM=18
TILES_DIR="maptiles/"
max_pixels= [256*2**zm for zm in range(22)]
#Un dictionnaire qui stocke les références aux tuiles ouvertes. Indexé par type de carte, zoom, index x, index y
opened_tiles={}
white_tiles={}
#lon:longitude, lat:latitude
def ll2pix(lon, lat, zoom):
pix_x=2**(zoom+7)*(lon/180+1)
pix_y=2**(zoom+7)*(-np.arctanh(np.sin(np.pi/180*lat))/np.pi+1)
return pix_x,pix_y
def pix2ll(x,y,zoom):
lon=180*(x/(2**(zoom+7))-1)
lat=180/np.pi*(np.arcsin(np.tanh(-np.pi/(2**(zoom+7))*y+np.pi)))
return lon, lat
#Depuis la longitude / latitude dx,dy Renvoie la longitude / latitude lors du déplacement des pixels
def new_ll(lon_cur,lat_cur,zm, dx,dy):
x,y=ll2pix(lon_cur,lat_cur,zm)
return pix2ll(x+dx,y+dy,zm)
def dddmm2f(dddmm_mmmm):
#12345.6789 ->123 degrés 45.6789 minutes->123 degrés.(45.6789/60)
ddd=int(dddmm_mmmm)//100
mm_mmmm=dddmm_mmmm-ddd*100
return ddd+mm_mmmm/60
#Concaténez les tuiles pour créer une image plus grande que la fenêtre d'affichage, puis coupez-la à la taille de la fenêtre et renvoyez-la
def load_win_img(mtype, lon,lat,zm):
cx,cy=ll2pix(lon,lat,zm)
win_left=int(cx-WIN_W/2)
win_top=int(cy-WIN_H/2)
x_nth=win_left//TILE_W[mtype]
y_nth=win_top//TILE_H[mtype]
left_offset = win_left%TILE_W[mtype]
top_offset = win_top%TILE_H[mtype]
vcon_list=[]
tot_height=0
tot_height += TILE_H[mtype]-top_offset
j=0
while True:
hcon_list=[]
tot_width=0
tot_width += TILE_W[mtype]-left_offset
i=0
while True:
img_tmp=open_tile_img(mtype, x_nth+i,y_nth+j,zm)
hcon_list.append(img_tmp) #
if tot_width >= WIN_W:
break
tot_width += TILE_W[mtype]
i+=1
hcon_img=cv2.hconcat(hcon_list)
vcon_list.append(hcon_img)
if tot_height >= WIN_H:
break
tot_height += TILE_H[mtype]
j+=1
convined_img=cv2.vconcat(vcon_list)
return convined_img[top_offset:top_offset+WIN_H, left_offset:left_offset+WIN_W, :]
def tile_file_name(mtype, x_nth,y_nth,zm):
# x_nth=x//TILE_W[mtype]
# y_nth=y//TILE_H[mtype]
return TILES_DIR+"z%02d/%s_z%02d_%dx%d_%07d_%07d"%(zm,map_type_name[mtype],zm,TILE_W[mtype],TILE_H[mtype],x_nth,y_nth)+"."+fmt[mtype]
#Ouvrir la tuile
#Un point qui n'a jamais été ouvert->Essayez de télécharger / enregistrer. En cas d'échec, une image blanchie à la chaux est renvoyée. En cas de succès, enregistrez le type de point / zoom / carte dans le dictionnaire et marquez-le comme ouvert par la suite.
#Enregistré dans un fichier mais pas ouvert->Ouvrez normalement. Inscrivez-vous également dans le dictionnaire
#Déjà ouvert->Renvoie l'image enregistrée dans le dictionnaire
def open_tile_img(mtype, x_nth,y_nth,zm):
if (mtype, zm,x_nth,y_nth) in opened_tiles:
print("opened_tiles(%d,%d,%d,%d)"%(mtype, zm,x_nth,y_nth))
return opened_tiles[(mtype, zm,x_nth,y_nth)]
fname=tile_file_name(mtype, x_nth,y_nth,zm)
if os.path.exists(fname):
print("opening tile(%d,%d,%d,%d)"%(mtype,zm,x_nth,y_nth) +" -> "+fname)
else:
c_lon,c_lat=pix2ll((x_nth+0.5)*TILE_W[mtype],(y_nth+0.5)*TILE_H[mtype],zm)
if map_type_name[mtype][0:2]=="gg":
url="http://maps.google.com/maps/api/staticmap?"
url+="¢er=%.08f,%08f&zoom=%d&size=%dx%d&maptype=%s" % \
(c_lat,c_lon,zm,TILE_W[mtype],TILE_H[mtype],map_type_name[mtype][2:])
#maptype
#feuille de route Carte normale. Valeur par défaut du paramètre maptype
#photographie aérienne par satellite
#terrain Image de la carte du terrain physique montrant le terrain et la végétation
#photographie aérienne hybride + carte normale. Superposition des routes principales et des noms de lieux sur des photographies aériennes
else:
url="http://cyberjapandata.gsi.go.jp/xyz/%s/%d/%d/%d.%s"%(map_type_name[mtype],zm,x_nth,y_nth,fmt[mtype])
print("Downloading... ")
print(url)
print(" -> "+fname)
try:
urllib.request.urlretrieve(url,fname) #python3
# urllib.urlretrieve(url,fname) #python2
except Exception as e:
#Si la tuile ne peut pas être obtenue, l'image remplie de blanc est renvoyée.
print(e)
print("Download faild -> blank")
if (TILE_W[mtype],TILE_H[mtype]) in white_tiles:
return white_tiles[(TILE_W[mtype],TILE_H[mtype])]
else:
white=np.zeros([TILE_H[mtype],TILE_W[mtype],3],dtype=np.uint8)
white[:,:,:]=255
white_tiles[(TILE_W[mtype],TILE_H[mtype])]=white
return white
opened_tiles[(mtype, zm,x_nth,y_nth)]=cv2.imread(fname)
return opened_tiles[(mtype, zm,x_nth,y_nth)]
if __name__ == '__main__':
map_type=0
c_lon=HOME_LON
c_lat=HOME_LAT
zoom=HOME_ZOOM
cv2.namedWindow("Ackerman's Map", cv2.WINDOW_AUTOSIZE)
map_type_bak = -1
c_lon_bak = -1
c_lat_bak = -1
zoom_bak = -1
#mainloop
while (True):
if map_type_bak != map_type or c_lon_bak != c_lon or c_lat_bak != c_lat or zoom_bak != zoom:
win_img=load_win_img(map_type, c_lon,c_lat,zoom)
cv2.imshow("Ackerman's Map", win_img)
map_type_bak = map_type
c_lon_bak = c_lon
c_lat_bak = c_lat
zoom_bak = zoom
k=cv2.waitKey(0) & 0xff #Lors de l'ajout de la fonction GPS, interrogez sans régler le temps d'attente sur 0
print("pressed:"+str(k))
if k == ord('+'):
if zoom<max_zoom[map_type]:
zoom += 1
elif k == ord('-'):
if zoom>min_zoom[map_type]:
zoom -= 1
elif k == ord('a'):
c_lon,c_lat=new_ll(c_lon,c_lat,zoom,-WIN_W/4,0)
elif k == ord('s'):
c_lon,c_lat=new_ll(c_lon,c_lat,zoom,0,-WIN_H/4)
elif k == ord('d'):
c_lon,c_lat=new_ll(c_lon,c_lat,zoom,0,+WIN_H/4)
elif k == ord('f'):
c_lon,c_lat=new_ll(c_lon,c_lat,zoom,+WIN_W/4,0)
elif k == 32:
#space key
map_type = (map_type+1)%len(map_type_name)
if zoom > max_zoom[map_type]:
zoom=max_zoom[map_type]
if zoom < min_zoom[map_type]:
zoom=min_zoom[map_type]
elif k == 8:
#Backspace
map_type = (map_type-1)%len(map_type_name)
if zoom > max_zoom[map_type]:
zoom=max_zoom[map_type]
if zoom < min_zoom[map_type]:
zoom=min_zoom[map_type]
elif k == ord("q"):
break
cv2.destroyAllWindows()
Pendant un moment, j'ai retracé l'exemple du livre d'introduction de raspberrypi et modifié le programme de temps en temps, et essayé un code court en lisant le livre d'introduction de python3, mais je me demande pourquoi je l'ai écrit à partir de zéro pour la première fois. J'avais l'habitude de programmer principalement en langage C il y a plus de 15 ans, mais comparé à cette situation, c'est une liste, un dictionnaire, une notation inclusive et le paradis. Quelle est l'utilité des tableaux associatifs (≒ dictionnaires) dans d'autres langues? Je réfléchissais, mais je sens que j'ai pu l'utiliser efficacement ici.
De plus, la carte de l'Institut géographique qui a été affichée en note latérale est assez intéressante. "Vous avez habité ici il y a 50 ans?" "Wow, ce bâtiment mystérieux existe depuis plus de 30 ans?!" Dans le code
#Gare de Tokyo
HOME_LON=139.767052
HOME_LAT= 35.681167
Il peut être intéressant de changer la zone autour de la zone en fonction de la latitude et de la longitude de votre résidence et de faire une promenade tout en changeant de carte.
J'ai déjà écrit sur la connexion et l'affichage de ma position actuelle, et j'ai fait quelque chose comme une version dégradée de FoxtrotGPS, mais elle a été publiée dans un magazine. Je ne l'ai pas posté pour le moment car le code est assez chargé. C'est comme décrypter le format NMEA, mais c'était plus facile que prévu. J'envisageais également une méthode comme la communication avec gpsd, mais cela semble plus facile que cela.
Recommended Posts