feat: initialize sunrise with 100-player shared rooms
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""OSM XML snapshots -> attributed footprint GeoJSON, with no fabricated source heights."""
|
||||
import collections
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
items = {}
|
||||
sources = []
|
||||
boxes = ['126.975,37.410,126.995,37.435','126.995,37.410,127.015,37.435','126.975,37.435,126.995,37.460','126.995,37.435,127.015,37.460']
|
||||
for i, bbox in enumerate(boxes):
|
||||
path = root / f'data/raw/gwacheon/tile-{i}.osm'
|
||||
tree = ET.parse(path).getroot()
|
||||
sources.append({'file':path.name,'url':'https://www.openstreetmap.org/api/0.6/map?bbox='+bbox,'sha256':hashlib.sha256(path.read_bytes()).hexdigest()})
|
||||
for element in tree:
|
||||
items[(element.tag,element.get('id'))] = element
|
||||
nodes = {key[1]:[float(e.get('lon')),float(e.get('lat'))] for key,e in items.items() if key[0]=='node'}
|
||||
def tags(e):
|
||||
return {t.get('k'):t.get('v') for t in e.findall('tag')}
|
||||
def ring(e):
|
||||
refs = [n.get('ref') for n in e.findall('nd')]
|
||||
if len(refs)<4 or refs[0]!=refs[-1] or any(r not in nodes for r in refs):
|
||||
return None
|
||||
return [nodes[r] for r in refs]
|
||||
features=[]
|
||||
skipped=[]
|
||||
consumed=set()
|
||||
for (kind,identity),e in items.items():
|
||||
p=tags(e)
|
||||
if kind!='relation' or 'building' not in p:
|
||||
continue
|
||||
outer=[]; inner=[]; members=[]; valid=True
|
||||
for m in e.findall('member'):
|
||||
way=items.get(('way',m.get('ref')))
|
||||
r=ring(way) if way is not None else None
|
||||
if m.get('type')!='way' or r is None:
|
||||
valid=False; break
|
||||
(inner if m.get('role')=='inner' else outer).append(r)
|
||||
members.append(m.get('ref'))
|
||||
if valid and len(outer)==1:
|
||||
features.append({'type':'Feature','id':'relation/'+identity,'properties':p,'geometry':{'type':'Polygon','coordinates':outer+inner}})
|
||||
consumed.update(members)
|
||||
else:
|
||||
skipped.append({'id':'relation/'+identity,'reason':'multipart or incomplete relation; not silently filled'})
|
||||
for (kind,identity),e in items.items():
|
||||
p=tags(e)
|
||||
if kind!='way' or 'building' not in p or identity in consumed:
|
||||
continue
|
||||
if p['building'] in ['no','construction','ruins'] or p.get('location')=='underground':
|
||||
skipped.append({'id':'way/'+identity,'reason':'not an existing above-ground building'}); continue
|
||||
r=ring(e)
|
||||
if r is None:
|
||||
skipped.append({'id':'way/'+identity,'reason':'open or incomplete footprint'}); continue
|
||||
features.append({'type':'Feature','id':'way/'+identity,'properties':p,'geometry':{'type':'Polygon','coordinates':[r]}})
|
||||
# API returns ways crossing the requested bounds: retain complete footprints only if center is in AOI.
|
||||
features=[f for f in features if 126.975 <= sum(c[0] for c in f['geometry']['coordinates'][0][:-1])/len(f['geometry']['coordinates'][0][:-1]) <= 127.015 and 37.410 <= sum(c[1] for c in f['geometry']['coordinates'][0][:-1])/len(f['geometry']['coordinates'][0][:-1]) <= 37.460]
|
||||
data={'type':'FeatureCollection','attribution':'© OpenStreetMap contributors','license':'ODbL-1.0','features':features}
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--output-dir', type=Path, default=root/'public/buildings')
|
||||
out=parser.parse_args().output_dir
|
||||
out.mkdir(exist_ok=True,parents=True)
|
||||
(out/'gwacheon.geojson').write_text(json.dumps(data,ensure_ascii=False,separators=(',',':')),encoding='utf-8')
|
||||
report={'downloadedAt':'2026-10-29','bbox':[126.975,37.410,127.015,37.460],'count':len(features),'types':dict(collections.Counter(f['properties']['building'] for f in features)),'heightTags':sum('height' in f['properties'] for f in features),'levelTags':sum('building:levels' in f['properties'] for f in features),'sources':sources,'skipped':skipped,'license':'https://www.openstreetmap.org/copyright'}
|
||||
(out/'metadata.json').write_text(json.dumps(report,ensure_ascii=False,indent=2),encoding='utf-8')
|
||||
print(json.dumps(report,ensure_ascii=False))
|
||||
Reference in New Issue
Block a user