Created
April 25, 2016 16:32
-
-
Save snorfalorpagus/cd62e3fac632a3e648eb382f95f646b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import fiona | |
| from shapely.geometry import shape, mapping, LineString, MultiLineString | |
| from copy import deepcopy | |
| def split_segments(geometry, length): | |
| """Split a LineString into segments | |
| Parameters | |
| ---------- | |
| geometry : shapely geometry | |
| length : float | |
| Returns | |
| ------- | |
| A MultiLineString representing the original geometry split into segments. | |
| Each segment is an individual part of the geometry. | |
| """ | |
| # TODO: 3D distance | |
| # TODO: mulitlinestring input | |
| # TODO: better exceptions | |
| assert(length > 0.0) | |
| coords = list(geometry.coords) | |
| l_cur = 0.0 | |
| x_cur, y_cur = coords[0][0:2] | |
| coords_new = [coords[0]] | |
| lines = [] | |
| for n in range(0, len(coords)-1): | |
| while True: | |
| x_next, y_next = coords[n+1] | |
| if x_cur == x_next and y_cur == y_next: | |
| break | |
| dx = x_next - x_cur | |
| dy = y_next - y_cur | |
| distance = (dx**2 + dy**2)**0.5 | |
| if distance > (length - l_cur): | |
| x_cur += dx * (length - l_cur) / distance | |
| y_cur += dy * (length - l_cur) / distance | |
| coords_new.append((x_cur, y_cur)) | |
| line = LineString(coords_new) | |
| lines.append(line) | |
| coords_new = [(x_cur, y_cur)] | |
| l_cur = 0.0 | |
| else: | |
| x_cur, y_cur = x_next, y_next | |
| l_cur += distance | |
| coords_new.append((x_cur, y_cur)) | |
| line = LineString(coords_new) | |
| lines.append(line) | |
| return MultiLineString(lines) | |
| with fiona.open('D:/tmp/syphons.shp', 'r') as src: | |
| meta = deepcopy(src.meta) | |
| meta['schema']['properties']['id_seg'] = 'int:10' | |
| meta['schema']['properties']['firstX'] = 'float:10.1' | |
| meta['schema']['properties']['firstY'] = 'float:10.1' | |
| meta['schema']['properties']['lastX'] = 'float:10.1' | |
| meta['schema']['properties']['lastY'] = 'float:10.1' | |
| meta['schema']['properties']['length'] = 'float:10.3' | |
| meta['schema']['properties']['chainage'] = 'float:10.3' | |
| with fiona.open('output.shp', 'w', **meta) as dst: | |
| for feature in src: | |
| geometry = shape(feature['geometry']) | |
| count = 0 | |
| assert(isinstance(geometry, LineString)) | |
| segments = split_segments(geometry, 50.0) | |
| length = 0.0 | |
| for segment in segments: | |
| feature['geometry'] = mapping(segment) | |
| feature['properties']['id_seg'] = count + 1 | |
| feature['properties']['firstX'] = segment.coords[0][0] | |
| feature['properties']['firstY'] = segment.coords[0][0] | |
| feature['properties']['lastX'] = segment.coords[-1][0] | |
| feature['properties']['lastY'] = segment.coords[-1][0] | |
| feature['properties']['length'] = segment.length | |
| feature['properties']['chainage'] = length | |
| dst.write(feature) | |
| length += segment.length | |
| count += 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment