mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-03-23 04:15:15 +00:00
Merge branch 'master' into plugins
This commit is contained in:
commit
b301512860
21
CHANGELOG.md
21
CHANGELOG.md
@ -1,3 +1,24 @@
|
||||
## 1.18.1
|
||||
|
||||
* Only warn once about invalid polygons in tippecanoe-decode
|
||||
|
||||
## 1.18.0
|
||||
|
||||
* Fix compression of tiles in tile-join
|
||||
* Calculate the tileset bounding box in tile-join from the tile boundaries
|
||||
|
||||
## 1.17.7
|
||||
|
||||
* Enforce polygon winding and closure rules in tippecanoe-decode
|
||||
|
||||
## 1.17.6
|
||||
|
||||
* Add tile-join options to set name, attribution, description
|
||||
|
||||
## 1.17.5
|
||||
|
||||
* Preserve the tileset names from the source mbtiles in tile-join
|
||||
|
||||
## 1.17.4
|
||||
|
||||
* Fix RFC 8142 support: Don't try to split *all* memory mapped files
|
||||
|
2
Makefile
2
Makefile
@ -160,7 +160,7 @@ join-test:
|
||||
cmp tests/join-population/joined-i.mbtiles.json.check tests/join-population/joined-i.mbtiles.json
|
||||
cmp tests/join-population/merged.mbtiles.json.check tests/join-population/merged.mbtiles.json
|
||||
cmp tests/join-population/windows.mbtiles.json.check tests/join-population/windows.mbtiles.json
|
||||
./tile-join -f -l macarthur -o tests/join-population/just-macarthur.mbtiles tests/join-population/merged.mbtiles
|
||||
./tile-join -f -l macarthur -n "macarthur name" -N "macarthur description" -A "macarthur attribution" -o tests/join-population/just-macarthur.mbtiles tests/join-population/merged.mbtiles
|
||||
./tile-join -f -L macarthur -o tests/join-population/no-macarthur.mbtiles tests/join-population/merged.mbtiles
|
||||
./tippecanoe-decode tests/join-population/just-macarthur.mbtiles > tests/join-population/just-macarthur.mbtiles.json.check
|
||||
./tippecanoe-decode tests/join-population/no-macarthur.mbtiles > tests/join-population/no-macarthur.mbtiles.json.check
|
||||
|
@ -431,6 +431,9 @@ The options are:
|
||||
* `-pk`: Don't skip tiles larger than 500K.
|
||||
* `-l` *layer*: Include the named layer in the output. You can specify multiple `-l` options to keep multiple layers. If you don't specify, they will all be retained.
|
||||
* `-L` *layer*: Remove the named layer from the output. You can specify multiple `-L` options to remove multiple layers.
|
||||
* `-A` *attribution*: Set the attribution string.
|
||||
* `-n` *name*: Set the tileset name.
|
||||
* `-N` *description*: Set the tileset description.
|
||||
|
||||
Because tile-join just copies the geometries to the new .mbtiles without processing them
|
||||
(except to rescale the extents if necessary),
|
||||
@ -519,3 +522,4 @@ resolutions.
|
||||
* `-Z` _minzoom_: Specify the lowest zoom level to decode from the tileset
|
||||
* `-l` _layer_: Decode only layers with the specified names. (Multiple `-l` options can be specified.)
|
||||
* `-c`: Include each feature's layer and zoom level as part of its `tippecanoe` object rather than as a FeatureCollection wrapper
|
||||
* `-f`: Decode tiles even if polygon ring order or closure problems are detected
|
||||
|
18
decode.cpp
18
decode.cpp
@ -20,13 +20,15 @@
|
||||
|
||||
int minzoom = 0;
|
||||
int maxzoom = 32;
|
||||
bool force = false;
|
||||
|
||||
void handle(std::string message, int z, unsigned x, unsigned y, int describe, std::set<std::string> const &to_decode, bool pipeline) {
|
||||
int within = 0;
|
||||
mvt_tile tile;
|
||||
bool was_compressed;
|
||||
|
||||
try {
|
||||
if (!tile.decode(message)) {
|
||||
if (!tile.decode(message, was_compressed)) {
|
||||
fprintf(stderr, "Couldn't parse tile %d/%u/%u\n", z, x, y);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -39,7 +41,11 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe, st
|
||||
printf("{ \"type\": \"FeatureCollection\"");
|
||||
|
||||
if (describe) {
|
||||
printf(", \"properties\": { \"zoom\": %d, \"x\": %d, \"y\": %d }", z, x, y);
|
||||
printf(", \"properties\": { \"zoom\": %d, \"x\": %d, \"y\": %d", z, x, y);
|
||||
if (!was_compressed) {
|
||||
printf(", \"compressed\": false");
|
||||
}
|
||||
printf(" }");
|
||||
|
||||
if (projection != projections) {
|
||||
printf(", \"crs\": { \"type\": \"name\", \"properties\": { \"name\": ");
|
||||
@ -77,7 +83,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe, st
|
||||
}
|
||||
}
|
||||
|
||||
layer_to_geojson(stdout, layer, z, x, y, !pipeline, pipeline, pipeline, 0, 0, 0);
|
||||
layer_to_geojson(stdout, layer, z, x, y, !pipeline, pipeline, pipeline, 0, 0, 0, !force);
|
||||
|
||||
if (!pipeline) {
|
||||
if (describe) {
|
||||
@ -253,7 +259,7 @@ int main(int argc, char **argv) {
|
||||
std::set<std::string> to_decode;
|
||||
bool pipeline = false;
|
||||
|
||||
while ((i = getopt(argc, argv, "t:Z:z:l:c")) != -1) {
|
||||
while ((i = getopt(argc, argv, "t:Z:z:l:cf")) != -1) {
|
||||
switch (i) {
|
||||
case 't':
|
||||
set_projection_or_exit(optarg);
|
||||
@ -275,6 +281,10 @@ int main(int argc, char **argv) {
|
||||
pipeline = true;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argv);
|
||||
}
|
||||
|
@ -505,6 +505,12 @@ The options are:
|
||||
\fB\fC\-l\fR \fIlayer\fP: Include the named layer in the output. You can specify multiple \fB\fC\-l\fR options to keep multiple layers. If you don't specify, they will all be retained.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-L\fR \fIlayer\fP: Remove the named layer from the output. You can specify multiple \fB\fC\-L\fR options to remove multiple layers.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-A\fR \fIattribution\fP: Set the attribution string.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-n\fR \fIname\fP: Set the tileset name.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-N\fR \fIdescription\fP: Set the tileset description.
|
||||
.RE
|
||||
.PP
|
||||
Because tile\-join just copies the geometries to the new .mbtiles without processing them
|
||||
@ -612,4 +618,6 @@ resolutions.
|
||||
\fB\fC\-l\fR \fIlayer\fP: Decode only layers with the specified names. (Multiple \fB\fC\-l\fR options can be specified.)
|
||||
.IP \(bu 2
|
||||
\fB\fC\-c\fR: Include each feature's layer and zoom level as part of its \fB\fCtippecanoe\fR object rather than as a FeatureCollection wrapper
|
||||
.IP \(bu 2
|
||||
\fB\fC\-f\fR: Decode tiles even if polygon ring order or closure problems are detected
|
||||
.RE
|
||||
|
4
mvt.cpp
4
mvt.cpp
@ -82,7 +82,7 @@ int compress(std::string const &input, std::string &output) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mvt_tile::decode(std::string &message) {
|
||||
bool mvt_tile::decode(std::string &message, bool &was_compressed) {
|
||||
layers.clear();
|
||||
std::string src;
|
||||
|
||||
@ -90,8 +90,10 @@ bool mvt_tile::decode(std::string &message) {
|
||||
std::string uncompressed;
|
||||
decompress(message, uncompressed);
|
||||
src = uncompressed;
|
||||
was_compressed = true;
|
||||
} else {
|
||||
src = message;
|
||||
was_compressed = false;
|
||||
}
|
||||
|
||||
protozero::pbf_reader reader(src);
|
||||
|
2
mvt.hpp
2
mvt.hpp
@ -91,7 +91,7 @@ struct mvt_tile {
|
||||
std::vector<mvt_layer> layers;
|
||||
|
||||
std::string encode();
|
||||
bool decode(std::string &message);
|
||||
bool decode(std::string &message, bool &was_compressed);
|
||||
};
|
||||
|
||||
bool is_compressed(std::string const &data);
|
||||
|
@ -52,7 +52,7 @@ void *run_writer(void *a) {
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < wa->layers->size(); i++) {
|
||||
layer_to_geojson(fp, (*(wa->layers))[i], wa->z, wa->x, wa->y, false, true, false, 0, 0, 0);
|
||||
layer_to_geojson(fp, (*(wa->layers))[i], wa->z, wa->x, wa->y, false, true, false, 0, 0, 0, false);
|
||||
}
|
||||
|
||||
if (fclose(fp) != 0) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.334735,37.877356,-122.281639,37.898925",
|
||||
"bounds": "-122.343750,37.857507,-122.255859,37.926868",
|
||||
"center": "-122.299805,37.892187,12",
|
||||
"description": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"tabblock_06001420\", \"description\": \"\", \"minzoom\": 3, \"maxzoom\": 12, \"fields\": {\"ALAND10\": \"Number\", \"AWATER10\": \"Number\", \"BLOCKCE10\": \"String\", \"COUNTYFP10\": \"String\", \"FUNCSTAT10\": \"String\", \"INTPTLAT10\": \"String\", \"INTPTLON10\": \"String\", \"MTFCC10\": \"String\", \"NAME10\": \"String\", \"STATEFP10\": \"String\", \"TRACTCE10\": \"String\", \"UACE10\": \"String\", \"UATYP10\": \"String\", \"UR10\": \"String\", \"population\": \"Number\"} } ] }",
|
||||
"maxzoom": "12",
|
||||
"minzoom": "0",
|
||||
"name": "tests/join-population/joined-i.mbtiles",
|
||||
"name": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.334735,37.877356,-122.281639,37.898925",
|
||||
"bounds": "-122.343750,37.857507,-122.255859,37.926868",
|
||||
"center": "-122.299805,37.892187,12",
|
||||
"description": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"tabblock_06001420\", \"description\": \"\", \"minzoom\": 3, \"maxzoom\": 12, \"fields\": {\"ALAND10\": \"Number\", \"AWATER10\": \"Number\", \"BLOCKCE10\": \"String\", \"COUNTYFP10\": \"String\", \"FUNCSTAT10\": \"String\", \"INTPTLAT10\": \"String\", \"INTPTLON10\": \"String\", \"MTFCC10\": \"String\", \"NAME10\": \"String\", \"STATEFP10\": \"String\", \"TRACTCE10\": \"String\", \"UACE10\": \"String\", \"UATYP10\": \"String\", \"UR10\": \"String\", \"population\": \"Number\"} } ] }",
|
||||
"maxzoom": "12",
|
||||
"minzoom": "0",
|
||||
"name": "tests/join-population/joined.mbtiles",
|
||||
"name": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
@ -1,12 +1,13 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.334735,37.695438,-122.104097,37.898925",
|
||||
"attribution": "macarthur attribution",
|
||||
"bounds": "-122.343750,37.695438,-122.104097,37.926868",
|
||||
"center": "-122.299805,37.892187,12",
|
||||
"description": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"description": "macarthur description",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"macarthur\", \"description\": \"\", \"minzoom\": 5, \"maxzoom\": 11, \"fields\": {\"FULLNAME\": \"String\", \"LINEARID\": \"String\", \"MTFCC\": \"String\", \"RTTYP\": \"String\"} } ] }",
|
||||
"maxzoom": "12",
|
||||
"minzoom": "0",
|
||||
"name": "tests/join-population/just-macarthur.mbtiles",
|
||||
"name": "macarthur name",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.334735,37.695438,-122.104097,37.898925",
|
||||
"bounds": "-122.343750,37.695438,-122.104097,37.926868",
|
||||
"center": "-122.299805,37.892187,12",
|
||||
"description": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"macarthur\", \"description\": \"\", \"minzoom\": 5, \"maxzoom\": 11, \"fields\": {\"FULLNAME\": \"String\", \"LINEARID\": \"String\", \"MTFCC\": \"String\", \"RTTYP\": \"String\"} }, { \"id\": \"tabblock_06001420\", \"description\": \"\", \"minzoom\": 3, \"maxzoom\": 12, \"fields\": {\"ALAND10\": \"Number\", \"AWATER10\": \"Number\", \"BLOCKCE10\": \"String\", \"COUNTYFP10\": \"String\", \"FUNCSTAT10\": \"String\", \"GEOID10\": \"String\", \"INTPTLAT10\": \"String\", \"INTPTLON10\": \"String\", \"MTFCC10\": \"String\", \"NAME10\": \"String\", \"STATEFP10\": \"String\", \"TRACTCE10\": \"String\", \"UACE10\": \"String\", \"UATYP10\": \"String\", \"UR10\": \"String\"} } ] }",
|
||||
"maxzoom": "12",
|
||||
"minzoom": "0",
|
||||
"name": "tests/join-population/merged.mbtiles",
|
||||
"name": "tests/join-population/macarthur.mbtiles + tests/join-population/macarthur2.mbtiles + tests/join-population/tabblock_06001420.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.334735,37.695438,-122.104097,37.898925",
|
||||
"bounds": "-122.343750,37.695438,-122.104097,37.926868",
|
||||
"center": "-122.299805,37.892187,12",
|
||||
"description": "tests/join-population/tabblock_06001420.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"tabblock_06001420\", \"description\": \"\", \"minzoom\": 3, \"maxzoom\": 12, \"fields\": {\"ALAND10\": \"Number\", \"AWATER10\": \"Number\", \"BLOCKCE10\": \"String\", \"COUNTYFP10\": \"String\", \"FUNCSTAT10\": \"String\", \"GEOID10\": \"String\", \"INTPTLAT10\": \"String\", \"INTPTLON10\": \"String\", \"MTFCC10\": \"String\", \"NAME10\": \"String\", \"STATEFP10\": \"String\", \"TRACTCE10\": \"String\", \"UACE10\": \"String\", \"UATYP10\": \"String\", \"UR10\": \"String\"} } ] }",
|
||||
"maxzoom": "12",
|
||||
"minzoom": "0",
|
||||
"name": "tests/join-population/no-macarthur.mbtiles",
|
||||
"name": "tests/join-population/macarthur.mbtiles + tests/join-population/macarthur2.mbtiles + tests/join-population/tabblock_06001420.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
@ -1,12 +1,12 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-122.294563,37.695438,-122.104097,37.833010",
|
||||
"bounds": "-122.343750,37.439974,-121.992188,37.996163",
|
||||
"center": "-122.167969,37.833010,10",
|
||||
"description": "tests/join-population/macarthur.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"macarthur\", \"description\": \"\", \"minzoom\": 5, \"maxzoom\": 10, \"fields\": {\"FULLNAME\": \"String\", \"LINEARID\": \"String\", \"MTFCC\": \"String\", \"RTTYP\": \"String\"} } ] }",
|
||||
"maxzoom": "10",
|
||||
"minzoom": "5",
|
||||
"name": "tests/join-population/windows.mbtiles",
|
||||
"name": "tests/join-population/macarthur.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
|
20
tests/overlap/out/-z0_-pC.json
Normal file
20
tests/overlap/out/-z0_-pC.json
Normal file
@ -0,0 +1,20 @@
|
||||
{ "type": "FeatureCollection", "properties": {
|
||||
"bounds": "-135.000000,-31.000000,-3.000000,79.000000",
|
||||
"center": "-3.000000,0.000000,0",
|
||||
"description": "tests/overlap/out/-z0_-pC.json.check.mbtiles",
|
||||
"format": "pbf",
|
||||
"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {} } ] }",
|
||||
"maxzoom": "0",
|
||||
"minzoom": "0",
|
||||
"name": "tests/overlap/out/-z0_-pC.json.check.mbtiles",
|
||||
"type": "overlay",
|
||||
"version": "2"
|
||||
}, "features": [
|
||||
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0, "compressed": false }, "features": [
|
||||
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
|
||||
{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -33.046875, 79.004962 ], [ -3.076172, 61.015725 ], [ -37.001953, 34.016242 ], [ -71.015625, 29.075375 ], [ -103.007812, 39.027719 ], [ -117.070312, 60.020952 ], [ -113.027344, 69.005675 ], [ -93.076172, 75.004940 ], [ -74.003906, 79.004962 ], [ -33.046875, 79.004962 ] ] ] } }
|
||||
,
|
||||
{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -81.035156, 63.035039 ], [ -28.037109, 59.040555 ], [ -10.019531, 50.007739 ], [ -5.009766, 8.059230 ], [ -17.050781, -21.943046 ], [ -75.058594, -30.977609 ], [ -118.037109, -8.928487 ], [ -135.000000, 29.075375 ], [ -113.027344, 53.014783 ], [ -81.035156, 63.035039 ] ] ] } }
|
||||
] }
|
||||
] }
|
||||
] }
|
@ -32,8 +32,9 @@ struct stats {
|
||||
void handle(std::string message, int z, unsigned x, unsigned y, std::map<std::string, layermap_entry> &layermap, std::vector<std::string> &header, std::map<std::string, std::vector<std::string>> &mapping, std::set<std::string> &exclude, std::set<std::string> &keep_layers, std::set<std::string> &remove_layers, int ifmatched, mvt_tile &outtile) {
|
||||
mvt_tile tile;
|
||||
int features_added = 0;
|
||||
bool was_compressed;
|
||||
|
||||
if (!tile.decode(message)) {
|
||||
if (!tile.decode(message, was_compressed)) {
|
||||
fprintf(stderr, "Couldn't decompress tile %d/%u/%u\n", z, x, y);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -402,7 +403,9 @@ void *join_worker(void *v) {
|
||||
}
|
||||
|
||||
if (anything) {
|
||||
std::string compressed = tile.encode();
|
||||
std::string pbf = tile.encode();
|
||||
std::string compressed;
|
||||
compress(pbf, compressed);
|
||||
|
||||
if (!pk && compressed.size() > 500000) {
|
||||
fprintf(stderr, "Tile %lld/%lld/%lld size is %lld, >500000. Skipping this tile\n.", ai->first.z, ai->first.x, ai->first.y, (long long) compressed.size());
|
||||
@ -464,7 +467,7 @@ void handle_tasks(std::map<zxy, std::vector<std::string>> &tasks, std::vector<st
|
||||
}
|
||||
}
|
||||
|
||||
void decode(struct reader *readers, char *map, std::map<std::string, layermap_entry> &layermap, sqlite3 *outdb, struct stats *st, std::vector<std::string> &header, std::map<std::string, std::vector<std::string>> &mapping, std::set<std::string> &exclude, int ifmatched, std::string &attribution, std::string &description, std::set<std::string> &keep_layers, std::set<std::string> &remove_layers) {
|
||||
void decode(struct reader *readers, char *map, std::map<std::string, layermap_entry> &layermap, sqlite3 *outdb, struct stats *st, std::vector<std::string> &header, std::map<std::string, std::vector<std::string>> &mapping, std::set<std::string> &exclude, int ifmatched, std::string &attribution, std::string &description, std::set<std::string> &keep_layers, std::set<std::string> &remove_layers, std::string &name) {
|
||||
std::vector<std::map<std::string, layermap_entry>> layermaps;
|
||||
for (size_t i = 0; i < CPUS; i++) {
|
||||
layermaps.push_back(std::map<std::string, layermap_entry>());
|
||||
@ -472,11 +475,34 @@ void decode(struct reader *readers, char *map, std::map<std::string, layermap_en
|
||||
|
||||
std::map<zxy, std::vector<std::string>> tasks;
|
||||
|
||||
double minlat = INT_MAX;
|
||||
double minlon = INT_MAX;
|
||||
double maxlat = INT_MIN;
|
||||
double maxlon = INT_MIN;
|
||||
int zoom_for_bbox = -1;
|
||||
|
||||
while (readers != NULL && readers->zoom < 32) {
|
||||
reader *r = readers;
|
||||
readers = readers->next;
|
||||
r->next = NULL;
|
||||
|
||||
if (r->zoom != zoom_for_bbox) {
|
||||
// Only use highest zoom for bbox calculation
|
||||
// to avoid z0 always covering the world
|
||||
|
||||
minlat = minlon = INT_MAX;
|
||||
maxlat = maxlon = INT_MIN;
|
||||
zoom_for_bbox = r->zoom;
|
||||
}
|
||||
|
||||
double lat1, lon1, lat2, lon2;
|
||||
tile2lonlat(r->x, r->y, r->zoom, &lon1, &lat1);
|
||||
tile2lonlat(r->x + 1, r->y + 1, r->zoom, &lon2, &lat2);
|
||||
minlat = min(lat2, minlat);
|
||||
minlon = min(lon1, minlon);
|
||||
maxlat = max(lat1, maxlat);
|
||||
maxlon = max(lon2, maxlon);
|
||||
|
||||
zxy tile = zxy(r->zoom, r->x, r->y);
|
||||
if (tasks.count(tile) == 0) {
|
||||
tasks.insert(std::pair<zxy, std::vector<std::string>>(tile, std::vector<std::string>()));
|
||||
@ -517,6 +543,11 @@ void decode(struct reader *readers, char *map, std::map<std::string, layermap_en
|
||||
*rr = r;
|
||||
}
|
||||
|
||||
st->minlon = min(minlon, st->minlon);
|
||||
st->maxlon = max(maxlon, st->maxlon);
|
||||
st->minlat = min(minlat, st->minlat);
|
||||
st->maxlat = max(maxlat, st->maxlat);
|
||||
|
||||
handle_tasks(tasks, layermaps, outdb, header, mapping, exclude, ifmatched, keep_layers, remove_layers);
|
||||
layermap = merge_layermaps(layermaps);
|
||||
|
||||
@ -558,15 +589,25 @@ void decode(struct reader *readers, char *map, std::map<std::string, layermap_en
|
||||
}
|
||||
sqlite3_finalize(r->stmt);
|
||||
}
|
||||
if (sqlite3_prepare_v2(r->db, "SELECT value from metadata where name = 'name'", -1, &r->stmt, NULL) == SQLITE_OK) {
|
||||
if (sqlite3_step(r->stmt) == SQLITE_ROW) {
|
||||
if (name.size() == 0) {
|
||||
name = std::string((char *) sqlite3_column_text(r->stmt, 0));
|
||||
} else {
|
||||
name += " + " + std::string((char *) sqlite3_column_text(r->stmt, 0));
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(r->stmt);
|
||||
}
|
||||
if (sqlite3_prepare_v2(r->db, "SELECT value from metadata where name = 'bounds'", -1, &r->stmt, NULL) == SQLITE_OK) {
|
||||
if (sqlite3_step(r->stmt) == SQLITE_ROW) {
|
||||
const unsigned char *s = sqlite3_column_text(r->stmt, 0);
|
||||
double minlon, minlat, maxlon, maxlat;
|
||||
sscanf((char *) s, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat);
|
||||
st->minlon = min(minlon, st->minlon);
|
||||
st->maxlon = max(maxlon, st->maxlon);
|
||||
st->minlat = min(minlat, st->minlat);
|
||||
st->maxlat = max(maxlat, st->maxlat);
|
||||
if (sscanf((char *) s, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat) == 4) {
|
||||
st->minlon = min(minlon, st->minlon);
|
||||
st->maxlon = max(maxlon, st->maxlon);
|
||||
st->minlat = min(minlat, st->minlat);
|
||||
st->maxlat = max(maxlat, st->maxlat);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(r->stmt);
|
||||
}
|
||||
@ -684,11 +725,13 @@ int main(int argc, char **argv) {
|
||||
std::set<std::string> keep_layers;
|
||||
std::set<std::string> remove_layers;
|
||||
|
||||
std::string set_name, set_description, set_attribution;
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
int i;
|
||||
|
||||
while ((i = getopt(argc, argv, "fo:c:x:ip:l:L:")) != -1) {
|
||||
while ((i = getopt(argc, argv, "fo:c:x:ip:l:L:A:N:n:")) != -1) {
|
||||
switch (i) {
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
@ -702,6 +745,18 @@ int main(int argc, char **argv) {
|
||||
ifmatched = 1;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
set_attribution = optarg;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
set_name = optarg;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
set_description = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (strcmp(optarg, "k") == 0) {
|
||||
pk = true;
|
||||
@ -755,6 +810,7 @@ int main(int argc, char **argv) {
|
||||
std::map<std::string, layermap_entry> layermap;
|
||||
std::string attribution;
|
||||
std::string description;
|
||||
std::string name;
|
||||
|
||||
struct reader *readers = NULL;
|
||||
|
||||
@ -772,9 +828,19 @@ int main(int argc, char **argv) {
|
||||
*rr = r;
|
||||
}
|
||||
|
||||
decode(readers, csv, layermap, outdb, &st, header, mapping, exclude, ifmatched, attribution, description, keep_layers, remove_layers);
|
||||
decode(readers, csv, layermap, outdb, &st, header, mapping, exclude, ifmatched, attribution, description, keep_layers, remove_layers, name);
|
||||
|
||||
mbtiles_write_metadata(outdb, NULL, outfile, st.minzoom, st.maxzoom, st.minlat, st.minlon, st.maxlat, st.maxlon, st.midlat, st.midlon, 0, attribution.size() != 0 ? attribution.c_str() : NULL, layermap, true, description.c_str());
|
||||
if (set_attribution.size() != 0) {
|
||||
attribution = set_attribution;
|
||||
}
|
||||
if (set_description.size() != 0) {
|
||||
description = set_description;
|
||||
}
|
||||
if (set_name.size() != 0) {
|
||||
name = set_name;
|
||||
}
|
||||
|
||||
mbtiles_write_metadata(outdb, NULL, name.c_str(), st.minzoom, st.maxzoom, st.minlat, st.minlon, st.maxlat, st.maxlon, st.midlat, st.midlon, 0, attribution.size() != 0 ? attribution.c_str() : NULL, layermap, true, description.c_str());
|
||||
mbtiles_close(outdb, argv);
|
||||
|
||||
return 0;
|
||||
|
2
tile.cpp
2
tile.cpp
@ -1374,7 +1374,7 @@ void *run_prefilter(void *v) {
|
||||
decode_meta(sf.m, sf.keys, sf.values, rpa->stringpool + rpa->pool_off[sf.segment], tmp_layer, tmp_feature);
|
||||
tmp_layer.features.push_back(tmp_feature);
|
||||
|
||||
layer_to_geojson(rpa->prefilter_fp, tmp_layer, 0, 0, 0, false, true, false, sf.index, sf.seq, sf.extent);
|
||||
layer_to_geojson(rpa->prefilter_fp, tmp_layer, 0, 0, 0, false, true, false, sf.index, sf.seq, sf.extent, false);
|
||||
}
|
||||
|
||||
if (fclose(rpa->prefilter_fp) != 0) {
|
||||
|
@ -1 +1 @@
|
||||
#define VERSION "tippecanoe v1.17.4\n"
|
||||
#define VERSION "tippecanoe v1.18.1\n"
|
||||
|
@ -24,7 +24,7 @@ struct lonlat {
|
||||
}
|
||||
};
|
||||
|
||||
void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, unsigned long long index, long long sequence, long long extent) {
|
||||
void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, unsigned long long index, long long sequence, long long extent, bool complain) {
|
||||
for (size_t f = 0; f < layer.features.size(); f++) {
|
||||
mvt_feature const &feat = layer.features[f];
|
||||
|
||||
@ -232,6 +232,21 @@ void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x,
|
||||
rings[n].push_back(ops[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (i + 1 >= ops.size() || ops[i + 1].op == VT_MOVETO) {
|
||||
if (ops[i].op != VT_CLOSEPATH) {
|
||||
static bool warned = false;
|
||||
|
||||
if (!warned) {
|
||||
fprintf(stderr, "Ring does not end with closepath (ends with %d)\n", ops[i].op);
|
||||
if (complain) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int outer = 0;
|
||||
@ -262,6 +277,19 @@ void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x,
|
||||
|
||||
int state = 0;
|
||||
for (size_t i = 0; i < rings.size(); i++) {
|
||||
if (i == 0 && areas[i] < 0) {
|
||||
static bool warned = false;
|
||||
|
||||
if (!warned) {
|
||||
fprintf(stderr, "Polygon begins with an inner ring\n");
|
||||
if (complain) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (areas[i] >= 0) {
|
||||
if (state != 0) {
|
||||
// new multipolygon
|
||||
|
@ -1,2 +1,2 @@
|
||||
void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, unsigned long long index, long long sequence, long long extent);
|
||||
void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x, unsigned y, bool comma, bool name, bool zoom, unsigned long long index, long long sequence, long long extent, bool complain);
|
||||
void fprintq(FILE *f, const char *s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user