Suite

Trouver le chemin le plus court entre les points en évitant le fichier de formes ?


Je suis un développeur python intermédiaire avec une expérience SIG très limitée. J'ai une liste de latitude/longitude d'un navire en mer. Je dois les joindre en une polyligne en utilisant la distance la plus courte entre eux pour tracer le chemin suivi par le navire. Cependant, le chemin ne peut pas passer par la terre (pour lequel j'ai un shapefile). Comment puis-je faire ceci? J'utilise Python 2.7.

Je n'utilise actuellement aucun logiciel SIG et j'espère faire la tâche en utilisant les modules python comme matplotlib et scipy.


Cela ressemble à un problème amusant. je considérerais :

  1. Lisez le fichier shp des limites terrestres en utilisant l'une de ces recettes : Comment installer Fiona pour lire les attributs Shapefile avec OSGeo4W ?. Il serait probablement bon de le lire dans une géométrie Shapely. J'aime utiliser ogr pour lire les fichiers de formes :
import ogr import shapely driver = ogr.GetDriverByName('ESRI Shapefile') dataSource = driver.Open('landboundary.shp', 0) layer = dataSource.GetLayer() feature = layer[0] # first border geom = feature.GetGeometryRef () shapely.geometry.base.geom_from_wkt(geom.ExportToWkt())
  1. Utilisez NetworkX pour créer un réseau de toutes les coordonnées de votre navire lat long, mais ne connectez pas les coordonnées dont la connexion en ligne droite coupe la frontière terrestre. Voici un exemple à résoudre pour l'intersection de géométries : Shapely LineString et Polygon se croisent ?.

  2. Calculez ensuite le chemin le moins coûteux en utilisant NetworkX avec la distance comme coût. Le LCP ne traversera pas la terre parce que ces nœuds ne sont pas connectés.

De plus, juste pour info, les géométries galbées sont converties en WKT (texte bien connu qui est un format basé sur du texte) comme celui-ci,myShapelyGeometry.wkt, qui est très facile et intuitif à analyser et à utiliser comme vous le souhaitez.

Edit : Juste quelques informations supplémentaires : pour calculer la distance entre deux coordonnées lat long, vous pouvez utiliser pyproj :

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

En outre, vous pouvez démarrer un graphe networkx comme :

import networkx graph = networkx.Graph() graph.add_edge('coord_a', 'coord_b', weight=distance) # ajoute plus d'arêtes de la même manière 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)


Voir la vidéo: FloydWarshall algorithm in 4 minutes (Octobre 2021).