def features_init(pipeline, root, logger): features = ddd.group2(name="Features2") root.append(features) features3 = ddd.group2(name="Features3") root.append(features3)
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 '''
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)
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) """
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)
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)
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)
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)
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
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")
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
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)
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")
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)
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
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)
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)
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")
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)
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)
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)
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)
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)
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)
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)
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
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)
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'] = {}
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)
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