Commit b30d5ecc authored by Thomas Albrecht's avatar Thomas Albrecht

- use kdtree for nearest neighbor search in building_lib:analyse

- dirty hacked .ac vertex reader for stg models
- some small misc stuff
parent 8c9abb20
......@@ -72,7 +72,7 @@ def check_height(building_height, t):
for i in range(len(t.v_splits_meters)):
if t.v_splits_meters[i] >= building_height:
tex_y0 = 1-t.v_splits[i]
print "# height %g storey %i" % (building_height, i)
#print "# height %g storey %i" % (building_height, i)
break
tex_y1 = 1.
#tex_filename = t.filename + '.png'
......@@ -87,6 +87,44 @@ def reset_nb():
global nb
nb = 0
def get_nodes_from_acs(objs, path_prefix):
"""load all .ac, extract nodes"""
# FIXME: use real ac3d reader: https://github.com/majic79/Blender-AC3D/blob/master/io_scene_ac3d/import_ac3d.py
# FIXME: don't skip .xml
nodes=np.array([[0,0]])
for b in objs:
if b.name.endswith(".ac") and b.stg_typ == "OBJECT_STATIC":
print "READ", b.name
try:
ac = open(path_prefix + b.name, 'r')
except:
continue
lines = ac.readlines()
i = 0
while (i < len(lines)):
if lines[i].startswith('numvert'):
line = lines[i]
numvert = int(line.split()[1])
#print "numvert", numvert
for j in range(numvert):
i += 1
splitted = lines[i].split()
node = np.array([[float(splitted[0]),
float(splitted[2])]])
#stg_hdg
node += b.anchor.list()
nodes = np.append(nodes, node,0)
i += 1
ac.close()
#print "------"
print "nodes: ", nodes.shape
return nodes
def analyse(buildings, static_objects, transform, elev, facades, roofs):
......@@ -99,6 +137,17 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs):
We're in global coordinates
"""
# -- build KDtree for static models
from scipy.spatial import KDTree
s = get_nodes_from_acs(static_objects.objs, "e013n51/")
# s = np.zeros((len(static_objects.objs), 2))
# i = 0
# for b in static_objects.objs:
# s[i] = b.anchor.list()
# i += 1
static_tree = KDTree(s, leafsize=10) # -- switch to brute force at 10
new_buildings = []
for b in buildings:
# am anfang geometrieanalyse
......@@ -136,16 +185,17 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs):
# failing that, try levels
if float(b.levels) > 0:
pass
print "have levels", b.levels
#print "have levels", b.levels
else:
# failing that, use random levels
b.levels = random_levels()
b.height = float(b.levels) * level_height
print "hei", b.height, b.levels
#print "hei", b.height, b.levels
if b.height < 3.4:
print "Skipping small building with height < 3.4"
tools.stats.skipped_small += 1
continue
......@@ -208,12 +258,36 @@ def analyse(buildings, static_objects, transform, elev, facades, roofs):
lenX = np.roll(lenX, 1)
X[0] = X[-1]
# -- static objects nearby?
# FIXME: which radius? Or use centroid point?
#radius = max(lenX)
radius = 1.
#nearby = static_tree.query_ball_point(X, radius)
nearby = []
# FIXME: why now all nearby??
if b.name == "Semperoper":
bla
if len(nearby):
try:
print "Static objects nearby. Skipping ", b.name
except:
print "FIXME: Encoding problem", b.name.encode('ascii', 'ignore')
#for n in nearby:
# print static_objects.objs[n].name,
#print
tools.stats.skipped_nearby += 1
continue
# -- shapely stuff
# - compute area
r = LinearRing(list(X))
p = Polygon(r)
tools.stats.count(p.area)
#tools.stats.print_summary()
# if p.area < 200.:
# print "small?", p.area
......@@ -251,7 +325,10 @@ def write(b, out, elev, tile_elev, transform, offset, LOD_lists):
global nb
nb += 1
print nb
#print nb
if nb % 100 == 0: print nb
else: print ".",
out.write("OBJECT poly\n")
name = "b%i" % nb
out.write("name \"%s\"\n" % name)
......
......@@ -17,6 +17,10 @@
# - correct stg id
# -
# FIXME:
# - pythonic way of i = 0; for b in refs: bla[i] = b
# why need hdg=180 in transform? If hdg=0, cluster is broken
"""
osm2city.py aims at generating 3D city models for FG, using OSM data.
Currently, it generates 3D textured buildings, much like bob.pl.
......@@ -41,7 +45,7 @@ You should disable random buildings.
# - decide LOD
# - write clusters
import pdb
#import pdb
import numpy as np
import sys
......@@ -69,9 +73,9 @@ buildings = [] # -- master list, holds all buildings
first = True
tile_size_x=500 # -- our tile size in meters
tile_size_y=500
#infile = 'dd-altstadt.osm'; total_objects = 158
infile = 'dd-altstadt.osm'; total_objects = 158
#infile = 'altstadt.osm'; total_objects = 100 # 2172
infile = 'xapi-buildings.osm'; total_objects = 2000 # huge!
#infile = 'xapi-buildings.osm'; total_objects = 2000 # huge!
#p.parse('xapi.osm') # fails
#p.parse('xapi-small.osm')
......@@ -87,11 +91,13 @@ def dist(a,b):
class Building(object):
"""Central object class.
Holds all data relevant for a building. Coordinates, type, area, ..."""
def __init__(self, osm_id, tags, refs, name, height, levels):
def __init__(self, osm_id, tags, refs, name, height, levels, stg_typ = None, stg_hdg = None):
self.osm_id = osm_id
self.tags = tags
self.refs = refs
self.name = name
self.name = name # stg: name
self.stg_typ = stg_typ # stg: OBJECT_SHARED or _STATIC
self.stg_hdg = stg_hdg
self.height = height
self.levels = levels
self.area = 0
......@@ -215,7 +221,7 @@ maxlon=13.88
lon = 13.7467
lat = 51.0377
transform = coordinates.Transformation((lat, lon), hdg = 0)
transform = coordinates.Transformation((lat, lon), hdg = 0) # FIXME: is Transformation screwed bec. we need hdg=180?
#origin = coordinates.Position(transform, [], lat, lon)
if 0:
......@@ -461,6 +467,7 @@ if __name__ == "__main__":
offset = cl.center
tile_elev = elev(cl.center)
print "TILE E", tile_elev
#transform.setOffset((-offset).list())
center_lat, center_lon = transform.toGlobal((cl.center.x, cl.center.y))
......
......@@ -33,7 +33,7 @@ class Stg:
alt = float(splitted[4])
r = Coords(-1, lon, lat)
hdg = float(splitted[5])
objs.append(Building(osm_id=-1, tags=-1, refs=[r], name="", height=0, levels=0))
objs.append(Building(osm_id=-1, tags=-1, refs=[r], name=path, height=0, levels=0, stg_typ = typ, stg_hdg = hdg))
f.close()
return objs
......
......@@ -72,7 +72,8 @@ def raster(transform, fname, x0, y0, size_x=1000, size_y=1000, step_x=5, step_y=
class Stats(object):
def __init__(self):
self.objects = 0
self.skipped = 0
self.skipped_small = 0
self.skipped_nearby = 0
self.buildings_in_LOD = np.zeros(3)
self.area_levels = np.array([1,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000])
self.area_above = np.zeros_like(self.area_levels)
......@@ -92,10 +93,13 @@ class Stats(object):
out = sys.stdout
out.write(textwrap.dedent("""
total buildings %i
skipped %i
skipped
small %i
nearby %i
vertices %i
surfaces %i
""" % (self.objects, self.skipped, self.vertices, self.surfaces)))
""" % (self.objects, self.skipped_small, self.skipped_nearby,
self.vertices, self.surfaces)))
for i in range(len(self.area_levels)):
out.write(" %5g m^2 %5i\n" % (self.area_levels[i], self.area_above[i]))
#print self
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment