-
Notifications
You must be signed in to change notification settings - Fork 0
/
SimpleSimplification.py
116 lines (87 loc) · 4.24 KB
/
SimpleSimplification.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from Simplification import Simplification
class SimpleSimplification(Simplification):
def __init__(self):
pass
def simplify(self, constraint_points, geometries, zoom):
geometries_count = 0
points_count = 0
simplified_points_count = 0
# Iterate over all geometries
for geoIndex, geometry in geometries.items():
# Geometry is a line string
if geometry['type'] == 'LineString':
coordinates = geometry['coordinates']
# Count stats
geometries_count += 1
points_count += len(coordinates)
# Apply simplification
self.removeCoordinates(coordinates, zoom)
geometries[geoIndex]['coordinates'] = coordinates
# Count stats
simplified_points_count += len(coordinates)
# Geometry is a multi line string
elif geometry['type'] == 'MultiLineString':
line_strings = geometry['coordinates']
for line_index, line_coordinates in enumerate(line_strings):
# Count stats
geometries_count += 1
points_count += len(line_coordinates)
# Apply simplification
self.removeCoordinates(line_coordinates, zoom)
line_strings[line_index] = line_coordinates
# Count stats
simplified_points_count += len(line_coordinates)
line_strings[:] = [line for line in line_strings if len(line) > 1]
# Geometry is a polygon
elif geometry['type'] == 'Polygon':
line_rings = geometry['coordinates']
# Iterate over all contained line rings
for ringIndex, ringCoordinates in enumerate(line_rings):
# Count stats
geometries_count += 1
points_count += len(ringCoordinates)
# Apply simplification
self.removeCoordinates(ringCoordinates, zoom)
line_rings[ringIndex] = ringCoordinates
# Count stats
simplified_points_count += len(ringCoordinates)
line_rings[:] = [ring for ring in line_rings if len(ring) > 1]
elif geometry['type'] == 'MultiPolygon':
polygon_list = geometry['coordinates']
for polygonIndex, line_rings in enumerate(polygon_list):
# Iterate over all contained line rings
for ringIndex, ringCoordinates in enumerate(line_rings):
# Count stats
geometries_count += 1
points_count += len(ringCoordinates)
# Apply simplification
self.removeCoordinates(ringCoordinates, zoom)
polygon_list[polygonIndex][ringIndex] = ringCoordinates
# Count stats
simplified_points_count += len(ringCoordinates)
polygon_list[polygonIndex][:] = [ring for ring in polygon_list[polygonIndex] if len(ring) > 1]
else:
print(f"Other geometry: {geometry['type']}")
# raise Exception("Invalid geometry type")
# Output stats
print(f"---------- Zoom: {zoom} ----------")
print(f"Geometries: {geometries_count}")
print(f"Total points: {points_count}")
print(f"Remaining points: {simplified_points_count}")
print(f"Total points per geometry: {points_count / geometries_count}")
print(f"Remaining points per geometry: {simplified_points_count / geometries_count}")
print("----------------------------------")
print()
return geometries
def removeCoordinates(self, coordinates, zoom):
# Do nothing of zoom level is 19 or greater
if int(zoom) >= 19:
return
n = zoom - 5
if n < 1:
n = 1
# Iterate over all available coordinates
for index, coordinate in enumerate(coordinates):
# Remove every n-th coordinate
if index % n == 0:
coordinates.pop(index)