fitodic / centerline

Calculate the polygon's centerline
https://centerline.readthedocs.io
MIT License
271 stars 55 forks source link

Question about: Reverse caculate width if have centerlines #40

Closed phamkhactu closed 1 year ago

phamkhactu commented 1 year ago

Hi @fitodic

Thanks for great repo that helping to have centerlines My question is: "if I have centerline, can reverse to caculate width of polygons" Here is pic example image

Have you have ideas?? Thank you very much!

fitodic commented 1 year ago

I'm not sure I fully understand the question, but you could always create a buffer around the centerline's geometry:

centerline = Centerline(...)
area = centerline.geometry.buffer(...)
phamkhactu commented 1 year ago

I'm not sure I fully understand the question, but you could always create a buffer around the centerline's geometry:

centerline = Centerline(...)
area = centerline.geometry.buffer(...)

Yeah, maybe I make you feel confuse. My question is:"how to calculate width polygons?? if I have center line(points)"

fitodic commented 1 year ago

I'm still confused because if you have a centerline, and you want to create a polygon/area around it with a buffer of 1 meter, then the width will be 2 meters in almost every point of the area. In this case, it just depends on the buffer size, nothing more.

If you have a set of points, the creating a centerline doesn't do you much good because you need a different approach. For example (from reddit), you could create perpendicular lines that intersect the polygon, "cut" the lines so you're only left with the intersection of the line and the polygon and calculate the average or median length.

I'll close this issue because it's not related to this project.

phamkhactu commented 1 year ago

I'm still confused because if you have a centerline, and you want to create a polygon/area around it with a buffer of 1 meter, then the width will be 2 meters in almost every point of the area. In this case, it just depends on the buffer size, nothing more.

If you have a set of points, the creating a centerline doesn't do you much good because you need a different approach. For example (from reddit), you could create perpendicular lines that intersect the polygon, "cut" the lines so you're only left with the intersection of the line and the polygon and calculate the average or median length.

I'll close this issue because it's not related to this project.

@fitodic yeah Thank you.

Turtle6665 commented 1 year ago

Hi @phamkhactu,

It might be too late for you, but this is a solution to your problem using geopandas:

If you want to have the distance of the closest edge perpendicular to the centerlines:

import geopandas as gpd
centerline = Centerline(initial_polygon)
centerline_gdf = gpd.GeoDataFrame(geometry=gpd.GeoSeries(centerline.geometry.geoms))
maxWidth = 200 #the maximum expected width. It can be set to a realy high number but it reduces the performances. If the width is actualy bigger than maxWidth, it's set to np.nan
centerline_gdf["Width"] = centerline_gdf.geometry.apply(lambda x: x.distance(x.buffer(maxWidth,cap_style=2, join_style=2).intersection(initial_polygon)))

If you want the distance of the closest edge regardless of the orientation (it's way much faster): Drop the last line and replace it with:

centerline_gdf["Width"] = centerline_gdf.geometry.apply(lambda x: x.distance(initial_polygon))

Have a great day.

phamkhactu commented 1 year ago

Hi @phamkhactu,

It might be too late for you, but this is a solution to your problem using geopandas:

If you want to have the distance of the closest edge perpendicular to the centerlines:

import geopandas as gpd
centerline = Centerline(initial_polygon)
centerline_gdf = gpd.GeoDataFrame(geometry=gpd.GeoSeries(centerline.geometry.geoms))
maxWidth = 200 #the maximum expected width. It can be set to a realy high number but it reduces the performances. If the width is actualy bigger than maxWidth, it's set to np.nan
centerline_gdf["Width"] = centerline_gdf.geometry.apply(lambda x: x.distance(x.buffer(maxWidth,cap_style=2, join_style=2).intersection(initial_polygon)))

If you want the distance of the closest edge regardless of the orientation (it's way much faster): Drop the last line and replace it with:

centerline_gdf["Width"] = centerline_gdf.geometry.apply(lambda x: x.distance(initial_polygon))

Have a great day.

Hi @Turtle6665,

Yeah Thank you very much.