Пример #1
0
def main(args):
    '''
    Main function, invoked from either command line or qc_wrap
    '''
    pargs = parser.parse_args(args[1:])
    lasname = pargs.las_file
    kmname = constants.get_tilename(lasname)
    msg = "Running %s on block: %s, %s"
    print(msg % (os.path.basename(args[0]), kmname, time.asctime()))

    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportSpikes(pargs.use_local)

    if pargs.zlim < 0:
        print("zlim must be positive!")
        usage()

    if pargs.slope < 0 or pargs.slope >= 90:
        print("Specify a slope angle in the range 0->90 degrees.")
        usage()

    cut_class = pargs.cut_class
    print("Cutting to class (terrain) {0:d}".format(cut_class))
    pc = pointcloud.fromAny(lasname).cut_to_class(cut_class)
    if pc.get_size() < 10:
        print("Too few points in pointcloud.")
        return

    print("Sorting spatially...")
    pc.sort_spatially(FILTER_RAD)
    slope_arg = np.tan(np.radians(pargs.slope))**2
    msg = "Using steepnes parameters: angle: {0:.2f} degrees, delta-z: {1:.2f}"
    print(msg.format(pargs.slope, pargs.zlim))
    print("Filtering, radius: {0:.2f}".format(FILTER_RAD))
    dz = pc.spike_filter(FILTER_RAD, slope_arg, pargs.zlim)
    mask = (dz != 0)
    dz = dz[mask]
    pc = pc.cut(mask)
    print("Spikes: {0:d}".format(mask.sum()))
    for i in range(pc.size):
        x, y = pc.xy[i]
        z = pc.z[i]
        mdz = dz[i]
        c = pc.c[i]
        pid = pc.pid[i]
        print("spike: x: {0:.2f} y: {1:.2f} mean-dz: {2:.2f}".format(
            x, y, mdz))
        wkt_geom = "POINT({0:.2f} {1:.2f})".format(x, y)
        reporter.report(kmname,
                        FILTER_RAD,
                        mdz,
                        x,
                        y,
                        z,
                        c,
                        pid,
                        wkt_geom=wkt_geom)
Пример #2
0
def main(args):
	pargs=parser.parse_args(args[1:])
	lasname=pargs.las_file
	roadname=pargs.road_data
	cut=pargs.cut_to
	if pargs.schema is not None:
		report.set_schema(pargs.schema)
	reporter=report.ReportZcheckRoad(pargs.use_local)
	done=zcheck_base.zcheck_base(lasname,roadname,angle_tolerance,xy_tolerance,z_tolerance,cut,reporter,buffer_dist=buffer_dist,layername=pargs.layername,layersql=pargs.layersql)
Пример #3
0
def main(args):
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as e:
        print(str(e))
        return 1
    lasname = pargs.las_file
    kmname = constants.get_tilename(lasname)
    print("Running %s on block: %s, %s" % (progname, kmname, time.asctime()))
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportWobbly(pargs.use_local)
    pc = pointcloud.fromAny(lasname).cut_to_class(pargs.cut_to)
    print("%d points of class %d in this tile..." %
          (pc.get_size(), pargs.cut_to))
    if pc.get_size() < 3:
        print("Few points of class %d in this tile..." % pargs.cut_to)
        return 0
    print("Using z-limit %.2f m" % pargs.zmin)
    pc.sort_spatially(pargs.frad)
    meanz = pc.mean_filter(pargs.frad)
    diff = pc.z - meanz
    M = (np.fabs(diff) > pargs.zmin)
    n = M.sum()
    print("Found %d wobbly points" % n)
    if n > 0:
        pc = pc.cut(M)
        diff = diff[M]
        ds, lyr = polygonise_points(pc, 2 * pargs.frad, 1)
        nf = lyr.GetFeatureCount()
        for i in range(nf):
            fet = lyr.GetNextFeature()
            geom = fet.GetGeometryRef()
            arr_geom = array_geometry.ogrpoly2array(geom, flatten=True)
            N = array_geometry.points_in_polygon(pc.xy, arr_geom)
            n = N.sum()
            if n > 0:
                d = diff[N]
                m1 = d.min()
                m2 = d.max()

            else:
                m1 = -999
                m2 = -999

            reporter.report(kmname,
                            pargs.cut_to,
                            pargs.frad,
                            n,
                            m1,
                            m2,
                            ogr_geom=geom)

    return 0
Пример #4
0
def main(args):
    '''
    Main function that can be called from either the command line or via qc_wrap.py
    '''
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as error_msg:
        print(str(error_msg))
        return 1

    kmname = constants.get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (PROGNAME, kmname, time.asctime()))

    if pargs.below_poly:
        below_poly = True
        ptype = "below_poly"
    else:
        below_poly = False
    if pargs.type is not None:
        ptype = pargs.type
    else:
        ptype = "undefined"
    if below_poly:
        print("Only using points which lie below polygon mean z!")
    pc = pointcloud.fromAny(pargs.las_file)
    print("Classes in pointcloud: %s" % pc.get_classes())

    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception:
        print("Could not get extent from tilename.")
        extent = None

    polygons = vector_io.get_geometries(pargs.ref_data, pargs.layername,
                                        pargs.layersql, extent)
    feature_count = 0
    use_local = pargs.use_local

    if pargs.schema is not None:
        report.set_schema(pargs.schema)

    reporter = report.ReportClassCheck(use_local)
    for polygon in polygons:
        if below_poly:
            if polygon.GetCoordinateDimension() < 3:
                print(
                    "Error: polygon not 3D - below_poly does not make sense!")
                continue
            a_polygon3d = array_geometry.ogrpoly2array(polygon,
                                                       flatten=False)[0]
            #warping loop here....
            if pargs.toE:
                geoid = grid.fromGDAL(GEOID_GRID, upcast=True)
                print("Using geoid from %s to warp to ellipsoidal heights." %
                      GEOID_GRID)
                toE = geoid.interpolate(a_polygon3d[:, :2].copy())
                mask = toE == geoid.nd_val
                if mask.any():
                    raise Warning(
                        "Warping to ellipsoidal heights produced no-data values!"
                    )
                a_polygon3d[:, 2] += toE
            mean_z = a_polygon3d[:, 2].mean()
            if mean_z < SENSIBLE_Z_MIN or mean_z > SENSIBLE_Z_MAX:
                msg = "Warning: This feature seems to have unrealistic mean z value: {0:.2f} m"
                print(msg.format(mean_z))
                continue
            del a_polygon3d
        else:
            mean_z = -1
        polygon.FlattenTo2D()
        feature_count += 1
        separator = "-" * 70
        print("%s\nFeature %d\n%s" % (separator, feature_count, separator))
        a_polygon = array_geometry.ogrpoly2array(polygon)
        pc_in_poly = pc.cut_to_polygon(a_polygon)

        if below_poly:
            pc_in_poly = pc_in_poly.cut_to_z_interval(-999, mean_z)
        n_all = pc_in_poly.get_size()
        freqs = [0] * (len(constants.classes) + 1)  #list of frequencies...

        if n_all > 0:
            c_all = pc_in_poly.get_classes()
            if below_poly and DEBUG:
                print("Mean z of polygon is:        %.2f m" % mean_z)
                print("Mean z of points below is:   %.2f m" %
                      pc_in_poly.z.mean())
            print("Number of points in polygon:  %d" % n_all)
            print("Classes in polygon:           %s" % str(c_all))
            # important for reporting that the order here is the same as in the table
            # definition in report.py!!
            n_found = 0
            for i, cls in enumerate(constants.classes):
                if cls in c_all:
                    pcc = pc_in_poly.cut_to_class(cls)
                    n_c = pcc.get_size()
                    f_c = n_c / float(n_all)
                    n_found += n_c
                    print("Class %d::" % cls)
                    print("   #Points:  %d" % n_c)
                    print("   Fraction: %.3f" % f_c)
                    freqs[i] = f_c
            f_other = (n_all - n_found) / float(n_all)
            freqs[-1] = f_other
        send_args = [kmname] + freqs + [n_all, ptype]
        reporter.report(*send_args, ogr_geom=polygon)
Пример #5
0
def main(args):
    '''
    Core function. Called either stand-alone or from qc_wrap.
    '''
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as error_str:
        print(str(error_str))
        return 1

    kmname = constants.get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (PROGNAME, kmname, time.asctime()))
    cell_size = pargs.cs
    ncols_f = TILE_SIZE / cell_size
    ncols = int(ncols_f)
    if ncols != ncols_f:
        print("TILE_SIZE: %d must be divisible by cell size..." % (TILE_SIZE))
        usage()
        return 1

    print("Using cell size: %.2f" % cell_size)
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)

    reporter = report.ReportDensity(use_local)
    outdir = pargs.outdir

    if not os.path.exists(outdir):
        os.mkdir(outdir)

    lasname = pargs.las_file
    waterconnection = pargs.ref_data
    outname_base = "den_{0:.0f}_".format(cell_size) + os.path.splitext(
        os.path.basename(lasname))[0] + ".tif"
    outname = os.path.join(outdir, outname_base)
    print("Reading %s, writing %s" % (lasname, outname))

    try:
        (x_min, y_min, x_max, y_max) = constants.tilename_to_extent(kmname)
    except Exception as error_str:
        print("Exception: %s" % str(error_str))
        print("Bad 1km formatting of las file: %s" % lasname)
        return 1

    las_file = laspy.file.File(lasname, mode='r')

    nx = int((x_max - x_min) / cell_size)
    ny = int((y_max - y_min) / cell_size)
    ds_grid = gdal.GetDriverByName('GTiff').Create(outname, nx, ny, 1,
                                                   gdal.GDT_Float32)
    georef = (x_min, cell_size, 0, y_max, 0, -cell_size)
    ds_grid.SetGeoTransform(georef)
    band = ds_grid.GetRasterBand(1)
    band.SetNoDataValue(ND_VAL)

    # make local copies so we don't have to call the x and y getter functions
    # of las_file a nx*ny times
    xs = las_file.x
    ys = las_file.y

    # determine densities
    den_grid = np.ndarray(shape=(nx, ny), dtype=float)
    for i in range(nx):
        for j in range(ny):
            I = np.ones(las_file.header.count, dtype=bool)

            if i < nx - 1:
                I &= np.logical_and(xs >= x_min + i * cell_size,
                                    xs < x_min + (i + 1) * cell_size)
            else:
                I &= np.logical_and(xs >= x_min + i * cell_size,
                                    xs <= x_min + (i + 1) * cell_size)

            if j < ny - 1:
                I &= np.logical_and(ys >= y_min + j * cell_size,
                                    ys < y_min + (j + 1) * cell_size)
            else:
                I &= np.logical_and(ys >= y_min + j * cell_size,
                                    ys <= y_min + (j + 1) * cell_size)

            den_grid[ny - j - 1][i] = np.sum(I) / (cell_size * cell_size)

    band.WriteArray(den_grid)
    las_file.close()

    t1 = time.clock()
    if pargs.lakesql is None and pargs.seasql is None:
        print('No layer selection specified!')
        print(
            'Assuming that all water polys are in first layer of connection...'
        )
        lake_mask = vector_io.burn_vector_layer(
            waterconnection,
            georef,
            den_grid.shape,
            None,
            None,
        )
    else:
        lake_mask = np.zeros(den_grid.shape, dtype=np.bool)
        if pargs.lakesql is not None:
            print("Burning lakes...")
            lake_mask |= vector_io.burn_vector_layer(
                waterconnection,
                georef,
                den_grid.shape,
                None,
                pargs.lakesql,
            )
        if pargs.seasql is not None:
            print("Burning sea...")
            lake_mask |= vector_io.burn_vector_layer(
                waterconnection,
                georef,
                den_grid.shape,
                None,
                pargs.seasql,
            )

    t2 = time.clock()
    print("Burning 'water' took: %.3f s" % (t2 - t1))

    # what to do with nodata??
    nd_mask = (den_grid == ND_VAL)
    den_grid[den_grid == ND_VAL] = 0
    n_lake = lake_mask.sum()
    print("Number of no-data densities: %d" % (nd_mask.sum()))
    print("Number of water cells       : %d" % (n_lake))
    if n_lake < den_grid.size:
        not_lake = den_grid[np.logical_not(lake_mask)]
        den = not_lake.min()
        mean_den = not_lake.mean()
    else:
        den = ALL_LAKE
        mean_den = ALL_LAKE
    print("Minumum density            : %.2f" % den)

    wkt = constants.tilename_to_extent(kmname, return_wkt=True)
    reporter.report(kmname, den, mean_den, cell_size, wkt_geom=wkt)

    return 0
Пример #6
0
def main(args):
    '''
    Main script functionality. Can be invoked from either the command line
    or via qc_wrap.py
    '''

    try:
        pargs = parser.parse_args(args[1:])
    except Exception as error_msg:
        print(str(error_msg))
        return 1

    kmname = get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (PROGNAME, kmname, time.asctime()))
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportClassCount(pargs.use_local)
    pc = pointcloud.fromAny(pargs.las_file)
    n_points_total = pc.get_size()
    if n_points_total == 0:
        print(
            "Something is terribly terribly wrong here! Simon - vi skal melde en fjel"
        )

    pc_temp = pc.cut_to_class(constants.created_unused)
    n_created_unused = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.surface)
    n_surface = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.terrain)
    n_terrain = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.low_veg)
    n_low_veg = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.high_veg)
    n_high_veg = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.med_veg)
    n_med_veg = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.building)
    n_building = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.outliers)
    n_outliers = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.mod_key)
    n_mod_key = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.water)
    n_water = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.ignored)
    n_ignored = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.bridge)
    n_bridge = pc_temp.get_size()

    # new classes
    pc_temp = pc.cut_to_class(constants.high_noise)
    n_high_noise = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.power_line)
    n_power_line = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.terrain_in_buildings)
    n_terrain_in_buildings = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.low_veg_in_buildings)
    n_low_veg_in_buildings = pc_temp.get_size()

    pc_temp = pc.cut_to_class(constants.man_excl)
    n_man_excl = pc_temp.get_size()

    polywkt = tilename_to_extent(kmname, return_wkt=True)
    print(polywkt)

    reporter.report(kmname,
                    n_created_unused,
                    n_surface,
                    n_terrain,
                    n_low_veg,
                    n_med_veg,
                    n_high_veg,
                    n_building,
                    n_outliers,
                    n_mod_key,
                    n_water,
                    n_ignored,
                    n_power_line,
                    n_bridge,
                    n_high_noise,
                    n_terrain_in_buildings,
                    n_low_veg_in_buildings,
                    n_man_excl,
                    n_points_total,
                    wkt_geom=polywkt)
Пример #7
0
def main(args):
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as e:
        print(str(e))
        return 1
    kmname = constants.get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (progname, kmname, time.asctime()))
    lasname = pargs.las_file
    polyname = pargs.poly_data
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportBuildingAbsposCheck(use_local)
    ##################################
    pc = pointcloud.fromAny(lasname).cut_to_class(cut_to_classes)
    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception as e:
        print("Could not get extent from tilename.")
        extent = None
    polys = vector_io.get_geometries(polyname, pargs.layername, pargs.layersql,
                                     extent)
    fn = 0
    sl = "-" * 65
    for poly in polys:
        n_corners_found = 0
        fn += 1
        print("%s\nChecking feature %d\n%s\n" % (sl, fn, sl))
        a_poly = array_geometry.ogrgeom2array(poly)
        pcp = pc.cut_to_polygon(a_poly)
        if pcp.get_size() < 500:
            print("Few points in polygon...")
            continue
        a_poly = a_poly[0]
        all_post = np.zeros_like(a_poly)  #array of vertices found
        all_pre = np.zeros_like(
            a_poly)  #array of vertices in polygon, correpsonding to found...
        pcp.triangulate()
        geom = pcp.get_triangle_geometry()
        m = geom[:, 1].mean()
        sd = geom[:, 1].std()
        if (m > 1.5 or 0.5 * sd > m):
            print("Feature %d, bad geometry...." % fn)
            print("{} {}".format(m, sd))
            continue
        #geom is ok - we proceed with a buffer around da house
        poly_buf = poly.Buffer(2.0)
        a_poly2 = array_geometry.ogrgeom2array(poly_buf)
        pcp = pc.cut_to_polygon(a_poly2)
        print("Points in buffer: %d" % pcp.get_size())
        pcp.triangulate()
        geom = pcp.get_triangle_geometry()
        tanv2 = tan(radians(cut_angle))**2
        #set a mask to mark the triangles we want to consider as marking the house boundary
        mask = np.logical_and(geom[:, 0] > tanv2, geom[:, 2] > z_limit)
        #we consider the 'high' lying vertices - could also just select the highest of the three vertices...
        p_mask = (pcp.z > pcp.z.min() + 2)
        #and only consider those points which lie close to the outer bd of the house...
        p_mask &= array_geometry.points_in_buffer(
            pcp.xy, a_poly, 1.2)  #a larger shift than 1.2 ??
        #this just selects vertices where p_mask is true, from triangles where mask is true - nothing else...
        bd_mask = pcp.get_boundary_vertices(mask, p_mask)
        bd_pts = pcp.xy[bd_mask]
        #subtract mean to get better numeric stability...
        xy_t = bd_pts.mean(axis=0)
        xy = bd_pts - xy_t
        a_poly -= xy_t
        if DEBUG:
            plot_points(a_poly, xy)
        #now find those corners!
        lines_ok = dict()
        found_lines = dict()
        for vertex in range(a_poly.shape[0] -
                            1):  #check line emanating from vertex...
            p1 = a_poly[vertex]
            p2 = a_poly[vertex + 1]
            ok, pts = check_distribution(p1, p2, xy)
            lines_ok[vertex] = (ok, pts)
        #now find corners
        vertex = 0  #handle the 0'th corner specially...
        while vertex < a_poly.shape[0] - 2:
            if lines_ok[vertex][0] and lines_ok[vertex + 1][0]:  #proceed
                print("%s\nCorner %d should be findable..." %
                      ("+" * 50, vertex + 1))
                corner_found = find_corner(vertex, lines_ok, found_lines,
                                           a_poly)
                all_pre[n_corners_found] = a_poly[vertex + 1]
                all_post[n_corners_found] = corner_found
                #print a_poly[vertex+1],corner_found,vertex
                n_corners_found += 1
                vertex += 1
            else:  #skip to next findable corner
                vertex += 2
        if lines_ok[0][0] and lines_ok[a_poly.shape[0] - 2][0]:
            print("Corner 0 should also be findable...")
            corner_found = find_corner(a_poly.shape[0] - 2, lines_ok,
                                       found_lines, a_poly)
            all_pre[n_corners_found] = a_poly[0]
            all_post[n_corners_found] = corner_found
            n_corners_found += 1
        print("\n********** In total for feature %d:" % fn)
        print("Corners found: %d" % n_corners_found)
        if n_corners_found > 0:
            all_post = all_post[:n_corners_found]
            all_pre = all_pre[:n_corners_found]
            all_dxy = all_post - all_pre
            mdxy = all_dxy.mean(axis=0)
            sdxy = np.std(all_dxy, axis=0)
            ndxy = norm(all_dxy)
            params = (1, mdxy[0], mdxy[1])
            print("Mean dxy:      %.3f, %.3f" % (mdxy[0], mdxy[1]))
            print("Sd      :      %.3f, %.3f" % (sdxy[0], sdxy[1]))
            print("Max absolute : %.3f m" % (ndxy.max()))
            print("Mean absolute: %.3f m" % (ndxy.mean()))
            if n_corners_found > 1:
                print("Helmert transformation (pre to post):")
                params = helmert2d(all_pre, all_post)
                print("Scale:  %.5f ppm" % ((params[0] - 1) * 1e6))
                print("dx:     %.3f m" % params[1])
                print("dy:     %.3f m" % params[2])
                print("Residuals:")
                all_post_ = params[0] * all_pre + params[1:]
                all_dxy = all_post - all_post_
                mdxy = all_dxy.mean(axis=0)
                sdxy = np.std(all_dxy, axis=0)
                ndxy = norm(all_dxy)
                print("Mean dxy:      %.3f, %.3f" % (mdxy[0], mdxy[1]))
                print("Sd      :      %.3f, %.3f" % (sdxy[0], sdxy[1]))
                print("Max absolute : %.3f m" % (ndxy.max()))
                print("Mean absolute: %.3f m" % (ndxy.mean()))
            reporter.report(kmname,
                            params[0],
                            params[1],
                            params[2],
                            n_corners_found,
                            ogr_geom=poly)
Пример #8
0
def run_check(p_number, testname, db_name, add_args, runid, use_local, schema,
              use_ref_data, lock):
    '''
    Main checker rutine which should be defined for all processes.
    '''

    logger = multiprocessing.log_to_stderr()
    test_func = qc.get_test(testname)
    #Set up some globals in various modules... per process.
    if runid is not None:
        report.set_run_id(runid)

    if use_local:
        # rather than sending args to scripts, which might not have implemented
        # handling that particular argument, set a global attr in report.
        report.set_use_local(True)
    elif schema is not None:
        report.set_schema(schema)
    #LOAD THE DATABASE
    con = sqlite.connect(db_name)
    if con is None:
        logger.error(
            "[qc_wrap]: Process: {0:d}, unable to fetch process db".format(
                p_number))
        return

    cur = con.cursor()
    timestamp = (time.asctime().split()[-2]).replace(':', '_')
    logname = testname + '_' + timestamp + '_' + str(p_number) + '.log'
    logname = os.path.join(LOGDIR, logname)
    logfile = open(logname, 'w')
    stdout = osutils.redirect_stdout(logfile)
    stderr = osutils.redirect_stderr(logfile)
    filler = '*-*' * 23
    print(filler)
    print(
        '[qc_wrap]: Running {test} routine at {time}, process: {proc}, run id: {rid}'
        .format(test=testname, time=time.asctime(), proc=p_number, rid=runid))

    print(filler)
    done = 0
    cur.execute('select count() from ' + testname + ' where status=0')
    n_left = cur.fetchone()[0]
    while n_left > 0:
        print(filler)
        print("[qc_wrap]: Number of tiles left: {0:d}".format(n_left))
        print(filler)
        #Critical section#
        lock.acquire()
        cur.execute("select id,las_path,ref_path from " + testname +
                    " where status=0")
        data = cur.fetchone()
        if data is None:
            print("[qc_wrap]: odd - seems to be no more tiles left...")
            lock.release()
            break
        fid, lasname, vname = data
        cur.execute(
            "update " + testname +
            " set status=?,prc_id=?,exe_start=? where id=?",
            (STATUS_PROCESSING, p_number, time.asctime(), fid))
        try:
            con.commit()
        except Exception as err_msg:
            stderr.write(
                "[qc_wrap]: Unable to update tile to finish status...\n" +
                err_msg + "\n")
            break
        finally:
            lock.release()

        #end critical section#
        print("[qc_wrap]: Doing lasfile {0:s}...".format(lasname))
        send_args = [testname, lasname]
        if use_ref_data:
            send_args.append(vname)
        send_args += add_args
        try:
            return_code = test_func(send_args)
        except Exception as err_msg:
            return_code = -1
            msg = str(err_msg)
            status = STATUS_ERROR
            stderr.write("[qc_wrap]: Exception caught:\n" + msg + "\n")
            stderr.write("[qc_wrap]: Traceback:\n" + traceback.format_exc() +
                         "\n")
        else:
            #set new status
            msg = "ok"
            status = STATUS_OK
            try:
                return_code = int(return_code)
            except (NameError, ValueError, TypeError):
                return_code = 0
        cur.execute(
            "update " + testname +
            " set status=?,exe_end=?,rcode=?,msg=? where id=?",
            (status, time.asctime(), return_code, msg, fid))
        done += 1
        try:
            con.commit()
        except Exception as err_msg:
            stderr.write(
                "[qc_wrap]: Unable to update tile to finish status...\n" +
                err_msg + "\n")
        #go on to next one...
        cur.execute("select count() from " + testname + " where status=0")
        n_left = cur.fetchone()[0]

    print("[qc_wrap]: Checked %d tiles, finished at %s" %
          (done, time.asctime()))
    cur.close()
    con.close()
    #avoid writing to a closed fp...
    stdout.close()
    stderr.close()
    logfile.close()
Пример #9
0
def main(args):
    pargs = parser.parse_args(args[1:])
    lasname = pargs.las_file
    polyname = pargs.build_polys
    kmname = constants.get_tilename(lasname)
    print("Running %s on block: %s, %s" %
          (os.path.basename(args[0]), kmname, time.asctime()))
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportRoofridgeCheck(use_local)
    cut_class = pargs.cut_class
    print("Using class(es): %s" % (cut_class))
    # default step values for search...
    steps1 = 32
    steps2 = 14
    search_factor = pargs.search_factor
    if search_factor != 1:
        # can turn search steps up or down
        steps1 = int(search_factor * steps1)
        steps2 = int(search_factor * steps2)
        print("Incresing search factor by: %.2f" % search_factor)
        print(
            "Running time will increase exponentionally with search factor...")
    pc = pointcloud.fromAny(lasname).cut_to_class(cut_class).cut_to_z_interval(
        Z_MIN, Z_MAX)
    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception:
        print("Could not get extent from tilename.")
        extent = None
    polys = vector_io.get_geometries(polyname, pargs.layername, pargs.layersql,
                                     extent)
    fn = 0
    sl = "+" * 60
    is_sloppy = pargs.sloppy
    use_all = pargs.use_all
    for poly in polys:
        print(sl)
        fn += 1
        print("Checking feature number %d" % fn)
        a_poly = array_geometry.ogrgeom2array(poly)
        # secret argument to use all buildings...
        if (len(a_poly) > 1 or
                a_poly[0].shape[0] != 5) and (not use_all) and (not is_sloppy):
            print("Only houses with 4 corners accepted... continuing...")
            continue
        pcp = pc.cut_to_polygon(a_poly)
        # hmmm, these consts should perhaps be made more visible...
        if (pcp.get_size() < 500 and (not is_sloppy)) or (pcp.get_size() < 10):
            print("Few points in polygon...")
            continue
        # Go to a more numerically stable coord system - from now on only consider outer ring...
        a_poly = a_poly[0]
        xy_t = a_poly.mean(axis=0)
        a_poly -= xy_t
        pcp.xy -= xy_t
        pcp.triangulate()
        geom = pcp.get_triangle_geometry()
        m = geom[:, 1].mean()
        sd = geom[:, 1].std()
        if (m > 1.5 or 0.5 * sd > m) and (not is_sloppy):
            print("Feature %d, bad geometry...." % fn)
            print(m, sd)
            continue
        planes = cluster(pcp, steps1, steps2)
        if len(planes) < 2:
            print("Feature %d, didn't find enough planes..." % fn)
        pair, equation = find_planar_pairs(planes)
        if pair is not None:
            p1 = planes[pair[0]]
            p2 = planes[pair[1]]
            z1 = p1[0] * pcp.xy[:, 0] + p1[1] * pcp.xy[:, 1] + p1[2]
            z2 = p2[0] * pcp.xy[:, 0] + p2[1] * pcp.xy[:, 1] + p2[2]
            print("%s" % ("*" * 60))
            print("Statistics for feature %d" % fn)
            if DEBUG:
                plot3d(pcp.xy, pcp.z, z1, z2)
            intersections, distances, rotations = get_intersections(
                a_poly, equation)
            if intersections.shape[0] == 2:
                line_x = intersections[:, 0]
                line_y = intersections[:, 1]
                z_vals = p1[0] * intersections[:, 0] + p1[
                    1] * intersections[:, 1] + p1[2]
                if abs(z_vals[0] - z_vals[1]) > 0.01:
                    print("Numeric instabilty for z-calculation...")
                z_val = float(np.mean(z_vals))
                print("Z for intersection is %.2f m" % z_val)
                if abs(equation[1]) > 1e-3:
                    a = -equation[0] / equation[1]
                    b = equation[2] / equation[1]
                    line_y = a * line_x + b
                elif abs(equation[0]) > 1e-3:
                    a = -equation[1] / equation[0]
                    b = equation[2] / equation[0]
                    line_x = a * line_y + b
                if DEBUG:
                    plot_intersections(a_poly, intersections, line_x, line_y)
                # transform back to real coords
                line_x += xy_t[0]
                line_y += xy_t[1]
                wkt = "LINESTRING(%.3f %.3f %.3f, %.3f %.3f %.3f)" % (
                    line_x[0], line_y[0], z_val, line_x[1], line_y[1], z_val)
                print("WKT: %s" % wkt)
                reporter.report(kmname,
                                rotations[0],
                                distances[0],
                                distances[1],
                                wkt_geom=wkt)
            else:
                print(
                    "Hmmm - something wrong, didn't get exactly two intersections..."
                )
Пример #10
0
def main(args):
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as e:
        print(str(e))
        return 1
    kmname = constants.get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (progname, kmname, time.asctime()))
    lasname = pargs.las_file
    pointname = pargs.ref_data
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportZcheckAbs(use_local)

    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception as e:
        print("Could not get extent from tilename.")
        extent = None
    pc_ref = None  #base reference pointcloud
    pc_refs = []  #list of possibly 'cropped' pointclouds...
    if pargs.multipoints:
        ftype = "multipoints"
        explode = False
    elif pargs.lines:
        ftype = "lines"
        explode = True
    geoms = vector_io.get_geometries(pointname,
                                     pargs.layername,
                                     pargs.layersql,
                                     extent,
                                     explode=explode)
    for geom in geoms:
        xyz = array_geometry.ogrgeom2array(geom, flatten=False)
        if xyz.shape[0] > 0:
            pc_refs.append(pointcloud.Pointcloud(xyz[:, :2], xyz[:, 2]))
    print("Found %d non-empty geometries" % len(pc_refs))
    if len(pc_refs) == 0:
        print("No input geometries in intersection...")
    if pargs.ftype is not None:
        ftype = pargs.ftype
    cut_input_to = pargs.cut_to
    print("Cutting input pointcloud to class %d" % cut_input_to)
    pc = pointcloud.fromAny(lasname).cut_to_class(
        cut_input_to)  #what to cut to here...??
    #warping loop here....
    if (pargs.toE):
        geoid = grid.fromGDAL(GEOID_GRID, upcast=True)
        print("Using geoid from %s to warp to ellipsoidal heights." %
              GEOID_GRID)
        for i in range(len(pc_refs)):
            toE = geoid.interpolate(pc_refs[i].xy)
            M = (toE == geoid.nd_val)
            if (M.any()):
                print(
                    "Warping to ellipsoidal heights produced no-data values!")
                M = np.logical_not(M)
                toE = toE[M]
                pc_refs[i] = pc_refs[i].cut(M)
            pc_refs[i].z += toE
    #Remove empty pointsets
    not_empty = []
    for pc_r in pc_refs:
        if pc_r.get_size() > 0:
            not_empty.append(pc_r)  #dont worry, just a pointer...
        else:
            raise Warning("Empty input set...")
    print("Checking %d point sets" % len(not_empty))
    #Loop over strips#

    for id in pc.get_pids():
        print("%s\n" % ("+" * 70))
        print("Strip id: %d" % id)
        pc_c = pc.cut_to_strip(id)
        if pc_c.get_size() < 50:
            print("Not enough points...")
            continue
        might_intersect = []
        for i, pc_r in enumerate(not_empty):
            if pc_c.might_overlap(pc_r):
                might_intersect.append(i)
        if len(might_intersect) == 0:
            print("Strip does not intersect any point 'patch'...")
            continue
        pc_c.triangulate()
        pc_c.calculate_validity_mask(angle_tolerance, xy_tolerance,
                                     z_tolerance)
        #now loop over the patches which might intersect this strip...
        any_checked = False
        for i in might_intersect:
            pc_r = not_empty[i].cut_to_box(*(pc_c.get_bounds()))
            if pc_r.get_size == 0:
                continue
            any_checked = True
            print("Stats for check of 'patch/set' %d against strip %d:" %
                  (i, id))
            stats = check_points(pc_c, pc_r)
            if stats is None:
                print("Not enough points in proper triangles...")
                continue
            m, sd, n = stats
            cm_x, cm_y = pc_r.xy.mean(axis=0)
            cm_z = pc_r.z.mean()
            print("Center of mass: %.2f %.2f %.2f" % (cm_x, cm_y, cm_z))
            cm_geom = ogr.Geometry(ogr.wkbPoint25D)
            cm_geom.SetPoint(0, cm_x, cm_y, cm_z)
            #what geometry should be reported, bounding box??
            reporter.report(kmname, id, ftype, m, sd, n, ogr_geom=cm_geom)
        if not any_checked:
            print("Strip did not intersect any point 'patch'...")
Пример #11
0
def main(args):
    pargs = parser.parse_args(args[1:])
    lasname = pargs.las_file
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    if pargs.height is not None:
        reporter = report.ReportClouds(use_local)
        CS = 4
        CELL_COUNT_LIM = 4
    else:
        reporter = report.ReportAutoBuilding(use_local)
        CS = 1
        CELL_COUNT_LIM = 2
    kmname = constants.get_tilename(lasname)
    print("Running %s on block: %s, %s" %
          (os.path.basename(args[0]), kmname, time.asctime()))
    try:
        xul, yll, xlr, yul = constants.tilename_to_extent(kmname)
    except Exception as e:
        print("Exception: %s" % str(e))
        print("Bad 1km formatting of las file name: %s" % lasname)
        return 1
    if pargs.height is not None:
        print("Cutting to z above %.2f m" % (pargs.height))
        pc = pointcloud.fromAny(lasname).cut_to_z_interval(
            pargs.height, default_max_z)
    else:
        print("Cutting to class %d" % pargs.cut_to)
        pc = pointcloud.fromAny(lasname).cut_to_class(pargs.cut_to)

    if pc.get_size() == 0:
        print("No points after restriction...")
        return 0

    cs = CS
    ncols = TILE_SIZE // cs
    nrows = ncols
    georef = [xul, cs, 0, yul, 0, -cs]
    arr_coords = ((pc.xy - (georef[0], georef[3])) /
                  (georef[1], georef[5])).astype(np.int32)
    M = np.logical_and(arr_coords[:, 0] >= 0, arr_coords[:, 0] < ncols)
    M &= np.logical_and(arr_coords[:, 1] >= 0, arr_coords[:, 1] < nrows)
    arr_coords = arr_coords[M]
    # Wow - this gridding is sooo simple! and fast!
    #create flattened index
    B = arr_coords[:, 1] * ncols + arr_coords[:, 0]
    bins = np.arange(0, ncols * nrows + 1)
    h, b = np.histogram(B, bins)
    print("{} {} {}".format(h.shape, h.max(), h.min()))
    h = h.reshape((nrows, ncols))
    if DEBUG:
        plt.imshow(h)
        plt.show()
    M = (h >= CELL_COUNT_LIM).astype(np.uint8)
    #Now create a GDAL memory raster
    mem_driver = gdal.GetDriverByName("MEM")
    mask_ds = mem_driver.Create("dummy", int(M.shape[1]), int(M.shape[0]), 1,
                                gdal.GDT_Byte)
    mask_ds.SetGeoTransform(georef)
    mask_ds.GetRasterBand(1).WriteArray(M)  #write zeros to output
    #Ok - so now polygonize that - use the mask as ehem... mask...
    m_drv = ogr.GetDriverByName("Memory")
    ds = m_drv.CreateDataSource("dummy")
    if ds is None:
        print("Creation of output ds failed.\n")
        return
    lyr = ds.CreateLayer("polys", None, ogr.wkbPolygon)
    fd = ogr.FieldDefn(dst_fieldname, ogr.OFTInteger)
    lyr.CreateField(fd)
    dst_field = 0
    print("Polygonizing.....")
    gdal.Polygonize(mask_ds.GetRasterBand(1), mask_ds.GetRasterBand(1), lyr,
                    dst_field)
    lyr.ResetReading()
    nf = lyr.GetFeatureCount()
    for i in range(nf):
        fet = lyr.GetNextFeature()
        geom = fet.GetGeometryRef()
        reporter.report(kmname, ogr_geom=geom)
    return 0
Пример #12
0
def main(args):
    '''
    Run road delta check. Invoked from either command line or qc_wrap.py
    '''
    pargs = parser.parse_args(args[1:])
    lasname = pargs.las_file
    linename = pargs.lines
    kmname = constants.get_tilename(lasname)
    print("Running %s on block: %s, %s" %
          (os.path.basename(args[0]), kmname, time.asctime()))
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportDeltaRoads(pargs.use_local)
    cut_class = pargs.cut_class
    pc = pointcloud.fromAny(lasname).cut_to_class(cut_class)
    if pc.get_size() < 5:
        print("Too few points to bother..")
        return 1

    pc.triangulate()
    geom = pc.get_triangle_geometry()
    print("Using z-steepnes limit {0:.2f} m".format(pargs.zlim))
    mask = np.logical_and(geom[:, 1] < XY_MAX, geom[:, 2] > pargs.zlim)
    geom = geom[mask]  # save for reporting
    if not mask.any():
        print("No steep triangles found...")
        return 0

    # only the centers of the interesting triangles
    centers = pc.triangulation.get_triangle_centers()[mask]
    print("{0:d} steep triangles in tile.".format(centers.shape[0]))
    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception:
        print("Could not get extent from tilename.")
        extent = None

    lines = vector_io.get_geometries(linename, pargs.layername, pargs.layersql,
                                     extent)
    feature_count = 0
    for line in lines:
        xy = array_geometry.ogrline2array(line, flatten=True)
        if xy.shape[0] == 0:
            print("Seemingly an unsupported geometry...")
            continue

        # select the triangle centers which lie within line_buffer of the road segment
        mask = array_geometry.points_in_buffer(centers, xy, LINE_BUFFER)
        critical = centers[mask]

        print("*" * 50)
        print("{0:d} steep centers along line {1:d}".format(
            critical.shape[0], feature_count))
        feature_count += 1

        if critical.shape[0] > 0:
            z_box = geom[mask][:, 2]
            z1 = z_box.max()
            z2 = z_box.min()
            wkt = "MULTIPOINT("
            for point in critical:
                wkt += "{0:.2f} {1:.2f},".format(point[0], point[1])
            wkt = wkt[:-1] + ")"
            reporter.report(kmname, z1, z2, wkt_geom=wkt)
Пример #13
0
            con.commit()
            continue
        testname,schema,runid,targs=data
        logger.info("Was told to do job with id %s, test %s, on data (%s,%s)" %(job_id,testname,path,ref_path))
        #now just run the script.... hmm - perhaps import with importlib and run it??
        stdout.write(sl+"[proc_client] Doing definition %s from %s, test: %s\n"%(job_id,db_cstr,testname))
        args={"__name__":"qc_wrap","path":path}
        try:
            targs=json.loads(targs) #convert to a python list
            test_func=qc.get_test(testname)
            use_ref_data=qc.tests[testname][0]
            use_reporting=qc.tests[testname][1]
            #both of these can be None - but that's ok.
            if use_reporting:
                report.set_run_id(runid)
                report.set_schema(schema)
            send_args=[testname,path]
            if use_ref_data:
                assert(len(ref_path)>0)
                send_args.append(ref_path)
            send_args+=targs
            rc=test_func(send_args)

        except Exception,e:
            stderr.write("[proc_client]: Exception caught:\n"+str(e)+"\n")
            stderr.write("[proc_client]: Traceback:\n"+traceback.format_exc()+"\n")
            logger.error("Caught: \n"+str(e))
            msg=str(e)[:128] #truncate msg for now - or use larger field width.
            cur.execute("update proc_jobs set status=%s,msg=%s where ogc_fid=%s",(STATUS_ERROR,msg,id))
            con.commit()
        else:
Пример #14
0
def main(args):
    try:
        pargs = parser.parse_args(args[1:])
    except Exception as e:
        print(str(e))
        return 1
    kmname = constants.get_tilename(pargs.las_file)
    print("Running %s on block: %s, %s" % (progname, kmname, time.asctime()))
    lasname = pargs.las_file
    polyname = pargs.poly_data
    use_local = pargs.use_local
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportBuildingRelposCheck(use_local)
    ##################################
    pc = pointcloud.fromAny(lasname).cut_to_z_interval(
        -10, 200).cut_to_class(cut_to_classes)
    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception as e:
        print("Could not get extent from tilename.")
        extent = None
    polys = vector_io.get_geometries(polyname)
    fn = 0
    sl = "-" * 65
    pcs = dict()
    for id in pc.get_pids():
        print("%s\n" % ("+" * 70))
        print("Strip id: %d" % id)
        pc_ = pc.cut_to_strip(id)
        if pc_.get_size() > 500:
            pcs[id] = pc_
        else:
            print("Not enough points....")
    del pc
    done = []
    for id1 in pcs:
        pc1 = pcs[id1]
        for id2 in pcs:
            if id1 == id2 or (id1, id2) in done or (id2, id1) in done:
                continue
            done.append((id1, id2))
            pc2 = pcs[id2]
            ml = "-" * 70
            print("%s\nChecking strip %d against strip %d\n%s" %
                  (ml, id1, id2, ml))
            if not pc1.might_overlap(pc2):
                if DEBUG:
                    print(
                        "Strip %d and strip %d does not seem to overlap. Continuing..."
                        % (id1, id2))
                    print("DEBUG: Strip1 bounds:\n%s\nStrip2 bounds:\n%s" %
                          (pc1.get_bounds(), pc2.get_bounds()))
                continue
            for poly in polys:
                centroid = poly.Centroid()
                centroid.FlattenTo2D()
                if LIGHT_DEBUG:
                    print("Geom type: %s" % centroid.GetGeometryName())
                n_corners_found = 0
                fn += 1
                print("%s\nChecking feature %d\n%s\n" % (sl, fn, sl))
                a_poly = array_geometry.ogrgeom2array(poly)
                pcp1 = pc1.cut_to_polygon(a_poly)
                if pcp1.get_size() < 300:
                    print("Few (%d) points in polygon..." % pcp1.get_size())
                    continue
                pcp2 = pc2.cut_to_polygon(a_poly)
                if pcp2.get_size() < 300:
                    print("Few (%d) points in polygon..." % pcp2.get_size())
                    continue
                a_poly = a_poly[0]
                poly_buf = poly.Buffer(2.0)
                xy_t = a_poly.mean(
                    axis=0
                )  #transform later to center of mass system for numerical stability...
                #transform a_poly coords to center of mass system here
                a_poly -= xy_t
                a_poly2 = array_geometry.ogrgeom2array(poly_buf)
                #dicts to store the found corners in the two strips...
                found1 = dict()
                found2 = dict()
                for pc, pcp, store in [(pc1, pcp1, found1),
                                       (pc2, pcp2, found2)]:
                    pcp.triangulate()
                    geom = pcp.get_triangle_geometry()
                    m = geom[:, 1].mean()
                    sd = geom[:, 1].std()
                    if (m > 1.5 or 0.5 * sd > m):
                        print("Feature %d, bad geometry...." % fn)
                        print("{} {}".format(m, sd))
                        break
                    #geom is ok - we proceed with a buffer around da house
                    pcp = pc.cut_to_polygon(a_poly2)
                    ######
                    ## Transform pointcloud to center of mass system here...
                    #######
                    pcp.xy -= xy_t
                    print("Points in buffer: %d" % pcp.get_size())
                    pcp.triangulate()
                    geom = pcp.get_triangle_geometry()
                    tanv2 = tan(radians(cut_angle))**2
                    #set a mask to mark the triangles we want to consider as marking the house boundary
                    mask = np.logical_and(geom[:, 0] > tanv2,
                                          geom[:, 2] > z_limit)
                    #we consider the 'high' lying vertices - could also just select the highest of the three vertices...
                    p_mask = (pcp.z > pcp.z.min() + 2)
                    #and only consider those points which lie close to the outer bd of the house...
                    p_mask &= array_geometry.points_in_buffer(
                        pcp.xy, a_poly, 1.2)  #a larger shift than 1.2 ??
                    #this just selects vertices where p_mask is true, from triangles where mask is true - nothing else...
                    bd_mask = pcp.get_boundary_vertices(mask, p_mask)
                    xy = pcp.xy[bd_mask]

                    print("Boundary points: %d" % xy.shape[0])
                    if DEBUG:
                        plot_points(a_poly, xy)
                    #now find those corners!
                    lines_ok = dict()
                    found_lines = dict()
                    for vertex in range(
                            a_poly.shape[0] -
                            1):  #check line emanating from vertex...
                        p1 = a_poly[vertex]
                        p2 = a_poly[vertex + 1]
                        ok, pts = check_distribution(p1, p2, xy)
                        lines_ok[vertex] = (ok, pts)
                    #now find corners
                    vertex = 0  #handle the 0'th corner specially...
                    while vertex < a_poly.shape[0] - 2:
                        if lines_ok[vertex][0] and lines_ok[vertex +
                                                            1][0]:  #proceed
                            print("%s\nCorner %d should be findable..." %
                                  ("+" * 50, vertex + 1))
                            corner_found = find_corner(vertex, lines_ok,
                                                       found_lines, a_poly)
                            diff = norm2(a_poly[vertex + 1] - corner_found)
                            if (
                                    diff < TOL_CORNER
                            ):  #seems reasonable that this is a true corner...
                                store[vertex + 1] = corner_found
                                n_corners_found += 1
                            #print a_poly[vertex+1],corner_found,vertex
                            vertex += 1
                        else:  #skip to next findable corner
                            vertex += 2
                    if lines_ok[0][0] and lines_ok[a_poly.shape[0] - 2][0]:
                        print("Corner 0 should also be findable...")
                        corner_found = find_corner(a_poly.shape[0] - 2,
                                                   lines_ok, found_lines,
                                                   a_poly)
                        diff = norm2(a_poly[0] - corner_found)
                        if (diff < TOL_CORNER
                            ):  #seems reasonable that this is a true corner...
                            store[0] = corner_found
                            n_corners_found += 1
                    print("Corners found: %d" % n_corners_found)
                    if n_corners_found == 0:  #no need to do another check...
                        break
                print(
                    "Found %d corners in strip %d, and %d corners in strip %d"
                    % (len(found1), id1, len(found2), id2))
                if len(found1) > 0 and len(found2) > 0:
                    match1 = []
                    match2 = []
                    for cn in found1:
                        if cn in found2:
                            match1.append(found1[cn])
                            match2.append(found2[cn])
                    if len(match1) > 0:
                        match1 = np.array(match1)
                        match2 = np.array(match2)
                        n_corners_found = match1.shape[0]
                        print("\n********** In total for feature %d:" % fn)
                        print("Corners found in both strips: %d" %
                              n_corners_found)
                        all_dxy = match1 - match2
                        mdxy = all_dxy.mean(axis=0)
                        sdxy = np.std(all_dxy, axis=0)
                        ndxy = norm(all_dxy)
                        params = (1, mdxy[0], mdxy[1])
                        print("Mean dxy:      %.3f, %.3f" % (mdxy[0], mdxy[1]))
                        print("Sd      :      %.3f, %.3f" % (sdxy[0], sdxy[1]))
                        print("Max absolute : %.3f m" % (ndxy.max()))
                        print("Mean absolute: %.3f m" % (ndxy.mean()))
                        if n_corners_found > 1:
                            print(
                                "Helmert transformation (corners1 to corners2):"
                            )
                            params = helmert2d(match1, match2)  #2->1 or 1->2 ?
                            print("Scale:  %.5f ppm" % ((params[0] - 1) * 1e6))
                            print("dx:     %.3f m" % params[1])
                            print("dy:     %.3f m" % params[2])
                            print("Residuals:")
                            match2_ = params[0] * match1 + params[1:]
                            all_dxy = match2_ - match2
                            mdxy_ = all_dxy.mean(axis=0)
                            sdxy_ = np.std(all_dxy, axis=0)
                            ndxy_ = norm(all_dxy)
                            if DEBUG or LIGHT_DEBUG:
                                plot3([match1, match2, match2_])
                            #center of mass distances only!!
                            cm_vector = (match2.mean(axis=0) -
                                         match1.mean(axis=0))
                            cm_dist = norm2(cm_vector)
                            print("Mean dxy:      %.3f, %.3f" %
                                  (mdxy_[0], mdxy_[1]))
                            print("Sd      :      %.3f, %.3f" %
                                  (sdxy_[0], sdxy_[1]))
                            print("Max absolute : %.3f m" % (ndxy_.max()))
                            print("Mean absolute: %.3f m" % (ndxy_.mean()))
                            reporter.report(kmname,
                                            id1,
                                            id2,
                                            cm_vector[0],
                                            cm_vector[1],
                                            cm_dist,
                                            params[0],
                                            params[1],
                                            params[2],
                                            sdxy_[0],
                                            sdxy_[1],
                                            n_corners_found,
                                            ogr_geom=centroid)
Пример #15
0
def run_check(p_number, testname, db_name, add_args, runid, use_local, schema,
              use_ref_data, lock):
    '''
    Main checker rutine which should be defined for all processes.
    '''

    logger = multiprocessing.log_to_stderr()
    test_func = qc.get_test(testname)
    #Set up some globals in various modules... per process.
    if runid is not None:
        report.set_run_id(runid)

    if use_local:
        # rather than sending args to scripts, which might not have implemented
        # handling that particular argument, set a global attr in report.
        report.set_use_local(True)
    elif schema is not None:
        report.set_schema(schema)
    #LOAD THE DATABASE
    con = sqlite.connect(db_name)
    if con is None:
        logger.error(
            "[qc_wrap]: Process: {0:d}, unable to fetch process db".format(
                p_number))
        return

    cur = con.cursor()
    timestamp = (time.asctime().split()[-2]).replace(':', '_')
    logname = testname + '_' + timestamp + '_' + str(p_number) + '.log'
    logname = os.path.join(LOGDIR, logname)
    logfile = open(logname, 'w')
    stdout = osutils.redirect_stdout(logfile)
    stderr = osutils.redirect_stderr(logfile)
    filler = '*-*' * 23
    print(filler)
    print(
        '[qc_wrap]: Running {test} routine at {time}, process: {proc}, run id: {rid}'
        .format(test=testname, time=time.asctime(), proc=p_number, rid=runid))

    print(filler)
    done = 0
    cur.execute('select count() from ' + testname + ' where status=0')
    n_left = cur.fetchone()[0]
    while n_left > 0:
        print(filler)
        print("[qc_wrap]: Number of tiles left: {0:d}".format(n_left))
        print(filler)
        #Critical section#
        lock.acquire()
        cur.execute("select id,las_path,ref_path from " + testname +
                    " where status=0")
        data = cur.fetchone()
        if data is None:
            print("[qc_wrap]: odd - seems to be no more tiles left...")
            lock.release()
            break
        fid, lasname, vname = data
        cur.execute(
            "update " + testname +
            " set status=?,prc_id=?,exe_start=? where id=?",
            (STATUS_PROCESSING, p_number, time.asctime(), fid))
        try:
            con.commit()
        except Exception, err_msg:
            stderr.write(
                "[qc_wrap]: Unable to update tile to finish status...\n" +
                err_msg + "\n")
            break
        finally:
Пример #16
0
def main(args):
    pargs = parser.parse_args(args[1:])
    lasname = pargs.las_file
    polyname = pargs.build_polys
    kmname = constants.get_tilename(lasname)
    print("Running %s on block: %s, %s" % (os.path.basename(args[0]), kmname, time.asctime()))
    if pargs.schema is not None:
        report.set_schema(pargs.schema)
    reporter = report.ReportRoofridgeStripCheck(pargs.use_local)
    cut_class = pargs.cut_class
    # default step values for search...
    steps1 = 30
    steps2 = 13
    search_factor = pargs.search_factor
    if search_factor != 1:
        # can turn search steps up or down
        steps1 = int(search_factor * steps1)
        steps2 = int(search_factor * steps2)
        print("Incresing search factor by: %.2f" % search_factor)
        print("Running time will increase exponentionally with search factor...")
    pc = pointcloud.fromAny(lasname).cut_to_class(cut_class).cut_to_z_interval(Z_MIN, Z_MAX)
    try:
        extent = np.asarray(constants.tilename_to_extent(kmname))
    except Exception:
        print("Could not get extent from tilename.")
        extent = None
    polys = vector_io.get_geometries(polyname, pargs.layername, pargs.layersql, extent)
    fn = 0
    sl = "+" * 60
    is_sloppy = pargs.sloppy
    use_all = pargs.use_all
    for poly in polys:
        print(sl)
        fn += 1
        print("Checking feature number %d" % fn)
        a_poly = array_geometry.ogrgeom2array(poly)
        # secret argument to use all buildings...
        if (len(a_poly) > 1 or a_poly[0].shape[0] != 5) and (not use_all) and (not is_sloppy):
            print("Only houses with 4 corners accepted... continuing...")
            continue
        pcp = pc.cut_to_polygon(a_poly)
        strips = pcp.get_pids()
        if len(strips) != 2:
            print("Not exactly two overlapping strips... continuing...")
            continue
        # Go to a more numerically stable coord system - from now on only consider outer ring...
        a_poly = a_poly[0]
        xy_t = a_poly.mean(axis=0)  # center of mass system
        a_poly -= xy_t
        lines = []  # for storing the two found lines...
        for sid in strips:
            print("-*-" * 15)
            print("Looking at strip %d" % sid)
            pcp_ = pcp.cut_to_strip(sid)
            # hmmm, these consts should perhaps be made more visible...
            if (pcp_.get_size() < 500 and (not is_sloppy)) or (pcp_.get_size() < 10):
                print("Few points in polygon... %d" % pcp_.get_size())
                continue
            pcp_.xy -= xy_t
            pcp_.triangulate()
            geom = pcp_.get_triangle_geometry()
            m = geom[:, 1].mean()
            sd = geom[:, 1].std()
            if (m > 1.5 or 0.5 * sd > m) and (not is_sloppy):
                print("Feature %d, strip %d, bad geometry...." % (fn, sid))
                break
            planes = cluster(pcp_, steps1, steps2)
            if len(planes) < 2:
                print("Feature %d, strip %d, didn't find enough planes..." % (fn, sid))
            pair, equation = find_planar_pairs(planes)
            if pair is not None:
                p1 = planes[pair[0]]
                print("%s" % ("*" * 60))
                print("Statistics for feature %d" % fn)

                # Now we need to find some points on the line near the house... (0,0) is
                # the center of mass
                norm_normal = equation[0]**2 + equation[1]**2
                if norm_normal < 1e-10:
                    print("Numeric instablity, small normal")
                    break
                # this should be on the line
                cm_line = np.asarray(equation[:2]) * (equation[2] / norm_normal)
                line_dir = np.asarray((-equation[1], equation[0])) / (sqrt(norm_normal))
                end1 = cm_line + line_dir * LINE_RAD
                end2 = cm_line - line_dir * LINE_RAD
                intersections = np.vstack((end1, end2))
                line_x = intersections[:, 0]
                line_y = intersections[:, 1]
                z_vals = p1[0] * intersections[:, 0] + p1[1] * intersections[:, 1] + p1[2]
                if abs(z_vals[0] - z_vals[1]) > 0.01:
                    print("Numeric instabilty for z-calculation...")
                z_val = float(np.mean(z_vals))
                print("Z for intersection is %.2f m" % z_val)
                # transform back to real coords
                line_x += xy_t[0]
                line_y += xy_t[1]
                wkt = "LINESTRING(%.3f %.3f %.3f, %.3f %.3f %.3f)" % (
                    line_x[0], line_y[0], z_val, line_x[1], line_y[1], z_val)
                print("WKT: %s" % wkt)
                lines.append([sid, wkt, z_val, cm_line, line_dir])

        if len(lines) == 2:
            # check for parallelity
            id1 = lines[0][0]
            id2 = lines[1][0]
            z1 = lines[0][2]
            z2 = lines[1][2]
            if abs(z1 - z2) > 0.5:
                print("Large difference in z-values for the two lines!")
            else:
                ids = "{0:d}_{1:d}".format(id1, id2)
                inner_prod = (lines[0][4] * lines[1][4]).sum()
                inner_prod = max(-1, inner_prod)
                inner_prod = min(1, inner_prod)

                if DEBUG:
                    print("Inner product: %.4f" % inner_prod)

                ang = abs(degrees(acos(inner_prod)))
                if ang > 175:
                    ang = abs(180 - ang)
                if ang < 15:
                    v = (lines[0][3] - lines[1][3])
                    d = np.sqrt((v**2).sum())
                    if d < 5:
                        for line in lines:
                            reporter.report(kmname, id1, id2, ids, d, ang,
                                            line[2], wkt_geom=line[1])
                    else:
                        print("Large distance between centers %s, %s, %.2f" %
                              (lines[0][3], lines[1][3], d))
                else:
                    print("Pair found - but not very well aligned - angle: %.2f" % ang)
        else:
            print("Pair not found...")