<jupyter_start><jupyter_text>Práctica de Formatos de datos: XML La __EMT__ dispone de un portal de datos abiertos que se puede encontrar en la página http://opendata.emtmadrid.es/Home. El objetivo del mismo es ofrecer diferentes tipos de datos sobre la actividad de los autobuses de la EMT. El acceso a los datos se realiza a través de una API de servicios web. Para poder utilizar la API de servicios, en primre lugar hay que registrarse, lo cual puede hacerse en la página http://opendata.emtmadrid.es/Formulario. El registro devuelve como resultado en un mensaje electrónico, dos valores:* Id de cliente: Identificador de cliente* Pass Key: PasswordA continuación, hay que elegir el servicio que se quiere utilizar. Hay 4 servicios definidos: BUS, GEO, MEDIA, INFOPARKING y BICIMAD. Cada servicio tiene asociado un conjunto de métodos que al invocarlos, devuelven un resultado. Por ejemplo, el servicio BUS dispone del servicio __"GetRouteLines"__ que obtiene el itinerario de una línea (o varias líneas separadas por el carácter pipe(|)), con los vértices para construir las rectas del recorrido y las coordenadas UTM de los ejes viales y los códigos de parada. Si se quiere invocar desde Python, se puede hacer usando el siguiente código:<jupyter_code>import requests
datos = {
    'idClient':'Identificador de cliente',
    'PassKey':'Password',
    'SelectDate': '27/10/2017',
    'Lines':'27'
}
 
url = 'https://servicios.emtmadrid.es:8443/bus/servicebus.asmx/GetRouteLines'
response = requests.post(url, data=datos)
print(response.text)<jupyter_output><empty_output><jupyter_text>En esta práctica se va a trabajar con varios métodos:* Método __'GetStreet'__ del servicio GEO. Este método obtiene una lista de emplazamientos EMT coincidentes con una localización. Cada emplazamiento está compuesto por una lista de paradas EMT situadas dentro de un radio predefinido con todos sus atributos, así como las líneas EMT que pasan por cada parada de la lista. En el documento __Servicios_EMT.pdf__ adjunto a esta práctica, se explica con detalle los parámetros de entrada y el resultado que devuelve este método. El método se puede invocar indicando al menos el nombre de la calle y el número:<jupyter_code>import requests
datos = {
    'idClient':'Identificador de cliente',
    'PassKey':'Password',
    'description': 'Profesor <NAME>',
    'streetNumber':'9',
    'Radius':'',
    'Stops':'',
    'statistics':'',
    'cultureInfo':''
}
 
url = 'https://servicios.emtmadrid.es:8443/geo/servicegeo.asmx/GetStreet'
response = requests.post(url, data=datos)
print(response.text)<jupyter_output><empty_output><jupyter_text>El método devuelve un documento XML. Entre los elementos del documento, se encuentran las coordenadas X e Y del lugar buscado. En la búsqueda del ejemplo, la calle búscada tiene como coordenadas UTM X e Y:<jupyter_code><CoordinateX>-3.73379031085432</CoordinateX>
    <CoordinateY>40.4530280706993</CoordinateY><jupyter_output><empty_output><jupyter_text>* Método __'GetStreetRoute'__ del servicio MEDIA. Este método obtiene hasta tres rutas óptimas para ir de un sitio a otro a pie y en autobús. En el documento __Servicios_EMT.pdf__ adjunto a esta práctica, se explica con detalle los parámetros de entrada y el resultado que devuelve este método. El método se puede invocar indicando los siguientes parámetros  * idClient: Código de cliente autorizado para la operación y suministrado por EMT.  * passKey: Código de clave asociado al cliente.  * coordinateXFrom: Campo para identificar la posición "x" del origen de la ruta a consultar.     * coordinateYFrom: Campo para identificar la posición "y" del origen de la ruta a consultar.  * coordinateXTo: Campo para identificar la posición "x" del destino de la ruta a consultar.     * coordinateYTo: Campo para identificar la posición "y" del destino de la ruta a consultar.   * criteriaSelection: Campo que indica el criterio de la búsqueda. Los valores son:         * 11 - Mínimo tiempo de trayecto           * 13 - Mínimos trasbordos           * 14 - Mínimo recorrido a pie<jupyter_code>import requests
datos = {
    'idClient':'Identificador de cliente',
    'PassKey':'Password',
    'statistics':'',
    'cultureInfo':'',
    'coordinateXFrom': '-3,63271713087776',
    'coordinateYFrom':'40,4543980802915',
    'originName':'',
    'coordinateXTo': '-3.7013019',
    'coordinateYTo':'40.4176416',
    'destinationName':'',
    'criteriaSelection':'13',
    'day':'',
    'month':'',
    'year':'',
    'hour':'',
    'minute':'',
    'GenerarAudio':''
}
 
url = 'https://servicios.emtmadrid.es:8443/servicemedia/servicemedia.asmx/GetStreetRoute'
response = requests.post(url, data=datos)
print(response.text)<jupyter_output><empty_output><jupyter_text>El método devuelve un documento XML que contiene información sobre las rutas óptimas (se explica con detalle en el documento __Servicios_EMT.pdf__). En particular muestra la siguiente información:* El elemento __DescriptionRouteData__ donde aparece la siguiente información:  * DescriptionDate: Fecha de la ruta.  * DescriptionInitTime: Descripción de hora de inicio de la ruta.  * DescriptionEstimateTimeArrival: Descripción de la hora estimada de llegada.  * Transfers: Trasbordos.  * LongJourney: Duración del viaje.* El elemento __ListSectionRoute__ aparece una lista de subelementos __Section__.Cada uno de ellos, describe parcialmente una parte de la ruta. En un caso ideal, aparecerá un subelemento de __Section__ de tipo __WalkingLeg__  que describe el inicio de la ruta andando, a continuación un conjunto de subelementos de __Section__ de tipo __BusLeg__ que describen cada uno de ellos la ruta en una línea de autobus que forma parte de la ruta buscada, y por último otro subelemento de __Section__ de tipo __WalkingLeg__  que describe el final de la ruta andando.* El elemento __POI__ que muestra información sobre puntos de interés que se encuentran a lo largo de la ruta. Se pide:* [1 punto] Crear una función que solicite al usuario dos calles de Madrid, que actúen de origen y destino de una ruta* [2 puntos]Crear una función que dada una calle de Madrid, devuelva las coordenadas X e Y de la calle.* [4 puntos]Crear una función que dadas las coordenadas X e Y de un origen y un destino dentro de Madrid, obtenga la ruta más óptima para ir del origen al destino usando autobuses de la EMT. La función deberá imprimir por pantalla, la siguiente información: * Fecha de la ruta.  * Hora de inicio de la ruta.  * Hora estimada de llegada  * Número de trasbordos.  * Duración del viaje.  * Descripción textual de la ruta.  Usando el ejemplo anterior debería mostrar:  * Fecha de la ruta: 26/10/2017  * Hora de inicio de la ruta: 03:55  * Hora estimada de llegada: 05:28  * Número de trasbordos: 1  * Duración del viaje: 93  * Descripción textual de la ruta:      * Caminar 42' hasta parada 3125 - EMILIO VARGAS-ARTURO SORIA, linea N4          * 28' en autobús (línea N4) hasta parada 449 - SERRANO-ORTEGA Y GASSET          * Desde parada 449 caminar 5' hasta parada 61 - Castellana-Ministerio Interior, linea N25      * 15' en autobús (línea N25) hasta parada 3691 - SOL-SEVILLA     * Desde parada 3691 caminar 3'* [1 punto]Crear una función que solicite al usuarios los nombres de 2 calles de Madrid y muestre la información referente a la ruta más óptima para llegar de una calle a otra usando autobuses de la EMT.* [2 puntos]Crear una función que solicite al usuarios los nombres de 2 calles de Madrid y muestre un listado de todos los puntos de interés que hay dentro de la ruta más óptima para llegar de una calle a otra usando autobuses de la EMT. A continuación, se le pedirá al usuario que introduzca el nombre de uno de los puntos de interés mostrado, y como resultado se mostrará por pantalla los siguientes datos del punto de interés:  * Nombre del punto de interés.    * Dirección del punto de interés.    * Teléfono del punto de interés.<jupyter_code># [1 punto] Crear una función que solicite al usuario dos calles de Madrid, que actúen de origen y destino de una ruta

def pideRuta():
    
    ruta = tuple() # Variable a devolver

    origen = input("Introduzca la calle origen de la ruta: ")

    while(origen == ""):
        print("El origen no puede estar vaciío. Vuelva a introducir el origen: ")
        origen = input("Introduzca la calle origen de la ruta: ")
    
    numOrigen = input("Introduzca el número del origen: ") # No comprobamos que sea distinto de "" porque puede que sea una plaza sin número

    destino = input("Introduzca la calle destino de la ruta: ")

    while(destino == ""):
        print("El destino no puede estar vacío. Vuelva a introducir el destino: ")
        destino = input("Introduzca la calle destino de la ruta: ")

    numDestino = input("Introduzca el número del destino: ") # No comprobamos que sea distinto de "" porque puede que sea una plaza sin número
        
    ruta = ((origen, numOrigen), (destino, numDestino))
    
    return ruta


# [2 puntos]Crear una función que dada una calle de Madrid, devuelva las coordenadas X e Y de la calle.

import requests
from xml.etree import ElementTree

def devuelveCoordenadas(calle, numero):
    
    datos = {
    'idClient':'',
    'passKey':'',
    'description': str(calle),
    'streetNumber': str(numero),
    'Radius':'',
    'Stops':'',
    'statistics':'',
    'cultureInfo':''
    }
    
    url = 'https://servicios.emtmadrid.es:8443/geo/servicegeo.asmx/GetStreet'
    response = requests.post(url, data=datos) # Datos en XML
    
    
    # Si la calle no se encuentra, se lanza excepción y se detiene la ejecución
    
    with open("coord.xml","w") as f:
        f.write(str(response.text))
        f.close()
    
    f = open("coord.xml","rt")
    
    parseado = ElementTree.parse(f)
    
    raiz = parseado.getroot()
    
    # Conocemos la estructura del XML por lo que podemos acceder de forma indexada
    elemX = raiz[0][7].text        
    
    elemY = raiz[0][8].text
    
    coord = (elemX, elemY)
    
    return coord
    
# [4 puntos]Crear una función que dadas las coordenadas X e Y de un origen y un destino dentro de Madrid,
# obtenga la ruta más óptima para ir del origen al destino usando autobuses de la EMT. (Más info arriba)

import requests
from xml.etree import ElementTree

def calculaRutaOptima(coordenadasOrigen, coordenadasDestino): # Ambas son tuplas con X Y
    
    datos = {
    'idClient':'',
    'PassKey':'',
    'statistics':'',
    'cultureInfo':'',
    'coordinateXFrom': str(coordenadasOrigen[0]),
    'coordinateYFrom': str(coordenadasOrigen[1]),
    'originName':'',
    'coordinateXTo': str(coordenadasDestino[0]),
    'coordinateYTo': str(coordenadasDestino[1]),
    'destinationName':'',
    'criteriaSelection':'13',
    'day':'',
    'month':'',
    'year':'',
    'hour':'',
    'minute':'',
    'GenerarAudio':''
}
    
    url = 'https://servicios.emtmadrid.es:8443/servicemedia/servicemedia.asmx/GetStreetRoute'
    response = requests.post(url, data=datos)
    
    with open("rutaOptima.xml","w") as f:
        f.write(str(response.text))
        f.close()
    
    f = open("rutaOptima.xml","rt")
    arbol = ElementTree.parse(f)
    root = arbol.getroot()
    for nodo in root.iter("DescriptionRouteData"):
        fecha_de_la_ruta = nodo.find("DescriptionDate").text
        hora_de_inicio_de_la_ruta = nodo.find("DescriptionInitTime").text
        hora_estimada_de_llegada = nodo.find("DescriptionEstimateTimeArrival").text
        numero_de_trasbordos = nodo.find("Transfers").text
        duracion_del_viaje = nodo.find ("LongJourney").text
        print("\nFecha del viaje: " + fecha_de_la_ruta)
        print("Hora de inicio: " + hora_de_inicio_de_la_ruta) 
        print("Hora estimada de llegada: " + hora_estimada_de_llegada) 
        print("Número de transbordos: " + numero_de_trasbordos) 
        print("Duración del viaje: " + duracion_del_viaje)
         
    print("\nDescripción textual de la ruta:")
    
    # Lo recibido en el XML de la EMT muestra un "Desde  caminar" que queda incompleto al principio y un "caminar hasta" también
    # incompleto, al final, lo cual difiere de la presentación sugerida en el guión, así que truncamos la información
    # recibida para que tenga una buena presentación
    description = ""
    for nodo in root.iter("RouteDescription"):
        description = description + "\n" + nodo.text
        
    tam = len(description)
    description = description[8:tam - 7] # Truncamos la info para que tenga una buena presentación
    print(description)
    print("\n")
    f.close()


# [1 punto]Crear una función que solicite al usuarios los nombres de 2 calles de Madrid y muestre la
# información referente a la ruta más óptima para llegar de una calle a otra usando autobuses de la EMT.

def infoRutaOptima ():
    
    calles = pideRuta() # calles es tupla origen-destino
    
    coordenadasOrigen = devuelveCoordenadas(calles[0][0], calles[0][1])
    coordenadasDestino = devuelveCoordenadas(calles[1][0], calles[1][1])
    
    calculaRutaOptima(coordenadasOrigen, coordenadasDestino)



# [2 puntos]Crear una función que solicite al usuarios los nombres de 2 calles de Madrid y muestre un
# listado de todos los puntos de interés que hay dentro de la ruta más óptima para llegar de una calle a
# otra usando autobuses de la EMT. A continuación, se le pedirá al usuario que introduzca el nombre de uno
# de los puntos de interés mostrado, y como resultado se mostrará por pantalla los siguientes datos del punto
# de interés:
# Nombre del punto de interés.
# Dirección del punto de interés.
# Teléfono del punto de interés.

from xml.etree import ElementTree

def puntosInteres():

    calles = pideRuta() # calles es tupla origen-destino

    # Obtener ruta óptima

    coordenadasOrigen = devuelveCoordenadas(calles[0][0], calles[0][1])
    coordenadasDestino = devuelveCoordenadas(calles[1][0], calles[1][1])
    
    calculaRutaOptima(coordenadasOrigen, coordenadasDestino)
    
    # Ahora usamos rutaOptima.xml, que sea ha creado en calculRutaOptima
    f = open("rutaOptima.xml","rt")
    arbol = ElementTree.parse(f)
    root = arbol.getroot()
    print("\nPuntos de interés en la ruta seleccionada:\n")
    for nodo in root.iter("POI"):
        elem = nodo.find("nombre").text
        elem = elem.strip()
        if elem != "" and elem != '\n': # Para evitar elementos vacíos y saltos de línea
            print(elem)
    
    encontrado = False
    
    while not encontrado:
        punto = input("\nIntroduzca el punto de interés deseado: ")
        punto = punto.upper()

        for nodo in root.iter("POI"):
            if str(nodo.find("nombre").text) == str(punto):
                encontrado = True
                print("\n")
                print(nodo.find("nombre").text)
                print(nodo.find("direccion").text)
                print(nodo.find("telefono").text)
                
        if not encontrado:
            print("Introduzca un punto de interés válido")
        
    f.close()

infoRutaOptima()


puntosInteres()<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup