This repository has been archived by the owner on Oct 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generar_graf.py
114 lines (96 loc) · 3.92 KB
/
generar_graf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Copyright (C) 2019 Marçal Comajoan Cara
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import pickle
import urllib.request
import xml.etree.ElementTree as xml
from graf import GrafDirigit
from utils import distancia
def descarregar_osm():
'''Descarrega el fitxer OSM XML amb les dades del mapa de Calldetenes.'''
url = "https://www.openstreetmap.org/api/0.6/map?bbox=2.2666%2C41.9062%2C2.3179%2C41.9398"
with urllib.request.urlopen(url) as response, open("static/mapa.osm", 'wb') as mapa_osm:
mapa_osm.write(response.read())
def processar_osm():
'''Processa el fitxer OSM XML i en crea un graf.
Un cop s'ha obtingut el graf, es guarda en pickle (un format per guardar
objectes de Python) per no haver-lo de processar cada cop.'''
element_tree = xml.parse("static/mapa.osm").getroot()
dicc_vertexs = {}
vies = []
tipus_via = ["motorway", "motorway_link", "trunk", "trunk_link", "primary",
"primary_link", "secondary", "secondary_link", "tertiary",
"tertiary_link", "unclassified", "residential", "service",
"living_street", "track"]
for i in element_tree:
if i.tag == "node":
dicc_vertexs[int(i.attrib["id"])] = [
float(i.attrib["lat"]), float(i.attrib["lon"])]
elif i.tag == "way":
via = []
unidireccional = False
insertar = False
for j in i:
if j.tag == "nd":
via.append(int(j.attrib["ref"]))
elif j.tag == "tag":
if (j.attrib["k"] == "oneway" and j.attrib["v"] == "yes") or (
j.attrib["k"] == "junction" and (
j.attrib["v"] in ["roundabout", "circular"])):
unidireccional = True
elif j.attrib["k"] == "highway" and j.attrib["v"] in tipus_via:
insertar = True
if insertar:
vies.append(via)
if not unidireccional:
vies.append(list(reversed(via)))
G = GrafDirigit()
for id, coordenades in dicc_vertexs.items():
for via in vies:
if id in via:
dicc_vertexs[id] = G.ordre()
G.afegir_vertex(coords=coordenades)
break
for via in vies:
for i, id in enumerate(via):
via[i] = dicc_vertexs[id]
for i in range(len(via) - 1):
G.afegir_aresta((via[i], via[i + 1]))
for e in G.arestes():
G.assignar_atributs(e, llargada=distancia(
G.llegir_atributs(e[0])["coords"],
G.llegir_atributs(e[1])["coords"]))
with open("static/graf.pickle", "wb") as fitxer_graf:
pickle.dump(G, fitxer_graf)
def generar_llista_incidencia():
'''A partir de la llista d'adjacència del graf, genera la llista d'incidència
del graf, que serà utilitzada pels algorismes de cerca bidireccional.'''
with open("static/graf.pickle", "rb") as fitxer_graf:
G = pickle.load(fitxer_graf)
llista_incidencia = []
for u in G.vertexs():
llista_incidencia.append([])
for u in G.vertexs():
for v in G.llista_adjacencia[u]:
llista_incidencia[v].append(u)
with open("static/llista_incidencia.pickle", "wb") as fitxer_llista_incidencia:
pickle.dump(llista_incidencia, fitxer_llista_incidencia)
print("Descarregant el mapa de Calldetenes d'OpenStreetMap...")
descarregar_osm()
print("Convertint el mapa en un graf...")
processar_osm()
print("Generant la llista d'incidència del graf pels algorismes de cerca "
"bidireccional...")
generar_llista_incidencia()
print("Procés completat!")