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()
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()
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'))
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
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
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)
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)
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)
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)