|
1 | 1 | import logging |
2 | 2 | import os |
| 3 | +import subprocess |
3 | 4 | import sys |
4 | 5 |
|
5 | 6 | import click |
|
19 | 20 | """ |
20 | 21 |
|
21 | 22 |
|
| 23 | +def _get_max_ids(source_extract): |
| 24 | + # get the max ID from source extract using osmium |
| 25 | + ## first ensure that osmium exists |
| 26 | + try: |
| 27 | + proc = subprocess.check_call( |
| 28 | + "osmium --help", |
| 29 | + shell=True, |
| 30 | + stdout=subprocess.DEVNULL, |
| 31 | + stderr=subprocess.DEVNULL, |
| 32 | + ) |
| 33 | + except subprocess.CalledProcessError as e: |
| 34 | + logging.warning( |
| 35 | + "osmium not found; unable to determine max OSM id in source extract" |
| 36 | + ) |
| 37 | + raise e |
| 38 | + |
| 39 | + ids = {} |
| 40 | + for idtype in ["data.maxid.ways", "data.maxid.nodes", "data.maxid.relations"]: |
| 41 | + proc = subprocess.Popen( |
| 42 | + f"osmium fileinfo -e -g {idtype} --no-progress {source_extract}", |
| 43 | + shell=True, |
| 44 | + stdout=subprocess.PIPE, |
| 45 | + stderr=subprocess.PIPE, |
| 46 | + ) |
| 47 | + if proc.stderr.read(): |
| 48 | + raise subprocess.CalledProcessError(-1, "osmium", "Error in osmium.") |
| 49 | + ids[idtype.split(".")[-1]] = int(proc.stdout.read().strip()) |
| 50 | + return ids |
| 51 | + |
| 52 | + |
22 | 53 | def _get_db_tables(suffix, dbname, dbport, dbuser, dbpass, dbhost): |
23 | 54 | c = psy.connect( |
24 | 55 | dbname=dbname, host=dbhost, user=dbuser, password=dbpass, port=dbport |
@@ -67,6 +98,13 @@ def _get_db_tables(suffix, dbname, dbport, dbuser, dbpass, dbhost): |
67 | 98 | default=0, |
68 | 99 | show_default=True, |
69 | 100 | ) |
| 101 | +@click.option( |
| 102 | + "--no_collisions", |
| 103 | + help="Stop execution if the chosen ID offset " |
| 104 | + "will cause collisions with existing OSM ids." |
| 105 | + " (requires osmium).", |
| 106 | + is_flag=True, |
| 107 | +) |
70 | 108 | @click.option( |
71 | 109 | "--self", |
72 | 110 | "-si", |
@@ -103,6 +141,19 @@ def main(*args: tuple, **kwargs: dict): |
103 | 141 | setup_logging(debug=kwargs["debug"]) |
104 | 142 | logging.debug(f"Args: {kwargs}") |
105 | 143 |
|
| 144 | + # Check for ID collisions and warn |
| 145 | + try: |
| 146 | + ids = _get_max_ids(kwargs["osmsrc"]) |
| 147 | + if any([kwargs["id_offset"] < id for id in ids.values()]): |
| 148 | + _log_text = f"Chosen ID offset {kwargs['id_offset']} may cause collisions with existing OSM IDs (max IDs: {ids})." |
| 149 | + if kwargs["no_collisions"]: |
| 150 | + logging.fatal(_log_text) |
| 151 | + sys.exit(-1) |
| 152 | + else: |
| 153 | + logging.warning(_log_text) |
| 154 | + except subprocess.CalledProcessError: |
| 155 | + logging.error("Error checking existing OSM max ids.") |
| 156 | + |
106 | 157 | new_tables = [] |
107 | 158 | for suffix in kwargs["suffix"]: |
108 | 159 | new_tables.extend( |
|
0 commit comments