10

I have a Polygon which I want to convert to centerline linestring.

Polygon IMAGE 1

I used the Vector to convert to Polyline but they are not center line as under:

VECTOR TOOL

enter image description here

IMAGE 2

Polyline created by the above tool is not centerline polyline.

enter image description here IMAGE 3

What I am expecting to get is as under (centerline per road, instead of the lines on the side of the road[Image 3]):

enter image description here

IMAGE 4

21
  • See this post: gis.stackexchange.com/questions/33887/…
    – Cushen
    Jul 27, 2018 at 0:47
  • I tried those options but it didnt work. The model implemented by underdark. Also didnt work, it returned empty shape file.
    – Duffer
    Jul 27, 2018 at 1:22
  • OpenJUMP has a skeletonizer plugin.
    – user30184
    Jul 27, 2018 at 3:55
  • The skeletonizer plugin in OpenJUMP needs me to add an input PointSHape Filealong with the Polygon. Hence I cant use it. I need something similar to pro.arcgis.com/en/pro-app/tool-reference/topographic-production/…
    – Duffer
    Jul 27, 2018 at 4:39
  • 2
    If you want to stay in QGIS environment, try HCMGIS plugin. (Geometry processing | Skeleton / Medial Axis).. it requires QGIS3.0+ though.
    – Kazuhito
    Jul 27, 2018 at 14:23

5 Answers 5

9

Answer: You can.

I found time for you and hurry to help you. My answer is now practical.

The original data and table names are fictitious, do not forget to rename them with reference to your example.

Sit in my car and go together to the stop - the "center line of the road."

The initial geodata are polygons of a road network with a width of about 11 m in the EPSG: 4326 coordinate system, broken into segments, see Fig. 1.

enter image description here

  1. In a convenient way for you, create a negative buffer, for example in pgAdmin:

create table buf_negative as SELECT ST_Buffer (geom, -0.000045) as geom FROM buf_dump; or in QGIS tools: "Vector-Geoprocessing-Buffer Zones". Thus, we reduced the width of the roads from 11 m to 1 m, see Fig.2

enter image description here

  1. Convert the negative buffer (1 m) into lines, for example with QGIS tools: "Vector-Processing geometry-polygons in a line" result see Fig. 3

enter image description here

  1. Extract from the lines of the point, for example with the QGIS tools: "Vector-Processing geometry-Extract nodes", the result see Fig. 4

enter image description here

  1. Create point buffers from them, so that they intersect each other, Further combine them with each other using the tool "Vector>Geoprocessing>Merge" and extract centroids from adjacent buffers, the result is shown in Fig. 5 (centroids are red dots)

enter image description here

  1. From the centroid points, create the Delaunay Triangulation, for example with the QGIS tools: "Vector-Processing geometry-Delaunay triangulation", and trim the result with your 1 m negative buffer polygons, see the result of Fig. 6

enter image description here

  1. Blast the lines into segments, for example, using QGIS Desktop with GRASS tools: "Data Analysis - Lines-Explode Lines", see Fig. 7

enter image description here

  1. Run the following script in PGAdmin:

create table buf_centre_ln as SELECT ST_Intersection (a.geom, b.geom) AS geom FROM explode_ln as a JOIN buf_negative as b ON ST_Within (a.geom, b.geom);

see the result in Fig. 8

enter image description here

  1. Remove duplicating lines and do with the center lines, whatever,
0
2

The library pygeoops also has an implementation to calculate a centerline of a polygon: pygeoops.centerline. It also removes short branches, simplifies the result,... to get a "clean" result.

Sample script:

import pygeoops
import shapely

polygon = shapely.from_wkt("POLYGON ((0 0, 0 8, -2 10, 4 10, 2 8, 2 2, 10 2, 10 0, 0 0))")
centerline = pygeoops.centerline(polygon)

Result:

enter image description here

Disclaimer: I'm the developer of pygeoops

1

It is possible to achieve it, on PostgresGis, with one of the options of the free tool "geom8tricks" With the "PolygonsToLines" option, once you select the origin polygons and the destination Database connection has been correctly configured, you get the line objects, centered on the polygons . The program does it in two stages, in a first one it obtains the decomposition of the polygon in lines, by means of st_skeleton function

In a second stage, the longest line of all those that make up the object is selected Select the longest line

The problem of intersections is solved whenever there is a primary key column in the origin polygons, which allows to distinguish between the objects that intersect Line Intersection

2
0

I looked for the Geom8tricks suggestion above and found this link which seems to also include the PolygonToLines feature. I haven't used it myself.

For anyone still looking for this I think he's referring to http://geom8tricks.com/index_ml.html?lang=en

2
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Vince
    Feb 23, 2023 at 23:11
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Babel
    Feb 23, 2023 at 23:15
0

There is a python library centerline 1.0.1.

https://centerline.readthedocs.io/en/latest/

https://github.com/fitodic/centerline/issues

On github for the lib centerline (issues) user Turtle6665 proposed an alternative solution for shapely 2.0 and geopandas.

import shapely
import geopandas as gpd

def construct_centerline(input_geometry, interpolation_distance=0.5):
   #find the voronoi verticies (equivalent to Centerline._get_voronoi_vertices_and_ridges())
   borders = input_geometry.segmentize(interpolation_distance) #To have smaler verticies (equivalent to Centerline._get_densified_borders())
   voronoied = shapely.voronoi_polygons(borders,only_edges=True) #equivalent to the scipy.spatial.Voronoi
   
   #to select only the linestring within the input geometry (equivalent to Centerline._linestring_is_within_input_geometry)
   centerlines = gpd.GeoDataFrame(geometry=gpd.GeoSeries(voronoied.geoms)).sjoin(gpd.GeoDataFrame(geometry=gpd.GeoSeries(input_geometry)),predicate="within")
   return centerlines.unary_union

centerlines = construct_centerline(open_area_Road[0],interpolation_distance=0.5)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.