feat: fixed multipolygon handling
This commit is contained in:
parent
fe51bdb10e
commit
e0a85d2cfe
2 changed files with 279 additions and 8 deletions
261
countries.geojson
Normal file
261
countries.geojson
Normal file
File diff suppressed because one or more lines are too long
26
map.py
26
map.py
|
@ -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>')
|
||||||
|
|
Loading…
Reference in a new issue