3. Coordenadas – GPS a utm y distancias a gateway

Las coordenadas de cada punto donde se ubica un dispositivo se obtienen usando un GPS.

Cada nodo se identifica con tres letras y dos dígitos por ejemplo usando cultivo y numeración ascendente al alejarse del gateway. Por ejemplo, para el cultivo de Cacao , radial «A» desde el gateway y punto en ubicación 04  el identificador de ubicación será CA04.

Las coordenadas se registran obteniendo el archivo kml del equipo GPS y contienen los valores de Latitud y Longitud. Por facilidad de uso y ubicación las coordenadas se usan en formato utm (Universal Transverse Mercator).

El archivo KML contiene los datos de los puntos, básicamente en el siguiente formato:

<Placemark>
        <name>CA04
        <styleUrl>#msn_pink-diamond</styleUrl>
        <Point>
                <coordinates>-79.96257337394334,
                             -2.139534989113919,
                             65.76000000000001</coordinates>
        </Point>
</Placemark>

Se adjunta un ejemplo del archivo para pruebas.

Granja2021_LOS.kml

El objetivo es generar un archivo con distancias al gateway y alturas del perfil del terreno semejante al ejemplo mostrado:

       altitud  altitud_gps  dist_Gw03   latitud   longitud  utm_este  utm_norte utm_zLetra utm_zNum
punto                                                                                               
Gw03      65.0        68.30       0.00 -2.140439 -79.962474  615377.0  9763377.0          M       17
LOS01     64.0        66.16      24.74 -2.140222 -79.962528  615371.0  9763401.0          M       17
LOS02     59.0        66.16      75.93 -2.139770 -79.962627  615360.0  9763451.0          M       17
LOS03     58.0        66.16      99.64 -2.139553 -79.962636  615359.0  9763475.0          M       17
LOS04     58.0        66.06     126.44 -2.139309 -79.962645  615358.0  9763502.0          M       17
...

En cada punto, la altitud_gps se puede mejorar usando el perfil del terreno desde google earth. Las instrucciones se muestran más adelante en «Perfil de alturas de terreno».

Coordenadas en utm

Para la conversión a utm, se usa la librería en Python con el mismo nombre. En caso de no disponer de la librería, puede ser instalada con la instrucción pip desde una ventana de comandos:

pip install utm

con lo que es posible hacer las conversiones a UTM desde latitud y longitud y viceversa.

Las coordenadas en formato UTM para el ejemplo dado, se encuentran ubicadas en la zona «17 M». Revisar para cada caso la zona

Perfil de alturas de terreno

Los datos de alturas del gps usado presentan variaciones irregulares de altura, por lo que para mejores valores se usa el perfil desde google earth usando las marcas de las coordenadas del archivo.kml

Para visualizar el perfil se agrega una línea como una «ruta» entre el punto del Gateway (Gw3) y el último punto de observación. Los datos del perfil se pueden observar al seleccionar la ruta y usar la opción de «mostrar perfil de elevación». La opción se obtiene con «click derecho» del mouse. Se tiene adicionalmente como referencia, las distancias desde el gateway obtenidas en el proceso de conversión a utm. Los valores leidos de alturas para cada punto se guardan en un archivo .csv

El archivo obtenido en el ejemplo de alturas se muestra en:

Granja2021_alturas.csv


Instrucciones en Python

El algoritmo integra los resultados de la conversión de coordenadas a utm, incluye las distancias al gateway e integra las alturas obtenidas de forma externa para tener como resultado el archivo.csv.

Granja2021_LOS.csv

Una revisión para generar el archivo es evitar sobreescribir un archivo anterior. Por lo que si se requiere procesar nuevamente los datos se pide borrar el archivo anterior antes de ejecutar el algoritmo.

El algoritmo se divide en procesos identificados por un número ascendente. La variable ‘procesoCompletado‘ permite dar indicaciones de avances en el algoritmo en caso que se produzcan errores como haber escrito el nombre del archivo de datos con errores, que el nombre del gateway debe empezar con «Gw», etc.

# Procesa puntos de coordenadas, a utm
# girni-fiec-espol Revision:20220724
# http://blog.espol.edu.ec/girni/ 

import geopandas as gpd
import fiona
import utm
import numpy as np
import pandas as pd
import os

# INGRESO
archivokml  = 'Granja2021_LOS.kml' 
carp_coord  = 'Coordenadas'

# archivo de alturas tomadas de google
arch_altura = 'Granja2021_alturas.csv'

# zona UTM
zonaNum   = 17
zonaLetra = 'M'

precision = 2

# PROCEDIMIENTO
procesoCompleto = 0

# Lectura de archivo .KML
if len(carp_coord)>0:
    carp_coord = carp_coord+'/'
archivo_ruta = carp_coord+archivokml
if os.path.exists(archivo_ruta):
    gpd.io.file.fiona.drvsupport.supported_drivers['KML'] = 'rw'
    puntos = gpd.read_file(archivo_ruta, driver='KML')
    puntos = puntos.sort_values(by=['Name'])
    
    procesoCompleto = 1

if procesoCompleto == 1:
    # tabla en UTM
    tabla = pd.DataFrame()
    n_Gw = '';
    for i in puntos.index:
        # en latitud, longitud y altura
        punto_nombre = puntos.loc[i]['Name']
        longitud = puntos.loc[i]['geometry'].x
        latitud  = puntos.loc[i]['geometry'].y
        altitud  = puntos.loc[i]['geometry'].z
        altitud  = np.round(altitud,precision)
        #convierte lat_lon en UTM
        coord_utm = utm.from_latlon(latitud,longitud,
                                    zonaNum,zonaLetra)
        utm_este  = np.round(coord_utm[0],precision)
        utm_norte = np.round(coord_utm[1],precision)
        if punto_nombre.startswith('Gw'):
            n_Gw = punto_nombre
            x1 = utm_este
            y1 = utm_norte
                # añade coordenadas UTM a tabla
        tabla.at[i,'punto']      = punto_nombre
        tabla.at[i,'utm_este']   = utm_este
        tabla.at[i,'utm_norte']  = utm_norte
        tabla.at[i,'utm_zNum']   = str(zonaNum)
        tabla.at[i,'utm_zLetra'] = zonaLetra
        tabla.at[i,'altitud']    = 0
        tabla.at[i,'altitud_gps']= altitud
        tabla.at[i,'latitud']    = latitud
        tabla.at[i,'longitud']   = longitud
    procesoCompleto = 2

if procesoCompleto==2:
    # gateway encontrado
    if len(n_Gw)>0:
        procesoCompleto = 3

if procesoCompleto == 3:
    # distancias a Gateways
    for i in puntos.index:
        dist = 0.0
        x2 = tabla.at[i,'utm_este']
        y2 = tabla.at[i,'utm_norte']
        dist = np.sqrt((x2-x1)**2 + (y2-y1)**2)
        dist = np.round(dist,precision)
        tabla.at[i,'dist_'+n_Gw] = dist

    # indice por nombre de punto
    tabla = tabla.set_index('punto')
    # ordena por indice
    tabla = tabla.sort_index(axis=1)

    procesoCompleto = 4

if procesoCompleto == 4:
    # añade alturas desde archivo
    if len(arch_altura)>0:
        arch_rutaA = carp_coord + arch_altura
        if os.path.exists(arch_rutaA):
            tablaAltura = pd.read_csv(arch_rutaA)
            tablaAltura = tablaAltura.set_index('punto')
            for cadapunto in tabla.index:
                if cadapunto in tablaAltura.index:
                    encontrada = tablaAltura.loc[cadapunto]['altitud']
                    tabla.at[cadapunto,'altitud'] = encontrada

            procesoCompleto = 5
        
# Para escritura de archivo
archivocsv   = archivokml.split('.')[0] + '.csv'
archivo_ruta = carp_coord+archivocsv

# SALIDA
if procesoCompleto == 5:
    print(tabla)
    # Escribe archivo: tabla de resultados
    if os.path.exists(archivo_ruta):
        print('El archivo existe: ',archivo_ruta)
        print('Esta acción borraría el archivo último actualizado')
        print('Puede borrarlo manualmente antes de reintentar')
    else:
        tabla.to_csv(archivo_ruta)
else:
    print('proceso completado hasta:', procesoCompleto)
    print('Revisar errores en proceso:', procesoCompleto+1)
    print('   Procesos:')
    print('1: abrir archivo .KML',archivokml)
    print('2: crear tabla de datos')
    print('3: encontrar gateway:', n_Gw)
    print('4: calcula distancia cada punto a gateway')
    print('5: añadir alturas desde archivo: ', arch_rutaA)

Referencia: Bidirectional UTM-WGS84 converter for python. https://pypi.org/project/utm/0.4.2/