I'm relatively new to the GIS field. I have several polylines (streets) and would like to locate stations on these lines. The start and end points of the lines, the length of the line and the distance of the stations from the starting point are given. I'm looking for the coordinates for the stations. With GRASS and PostGIS there are probably possibilities. Does anyone have good explanations?
1 Answers
In QGIS Built-in functions (I think since the 3.0 version), it is a function for do what you want :
fonction line_interpolate_point
Returns the point interpolated by a specified distance along a linestring geometry.
Syntax
line_interpolate_point(geometry, distance)
Arguments
geometry : a linestring geometry
distance : distance along line to interpolate
Examples
geom_to_wkt(line_interpolate_point(geometry:=geom_from_wkt('LineString(0 0, 10 0)'),distance:=5)) → 'Point (5 0)'
In your case, add two real fields (one for x_coords, and one for y_coords) to the line layer, go to the field Calculator and for update the x_coord field with :
x(line_interpolate_point($geometry, "station_distance_field"))
and y_coord field :
y(line_interpolate_point($geometry, "station_distance_field"))
With PostGIS, I think the result can be found with the function ST_LineInterpolatePoint.
The first argument is a line / polyline geometry and the second one, the fraction of total linestring length from the start point. If you have the distance of the station and the length of the line (cf. ST_Length), you can have the second argument.
EDIT
Based on your comment, and for example, open a python console and run in the editor the following code, creating a memory line layer with 3 features :
vl = QgsVectorLayer("linestring?crs=EPSG:3044\
&field=route_name:string(50)\
&field=length:integer\
&field=Startingpoint:string(70)\
&field=Endpoint:string(70)\
&field=Distance:int8",
"line_layer",
"memory")
pr = vl.dataProvider()
ft = QgsFeature()
ft.setGeometry(QgsGeometry.fromWkt("LineString (753979 5779912, 729900 5699907, 687178 5651749, 675527 5640874)"))
ft.setAttributes(['route_1', 163829, '', '', 50])
pr.addFeatures([ft])
ft.setGeometry(QgsGeometry.fromWkt("LineString (450270 5842052, 519401 5861471, 641350 5824964, 651448 5802438, 650671 5741075, 583871 5657186, 447940 5664177)"))
ft.setAttributes(['route_2', 528657,'', '', 100])
pr.addFeatures([ft])
ft.setGeometry(QgsGeometry.fromWkt("LineString (416093 5581065, 541927 5580288, 598629 5535237, 622708 5466106, 632029 5428822, 693392 5395422, 725239 5400083)"))
ft.setAttributes(['route_3', 412041, '', '', 200])
pr.addFeatures([ft])
vl.commitChanges()
QgsProject.instance().addMapLayer(vl)
- 15,695
- 1
- 29
- 64
-
The direction seems to be right. Unfortunately, no value is generated. My distance field is defined as real. Is that correct? Would I have to add a starting point to the function? – hugo Jan 31 '19 at 08:58
-
Have you replaced, in the proposal code, the "station_distance_field" by your distance field ? What's the projection (CRS) of the line layer and what's the units of the real values of the station distance ? – J. Monticolo Jan 31 '19 at 09:07
-
The projection is EPSG:3044 - ETRS89 / ETRS-TM32 and the units are meters. Structure of the table is the following: Field 1 = name of the route (string); Field 2 = length (integer); Field 3 = Startingpoint (String); Field 4 = Endpoint (String); Field 5 = Distance (Integer64) – hugo Jan 31 '19 at 09:18
-
Can you test the code I've added in the post and tell if the functions work ? I use
x(line_interpolate_point($geometry, "Distance"))and it's work perfectly. – J. Monticolo Jan 31 '19 at 09:57 -
It does not work. execfile(u'c:/users/schrei~1/appdata/local/temp/tmp2vtycu.py'.encode('mbcs')) Traceback (most recent call last): File "", line 1, in
File "c:/users/schrei~1/appdata/local/temp/tmp2vtycu.py", line 27, in – hugo Jan 31 '19 at 10:06QgsProject.instance().addMapLayer(vl) AttributeError: 'QgsProject' object has no attribute 'addMapLayer' -
-
I've forgot a question : what's the QGIS version used ? I test it on version 3.4 . – J. Monticolo Jan 31 '19 at 10:08
-
Now i used 3.0. There it works! Now i have 3 lines with different distances – hugo Jan 31 '19 at 10:11
-
Unfortunately, the field calculator does not work here either. Syntax is correct, but always comes null. – hugo Jan 31 '19 at 10:19
-
I don't understand, with the memory vector layer, I create
x_coordsfield with real type and update it with the formula, and it gives me results. – J. Monticolo Jan 31 '19 at 10:48 -