def generate_building_3d_elevation(self, building_3d): building_3d = terrain.terrain_geotiff_min_elevation_apply(building_3d, self.osm.ddd_proj) #building_3d.extra['ddd:building:feature'].extra['ddd:building:elevation'] = building_3d.extra['_terrain_geotiff_min_elevation_apply:elevation'] building_3d.set('ddd:building:elevation', building_3d.extra['_terrain_geotiff_min_elevation_apply:elevation']) #logger.info("Assigning elevation %s to building: %s -> %s", building_3d.extra['_terrain_geotiff_min_elevation_apply:elevation'], building_3d, building_3d.extra['ddd:building:feature']) building_3d = building_3d.translate([0, 0, -0.20]) # temporary hack floor snapping return building_3d
def generate_area_3d_apply_elevation(self, area_2d, area_3d): apply_layer_height = True if area_3d.mesh or area_3d.children: #height = area_2d.extra.get('ddd:height', 0.2) area_elevation = area_2d.extra.get('ddd:area:elevation', 'geotiff') if area_elevation == 'geotiff': area_3d = terrain.terrain_geotiff_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'min': area_3d = terrain.terrain_geotiff_min_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'max': area_3d = terrain.terrain_geotiff_max_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'path': # logger.debug("3D layer transition: %s", way) # if way.extra['ddd:layer_transition']: if ('way_1d' in area_3d.extra): path = area_3d.extra['way_1d'] vertex_func = self.osm.ways1.get_height_apply_func(path) area_3d = area_3d.vertex_func(vertex_func) apply_layer_height = False # ddd:height:base is also not applied, as it is applied during area creation (extruded, to avoid area_3d = terrain.terrain_geotiff_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'water': apply_layer_height = False pass elif area_elevation == 'none': pass else: raise AssertionError() if apply_layer_height: layer = str( area_3d.extra.get('ddd:layer', area_3d.extra.get('osm:layer', 0))) # TODO: This ddd:base_height conflicts with ddd:height:base? base_height = float( area_3d.extra.get('ddd:base_height', self.osm.ways1.layer_height(layer))) area_3d = area_3d.translate([0, 0, base_height]) # Commented as ways were using this but they are extruded to height #base_height = area_2d.get('ddd:height:base', None) #if base_height: # area_3d = area_3d.translate([0, 0, base_height]) return area_3d
def osm_extras_mapillary_get(pipeline, osm, root, logger): # Add mapillary items # TODO: Move to separate task and rule module, separate point generation from image/metadata generation, reuse code, this could be much shorter mc = MapillaryClient(client_id=pipeline.data['mapillary:client_id']) transformer = pyproj.Transformer.from_proj(osm.osm_proj, osm.ddd_proj) transformer2 = pyproj.Transformer.from_proj(osm.ddd_proj, osm.osm_proj) query_coords = osm.area_crop2.centroid().geom.coords[0] query_coords = project_coordinates(query_coords, transformer2) query_limit = 200 query_radius = 500 logger.info("Requesting Mapillary images near to (limit=%d, radius=%d)", query_coords, query_limit, query_radius) data = mc.images_list(query_coords, limit=query_limit, radius=query_radius) for feature in data['features'][:]: key = feature['properties']['key'] pano = feature['properties']['pano'] camera_angle = feature['properties']['ca'] geom = feature['geometry'] coords = geom['coordinates'] #coords = (float(coords[0]) * 111000.0, float(coords[1]) * 111000.0) coords = project_coordinates(coords, transformer) logger.debug( "Mapillary Image: %s CameraAngle: %.1f Pano: %s Coords: %s" % (key, camera_angle, pano, coords)) mc.request_image(key) image = mc.image_textured(feature).scale([3, 3, 3]) image_height = 1.5 image = image.translate([0, 1, 0]) image = image.rotate([0, 0, (0 + (-camera_angle)) * ddd.DEG_TO_RAD]) image = image.translate([coords[0], coords[1], image_height]) cam = ddd.cube(d=0.05).translate([coords[0], coords[1], image_height ]).material(ddd.mats.highlight) image.append(cam) image = terrain.terrain_geotiff_min_elevation_apply( image, osm.ddd_proj) osm.other_3d.append(image) logger.info("Added %d images from Mapillary.", len(osm.other_3d.children)) # Optinally save Mapillary data only if osm.other_3d.children: osm.other_3d.save("/tmp/mapi.glb")
def generate_area_3d_apply_elevation(self, area_2d, area_3d): apply_layer_height = True if area_3d.mesh or area_3d.children: #height = area_2d.extra.get('ddd:height', 0.2) area_elevation = area_2d.extra.get('ddd:area:elevation', 'geotiff') if area_elevation == 'geotiff': area_3d = terrain.terrain_geotiff_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'min': area_3d = terrain.terrain_geotiff_min_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'max': area_3d = terrain.terrain_geotiff_max_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'path': # logger.debug("3D layer transition: %s", way) # if way.extra['ddd:layer_transition']: if ('way_1d' in area_3d.extra): path = area_3d.extra['way_1d'] vertex_func = self.osm.ways1.get_height_apply_func(path) area_3d = area_3d.vertex_func(vertex_func) apply_layer_height = False area_3d = terrain.terrain_geotiff_elevation_apply( area_3d, self.osm.ddd_proj) elif area_elevation == 'water': apply_layer_height = False pass elif area_elevation == 'none': pass else: raise AssertionError() if apply_layer_height: layer = str( area_3d.extra.get('ddd:layer', area_3d.extra.get('osm:layer', 0))) base_height = float( area_3d.extra.get('ddd:base_height', self.osm.ways1.layer_height(layer))) area_3d = area_3d.translate([0, 0, base_height]) return area_3d
def generate_item_3d(self, item_2d): # TODO! Move to pipeline or at least call from pipeline #if 'osm:feature' in item_2d.extra: # if ("Julio Verne" in item_2d.extra['osm:feature']['properties'].get('name', "")): # print(item_2d) item_3d = None if item_2d.extra.get('osm:amenity', None) == 'fountain': item_3d = self.generate_item_3d_fountain(item_2d) elif item_2d.extra.get( 'osm:amenity', None) == 'bench': # not to be confused with seat item_3d = self.generate_item_3d_bench(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'drinking_water': item_3d = self.generate_item_3d_generic(item_2d, urban.drinking_water, "Drinking water") elif item_2d.extra.get('osm:amenity', None) == 'post_box': #item_3d = self.generate_item_3d_post_box(item_2d) operator = item_2d.extra['osm:feature'].get('operator', None) item_3d = self.generate_item_3d_generic_catalog( "post_box-default-1", item_2d, urban.post_box, "Postbox") item_3d.name = 'Postbox (%s): %s' % (operator, item_2d.name) elif item_2d.extra.get('osm:amenity', None) == 'table': item_3d = self.generate_item_3d_generic(item_2d, urban.patio_table, "Table") elif item_2d.extra.get( 'osm:amenity', None) == 'seat': # not to be confused with bench item_3d = self.generate_item_3d_generic(item_2d, urban.patio_chair, "Seat") elif item_2d.extra.get('osmext:amenity', None) == 'umbrella': item_3d = self.generate_item_3d_generic(item_2d, urban.patio_umbrella, "Umbrella") #elif item_2d.extra.get('osm:amenity', None) == 'taxi': # item_3d = self.generate_item_3d_taxi(item_2d) #elif item_2d.extra.get('osm:amenity', None) == 'toilets': # item_3d = self.generate_item_3d_taxi(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'waste_basket': item_3d = self.generate_item_3d_waste_basket(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'waste_disposal': if random.choice([1, 2]) == 1: item_3d = self.generate_item_3d_generic_catalog( "waste-disposal-1", item_2d, urban.waste_container, "Waste Disposal") else: item_3d = self.generate_item_3d_generic_catalog( "waste-disposal-closed-1", item_2d, urban.waste_container_with_lid_closed, "Waste Disposal (C)") elif item_2d.extra.get('osm:amenity', None) == 'recycling': item_3d = self.generate_item_3d_generic_catalog( "waste-container-dome-1", item_2d, urban.waste_container_dome, "Recycling") elif item_2d.extra.get('osm:amenity', None) == 'bicycle_parking': #item_3d = self.generate_item_3d_waste_disposal(item_2d) item_2d.set('ddd:angle', item_2d.get('ddd:angle') + math.pi / 2) item_3d = self.generate_item_3d_generic_catalog( "bicycle-parking-bar-u", item_2d, common.bar_u, "Bicycle Parking Bar U") elif item_2d.extra.get('osm:emergency', None) == 'fire_hydrant': item_3d = self.generate_item_3d_generic_catalog( "fire_hydrant-default-1", item_2d, urban.fire_hydrant, "Fire Hydrant") elif item_2d.extra.get('osm:natural', None) == 'tree': # TODO: Do decimations in the pipeline (if at all) self.tree_decimate_idx += 1 if self.tree_decimate <= 1 or self.tree_decimate_idx % self.tree_decimate == 0: #item_3d = random.choice(self.pool['tree']).instance() #coords = item_2d.geom.coords[0] #item_3d = item_3d.translate([coords[0], coords[1], 0.0]) item_3d = self.generate_item_3d_tree(item_2d) elif item_2d.extra.get('osm:natural', None) == 'rock' or item_2d.extra.get( 'ddd:item', None) == 'natural_rock': # TODO: Use a generic metadata-based catalog/instnacing key and arguments (and grouping by arguments for instancing) bounds = [ random.uniform(2, 4), random.uniform(1, 3), random.uniform(1, 2) ] variant = random.choice(range(4)) + 1 item_3d = self.generate_item_3d_generic_catalog( "natural-rock-%d" % variant, item_2d, lambda: landscape.rock(bounds), "Rock") item_3d = item_3d.translate([0, 0, random.uniform(-0.5, 0.0)]) elif item_2d.extra.get('osm:natural', None) == 'stone': #item_3d = self.generate_item_3d_generic_catalog("natural-stone-1", item_2d, lambda: landscape.rock([4, 4.5, 4.0]), "Stone") item_3d = self.generate_item_3d_generic( item_2d, lambda: landscape.rock([4, 4.5, 4.0]), "Stone") item_3d = item_3d.translate([0, 0, -random.uniform(0.0, 1.0)]) elif item_2d.extra.get('osm:tourism', None) == 'artwork' and item_2d.extra.get( 'osm:artwork_type', None) == 'sculpture': item_3d = self.generate_item_3d_sculpture(item_2d) elif item_2d.extra.get('osm:tourism', None) == 'artwork' and item_2d.extra.get( 'osm:artwork_type', None) == 'statue': item_3d = self.generate_item_3d_sculpture(item_2d) elif item_2d.extra.get('osm:tourism', None) == 'artwork' and item_2d.extra.get( 'osm:artwork_type', None) == None: item_3d = self.generate_item_3d_sculpture(item_2d) elif item_2d.extra.get('osm:historic', None) == 'monument': # Large monument item_3d = self.generate_item_3d_monument(item_2d) elif item_2d.extra.get('osm:historic', None) == 'memorial': item_3d = self.generate_item_3d_monument(item_2d) elif item_2d.extra.get('osm:historic', None) == 'wayside_cross': item_3d = self.generate_item_3d_wayside_cross(item_2d) elif item_2d.extra.get('osm:historic', None) == 'archaeological_site': item_3d = self.generate_item_3d_historic_archaeological_site( item_2d) elif item_2d.extra.get('osm:man_made', None) == 'crane': item_3d = self.generate_item_3d_crane(item_2d) elif item_2d.extra.get('osm:man_made', None) == 'lighthouse': item_3d = self.generate_item_3d_lighthouse(item_2d) elif item_2d.extra.get('osm:man_made', None) == 'tower' and item_2d.extra.get( 'osm:tower:type', None) == 'communication': item_3d = self.generate_item_3d_man_made_tower_communication( item_2d) elif item_2d.extra.get('osm:highway', None) == 'bus_stop': item_3d = self.generate_item_3d_bus_stop(item_2d) elif item_2d.extra.get('osm:power', None) == 'tower': item_3d = self.generate_item_3d_powertower(item_2d) elif item_2d.extra.get('osm:power', None) == 'pole': item_3d = self.generate_item_3d_powerpole(item_2d) elif item_2d.extra.get('osm:power', None) == 'catenary_mast': logger.warn( "Using temporary object: powerpole (for catenary_mast)") item_3d = self.generate_item_3d_powerpole(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'fence': item_3d = self.generate_item_3d_fence(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'hedge': item_3d = self.generate_item_3d_hedge(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'bollard': item_3d = self.generate_item_3d_generic(item_2d, urban.bollard, "Bollard") #elif item_2d.extra.get('osm:leisure', None) == 'playground': elif item_2d.extra.get('osm:playground', None) == 'swing': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_swingset, "Playground Swings") elif item_2d.extra.get('osm:playground', None) == 'sandbox': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_sandbox, "Playground Sandbox") elif item_2d.extra.get('osm:playground', None) == 'slide': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_slide, "Playground Slide") elif item_2d.extra.get('osm:playground', None) == 'monkey_bar': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_arc, "Playground Monkey Bar Arc") elif item_2d.extra.get('osm:power', None) in ('line', 'minor_line'): # TODO: Tilt objects using a generic tilting mechanism (also, this one may be also based on terrain gradient) item_3d = self.generate_item_3d_powerline(item_2d) elif item_2d.extra.get('osm:golf', None) == 'hole': # TODO: Tilt objects using a generic tilting mechanism (also, this one may be also based on terrain gradient) item_3d = self.generate_item_3d_generic(item_2d, sports.golf_flag, "Golf Flag") elif item_2d.extra.get('osm:highway', None) == 'street_lamp' and item_2d.get( 'osm:lamp_mount', None) == 'high_mast': item_3d = self.generate_item_3d_street_lamp_high_mast(item_2d) elif item_2d.extra.get('osm:highway', None) == 'street_lamp': item_3d = self.generate_item_3d_street_lamp(item_2d) elif item_2d.extra.get('osm:highway', None) == 'traffic_signals': item_3d = self.generate_item_3d_traffic_signals(item_2d) elif item_2d.extra.get('osm:traffic_sign', None) is not None or any( [k.startswith('osm:traffic_sign:') for k in item_2d.extra.keys()]): item_3d = self.generate_item_3d_traffic_sign(item_2d) elif item_2d.extra.get('ddd:road_marking', None): item_3d = self.generate_item_3d_road_marking(item_2d) elif item_2d.get('ddd:item', None) == 'grass_blade': item_3d = self.generate_item_3d_grass_blade(item_2d) elif item_2d.get('ddd:item', None) == 'flowers': item_3d = self.generate_item_3d_flowers(item_2d) elif item_2d.get('ddd:ladder', None) == 'swimming_pool': item_3d = self.generate_item_3d_generic(item_2d, landscape.ladder_pool, "Swimming Pool Ladder") else: logger.debug("Unknown item: %s", item_2d.extra) # TODO: Apply height via tags, similar approach to areas if item_3d: # Copy item_2d attributes # TODO: shall this be guaranteed by the generators? for k, v in item_2d.extra.items(): item_3d.set(k, default=v, children=True) #data = dict(item_2d.extra) #data.update(item_3d.extra) #item_3d.extra = data # Apply height # TODO: Rename this property to either ddd:item... or to a common mechanism for areas, items... height_mapping = item_3d.get( 'ddd:item:elevation', item_3d.get('_height_mapping', 'terrain_geotiff_min_elevation_apply')) if height_mapping == 'terrain_geotiff_elevation_apply': item_3d = terrain.terrain_geotiff_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'terrain_geotiff_incline_elevation_apply': item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'terrain_geotiff_and_path_apply': path = item_3d.extra['way_1d'] vertex_func = self.osm.ways.get_height_apply_func(path) item_3d = item_3d.vertex_func(vertex_func) item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'none': # building... pass elif height_mapping == 'building': # building... pass else: item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) # Apply base height base_height = item_2d.get('ddd:height:base', None) if base_height: item_3d = item_3d.translate([0, 0, base_height]) return item_3d
def generate_item_3d(self, item_2d): # TODO! Move to pipeline or at least call from pipeline #if 'osm:feature' in item_2d.extra: # if ("Julio Verne" in item_2d.extra['osm:feature']['properties'].get('name', "")): # print(item_2d) item_3d = None if item_2d.extra.get('osm:amenity', None) == 'fountain': item_3d = self.generate_item_3d_fountain(item_2d) elif item_2d.extra.get( 'osm:amenity', None) == 'bench': # not to be confused with seat item_3d = self.generate_item_3d_bench(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'drinking_water': item_3d = self.generate_item_3d_generic(item_2d, urban.drinking_water, "Drinking water") elif item_2d.extra.get('osm:amenity', None) == 'post_box': item_3d = self.generate_item_3d_post_box(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'table': item_3d = self.generate_item_3d_generic(item_2d, urban.patio_table, "Table") elif item_2d.extra.get( 'osm:amenity', None) == 'seat': # not to be confused with bench item_3d = self.generate_item_3d_generic(item_2d, urban.patio_chair, "Seat") elif item_2d.extra.get('osmext:amenity', None) == 'umbrella': item_3d = self.generate_item_3d_generic(item_2d, urban.patio_umbrella, "Umbrella") #elif item_2d.extra.get('osm:amenity', None) == 'taxi': # item_3d = self.generate_item_3d_taxi(item_2d) #elif item_2d.extra.get('osm:amenity', None) == 'toilets': # item_3d = self.generate_item_3d_taxi(item_2d) elif item_2d.extra.get('osm:amenity', None) == 'waste_basket': item_3d = self.generate_item_3d_waste_basket(item_2d) #elif item_2d.extra.get('osm:amenity', None) == 'waste_disposal': # item_3d = self.generate_item_3d_waste_disposal(item_2d) #elif item_2d.extra.get('osm:amenity', None) == 'recycling': # item_3d = self.generate_item_3d_waste_disposal(item_2d) #elif item_2d.extra.get('osm:amenity', None) == 'bicycle_parking': # item_3d = self.generate_item_3d_waste_disposal(item_2d) elif item_2d.extra.get('osm:emergency', None) == 'fire_hydrant': item_3d = self.generate_item_3d_generic(item_2d, urban.fire_hydrant, "Fire Hydrant") #elif item_2d.extra.get('osm:natural', None) == 'coastline': # item_3d = self.generate_item_3d_coastline(item_2d) elif item_2d.extra.get('osm:natural', None) == 'tree': self.tree_decimate_idx += 1 if self.tree_decimate <= 1 or self.tree_decimate_idx % self.tree_decimate == 0: #item_3d = random.choice(self.pool['tree']).instance() #coords = item_2d.geom.coords[0] #item_3d = item_3d.translate([coords[0], coords[1], 0.0]) item_3d = self.generate_item_3d_tree(item_2d) elif item_2d.extra.get('osm:tourism', None) == 'artwork' and item_2d.extra.get( 'osm:artwork_type', None) == 'sculpture': item_3d = self.generate_item_3d_sculpture(item_2d) elif item_2d.extra.get('osm:tourism', None) == 'artwork' and item_2d.extra.get( 'osm:artwork_type', None) == 'statue': item_3d = self.generate_item_3d_sculpture(item_2d) elif item_2d.extra.get('osm:historic', None) == 'monument': # Large monument item_3d = self.generate_item_3d_monument(item_2d) elif item_2d.extra.get('osm:historic', None) == 'memorial': item_3d = self.generate_item_3d_monument(item_2d) elif item_2d.extra.get('osm:historic', None) == 'wayside_cross': item_3d = self.generate_item_3d_wayside_cross(item_2d) elif item_2d.extra.get('osm:man_made', None) == 'lighthouse': item_3d = self.generate_item_3d_lighthouse(item_2d) elif item_2d.extra.get('osm:man_made', None) == 'crane': item_3d = self.generate_item_3d_crane(item_2d) elif item_2d.extra.get('osm:highway', None) == 'bus_stop': item_3d = self.generate_item_3d_bus_stop(item_2d) elif item_2d.extra.get('osm:power', None) == 'tower': item_3d = self.generate_item_3d_powertower(item_2d) elif item_2d.extra.get('osm:power', None) == 'pole': item_3d = self.generate_item_3d_powerpole(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'fence': item_3d = self.generate_item_3d_fence(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'hedge': item_3d = self.generate_item_3d_hedge(item_2d) elif item_2d.extra.get('osm:barrier', None) == 'bollard': item_3d = self.generate_item_3d_generic(item_2d, urban.bollard, "Bollard") #elif item_2d.extra.get('osm:leisure', None) == 'playground': elif item_2d.extra.get('osm:playground', None) == 'swing': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_swingset, "Playground Swings") elif item_2d.extra.get('osm:playground', None) == 'sandbox': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_sandbox, "Playground Sandbox") elif item_2d.extra.get('osm:playground', None) == 'slide': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_slide, "Playground Slide") elif item_2d.extra.get('osm:playground', None) == 'monkey_bar': item_3d = self.generate_item_3d_generic( item_2d, urban.childrens_playground_arc, "Playground Monkey Bar Arc") elif item_2d.extra.get('osm:highway', None) == 'street_lamp': item_3d = self.generate_item_3d_street_lamp(item_2d) elif item_2d.extra.get('osm:highway', None) == 'traffic_signals': item_3d = self.generate_item_3d_traffic_signals(item_2d) elif item_2d.extra.get('osm:traffic_sign', None) is not None or any( [k.startswith('osm:traffic_sign:') for k in item_2d.extra.keys()]): item_3d = self.generate_item_3d_traffic_sign(item_2d) elif item_2d.get('ddd:item', None) == 'grass_blade': item_3d = self.generate_item_3d_grass_blade(item_2d) elif item_2d.get('ddd:item', None) == 'flowers': item_3d = self.generate_item_3d_flowers(item_2d) else: logger.debug("Unknown item: %s", item_2d.extra) # TODO: Apply height via tags, similar approach to areas if item_3d: # Apply height height_mapping = item_3d.extra.get( '_height_mapping', 'terrain_geotiff_min_elevation_apply') if height_mapping == 'terrain_geotiff_elevation_apply': item_3d = terrain.terrain_geotiff_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'terrain_geotiff_incline_elevation_apply': item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'terrain_geotiff_and_path_apply': path = item_3d.extra['way_1d'] vertex_func = self.osm.ways.get_height_apply_func(path) item_3d = item_3d.vertex_func(vertex_func) item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) elif height_mapping == 'none': # building... pass elif height_mapping == 'building': # building... pass else: item_3d = terrain.terrain_geotiff_min_elevation_apply( item_3d, self.osm.ddd_proj) # Apply base height base_height = item_2d.get('ddd:height:base', None) if base_height: item_3d = item_3d.translate([0, 0, base_height]) # Copy item_2d attributes for k, v in item_2d.extra.items(): item_3d.set(k, default=v, children=True) #data = dict(item_2d.extra) #data.update(item_3d.extra) #item_3d.extra = data return item_3d
def osm_model_elevation_apply_terrain_min(obj, osm, root): obj = terrain.terrain_geotiff_min_elevation_apply(obj, osm.ddd_proj) return obj