ungarj / label_centerlines Goto Github PK
View Code? Open in Web Editor NEWpython tool to extract smoothed centerlines from polygons
License: MIT License
python tool to extract smoothed centerlines from polygons
License: MIT License
Currently, the "best path" (a mixture of length and angle sum) is determined by converting the voronoi diagram to a networkx graph. Then, every possible path within this graph is analyzed.
This step takes the most time when generating the centerline. It depends on the number of points generated after segmentation and can easily take up to several minutes for larger polygons.
I will try to use this tool to semi automatically generate centerlines for riverbanks which have none. The problem is that it's only finding centerlines for segments that are wide enough, and it seems that there's no way to control the minimum width. I'm proficient in Python, but I know nothing about these types of algorithms, so if you could at least point me in the right direction, I could probably send a PR.
Python 3.6.5
Fiona==1.8a1
networkx==1.11
scipy==0.19.1
Shapely==1.6.1
g is a Shapely Polygon.
>>> get_centerline(g)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-31-9094808c574c> in <module>()
----> 1 get_centerline(g)
~/.local/lib/python3.6/site-packages/label_centerlines-0.1-py3.6.egg/label_centerlines/_src.py in get_centerline(geom, segmentize_maxlen, max_points, simplification, smooth_sigma)
78 raise CenterlineError("Polygon has too few points")
79 logger.debug("get longest path from %s end nodes", len(end_nodes))
---> 80 longest_paths = _get_longest_paths(end_nodes, graph)
81 if not longest_paths:
82 logger.debug("no paths found between end nodes")
~/.local/lib/python3.6/site-packages/label_centerlines-0.1-py3.6.egg/label_centerlines/_src.py in _get_longest_paths(nodes, graph, maxnum)
165 continue
166 return [
--> 167 x for (y, x) in sorted(_gen_paths_distances(), reverse=True)
168 ][:maxnum]
169
TypeError: '<' not supported between instances of 'dict' and 'dict'
Same error occurs if I try the CLI tool with ne_110m_land.shp
.
Thank you very much.
At first, my goal is to do an automatic calculation of the length of the glacier.
I was amazed when I saw your code on gihub and it inspired me.
So thank you.
I want to end with a question.
In the looking for the path step, whether it can be based on both the distance weight and the altitude value.
Thus, the path with the shortest cutting distance from low altitude to high altitude is obtained?
This label_centerlines is realy a very good project. However, I wonder whether it can provide the center lines from a 3D binary mask?
In addition, currently, I use the skimage.measure.skeleton to obtain the skeletion, but the skeletion is really not smooth and there are some wrong branches. Thus, could you please explain how to exclude the wrong branch and smooth the center line?
Thank you very much!
For some reason, centerline thinks some of my polygons do not have enough end_nodes when they clearly do looking at the picture. One polygon will work properly and have a nice centerline but another one that looks very similar to it will run into the end_nodes issue. When printing the shapely polygon coordinates, I see that it has multiple points, but a couple of them are very close to one another. Is there a fix for this?
The following error Keeps popping up when tried to installed the "python setup.py install" in anaconda prompt
C:\Users\kshrv>python setup.py install
Traceback (most recent call last):
File "C:\Users\kshrv\setup.py", line 5, in
with open('label_centerlines/init.py') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'label_centerlines/init.py'
Line 48 of your src.py "geom.geom_type".
I know it's about identifying what shape it is.
But it always remind me about AttributeError: 'str' object has no attribute 'geom_type'.
I want to know, what's wrong?
thanks for your project, How do I convert a point on an edge of 255 in a binary image to a data type in this project
Thanks for a great project!
I've been trying it out for creating road centre lines from polygons. One issue I've run into is I had to always use the longest path, rather than select the smoothest from the top 5 longest.
With the top 5 I only get a short section (pink lines are the Voronoi lines, grey/blue line the output centre line):
When selecting just the longest (with _get_longest_paths(nodes, graph, maxnum=1)
I get the full line:
Polygon WKT is:
POLYGON ((518523.664 730722.779, 518519.335 730721.311, 518515.476 730720.002, 518517.91 730718.394, 518517.63 730711.824, 518519.123 730703.743, 518520.338 730689.848, 518516.265 730680.265, 518511.185 730671.948, 518498.973 730657.294, 518505.454 730646.656, 518506.612 730644.308, 518507.298 730642.9179999999, 518509.05 730645.093, 518510.342 730646.697, 518508.092 730653.775, 518509.626 730659.326, 518521.801 730674.1850000001, 518529.156 730683, 518527.916 730689.823, 518527.416 730691.5919999999, 518526.166 730695.384, 518525.914 730697.615, 518524.193 730709.558, 518524.231 730710.348, 518523.529 730715.078, 518522.777 730719.711, 518522.996 730721.355, 518523.664 730722.779))
I used the following settings:
get_centerline(poly, segmentize_maxlen=0.5, max_points=3000, simplification=0.05, smooth_sigma=1)
I can create a pull request if you think adding a maxpaths
property is appropriate.
Hi ungarj or anyone who may be able to point me in the right direction
I am trying to make a lake centerlines geojson file similar to the osm-lakelines project, which looks like it uses the older create_centerlines.py to make this geojson file https://github.com/lukasmartinelli/osm-lakelines/releases/download/v0.9/lake_centerline.geojson
Pulling the steps from the docker images there it seems these would be the steps
1.) Import the lake geometry into postgresql using imposm
2.) Export the geometry from postgresql into a shape file using pgsql2shp
3.) Calculate the centerlines using label_centerlines
I made did the following in bash to generate the file
( https://github.com/acalcutt/osm-lakelines/ )
imposm import -connection "$PG_CONNECT" -mapping "$MAPPING_YAML" -overwritecache -cachedir "$IMPOSM3_CACHE_DIR" -read "$FULL_PBF" -dbschema-import="$DB_SCHEMA" -write
query="SELECT osm_id, ST_SimplifyPreserveTopology(geometry, 100) AS geometry FROM osm_lake_polygon WHERE area > 2 * 1000 * 1000 AND ST_GeometryType(geometry)='ST_Polygon' AND name <> '' ORDER BY area DESC"
pgsql2shp -f "$CENTERLINES_SHP" -h "$POSTGRES_HOST" -u "$POSTGRES_USER" -P "$POSTGRES_PASS" "$POSTGRES_DB" "$query"
label_centerlines --output_driver GeoJSON "$CENTERLINES_SHP" "$CENTERLINES_GEOJSON"
This all seemed to work, but ogr2ogr will not load the resulting file.
ogr2ogr -progress -f Postgresql -s_srs EPSG:4326 -t_srs EPSG:3857 "PG:dbname=osm user=postgres host=localhost password=pgpassword port=5432" -lco OVERWRITE=YES -overwrite -nln "lake_centerline" "data/osm_lake_centerline.geojson"
ERROR 1: Failed to reproject feature 0 (geometry probably out of source or destination SRS).
ERROR 1: Terminating translation prematurely after failed
translation of layer osm_lake_centerline (use -skipfailures to skip errors)
When I compare it with the origional file the co-ordinates seem much different. for example
In the old file I see
{ "type": "Feature", "properties": { "OSM_ID": -6343.000000 }, "geometry": { "type": "LineString", "coordinates": [ [ -6.160017741542741, 57.202632052397163 ], [ -6.160017789121379, 57.20263208363577 ], [ -6.160017811116719, 57.202632126970215 ] ] } },
but in the file I made the co-ordinates are much bigger numbers
{ "type": "Feature", "properties": { "OSM_ID": -6343.0 }, "geometry": { "type": "LineString", "coordinates": [ [ -685730.038266069372185, 7801648.177360998466611 ], [ -685730.043562498758547, 7801648.183780899271369 ], [ -685730.046011009137146, 7801648.192686640657485 ] ] } },
I also notice the projections is "urn:ogc:def:crs:OGC:1.3:CRS84" vs "urn:ogc:def:crs:EPSG::3857"
So i guess my question is why the difference in numbers? am I exporting the shape file incorrectly? Is the newer (non .py) version of lake centerlines working differently? Anybody have any tips that may help me finally make this file?
The shape file and geojson I generated are up here if anyone wants to look at them https://github.com/acalcutt/osm-lakelines/releases/tag/v9.1
Thanks for great repo.
I get center_line from function, but when draw it's wrong
import matplotlib.pyplot as plt
import numpy as np
import shapely
from shapely.ops import transform
# from shapely.plotting import plot_polygon
from shapely.geometry import shape
from centerline.geometry import Centerline
from shapely.geometry import Polygon, Point, LineString, MultiPoint
import numpy as np
from shapely.plotting import plot_polygon
from centerline_extract import get_centerline
d = { "type": "Feature", "properties": { "OBJECTID": 6.0, "SHAPE_Leng": 0.0018435614763720001, "SHAPE_Area": 1.830693e-08, "name": None, "rongMax": None, "rongMin": None, "rongTB": None }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 105.814233473000058, 21.009605263000026 ], [ 105.814270254000064, 21.009557108000024 ], [ 105.814294123000082, 21.009508220000043 ], [ 105.814310222000074, 21.00947741400006 ], [ 105.814272326000037, 21.009456668000041 ], [ 105.814212241000064, 21.009415109000031 ], [ 105.81420315400004, 21.00940840100003 ], [ 105.81417328200007, 21.009386347000031 ], [ 105.814165209000066, 21.009398109000074 ], [ 105.814144615000032, 21.009394712000073 ], [ 105.814124802000038, 21.009382587000061 ], [ 105.814117689000057, 21.009392403000049 ], [ 105.814070315000038, 21.009362398000064 ], [ 105.814035767000064, 21.00933989300006 ], [ 105.81399544900006, 21.009314226000072 ], [ 105.813992317000043, 21.00931666200006 ], [ 105.813938111000084, 21.009278877000042 ], [ 105.813956262000033, 21.009253924000063 ], [ 105.813898282000082, 21.009273615000041 ], [ 105.813906806000034, 21.009281664000071 ], [ 105.813926242000036, 21.009296736000067 ], [ 105.813930008000057, 21.009292257000027 ], [ 105.814022481000052, 21.009355528000071 ], [ 105.814091046000044, 21.009398283000053 ], [ 105.814108600000054, 21.009407042000078 ], [ 105.814147095000067, 21.009413957000049 ], [ 105.814147350000042, 21.009413089000077 ], [ 105.814174914000034, 21.009421213000053 ], [ 105.814174412000057, 21.009422525000048 ], [ 105.814199988000041, 21.009438416000023 ], [ 105.814196086000038, 21.00944436900005 ], [ 105.81427995100006, 21.009495137000044 ], [ 105.81422490500006, 21.009573164000074 ], [ 105.814231047000078, 21.009576607000042 ], [ 105.814197398000033, 21.009632903000067 ], [ 105.814200504000041, 21.009634568000024 ], [ 105.814165204000062, 21.009698650000075 ], [ 105.814130529000067, 21.009681203000071 ], [ 105.814110726000081, 21.009670929000038 ], [ 105.814077452000049, 21.00965476600004 ], [ 105.814043983000033, 21.009639770000035 ], [ 105.814037492000068, 21.009636667000052 ], [ 105.814028830000041, 21.009653373000049 ], [ 105.814056730000061, 21.009666333000041 ], [ 105.814085146000082, 21.009679532000064 ], [ 105.814120301000059, 21.009698368000045 ], [ 105.814155253000081, 21.009715444000051 ], [ 105.81417351500005, 21.009716377000075 ], [ 105.814180653000051, 21.009702379000032 ], [ 105.814231116000087, 21.009606946000076 ], [ 105.814233473000058, 21.009605263000026 ] ] ] ] } }
geom = shape(d['geometry'])
coord_ori = d["geometry"]['coordinates']
coord_ori = np.array(coord_ori)
coord_ori = coord_ori.reshape((51,2))
# print(coord.shape)
length = coord_ori.shape[0]
coord = coord_ori[:length-1]
polygon = Polygon(coord_ori)
center_line = get_centerline(geom=polygon)
print(center_line)
plt.plot(*center_line.xy,'ro', label='Point')
plot_polygon(geom)
plt.show()
I've got the following error:
ImportError: libgfortran.so.4: cannot open shared object file: No such file or directory
After recompiling numpy there is only
ImportError: /usr/lib/python3.6/site-packages/numpy/random/mtrand.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZGVbN2v___log_finite
(related to JohannesBuchner/cuba#1 ?)
--
Sorry for this bug report, it seems related to my distro's numpy installation.
AND what's the data structure for geom???
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.