-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.py
111 lines (84 loc) · 3.45 KB
/
main.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
import json
import os
import random
import uuid
from rtree.index import Index, Property
from shapely.geometry import shape, Point, MultiPolygon, Polygon
def gen_random_point(number, polygon, seed=None):
""" Returns a `number` of random points inside the given `polygon`. """
random.seed(seed)
list_of_points = []
minx, miny, maxx, maxy = polygon.bounds
counter = 0
while counter < number:
pnt = Point(random.uniform(minx, maxx), random.uniform(miny, maxy))
if polygon.contains(pnt):
list_of_points.append(pnt)
counter += 1
return list_of_points
def get_polygons(geometry):
if isinstance(geometry, MultiPolygon):
for polygon in geometry.geoms:
yield polygon
elif isinstance(geometry, Polygon):
yield geometry
def get_countries():
"""
Returns a generator to iterate through a set of countries data.
:return: Returns a 2-elements tuple with the country name and its geometry.
"""
countries = []
path = os.path.join(os.path.dirname(__file__), "countries.geo.json")
with open(path, 'rb') as file:
geojson = file.read()
geojson = json.loads(geojson)
for feature in geojson['features']:
country_name = feature['properties']['name']
geometry = shape(feature['geometry'])
countries.append((country_name, geometry))
return countries
def demo_delete():
seed = 1 # Seed for random points
countries = get_countries()
country_id_to_remove = 170 # United States of America
country_uuids_to_remove = [] # Polygons' ids to remove from the index
properties = Property()
# properties.writethrough = True
# properties.leaf_capacity = 1000
# properties.fill_factor = 0.5
index = Index(properties=properties)
points_per_polygon = 1
points = []
# Inserts countries data to the index
for i, (country_name, geometry) in enumerate(countries):
for polygon in get_polygons(geometry):
temp_uuid = uuid.uuid1().int
index.insert(temp_uuid, polygon.bounds, country_name)
if i == country_id_to_remove:
# Saves index ids of the polygon to be removed later
country_uuids_to_remove.append(temp_uuid)
# Generates random points in every polygon and saves them
random_points = gen_random_point(points_per_polygon, polygon, seed)
points.append((country_name, random_points))
# Checks every generated point has matches
for (country_name, country_points) in points:
for point in country_points:
hits = list(index.intersection(point.bounds, objects=True))
assert any(hit.object == country_name for hit in hits)
# Remove geometry
geometry = countries[country_id_to_remove][1]
for i, polygon in enumerate(get_polygons(geometry)):
index.delete(country_uuids_to_remove[i], polygon.bounds)
points_missing = []
# Checks (again) if every generated point has matches
for (country_name, country_points) in points:
for point in country_points:
hits = list(index.intersection(point.bounds, objects=True))
# Save any point without matches
if not any(hit.object == country_name for hit in hits):
points_missing.append(str(point) + " - " + country_name)
# Print missing points
for point in points_missing:
print(point)
if __name__ == '__main__':
demo_delete()