Texto del callejero de Azure Maps
Archivo: dibuja_texto_extraido_servicio_mapas_azure.py · orden DIBUJA_TEXTO_EXTRAIDO_SERVICIO_MAPAS_AZURE,
orden interactiva (PythonCommand) con un parámetro: la
clave de Azure Maps.
Variante del ejemplo del Catastro que usa el servicio Azure Maps e inserta el texto rotado. Cada texto necesita dos datos: el primero fija el punto de inserción y consulta la calle; el segundo marca la dirección de la rotación.
Cómo se usa
Obtén la clave (subscription key) de tu cuenta de Azure Maps.
Escribe en la línea de comandos el nombre de la orden y la clave:
DIBUJA_TEXTO_EXTRAIDO_SERVICIO_MAPAS_AZURE=clavePulsa el botón de dato en el punto de inserción del texto.
Pulsa el botón de dato en un segundo punto para fijar la dirección del texto.
Si no se indica exactamente un parámetro, la orden emite el sonido de error y muestra un cuadro con el motivo y la forma de uso. Si la consulta a Azure Maps falla, la orden escribe el error en el panel de resultados, emite el sonido de error y espera de nuevo el punto de inserción.
El código
import digi3d
import json
import urllib.request
USO = 'DIBUJA_TEXTO_EXTRAIDO_SERVICIO_MAPAS_AZURE=[clave de Azure Maps]'
def error(mensaje):
"""Emite el sonido de error y muestra el mensaje con la forma de uso de la orden."""
digi3d.music(digi3d.MusicType.Error)
digi3d.show_info('{}\n\nUso: {}'.format(mensaje, USO))
class DibujaTextoExtraidoServicioMapasAzure(digi3d.PythonCommand):
def __init__(self, clave):
digi3d.PythonCommand.__init__(self, 'dibuja_texto_extraido_servicio_mapas_azure')
self.clave = clave
self.origen = None
def on_data_down(self, coordenadas):
if self.origen is None:
self.asigna_origen_y_nombre_calle(coordenadas)
else:
rotacion = self.view.geographic_calculator.calculate_trigonometric_angle(self.origen, coordenadas)
texto = digi3d.Text(self.calle, self.origen, rotation=rotacion)
self.view.add(texto)
self.view.redraw()
self.origen = None
self.new_transaction()
def asigna_origen_y_nombre_calle(self, coordenadas):
# El intérprete embebido solo tiene la stdlib (no "requests"); usamos urllib.request.
try:
self.origen = coordenadas
geograficas = self.view.to_geo(coordenadas)
url = 'https://atlas.microsoft.com/search/address/reverse/json?&api-version=1.0&subscription-key={}&language=es-ES&query={},{}'.format(self.clave, geograficas[0], geograficas[1])
with urllib.request.urlopen(url) as r:
respuesta = json.load(r)
self.calle = respuesta['addresses'][0]['address']['streetName']
except Exception as e:
# Sin calle no hay texto que orientar: el siguiente dato vuelve a ser un origen.
print(e)
self.origen = None
digi3d.music(digi3d.MusicType.Error)
return True
if len(argv) != 1:
error('Falta la clave de Azure Maps.')
else:
orden = DibujaTextoExtraidoServicioMapasAzure(argv[0])
digi3d.current_view().add_command(orden)
Cómo funciona
- El parámetro: la clave llega en
argv[0]. Siargvno tiene exactamente un elemento, la funciónerroremite el sonido de error y muestra condigi3d.show_infoel mensaje «Falta la clave de Azure Maps.» y la forma de uso. La orden guarda la clave enself.clavey la incluye en la URL de cada consulta. - Estado entre pulsaciones: la orden guarda el primer punto en
self.origen. Mientrasself.origenesNone, el siguiente dato fija el origen y consulta la calle. Cuandoself.origentiene valor, el siguiente dato calcula la rotación, inserta el texto y vuelve a ponerself.origenaNone. Así una orden interactiva pide varios datos. - Fallo de la consulta: si la conversión, la petición o la lectura de la respuesta lanza una
excepción,
asigna_origen_y_nombre_calleescribe el error en el panel de resultados, vuelve a ponerself.origenaNoney emite el sonido de error. El siguiente dato vuelve a ser un punto de inserción. - Coordenadas geográficas: el servicio de Azure trabaja en longitud y latitud, así que la orden
convierte el punto con
self.view.to_geo(coordenadas), que devuelve(longitud, latitud). - Rotación a partir de dos puntos:
self.view.geographic_calculator.calculate_trigonometric_angle(origen, destino)devuelve el ángulo entre los dos puntos, y la orden lo pasa al texto. - Texto rotado:
digi3d.Text(texto, coordenadas, rotation=rotacion). La rotación se pasa por nombre (rotation=...) porque el tercer argumento posicional deTextescodes, no la rotación. self.new_transaction()deja cada texto en una transacción propia, así que cada UNDO deshace un texto.- La llamada web se hace, como en el ejemplo del Catastro, con
urllib.requestyjson.
Véase también
- Texto del callejero del Catastro
- PythonCommand · Text
- GeographicCalculator —
calculate_trigonometric_angle - DrawingView —
to_geo