diff --git a/queries.yaml b/queries.yaml index f06b74517..d77cf12f8 100644 --- a/queries.yaml +++ b/queries.yaml @@ -1139,13 +1139,22 @@ post_process: params: source_layer: roads start_zoom: 8 - end_zoom: 16 + end_zoom: 15 # setting the following will try to merge linestrings across junctions # (i.e: more than 2 roads meeting at a point) where the angle between # roads at that point is less than 5 degrees. merge_junctions: true merge_junction_angle: 5.0 + # we do want to merge at 15, but we don't want to merge junctions becase that + # might merge across oneway information, which doesn't get dropped until + # zoom < 15. + - fn: vectordatasource.transform.merge_line_features + params: + source_layer: roads + start_zoom: 15 + end_zoom: 16 + # simplify roads again, to take advantage of any opportunities opened up # by merging roads with the same properties in the previous step. - fn: vectordatasource.transform.simplify_layer diff --git a/test/test_transform.py b/test/test_transform.py index 39b9bda13..2a0bdaabe 100644 --- a/test/test_transform.py +++ b/test/test_transform.py @@ -965,3 +965,29 @@ def test_merge_buildings(self): self.assertEquals(len(result), 1) self.assertTrue(result[0].is_valid) + + +class AngleAtTest(unittest.TestCase): + + def _check(self, coords, angle): + from shapely.geometry import LineString + from vectordatasource.transform import _angle_at + + ls = LineString(coords) + self.assertEqual(_angle_at(ls, ls.coords[0]), angle) + self.assertEqual(_angle_at(ls, ls.coords[-1]), angle) + + def test_angle_at_zero(self): + self._check([[0, 0], [1, 0]], 0) + + def test_angle_at_180(self): + self._check([[1, 0], [0, 0]], 0) + + def test_angle_at_90(self): + self._check([[0, 0], [0, 1]], 90) + + def test_angle_at_270(self): + self._check([[0, 1], [0, 0]], 90) + + def test_angle_at_degenerate(self): + self._check([[0, 0], [0, 0]], None) diff --git a/vectordatasource/transform.py b/vectordatasource/transform.py index f58953729..d7c692e1a 100644 --- a/vectordatasource/transform.py +++ b/vectordatasource/transform.py @@ -3580,6 +3580,13 @@ def _angle_at(linestring, pt): dy = -dy a = math.atan2(dy, dx) / math.pi * 180.0 + + # wrap around at exactly 180, because we don't care about the direction of + # the road, only what angle the line is at, and 180 is horizontal same as + # 0. + if a == 180.0: + a = 0.0 + assert 0 <= a < 180 return a