def parse_way(self, way): """Parse a way element and create the corresponding object.""" osmId = way.attrib['id'] tags = self.get_tags(way) refs = [] for ref in way.findall('nd'): refs.append(ref.attrib['ref']) self.wayRefList[ osmId] = refs # we need to store them because the can then be usefull when parsin 'relations' # dont take into acount underground structure if float(tags.get('layer', '0')) < 0: return if 'building' in tags or 'building:part' in tags: Building.add_to_list(osmId, tags, refs) elif 'highway' in tags: Road.add_to_list(osmId, tags, refs) elif tags.get('waterway') == 'river' or tags.get( 'waterway') == 'stream': River.add_to_list(osmId, tags, refs) elif tags.get('barrier') == 'fence' or tags.get('barrier') == 'wall': Barrier.add_to_list(osmId, tags, refs) elif 'natural' in tags: Area.add_to_list(osmId, tags['natural'], tags, refs) elif 'landuse' in tags: Area.add_to_list(osmId, tags['landuse'], tags, refs) elif 'waterway' in tags: Area.add_to_list(osmId, tags['waterway'], tags, refs) elif 'amenity' in tags and tags['amenity'] == 'parking': Area.add_to_list(osmId, 'parking', tags, refs) elif 'name' in tags and tags['name'] == 'parking line': ParkingLines.add_to_list(osmId, tags, refs)
def export(cls, file): """Export all the trees from the trees list.""" for tree in Tree.list[:]: if WebotsObject.removalRadius > 0.0: # Check that the tree is inside the scope of a road, # otherwise, remove it from the tree list. if not Road.are_coords_close_to_some_road_waypoint( [[tree.coord.x, tree.coord.z]], areOSMReferences=False): Tree.list.remove(tree) continue file.write('SimpleTree {\n') if tree.leafType == 'needleleaved': file.write(' type "%s"\n' % random.choice(Tree.needleLeavesTypes)) elif tree.leafType == 'broadleaved': file.write(' type "%s"\n' % random.choice(Tree.broadLeavesTypes)) else: file.write(' type "random"\n') file.write(' rotation 0 1 0 %.3f\n' % (random.random() * 2 * math.pi)) file.write(' translation %.2f %.2f %.2f\n' % (tree.coord.x, tree.coord.y, tree.coord.z)) file.write(' name "tree(%d)"\n' % Tree.nameIndex) Tree.nameIndex += 1 file.write(' enableBoundingObject FALSE\n') if tree.height is not None: file.write(' height %.3f\n' % (tree.height)) if tree.radius is not None: file.write(' radius %.3f\n' % (tree.radius)) elif tree.height is not None: file.write(' radius %.3f\n' % (tree.height / 2.0)) file.write('}\n')
def export(cls, file): """Export all the parking lines from the parking lines list.""" for parkingLines in ParkingLines.list[:]: if len(parkingLines.ref) != 2: ParkingLines.list.remove(parkingLines) continue if WebotsObject.removalRadius > 0.0: # Check that the parking lines is inside the scope of a road, # otherwise, remove it from the parking lines list. if not Road.are_coords_close_to_some_road_waypoint(parkingLines.ref): ParkingLines.list.remove(parkingLines) continue # Coordinates extration c0 = (OSMCoord.coordDictionnary[parkingLines.ref[0]].x, OSMCoord.coordDictionnary[parkingLines.ref[0]].y, OSMCoord.coordDictionnary[parkingLines.ref[0]].z) c1 = (OSMCoord.coordDictionnary[parkingLines.ref[1]].x, OSMCoord.coordDictionnary[parkingLines.ref[1]].y, OSMCoord.coordDictionnary[parkingLines.ref[1]].z) # Compute the length and the angle v0 = Vector2D(c0[0], c0[2]) v1 = Vector2D(c1[0], c1[2]) deltaV = v0 - v1 length = deltaV.norm() angle = - deltaV.angle() + math.pi expectedCarParkWidth = 2.4 nCarParks = int((length + expectedCarParkWidth // 2) // expectedCarParkWidth) # cf. http://stackoverflow.com/questions/3950372/round-with-integer-division carParkWidth = length / nCarParks file.write("ParkingLines {\n") file.write(" translation %.2lf %.2lf %.2lf\n" % (c0[0], c0[1] + 0.01, c0[2])) file.write(" rotation 0 1 0 %.2lf\n" % (angle)) file.write(" numberOfCarParks %d\n" % (nCarParks)) file.write(" carParkWidth %f\n" % (carParkWidth)) file.write("}\n")
def export(cls, file): """Export all the rivers from the rivers list.""" for river in River.list[:]: if not river.ref: River.list.remove(river) continue if WebotsObject.removalRadius > 0.0: # Check that the river is inside the scope of a road, # otherwise, remove it from the river list. if not Road.are_coords_close_to_some_road_waypoint(river.ref): River.list.remove(river) continue if not river.name == "": file.write("DEF " + protect_def_name(river.name) + " " + "Transform {\n") else: file.write("Transform {\n") file.write(" translation %.2lf %.2lf %.2lf\n" % (OSMCoord.coordDictionnary[river.ref[0]].x, OSMCoord.coordDictionnary[river.ref[0]].y, OSMCoord.coordDictionnary[river.ref[0]].z)) file.write(" children [\n") file.write(" Shape {\n") file.write(" appearance PBRAppearance {\n") file.write(" baseColor 0.3 0.5 0.8\n") file.write(" roughness 0.3\n") file.write(" metalness 0\n") file.write(" }\n") file.write(" geometry Extrusion {\n") file.write(" crossSection [\n") file.write(" %.2f 0\n" % (-river.width / 2)) file.write(" %.2f 0.5\n" % (-river.width / 2)) file.write(" %.2f 0.5\n" % (river.width / 2)) file.write(" %.2f 0\n" % (river.width / 2)) file.write(" %.2f 0\n" % (-river.width / 2)) file.write(" ]\n") file.write(" spine [\n") for ref in river.ref: if ref in OSMCoord.coordDictionnary: file.write(" %.2f %.2f %.2f,\n" % (OSMCoord.coordDictionnary[ref].x - OSMCoord.coordDictionnary[river.ref[0]].x, OSMCoord.coordDictionnary[ref].y - OSMCoord.coordDictionnary[river.ref[0]].y, OSMCoord.coordDictionnary[ref].z - OSMCoord.coordDictionnary[river.ref[0]].z)) else: print("Warning: node " + str(ref) + " not referenced.") file.write(" ]\n") file.write(" splineSubdivision 0\n") file.write(" }\n") file.write(" castShadows FALSE\n") file.write(" }\n") file.write(" ]\n") file.write("}\n")
def export(cls, file, noParkings): """Export all the areas from the areas list.""" for area in Area.list[:]: if noParkings and area.type == 'parking': Area.list.remove(area) continue if WebotsObject.removalRadius > 0.0: # Check that the area is inside the scope of a road, # otherwise, remove it from the area list. if not Road.are_coords_close_to_some_road_waypoint(area.ref): Area.list.remove(area) continue defName = "" if not area.name == "": defName = area.name else: defName = area.type defName = protect_def_name(defName) if area.type == 'forest' and not Area.noForests: treesFile = area.generate_tree_file(os.path.dirname(os.path.abspath(file.name))) if file is not None: file.write("Forest {\n") file.write(" shape [\n") if Area.are_references_clockwise(area.ref) is False: for ref in area.ref: file.write(" %.2f %.2f, " % (OSMCoord.coordDictionnary[ref].x, OSMCoord.coordDictionnary[ref].z)) else: for ref in reversed(area.ref): file.write(" %.2f %.2f, " % (OSMCoord.coordDictionnary[ref].x, OSMCoord.coordDictionnary[ref].z)) file.write("\n]\n") if area.leafType == "needleleaved": file.write(' type "%s"\n' % random.choice(Tree.needleLeavesTypes)) elif area.leafType == "broadleaved": file.write(' type "%s"\n' % random.choice(Tree.broadLeavesTypes)) else: file.write(" type \"random\"\n") file.write(" treesFiles [\n") file.write(" " + "\"" + treesFile + "\"" + "\n") file.write(" ]\n") file.write("}\n") else: verticalOffset = -0.01 if area.type == 'parking' else 0.0 drawFlat = True if area.type == 'water' else False Area.draw_area(file, area.ref, area.color[0], area.color[1], area.color[2], defName, area.transparency, area.texture, verticalOffset=verticalOffset, drawFlat=drawFlat)
maxlat=maxlat, maxlon=maxlon, elevation=elevation) print(" * Elevation data acquired") else: print_header(outputFile, minlat=minlat, minlon=minlon, maxlat=maxlat, maxlon=maxlon) WebotsObject.elevation = elevation # parse OSM file parser = Parser() parser.parse_file(options.inFile, options.disableMultipolygonBuildings) Road.initialize_speed_limit(parser.country) print(" * OSM filed parsed") if options.enable3D and elevation is not None: add_height_to_coordinates( elevation) # important to do it before 'center_coordinates' xOffset, zOffset = OSMCoord.center_coordinates(minlat=minlat, minlon=minlon, maxlat=maxlat, maxlon=maxlon) WebotsObject.xOffset = xOffset WebotsObject.zOffset = zOffset # From now we are in local coordinates system and not earth coordinates system anymore
def export(cls, file): """Export all the barriers from the barriers list.""" for barrier in Barrier.list[:]: if not barrier.ref: Barrier.list.remove(barrier) continue if WebotsObject.removalRadius > 0.0: # Check that the barrier is inside the scope of a road, # otherwise, remove it from the barrier list. if not Road.are_coords_close_to_some_road_waypoint( barrier.ref): Barrier.list.remove(barrier) continue if barrier.type == 'fence': file.write('Fence {\n') file.write(' name "fence(%d)"\n' % Barrier.fenceNameIndex) Barrier.fenceNameIndex += 1 file.write(' height %.2f\n' % barrier.height) file.write(' path [\n') for ref in barrier.ref: if ref in OSMCoord.coordDictionnary: file.write(' %.2f %.2f %.2f,\n' % (OSMCoord.coordDictionnary[ref].x, OSMCoord.coordDictionnary[ref].y, OSMCoord.coordDictionnary[ref].z)) else: print('Warning: node ' + str(ref) + ' not referenced.') file.write(' ]\n') file.write(' splineSubdivision 0\n') file.write('}\n') elif barrier.type == 'wall': file.write('Solid {\n') file.write(' translation 0 %.2f 0\n' % (barrier.height / 2)) file.write(' children [\n') file.write(' DEF SHAPE Shape {\n') file.write(' appearance PBRAppearance {\n') file.write(' baseColorMap ImageTexture {\n') file.write(' url [ "textures/red_brick_wall.jpg" ]\n') file.write(' }\n') file.write(' roughness 1\n') file.write(' metalness 0\n') file.write(' textureTransform TextureTransform {\n') file.write(' scale %.1f %.1f\n' % (barrier.length(), barrier.height)) file.write(' }\n') file.write(' }\n') file.write(' geometry Extrusion {\n') file.write(' crossSection [\n') file.write(' %.2f %.2f\n' % ((barrier.width / 2), (barrier.height / 2))) file.write(' %.2f %.2f\n' % ((barrier.width / 2), (-barrier.height / 2))) file.write(' %.2f %.2f\n' % ((-barrier.width / 2), (-barrier.height / 2))) file.write(' %.2f %.2f\n' % ((-barrier.width / 2), (barrier.height / 2))) file.write(' %.2f %.2f\n' % ((barrier.width / 2), (barrier.height / 2))) file.write(' ]\n') file.write(' spine [\n') for ref in barrier.ref: if ref in OSMCoord.coordDictionnary: file.write(' %.2f %.2f %.2f,\n' % (OSMCoord.coordDictionnary[ref].x, OSMCoord.coordDictionnary[ref].y, OSMCoord.coordDictionnary[ref].z)) else: print('Warning: node ' + str(ref) + ' not referenced.') file.write(' ]\n') file.write(' splineSubdivision 0\n') file.write(' }\n') file.write(' }\n') file.write(' ]\n') file.write(' name "wall(%d)"\n' % Barrier.wallNameIndex) Barrier.wallNameIndex += 1 file.write(' boundingObject USE SHAPE\n') file.write('}\n')
def export(cls, file): """Export all the buildings from the buildings list.""" for building in Building.list[:]: settingsSection = Settings.get_section('building', building.type) if settingsSection is None or len(building.ref) < 1: Building.list.remove(building) continue if WebotsObject.removalRadius > 0.0: # Check that the building is inside the scope of a road, # otherwise, remove it from the building list. if not Road.are_coords_close_to_some_road_waypoint(building.ref): Building.list.remove(building) continue if building.height > 0 and building.levels < 0: building.levels = int(building.height / 3.0) file.write("SimpleBuilding {\n") # set the height of the building to be the height of the minimum corner if WebotsObject.enable3D: height = float('inf') for ref in building.ref: if ref in OSMCoord.coordDictionnary and OSMCoord.coordDictionnary[ref].y < height: height = OSMCoord.coordDictionnary[ref].y if height == float('inf'): height = 0 height = height + building.layer * WebotsObject.layerHeight file.write(" translation %.2lf %.2lf %.2lf\n" % (OSMCoord.coordDictionnary[building.ref[0]].x, height, OSMCoord.coordDictionnary[building.ref[0]].z)) else: file.write(" translation %.2lf %.2lf %.2lf\n" % (OSMCoord.coordDictionnary[building.ref[0]].x, building.layer * WebotsObject.layerHeight, OSMCoord.coordDictionnary[building.ref[0]].z)) name = building.name if name != '' and building.number != '': name += ' ' + building.number if name == '': name = "building(%d)" % Building.nameIndex Building.nameIndex += 1 else: newName = name i = 1 while newName in Building.nameList: newName = name + '(%d)' % i i += 1 Building.nameList.append(newName) name = newName name = name.replace('"', '') file.write(' name "%s"\n' % name) file.write(" corners [\n") for ref in building.ref: if ref in OSMCoord.coordDictionnary: file.write(" %.2f %.2f,\n" % (OSMCoord.coordDictionnary[ref].x - OSMCoord.coordDictionnary[building.ref[0]].x, OSMCoord.coordDictionnary[ref].z - OSMCoord.coordDictionnary[building.ref[0]].z)) else: print("Warning: node " + str(ref) + " not referenced.") file.write(" ]\n") # Set the roofShape if building.roofShape in building.importedRoofShapes: file.write(' roofShape "%s"\n' % building.importedRoofShapes[building.roofShape]) elif Settings.has_option(settingsSection, 'roofShape'): file.write(" roofShape " + Settings.get(settingsSection, 'roofShape') + "\n") else: if len(building.ref) <= 4: file.write(" roofShape \"pyramidal roof\"\n") else: file.write(" roofShape \"flat roof\"\n") # Set the wallType if building.material in building.importedWallTypes and building.importedWallTypes[building.material] in building.coloredWallTypes and building.color != "": file.write(" wallType \"%s\"\n" % building.importedWallTypes[building.material]) elif building.color != "": file.write(' wallType "%s"\n' % random.choice(building.coloredWallTypes)) elif building.material in building.importedWallTypes: file.write(" wallType \"%s\"\n" % building.importedWallTypes[building.material]) elif Settings.has_option(settingsSection, 'wallType'): file.write(" wallType " + Settings.get(settingsSection, 'wallType') + "\n") else: file.write(" wallType \"random\"\n") # Set the roofType if building.roofMaterial in building.coloredRoofTypes and building.importedRoofTypes[building.roofMaterial] in building.coloredRoofTypes and building.roofColor != "": file.write(' roofType "%s"\n' % building.importedRoofTypes[building.roofMaterial]) elif building.roofColor != "": file.write(' roofType "%s"\n' % random.choice(building.coloredRoofTypes)) elif building.roofMaterial in building.importedRoofTypes: file.write(' roofType "%s"\n' % building.importedRoofTypes[building.roofMaterial]) elif Settings.has_option(settingsSection, 'roofType'): file.write(" roofType " + Settings.get(settingsSection, 'roofType') + "\n") # Set the wallColor if building.color != '': file.write(" wallColor [ %.2f %.2f %.2f ]\n" % (building.red, building.green, building.blue)) # Set the roofColor if building.roofColor != '': file.write(" wallColor [ %.2f %.2f %.2f ]\n" % (building.roofRed, building.roofGreen, building.roofBlue)) # Set the roofHeight if building.roofHeight > 0: file.write(" roofHeight %.2f\n" % building.roofHeight) elif Settings.has_option(settingsSection, 'roofHeight'): file.write(" roofHeight " + Settings.getfloat(settingsSection, 'roofHeight') + "\n") # Set the levels if building.levels > 0: file.write(" floorNumber " + str(building.levels) + "\n") elif Settings.has_option(settingsSection, 'floorNumber'): building.levels = Settings.getfloat(settingsSection, 'floorNumber') file.write(" floorNumber " + Settings.get(settingsSection, 'floorNumber') + "\n") # Set the startingFloor if building.minHeight > 0 and building.levels > 0: file.write(" startingFloor %d\n" % int(building.minHeight / building.height * building.levels)) file.write(" bottom TRUE\n") elif building.minLevel is not None: file.write(" startingFloor " + str(building.minLevel) + "\n") file.write(" bottom TRUE\n") elif building.layer > 0: file.write(" bottom TRUE\n") # Set the floorHeight if building.height > 0: if building.levels > 0: file.write(" floorHeight %.2f\n" % (building.height / building.levels)) else: file.write(" floorHeight %.2f\n" % (building.height / 3)) elif Settings.has_option(settingsSection, 'floorHeight'): file.write(" floorHeight " + Settings.get(settingsSection, 'floorHeight') + "\n") file.write("}\n")