From 73671ddd691f6658763f57e6b8299cdc6287af35 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Thu, 17 Apr 2025 12:16:41 +0200 Subject: [PATCH] Simplify lines (not tested yet) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses simplification with Visvalingam–Whyatt or Ramer–Douglas–Peucker algorithms --- pyproject.toml | 1 + trap/stage.py | 28 ++++++++++++++++++++++++++++ uv.lock | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index cec4235..9133096 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ dependencies = [ "foucault", "python-statemachine>=2.5.0", "facenet-pytorch>=2.5.3", + "simplification>=0.7.12", ] [project.scripts] diff --git a/trap/stage.py b/trap/stage.py index b642431..9b2151b 100644 --- a/trap/stage.py +++ b/trap/stage.py @@ -12,6 +12,8 @@ from statemachine import Event, State, StateMachine from statemachine.exceptions import TransitionNotAllowed import zmq +from simplification.cutil import simplify_coords_idx, simplify_coords_vw_idx + from sgan.sgan import data from trap import shapes from trap.base import DataclassJSONEncoder, Frame, Track @@ -328,6 +330,7 @@ class DrawnScenario(TrackScenario): # def from_list(cls, l: List[float, float]) -> RenderablePosition: # return cls(x = float(l[0]), y=float(l[1])) +# TODO)) Or Shapely point? RenderablePosition = Tuple[float,float] @dataclass @@ -349,14 +352,38 @@ class RenderablePoint(): def from_list(cls, l: List[float, float], color: SrgbaColor) -> RenderablePoint: return cls([float(l[0]), float(l[1])], color) +SIMPLIFY_FACTOR_RDP = .5 +SIMPLIFY_FACTOR_VW = 10 + +class SimplifyMethod(Enum): + RDP = 1 #' Ramer–Douglas–Peucker' + VW = 2 # Visvalingam-Whyatt + @dataclass class RenderableLine(): points: List[RenderablePoint] + def as_simplified(self, method: SimplifyMethod = SimplifyMethod.RDP): + linestring = [p.position for p in self.points] + if method == SimplifyMethod.RDP: + indexes = simplify_coords_idx(linestring, SIMPLIFY_FACTOR_RDP) + elif method == SimplifyMethod.VW: + indexes = simplify_coords_vw_idx(linestring, SIMPLIFY_FACTOR_VW) + points = [self.points[i] for i in indexes] + return RenderableLine(points) + + + @dataclass class RenderableLines(): lines: List[RenderableLine] + def as_simplified(self, method: SimplifyMethod = SimplifyMethod.RDP): + """Wraps RenderableLine simplification""" + return RenderableLines( + [line.as_simplified(method) for line in self.lines] + ) + class Stage(Node): """ Render a stage, on which different TrackScenarios take place to a @@ -433,6 +460,7 @@ class Stage(Node): # print(lines) rl = RenderableLines(lines) + rl = rl.as_simplified() self.counter.set("stage.lines", len(lines)) self.stage_sock.send_json(rl, cls=DataclassJSONEncoder) diff --git a/uv.lock b/uv.lock index 097f2be..049ef98 100644 --- a/uv.lock +++ b/uv.lock @@ -2191,6 +2191,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c", size = 13842 }, ] +[[package]] +name = "simplification" +version = "0.7.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/e8/9f45e78794a64f80ef457abb730eb6a9f8970a4b1970bf66f8d697387f93/simplification-0.7.12.tar.gz", hash = "sha256:88feb3e7556f49752f9decf83102d2cffbbc22ac1376329c983f4a6b4ba92e58", size = 1429940 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/7a/6cda233c007ef031c0f512708c444eea792e2738754c634c8f5f2c10033a/simplification-0.7.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:be9e83ed265091421dee6686064dd017ca8ebaece1237b2dffbfc6ca2c125ae5", size = 274648 }, + { url = "https://files.pythonhosted.org/packages/da/4e/d6beacd34ab3e4d45a443f6b844858da348ee9c98a81678e7964e5346930/simplification-0.7.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e34d8135e1c6d610fc3f845665f0012ca4bbc3e1e45c00243c4d6fb446e5039", size = 254195 }, + { url = "https://files.pythonhosted.org/packages/76/d7/d294ff839d61096eb4f12f1a8239defd19608aa4e28727da07b919aa38b5/simplification-0.7.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:208c601b2a4a412f5af34a64cb56d07472279af8e7a23efbbeb9d72c9dada74d", size = 681462 }, + { url = "https://files.pythonhosted.org/packages/81/77/a50ea0045aff794b82e577cdca18a54d24dd69732d4941e3ff255b6969c0/simplification-0.7.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdaf6f77c3c10786cd781b4f7dc21b27d12658336e974719a1a92bac6cf71814", size = 700391 }, + { url = "https://files.pythonhosted.org/packages/a6/ff/8661056732560200f0f6e340cb33e70c088aeaad1d71c0c99a7e5cfc51d9/simplification-0.7.12-cp310-cp310-win_amd64.whl", hash = "sha256:2e01ac96efdb5562bd8904d4d174f5d7cc901fcdc600d4d298d06fabbcd21cf1", size = 185096 }, +] + [[package]] name = "six" version = "1.17.0" @@ -2557,6 +2573,7 @@ dependencies = [ { name = "qrcode" }, { name = "setproctitle" }, { name = "shapely" }, + { name = "simplification" }, { name = "tensorboardx" }, { name = "torch", version = "1.12.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'linux'" }, { name = "torch", version = "1.12.1+cu113", source = { url = "https://download.pytorch.org/whl/cu113/torch-1.12.1%2Bcu113-cp310-cp310-linux_x86_64.whl" }, marker = "sys_platform == 'linux'" }, @@ -2588,6 +2605,7 @@ requires-dist = [ { name = "qrcode", specifier = "~=8.0" }, { name = "setproctitle", specifier = ">=1.3.3,<2" }, { name = "shapely", specifier = ">=1,<2" }, + { name = "simplification", specifier = ">=0.7.12" }, { name = "tensorboardx", specifier = ">=2.6.2.2,<3" }, { name = "torch", marker = "python_full_version < '3.10' or python_full_version >= '4' or sys_platform != 'linux'", specifier = "==1.12.1" }, { name = "torch", marker = "python_full_version >= '3.10' and python_full_version < '4' and sys_platform == 'linux'", url = "https://download.pytorch.org/whl/cu113/torch-1.12.1%2Bcu113-cp310-cp310-linux_x86_64.whl" },