コード例 #1
0
def load_osm_file(context):
    """
    Load the given data into a freshly created test data using osm2pgsql.
    No further indexing is done.

    The data is expected as attached text in OPL format.
    """
    # create an OSM file and import it
    fname = write_opl_file(context.text, context.osm)
    try:
        run_osm2pgsql(
            get_osm2pgsql_options(context.nominatim, fname, append=False))
    finally:
        os.remove(fname)

    ### reintroduce the triggers/indexes we've lost by having osm2pgsql set up place again
    cur = context.db.cursor()
    cur.execute("""CREATE TRIGGER place_before_delete BEFORE DELETE ON place
                    FOR EACH ROW EXECUTE PROCEDURE place_delete()""")
    cur.execute("""CREATE TRIGGER place_before_insert BEFORE INSERT ON place
                   FOR EACH ROW EXECUTE PROCEDURE place_insert()""")
    cur.execute(
        """CREATE UNIQUE INDEX idx_place_osm_unique on place using btree(osm_id,osm_type,class,type)"""
    )
    context.db.commit()
コード例 #2
0
def import_osm_data(osm_files, options, drop=False, ignore_errors=False):
    """ Import the given OSM files. 'options' contains the list of
        default settings for osm2pgsql.
    """
    options['import_file'] = osm_files
    options['append'] = False
    options['threads'] = 1

    if not options['flatnode_file'] and options['osm2pgsql_cache'] == 0:
        # Make some educated guesses about cache size based on the size
        # of the import file and the available memory.
        mem = psutil.virtual_memory()
        fsize = 0
        if isinstance(osm_files, list):
            for fname in osm_files:
                fsize += os.stat(str(fname)).st_size
        else:
            fsize = os.stat(str(osm_files)).st_size
        options['osm2pgsql_cache'] = int(min((mem.available + mem.cached) * 0.75,
                                             fsize * 2) / 1024 / 1024) + 1

    run_osm2pgsql(options)

    with connect(options['dsn']) as conn:
        if not ignore_errors:
            with conn.cursor() as cur:
                cur.execute('SELECT * FROM place LIMIT 1')
                if cur.rowcount == 0:
                    raise UsageError('No data imported by osm2pgsql.')

        if drop:
            conn.drop_table('planet_osm_nodes')

    if drop and options['flatnode_file']:
        Path(options['flatnode_file']).unlink()
コード例 #3
0
def test_run_osm2pgsql():
    exec_utils.run_osm2pgsql(
        dict(osm2pgsql='echo',
             append=False,
             flatnode_file=None,
             dsn='dbname=foobar',
             threads=1,
             osm2pgsql_cache=500,
             osm2pgsql_style='./my.style',
             import_file='foo.bar'))
コード例 #4
0
def add_data_from_file(fname, options):
    """ Adds data from a OSM file to the database. The file may be a normal
        OSM file or a diff file in all formats supported by libosmium.
    """
    options['import_file'] = Path(fname)
    options['append'] = True
    run_osm2pgsql(options)

    # No status update. We don't know where the file came from.
    return 0
コード例 #5
0
def update(conn, options):
    """ Update database from the next batch of data. Returns the state of
        updates according to `UpdateState`.
    """
    startdate, startseq, indexed = status.get_status(conn)

    if startseq is None:
        LOG.error("Replication not set up. "
                  "Please run 'nominatim replication --init' first.")
        raise UsageError("Replication not set up.")

    if not indexed and options['indexed_only']:
        LOG.info("Skipping update. There is data that needs indexing.")
        return UpdateState.MORE_PENDING

    last_since_update = dt.datetime.now(dt.timezone.utc) - startdate
    update_interval = dt.timedelta(seconds=options['update_interval'])
    if last_since_update < update_interval:
        duration = (update_interval - last_since_update).seconds
        LOG.warning("Sleeping for %s sec before next update.", duration)
        time.sleep(duration)

    if options['import_file'].exists():
        options['import_file'].unlink()

    # Read updates into file.
    repl = ReplicationServer(options['base_url'])

    outhandler = WriteHandler(str(options['import_file']))
    endseq = repl.apply_diffs(outhandler,
                              startseq + 1,
                              max_size=options['max_diff_size'] * 1024)
    outhandler.close()

    if endseq is None:
        return UpdateState.NO_CHANGES

    # Consume updates with osm2pgsql.
    options['append'] = True
    options['disable_jit'] = conn.server_version_tuple() >= (11, 0)
    run_osm2pgsql(options)

    # Write the current status to the file
    endstate = repl.get_state_info(endseq)
    status.set_status(conn,
                      endstate.timestamp if endstate else None,
                      seq=endseq,
                      indexed=False)

    return UpdateState.UP_TO_DATE
コード例 #6
0
def update_from_osm_file(context):
    """
    Update a database previously populated with 'loading osm data'.
    Needs to run indexing on the existing data first to yield the correct result.

    The data is expected as attached text in OPL format.
    """
    context.nominatim.copy_from_place(context.db)
    context.nominatim.run_nominatim('index')
    context.nominatim.run_nominatim('refresh', '--functions')

    # create an OSM file and import it
    fname = write_opl_file(context.text, context.osm)
    try:
        run_osm2pgsql(
            get_osm2pgsql_options(context.nominatim, fname, append=True))
    finally:
        os.remove(fname)
コード例 #7
0
def add_osm_object(osm_type, osm_id, use_main_api, options):
    """ Add or update a single OSM object from the latest version of the
        API.
    """
    if use_main_api:
        base_url = f'https://www.openstreetmap.org/api/0.6/{osm_type}/{osm_id}'
        if osm_type in ('way', 'relation'):
            base_url += '/full'
    else:
        # use Overpass API
        if osm_type == 'node':
            data = f'node({osm_id});out meta;'
        elif osm_type == 'way':
            data = f'(way({osm_id});>;);out meta;'
        else:
            data = f'(rel(id:{osm_id});>;);out meta;'
        base_url = 'https://overpass-api.de/api/interpreter?' \
                   + urllib.parse.urlencode({'data': data})

    options['append'] = True
    options['import_data'] = get_url(base_url).encode('utf-8')

    run_osm2pgsql(options)
コード例 #8
0
def test_run_osm2pgsql_disable_jit(osm2pgsql_options):
    osm2pgsql_options['append'] = True
    osm2pgsql_options['import_file'] = 'foo.bar'
    osm2pgsql_options['disable_jit'] = True
    exec_utils.run_osm2pgsql(osm2pgsql_options)
コード例 #9
0
def test_run_osm2pgsql(osm2pgsql_options):
    osm2pgsql_options['append'] = False
    osm2pgsql_options['import_file'] = 'foo.bar'
    osm2pgsql_options['tablespaces']['osm_data'] = 'extra'
    exec_utils.run_osm2pgsql(osm2pgsql_options)