9 votos

¿Encontrar el camino más corto entre puntos evitando el shapefile?

Soy un desarrollador intermedio de python con una experiencia muy limitada en SIG. Tengo una lista de latitudes/longitudes de un barco en el mar. Necesito unirlas en una polilínea utilizando la distancia más corta entre ellas para trazar la trayectoria seguida por el barco. Sin embargo, el camino no puede pasar por tierra (para lo cual tengo un shapefile). ¿Cómo puedo hacerlo? Utilizo Python 2.7.

Actualmente no utilizo ningún software SIG y espero realizar la tarea utilizando los módulos de python como matplotlib y scipy.

4voto

user55937 Puntos 448

Parece un problema divertido. Yo lo consideraría:

  1. Lea el archivo shp de límites del terreno utilizando una de estas recetas: ¿Cómo instalar Fiona para leer atributos Shapefile con OSGeo4W? . Probablemente sería bueno leerlo en una geometría Shapely. Me gusta usar ogr para leer shapefiles:

    import ogr import shapely driver = ogr.GetDriverByName('ESRI Shapefile') dataSource = driver.Open('landboundary.shp', 0) layer = dataSource.GetLayer() feature = layer[0] # first boundary geom = feature.GetGeometryRef() shapely.geometry.base.geom_from_wkt(geom.ExportToWkt())

  2. Utilice NetworkX para construir una red de todas sus coordenadas lat long ship, pero no conecte coordenadas cuya conexión en línea recta intersecte el límite del terreno. He aquí un ejemplo para resolver la intersección de geometrías: ¿Se cruzan Shapely LineString y Polygon? .

  3. A continuación, calcula la ruta de menor coste utilizando NetworkX con la distancia como coste. El LCP no cruzará por tierra porque esos nodos no están conectados.

Además, para tu información, las geometrías con forma se convierten a WKT (texto conocido, que es un formato basado en texto) de esta manera, myShapelyGeometry.wkt que es muy fácil e intuitivo de analizar y utilizar como se desee.

Edición: Sólo un poco de información adicional: Para calcular la distancia entre dos coords lat long, puede utilizar pyproj:

import pyproj
geod = pyproj.Geod(ellps='WGS84')
_,_,distance = geod.inv(long_start,lat_start,long_end,lat_end)

Además, puede iniciar un gráfico networkx como:

import networkx
graph = networkx.Graph()
graph.add_edge('coord_a', 'coord_b', weight=distance)
# add more edges in the same way
start_node = find_closest_node(graph, lat_start, long_start)
end_node = find_closest_node(graph, lat_end, long_end)
ship_path = networkx.shortest_path(graph, start_node, end_node)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X