Example #1
0
def postgis(conn, config, out_dir, doexec=True):
    """Export as PostgreSQL backup file
    
    For example the backup can be restored as:
    
    .. code-block:: sh
    
        createdb <db>
        psql -d <db> -c 'create extension postgis;'
        pg_restore --no-owner --no-privileges -h <host> -U <user> -d <db> -w bagactueel_schema.backup
        pg_restore --no-owner --no-privileges -j 2 --clean -h <host> -U <user> -d <db> -w <bag3d backup>.backup

    Parameters
    ----------
    conn : :py:class:`bag3d.config.db.db`
        Open connection
    config : dict
        Configuration
    out_dir : str
        Path to the output directory. The directory 'csv' will be created if 
        doesn't exist.
    """
    schema = config['output']['production']['schema']
    bag3d = config['output']['production']['bag3d_table']

    date = datetime.date.today().isoformat()

    postgis_dir = os.path.join(out_dir, "postgis")
    os.makedirs(postgis_dir, exist_ok=True)
    # PostGIS schema (required because of the pandstatus custom data type)
    f = os.path.join(postgis_dir, "bagactueel_schema.backup")
    command = [
        "pg_dump", "--host", conn.host, "--port", conn.port, "--username",
        conn.user, "--no-password", "--format", "custom", "--no-owner",
        "--compress", "7", "--encoding", "UTF8", "--verbose", "--schema-only",
        "--schema", "bagactueel", "--file", f, conn.dbname
    ]
    bag.run_subprocess(command, shell=True, doexec=doexec)
    compute_md5(f, postgis_dir)

    # The 3D BAG (building heights + footprint geom)s
    f = os.path.join(postgis_dir, 'bag3d_{d}.backup'.format(d=date))
    tbl = '%s.%s' % (schema, bag3d)
    command = [
        "pg_dump", "--host", conn.host, "--port", conn.port, "--username",
        conn.user, "--no-password", "--format", "custom", "--no-owner",
        "--compress", "7", "--encoding", "UTF8", "--verbose", "--file", f,
        "--table", tbl, conn.dbname
    ]
    logger.info("Exporting PostGIS backup")
    bag.run_subprocess(command, shell=True, doexec=doexec)
    compute_md5(f, postgis_dir)
Example #2
0
def gpkg(conn, config, out_dir, doexec=True):
    """Export into GeoPackage
    
    Parameters
    ----------
    conn : :py:class:`bag3d.config.db.db`
        Open connection
    config : dict
        Configuration
    out_dir : str
        Path to the output directory. The directory 'csv' will be created if 
        doesn't exist.
    """
    schema = config['output']['production']['schema']
    bag3d = config['output']['production']['bag3d_table']
    date = datetime.date.today().isoformat()
    x = "bag3d_{d}.gpkg".format(d=date)
    d = os.path.join(out_dir, "gpkg")
    os.makedirs(d, exist_ok=True)
    f = os.path.join(d, x)
    if conn.password:
        dns = "PG:'dbname={db} host={h} port={p} user={u} password={pw} \
        schemas={schema} tables={bag3d}'".format(db=conn.dbname,
                                                 h=conn.host,
                                                 p=conn.port,
                                                 pw=conn.password,
                                                 u=conn.user,
                                                 schema=schema,
                                                 bag3d=bag3d)
    else:
        dns = "PG:'dbname={db} host={h} port={p} user={u} schemas={schema} \
        tables={bag3d}'".format(db=conn.dbname,
                                h=conn.host,
                                p=conn.port,
                                pw=conn.password,
                                u=conn.user,
                                schema=schema,
                                bag3d=bag3d)
    command = ["ogr2ogr", "-f", "GPKG", f, dns]
    logger.info("Exporting GPKG")
    bag.run_subprocess(command, shell=True, doexec=doexec)
    compute_md5(f, d)
Example #3
0
def downloader(tile_list, url, dir_out, doexec=True):
    is_wget = which("wget")
    is_unzip = which("unzip")
    is_rm = which("rm")
    if is_wget is None:
        logger.error("'wget' not found, exiting")
        exit(1)
    if is_unzip is None:
        logger.error("'unzip' not found, exiting")
        exit(1)
    if is_rm is None:
        logger.error("'rm' not found, exiting")
        exit(1)
    try:
        fout = os.path.join(dir_out, 'tile')
        for tile in tile_list:
            command = [
                'wget', '-nc', '-P', dir_out,
                url.format(tile), '-O', fout
            ]
            bag.run_subprocess(command, shell=False, doexec=doexec)
            command = ['unzip', '-o', fout, '-d', dir_out]
            bag.run_subprocess(command, shell=False, doexec=doexec)
            command = ['rm', fout]
            bag.run_subprocess(command, shell=False, doexec=doexec)
        logger.info("Downloaded %s tiles", len(tile_list))
    except Exception as e:
        logger.exception(e)
Example #4
0
def downloader(tile_list, url, dir_out, doexec=True):
    try:
        fout = os.path.join(dir_out, 'tile')
        for tile in tile_list:
            command = [
                'wget', '-nc', '-P', dir_out,
                url.format(tile), '-O', fout
            ]
            bag.run_subprocess(command, shell=False, doexec=doexec)
            command = ['unzip', '-o', fout, '-d', dir_out]
            bag.run_subprocess(command, shell=False, doexec=doexec)
            command = ['rm', fout]
            bag.run_subprocess(command, shell=False, doexec=doexec)
        logger.info("Downloaded %s tiles", len(tile_list))
    except Exception as e:
        logger.exception(e)
Example #5
0
def call_3dfier(db,
                tile,
                schema_tiles,
                table_index_pc,
                fields_index_pc,
                idx_identical,
                table_index_footprint,
                fields_index_footprint,
                uniqueid,
                extent_ewkb,
                clip_prefix,
                prefix_tile_footprint,
                yml_dir,
                tile_out,
                output_format,
                output_dir,
                path_3dfier,
                thread,
                pc_file_index,
                tile_group,
                doexec=True):
    """Call 3dfier with the YAML config created by yamlr().

    Note
    ----
    For the rest of the parameters see batch3dfier_config.yml.

    Parameters
    ----------
    db : :py:class:`bag3d.config.db.db`
        Open connection
    tile : str
        Name of of the 2D tile.
    schema_tiles : str
        Schema of the footprint tiles.
    thread : str
        Name/ID of the active thread.
    extent_ewkb : str
        EWKB representation of 'extent' in batch3dfier_config.yml.
    clip_prefix : str
        Prefix for naming the clipped/united views. This value shouldn't be a substring of the pointcloud file names.
    prefix_tile_footprint : str or None
        Prefix prepended to the footprint tile view names. If None, the views are named as
        the values in fields_index_fooptrint['unit_name'].

    Returns
    -------
    dict
        tile_skipped : str
            The tiles that are skipped because no corresponding pointcloud file
            was found in 'dataset_dir' (YAML)
        out_path : str
            Output path of 3dfier
    """
    # perf = report_procs()
    # if perf:
    #     logger_perf.debug("%s - %s - %s" % (tile_group, tile, perf))
    start = time.process_time()
    tiles = find_pc_tiles(db,
                          table_index_pc,
                          fields_index_pc,
                          idx_identical,
                          table_index_footprint,
                          fields_index_footprint,
                          extent_ewkb,
                          tile_footprint=tile,
                          prefix_tile_footprint=prefix_tile_footprint)
    p = [pc_file_index[tile] for tile in pc_file_index.keys() & tiles.keys()]
    ahn_version = set([tiles[v] for v in pc_file_index.keys() & tiles.keys()])
    pc_path = list(chain.from_iterable(p))
    # prepare output file name
    if not tile_out:
        tile_out = tile.replace(clip_prefix, '', 1)
    if pc_path:
        # Needs a YAML per thread so one doesn't overwrite it while the other
        # uses it
        yml_name = tile + ".yml"
        yml_path = os.path.join(yml_dir, yml_name)
        config = yamlr(dbname=db.dbname,
                       host=db.host,
                       port=db.port,
                       user=db.user,
                       pw=db.password,
                       schema_tiles=schema_tiles,
                       bag_tile=tile,
                       pc_path=pc_path,
                       uniqueid=uniqueid,
                       ahn_version=ahn_version)
        # Write temporary config file
        logger.debug(config)
        try:
            with open(yml_path, "w") as text_file:
                text_file.write(config)
        except BaseException as e:
            logger.exception("Error: cannot write %s", yml_path)
        # Prep output file name
        if "obj" in output_format.lower():
            o = tile_out + ".obj"
            output_path = os.path.join(output_dir, o)
        elif "csv" in output_format.lower():
            o = tile_out + ".csv"
            output_path = os.path.join(output_dir, o)
        else:
            output_path = os.path.join(output_dir, tile_out)
        # Run 3dfier
        command = [
            path_3dfier, yml_path, "--stat_RMSE", "--CSV-BUILDINGS-MULTIPLE",
            output_path
        ]
        try:
            logger.debug(" ".join(command))
            success = bag.run_subprocess(command,
                                         shell=True,
                                         doexec=doexec,
                                         monitor=True,
                                         tile_id=tile)
            if success:
                tile_skipped = None
            else:
                tile_skipped = tile
                output_path = None
            try:
                remove(yml_path)
            except Exception as e:
                logger.error(e)
        except BaseException as e:
            logger.exception("Cannot run 3dfier on tile %s", tile)
            tile_skipped = tile
            output_path = None
    else:
        logger.debug("Pointcloud file(s) %s not available. Skipping tile.",
                     str(tiles.keys()))
        tile_skipped = tile
        output_path = None
    # end = time.process_time()
    # proc_time = (end - start) / 60
    # logger_perf.debug("%s - %s - process_time: %s" % (tile_group, tile, proc_time))
    return {'tile_skipped': tile_skipped, 'out_path': output_path}
Example #6
0
def compute_md5(file, d):
    """Compute the md5sum of a file"""
    filename = os.path.splitext(os.path.basename(file))
    md5_file = filename[0] + ".md5"
    cmd = ["md5sum", "--tag", file, ">", os.path.join(d, md5_file)]
    bag.run_subprocess(cmd, shell=True)