Simplify lines (not tested yet)

Uses simplification with Visvalingam–Whyatt or
Ramer–Douglas–Peucker algorithms
This commit is contained in:
Ruben van de Ven 2025-04-17 12:16:41 +02:00
parent dc41f64df9
commit 73671ddd69
3 changed files with 47 additions and 0 deletions

View file

@ -31,6 +31,7 @@ dependencies = [
"foucault",
"python-statemachine>=2.5.0",
"facenet-pytorch>=2.5.3",
"simplification>=0.7.12",
]
[project.scripts]

View file

@ -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 #' RamerDouglasPeucker'
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)

18
uv.lock
View file

@ -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" },