Ejemplo n.º 1
0
def features_init(pipeline, root, logger):

    features = ddd.group2(name="Features2")
    root.append(features)

    features3 = ddd.group2(name="Features3")
    root.append(features3)
Ejemplo n.º 2
0
    def generate_item_2d_outdoor_seating(self, feature):

        # Distribute centers for seating (ideally, grid if shape is almost square, sampled if not)
        # For now, using center:

        center = feature.centroid()

        table = center.copy(name="Outdoor seating table: %s" % feature.name)
        table.extra['osm:amenity'] = 'table'
        table.extra['osm:seats'] = random.randint(0, 4)

        umbrella = ddd.group2()
        if random.uniform(0, 1) < 0.8:
            umbrella = center.copy(name="Outdoor seating umbrella: %s" % feature.name)
            umbrella.extra['osmext:amenity'] = 'umbrella'

        chairs = ddd.group2(name="Outdoor seating seats")
        ang_offset = random.choice([0, math.pi / 2, math.pi, math.pi * 3/4])
        for i in range(table.extra['osm:seats']):
            ang = ang_offset + (2 * math.pi / table.extra['osm:seats']) * i + random.uniform(-0.1, 0.1)
            chair = ddd.point([0, random.uniform(0.7, 1.1)], name="Outdoor seating seat %d: %s" % (i, feature.name))
            chair = chair.rotate(ang).translate(center.geom.coords[0])
            chair.extra['osm:amenity'] = 'seat'
            chair.extra['ddd:angle'] = ang + random.uniform(-0.1, 0.1) # * (180 / math.pi)
            chairs.append(chair)

        item = ddd.group2([table, umbrella, chairs], "Outdoor seating: %s" % feature.name)

        return item

        '''
Ejemplo n.º 3
0
def osm_structured_surfaces(osm, root, pipeline):
    """
    Walk layers and their transitions for ways and areas.
    Does this after all structured partitioning, so ways and areas are the smallest possible.

    This is done before ground filling, so this information can be used.

    This information is used to build tunnels and bridges, joining the ways that
    go across them onto a unique surface, as long as they belong to the same layer or its transition layer.
    """


    layer_m1 = root.select(path="/Ways/", selector='["ddd:layer" = "-1"];["ddd:layer" = "-1a"]')
    layer_1 = root.select(path="/Ways/", selector='["ddd:layer" = "0a"];["ddd:layer" = "1"]')
    groups = [layer_m1, layer_1]

    structures = ddd.group2(name="Structures2")
    root.append(structures)

    surfaces = ddd.group2(name="Surfaces")
    root.append(surfaces)

    for group in groups:
        # Calculate influence areas, tag them (type of tunnel / bridge, etc)
        surfaces = group.union().buffer(2.0).individualize()  # .remove_holes()
        #surfaces.show()
        surfaces.children.extend(surfaces.children)
Ejemplo n.º 4
0
def rooms_init(root, pipeline):

    pipeline.data['rooms:empty_union'] = ddd.group2()
    pipeline.data['rooms:solid_union'] = ddd.group2()
    pipeline.data['rooms:background_union'] = ddd.group2()

    rooms = ddd.group2(name="Rooms")
    root.append(rooms)

    items = ddd.group2(name="Items")
    root.append(items)
    """
Ejemplo n.º 5
0
def osm_structured_generate_areas_ground_fill(osm, root, logger):
    """
    Generates (fills) remaining ground areas (not between ways or otherwise occupied by other areas).
    Ground must come after every other area (interways, etc), as it is used to "fill" missing gaps.
    """

    area_crop = osm.area_filter
    logger.info("Generating terrain (bounds: %s)", area_crop.bounds)

    union = ddd.group2([root.find("/Ways").select('["ddd:layer" ~ "^(0|-1a)$"]'),
                        root.find("/Areas").select('["ddd:layer" ~ "^(0|-1a)$"]'),
                        #root.find("/Water")
                        ])
    #union = union.clean_replace(eps=0.01)
    ##union = union.clean(eps=0.01)
    union = osm.areas2.generate_union_safe(union)
    union = union.clean(eps=0.01)  # Removing this causes a core dump during 3D generation

    terr = ddd.rect(area_crop.bounds, name="Ground")
    terr = terr.material(ddd.mats.terrain)
    terr.extra["ddd:layer"] = "0"
    terr.extra["ddd:height"] = 0

    try:
        terr = terr.subtract(union)
        terr = terr.clean(eps=0.0)  #eps=0.01)
    except Exception as e:
        logger.error("Could not subtract areas_2d from terrain.")
        return

    root.find("/Areas").append(terr)
Ejemplo n.º 6
0
def osm_augment_rocks_generate_rocks(obj, osm, root):
    """
    """
    item_density_m2 = 1.0 / 1000.0
    num_items = int((obj.area() * item_density_m2))

    def filter_func_noise(coords):
        val = noise.pnoise2(coords[0],
                            coords[1],
                            octaves=2,
                            persistence=0.5,
                            lacunarity=2,
                            repeatx=1024,
                            repeaty=1024,
                            base=0)
        return (val > random.uniform(-0.5, 0.5))

    items = ddd.group2(name='Rocks: %s' % obj.name)
    for p in obj.random_points(num_points=num_items,
                               filter_func=filter_func_noise):
        item = ddd.point(p, name="Rock")
        #item.extra['ddd:aug:status'] = 'added'
        item.extra['ddd:item'] = 'natural_rock'
        item.extra['ddd:angle'] = ddd.random.angle()
        items.append(item)

    root.find("/ItemsNodes").append(items.children)
Ejemplo n.º 7
0
def features_regions_merge_random(pipeline, root, logger):
    regions = root.find("/Features2/Regions")

    #regions.show()

    #for r in regions_by_area:
    for i in range(int(len(regions.children) * 0.75)):
        regions = regions.clean()
        regions.children.sort(key=lambda r: r.geom.area)
        r = regions.children[0]
        contiguous = [cr for cr in regions.children if cr.touches(r)]
        contiguous.sort(key=lambda cr: cr.geom.area)

        #print("R: %s  Cont: %s" % (r, contiguous))
        #to_join = [c for c in contiguous if random.random() < 0.3]  # Join random neighbours
        to_join = [contiguous[0]]  # Join just the smallest neighbour

        joined_region = ddd.group2([r] + to_join).union()
        #ddd.group2([ddd.group2(to_join).material(ddd.mats.highlight), joined_region]).show()

        regions.remove(r)
        for c in to_join:
            regions.remove(c)

        regions.append(joined_region)

        regions = regions.clean()

    root.find("/Features2/Regions").replace(regions)
Ejemplo n.º 8
0
def osm_augment_plants_generate_grass_blades(obj, osm, root):
    """
    Generates grass blades.
    """
    blade_density_m2 = 1.0 / 20.0
    num_blades = int((obj.area() * blade_density_m2))

    def filter_func_noise(coords):
        val = noise.pnoise2(coords[0],
                            coords[1],
                            octaves=2,
                            persistence=0.5,
                            lacunarity=2,
                            repeatx=1024,
                            repeaty=1024,
                            base=0)
        return (val > random.uniform(-0.5, 0.5))

    blades = ddd.group2(name='Grass Blades: %s' % obj.name)
    for p in obj.random_points(num_points=num_blades,
                               filter_func=filter_func_noise):
        blade = ddd.point(p, name="Grass Blade")
        #blade.extra['ddd:aug:status'] = 'added'
        blade.extra['ddd:item'] = 'grass_blade'  # TODO: Change to DDD
        blades.append(blade)

    root.find("/ItemsNodes").append(blades.children)
Ejemplo n.º 9
0
    def generate_areas_2d_ways_interiors(self, union):
        """
        Generates interways areas.
        """

        result = ddd.group2()
        if not union.geom: return result

        for c in ([union.geom]
                  if union.geom.type == "Polygon" else union.geom):
            if c.type == "LineString":
                logger.warning(
                    "Interways areas union resulted in LineString geometry. Skipping."
                )
                continue
            if len(c.interiors) == 0:
                continue

            logger.info("Generating %d interiors.", len(c.interiors))
            for interior in c.interiors:
                area = ddd.polygon(interior.coords, name="Interways area")
                if area:
                    area = area.subtract(union)
                    area = area.clean(eps=0.01)
                    #area = area.clean()
                    if area.geom:
                        area.set('ddd:area:interways', True)
                        result.append(area)
                else:
                    logger.warn("Invalid interways area.")

        return result
Ejemplo n.º 10
0
def osm_structured_export_2d_tile(root, osm, pipeline):
    """Save a cropped tileable 2D image of the scene."""

    tile = ddd.group2([
        ddd.shape(osm.area_crop).material(ddd.material(color='#ffffff')),  # White background (?)
        #self.ground_2d,
        root.select(path="/Water", recurse=False),
        root.select(path="/Areas", recurse=False),
        root.select(path="/Ways", recurse=False),  #, select="")  self.ways_2d['-1a'], self.ways_2d['0'], self.ways_2d['0a'], self.ways_2d['1'],
        root.select(path="/Roadlines2", recurse=False),
        root.select(path="/Buildings", recurse=False),
        #self.areas_2d_objects, self.buildings_2d.material(ddd.material(color='#8a857f')),
        root.select(path="/ItemsAreas", recurse=False),  #self.items_2d,
        root.select(path="/ItemsWays", recurse=False),  #self.items_2d,
        root.select(path="/ItemsNodes", recurse=False).buffer(0.5).material(ddd.mats.red),

    ]).flatten().select(func=lambda o: o.extra.get('ddd:area:type') != 'underwater')

    tile = tile.intersection(ddd.shape(osm.area_crop))
    tile = tile.clean()
    tile.prop_set('svg:stroke-width', 0.01, children=True)

    path = pipeline.data['filenamebase'] + ".png"
    tile.save(path)

    tile.save("/tmp/osm-structured.png")
Ejemplo n.º 11
0
    def generate_item_3d_historic_archaeological_site(self, item_2d):
        # TODO: Move the actual site generation, given an area, to sketchy

        coords = item_2d.centroid().geom.coords[0]
        if item_2d.geom.type in ("Point", "LineString"):
            points = item_2d.buffer(5.0).random_points(12)
        else:
            points = item_2d.random_points(12)

        line1 = ddd.line(points[0:2])
        line2 = ddd.line(points[2:5])
        line3 = ddd.line(points[5:])
        geomobj = ddd.group2([line1, line2, line3]).buffer(0.5).union()
        #geomobj = filters.noise_random(geomobj, scale=0.075).clean().remove_z()
        #geomobj.show()

        item_3d = geomobj.extrude(0.8)
        #item_3d.copy_from(item_2d)
        item_3d = filters.noise_random(item_3d, scale=0.3)
        item_3d = item_3d.material(ddd.mats.tiles_stones_veg_sparse)
        item_3d = ddd.uv.map_cubic(item_3d)

        # Dont translate ir rotate, item is already in world space (built from item_2d).
        #item_3d = item_3d.rotate([0, 0, item_2d.get('ddd:angle', 0) - math.pi / 2])
        #item_3d = item_3d.translate([coords[0], coords[1], 0.0])  # mat_bronze
        item_3d.name = 'Archaeological Site: %s' % item_2d.name
        return item_3d
Ejemplo n.º 12
0
def osm_augment_plants_generate_flowers(obj, osm, root):
    blade_density_m2 = 1.0 / 20.0
    num_blades = int((obj.area() * blade_density_m2))

    def filter_func_noise(coords):
        val = noise.pnoise2(coords[0],
                            coords[1],
                            octaves=2,
                            persistence=0.5,
                            lacunarity=2,
                            repeatx=1024,
                            repeaty=1024,
                            base=0)
        return (val > random.uniform(-0.5, 0.5))

    blades = ddd.group2(name='Flowers: %s' % obj.name)
    for p in obj.random_points(num_points=num_blades,
                               filter_func=filter_func_noise):
        blade = ddd.point(p, name="Flowers")
        #blade.extra['ddd:aug:status'] = 'added'
        blade.extra['ddd:item'] = 'flowers'
        blade.extra['ddd:flowers:type'] = random.choice(('blue', 'roses'))
        blades.append(blade)

    root.find("/ItemsNodes").append(blades.children)
Ejemplo n.º 13
0
def osm_structured_ways_2d_generate_roadlines(root, osm, pipeline, logger):
    """
    Roadlines are incorporated here, but other augmented properties (traffic lights, lamp posts, traffic signs...)
    are added during augmentation.
    """
    logger.info("Generating roadlines.")
    root.append(ddd.group2(name="Roadlines2"))
    # TODO: This shall be moved to s60, in 3D, and separated from 2D roadline generation
    pipeline.data["Roadlines3"] = ddd.group3(name="Roadlines3")
Ejemplo n.º 14
0
def features_gen(pipeline, root, logger):

    area = ddd.disc(r=100.0)

    points_coords = area.random_points(num_points=200)
    points = ddd.group2([ddd.point(c) for c in points_coords], name="Points")
    points.extra['points_coords'] = points_coords

    root.find("/Features2").append(area)
    root.find("/Features2").append(points)
Ejemplo n.º 15
0
    def load_svg(path):
        """
        """

        paths, attributes = svg2paths(path)

        result = ddd.group2()

        for k, v in enumerate(attributes):
            #print(v)  # v['d']  # print d-string of k-th path in SVG

            # Ex svgpath = 'M10 10 C 20 20, 40 20, 50 10Z'
            mpl_path = parse_path(v['d'])
            '''
            import matplotlib.pyplot as plt
            fig = plt.figure(figsize=(200, 200))
            ax = fig.add_subplot(111)
            ax.axis([0, 0, 200, 200])
            collection = matplotlib.collections.PathCollection([mpl_path])
            collection.set_transform(ax.transData)
            #patch = matplotlib.patches.PathPatch(mpl_path, facecolor="red", lw=2)
            ax.add_artist(collection)
            #ax.add_patch(patch)
            ax.set_xlim([0, 200])
            ax.set_ylim([200, 0])
            plt.show()
            '''

            coords = mpl_path.to_polygons(closed_only=True)

            item = ddd.polygon(coords[0]).clean()  #.convex_hull()

            for c in coords[1:]:
                ng = ddd.polygon(c).clean()  #.convex_hull()
                #ng.show()
                #print (ng.geom.is_valid)
                #if not ng.geom.is_valid: continue
                if item.contains(ng):
                    item = item.subtract(ng)
                else:
                    item = item.union(ng)

            #result = ddd.group([ddd.polygon(c) for c in coords], empty=2)
            result.append(item)

        #result = result.scale([1.0 / (48 * 64), -1.0 / (48 * 64)])
        #result = result.simplify(0.005)  #
        #result.show()

        result = result.union().scale([1, -1]).clean(0)
        xmin, ymin, xmax, ymax = result.bounds()
        result = result.translate([0, -(ymin + ymax)])
        #result = ddd.align.anchor(result, ddd.ANCHOR_CENTER)

        return result
Ejemplo n.º 16
0
def osm_terrain_export_splatmap_channels_all(root, pipeline, osm, logger):
    for i in range(pipeline.data['splatmap:channels_num']):
        mat = pipeline.data['splatmap:channels_materials'][i]
        objs = ddd.group2()
        if mat:
            sel = root.find("/Areas").select('["ddd:material" = "%s"]["ddd:layer" = "0"]["ddd:material:splatmap" = True]' % mat.name)
            objs.append(sel.children)
            sel = root.find("/Ways").select('["ddd:material" = "%s"]["ddd:layer" = "0"]["ddd:material:splatmap" = True]' % mat.name)
            objs.append(sel.children)
        objs.name = 'Channel' + str(i)
        root.find("/Splatmap").append(objs)
Ejemplo n.º 17
0
    def __init__(self, configfiles=None, name=None):

        self.name = name
        self.tasks = None

        self.root = ddd.group2()

        self.data = dict(D1D2D3Bootstrap.data)

        if configfiles:
            self.load(configfiles)
Ejemplo n.º 18
0
    def __init__(self,
                 features=None,
                 area_filter=None,
                 area_crop=None,
                 osm_proj=None,
                 ddd_proj=None):

        self.catalog = PrefabCatalog()

        self.items = ItemsOSMBuilder(self)
        self.items2 = AreaItemsOSMBuilder(self)
        self.ways1 = Ways1DOSMBuilder(self)
        self.ways2 = Ways2DOSMBuilder(self)
        self.ways3 = Ways3DOSMBuilder(self)
        self.areas2 = Areas2DOSMBuilder(self)
        self.areas3 = Areas3DOSMBuilder(self)
        self.buildings = BuildingOSMBuilder(self)
        self.customs = CustomsOSMBuilder(self)

        self.osmops = OSMBuilderOps(self)

        self.area_filter = area_filter
        self.area_crop = area_crop

        self.area_filter2 = ddd.shape(self.area_filter)
        self.area_crop2 = ddd.shape(self.area_crop)

        #self.simplify_tolerance = 0.01

        self.layer_indexes = ('-2', '-1', '0', '1', '2', '3', '-2a', '-1a',
                              '0a', '1a')

        self.layer_heights = {
            '-2': -12.0,
            '-1': -6.0,
            '0': 0.0,
            '1': 6.0,
            '2': 12.0,
            '3': 18.0,
            #'-2a': -9.0, '-1a': -2.5, '0a': 3.0, '1a': 9.0}
            #'-2a': -12.0, '-1a': -5.0, '0a': 0.0, '1a': 6.0}
            '-2a': 0.0,
            '-1a': 0.0,
            '0a': 0.0,
            '1a': 0.0
        }

        self.webmercator_proj = pyproj.Proj(init='epsg:3857')
        self.osm_proj = osm_proj  # 4326
        self.ddd_proj = ddd_proj

        self.features = features if features else []
        self.features_2d = ddd.group2(name="Features")
Ejemplo n.º 19
0
def osm_structured_generate_areas_interways_phase1_ways_sidewalks(
        pipeline, osm, root, logger):
    """
    Experimenting with aumenting sidewalks / kerbs
    """

    # TODO: if done, this shall generate at different layers and according to way metadata

    logger.info("Generating sidewalks for ways.")
    ways = root.find("/Ways").select(
        '["ddd:layer" ~ "0|-1a"][ ! "ddd:way:overlay"]["ddd:way:sidewalk:width"]'
    )

    # Calculate union
    union = root.find("/Ways").select('["ddd:layer" ~ "0|-1a"]').union()
    union = union.append(pipeline.data['buildings_level_0'])
    union = union.append(root.find("/Areas"))
    union = osm.areas2.generate_union_safe(union)
    union = union.clean()

    # Buffer sidewalks
    sidewalks = ddd.group2()
    for sidewalk in ways.flatten().children:
        sidewalk_width = sidewalk.get('ddd:way:sidewalk:width', None)
        if not sidewalk_width: continue
        sidewalk = sidewalk.buffer(sidewalk_width)
        sidewalks.append(sidewalk)

    sidewalks = sidewalks.union().subtract(union).individualize(
        always=True).flatten().clean(eps=0.0)  # -0.01)

    # Construct sidewalks 2D
    for sidewalk in sidewalks.children:

        if sidewalk.is_empty(): continue

        sidewalk.name = "Way Sidewalk"
        sidewalk = sidewalk.material(ddd.mats.pavement)
        sidewalk.set('ddd:area:type', 'sidewalk', children=True)
        sidewalk.set(
            'ddd:area:interways', True, children=True
        )  # It's not interways, but this is used to subtract areas from them
        sidewalk.set('ddd:kerb', True, children=True)
        sidewalk.set('ddd:height', 0.2, children=True)
        sidewalk.set('ddd:layer', "0", children=True)

        sidewalk.set('ddd:area:area', sidewalk.geom.area)
        # Set a copy of itself as original area (so it can be cut and used for sidewalk kerb calculations)
        sidewalk.set('ddd:area:original', sidewalk.copy())
        # TODO: I think this should not be needed here, as buildings shall be removed from all areas later anyway?
        #interior.replace(interior.subtract(buildings).clean())
        root.find("/Areas").append(sidewalk)
Ejemplo n.º 20
0
def features_points_voronoi(pipeline, root, logger):

    points = root.find("/Features2/Points")
    vor = Voronoi(points.extra['points_coords'])

    #lines = [ddd.line(vor.vertices[line]) for line in vor.ridge_vertices if -1 not in line]
    #lines = ddd.group2(lines)

    #[[], [-1, 0], [-1, 1], [1, -1, 0], [3, -1, 2], [-1, 3], [-1, 2], [0, 1, 3, 2], [2, -1, 0], [3, -1, 1]]
    #print(vor.regions)
    regions = [ddd.polygon( [vor.vertices[i] for i in r ] ) for r in vor.regions if -1 not in r]

    regions = ddd.group2(regions, name="Regions")

    root.find("/Features2").append(regions)
Ejemplo n.º 21
0
    def generate_areas_2d_process(self, areas_2d_group, areas_2d, subtract):

        # TODO: Assign area here, it's where it's used
        areas = areas_2d.select('["ddd:area:area"]').children

        logger.info("Sorting 2D areas (%d).", len(areas))
        areas.sort(
            key=lambda a: a.extra['ddd:area:area'])  # extra['ddd:area:area'])
        #areas.sort(key=lambda a: a.geom.area)  # extra['ddd:area:area'])

        for idx in range(len(areas)):
            area = areas[idx]
            area.extra['ddd:area:original'] = area
            for larger in areas[idx + 1:]:
                if larger.contains(area):
                    #logger.info("Area %s contains %s.", larger, area)
                    area.extra['ddd:area:container'] = larger
                    larger.extra['ddd:area:contained'].append(area)
                    #break   # Using this break causes some area containments to be incorrectly assigned

        # Union all roads in the plane to subtract
        logger.info("Generating 2D areas subtract.")
        #union = ddd.group([self.osm.ways_2d['0'], self.osm.ways_2d['-1a']]).union()  # , areas_2d
        union = subtract.union()

        logger.info("Generating 2D areas (%d)", len(areas))
        for area in reversed(areas):

            #feature = area.extra['osm:feature']
            if not area.geom:
                logger.error("Area with no geometry: %s", area)
            if area.geom.type == 'Point': continue

            original_area = area
            area.extra[
                'ddd:area:original'] = original_area  # Before subtracting any internal area

            # Subtract areas contained (use contained relationship)
            narea = area.subtract(ddd.group2(area.extra['ddd:area:contained']))
            narea = narea.subtract(union)
            #narea = narea.clean()  #eps=0.0)

            if narea and narea.geom:
                logger.debug("Area: %s", narea)
                #area = area.subtract(union)

                areas_2d_group.remove(original_area)
                areas_2d_group.append(narea)
Ejemplo n.º 22
0
def start_run(root):
    """
    Run at initial stage, load data.
    """
    # Get features (depends on the process)
    features = ddd.group2()
    with open("../data/periodictable/periodictable.csv") as f:
        csv = DictReader(f)
        for row in csv:
            feature = ddd.point(name="Element: %s" % row['Element'])
            for k in row.keys():
                feature.extra['element:' + k.lower()] = row[k]
            features.append(feature)

    features.name="Elements2"
    root.append(features)
Ejemplo n.º 23
0
def osm_groups_create_root_nodes(root, osm, pipeline):
    items = ddd.group2(name="Areas")
    root.append(items)
    items = ddd.group2(name="Ways")
    root.append(items)
    items = ddd.group2(name="Buildings")
    root.append(items)
    items = ddd.group2(name="ItemsNodes")
    root.append(items)
    items = ddd.group2(name="ItemsAreas")
    root.append(items)
    items = ddd.group2(name="ItemsWays")
    root.append(items)
    items = ddd.group2(name="Meta")  # 2D meta information (boundaries, etc...)
    root.append(items)
Ejemplo n.º 24
0
    def georaster_coverage(self):

        covermap = ddd.group2(name="DDD GeoRaster Coverage")

        tiles_config = settings.DDD_GEO_DEM_TILES
        transformers = {}
        for tc in tiles_config:

            logger.info("Inspecting DEM file: %s", tc['path'])

            crs = tc['crs'].lower()
            transformer = transformers.get(crs, None)
            if not transformer:
                transformer = pyproj.Transformer.from_proj(crs, 'epsg:4326', always_xy=True)
                transformers[crs] = transformer

            projected_point_x0y0 = transformer.transform(tc['bounds'][0], tc['bounds'][1])
            projected_point_x0y1 = transformer.transform(tc['bounds'][0], tc['bounds'][3])
            projected_point_x1y0 = transformer.transform(tc['bounds'][2], tc['bounds'][1])
            projected_point_x1y1 = transformer.transform(tc['bounds'][2], tc['bounds'][3])

            # Generate polygon in wgs84
            tile = ddd.polygon([projected_point_x0y0, projected_point_x1y0, projected_point_x1y1, projected_point_x0y1])
            tile.name = "Tile: %s" % tc['path']

            tile.extra.update(tc)

            file_size = None
            try:
                file_size = os.path.getsize(tc['path'])
            except FileNotFoundError as e:
                pass

            tile.extra['file_size'] = file_size
            tile.extra['file_available'] = file_size is not None

            covermap.append(tile)

            #print(tc)

        #map.show()
        filename = "/tmp/ddd-georaster-coverage.geojson"
        logger.info("Saving map to: %s", filename)
        covermap.save(filename)
Ejemplo n.º 25
0
def osm_structured_generate_areas_interways(pipeline, osm, root, logger):
    """Generates interior areas between ways."""

    logger.info("Generating union for interways.")
    union = ddd.group2([root.find("/Ways").select('["ddd:layer" ~ "0|-1a"]'),
                        root.find("/Areas").select('["ddd:layer" ~ "0|-1a"]') ])
    #union = union.clean()
    union = osm.areas2.generate_union_safe(union)
    #union = union.clean()

    logger.info("Generating interways from interiors.")
    interiors = osm.areas2.generate_areas_2d_ways_interiors(union)
    interiors = interiors.material(ddd.mats.pavement)
    interiors.prop_set('ddd:area:type', 'sidewalk', children=True)
    interiors.prop_set('ddd:kerb', True, children=True)
    interiors.prop_set('ddd:height', 0.2, children=True)
    interiors.prop_set('ddd:layer', "0", children=True)
    #interiors = interiors.clean()

    root.find("/Areas").append(interiors.children)
Ejemplo n.º 26
0
def generate_area_2d_park(area, tree_density_m2=0.0025, tree_types=None):

    max_trees = None

    if tree_types is None:
        tree_types = {'default': 1}  #, 'palm': 0.001}

    #area = ddd.shape(feature["geometry"], name="Park: %s" % feature['properties'].get('name', None))
    feature = area.extra['osm:feature']
    area = area.material(ddd.mats.park)
    area.name = "Park: %s" % feature['properties'].get('name', None)
    area.extra['ddd:area:type'] = 'park'

    # Add trees if necesary
    # FIXME: should not check for None in intersects, filter shall not return None (empty group)

    trees = ddd.group2(name="Trees (Aug): %s" % area.name)

    if area.geom:

        tree_area = area  # area.intersection(ddd.shape(osm.area_crop)).union()
        if tree_area.geom:
            # Decimation would affect after
            num_trees = int((tree_area.geom.area * tree_density_m2))
            #if num_trees == 0 and random.uniform(0, 1) < 0.5: num_trees = 1  # alone trees
            if max_trees:
                num_trees = min(num_trees, max_trees)

            def filter_func_noise(coords):
                val = noise.pnoise2(coords[0] * 0.1, coords[1] * 0.1, octaves=2, persistence=0.5, lacunarity=2, repeatx=1024, repeaty=1024, base=0)
                return (val > random.uniform(-0.5, 0.5))

            for p in tree_area.random_points(num_points=num_trees):
                tree_type = weighted_choice(tree_types)
                tree = ddd.point(p, name="Tree")
                tree.extra['ddd:aug:status'] = 'added'
                tree.extra['osm:natural'] = 'tree'  # TODO: Change to DDD
                tree.extra['osm:tree:type'] = tree_type  # TODO: Change to DDD
                trees.append(tree)

    return trees
Ejemplo n.º 27
0
def osm_groups_items_ways_natural_tree_row(root, osm, obj):
    """
    Generate tree node items for tree row ways.
    """

    trees = ddd.group2(name="Tree Row: %s" % obj.name)
    trees.copy_from(obj)

    length = obj.length()
    density = 1 / 12.0  # tree every 10 m
    count = int(length * density) + 1

    for i in range(count):
        tree = ddd.point(name="Tree %d" % (i + 1))
        tree.copy_from(trees)
        tree.set('osm:natural', 'tree')
        trees.append(tree)

    ddd.align.along(trees, obj)

    root.find("/ItemsNodes").children.extend(trees.children)
Ejemplo n.º 28
0
def osm_terrain_export_splatmap_init(root, pipeline, osm, logger):
    splatmap = ddd.group2(name="Splatmap")
    root.append(splatmap)

    # TODO: This is copied in osm_materials pipeline for export, keep here in a task as metadata (and add to descriptor)
    pipeline.data['splatmap:channels_materials'] = [
        ddd.mats.terrain,
        ddd.mats.dirt,
        ddd.mats.asphalt,
        ddd.mats.pavement,

        ddd.mats.sidewalk,
        ddd.mats.pathwalk,
        None,
        None,

        ddd.mats.grass,
        ddd.mats.garden,
        ddd.mats.park,
        ddd.mats.forest,

        ddd.mats.sand,
        ddd.mats.rock,
        ddd.mats.terrain_rock,
        ddd.mats.terrain_ground,
        ]

    pipeline.data['splatmap:channels_num'] = 16

    pipeline.data['splatmap:channels:collapse_map'] = None
    #pipeline.data['splatmap:channels:collapse_map'] = [
    #    [0, 2, 12],     # Terrain, asphalt, pavement, sand
    #    [1, 13],        # Paths, dirt, rock
    #    [8, 9, 10, 11], # Grass, garden, pàrk, forest
    #    [3, 4, 5]       # Pedestrian, tiles
    #]

    pipeline.data['splatmap:ids'] = {}
Ejemplo n.º 29
0
    def generate_areas_2d_postprocess_water(self, areas_2d, ways_2d):
        logger.info("Postprocessing water areas and ways")

        # Get all water areas ('ddd:water')
        water_areas = areas_2d.select('["ddd:area:type" = "water"]',
                                      recurse=False).union().clean(eps=0.05)
        #water_areas.show()

        river_areas = ways_2d.select('["ddd:area:type" = "water"]',
                                     recurse=False)
        #river_areas.show()

        #all_water_areas = ddd.group2(water_areas.children)

        # Move river areas to areas
        #for c in river_areas.children:
        #    ways_2d.remove(c)
        #    areas_2d.children.extend(river_areas.children)
        # Subtract water areas to ways
        # TODO: Might be done via generic mechanism (assign ways to areas, etc)
        for r in river_areas.children:
            new_river = r.intersection(self.osm.area_filter2)
            if new_river.intersects(water_areas):
                new_river = new_river.subtract(water_areas)
            r.replace(new_river)
        #river_areas.show()

        all_water_areas = ddd.group2([water_areas, river_areas])

        # Create ground area
        underwater_area = all_water_areas.union().clean(eps=0.05)
        #underwater_area.show()
        underwater_area = underwater_area.material(ddd.mats.terrain)
        underwater_area.extra['ddd:area:type'] = 'underwater'
        underwater_area.extra['ddd:layer'] = '0'
        underwater_area.extra['svg:ignore'] = True
        #underwater_area.show()
        areas_2d.append(underwater_area)
Ejemplo n.º 30
0
    def generate_union_safe(self, groups):
        """
        Unions a series of groups.

        This is used for generation of interways, as the resulting union interiors are the target areas.
        """
        try:
            union = groups.copy().union_replace()
            union = union.clean(eps=0.01)
        except TopologicalError as e:
            logger.debug("Error calculating safe union_safe (1/3): %s", e)
            children_unions = []
            for g in groups.children:
                u = g.clean(eps=0.01).union()
                children_unions.append(u)
            try:
                union = ddd.group2(children_unions)
                union = union.union()
            except TopologicalError as e:
                logger.error("Error calculating union_safe (2/3): %s", e)
                #union = groups.clean(eps=0.05).union()  # causes areas overlap?
                #union = ddd.group2()
        return union