Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
def osm_model_generate_structures(osm, root, pipeline, logger):
    """

    TODO: Generate structures as a whole, without dealing with individual types, using metadata.
    """

    structures = ddd.group3(name="Structures3")

    #sidewalks_3d = objsidewalks_2d.extrude(0.3).translate([0, 0, -5]).material(ddd.mats.sidewalk)
    walls = root.find("/Structures2/Walls")
    if walls:
        walls_3d = walls.extrude(5.5).translate([0, 0,
                                                 -6]).material(ddd.mats.cement)
        walls_3d = terrain.terrain_geotiff_elevation_apply(
            walls_3d, osm.ddd_proj)
        if int(ddd.data.get('ddd:area:subdivide', 0)) > 0:
            walls_3d = ddd.meshops.subdivide_to_grid(
                walls_3d, float(ddd.data.get('ddd:area:subdivide')))
        walls_3d = ddd.uv.map_cubic(walls_3d)
        structures.append(walls_3d)

    ceilings = root.find("/Structures2/Ceilings")
    if ceilings:
        ceilings_3d = ceilings.extrude(0.5).translate([0, 0, -1.0]).material(
            ddd.mats.cement)
        ceilings_3d = terrain.terrain_geotiff_elevation_apply(
            ceilings_3d, osm.ddd_proj)
        if int(ddd.data.get('ddd:area:subdivide', 0)) > 0:
            ceilings_3d = ddd.meshops.subdivide_to_grid(
                ceilings_3d, float(ddd.data.get('ddd:area:subdivide')))
        ceilings_3d = ddd.uv.map_cubic(ceilings_3d)
        structures.append(ceilings_3d)

    #sidewalks_3d = terrain.terrain_geotiff_elevation_apply(sidewalks_3d, self.osm.ddd_proj)
    #sidewalks_3d = ddd.uv.map_cubic(sidewalks_3d)
    #floors_3d = floors_2d.extrude(-0.3).translate([0, 0, -5]).material(ddd.mats.sidewalk)
    #floors_3d = floors_2d.triangulate().translate([0, 0, -5]).material(ddd.mats.sidewalk)
    #floors_3d = terrain.terrain_geotiff_elevation_apply(floors_3d, osm.ddd_proj)

    #subway = ddd.group([sidewalks_3d, walls_3d, floors_3d, ceilings_3d], empty=3).translate([0, 0, -0.2])
    #self.osm.other_3d.children.append(subway)

    root.append(structures)
Exemplo n.º 4
0
    def generate_ways_3d_subways(self):
        """
        Generates boxing for sub ways.
        """
        logger.info("Generating subways.")
        logger.warn("IMPLEMENT 2D/3D separation for this, as it needs to be cropped, and it's being already cropped earlier")

        # Take roads
        ways = [w for w in self.osm.ways_2d["-1a"].children] + [w for w in self.osm.ways_2d["-1"].children]

        union = self.osm.ways_2d["-1"].union()
        union_with_transitions = ddd.group(ways, empty="2").union()
        union_sidewalks = union_with_transitions.buffer(0.6, cap_style=2, join_style=2)

        sidewalks_2d = union_sidewalks.subtract(union_with_transitions)  # we include transitions
        walls_2d = sidewalks_2d.buffer(0.5, cap_style=2, join_style=2).subtract(union_sidewalks)
        floors_2d = union_sidewalks.copy()
        ceilings_2d = union.buffer(0.6, cap_style=2, join_style=2).subtract(self.osm.ways_2d["-1a"])

        # FIXME: Move cropping to generic site, use interintermediatemediate osm.something for storage
        crop = ddd.shape(self.osm.area_crop)
        sidewalks_2d = sidewalks_2d.intersection(crop)
        walls_2d = walls_2d.intersection(crop)
        floors_2d = floors_2d.intersection(crop)
        ceilings_2d = ceilings_2d.intersection(crop)

        sidewalks_3d = sidewalks_2d.extrude(0.3).translate([0, 0, -5]).material(ddd.mats.sidewalk)
        walls_3d = walls_2d.extrude(5).translate([0, 0, -5]).material(ddd.mats.cement)
        #floors_3d = floors_2d.extrude(-0.3).translate([0, 0, -5]).material(ddd.mats.sidewalk)
        floors_3d = floors_2d.triangulate().translate([0, 0, -5]).material(ddd.mats.sidewalk)
        ceilings_3d = ceilings_2d.extrude(0.5).translate([0, 0, -1.0]).material(ddd.mats.cement)

        sidewalks_3d = terrain.terrain_geotiff_elevation_apply(sidewalks_3d, self.osm.ddd_proj)
        sidewalks_3d = ddd.uv.map_cubic(sidewalks_3d)
        walls_3d = terrain.terrain_geotiff_elevation_apply(walls_3d, self.osm.ddd_proj)
        walls_3d = ddd.uv.map_cubic(walls_3d)
        floors_3d = terrain.terrain_geotiff_elevation_apply(floors_3d, self.osm.ddd_proj)
        ceilings_3d = terrain.terrain_geotiff_elevation_apply(ceilings_3d, self.osm.ddd_proj)
        ceilings_3d = ddd.uv.map_cubic(ceilings_3d)

        subway = ddd.group([sidewalks_3d, walls_3d, floors_3d, ceilings_3d], empty=3).translate([0, 0, -0.2])
        self.osm.other_3d.children.append(subway)
Exemplo n.º 5
0
    def generate_area_3d_pitch(self, area_2d):

        if area_2d.geom is None or area_2d.geom.is_empty:
            return None

        area_2d_orig = area_2d.extra.get('ddd:crop:original')  #, area_2d)

        #logger.debug("Pitch: %s", area_2d)
        area_3d = self.generate_area_3d_gen(area_2d)

        # TODO: pass size then adapt to position and orientation, easier to construct and reuse
        # TODO: get area uncropped (create a cropping utility that stores the original area)

        sport_full = area_2d.extra.get('ddd:sport', None)
        sport = sport_full.split(";")[0]  # Get first value if multivalued

        lines = None
        if sport == 'tennis':
            lines = sports.field_lines_area(area_2d_orig,
                                            sports.tennis_field_lines,
                                            padding=2.5)
        elif sport == 'basketball':
            lines = sports.field_lines_area(area_2d_orig,
                                            sports.basketball_field_lines,
                                            padding=1)
        elif sport == 'gymnastics':
            #lines = sports.field_lines_area(area_2d_orig, sports.basketball_field_lines, padding=2.0)
            lines = ddd.group3()
        elif sport in ('handball'):
            lines = sports.field_lines_area(area_2d_orig,
                                            sports.handball_field_lines,
                                            padding=1)
        elif sport in ('soccer', 'futsal'):
            lines = sports.field_lines_area(area_2d_orig,
                                            sports.football_field_lines,
                                            padding=1)
        else:
            # No sport assigned
            lines = ddd.group3()

        if lines:
            lines = terrain.terrain_geotiff_elevation_apply(
                lines, self.osm.ddd_proj)  #.translate([0, 0, 0.01])
            height = area_2d.extra.get('ddd:height', 0.0)
            lines = lines.translate([0, 0, height])

            area_3d = ddd.group3([area_3d, lines])
        else:
            logger.debug("No pitch lines generated.")

        return area_3d
Exemplo n.º 6
0
    def generate_customs_3d(self):
        logger.info("Generating 3D custom items (from %d customs_1d)",
                    len(self.osm.customs_1d.children))

        for custom_2d in self.osm.customs_1d.children:
            #if custom_2d.geom.empty: continue
            custom_3d = self.generate_custom_3d(custom_2d)
            if custom_3d:
                custom_3d.name = custom_3d.name if custom_3d.name else custom_2d.name
                logger.debug("Generated custom item: %s", custom_3d)
                self.osm.customs_3d.children.append(custom_3d)

        # FIXME: Do not alter every vertex, move the entire object instead
        self.osm.customs_3d = terrain.terrain_geotiff_elevation_apply(
            self.osm.customs_3d, self.osm.ddd_proj)
Exemplo n.º 7
0
def osm_model_generate_coastline(osm, root, obj, logger):

    # Crop this feature as it has not been cropped
    area_crop = osm.area_crop2 if osm.area_crop2 else osm.area_filter2
    coastlines_3d = obj.intersection(area_crop).union().clean()
    if not coastlines_3d.geom:
        return

    coastlines_3d = coastlines_3d.individualize().extrude(
        15.0).flip_faces().translate([0, 0, -15.0])

    # Subdivide
    if int(ddd.data.get('ddd:area:subdivide', 0)) > 0:
        logger.debug("Subdividing coastline meshes: %s", obj)
        coastlines_3d = ddd.meshops.subdivide_to_grid(
            coastlines_3d, float(ddd.data.get('ddd:area:subdivide')))

    coastlines_3d = terrain.terrain_geotiff_elevation_apply(
        coastlines_3d, osm.ddd_proj)
    coastlines_3d = coastlines_3d.material(ddd.mats.rock)
    coastlines_3d = ddd.uv.map_cubic(coastlines_3d)
    coastlines_3d.name = 'Coastline: %s' % coastlines_3d.name
    root.find("/Other3").append(coastlines_3d)
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    def generate_ways_3d_elevated(self):

        logger.info("Generating elevated ways.")
        logger.warn(
            "IMPLEMENT 2D/3D separation for this, as it needs to be cropped")

        elevated = []

        # Walk roads
        ways = ([w for w in self.osm.ways_2d["1"].children] +
                [w for w in self.osm.ways_2d["0a"].children] +
                [w for w in self.osm.ways_2d["-1a"].children])
        # ways_union = ddd.group(ways).union()

        sidewalk_width = 0.4

        elevated_union = DDDObject2()
        for way in ways:
            # way_longer = way.buffer(0.3, cap_style=1, join_style=2)

            if 'intersection' in way.extra: continue

            way_with_sidewalk_2d = way.buffer(sidewalk_width,
                                              cap_style=2,
                                              join_style=2)
            #way_with_sidewalk_2d_extended = osmops.extend_way(way).buffer(sidewalk_width, cap_style=2, join_style=2)
            sidewalk_2d = way_with_sidewalk_2d.subtract(way).material(
                ddd.mats.sidewalk)
            wall_2d = way_with_sidewalk_2d.buffer(
                0.25, cap_style=2,
                join_style=2).subtract(way_with_sidewalk_2d).buffer(
                    0.001, cap_style=2, join_style=2).material(ddd.mats.cement)
            floor_2d = way_with_sidewalk_2d.buffer(
                0.3, cap_style=2,
                join_style=2).buffer(0.001, cap_style=2,
                                     join_style=2).material(ddd.mats.cement)

            sidewalk_2d.extra['way_2d'] = way
            wall_2d.extra['way_2d'] = way
            floor_2d.extra['way_2d'] = way

            # Get connected ways
            connected = self.osm.ways1.follow_way(way.extra['way_1d'], 1)
            connected_2d = ddd.group(
                [self.osm.ways2.get_way_2d(c) for c in connected])
            if 'intersection_start_2d' in way.extra['way_1d'].extra:
                connected_2d.append(
                    way.extra['way_1d'].extra['intersection_start_2d'])
            if 'intersection_end_2d' in way.extra['way_1d'].extra:
                connected_2d.append(
                    way.extra['way_1d'].extra['intersection_end_2d'])
            # print(connected)

            sidewalk_2d = sidewalk_2d.subtract(connected_2d).buffer(0.001)
            wall_2d = wall_2d.subtract(connected_2d.buffer(sidewalk_width))
            # TODO: Subtract floors from connected or resolve intersections
            wall_2d = wall_2d.subtract(elevated_union)

            # FIXME: Move cropping to generic site, use itermediate osm.something for storage
            crop = ddd.shape(self.osm.area_crop)
            sidewalk_2d = sidewalk_2d.intersection(
                crop.buffer(-0.003)).clean(eps=0.01)
            wall_2d = wall_2d.intersection(crop.buffer(-0.003)).clean(eps=0.01)
            floor_2d = floor_2d.intersection(
                crop.buffer(-0.003)).clean(eps=0.01)

            #FIXME: TODO: this shal be done earlier, before generating the path
            #if way.extra.get('ddd:way:elevated:material', None):
            #    way.extra['way_2d'].material(way.extra.get('ddd:way:elevated:material'))

            # ddd.group((sidewalk_2d, wall_2d)).show()
            if way.extra.get('ddd:way:elevated:border', None) == 'fence':
                fence_2d = wall_2d.outline().clean()
                fence_2d = fence_2d.material(ddd.mats.fence)
                #fence_2d.dump()
                #wall_2d.show()
                fence_2d.extra['ddd:item'] = True
                fence_2d.extra['ddd:item:height'] = 1.2
                fence_2d.extra['ddd:height'] = 1.2
                fence_2d.extra['barrier'] = "fence"
                fence_2d.extra[
                    '_height_mapping'] = "terrain_geotiff_and_path_apply"
                fence_2d.extra['way_1d'] = way.extra['way_1d']

                self.osm.items_1d.append(fence_2d)
                elevated.append((sidewalk_2d, None, floor_2d))
            else:
                elevated.append((sidewalk_2d, wall_2d, floor_2d))

            elevated_union = elevated_union.union(
                ddd.group([sidewalk_2d, wall_2d, floor_2d]))

            # Bridge piers
            path = way.extra['way_1d']
            if path.geom.length > 15.0:  # and path.extra['ddd:bridge:posts']:
                # Generate posts
                interval = 35.0
                length = path.geom.length
                numposts = int(length / interval)
                idx = 0

                logger.debug("Piers for bridge (length=%s, num=%d, way=%s)",
                             length, numposts, way)
                for d in numpy.linspace(0.0, length, numposts, endpoint=False):
                    if d == 0.0: continue

                    # Calculate left and right perpendicular intersections with sidewalk, park, land...
                    p, segment_idx, segment_coords_a, segment_coords_b = path.interpolate_segment(
                        d)

                    # FIXME: Use items and crop in a generic way (same for subways) (so ignore below in common etc)
                    if not self.osm.area_crop.contains(ddd.point(p).geom):
                        continue

                    dir_vec = (segment_coords_b[0] - segment_coords_a[0],
                               segment_coords_b[1] - segment_coords_a[1])
                    dir_vec_length = math.sqrt(dir_vec[0]**2 + dir_vec[1]**2)
                    dir_vec = (dir_vec[0] / dir_vec_length,
                               dir_vec[1] / dir_vec_length)
                    angle = math.atan2(dir_vec[1], dir_vec[0])

                    idx = idx + 1

                    if len(p) < 3:
                        logger.error(
                            "Bridge path with less than 3 components when building bridge piers."
                        )
                        continue

                    if p[2] > 1.0:  # If no height, no pilar, but should be a margin and also corrected by base_height
                        item = ddd.rect([
                            -way.extra['ddd:way:width'] * 0.3, -0.5,
                            way.extra['ddd:way:width'] * 0.3, 0.5
                        ],
                                        name="Bridge Post %s" % way.name)
                        item = item.extrude(-(math.fabs(p[2]) - 0.5)).material(
                            ddd.mats.cement)
                        item = ddd.uv.map_cubic(item)
                        item = item.rotate([0, 0, angle - math.pi / 2
                                            ]).translate([p[0], p[1], 0])
                        vertex_func = self.get_height_apply_func(path)
                        item = item.vertex_func(vertex_func)
                        item = terrain.terrain_geotiff_elevation_apply(
                            item, self.osm.ddd_proj)
                        item = item.translate([0, 0, -0.8])
                        item.extra['way_2d'] = way
                        item.extra['ddd:bridge:post'] = True
                        self.osm.other_3d.children.append(item)

        elevated_3d = []
        for item in elevated:
            sidewalk_2d, wall_2d, floor_2d = item
            sidewalk_3d = sidewalk_2d.extrude(0.2).translate([0, 0, -0.2])
            wall_3d = wall_2d.extrude(0.6) if wall_2d else None
            floor_3d = floor_2d.extrude(-0.5).translate([0, 0, -0.2])
            # extra_height = way_2d.extra['extra_height']
            # way_3d = way_2d.extrude(-0.2 - extra_height).translate([0, 0, extra_height])  # + layer_height

            sidewalk_3d = ddd.uv.map_cubic(sidewalk_3d)
            wall_3d = ddd.uv.map_cubic(wall_3d) if wall_3d else None
            floor_3d = ddd.uv.map_cubic(floor_3d)

            elevated_3d.append(sidewalk_3d)
            elevated_3d.append(floor_3d)
            if wall_3d:
                elevated_3d.append(wall_3d)

        # Raise items to their way height position
        nitems = []
        for item in elevated_3d:
            # print(item.extra)
            path = item.extra['way_1d']
            vertex_func = self.osm.ways1.get_height_apply_func(path)
            nitem = item.vertex_func(vertex_func)
            nitems.append(nitem)

        result = ddd.group(nitems, empty=3)
        result = terrain.terrain_geotiff_elevation_apply(
            result, self.osm.ddd_proj)
        self.osm.other_3d.children.append(result)
Exemplo n.º 10
0
    def generate_area_3d_underwater(self, area_2d):
        logger.info("Generating underwater for: %s", area_2d)
        #area_2d.dump()
        areas_2d = area_2d.individualize().flatten().clean()
        #area_2d.show()

        result = ddd.group3()
        for area_2d in areas_2d.children:

            area_2d = area_2d.clean()
            try:
                area_2d.validate()
            except DDDException as e:
                logger.error(
                    "Could not generate underwater area (invalid area %s): %s",
                    area_2d, e)
                continue

            if area_2d.geom.type == "LineString":
                logger.error(
                    "Could not generate underwater area (area is line): %s",
                    area_2d)
                continue

            try:
                area_3d = area_2d.extrude_step(
                    area_2d.buffer(-1.0),
                    -0.3,
                    base=False,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-2.0),
                    -0.5,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-4.0),
                    -1.0,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-6.0),
                    -0.5,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-9.0),
                    -0.4,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-12.0),
                    -0.3,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
            except Exception as e:
                logger.warn(
                    "Exception extruding underwater area (reduced LinearRings need caring): %s",
                    e)
                print(area_2d.geom)
                print(area_2d.buffer(-1.0).geom)
                area_3d = None

            if area_3d is None or area_3d.extra['_extrusion_steps'] < 3:
                logger.debug(
                    "Could not extrude underwater area softly. Extruding abruptly."
                )
                area_3d = area_2d.extrude_step(
                    area_2d.buffer(-0.05),
                    -1.0,
                    base=False,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-0.15),
                    -0.5,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-0.3),
                    -0.5,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
                area_3d = area_3d.extrude_step(
                    area_2d.buffer(-1.0),
                    -0.5,
                    method=ddd.EXTRUSION_METHOD_SUBTRACT)
            if area_3d.extra['_extrusion_steps'] < 1:
                logger.warn("Could not extrude underwater area: %s", area_3d)
                area_3d = area_3d.translate([0, 0, -1.0])
            if area_3d: result.append(area_3d)

        result = terrain.terrain_geotiff_elevation_apply(
            result, self.osm.ddd_proj)
        #result.show()

        return result
Exemplo n.º 11
0
Arquivo: items.py Projeto: c3ypt1c/ddd
    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
Exemplo n.º 12
0
def osm_model_elevation_apply_terrain(obj, osm, root):
    obj = terrain.terrain_geotiff_elevation_apply(obj, osm.ddd_proj)
    return obj