From 785e773d8ad0ddbf883f8874450e227768f6ea14 Mon Sep 17 00:00:00 2001 From: roelderickx Date: Sun, 10 Sep 2023 17:45:03 +0200 Subject: [PATCH] #36 replace --consider-elevation parameter with --add-z-value-tag for a more generic solution --- README.md | 8 ++++---- ogr2osm/ogr2osm.py | 9 +++------ ogr2osm/osm_data.py | 24 +++++++++++++++--------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 7cdff01..1488256 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ usage: ogr2osm [-h] [--version] [-t TRANSLATION] [--encoding ENCODING] [--saveid SAVEID] [-o OUTPUT] [-f] [--pbf] [--no-upload-false] [--never-download] [--never-upload] [--locked] [--add-bounds] [--suppress-empty-tags] [--max-tag-length MAXTAGLENGTH] + [--add-z-value-tag TAGNAME] DATASOURCE positional arguments: @@ -118,9 +119,6 @@ options: Split ways with more than the specified number of nodes. Defaults to 1800. Any value below 2 - do not split. - --consider-elevation If nodes have the same (X,Y) coordinates but different - Z-levels (e.g, different elevation), then they will be - given different node IDs (default: False) --id ID ID to start counting from for the output file. Defaults to 0. --idfile IDFILE Read ID to start counting from from a file. @@ -145,6 +143,8 @@ options: Set max character length of tag values. Exceeding values will be truncated and end with '...'. Defaults to 255. Values smaller than 3 disable the limit. + --add-z-value-tag TAGNAME + The tagname in which the z-value will be saved. ``` ### As a library @@ -202,7 +202,7 @@ osmdata = ogr2osm.OsmData(translation_object) # - max_points_in_way: --split-ways parameter # - add_bounds: --add-bounds parameter # - start_id: --id parameter -# - consider_elevation: --consider-elevation parameter +# - z_value_tagname: --add-z-value-tag osmdata.process(datasource) # 7. Instantiate either ogr2osm.OsmDataWriter or ogr2osm.PbfDataWriter and diff --git a/ogr2osm/ogr2osm.py b/ogr2osm/ogr2osm.py index 0552ad8..68674a7 100755 --- a/ogr2osm/ogr2osm.py +++ b/ogr2osm/ogr2osm.py @@ -96,11 +96,6 @@ def parse_commandline(logger): parser.add_argument("--split-ways", dest="maxNodesPerWay", type=int, default=1800, help="Split ways with more than the specified number of nodes. " + "Defaults to %(default)s. Any value below 2 - do not split.") - parser.add_argument("--consider-elevation", dest="considerElevation", action="store_true", - help="If nodes have the same (X,Y) coordinates but different Z-levels " + - "(e.g, different elevation), " + - "then they will be given different node IDs " + - "(default: %(default)s)") # ID generation options parser.add_argument("--id", dest="id", type=int, default=0, help="ID to start counting from for the output file. " + @@ -140,6 +135,8 @@ def parse_commandline(logger): f"truncated and end with '{OsmDataWriter.TAG_OVERFLOW}'. Defaults " + "to %(default)s. Values smaller than " + f"{len(OsmDataWriter.TAG_OVERFLOW)} disable the limit.") + parser.add_argument("--add-z-value-tag", dest="zValueTagName", type=str, metavar="TAGNAME", + help="The tagname in which the z-value will be saved.") parser.add_argument("--add-version", dest="addVersion", action="store_true", help=argparse.SUPPRESS) # can cause problems when used inappropriately parser.add_argument("--add-timestamp", dest="addTimestamp", action="store_true", @@ -271,7 +268,7 @@ def main(): osmdata = OsmData(translation_object, \ params.roundingDigits, params.maxNodesPerWay, params.addBounds, \ - params.id, params.positiveId, params.considerElevation) + params.id, params.positiveId, params.zValueTagName) osmdata.load_start_id_from_file(params.idfile) diff --git a/ogr2osm/osm_data.py b/ogr2osm/osm_data.py index 587335e..ff73bbf 100644 --- a/ogr2osm/osm_data.py +++ b/ogr2osm/osm_data.py @@ -18,7 +18,7 @@ class OsmData: def __init__(self, translation, rounding_digits=7, max_points_in_way=1800, add_bounds=False, \ - start_id=0, is_positive=False, consider_elevation=False): + start_id=0, is_positive=False, z_value_tagname=None): self.logger = logging.getLogger(__program__) # options @@ -26,7 +26,7 @@ def __init__(self, translation, rounding_digits=7, max_points_in_way=1800, add_b self.rounding_digits = rounding_digits self.max_points_in_way = max_points_in_way self.add_bounds = add_bounds - self.consider_elevation = consider_elevation + self.z_value_tagname = z_value_tagname self.__bounds = OsmBoundary() self.__nodes = [] @@ -84,17 +84,15 @@ def __round_number(self, n): return int(round(n * 10**self.rounding_digits)) - def __add_node(self, x, y, tags, is_way_member, z=None): + def __add_node(self, x, y, z, tags, is_way_member): rx = self.__round_number(x) ry = self.__round_number(y) - rz = self.__round_number(z) if self.consider_elevation and z else None + rz = self.__round_number(z) # TODO deprecated unique_node_id = None if is_way_member: unique_node_id = (rx, ry) - if rz is not None: - unique_node_id = (rx, ry, rz) else: unique_node_id = self.translation.get_unique_node_identifier(rx, ry, tags) # to be replaced by @@ -105,6 +103,9 @@ def __add_node(self, x, y, tags, is_way_member, z=None): for index in self.__unique_node_index[unique_node_id]: duplicate_node = self.__nodes[index] merged_tags = self.translation.merge_tags('node', duplicate_node.tags, tags) + if self.z_value_tagname: + new_tags = { self.z_value_tagname: str(rz) } + merged_tags = self.translation.merge_tags('node', merged_tags, new_tags) if merged_tags is not None: duplicate_node.tags = merged_tags return duplicate_node @@ -114,7 +115,11 @@ def __add_node(self, x, y, tags, is_way_member, z=None): self.__nodes.append(node) return node else: - node = OsmNode(x, y, tags) + merged_tags = tags + if self.z_value_tagname: + new_tags = { self.z_value_tagname: [ str(rz) ] } + merged_tags = self.translation.merge_tags('node', new_tags, tags) + node = OsmNode(x, y, merged_tags) self.__unique_node_index[unique_node_id] = [ len(self.__nodes) ] self.__nodes.append(node) return node @@ -133,7 +138,8 @@ def __add_relation(self, tags): def __parse_point(self, ogrgeometry, tags): - return self.__add_node(ogrgeometry.GetX(), ogrgeometry.GetY(), tags, False, z=ogrgeometry.GetZ()) + return self.__add_node(ogrgeometry.GetX(), ogrgeometry.GetY(), ogrgeometry.GetZ(), \ + tags, False) def __parse_multi_point(self, ogrgeometry, tags): @@ -188,7 +194,7 @@ def __parse_linestring(self, ogrgeometry, tags): potential_duplicate_ways = [] for i in range(ogrgeometry.GetPointCount()): (x, y, z) = ogrgeometry.GetPoint(i) - node = self.__add_node(x, y, {}, True, z=z) + node = self.__add_node(x, y, z, { }, True) if previous_node_id is None or previous_node_id != node.id: if previous_node_id is None: # first node: add all parent ways as potential duplicates