예제 #1
0
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
예제 #2
0
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")
예제 #3
0
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")