-
Notifications
You must be signed in to change notification settings - Fork 121
Restore building scale rank #1739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
zerebubuth
merged 7 commits into
master
from
zerebubuth/1732-restore-building-scale-rank
Dec 19, 2018
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
9bb3e24
Quantize building heights in a separate step before merging.
zerebubuth 3b0da05
Assign scale rank _before_ merging.
zerebubuth 8114241
Keep scale rank 4 buildings at z14.
zerebubuth 87fd074
Adjust min zoom thresholds to match new scale rank inclusions. Clamp …
zerebubuth 291db2f
Add test for scale rank zoom visibility.
zerebubuth 449a1d7
Apply scale_rank min_zoom clamping at zoom 16 as well, for consistency.
zerebubuth ca66504
Add better explanation of what clamp_min_zoom is doing, plus tests to…
zerebubuth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| # -*- encoding: utf-8 -*- | ||
| from . import FixtureTest | ||
|
|
||
|
|
||
| class Buildings(object): | ||
| def __init__(self, z, x, y, landuse_kind=None): | ||
| from tilequeue.tile import coord_to_mercator_bounds | ||
| from ModestMaps.Core import Coordinate | ||
| import dsl | ||
|
|
||
| bounds = coord_to_mercator_bounds(Coordinate(zoom=z, column=x, row=y)) | ||
| self.origin_x = bounds[0] | ||
| self.origin_y = bounds[1] | ||
| self.buildings = [] | ||
| self.way_id = 1 | ||
|
|
||
| if landuse_kind is not None: | ||
| self.buildings.append(dsl.way(self.way_id, dsl.tile_box(z, x, y), { | ||
| 'landuse': landuse_kind, | ||
| 'source': 'openstreetmap.org', | ||
| })) | ||
| self.way_id += 1 | ||
|
|
||
| # minx, miny, maxx, maxy are in mercator meters from the bottom left | ||
| # corner of the tile, so it's easier to calculate area. | ||
| def add(self, minx, miny, maxx, maxy, height=5, extra_tags={}): | ||
| from dsl import way | ||
| from shapely.geometry import box | ||
| from shapely.ops import transform | ||
| from tilequeue.tile import reproject_mercator_to_lnglat | ||
|
|
||
| shape = box(self.origin_x + minx, self.origin_y + miny, | ||
| self.origin_x + maxx, self.origin_y + maxy) | ||
| shape_lnglat = transform(reproject_mercator_to_lnglat, shape) | ||
|
|
||
| tags = { | ||
| 'source': 'openstreetmap.org', | ||
| 'building': 'yes', | ||
| } | ||
| tags.update(extra_tags) | ||
|
|
||
| self.buildings.append(way(self.way_id, shape_lnglat, tags)) | ||
| self.way_id += 1 | ||
|
|
||
|
|
||
| class BuildingScaleRankTest(FixtureTest): | ||
|
|
||
| def _setup_row(self, z, x, y, width, depth, n, height=5, extra_tags={}, | ||
| landuse_kind=None): | ||
| b = Buildings(z, x, y, landuse_kind=landuse_kind) | ||
| for i in xrange(0, n * width, width): | ||
| b.add(i, 0, i + width, depth, height=height, extra_tags=extra_tags) | ||
|
|
||
| self.generate_fixtures(*b.buildings) | ||
|
|
||
| def test_not_merged_z16(self): | ||
| # make a row of buildings, check that they get assigned scale | ||
| # rank and are _not_ merged at z16. | ||
| z, x, y = (16, 0, 0) | ||
|
|
||
| self._setup_row(z, x, y, 10, 40, 10) | ||
|
|
||
| # and there are 10 buildings with scale rank 5 | ||
| self.assert_n_matching_features( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'scale_rank': 5, | ||
| }, 10) | ||
|
|
||
| # and none with any other scale rank value. | ||
| self.assert_no_matching_feature( | ||
| z, x, y, 'buildings', { | ||
| 'scale_rank': (lambda r: r != 5) | ||
| }) | ||
|
|
||
| def test_merged_z15(self): | ||
| # make a row of buildings, check that they get assigned scale | ||
| # rank and are merged at z15. | ||
| z, x, y = (15, 0, 0) | ||
|
|
||
| self._setup_row(z, x, y, 10, 40, 10) | ||
|
|
||
| # should be only 1 building feature now | ||
| self.assert_n_matching_features( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'scale_rank': 5, | ||
| }, 1) | ||
|
|
||
| # and none with any other scale rank value. | ||
| self.assert_no_matching_feature( | ||
| z, x, y, 'buildings', { | ||
| 'scale_rank': (lambda r: r != 5) | ||
| }) | ||
|
|
||
| def test_drop_scale_rank_5_at_z14(self): | ||
| # make a row of buildings, check that they get assigned scale | ||
| # rank and are merged at z15. | ||
| z, x, y = (14, 0, 0) | ||
|
|
||
| self._setup_row(z, x, y, 10, 40, 10) | ||
|
|
||
| # scale_rank 5 features should be dropped at this zoom. | ||
| self.assert_no_matching_feature( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'scale_rank': 5, | ||
| }) | ||
|
|
||
| def test_merged_z14(self): | ||
| # make a row of buildings, check that they get assigned scale | ||
| # rank and are merged at z14. | ||
| z, x, y = (14, 0, 0) | ||
|
|
||
| self._setup_row(z, x, y, 10, 50, 10, landuse_kind='retail') | ||
|
|
||
| # should be only 1 building feature now | ||
| self.assert_n_matching_features( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'scale_rank': 4, | ||
| }, 1) | ||
|
|
||
| # and none with any other scale rank value. | ||
| self.assert_no_matching_feature( | ||
| z, x, y, 'buildings', { | ||
| 'scale_rank': (lambda r: r != 4) | ||
| }) | ||
|
|
||
| def test_tiny_shed_z17(self): | ||
| # check that a tiny shed, assigned zoom 17 in the buildings.yaml, | ||
| # doesn't get re-assigned a lower zoom. it should stay at z17. | ||
| z, x, y = (16, 0, 0) | ||
|
|
||
| # make one 1x1m building. | ||
| self._setup_row(z, x, y, 1, 1, 1) | ||
|
|
||
| self.assert_n_matching_features( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'min_zoom': 17, | ||
| }, 1) | ||
|
|
||
| def test_slightly_larger_outbuilding_z16(self): | ||
| # check that a small building (or large shed), assigned zoom 16 in the | ||
| # buildings.yaml, doesn't get re-assigned a lower zoom. it should stay | ||
| # at z16. | ||
| z, x, y = (16, 0, 0) | ||
|
|
||
| # make one 4x4m building. | ||
| self._setup_row(z, x, y, 4, 4, 1) | ||
|
|
||
| self.assert_n_matching_features( | ||
| z, x, y, 'buildings', { | ||
| 'kind': 'building', | ||
| 'min_zoom': 16, | ||
| }, 1) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in zoom 16? If we clamp feature inclusion at zooms 13, 14, 15 based on scale_rank, but don't clamp at max zoom 16, it seems like zoom 16 would include new features that could have a min_zoom < 16 but weren't shown at the earlier zooms?
Should we go farther and make
scale_rankandmin_zoomconsistent (and then markscale_rankfor retirement in v2)?From the map examples, including the clamping:
In the existing building.yaml file:
In Bubble Wrap:
problematic at zoom 15
In Refill (map):
problematic at zoom 15
Then the existing scale_rank.csv is:
Should the building.yaml file change like (I'm fussy on the landuse_kind and 14.5 logic)?
Then this clamp section wouldn't be needed at all? We leave the scale_rank CSV alone, but only modify the min_zoom calcs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, well spotted, thanks! Yes, we should make that consistent. I've made the change in 449a1d7.
Unfortunately, the
scale_rankcalculation makes use of thelanduse_kind, which is assigned by a post-processor and not known when we assignmin_zoomin the database. I'm all for simplifying, but we'll end up with a process that looks a lot like the current one (i.e: assign the minimummin_zoomfor the feature, then assignscale_rank, then usescale_rankto clampmin_zoom- basically dropping half a zoom based onlanduse_kind).One question is how the
min_zoomlogic works in the client. If we assign amin_zoomof 14.5, will that be visible in the zoom 14 tile? Or would it require work-arounds in the style file (filter: function() { return $zoom > feature.min_zoom - 0.5; }) to make sure that we're not including a bunch of data in the tile that'll never be shown?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked about this IRL...
Now that the clamp is always applied I think we're aways consistent, thanks!
Please add tests to ensure
min_zoom: 16andmin_zoom: 17buildings (tiny ones!) still get their min_zoom preserved, then I think we're good for merging.I filed #1745 to address removing
scale_rankentirely (just in favor ofmin_zoom) for eventual v2 milestone.