mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Tighten MLT wording
This commit is contained in:
@@ -43,7 +43,6 @@ tests/**/*.mbtiles
|
||||
tests/**/*.check
|
||||
tests/**/*.geobuf
|
||||
|
||||
# MLT build directory
|
||||
mlt-build/
|
||||
|
||||
# Vim
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
[submodule "maplibre-tile-spec"]
|
||||
path = maplibre-tile-spec
|
||||
url = https://github.com/maplibre/maplibre-tile-spec.git
|
||||
branch = main
|
||||
|
||||
@@ -606,20 +606,15 @@ layer-json-test: tippecanoe tippecanoe-decode
|
||||
rm -f tests/layer-json/out.mbtiles.json.check tests/layer-json/out.mbtiles
|
||||
|
||||
mlt-test: tippecanoe
|
||||
# Points: MLT output, verify tile count matches MVT
|
||||
./tippecanoe -q --output-format=mlt -z5 -f -o tests/mlt/points.mbtiles tests/mlt/points.geojson
|
||||
./tippecanoe -q -z5 -f -o tests/mlt/points-mvt.mbtiles tests/mlt/points.geojson
|
||||
@test $$(sqlite3 tests/mlt/points.mbtiles "SELECT COUNT(*) FROM tiles") -eq $$(sqlite3 tests/mlt/points-mvt.mbtiles "SELECT COUNT(*) FROM tiles") || (echo "FAIL: MLT and MVT tile counts differ" && exit 1)
|
||||
# Verify format metadata
|
||||
@test "$$(sqlite3 tests/mlt/points.mbtiles "SELECT value FROM metadata WHERE name='format'")" = "mlt" || (echo "FAIL: format metadata is not 'mlt'" && exit 1)
|
||||
# Verify tiles are gzip compressed
|
||||
@sqlite3 tests/mlt/points.mbtiles "SELECT hex(substr(tile_data, 1, 2)) FROM tiles LIMIT 1" | grep -q "1F8B" || (echo "FAIL: MLT tiles not gzip compressed" && exit 1)
|
||||
# Directory output with .mlt extension
|
||||
rm -rf tests/mlt/dir-out
|
||||
./tippecanoe -q --output-format=mlt -z2 -f -e tests/mlt/dir-out tests/mlt/points.geojson
|
||||
@test $$(find tests/mlt/dir-out -name '*.mlt' | wc -l) -gt 0 || (echo "FAIL: No .mlt files in directory output" && exit 1)
|
||||
@test $$(find tests/mlt/dir-out -name '*.pbf' | wc -l) -eq 0 || (echo "FAIL: .pbf files in MLT directory output" && exit 1)
|
||||
# Pretessellate flag
|
||||
./tippecanoe -q --output-format=mlt --pretessellate -z5 -f -o tests/mlt/points-tess.mbtiles tests/mlt/points.geojson
|
||||
@test $$(sqlite3 tests/mlt/points-tess.mbtiles "SELECT COUNT(*) FROM tiles") -gt 0 || (echo "FAIL: No tiles with pretessellate" && exit 1)
|
||||
rm -f tests/mlt/points.mbtiles tests/mlt/points-mvt.mbtiles tests/mlt/points-tess.mbtiles
|
||||
|
||||
@@ -553,9 +553,9 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
|
||||
* `-pf` or `--no-feature-limit`: Don't limit tiles to 200,000 features
|
||||
* `-pk` or `--no-tile-size-limit`: Don't limit tiles to 500K bytes
|
||||
* `-pC` or `--no-tile-compression`: Don't compress the vector tile data. If you are getting "Unimplemented type 3" error messages from a renderer, it is probably because it expects uncompressed tiles using this option rather than the normal gzip-compressed tiles.
|
||||
* `--output-format=`*format*: Set the tile encoding format. Supported values: `mvt` (default, Mapbox Vector Tiles) or `mlt` ([MapLibre Tiles](https://github.com/maplibre/maplibre-tile-spec)). MLT is a columnar format that typically produces smaller tiles than MVT.
|
||||
* `--pretessellate`: When using `--output-format=mlt`, pre-triangulate polygon geometries for faster rendering. Only applies to layers where all features are polygons.
|
||||
* `--no-mlt-feature-sort`: When using `--output-format=mlt`, disable within-tile spatial sorting of features by Hilbert curve index. Sorting is on by default and improves compression.
|
||||
* `--output-format=`*format*: Set the tile encoding format. Supported values: `mvt` (default, Mapbox Vector Tiles) or `mlt` ([MapLibre Tiles](https://github.com/maplibre/maplibre-tile-spec)).
|
||||
* `--pretessellate`: When using `--output-format=mlt`, pre-triangulate polygon geometries. Only applies to layers where all features are polygons.
|
||||
* `--no-mlt-feature-sort`: When using `--output-format=mlt`, disable within-tile spatial sorting of features by Hilbert curve index. Sorting is on by default.
|
||||
* `-pg` or `--no-tile-stats`: Don't generate the `tilestats` row in the tileset metadata. Uploads without [tilestats](https://github.com/mapbox/mapbox-geostats) will take longer to process.
|
||||
* `--tile-stats-attributes-limit=`*count*: Include `tilestats` information about at most *count* attributes instead of the default 1000.
|
||||
* `--tile-stats-sample-values-limit=`*count*: Calculate `tilestats` attribute statistics based on *count* values instead of the default 1000.
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
using Vertex = mlt::Encoder::Vertex;
|
||||
|
||||
// Try to parse a JSON object string into MLT STRUCT (flat string children only)
|
||||
static bool try_parse_json_object(const std::string &s, mlt::Encoder::StructValue &out) {
|
||||
static bool parse_json_object_property(const std::string &s, mlt::Encoder::StructValue &out) {
|
||||
if (s.empty() || s[0] != '{') {
|
||||
return false;
|
||||
}
|
||||
@@ -60,7 +59,6 @@ static bool try_parse_json_object(const std::string &s, mlt::Encoder::StructValu
|
||||
child_val = "null";
|
||||
break;
|
||||
default:
|
||||
// Nested object/array - stringify back
|
||||
char *nested = json_stringify(val);
|
||||
child_val = nested;
|
||||
free(nested);
|
||||
@@ -101,7 +99,7 @@ static mlt::Encoder::PropertyValue convert_value(const mvt_value &val) {
|
||||
case mvt_string: {
|
||||
std::string s = val.get_string_value();
|
||||
mlt::Encoder::StructValue struct_val;
|
||||
if (try_parse_json_object(s, struct_val)) {
|
||||
if (parse_json_object_property(s, struct_val)) {
|
||||
return struct_val;
|
||||
}
|
||||
return s;
|
||||
@@ -111,8 +109,6 @@ static mlt::Encoder::PropertyValue convert_value(const mvt_value &val) {
|
||||
}
|
||||
}
|
||||
|
||||
// Split MVT command stream into coordinate rings (sequences between moveto commands).
|
||||
// Each ring is a vector of vertices. For polygons, closepath is implicit (MLT strips closing points).
|
||||
static std::vector<std::vector<Vertex>> extract_rings(const mvt_feature &feature) {
|
||||
std::vector<std::vector<Vertex>> rings;
|
||||
|
||||
@@ -124,7 +120,6 @@ static std::vector<std::vector<Vertex>> extract_rings(const mvt_feature &feature
|
||||
} else if (g.op == mvt_lineto) {
|
||||
rings.back().push_back({static_cast<int32_t>(g.x), static_cast<int32_t>(g.y)});
|
||||
}
|
||||
// mvt_closepath: polygon ring close — MLT stores without closing point
|
||||
}
|
||||
return rings;
|
||||
}
|
||||
@@ -160,12 +155,9 @@ static mlt::Encoder::Geometry convert_geometry(const mvt_feature &feature) {
|
||||
break;
|
||||
|
||||
case mvt_polygon: {
|
||||
// Outer rings are clockwise (positive area), holes are counter-clockwise.
|
||||
// Group into polygons: each outer ring starts a new polygon.
|
||||
std::vector<std::vector<std::vector<Vertex>>> polygons;
|
||||
|
||||
for (auto &ring : rings) {
|
||||
// Signed area to detect winding: positive = clockwise = outer ring (in MVT screen coords)
|
||||
long long area2 = 0;
|
||||
for (size_t i = 0; i < ring.size(); i++) {
|
||||
size_t j = (i + 1) % ring.size();
|
||||
@@ -173,7 +165,6 @@ static mlt::Encoder::Geometry convert_geometry(const mvt_feature &feature) {
|
||||
}
|
||||
|
||||
if (area2 >= 0) {
|
||||
// Outer ring — start new polygon
|
||||
polygons.emplace_back();
|
||||
}
|
||||
if (!polygons.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user