コード例 #1
0
def qa_display_localities(pg_cur, settings):
    logger.info("\t- Step 8 of 8 : Start QA")
    start_time = datetime.now()

    pg_cur.execute(
        geoscape.prep_sql(
            "SELECT locality_pid, locality_name, coalesce(postcode, '') as postcode, state, "
            "address_count, street_count "
            "FROM admin_bdys.locality_bdys_display WHERE NOT ST_IsValid(geom);",
            settings))
    display_qa_results("Invalid Geometries", pg_cur)

    pg_cur.execute(
        geoscape.prep_sql(
            "SELECT locality_pid, locality_name, coalesce(postcode, '') as postcode, state, "
            "address_count, street_count "
            "FROM admin_bdys.locality_bdys_display WHERE ST_IsEmpty(geom);",
            settings))
    display_qa_results("Empty Geometries", pg_cur)

    pg_cur.execute(
        geoscape.open_sql_file("08-qa-display-localities.sql", settings))
    display_qa_results("Dropped Localities", pg_cur)

    logger.info("\t- Step 8 of 8 : display localities qa'd : {0}".format(
        datetime.now() - start_time))
コード例 #2
0
ファイル: load-gnaf.py プロジェクト: phillipf/gnaf-loader
def prep_admin_bdys(pg_cur):
    # Step 3 of 4 : create admin bdy tables read to be used
    start_time = datetime.now()

    # create tables using multiprocessing - using flag in file to split file up into sets of statements
    sql_list = geoscape.open_sql_file(
        "02-02a-prep-admin-bdys-tables.sql").split("-- # --")
    sql_list = sql_list + geoscape.open_sql_file(
        "02-02b-prep-census-2011-bdys-tables.sql").split("-- # --")
    sql_list = sql_list + geoscape.open_sql_file(
        "02-02c-prep-census-2016-bdys-tables.sql").split("-- # --")
    sql_list = sql_list + geoscape.open_sql_file(
        "02-02d-prep-census-2021-bdys-tables.sql").split("-- # --")

    # # Account for bdys that are not in states to load - not yet working
    # for sql in sql_list:
    #     if settings.states_to_load == ["OT"] and ".commonwealth_electorates " in sql:
    #         sql_list.remove(sql)
    #
    #     if settings.states_to_load == ["ACT"] and ".local_government_areas " in sql:
    #         sql_list.remove(sql)
    #
    #     logger.info(settings.states_to_load
    #
    #     if not ("NT" in settings.states_to_load or "SA" in settings.states_to_load
    #             or "VIC" in settings.states_to_load or "WA" in settings.states_to_load) \
    #             and ".local_government_wards " in sql:
    #         sql_list.remove(sql)
    #
    #     if settings.states_to_load == ["OT"] and ".state_lower_house_electorates " in sql:
    #         sql_list.remove(sql)
    #
    #     if not ("TAS" in settings.states_to_load or "VIC" in settings.states_to_load
    #             or "WA" in settings.states_to_load) and ".state_upper_house_electorates " in sql:
    #         sql_list.remove(sql)

    geoscape.multiprocess_list("sql", sql_list, logger)

    # Special case - remove custom outback bdy if South Australia not requested
    if "SA" not in settings.states_to_load:
        pg_cur.execute(
            geoscape.prep_sql(
                "DELETE FROM admin_bdys.locality_bdys WHERE locality_pid = 'SA999999'"
            ))
        pg_cur.execute(
            geoscape.prep_sql("VACUUM ANALYZE admin_bdys.locality_bdys"))

    logger.info("\t- Step 2 of 3 : admin boundaries prepped : {0}".format(
        datetime.now() - start_time))
コード例 #3
0
ファイル: load-gnaf.py プロジェクト: phillipf/gnaf-loader
def create_reference_tables(pg_cur):
    # set postgres search path back to the default
    pg_cur.execute("SET search_path = public, pg_catalog")

    # Step 1 of 14 : create reference tables
    start_time = datetime.now()
    pg_cur.execute(geoscape.open_sql_file("03-01-reference-create-tables.sql"))
    logger.info("\t- Step  1 of 14 : create reference tables : {0}".format(
        datetime.now() - start_time))

    # Step 2 of 14 : populate localities
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file("03-02-reference-populate-localities.sql"))
    logger.info("\t- Step  2 of 14 : localities populated : {0}".format(
        datetime.now() - start_time))

    # Step 3 of 14 : populate locality aliases
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file(
            "03-03-reference-populate-locality-aliases.sql"))
    logger.info("\t- Step  3 of 14 : locality aliases populated : {0}".format(
        datetime.now() - start_time))

    # Step 4 of 14 : populate locality neighbours
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file(
            "03-04-reference-populate-locality-neighbours.sql"))
    logger.info(
        "\t- Step  4 of 14 : locality neighbours populated : {0}".format(
            datetime.now() - start_time))

    # Step 5 of 14 : populate streets
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file("03-05-reference-populate-streets.sql"))
    logger.info(
        "\t- Step  5 of 14 : streets populated : {0}".format(datetime.now() -
                                                             start_time))

    # Step 6 of 14 : populate street aliases
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file("03-06-reference-populate-street-aliases.sql"))
    logger.info("\t- Step  6 of 14 : street aliases populated : {0}".format(
        datetime.now() - start_time))

    # Step 7 of 14 : populate addresses, using multiprocessing
    start_time = datetime.now()
    sql = geoscape.open_sql_file("03-07-reference-populate-addresses-1.sql")
    sql_list = geoscape.split_sql_into_list(pg_cur, sql, settings.gnaf_schema,
                                            "streets", "str", "gid", logger)
    if sql_list is not None:
        geoscape.multiprocess_list("sql", sql_list, logger)
    pg_cur.execute(geoscape.prep_sql("ANALYZE gnaf.temp_addresses;"))
    logger.info(
        "\t- Step  7 of 14 : addresses populated : {0}".format(datetime.now() -
                                                               start_time))

    # Step 8 of 14 : populate principal alias lookup
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file(
            "03-08-reference-populate-address-alias-lookup.sql"))
    logger.info(
        "\t- Step  8 of 14 : principal alias lookup populated : {0}".format(
            datetime.now() - start_time))

    # Step 9 of 14 : populate primary secondary lookup
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file(
            "03-09-reference-populate-address-secondary-lookup.sql"))
    pg_cur.execute(
        geoscape.prep_sql("VACUUM ANALYSE gnaf.address_secondary_lookup"))
    logger.info(
        "\t- Step  9 of 14 : primary secondary lookup populated : {0}".format(
            datetime.now() - start_time))

    # Step 10 of 14 : split the Melbourne locality into its 2 postcodes (3000, 3004)
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file("03-10-reference-split-melbourne.sql"))
    logger.info(
        "\t- Step 10 of 14 : Melbourne split : {0}".format(datetime.now() -
                                                           start_time))

    # Step 11 of 14 : finalise localities assigned to streets and addresses
    start_time = datetime.now()
    pg_cur.execute(
        geoscape.open_sql_file("03-11-reference-finalise-localities.sql"))
    logger.info("\t- Step 11 of 14 : localities finalised : {0}".format(
        datetime.now() - start_time))

    # Step 12 of 14 : finalise addresses, using multiprocessing
    start_time = datetime.now()
    sql = geoscape.open_sql_file("03-12-reference-populate-addresses-2.sql")
    sql_list = geoscape.split_sql_into_list(pg_cur, sql, settings.gnaf_schema,
                                            "localities", "loc", "gid", logger)
    if sql_list is not None:
        geoscape.multiprocess_list("sql", sql_list, logger)

    # turf the temp address table
    pg_cur.execute(
        geoscape.prep_sql("DROP TABLE IF EXISTS gnaf.temp_addresses"))
    logger.info(
        "\t- Step 12 of 14 : addresses finalised : {0}".format(datetime.now() -
                                                               start_time))

    # Step 13 of 14 : create almost correct postcode boundaries by aggregating localities, using multiprocessing
    start_time = datetime.now()
    sql = geoscape.open_sql_file("03-13-reference-derived-postcode-bdys.sql")
    sql_list = []
    for state in settings.states_to_load:
        state_sql = sql.replace("GROUP BY ",
                                "WHERE state = '{0}' GROUP BY ".format(state))
        sql_list.append(state_sql)
    geoscape.multiprocess_list("sql", sql_list, logger)

    # create analysis table?
    if settings.st_subdivide_supported:
        pg_cur.execute(
            geoscape.open_sql_file(
                "03-13a-create-postcode-analysis-table.sql"))

    logger.info("\t- Step 13 of 14 : postcode boundaries created : {0}".format(
        datetime.now() - start_time))

    # Step 14 of 14 : create indexes, primary and foreign keys, using multiprocessing
    start_time = datetime.now()
    raw_sql_list = geoscape.open_sql_file(
        "03-14-reference-create-indexes.sql").split("\n")
    sql_list = []
    for sql in raw_sql_list:
        if sql[0:2] != "--" and sql[0:2] != "":
            sql_list.append(sql)
    geoscape.multiprocess_list("sql", sql_list, logger)
    logger.info(
        "\t- Step 14 of 14 : create primary & foreign keys and indexes : {0}".
        format(datetime.now() - start_time))
コード例 #4
0
def main():
    full_start_time = datetime.now()

    # set command line arguments
    args = set_arguments()
    # get settings from arguments
    settings = get_settings(args)
    # connect to Postgres
    try:
        pg_conn = psycopg2.connect(settings['pg_connect_string'])
    except psycopg2.Error:
        logger.fatal(
            "Unable to connect to database\nACTION: Check your Postgres parameters and/or database security"
        )
        return False

    pg_conn.autocommit = True
    pg_cur = pg_conn.cursor()

    # log postgres/postgis versions being used
    geoscape.check_postgis_version(pg_cur, settings, logger)

    logger.info("")

    # get SRID of locality boundaries
    sql = geoscape.prep_sql(
        f"select Find_SRID('{settings['admin_bdys_schema']}', 'locality_bdys', 'geom')",
        settings)
    pg_cur.execute(sql)
    settings['srid'] = int(pg_cur.fetchone()[0])
    if settings['srid'] == 4283:
        logger.info(
            f"Locality boundary coordinate system is EPSG:{settings['srid']} (GDA94)"
        )
    elif settings['srid'] == 7844:
        logger.info(
            f"Locality boundary coordinate system is EPSG:{settings['srid']} (GDA2020)"
        )
    else:
        logger.fatal(
            "Invalid coordinate system (SRID) - EXITING!\nValid values are 4283 (GDA94) and 7844 (GDA2020)"
        )
        exit()

    # add Postgres functions to clean out non-polygon geometries from GeometryCollections
    pg_cur.execute(
        geoscape.open_sql_file("create-polygon-intersection-function.sql",
                               settings).format(settings['srid']))
    pg_cur.execute(
        geoscape.open_sql_file("create-multi-linestring-split-function.sql",
                               settings))

    # let's build some clean localities!
    logger.info("")
    create_states_and_prep_localities(settings)
    get_split_localities(pg_cur, settings)
    verify_locality_polygons(pg_cur, settings)
    get_locality_state_border_gaps(pg_cur, settings)
    finalise_display_localities(pg_cur, settings)
    create_display_postcodes(pg_cur, settings)
    export_display_localities(pg_cur, settings)
    qa_display_localities(pg_cur, settings)

    pg_cur.close()
    pg_conn.close()

    logger.info("Total time : {0}".format(datetime.now() - full_start_time))

    return True
コード例 #5
0
def export_display_localities(pg_cur, settings):
    start_time = datetime.now()

    # create export path
    pathlib.Path(settings['output_path']).mkdir(parents=True, exist_ok=True)

    sql = geoscape.open_sql_file("07-export-display-localities.sql", settings)

    if platform.system() == "Windows":
        password_str = "SET"
    else:
        password_str = "export"

    password_str += " PGPASSWORD={0}&&".format(settings['pg_password'])

    cmd = password_str + "pgsql2shp -f \"{0}\" -u {1} -h {2} -p {3} {4} \"{5}\""\
        .format(settings['shapefile_export_path'], settings['pg_user'], settings['pg_host'],
                settings['pg_port'], settings['pg_db'], sql)

    # logger.info(cmd
    geoscape.run_command_line(cmd)

    # zip shapefile
    if settings['srid'] == 4283:
        shp_zip_path = settings['shapefile_name'] + "-shapefile.zip"
    else:
        shp_zip_path = settings['shapefile_name'] + "-gda2020-shapefile.zip"

    output_zipfile = os.path.join(settings['output_path'], shp_zip_path)
    zf = zipfile.ZipFile(output_zipfile, mode="w")

    for ext in settings['shapefile_extensions']:
        file_name = settings['shapefile_name'] + ext
        file_path = os.path.join(settings['output_path'], file_name)
        zf.write(file_path, file_name, compress_type=zipfile.ZIP_DEFLATED)

    zf.close()

    time_elapsed = datetime.now() - start_time

    logger.info(
        "\t- Step 7 of 8 : display localities exported to SHP : {0}".format(
            time_elapsed))
    if time_elapsed.seconds < 2:
        logger.warning(
            "\t\t- This step took < 2 seconds - it may have failed silently. "
            "Check your output directory!")

    start_time = datetime.now()

    # Export as GeoJSON FeatureCollection
    sql = geoscape.prep_sql(
        "SELECT gid, locality_pid, locality_name, COALESCE(postcode, '') AS postcode, state, "
        "locality_class, address_count, street_count, ST_AsGeoJSON(geom, 5, 0) AS geom "
        "FROM {0}.locality_bdys_display".format(settings['admin_bdys_schema']),
        settings)
    pg_cur.execute(sql)

    # Create the GeoJSON output with an array of dictionaries containing the field names and values

    # get column names from cursor
    column_names = [desc[0] for desc in pg_cur.description]

    json_dicts = []
    row = pg_cur.fetchone()

    if row is not None:
        while row is not None:
            rec = {}
            props = {}
            i = 0
            rec["type"] = "Feature"

            for column in column_names:
                if column == "geometry" or column == "geom":
                    rec["geometry"] = row[i]
                else:
                    props[column] = row[i]

                i += 1

            rec["properties"] = props
            json_dicts.append(rec)
            row = pg_cur.fetchone()

    gj = json.dumps(json_dicts).replace("\\",
                                        "").replace('"{',
                                                    '{').replace('}"', '}')

    geojson = ''.join(['{"type":"FeatureCollection","features":', gj, '}'])

    text_file = open(settings['geojson_export_path'], "w")
    text_file.write(geojson)
    text_file.close()

    # compress GeoJSON
    if settings['srid'] == 4283:
        geojson_zip_path = settings['geojson_export_path'].replace(
            ".geojson", "-geojson.zip")
    else:
        geojson_zip_path = settings['geojson_export_path'].replace(
            ".geojson", "-gda2020-geojson.zip")

    zipfile.ZipFile(geojson_zip_path, mode="w")\
        .write(settings['geojson_export_path'], compress_type=zipfile.ZIP_DEFLATED)

    logger.info(
        "\t- Step 7 of 8 : display localities exported to GeoJSON : {0}".
        format(datetime.now() - start_time))