- Home
- Geospatialblog
- Distance Along route in PyQGIS
Distance Along route in PyQGIS
Published Date: Sept. 26, 2024, 4:57 a.m. || Abin Prajapti 61 views

from qgis.core import (
QgsProject,
QgsPointXY,
QgsPoint,
QgsGeometry,
QgsFeature,
QgsVectorLayer,
QgsWkbTypes,
QgsDistanceArea
)
def get_start_end_points(layer, sn_value):
start_point = None
end_point = None
# Filter the layer to select features with the specified sn_value
layer.setSubsetString(f'"sn" = {sn_value}')
for feature in layer.getFeatures():
geom = feature.geometry()
if geom.isEmpty():
continue
geom_type = geom.wkbType()
if geom_type == QgsWkbTypes.LineString:
points = geom.asPolyline()
if points:
start_point = QgsPointXY(points[0])
end_point = QgsPointXY(points[-1])
elif geom_type == QgsWkbTypes.MultiLineString:
lines = geom.asMultiPolyline()
if lines:
start_point = QgsPointXY(lines[0][0])
end_point = QgsPointXY(lines[-1][-1])
elif geom_type == QgsWkbTypes.Polygon:
rings = geom.asPolygon()
if rings and rings[0]:
start_point = QgsPointXY(rings[0][0])
end_point = QgsPointXY(rings[0][-1])
if start_point is None or end_point is None:
print("Error: Could not determine start or end points.")
return None, None
return start_point, end_point
def calculate_distance_along_route(layer, sn_value):
start_point, end_point = get_start_end_points(layer, sn_value)
if start_point is None or end_point is None:
return 0
distance_calculator = QgsDistanceArea()
total_distance = 0
# Filter the layer to select features with the specified sn_value
layer.setSubsetString(f'"sn" = {sn_value}')
for feature in layer.getFeatures():
geom = feature.geometry()
if geom.isEmpty():
continue
geom_type = geom.wkbType()
if geom_type == QgsWkbTypes.LineString:
points = geom.asPolyline()
if points:
try:
start_index = points.index(QgsPoint(start_point))
end_index = points.index(QgsPoint(end_point))
except ValueError:
print("Start or End point not found in the polyline.")
return 0
if start_index <= end_index:
# Convert points to QgsPointXY
segment = [QgsPointXY(p) for p in points[start_index:end_index+1]]
total_distance = distance_calculator.measureLine(segment)
else:
print("Start point is after the end point in the polyline.")
return 0
elif geom_type == QgsWkbTypes.MultiLineString:
lines = geom.asMultiPolyline()
found_start = False
for line in lines:
if found_start:
total_distance += distance_calculator.measureLine([QgsPointXY(p) for p in line])
if end_point in line:
end_index = line.index(QgsPointXY(end_point))
segment = [QgsPointXY(p) for p in line[:end_index+1]]
total_distance += distance_calculator.measureLine(segment)
break
else:
if start_point in line:
start_index = line.index(QgsPointXY(start_point))
segment = [QgsPointXY(p) for p in line[start_index:]]
total_distance += distance_calculator.measureLine(segment)
found_start = True
elif geom_type == QgsWkbTypes.Polygon:
# Handle polygon distances if needed
pass
return total_distance
# Load the road layer using the file path
layer_path = 'E:/Personal File/abin/pyqgis/data/BLOCK/road_sample.shp'
road_layer = QgsVectorLayer(layer_path, 'road_sample', 'ogr')
if not road_layer.isValid():
print(f"Failed to load the road layer from: {layer_path}")
else:
QgsProject.instance().addMapLayer(road_layer)
# Define the sn_value to select
sn_value = 1
# Calculate the distance along the route
distance = calculate_distance_along_route(road_layer, sn_value)
print(f"Distance along the route: {distance:.2f} meters")