def readRaster(rastPath, bandIndex=1, dataType=np.int16): name, ext = path.splitext(rastPath) rast = raster.Raster() if ext == ".asc" or ext == ".txt": rast.read(rastPath) else: # try: rasters = raster.readGDAL(rastPath, bandIndex=1, dataType=dataType) rast = rasters[0] # except: # raise IOError("Could not read raster %s using GDAL,"+ # " try using gdal_translate to change format") # sys.exit(1) return rast
def main(): # Parse command line arguments parser = argparse.ArgumentParser(description=__doc__) utils.add_standard_command_options(parser) parser.add_argument( "-f", "--format", action="store", dest="format", default="ESRI Shapefile", help="Format of road network" ) parser.add_argument("--inRoads", required=True, action="store", dest="inRoads", help="Input road network") parser.add_argument("--outRoads", required=True, action="store", dest="outRoads", help="Output road network") parser.add_argument( "--buildings", required=True, action="store", dest="buildings", help="Input building roof contours (3D)" ) parser.add_argument("--topo", required=True, action="store", dest="topo", help="Input raster DEM") parser.add_argument( "--split", type=int, action="store", dest="split", help="Threshold in changed road direction (degrees)" + " for when to split road", ) args = parser.parse_args() if not path.exists(args.topo): log.error("Input raster does not exist") sys.exit(1) if not path.exists(args.buildings): log.error("Input building contours does not exist") sys.exit(1) return 1 log.info("Reading DEM") topo = readGDAL(args.topo, bandIndex=1)[0] # Opening driver for road networks try: driver = ogr.GetDriverByName(args.format) except: log.error("Invalid format for road networks, check ogr documentation") sys.exit(1) if args.split is None: log.info("Do not split roads") splitLimit = None else: splitLimit = float(args.split) log.info("Split roads that change direction" + " more than %f" % splitLimit) # extract extent from topo raster xmin = topo.xll ymin = topo.yll xmax = topo.xur() ymax = topo.yur() # Calculate dimensions of spatial index ncols = int((xmax - xmin) / CELLSIZE) nrows = int((ymax - ymin) / CELLSIZE) # Init spatial index of building contours spatInd = SpatialIndex(xmin, ymin, nrows, ncols, CELLSIZE) log.info("Reading and indexing building contours") # Read buildings and store using spatial indices spatInd.indexBuildingContours(args.buildings) # open road network shape-file log.info("Reading road network") inRoadFile = driver.Open(args.inRoads, update=0) if path.exists(args.outRoads): driver.DeleteDataSource(args.outRoads) outRoadFile = driver.CreateDataSource(args.outRoads) if inRoadFile is None: log.error("Could not open file with input road network") sys.exit(1) if outRoadFile is None: log.error("Could not open file with output road network") sys.exit(1) # Get layer definition and first feature of input road network inRoadLayer = inRoadFile.GetLayer() inRoadLayerDefn = inRoadLayer.GetLayerDefn() outRoadLayer = outRoadFile.CreateLayer("first_layer", geom_type=inRoadLayer.GetGeomType()) # create fields on output road file for fieldInd in range(inRoadLayerDefn.GetFieldCount()): fieldDefn = inRoadLayerDefn.GetFieldDefn(fieldInd) outRoadLayer.CreateField(fieldDefn) outRoadLayerDefn = outRoadLayer.GetLayerDefn() fieldNames = [outRoadLayerDefn.GetFieldDefn(i).GetName() for i in range(outRoadLayerDefn.GetFieldCount())] log.info("Adding attributes to road feature (if missing)") # Add attributes for street canyon geometry if "BHGT1" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT1", ogr.OFTInteger)) if "BHGT2" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT2", ogr.OFTInteger)) if "BHGT1W" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT1W", ogr.OFTInteger)) if "BHGT2W" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT2W", ogr.OFTInteger)) if "BANG1" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BANG1", ogr.OFTInteger)) if "BANG2" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BANG2", ogr.OFTInteger)) if "BDIST" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BDIST", ogr.OFTInteger)) if "BSECT" not in fieldNames: fieldDefn = ogr.FieldDefn("BSECT", ogr.OFTString) fieldDefn.SetWidth(40) outRoadLayer.CreateField(fieldDefn) if "BSECTW" not in fieldNames: fieldDefn = ogr.FieldDefn("BSECTW", ogr.OFTString) fieldDefn.SetWidth(40) outRoadLayer.CreateField(fieldDefn) fig1 = plt.figure(1) ax1 = plt.subplot(111) ax1.axis("equal") if PLOTIND > 0: spatInd.plot(ax1) roadInd = 0 noGeom = 0 nsplit = 0 # get first road feature inRoadFeature = inRoadLayer.GetNextFeature() # Loop over all roads log.info("Finding nearest facades, setting heights...") pg = ProgressBar(inRoadLayer.GetFeatureCount(), sys.stdout) while inRoadFeature: pg.update(roadInd) outRoadFeatures = splitRoad(inRoadFeature, splitLimit, outRoadLayer.GetLayerDefn()) if len(outRoadFeatures) > 1: log.debug("Raod split into %s parts" % len(outRoadFeatures)) nsplit += len(outRoadFeatures) - 1 for outRoadFeature in outRoadFeatures: intersections = [] outRoadGeom = outRoadFeature.GetGeometryRef() road = Road(outRoadGeom) if outRoadGeom is None or outRoadGeom.GetPointCount() == 0 or not spatInd.inside(road): noGeom += 1 maxHeight1 = None maxHeight2 = None avgDist = None bAngle1 = None bAngle2 = None avgHeight1 = None avgHeight2 = None else: sumHeight1 = 0 sumHeight2 = 0 maxHeight1 = 0 maxHeight2 = 0 sumDist = 0 # Define crossections along the road, # Defined by start and endpoints at both side of the road cs1List, cs2List = road.defineCrossSections() nCS = len(cs1List) log.debug("Defined %i cross sections" % nCS) # Check intersections with building contours for all cross-sections for csInd in range(nCS): cs1 = cs1List[csInd] cs2 = cs2List[csInd] cs1MidPoint = cs1.P0 + 0.5 * (cs1.P1 - cs1.P0) buildingSegments = spatInd.getBuildingSegments(cs1MidPoint[0], cs1MidPoint[1]) log.debug("Calculating intersection") if PLOTIND == roadInd and CSIND == csInd: dist1, Pint1 = getIntersectingFacade(ax1, cs1, buildingSegments, True) else: dist1, Pint1 = getIntersectingFacade(ax1, cs1, buildingSegments, False) if Pint1 is None: log.debug("No intersection on side 1") height1 = 0 dist1 = MAXDIST else: log.debug("Intersection1 in (%f, %f, %f)" % (Pint1[0], Pint1[1], Pint1[2])) height1 = spatInd.getBuildingHeight(Pint1[0], Pint1[1], Pint1[2], topo) + HEIGHTCORR intersections.append(Pint1[:2]) if PLOTIND == roadInd and csInd == CSIND: plotSegments(ax1, buildingSegments, color="red", width=2.0) row, col = spatInd.getInd(cs1MidPoint[0], cs1MidPoint[1]) spatInd.plotCell(ax1, row, col, color="purple", width=2.0) plotSegments(ax1, [cs1List[csInd]], color="pink", style="-", width=1.0) plt.draw() cs2MidPoint = cs2.P0 + 0.5 * (cs2.P1 - cs2.P0) buildingSegments = spatInd.getBuildingSegments(cs2MidPoint[0], cs2MidPoint[1]) if PLOTIND == roadInd and csInd == CSIND: plotSegments(ax1, buildingSegments, color="red", width=2.0) row, col = spatInd.getInd(cs2MidPoint[0], cs2MidPoint[1]) spatInd.plotCell(ax1, row, col, color="brown", width=2.0) plotSegments(ax1, [cs2List[csInd]], color="red", style="-", width=1.0) plt.draw() log.debug("Calculating intersection") if PLOTIND == roadInd and CSIND == csInd: dist2, Pint2 = getIntersectingFacade(ax1, cs2, buildingSegments, True) else: dist2, Pint2 = getIntersectingFacade(ax1, cs2, buildingSegments, False) if Pint2 is None: log.debug("No intersection on side 2") height2 = 0 else: log.debug("Intersection2 in (%f, %f, %f)" % (Pint2[0], Pint2[1], Pint2[2])) height2 = spatInd.getBuildingHeight(Pint2[0], Pint2[1], Pint2[2], topo) + HEIGHTCORR intersections.append(Pint2[:2]) sumHeight1 += height1 sumHeight2 += height2 sumDist += dist1 + dist2 maxHeight1 = int(max(height1, maxHeight1)) maxHeight2 = int(max(height2, maxHeight2)) if PLOTIND == roadInd and CSIND == csInd: if Pint1 is not None: ax1.text(Pint1[0], Pint1[1], "Distance=%f" % dist1) if Pint2 is not None: ax1.text(Pint2[0], Pint2[1], "Distance=%f" % dist2) avgHeight1 = int(sumHeight1 / float(nCS)) avgHeight2 = int(sumHeight2 / float(nCS)) # averaging over both sides of street # distance refers to between facades on opposite sides avgDist = int(round(sumDist / float(nCS))) bAngle1, bAngle2 = road.normalAngles() if PLOTIND > 0: plotSegments(ax1, road.getSegments(), color="grey", width=0.3) if PLOTIND == roadInd: plotSegments(ax1, road.getSegments(), color="black", width=2.0) plotSegments(ax1, cs1List, color="green", style="--", width=0.5) plotSegments(ax1, cs2List, color="green", style="--", width=0.5) X = [intersect[0] for intersect in intersections] Y = [intersect[1] for intersect in intersections] if len(X) > 0: ax1.plot(X, Y, "*") plt.title("Road %i, cross-section %i" % (PLOTIND, CSIND)) plt.draw() # building height as list of sectors bsect = bheight2sect(avgHeight1, avgHeight2, bAngle1) bsectw = bheight2sect(maxHeight1, maxHeight2, bAngle1) outRoadFeature.SetField("BSECT", bsect) outRoadFeature.SetField("BSECTW", bsectw) outRoadFeature.SetField("BHGT1", avgHeight1) outRoadFeature.SetField("BHGT2", avgHeight2) outRoadFeature.SetField("BHGT1W", maxHeight1) outRoadFeature.SetField("BHGT2W", maxHeight2) outRoadFeature.SetField("BANG1", bAngle1) outRoadFeature.SetField("BANG2", bAngle2) outRoadFeature.SetField("BDIST", avgDist) outRoadLayer.CreateFeature(outRoadFeature) outRoadFeature.Destroy() inRoadFeature.Destroy() inRoadFeature = inRoadLayer.GetNextFeature() roadInd += 1 inRoads = inRoadLayer.GetFeatureCount() outRoads = outRoadLayer.GetFeatureCount() # close datasource for building contours inRoadFile.Destroy() outRoadFile.Destroy() pg.finished() if PLOTIND > 0: plt.show() log.info("Read %i roads, wrote %i roads (created %i by splitting)" % (inRoads, outRoads, nsplit)) if noGeom > 0: log.warning("Found %i roads without geometry" % noGeom) log.info("Finished")
def main(): # Parse command line arguments parser = argparse.ArgumentParser(description=__doc__) utils.add_standard_command_options(parser) parser.add_argument("-f", "--format", action="store", dest="format", default="ESRI Shapefile", help="Format of road network") parser.add_argument("--inRoads", required=True, action="store", dest="inRoads", help="Input road network") parser.add_argument("--outRoads", required=True, action="store", dest="outRoads", help="Output road network") parser.add_argument("--buildings", required=True, action="store", dest="buildings", help="Input building roof contours (3D)") parser.add_argument("--topo", required=True, action="store", dest="topo", help="Input raster DEM") parser.add_argument("--split", type=int, action="store", dest="split", help="Threshold in changed road direction (degrees)" + " for when to split road") args = parser.parse_args() if not path.exists(args.topo): log.error("Input raster does not exist") sys.exit(1) if not path.exists(args.buildings): log.error("Input building contours does not exist") sys.exit(1) return 1 log.info("Reading DEM") topo = readGDAL(args.topo, bandIndex=1)[0] # Opening driver for road networks try: driver = ogr.GetDriverByName(args.format) except: log.error("Invalid format for road networks, check ogr documentation") sys.exit(1) if args.split is None: log.info("Do not split roads") splitLimit = None else: splitLimit = float(args.split) log.info("Split roads that change direction" + " more than %f" % splitLimit) # extract extent from topo raster xmin = topo.xll ymin = topo.yll xmax = topo.xur() ymax = topo.yur() # Calculate dimensions of spatial index ncols = int((xmax - xmin) / CELLSIZE) nrows = int((ymax - ymin) / CELLSIZE) # Init spatial index of building contours spatInd = SpatialIndex(xmin, ymin, nrows, ncols, CELLSIZE) log.info("Reading and indexing building contours") # Read buildings and store using spatial indices spatInd.indexBuildingContours(args.buildings) # open road network shape-file log.info("Reading road network") inRoadFile = driver.Open(args.inRoads, update=0) if path.exists(args.outRoads): driver.DeleteDataSource(args.outRoads) outRoadFile = driver.CreateDataSource(args.outRoads) if inRoadFile is None: log.error("Could not open file with input road network") sys.exit(1) if outRoadFile is None: log.error("Could not open file with output road network") sys.exit(1) # Get layer definition and first feature of input road network inRoadLayer = inRoadFile.GetLayer() inRoadLayerDefn = inRoadLayer.GetLayerDefn() outRoadLayer = outRoadFile.CreateLayer("first_layer", geom_type=inRoadLayer.GetGeomType()) # create fields on output road file for fieldInd in range(inRoadLayerDefn.GetFieldCount()): fieldDefn = inRoadLayerDefn.GetFieldDefn(fieldInd) outRoadLayer.CreateField(fieldDefn) outRoadLayerDefn = outRoadLayer.GetLayerDefn() fieldNames = [ outRoadLayerDefn.GetFieldDefn(i).GetName() for i in range(outRoadLayerDefn.GetFieldCount()) ] log.info("Adding attributes to road feature (if missing)") # Add attributes for street canyon geometry if "BHGT1" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT1", ogr.OFTInteger)) if "BHGT2" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT2", ogr.OFTInteger)) if "BHGT1W" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT1W", ogr.OFTInteger)) if "BHGT2W" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BHGT2W", ogr.OFTInteger)) if "BANG1" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BANG1", ogr.OFTInteger)) if "BANG2" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BANG2", ogr.OFTInteger)) if "BDIST" not in fieldNames: outRoadLayer.CreateField(ogr.FieldDefn("BDIST", ogr.OFTInteger)) if "BSECT" not in fieldNames: fieldDefn = ogr.FieldDefn("BSECT", ogr.OFTString) fieldDefn.SetWidth(40) outRoadLayer.CreateField(fieldDefn) if "BSECTW" not in fieldNames: fieldDefn = ogr.FieldDefn("BSECTW", ogr.OFTString) fieldDefn.SetWidth(40) outRoadLayer.CreateField(fieldDefn) fig1 = plt.figure(1) ax1 = plt.subplot(111) ax1.axis('equal') if PLOTIND > 0: spatInd.plot(ax1) roadInd = 0 noGeom = 0 nsplit = 0 # get first road feature inRoadFeature = inRoadLayer.GetNextFeature() # Loop over all roads log.info("Finding nearest facades, setting heights...") pg = ProgressBar(inRoadLayer.GetFeatureCount(), sys.stdout) while inRoadFeature: pg.update(roadInd) outRoadFeatures = splitRoad(inRoadFeature, splitLimit, outRoadLayer.GetLayerDefn()) if len(outRoadFeatures) > 1: log.debug("Raod split into %s parts" % len(outRoadFeatures)) nsplit += len(outRoadFeatures) - 1 for outRoadFeature in outRoadFeatures: intersections = [] outRoadGeom = outRoadFeature.GetGeometryRef() road = Road(outRoadGeom) if outRoadGeom is None or \ outRoadGeom.GetPointCount() == 0 or not spatInd.inside(road): noGeom += 1 maxHeight1 = None maxHeight2 = None avgDist = None bAngle1 = None bAngle2 = None avgHeight1 = None avgHeight2 = None else: sumHeight1 = 0 sumHeight2 = 0 maxHeight1 = 0 maxHeight2 = 0 sumDist = 0 # Define crossections along the road, # Defined by start and endpoints at both side of the road cs1List, cs2List = road.defineCrossSections() nCS = len(cs1List) log.debug("Defined %i cross sections" % nCS) # Check intersections with building contours for all cross-sections for csInd in range(nCS): cs1 = cs1List[csInd] cs2 = cs2List[csInd] cs1MidPoint = cs1.P0 + 0.5 * (cs1.P1 - cs1.P0) buildingSegments = spatInd.getBuildingSegments( cs1MidPoint[0], cs1MidPoint[1]) log.debug("Calculating intersection") if PLOTIND == roadInd and CSIND == csInd: dist1, Pint1 = getIntersectingFacade( ax1, cs1, buildingSegments, True) else: dist1, Pint1 = getIntersectingFacade( ax1, cs1, buildingSegments, False) if Pint1 is None: log.debug("No intersection on side 1") height1 = 0 dist1 = MAXDIST else: log.debug("Intersection1 in (%f, %f, %f)" % (Pint1[0], Pint1[1], Pint1[2])) height1 = spatInd.getBuildingHeight( Pint1[0], Pint1[1], Pint1[2], topo) + HEIGHTCORR intersections.append(Pint1[:2]) if PLOTIND == roadInd and csInd == CSIND: plotSegments(ax1, buildingSegments, color='red', width=2.0) row, col = spatInd.getInd(cs1MidPoint[0], cs1MidPoint[1]) spatInd.plotCell(ax1, row, col, color="purple", width=2.0) plotSegments(ax1, [cs1List[csInd]], color="pink", style="-", width=1.0) plt.draw() cs2MidPoint = cs2.P0 + 0.5 * (cs2.P1 - cs2.P0) buildingSegments = spatInd.getBuildingSegments( cs2MidPoint[0], cs2MidPoint[1]) if PLOTIND == roadInd and csInd == CSIND: plotSegments(ax1, buildingSegments, color='red', width=2.0) row, col = spatInd.getInd(cs2MidPoint[0], cs2MidPoint[1]) spatInd.plotCell(ax1, row, col, color="brown", width=2.0) plotSegments(ax1, [cs2List[csInd]], color="red", style="-", width=1.0) plt.draw() log.debug("Calculating intersection") if PLOTIND == roadInd and CSIND == csInd: dist2, Pint2 = getIntersectingFacade( ax1, cs2, buildingSegments, True) else: dist2, Pint2 = getIntersectingFacade( ax1, cs2, buildingSegments, False) if Pint2 is None: log.debug("No intersection on side 2") height2 = 0 else: log.debug("Intersection2 in (%f, %f, %f)" % (Pint2[0], Pint2[1], Pint2[2])) height2 = spatInd.getBuildingHeight( Pint2[0], Pint2[1], Pint2[2], topo) + HEIGHTCORR intersections.append(Pint2[:2]) sumHeight1 += height1 sumHeight2 += height2 sumDist += dist1 + dist2 maxHeight1 = int(max(height1, maxHeight1)) maxHeight2 = int(max(height2, maxHeight2)) if PLOTIND == roadInd and CSIND == csInd: if Pint1 is not None: ax1.text(Pint1[0], Pint1[1], "Distance=%f" % dist1) if Pint2 is not None: ax1.text(Pint2[0], Pint2[1], "Distance=%f" % dist2) avgHeight1 = int(sumHeight1 / float(nCS)) avgHeight2 = int(sumHeight2 / float(nCS)) # averaging over both sides of street # distance refers to between facades on opposite sides avgDist = int(round(sumDist / float(nCS))) bAngle1, bAngle2 = road.normalAngles() if PLOTIND > 0: plotSegments(ax1, road.getSegments(), color='grey', width=0.3) if PLOTIND == roadInd: plotSegments(ax1, road.getSegments(), color='black', width=2.0) plotSegments(ax1, cs1List, color="green", style="--", width=0.5) plotSegments(ax1, cs2List, color="green", style="--", width=0.5) X = [intersect[0] for intersect in intersections] Y = [intersect[1] for intersect in intersections] if len(X) > 0: ax1.plot(X, Y, "*") plt.title("Road %i, cross-section %i" % (PLOTIND, CSIND)) plt.draw() # building height as list of sectors bsect = bheight2sect(avgHeight1, avgHeight2, bAngle1) bsectw = bheight2sect(maxHeight1, maxHeight2, bAngle1) outRoadFeature.SetField("BSECT", bsect) outRoadFeature.SetField("BSECTW", bsectw) outRoadFeature.SetField("BHGT1", avgHeight1) outRoadFeature.SetField("BHGT2", avgHeight2) outRoadFeature.SetField("BHGT1W", maxHeight1) outRoadFeature.SetField("BHGT2W", maxHeight2) outRoadFeature.SetField("BANG1", bAngle1) outRoadFeature.SetField("BANG2", bAngle2) outRoadFeature.SetField("BDIST", avgDist) outRoadLayer.CreateFeature(outRoadFeature) outRoadFeature.Destroy() inRoadFeature.Destroy() inRoadFeature = inRoadLayer.GetNextFeature() roadInd += 1 inRoads = inRoadLayer.GetFeatureCount() outRoads = outRoadLayer.GetFeatureCount() # close datasource for building contours inRoadFile.Destroy() outRoadFile.Destroy() pg.finished() if PLOTIND > 0: plt.show() log.info("Read %i roads, wrote %i roads (created %i by splitting)" % (inRoads, outRoads, nsplit)) if noGeom > 0: log.warning("Found %i roads without geometry" % noGeom) log.info("Finished")