| | |
| | |
| | import sys |
| | import os |
| | from qgis.analysis import QgsGraphBuilder |
| | from qgis.analysis import QgsGraphAnalyzer |
| |
|
| | from qgis.core import ( |
| | QgsApplication, |
| | QgsWkbTypes, |
| | QgsProject, |
| | QgsVectorLayer, |
| | QgsFeature, |
| | QgsGeometry, |
| | QgsPointXY, |
| | QgsPoint, |
| | QgsFields, |
| | QgsField, |
| | QgsVectorFileWriter |
| | ) |
| |
|
| | from qgis.PyQt.QtCore import QVariant |
| |
|
| | |
| | |
| | |
| | QGIS_PREFIX_PATH = "/usr" |
| | QGIS_PLUGIN_PATH = "/usr/lib/qgis/plugins" |
| |
|
| | qgs = QgsApplication([], False) |
| | qgs.setPrefixPath(QGIS_PREFIX_PATH, True) |
| | qgs.initQgis() |
| |
|
| |
|
| | layer = QgsVectorLayer("phl_roads_lines.gpkg", "roads", "ogr") |
| |
|
| | |
| |
|
| | |
| | start_point = QgsPointXY(121.0365, 14.6760) |
| | end_point = QgsPointXY(121.0000, 14.5550) |
| |
|
| | tolerance = 0.001 |
| | builder = QgsGraphBuilder(layer.sourceCrs()) |
| |
|
| | points = [start_point, end_point] |
| |
|
| | graph = builder.graph() |
| |
|
| | |
| | for feature in layer.getFeatures(): |
| | geom = feature.geometry() |
| | if geom.isMultipart(): |
| | lines = geom.asMultiPolyline() |
| | else: |
| | lines = [geom.asPolyline()] |
| | for line in lines: |
| | for i in range(len(line) - 1): |
| | |
| | p1 = QgsPointXY(line[i].x(), line[i].y()) |
| | p2 = QgsPointXY(line[i + 1].x(), line[i + 1].y()) |
| |
|
| | builder.addVertex(-1, p1) |
| | builder.addVertex(-1, p2) |
| |
|
| | id1 = builder.graph().findVertex(p1) |
| | id2 = builder.graph().findVertex(p2) |
| |
|
| | distance = p1.distance(p2) |
| |
|
| | builder.addEdge(id1, p1, id2, p2, [distance]) |
| |
|
| | graph = builder.graph() |
| |
|
| |
|
| | |
| | start_idx = graph.findVertex(start_point) |
| | end_idx = graph.findVertex(end_point) |
| |
|
| | |
| | |
| | tree, cost = QgsGraphAnalyzer.dijkstra(graph, start_idx, 0) |
| |
|
| | |
| | if cost[end_idx] == float('inf'): |
| | print("No Path Found") |
| | sys.exit(1) |
| |
|
| | |
| | route = [] |
| | cur_pos = end_idx |
| | while cur_pos != start_idx: |
| | incoming_edge = tree[cur_pos] |
| | if incoming_edge == -1: |
| | print("No Route!") |
| | sys.exit(1) |
| | |
| | |
| | from_vertex = graph.edge(incoming_edge).fromVertex() |
| | point = graph.vertex(from_vertex).point() |
| | route.append(point) |
| |
|
| | |
| | cur_pos = from_vertex |
| |
|
| | |
| | route.append(start_point) |
| | route.reverse() |
| |
|
| | |
| | fields = QgsFields() |
| | fields.append(QgsField("id", QVariant.Int)) |
| |
|
| | |
| | output_path = "shortest_path.gpkg" |
| |
|
| | |
| | output_layer = QgsVectorFileWriter.create( |
| | output_path, |
| | fields, |
| | QgsWkbTypes.LineString, |
| | layer.sourceCrs(), |
| | "GPKG" |
| | ) |
| |
|
| | |
| | feat = QgsFeature() |
| | feat.setFields(fields) |
| | feat.setAttribute("id", 1) |
| | feat.setGeometry(QgsGeometry.fromPolylineXY(route)) |
| |
|
| | |
| | output_layer.addFeature(feat) |
| |
|
| | |
| | del output_layer |
| |
|
| | print(f"✅ Shortest path successfully saved to: {output_path}") |
| |
|
| | |
| | qgs.exitQgis() |
| |
|