ESCatastroLib 0.0.1rc2__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,141 @@
1
+ URL_BASE_CALLEJERO = 'https://ovc.catastro.meh.es/OVCServWeb/OVCWcfCallejero/COVCCallejero.svc/json'
2
+ URL_BASE_COORDENADAS = 'https://ovc.catastro.meh.es/OVCServWeb/OVCWcfCallejero/COVCCoordenadas.svc/json'
3
+ URL_BASE_GEOGRAFIA = 'http://ovc.catastro.meh.es/INSPIRE/wfsCP.aspx'
4
+ URL_BASE_CROQUIS_DATOS = f'https://www1.sedecatastro.gob.es/CYCBienInmueble/SECImprimirCroquisYDatos.aspx'
5
+ URL_BASE_CARTOCIUDAD_GEOCODER = 'https://www.cartociudad.es/geocoder/api/geocoder'
6
+
7
+ MAPEOS_PROVINCIAS = {
8
+ 'La Coruña': 'A Coruña',
9
+ 'Orense': 'Ourense',
10
+ 'Santa Cruz De Tenerife': 'S.C. Tenerife',
11
+ 'Las Palmas De Gran Canaria': 'Las Palmas',
12
+ 'Alicante': 'Alacant',
13
+ 'Almería': 'Almeria',
14
+ 'Cádiz': 'Cadiz',
15
+ 'Córdoba': 'Cordoba',
16
+ 'Gerona': 'Girona',
17
+ 'Castellón De La Plana': 'Castello',
18
+ 'Castellón': 'Castello',
19
+ 'Lérida': 'Lleida',
20
+ 'Málaga': 'Malaga',
21
+ 'León': 'Leon',
22
+ 'Ávila': 'Avila',
23
+ 'Cáceres': 'Caceres',
24
+ 'Baleares': 'Illes Balears',
25
+ 'Islas Baleares': 'Illes Balears',
26
+ 'Jaén': 'Jaen',
27
+ 'València': 'Valencia'
28
+ }
29
+
30
+ TIPOS_VIA = {
31
+ "AC": "ACCESO",
32
+ "AG": "AGREGADO",
33
+ "AL": "ALDEA, ALAMEDA",
34
+ "AN": "ANDADOR",
35
+ "AR": "AREA, ARRABAL",
36
+ "AU": "AUTOPISTA",
37
+ "AV": "AVENIDA",
38
+ "AY": "ARROYO",
39
+ "BJ": "BAJADA",
40
+ "BL": "BLOQUE",
41
+ "BO": "BARRIO",
42
+ "BQ": "BARRANQUIL",
43
+ "BR": "BARRANCO",
44
+ "CA": "CAÑADA",
45
+ "CG": "COLEGIO, CIGARRAL",
46
+ "CH": "CHALET",
47
+ "CI": "CINTURON",
48
+ "CJ": "CALLEJA, CALLEJON",
49
+ "CL": "CALLE",
50
+ "CM": "CAMINO, CARMEN",
51
+ "CN": "COLONIA",
52
+ "CO": "CONCEJO, COLEGIO",
53
+ "CP": "CAMPA, CAMPO",
54
+ "CR": "CARRETERA, CARRERA",
55
+ "CS": "CASERIO",
56
+ "CT": "CUESTA, COSTANILLA",
57
+ "CU": "CONJUNTO",
58
+ "CY": "CALEYA",
59
+ "CZ": "CALLIZO",
60
+ "DE": "DETRÁS",
61
+ "DP": "DIPUTACION",
62
+ "DS": "DISEMINADOS",
63
+ "ED": "EDIFICIOS",
64
+ "EM": "EXTRAMUROS",
65
+ "EN": "ENTRADA, ENSANCHE",
66
+ "EP": "ESPALDA",
67
+ "ER": "EXTRARRADIO",
68
+ "ES": "ESCALINATA",
69
+ "EX": "EXPLANADA",
70
+ "FC": "FERROCARRIL",
71
+ "FN": "FINCA",
72
+ "GL": "GLORIETA",
73
+ "GR": "GRUPO",
74
+ "GV": "GRAN VIA",
75
+ "HT": "HUERTA, HUERTO",
76
+ "JR": "JARDINES",
77
+ "LA": "LAGO",
78
+ "LD": "LADO, LADERA",
79
+ "LG": "LUGAR",
80
+ "MA": "MALECON",
81
+ "MC": "MERCADO",
82
+ "ML": "MUELLE",
83
+ "MN": "MUNICIPIO",
84
+ "MS": "MASIAS",
85
+ "MT": "MONTE",
86
+ "MZ": "MANZANA",
87
+ "PB": "POBLADO",
88
+ "PC": "PLACETA",
89
+ "PD": "PARTIDA",
90
+ "PI": "PARTICULAR",
91
+ "PJ": "PASAJE, PASADIZO",
92
+ "PL": "POLIGONO",
93
+ "PM": "PARAMO",
94
+ "PQ": "PARROQUIA, PARQUE",
95
+ "PR": "PROLONGACION, CONTINUAC.",
96
+ "PS": "PASEO",
97
+ "PT": "PUENTE",
98
+ "PU": "PASADIZO",
99
+ "PZ": "PLAZA",
100
+ "QT": "QUINTA",
101
+ "RA": "RACONADA",
102
+ "RB": "RAMBLA",
103
+ "RC": "RINCON, RINCONA",
104
+ "RD": "RONDA",
105
+ "RM": "RAMAL",
106
+ "RP": "RAMPA",
107
+ "RR": "RIERA",
108
+ "RU": "RUA",
109
+ "SA": "SALIDA",
110
+ "SC": "SECTOR",
111
+ "SD": "SENDA",
112
+ "SL": "SOLAR",
113
+ "SN": "SALON",
114
+ "SU": "SUBIDA",
115
+ "TN": "TERRENOS",
116
+ "TO": "TORRENTE",
117
+ "TR": "TRAVESIA",
118
+ "UR": "URBANIZACION",
119
+ "VA": "VALLE",
120
+ "VD": "VIADUCTO",
121
+ "VI": "VIA",
122
+ "VL": "VIAL",
123
+ "VR": "VEREDA"
124
+ }
125
+
126
+ SISTEMAS_REFERENCIA = {
127
+ 'EPSG:4230': 'Geográficas en ED 50',
128
+ 'EPSG:4326': 'Geográficas en WGS 80',
129
+ 'EPSG:4258': 'Geográficas en ETRS89',
130
+ 'EPSG:32627': 'UTM huso 27N en WGS 84',
131
+ 'EPSG:32628': 'UTM huso 28N en WGS 84',
132
+ 'EPSG:32629': 'UTM huso 29N en WGS 84',
133
+ 'EPSG:32630': 'UTM huso 30N en WGS 84',
134
+ 'EPSG:32631': 'UTM huso 31N en WGS 84',
135
+ 'EPSG:25829': 'UTM huso 29N en ETRS89',
136
+ 'EPSG:25830': 'UTM huso 30N en ETRS89',
137
+ 'EPSG:25831': 'UTM huso 31N en ETRS89',
138
+ 'EPSG:23029': 'UTM huso 29N en ED50',
139
+ 'EPSG:23030': 'UTM huso 30N en ED50',
140
+ 'EPSG:23031': 'UTM huso 31N en ED50'
141
+ }
@@ -0,0 +1,213 @@
1
+ import requests
2
+ import json
3
+
4
+ from typing import Union
5
+
6
+ from .statics import URL_BASE_CALLEJERO, MAPEOS_PROVINCIAS, TIPOS_VIA, SISTEMAS_REFERENCIA, URL_BASE_COORDENADAS, URL_BASE_CARTOCIUDAD_GEOCODER
7
+ from .exceptions import lanzar_excepcion
8
+
9
+ def comprobar_long_contenido(contenido:str):
10
+ """
11
+ Comprueba si el mensaje se puede cargar, es decir, si no esta vacio
12
+
13
+ Args:
14
+ - contenido: El contenido de la peticion
15
+ Raises:
16
+ - lanzar_excepcion: Si el mensaje esta vacio o no se puede formar el JSON.
17
+ """
18
+
19
+ try:
20
+ if len(contenido)>0:
21
+ json.loads(contenido)
22
+ return True
23
+ else:
24
+ raise Exception()
25
+ except:
26
+ raise lanzar_excepcion(mensaje_error="Error al cargar JSON")
27
+
28
+ def comprobar_errores(respuesta: dict):
29
+ """
30
+ Comprueba si la respuesta contiene errores.
31
+
32
+ Args:
33
+ respuesta (dict): El diccionario de respuesta.
34
+
35
+ Raises:
36
+ lanzar_excepcion: Si se encuentra un error en la respuesta.
37
+
38
+ Returns:
39
+ bool: True si no se encuentran errores, False en caso contrario.
40
+ """
41
+ # Check if the response contains the expected structure
42
+ if len(list(respuesta.values())) > 0:
43
+ if list(respuesta.values())[0] is not None and 'lerr' in list(respuesta.values())[0].keys():
44
+ if 'err' in list(respuesta.values())[0]['lerr']:
45
+ raise lanzar_excepcion(mensaje_error=list(respuesta.values())[0]['lerr']['err'][0]['des'])
46
+ else:
47
+ raise lanzar_excepcion(mensaje_error=list(respuesta.values())[0]['lerr'][0]['des'])
48
+ return True
49
+
50
+ def listar_provincias():
51
+ """
52
+ Obtiene una lista de provincias.
53
+ Returns:
54
+ list: Una lista de nombres de provincias.
55
+ Raises:
56
+ None
57
+ """
58
+
59
+ response = requests.get(f'{URL_BASE_CALLEJERO}/ObtenerProvincias')
60
+ return [provincia.get('np') for provincia in response.json().get('consulta_provincieroResult').get('provinciero').get('prov')] if comprobar_errores(response.json()) else []
61
+
62
+ def listar_municipios(provincia: str, municipio: Union[str,None] = None):
63
+
64
+ """
65
+ Obtiene una lista de municipios de España.
66
+ Args:
67
+ provincia (str): El nombre de la provincia. Preferentemente en mayúsculas o capitalizado.
68
+ municipio (str, optional): El nombre del municipio. Por defecto es None.
69
+ Returns:
70
+ List[str]: Una lista de nombres de municipios.
71
+ Raises:
72
+ Exception: Si la provincia no existe. Muestra un mensaje con las provincias disponibles.
73
+ """
74
+
75
+ if provincia and provincia.capitalize() not in MAPEOS_PROVINCIAS and provincia.upper() not in listar_provincias():
76
+ raise Exception(f'La provincia {provincia} no existe. Las provincias de España son: {listar_provincias()}')
77
+
78
+ response = requests.get(f'{URL_BASE_CALLEJERO}/ObtenerMunicipios',
79
+ params={
80
+ 'provincia' : MAPEOS_PROVINCIAS.get(provincia.capitalize())
81
+ if MAPEOS_PROVINCIAS.get(provincia.capitalize(),None) != None
82
+ else provincia ,
83
+ 'municipio': municipio
84
+ })
85
+ if response.status_code == 200 and comprobar_long_contenido(response.content) and comprobar_errores(response.json()):
86
+ mun_dict_raw = json.loads(response.content)
87
+ return [mun.get('nm') for mun in mun_dict_raw.get('consulta_municipieroResult').get('municipiero').get('muni')]
88
+ else:
89
+ return []
90
+
91
+
92
+ def listar_tipos_via():
93
+ """
94
+ Retorna una lista de los tipos de vía disponibles.
95
+ Returns:
96
+ list: Una lista de los tipos de vía disponibles.
97
+ """
98
+
99
+ return TIPOS_VIA
100
+
101
+ def listar_calles(provincia: str, municipio: str):
102
+ """
103
+ Devuelve una lista de calles para una provincia y municipio dados.
104
+ Args:
105
+ provincia (str): El nombre de la provincia.
106
+ municipio (str): El nombre del municipio.
107
+ Returns:
108
+ list: Una lista de calles en formato "tipo de vía nombre de vía".
109
+ """
110
+
111
+ provincia_final = MAPEOS_PROVINCIAS.get(provincia.capitalize()) if provincia.capitalize() in MAPEOS_PROVINCIAS.keys() else provincia
112
+ if provincia_final.upper() in listar_provincias() and municipio.upper() in listar_municipios(provincia=provincia_final):
113
+ response = requests.get(f'{URL_BASE_CALLEJERO}/ObtenerCallejero',
114
+ params={
115
+ 'Provincia': provincia_final,
116
+ 'Municipio': municipio
117
+ })
118
+ if response.status_code == 200 and comprobar_long_contenido(response.content) and comprobar_errores(response.json()):
119
+ calles_dict_raw = json.loads(response.content)
120
+ return [f"{calle.get('dir').get('tv')} {calle.get('dir').get('nv')}" for calle in calles_dict_raw.get('consulta_callejeroResult').get('callejero').get('calle')]
121
+ else:
122
+ return []
123
+ else: return []
124
+
125
+ def listar_sistemas_referencia():
126
+ """
127
+ Devuelve una lista de sistemas de referencia disponibles.
128
+ Returns:
129
+ list: Una lista de sistemas de referencia disponibles.
130
+ """
131
+ return [key for key in SISTEMAS_REFERENCIA.keys()]
132
+
133
+ def convertir_coordenadas_a_rc(lat: float, lon: float, sr: str = 'EPSG:4326'):
134
+ """
135
+ Convierte coordenadas X e Y a una referencia catastral (RC).
136
+
137
+ Args:
138
+ lat (float): Latitud.
139
+ lon (float): Longitud.
140
+ sr (str): Sistema de referencia. Por defecto es 'EPSG:4326'.
141
+
142
+ Returns:
143
+ str: Referencia catastral (RC).
144
+ """
145
+ response = requests.get(f'{URL_BASE_COORDENADAS}/Consulta_RCCOOR',
146
+ params={
147
+ 'CoorX': lon,
148
+ 'CoorY': lat,
149
+ 'SRS': sr
150
+ })
151
+ if response.status_code == 200 and comprobar_long_contenido(response.content) and comprobar_errores(response.json()):
152
+ return ''.join([part for part in response.json().get('Consulta_RCCOORResult').get('coordenadas').get('coord')[0].get('pc').values()])
153
+ else:
154
+ return None
155
+
156
+ def convertir_rc_a_coordenadas(rc: str, sr: str = 'EPSG:4326'):
157
+ """
158
+ Convierte una referencia catastral (RC) a coordenadas X e Y.
159
+ Args:
160
+ rc (str): Referencia catastral.
161
+ sr (str): Sistema de referencia. Por defecto es 'EPSG:4326'.
162
+ Returns:
163
+ dict: Un diccionario con las coordenadas X e Y.
164
+ """
165
+ if len(rc) > 14:
166
+ rc_corregido = rc[0:14]
167
+ else: rc_corregido = rc
168
+
169
+ response = requests.get(f'{URL_BASE_COORDENADAS}/Consulta_CPMRC',
170
+ params={
171
+ 'RefCat': rc_corregido,
172
+ 'SRS': sr
173
+ })
174
+ if response.status_code == 200 and comprobar_long_contenido(response.content) and comprobar_errores(response.json()):
175
+ coordenadas = response.json().get('Consulta_CPMRCResult').get('coordenadas').get('coord')[0].get('geo')
176
+ return {
177
+ 'x': coordenadas.get('xcen'),
178
+ 'y': coordenadas.get('ycen')
179
+ }
180
+ else:
181
+ return None
182
+
183
+ def geocodificar_direccion(direccion: str, municipio: str = None):
184
+ """
185
+ Geocodifica una dirección utilizando el servicio de CartoCiudad.
186
+
187
+ Args:
188
+ direccion (str): La dirección a geocodificar.
189
+ provincia (str, optional): La provincia de la dirección. Por defecto es None.
190
+ municipio (str, optional): El municipio de la dirección. Por defecto es None.
191
+
192
+ Returns:
193
+ dict: Un diccionario con las coordenadas X e Y y otros datos relevantes.
194
+ """
195
+
196
+ response = requests.get(f'{URL_BASE_CARTOCIUDAD_GEOCODER}/findJsonp',
197
+ params = {
198
+ 'q': f'{direccion}, {municipio}'
199
+ })
200
+
201
+ if response.status_code == 200:
202
+ data = json.loads(response.content.decode('utf-8').replace('callback(', '').replace(')', ''))
203
+ return {
204
+ 'x': data.get('lng'),
205
+ 'y': data.get('lat'),
206
+ 'rc': data.get('refCatastral')
207
+ }
208
+ else:
209
+ return None
210
+
211
+ def lon_lat_from_coords_dict(coords):
212
+ return float(coords["x"]), float(coords["y"])
213
+