feat: fixed multipolygon handling

This commit is contained in:
s3lph 2024-12-17 00:14:18 +01:00
parent fe51bdb10e
commit e0a85d2cfe
Signed by: s3lph
GPG key ID: 0AA29A52FB33CFB5
2 changed files with 279 additions and 8 deletions

261
countries.geojson Normal file

File diff suppressed because one or more lines are too long

26
map.py
View file

@ -47,9 +47,9 @@ class Triangle:
return ray * t return ray * t
def plane_coords(self, v): def plane_coords(self, v):
u = np.dot(self.e1, v - self.v1) / self.e1n u = np.dot(self.e1 / self.e1n, v - self.v1)
n = np.cross(self.n, self.e1 / self.e1n) n = np.cross(self.n, self.e1 / self.e1n)
v = np.dot(n, v-self.v2) v = -np.dot(n, v - self.v1)
return np.array([u, v]) return np.array([u, v])
@ -65,11 +65,18 @@ def map_poly(tri, poly):
p0 = convert_to_cartesian(*poly[0]) p0 = convert_to_cartesian(*poly[0])
p0i = tri.intersect(p0) p0i = tri.intersect(p0)
mapped = [] mapped = []
new = True
for i in range(1, len(poly)): for i in range(1, len(poly)):
p1 = convert_to_cartesian(*poly[i]) p1 = convert_to_cartesian(*poly[i])
p1i = tri.intersect(p1) p1i = tri.intersect(p1)
if p0i is not None and p1i is not None: if p0i is not None and p1i is not None:
mapped.append((tri.plane_coords(p0i), tri.plane_coords(p1i))) if new:
mapped.append([tri.plane_coords(p0i), tri.plane_coords(p1i)])
new = False
else:
mapped[-1].append(tri.plane_coords(p1i))
else:
new = True
p0 = p1 p0 = p1
p0i = p1i p0i = p1i
return mapped return mapped
@ -78,14 +85,14 @@ def map_poly(tri, poly):
if __name__ == '__main__': if __name__ == '__main__':
t = Triangle(np.array([5,0,0]), np.array([0,5,0]), np.array([0,0,5])) t = Triangle(np.array([5,0,0]), np.array([0,5,0]), np.array([0,0,5]))
countries = {} countries = {}
with open('/tmp/countries.geojson', 'r') as f: with open('countries.geojson', 'r') as f:
j = json.load(f) j = json.load(f)
for f in j['features']: for f in j['features']:
cc = f['properties']['ADMIN'] cc = f['properties']['ADMIN']
if f['geometry']['type'] == 'MultiPolygon': if f['geometry']['type'] == 'MultiPolygon':
countries[cc] = [] countries[cc] = []
for poly in f['geometry']['coordinates'][0]: for poly in f['geometry']['coordinates']:
countries[cc].extend(map_poly(t, poly)) countries[cc].extend(map_poly(t, poly[0]))
elif f['geometry']['type'] == 'Polygon': elif f['geometry']['type'] == 'Polygon':
countries[cc] = map_poly(tri, f['geometry']['coordinates'][0]) countries[cc] = map_poly(tri, f['geometry']['coordinates'][0])
minx = min(t.v1p[0], t.v2p[0], t.v3p[0]) minx = min(t.v1p[0], t.v2p[0], t.v3p[0])
@ -97,6 +104,9 @@ if __name__ == '__main__':
print(f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="{minx} {miny} {w} {h}" width="{w}" height="{h}">') print(f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="{minx} {miny} {w} {h}" width="{w}" height="{h}">')
print(f'<path fill="none" stroke="black" stroke-width="0.01" d="M {t.v1p[0]} {t.v1p[1]} L {t.v2p[0]} {t.v2p[1]} L {t.v3p[0]} {t.v3p[1]} Z" />') print(f'<path fill="none" stroke="black" stroke-width="0.01" d="M {t.v1p[0]} {t.v1p[1]} L {t.v2p[0]} {t.v2p[1]} L {t.v3p[0]} {t.v3p[1]} Z" />')
for c, l in countries.items(): for c, l in countries.items():
for a, b in l: for ls in l:
print(f'<path fill="none" stroke="red" stroke-width="0.01" d="M {a[0]} {a[1]} L {b[0]} {b[1]}" />') print(f'<path fill="none" stroke="red" stroke-width="0.01" d="M {ls[0][0]} {ls[0][1]}', end='')
for x, y in ls[1:]:
print(f' L {x} {y}', end='')
print('" />')
print('</svg>') print('</svg>')