add semantic surfaces #161
-
Hello. I would l like to add semantic surfaces [Wall, Roof and Floor] to 'Solid' building objects please. def doVcBndGeomB(lsgeom, lsattributes, extent, minz, maxz, T, pts, jparams, min_zbld, result):
#-- create the JSON data structure for the City Model
cm = {}
cm["type"] = "CityJSON"
cm["version"] = "1.1"
# cm["transform"] = {
# "scale": [0.001, 0.001, 0.001],
# "translate": [extent[0], extent[0], minz]
# },
cm["CityObjects"] = {}
cm["vertices"] = []
##-- Metadata is added manually
cm["metadata"] = {
"title": jparams['cjsn_title'],
"referenceDate": jparams['cjsn_referenceDate'],
"referenceSystem": jparams['cjsn_referenceSystem'],
"geographicalExtent": [
extent[0],
extent[1],
minz ,
extent[1],
extent[1],
maxz
],
"datasetPointOfContact": {
"contactName": jparams['cjsn_contactName'],
"emailAddress": jparams['cjsn_emailAddress'],
"contactType": jparams['cjsn_contactType'],
"website": jparams['cjsn_website']
},
"+metadata-extended": {
"lineage":
[{"featureIDs": ["TINRelief"],
"source": [
{
"description": jparams['cjsn_+meta-description'],
"sourceSpatialResolution": jparams['cjsn_+meta-sourceSpatialResolution'],
"sourceReferenceSystem": jparams['cjsn_+meta-sourceReferenceSystem'],
"sourceCitation":jparams['cjsn_+meta-sourceCitation'],
}],
"processStep": {
"description" : "Processing of raster DEM using osm_LoD1_3DCityModel workflow",
"processor": {
"contactName": jparams['cjsn_contactName'],
"contactType": jparams['cjsn_contactType'],
"website": "https://github.com/AdrianKriger/osm_LoD1_3DCityModel"
}
}
},
{"featureIDs": ["Building"],
"source": [
{
"description": "OpenStreetMap contributors",
"sourceReferenceSystem": "urn:ogc:def:crs:EPSG:4326",
"sourceCitation": "https://www.openstreetmap.org",
}],
"processStep": {
"description" : "Processing of building vector contributions using osm_LoD1_3DCityModel workflow",
"processor": {
"contactName": jparams['cjsn_contactName'],
"contactType": jparams['cjsn_contactType'],
"website": "https://github.com/AdrianKriger/osm_LoD1_3DCityModel"
}
}
}]
}
},
##-- do terrain
add_terrain_v(pts, cm)
grd = {}
grd['type'] = 'TINRelief'
grd['geometry'] = [] #-- a cityobject can have >1
#-- the geometry
g = {}
g['type'] = 'CompositeSurface'
g['lod'] = 1
allsurfaces = [] #-- list of surfaces
add_terrain_b(T, allsurfaces)
g['boundaries'] = allsurfaces
#-- add the geom
grd['geometry'].append(g)
#-- insert the terrain as one new city object
cm['CityObjects']['terrain01'] = grd
count = 0
##-- then buildings
for (i, geom) in enumerate(lsgeom):
poly = list(result[lsattributes[i]['osm_id']].values()) #--- a list with the heights at each vertex
footprint = geom
#-- one building
oneb = {}
oneb['type'] = 'Building'
oneb['attributes'] = {}
for k, v in list(lsattributes[i].items()):
if v is None:
del lsattributes[i][k]
#oneb['attributes'][k] = lsattributes[i][k]
for a in lsattributes[i]:
oneb['attributes'][a] = lsattributes[i][a]
oneb['geometry'] = [] #-- a cityobject can have > 1
#-- the geometry
g = {}
g['type'] = 'Solid'
g['lod'] = 1
allsurfaces = [] #-- list of surfaces forming the oshell of the solid
#-- exterior ring of each footprint
oring = list(footprint.exterior.coords)
oring.pop() #-- remove last point since first==last
if footprint.exterior.is_ccw == False:
#-- to get proper orientation of the normals
oring.reverse()
if lsattributes[i]['osm_building'] == 'bridge':
#--- make sure the list of heights at each vertex do not go higher than the roof height
edges = [[ele for ele in sub if ele <= lsattributes[i]['roof_height']] for sub in poly]
extrude_walls(oring, lsattributes[i]['roof_height'], lsattributes[i]['bottom_bridge_height'],
allsurfaces, cm, edges)
count = count + 1
if lsattributes[i]['osm_building'] == 'roof':
#--- make sure the list of heights at each vertex do not go higher than the roof height
edges = [[ele for ele in sub if ele <= lsattributes[i]['roof_height']] for sub in poly]
extrude_walls(oring, lsattributes[i]['roof_height'], lsattributes[i]['bottom_roof_height'],
allsurfaces, cm, edges)
count = count + 1
if lsattributes[i]['osm_building'] != 'bridge' and lsattributes[i]['osm_building'] != 'roof':
#--- make sure the list of heights at each vertex do not go higher than the roof height
new_edges = [[ele for ele in sub if ele <= lsattributes[i]['roof_height']] for sub in poly]
#--- add the height of the ground level to each vertex in the list
new_edges = [[min_zbld[i-count]] + sub_list for sub_list in new_edges]
extrude_walls(oring, lsattributes[i]['roof_height'], min_zbld[i-count],
allsurfaces, cm, new_edges)
#-- interior rings of each footprint
irings = []
interiors = list(footprint.interiors)
for each in interiors:
iring = list(each.coords)
iring.pop() #-- remove last point since first==last
if each.is_ccw == True:
#-- to get proper orientation of the normals
iring.reverse()
irings.append(iring)
extrude_int_walls(iring, lsattributes[i]['roof_height'], min_zbld[i-count], allsurfaces, cm)
#-- top-bottom surfaces
if lsattributes[i]['osm_building'] == 'bridge':
extrude_roof_ground(oring, irings, lsattributes[i]['roof_height'],
False, allsurfaces, cm)
extrude_roof_ground(oring, irings, lsattributes[i]['bottom_bridge_height'],
True, allsurfaces, cm)
if lsattributes[i]['osm_building'] == 'roof':
extrude_roof_ground(oring, irings, lsattributes[i]['roof_height'],
False, allsurfaces, cm)
extrude_roof_ground(oring, irings, lsattributes[i]['bottom_roof_height'],
True, allsurfaces, cm)
if lsattributes[i]['osm_building'] != 'bridge' and lsattributes[i]['osm_building'] != 'roof':
#else:
extrude_roof_ground(oring, irings, lsattributes[i]['roof_height'],
False, allsurfaces, cm)
extrude_roof_ground(oring, irings, min_zbld[i-count], True, allsurfaces, cm)
#-- add the extruded surfaces to the geometry
g['boundaries'] = []
g['boundaries'].append(allsurfaces)
#g['boundaries'] = allsurfaces
#-- add the geom to the building
oneb['geometry'].append(g)
#-- insert the building as one new city object
cm['CityObjects'][lsattributes[i]['osm_id']] = oneb
return cm
def add_terrain_v(pts, cm):
for p in pts:
cm['vertices'].append([p[0], p[1], p[2]])
def add_terrain_b(Terr, allsurfaces):
for i in Terr:
allsurfaces.append([[i[0], i[1], i[2]]])
def extrude_walls(ring, height, ground, allsurfaces, cm, edges):
dps = 3
#-- each edge become a wall, ie a rectangle
for (j, v) in enumerate(ring[:-1]):
if len(edges[j]) > 2 or len(edges[j+1]) > 2:
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), edges[j][0]])
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), edges[j+1][0]])
c = 0
for i, o in enumerate(edges[j+1][1:]):
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), o])
c = c + 1
for i in edges[j][::-1][:-1]:
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), i])
c = c + 1
t = len(cm['vertices'])
c = c + 2
b = c
l = []
for i in range(c):
l.append(t-b)
b = b - 1
allsurfaces.append([l])
if len(edges[j]) == 2 and len(edges[j+1]) == 2:
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), edges[j][0]])
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), edges[j+1][0]])
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), edges[j+1][1]])
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), edges[j][1]])
t = len(cm['vertices'])
allsurfaces.append([[t-4, t-3, t-2, t-1]])
if len(edges[-1]) == 2 and len(edges[0]) == 2:
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), edges[-1][0]])
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), edges[0][0]])
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), edges[0][1]])
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), edges[-1][1]])
t = len(cm['vertices'])
allsurfaces.append([[t-4, t-3, t-2, t-1]])
if len(edges[-1]) > 2 or len(edges[0]) > 2:
c = 0
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), edges[-1][0]])
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), edges[0][0]])
for i, o in enumerate(edges[0][1:]):
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), o])
c = c + 1
for i in edges[-1][::-1][:-1]:
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), i])
c = c + 1
t = len(cm['vertices'])
c = c + 2
b = c
l = []
for i in range(c):
l.append(t-b)
b = b - 1
allsurfaces.append([l])
def extrude_int_walls(ring, height, ground, allsurfaces, cm):
dps = 3
#-- each edge become a wall, ie a rectangle
for (j, v) in enumerate(ring[:-1]):
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), ground])
#values.append(0)
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), ground])
#values.append(0)
cm['vertices'].append([round(ring[j+1][0], dps), round(ring[j+1][1], dps), height])
cm['vertices'].append([round(ring[j][0], dps), round(ring[j][1], dps), height])
t = len(cm['vertices'])
allsurfaces.append([[t-4, t-3, t-2, t-1]])
#-- last-first edge
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), ground])
#values.append(0)
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), ground])
cm['vertices'].append([round(ring[0][0], dps), round(ring[0][1], dps), height])
#values.append(0)
cm['vertices'].append([round(ring[-1][0], dps), round(ring[-1][1], dps), height])
t = len(cm['vertices'])
allsurfaces.append([[t-4, t-3, t-2, t-1]])
def extrude_roof_ground(orng, irngs, height, reverse, allsurfaces, cm):
oring = copy.deepcopy(orng)
irings = copy.deepcopy(irngs)
if reverse == True:
oring.reverse()
for each in irings:
each.reverse()
for (i, pt) in enumerate(oring):
cm['vertices'].append([round(pt[0], 3), round(pt[1], 3), height])
oring[i] = (len(cm['vertices']) - 1)
for (i, iring) in enumerate(irings):
for (j, pt) in enumerate(iring):
cm['vertices'].append([round(pt[0], 3), round(pt[1], 3), height])
irings[i][j] = (len(cm['vertices']) - 1)
output = []
output.append(oring)
for each in irings:
output.append(each)
allsurfaces.append(output) How do I add surfaces please? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
or do I have this completely wrong. |
Beta Was this translation helpful? Give feedback.
-
to add semantics surfaces you have to add a |
Beta Was this translation helpful? Give feedback.
Yes, only LoD2 and higher have semantic surfaces.