Skip to content
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

Round 2 enhancements for Felt #47

Merged
merged 86 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
2ecc9fc
bug fix for town, village as city level features (not neighbourhood)
nvkelso Jun 15, 2023
4646d8f
init Makefile targets
nvkelso Jun 15, 2023
bdcd8c1
add pmap:kind coallesce
nvkelso Jun 15, 2023
0e45322
converge towards shield_text_length; pass thru other network values; …
nvkelso Jun 15, 2023
99bd2df
refactor pmap:kind calculation and add pmap:kind_detail
nvkelso Jun 15, 2023
3a8ad37
refactor places, add pmap:min_zoom, add sort func, add label grid
nvkelso Jun 15, 2023
bda1226
rework low zoom NE water
nvkelso Jun 15, 2023
cce8016
stub out water label points (natural earth only)
nvkelso Jun 16, 2023
39e9092
fix test tile coord; tmp pmtiles bin location
nvkelso Jun 21, 2023
a33723f
add kind = national_park logic
nvkelso Jun 21, 2023
330ad89
add derived water polygon labels in physical points layer
nvkelso Jun 21, 2023
dedcc61
fix java errors, comment out setSortKey for later debug
nvkelso Jun 21, 2023
d452bbe
reorder sections for a-z legibility, add optional pmap:kind_detail pr…
nvkelso Jun 21, 2023
0faa99d
add washington state target
nvkelso Jun 22, 2023
d6baab1
show county lines earlier, export Tilezen kinds (and region not state)
nvkelso Jun 22, 2023
89cc47c
block {building|building:part}=no; push building:part to later zooms;…
nvkelso Jun 22, 2023
f19aa7d
do NOT export names; formatting
nvkelso Jun 22, 2023
e501a32
do NOT export names, or areas
nvkelso Jun 22, 2023
1a34443
export label points for water polygons; & etc
nvkelso Jun 22, 2023
73249f6
use Tilezen kind values (locality not city)
nvkelso Jun 22, 2023
44f3cc2
export POIs for ways, rels too (area graded per zoom); some kind of b…
nvkelso Jun 22, 2023
a93e7b1
fix service minor roads; fix sidewalks
nvkelso Jun 22, 2023
dde2a3f
show piers later; drop short featues
nvkelso Jun 22, 2023
1dce93b
fix NE layer parsing; do NOT export names (see physical points layer …
nvkelso Jun 22, 2023
492e03c
add comment
nvkelso Jun 23, 2023
05c7890
quantize heights by zoom; push building_part to later zooms
nvkelso Jun 23, 2023
492919e
always export pmap:kind
nvkelso Jun 23, 2023
29839e6
add national_park, protected_area, and nature_reserve (moved from nat…
nvkelso Jun 23, 2023
1b91f74
remove national_park, protected_area, nature_reserve (moved to landus…
nvkelso Jun 23, 2023
153a6bd
show rivers earlier; always set kind value; intermittent to boolean
nvkelso Jun 23, 2023
fe8aa5a
switch to min_label for NE instead of min_zoom; update zoom area grad…
nvkelso Jun 23, 2023
dc6b9c1
prefix population_rank with pmap:
nvkelso Jun 23, 2023
bffdf4d
bug fixes for kind calculations; better way area calculation; show la…
nvkelso Jun 23, 2023
ba46ffe
show motorway and primary earlier; show service roads later; show pat…
nvkelso Jun 23, 2023
55c1dbf
show airport runway, taxiway earlier; show some types of rail later; …
nvkelso Jun 23, 2023
c73c1df
update kind calculation; boolean exports
nvkelso Jun 23, 2023
30ab35c
prefix population_rank with pmap:
nvkelso Jun 23, 2023
28a99c8
remove debug attr
nvkelso Jun 23, 2023
99a4c73
add phony list; remove complicated targets
nvkelso Jun 23, 2023
b56aafa
add Tilezen schema comments
nvkelso Jun 24, 2023
62cb079
add Tilezen schema comments
nvkelso Jun 24, 2023
79be151
add beach, forest, military, naval_base, airfield, zoo kinds; bug fix…
nvkelso Jun 24, 2023
45c11fc
move kind calc above; Tilezen schema notes; min pixel size to 2 from 3
nvkelso Jun 24, 2023
59d4995
add Tilezen schema comments
nvkelso Jun 24, 2023
f1b9478
some tiny lake labels earlier; add Tilezen schema comments
nvkelso Jun 24, 2023
78a6c78
refactor property gathering logic and move setAttr later; add Tilezen…
nvkelso Jun 24, 2023
6a9972c
add attraction kinds, beach kind, hide early node university kind, ad…
nvkelso Jun 24, 2023
553e5eb
refactor property gathering and attr setting; Tilezen schema notes
nvkelso Jun 24, 2023
2c7ab10
Tilezen schema notes; hide names from early zooms for more merging
nvkelso Jun 24, 2023
4d6e41e
refactor property gathering and attr setting; Tilezen schema notes
nvkelso Jun 24, 2023
433d6c2
remove unused imports, fix silly Java error
nvkelso Jun 24, 2023
88fb01c
add to early zoom blocklist
nvkelso Jun 24, 2023
fa265a0
maven formatting
nvkelso Jun 24, 2023
b27b857
update style for schema changes
nvkelso Jun 28, 2023
34ca7b3
add SF target
nvkelso Jun 28, 2023
b5a5b99
ensure pier pass thru
nvkelso Jun 28, 2023
27291b4
add grass
nvkelso Jun 28, 2023
22b7635
add label grid, separate NE from OSM at zoom 7
nvkelso Jun 28, 2023
e18abdf
add label grid; bug fixes for kinds and zooms (per kind)
nvkelso Jun 28, 2023
e0a56da
add planet target
nvkelso Jun 28, 2023
84ddc13
significant whitespace
nvkelso Jun 28, 2023
eed7401
typo
nvkelso Jun 28, 2023
19c529c
planet not world
nvkelso Jun 28, 2023
9fb4d01
add new targets
nvkelso Jun 29, 2023
06fe05c
use low zoom boundaries from Natural Earth
nvkelso Jun 29, 2023
b46e565
add zoom logic for country, region
nvkelso Jun 29, 2023
e68bd09
guard against nulls
nvkelso Jun 30, 2023
5fbd2a2
guard against null names; spell out more country names
nvkelso Jun 30, 2023
4581fc1
guard against null names
nvkelso Jun 30, 2023
d94aafb
perf; rework NE kind and kind_detail
nvkelso Jun 30, 2023
41256f1
npe, again; cleanup imports and var names
nvkelso Jul 1, 2023
580d998
standardize on var names
nvkelso Jul 1, 2023
ce14bef
ensure odd numbered admin_level do not export
nvkelso Jul 1, 2023
7739f7f
add brunnel pmap:level, remove dedicated props
nvkelso Jul 1, 2023
d95ab78
add brunnel; push disused lines later
nvkelso Jul 1, 2023
02da19c
add quarter back
nvkelso Jul 1, 2023
8b69a55
standardize sf var name
nvkelso Jul 1, 2023
36d1527
push small parks later; university buildings later
nvkelso Jul 1, 2023
3d06817
brunnel; standardize sf var name; kind_detail
nvkelso Jul 1, 2023
7babaad
regrade park area > zooms
nvkelso Jul 1, 2023
3c1789d
add changelog, version, and semver statement
nvkelso Jul 10, 2023
90f584b
similar casing order change as #42 for merge conflicts
nvkelso Jul 12, 2023
49e81d4
reserve merge conflict over road casing order #42
nvkelso Jul 12, 2023
262e9ec
linting
nvkelso Jul 12, 2023
5b0ae4e
update 1.0.0 date
bdon Jul 14, 2023
b7221a2
Merge branch 'main' into nvkelso/felt-changes-part-2
bdon Jul 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions tiles/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# download dependencies and compile the JAR
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New Makefile with easier to type commands...

# generally do this after each code change
clean:
mvn clean package

# is a build only partially finishes, the PMTiles can be corrupted
clean-pmtiles:
rm -rf *.pmtiles

# This is optimized for local dev serving PMTiles out of directory local to this Makefile
# Don't use this for production (instead set --cors=ORIGIN)
# The default port is: 8080 (use --port to override)
# Assumes go-pmtiles has been installed locally (eg prebuilt go binary download) & the path is added to your shell env
# https://github.com/protomaps/go-pmtiles
# Example tile coord to test with: http://localhost:8080/monaco/12/2133/1495.mvt
serve:
~/Downloads/pmtiles serve --cors=* .
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: This path should be updated...


#
# Testing areas
#

# Smallest
#
#Download and generate monaco.pmtiles in the current directory:
monaco:
bdon marked this conversation as resolved.
Show resolved Hide resolved
java -jar target/*-with-deps.jar --download --force --area=monaco

# Generate monaco.pmtiles in the current directory (using already downloaded asset)
monaco-fast:
java -jar target/*-with-deps.jar --force --area=monaco

# Medium
#
#Download and generate switzerland.pmtiles in the current directory:
switzerland:
java -jar target/*-with-deps.jar --download --force --area=switzerland

# Generate switzerland.pmtiles in the current directory (using already downloaded asset)
switzerland-fast:
java -jar target/*-with-deps.jar --force --area=switzerland

#Download and generate switzerland.pmtiles in the current directory:
washington:
java -jar target/*-with-deps.jar --download --force --area=washington

# Generate switzerland.pmtiles in the current directory (using already downloaded asset)
washington-fast:
java -jar target/*-with-deps.jar --force --area=washington

# Large
#
# Download and generate ca/california.pmtiles in the current directory:
# Note: the slash confuses some downstream processes, try a symlink to california
california:
java -jar target/*-with-deps.jar --download --force --area=us/california

# Generate ca/california.pmtiles in the current directory (using already downloaded asset)
# Note: the slash confuses some downstream processes, try a symlink to california
california-fast:
java -jar target/*-with-deps.jar --force --area=us/california
1 change: 1 addition & 0 deletions tiles/src/main/java/com/protomaps/basemap/Basemap.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public Basemap(Boolean useTilezen) {
var physical_point = new PhysicalPoint();
registerHandler(physical_point);
registerSourceHandler("osm", physical_point);
registerSourceHandler("ne", physical_point::processNe);
bdon marked this conversation as resolved.
Show resolved Hide resolved

var place = new Places();
registerHandler(place);
Expand Down
19 changes: 19 additions & 0 deletions tiles/src/main/java/com/protomaps/basemap/layers/Boundaries.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public String name() {
@Override
public void processFeature(SourceFeature sf, FeatureCollector features) {
if (sf.canBeLine()) {
// Beware coastlines and coastal waters (eg with admin borders in large estuaries)
// like mouth of Columbia River between Oregon and Washington in USA
if (sf.hasTag("natural", "coastline") || sf.hasTag("maritime", "yes")) {
return;
}
Expand All @@ -38,10 +40,27 @@ public void processFeature(SourceFeature sf, FeatureCollector features) {
line.setMinZoom(0);
} else if (minAdminLevel.getAsInt() <= 4) {
line.setMinZoom(3);
} else if (minAdminLevel.getAsInt() <= 6) {
bdon marked this conversation as resolved.
Show resolved Hide resolved
line.setMinZoom(8);
} else {
line.setMinZoom(10);
}

switch (minAdminLevel.getAsInt()) {
case 2 -> {
line.setAttr("pmap:kind", "country");
}
case 4 -> {
line.setAttr("pmap:kind", "region");
bdon marked this conversation as resolved.
Show resolved Hide resolved
}
case 6 -> {
line.setAttr("pmap:kind", "county");
}
case 8 -> {
line.setAttr("pmap:kind", "locality");
}
}

if (disputed.getAsInt() == 1) {
line.setAttr("disputed", 1);
}
Expand Down
99 changes: 93 additions & 6 deletions tiles/src/main/java/com/protomaps/basemap/layers/Buildings.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.onthegomap.planetiler.VectorTile;
import com.onthegomap.planetiler.geo.GeometryException;
import com.onthegomap.planetiler.reader.SourceFeature;
import com.onthegomap.planetiler.util.Exceptions;
import com.protomaps.basemap.feature.FeatureId;
import com.protomaps.basemap.names.OsmNames;
import com.protomaps.basemap.postprocess.Area;
Expand All @@ -20,10 +21,33 @@ public String name() {
return "buildings";
}

static int quantize_val(double val, int step) {
// special case: if val is very small, we don't want it rounding to zero, so
// round the smallest values up to the first step.
if( val < step ) {
return (int) step;
}

return (int) Math.round(val / step) * step;
}

@Override
public void processFeature(SourceFeature sf, FeatureCollector features) {
if (sf.canBePolygon() && (sf.hasTag("building") || sf.hasTag("building:part"))) {
if (sf.canBePolygon() && (
( sf.hasTag("building") && !sf.hasTag("building", "no")) ||
bdon marked this conversation as resolved.
Show resolved Hide resolved
( sf.hasTag("building:part") && !sf.hasTag("building:part", "no"))))
{
Double height = parseDoubleOrNull(sf.getString("height"));
Double min_height = parseDoubleOrNull(sf.getString("min_height"));
bdon marked this conversation as resolved.
Show resolved Hide resolved
Integer min_zoom = 11;
String kind = "building";

// Limit building:part features to later zooms
// TODO: (nvkelso 20230621) this should be based on area and volume, too
if( sf.hasTag("building:part") ) {
kind = "building_part";
min_zoom = 14;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building parts aren't useful to show until alter zooms when they become large enough on the map to discern.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to making this based on area - think this should be expressible in pixels (planetiler considers a tile to be 256x256 onthegomap/planetiler#487

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ I take back what I said, because at this step in the code we're not dealing with a specific zoom level.

Overall code-wise, it bugs me a little to have so much logic down in postProcess. I would prefer postProcess be "operations that happen tile-wide", but it's now more like "operations that depend on zoom level". there isn't a solid way to assign different values like height quantization before that, though.

I think we should keep it as is and I can refactor it into a well-tested postProcessor that handles both area filtering as well as height quantization per zoom-level.

}

if (height == null) {
Double levels = parseDoubleOrNull(sf.getString("building:levels"));
Expand All @@ -34,12 +58,21 @@ public void processFeature(SourceFeature sf, FeatureCollector features) {

var feature = features.polygon(this.name())
.setId(FeatureId.create(sf))
.setAttrWithMinzoom("building:part", sf.getString("building:part"), 13)
.setAttr("pmap:kind", kind)
.setAttrWithMinzoom("layer", sf.getString("layer"), 13)
.setAttrWithMinzoom("height", height, 13)
.setZoomRange(10, 15);
// NOTE: Height is quantized by zoom in a post-process step
.setAttr("height", height)
.setZoomRange(min_zoom, 15);

if( kind == "building_part") {
// We don't need to set WithMinzoom because that's implicate with the ZoomRange
feature.setAttr("pmap:kind_detail", sf.getString("building:part"));
feature.setAttr("min_height", sf.getString("min_height"));
}

OsmNames.setOsmNames(feature, sf, 13);
// Names should mostly just be for POIs
// Sometimes building name and address are useful items, but only at zoom 17+
//OsmNames.setOsmNames(feature, sf, 13);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the names from buildings... if it's really important it'll show up in the POIs layer.

Alternatively we could only set this starting at zoom 15? As some building names will be lost (when there isn't a business there).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could non-building names become another POI kind?

Are polygon geometries with a text property even labeled in a satisfying way using the MapLibre symbol layer?

}
}

Expand All @@ -50,8 +83,62 @@ public List<VectorTile.Feature> postProcess(int zoom, List<VectorTile.Feature> i
}
items = Area.filterArea(items, 0);

if (zoom >= 14)
// DEBUG
//items = Area.addAreaTag(items);

if (zoom >= 15)
return items;

// quantize height by zoom when less than max_zoom 15 to facilitate better feature merging
bdon marked this conversation as resolved.
Show resolved Hide resolved
for (var item : items) {
try {
if (item.attrs().containsKey("height")) {
var height = (double) item.attrs().get("height");

// Protected against NULL values
if( height > 0 ) {
// at zoom <= 12 round height to nearest 20 meters
if (zoom <= 12) {
height = quantize_val(height, 20);
} else
// at zoom 13 round height to nearest 10 meters
if (zoom == 13) {
height = quantize_val(height, 10);
} else
// at zoom 14 round height to nearest 5 meters
if (zoom == 14) {
height = quantize_val(height, 5);
}

item.attrs().put("height", height);
}
}
} catch( Exception e ) { }

try {
if (item.attrs().containsKey("min_height")) {
var min_height = (double) item.attrs().get("min_height");

// Protected against NULL values
if (min_height > 0) {
if (zoom <= 12) {
min_height = quantize_val(min_height, 20);
} else
// at zoom 13 round height to nearest 10 meters
if (zoom == 13) {
min_height = quantize_val(min_height, 10);
} else
// at zoom 14 round height to nearest 5 meters
if (zoom == 14) {
min_height = quantize_val(min_height, 5);
}

item.attrs().put("min_height", min_height);
}
}
} catch( Exception e ) { }
}

return FeatureMerge.mergeNearbyPolygons(items, 3.125, 3.125, 0.5, 0.5);
}
}
9 changes: 5 additions & 4 deletions tiles/src/main/java/com/protomaps/basemap/layers/Earth.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ public String name() {

public void processOsm(SourceFeature sf, FeatureCollector features) {
features.polygon(this.name())
.setZoomRange(6, 15).setBufferPixels(8);
.setAttr("pmap:kind", "earth")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is superfluous but nice to have in prep for v4 spec so each feature has a kind. They get merged, so very small file size hit.

.setZoomRange(6, 15).setBufferPixels(8);
}

public void processNe(SourceFeature sf, FeatureCollector features) {
var sourceLayer = sf.getSourceLayer();
if (sourceLayer.equals("ne_110m_land")) {
features.polygon(this.name()).setZoomRange(0, 1);
features.polygon(this.name()).setZoomRange(0, 1).setBufferPixels(8).setAttr("pmap:kind", "earth");
} else if (sourceLayer.equals("ne_50m_land")) {
features.polygon(this.name()).setZoomRange(2, 4);
features.polygon(this.name()).setZoomRange(2, 4).setBufferPixels(8).setAttr("pmap:kind", "earth");
} else if (sourceLayer.equals("ne_10m_land")) {
features.polygon(this.name()).setZoomRange(5, 5);
features.polygon(this.name()).setZoomRange(5, 5).setBufferPixels(8).setAttr("pmap:kind", "earth");
}
}

Expand Down
Loading