Skip to content

Commit

Permalink
Add support for polygons in changefiles (as Ways) (#11)
Browse files Browse the repository at this point in the history
* first pass at deletion

* add relation and relationmember support to writer

* create nodes for polygons with holes as relations

* some tests + bugfixes

* error checking

* make intersection searching optional

* ensure closed ways

* if -> elif

* remove support for polygon modification

* instead of --no_intersections just make --existing optional

* remove reference to no_intersections

* make relations for long polygon exterior ways

* rework relations after testign

* small tweaks

* default for max_nodes_per_way
  • Loading branch information
acannistra authored Jun 15, 2021
1 parent 44c7a30 commit 9f73d49
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 38 deletions.
4 changes: 0 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ repos:
hooks:
- id: reorder-python-imports
language_version: python3
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.782
hooks:
- id: mypy
- repo: https://github.com/prettier/prettier
rev: 2.1.2
hooks:
Expand Down
21 changes: 19 additions & 2 deletions changegen/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import math
import os
import subprocess
import sys
Expand All @@ -11,6 +12,7 @@
from .generator import generate_deletions
from .util import setup_logging


"""
cli.py
Expand Down Expand Up @@ -97,6 +99,7 @@ def _get_db_tables(suffix, dbname, dbport, dbuser, dbpass, dbhost):
" features must be altered to include linestring intersections."
),
multiple=True,
default=[],
)
@click.option(
"-m",
Expand Down Expand Up @@ -135,6 +138,15 @@ def _get_db_tables(suffix, dbname, dbport, dbuser, dbpass, dbhost):
),
is_flag=True,
)
@click.option(
"--max_nodes_per_way",
help=(
"Number of nodes allowed per way. Default 2000."
" If a way exceeds this value "
" it will be subdivided into smaller ways. Pass `none` for no limit."
),
default="2000",
)
@click.option("--osmsrc", help="Source OSM PBF File path", required=True)
@click.argument("dbname", default=os.environ.get("PGDATABASE", "conflate"))
@click.argument("dbport", default=os.environ.get("PGPORT", "15432"))
Expand Down Expand Up @@ -195,15 +207,19 @@ def main(*args: tuple, **kwargs: dict):
)
logging.info(f"Found tables in db: {new_tables}")

max_nodes_per_way = kwargs["max_nodes_per_way"]
if str(max_nodes_per_way).lower() == "none":
max_nodes_per_way = math.inf
elif max_nodes_per_way == None:
max_nodes_per_way = 2000
if kwargs["modify_meta"] and kwargs["existing"]:
raise RuntimeError("--modify_meta cannot be used with --existing.")
if not kwargs["deletions"] and not kwargs["modify_meta"] and not kwargs["existing"]:
raise RuntimeError("Need either --modify_meta or --existing.")

for table in new_tables:
generate_changes(
table,
kwargs["existing"],
kwargs["deletions"],
kwargs["dbname"],
kwargs["dbport"],
kwargs["dbuser"],
Expand All @@ -215,6 +231,7 @@ def main(*args: tuple, **kwargs: dict):
neg_id=kwargs["neg_id"],
id_offset=kwargs["id_offset"],
self_intersections=kwargs["self"],
max_nodes_per_way=int(max_nodes_per_way),
modify_only=kwargs["modify_meta"],
)

Expand Down
17 changes: 17 additions & 0 deletions changegen/changewriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
Tag = namedtuple("Tag", "key,value")
Node = namedtuple("Node", "id, version, lat, lon, tags")
Way = namedtuple("Way", "id, version, nds, tags")
Relation = namedtuple("Relation", "id, version, members, tags")
RelationMember = namedtuple("RelationMember", "ref, type, role")


def write_osm_object(osm, writer):
Expand All @@ -54,10 +56,15 @@ def write_osm_object(osm, writer):
try:
attrs = dict(osm._asdict())
objtype = type(osm).__name__.lower()
# we don't want to write tags, nds, or members in the main element
# for objects. They'll get written as child elements below.
attrs.pop("tags")
if hasattr(osm, "nds"):
attrs.pop("nds")
if hasattr(osm, "members"):
attrs.pop("members")
attrs = {k: str(attrs[k]) for k in attrs.keys()}

with writer.element(objtype, **attrs):
# special cases for objects with
# <tags> or <nds> (ways). Write as sub-elems
Expand All @@ -67,6 +74,16 @@ def write_osm_object(osm, writer):
if hasattr(osm, "nds"):
for nd in osm.nds:
writer.write(etree.Element("nd", ref=str(nd)))
if hasattr(osm, "members"):
for member in osm.members:
writer.write(
etree.Element(
"member",
ref=str(member.ref),
type=member.type,
role=member.role,
)
)
writer.flush()
except AttributeError:
raise RuntimeError(f"OSM Object {osm} is malformed.")
Expand Down
Loading

0 comments on commit 9f73d49

Please sign in to comment.