mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-01-22 12:28:03 +00:00
Merge branch 'master' into earcut-polygon
Conflicts: geometry.cc
This commit is contained in:
commit
c6051d876f
@ -1,3 +1,9 @@
|
|||||||
|
## 1.9.5
|
||||||
|
|
||||||
|
* Remove temporary files that were accidentally left behind
|
||||||
|
* Be more careful about checking memory allocations and array bounds
|
||||||
|
* Add GNU-style long options
|
||||||
|
|
||||||
## 1.9.4
|
## 1.9.4
|
||||||
|
|
||||||
* Tippecanoe-decode can decode .pbf files that aren't in an .mbtiles container
|
* Tippecanoe-decode can decode .pbf files that aren't in an .mbtiles container
|
||||||
|
65
README.md
65
README.md
@ -57,35 +57,36 @@ Options
|
|||||||
|
|
||||||
### Naming
|
### Naming
|
||||||
|
|
||||||
* -l _name_: Layer name (default "file" if source is file.json or output is file.mbtiles). If there are multiple input files
|
* -l _name_ or --layer=_name_: Layer name (default "file" if source is file.json or output is file.mbtiles). If there are multiple input files
|
||||||
specified, the files are all merged into the single named layer.
|
specified, the files are all merged into the single named layer.
|
||||||
* -n _name_: Human-readable name (default file.json)
|
* -n _name_ or --name=_name_: Human-readable name (default file.json)
|
||||||
|
|
||||||
### File control
|
### File control
|
||||||
|
|
||||||
* -o _file_.mbtiles: Name the output file.
|
* -o _file_.mbtiles or --output=_file_.mbtiles: Name the output file.
|
||||||
* -f: Delete the mbtiles file if it already exists instead of giving an error
|
* -f or --force: Delete the mbtiles file if it already exists instead of giving an error
|
||||||
* -F: Proceed (without deleting existing data) if the metadata or tiles table already exists
|
* -F or --allow-existing: Proceed (without deleting existing data) if the metadata or tiles table already exists
|
||||||
or if metadata fields can't be set
|
or if metadata fields can't be set
|
||||||
* -t _directory_: Put the temporary files in _directory_.
|
* -t _directory_ or --temporary-directory=_directory_: Put the temporary files in _directory_.
|
||||||
* -P: Use multiple threads to read different parts of each input file at once.
|
* -P or --read-parallel: Use multiple threads to read different parts of each input file at once.
|
||||||
This will only work if the input is line-delimited JSON with each Feature on its
|
This will only work if the input is line-delimited JSON with each Feature on its
|
||||||
own line, because it knows nothing of the top-level structure around the Features.
|
own line, because it knows nothing of the top-level structure around the Features. Spurious "EOF" error
|
||||||
|
messages may result otherwise.
|
||||||
Performance will be better if the input is a named file that can be mapped into memory
|
Performance will be better if the input is a named file that can be mapped into memory
|
||||||
rather than a stream that can only be read sequentially.
|
rather than a stream that can only be read sequentially.
|
||||||
|
|
||||||
### Zoom levels and resolution
|
### Zoom levels and resolution
|
||||||
|
|
||||||
* -z _zoom_: Maxzoom: the highest zoom level for which tiles are generated (default 14)
|
* -z _zoom_ or --maximum-zoom=_zoom_: Maxzoom: the highest zoom level for which tiles are generated (default 14)
|
||||||
* -Z _zoom_: Minzoom: the lowest zoom level for which tiles are generated (default 0)
|
* -Z _zoom_ or --minimum-zoom=_zoom_: Minzoom: the lowest zoom level for which tiles are generated (default 0)
|
||||||
* -B _zoom_: Base zoom, the level at and above which all points are included in the tiles (default maxzoom).
|
* -B _zoom_ or --base-zoom=_zoom_: Base zoom, the level at and above which all points are included in the tiles (default maxzoom).
|
||||||
If you use -Bg, it will guess a zoom level that will keep at most 50,000 features in the densest tile.
|
If you use -Bg, it will guess a zoom level that will keep at most 50,000 features in the densest tile.
|
||||||
You can also specify a marker-width with -Bg*width* to allow fewer features in the densest tile to
|
You can also specify a marker-width with -Bg*width* to allow fewer features in the densest tile to
|
||||||
compensate for the larger marker, or -Bf*number* to allow at most *number* features in the densest tile.
|
compensate for the larger marker, or -Bf*number* to allow at most *number* features in the densest tile.
|
||||||
* -d _detail_: Detail at max zoom level (default 12, for tile resolution of 4096)
|
* -d _detail_ or --full-detail=_detail_: Detail at max zoom level (default 12, for tile resolution of 4096)
|
||||||
* -D _detail_: Detail at lower zoom levels (default 12, for tile resolution of 4096)
|
* -D _detail_ or --low-detail=_detail_: Detail at lower zoom levels (default 12, for tile resolution of 4096)
|
||||||
* -m _detail_: Minimum detail that it will try if tiles are too big at regular detail (default 7)
|
* -m _detail_ or --minimum-detail=_detail_: Minimum detail that it will try if tiles are too big at regular detail (default 7)
|
||||||
* -b _pixels_: Buffer size where features are duplicated from adjacent tiles. Units are "screen pixels"--1/256th of the tile width or height. (default 5)
|
* -b _pixels_ or --buffer=_pixels_: Buffer size where features are duplicated from adjacent tiles. Units are "screen pixels"--1/256th of the tile width or height. (default 5)
|
||||||
|
|
||||||
All internal math is done in terms of a 32-bit tile coordinate system, so 1/(2^32) of the size of Earth,
|
All internal math is done in terms of a 32-bit tile coordinate system, so 1/(2^32) of the size of Earth,
|
||||||
or about 1cm, is the smallest distinguishable distance. If _maxzoom_ + _detail_ > 32, no additional
|
or about 1cm, is the smallest distinguishable distance. If _maxzoom_ + _detail_ > 32, no additional
|
||||||
@ -93,35 +94,35 @@ resolution is obtained than by using a smaller _maxzoom_ or _detail_.
|
|||||||
|
|
||||||
### Properties
|
### Properties
|
||||||
|
|
||||||
* -x _name_: Exclude the named properties from all features
|
* -x _name_ or --exclude=_name_: Exclude the named properties from all features
|
||||||
* -y _name_: Include the named properties in all features, excluding all those not explicitly named
|
* -y _name_ or --include=_name_: Include the named properties in all features, excluding all those not explicitly named
|
||||||
* -X: Exclude all properties and encode only geometries
|
* -X or --exclude-all: Exclude all properties and encode only geometries
|
||||||
|
|
||||||
### Point simplification
|
### Point simplification
|
||||||
|
|
||||||
* -r _rate_: Rate at which dots are dropped at zoom levels below basezoom (default 2.5).
|
* -r _rate_ or --drop_rate=_rate_: Rate at which dots are dropped at zoom levels below basezoom (default 2.5).
|
||||||
If you use -rg, it will guess a drop rate that will keep at most 50,000 features in the densest tile.
|
If you use -rg, it will guess a drop rate that will keep at most 50,000 features in the densest tile.
|
||||||
You can also specify a marker-width with -rg*width* to allow fewer features in the densest tile to
|
You can also specify a marker-width with -rg*width* to allow fewer features in the densest tile to
|
||||||
compensate for the larger marker, or -rf*number* to allow at most *number* features in the densest tile.
|
compensate for the larger marker, or -rf*number* to allow at most *number* features in the densest tile.
|
||||||
* -g _gamma_: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number.
|
* -g _gamma_ or --gamma=_gamma_: Rate at which especially dense dots are dropped (default 0, for no effect). A gamma of 2 reduces the number of dots less than a pixel apart to the square root of their original number.
|
||||||
|
|
||||||
### Doing more
|
### Doing more
|
||||||
|
|
||||||
* -ac: Coalesce adjacent line and polygon features that have the same properties
|
* -ac or --coalesce: Coalesce adjacent line and polygon features that have the same properties
|
||||||
* -ar: Try reversing the directions of lines to make them coalesce and compress better
|
* -ar or --reverse: Try reversing the directions of lines to make them coalesce and compress better
|
||||||
* -ao: Reorder features to put ones with the same properties in sequence, to try to get them to coalesce
|
* -ao or --reorder: Reorder features to put ones with the same properties in sequence, to try to get them to coalesce
|
||||||
* -al: Let "dot" dropping at lower zooms apply to lines too
|
* -al or --drop-lines: Let "dot" dropping at lower zooms apply to lines too
|
||||||
|
|
||||||
### Doing less
|
### Doing less
|
||||||
|
|
||||||
* -ps: Don't simplify lines
|
* -ps or --no-line-simplification: Don't simplify lines
|
||||||
* -pS: Don't simplify lines at maxzoom (but do simplify at lower zooms)
|
* -pS or --simplify-only-low-zooms: Don't simplify lines at maxzoom (but do simplify at lower zooms)
|
||||||
* -pf: Don't limit tiles to 200,000 features
|
* -pf or --no-feature-limit: Don't limit tiles to 200,000 features
|
||||||
* -pk: Don't limit tiles to 500K bytes
|
* -pk or --no-tile-size-limit: Don't limit tiles to 500K bytes
|
||||||
* -pd: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries.
|
* -pd or --force-feature-limit: Dynamically drop some fraction of features from large tiles to keep them under the 500K size limit. It will probably look ugly at the tile boundaries.
|
||||||
* -pi: Preserve the original input order of features as the drawing order instead of ordering geographically. (This is implemented as a restoration of the original order at the end, so that dot-dropping is still geographic, which means it also undoes -ao).
|
* -pi or --preserve-input-order: Preserve the original input order of features as the drawing order instead of ordering geographically. (This is implemented as a restoration of the original order at the end, so that dot-dropping is still geographic, which means it also undoes -ao).
|
||||||
* -pp: Don't split complex polygons (over 700 vertices after simplification) into multiple features.
|
* -pp or --no-polygon-splitting: Don't split complex polygons (over 700 vertices after simplification) into multiple features.
|
||||||
* -q: Work quietly instead of reporting progress
|
* -q or --quiet: Work quietly instead of reporting progress
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
20
decode.cc
20
decode.cc
@ -196,7 +196,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
uint32_t count = geom >> 3;
|
uint32_t count = geom >> 3;
|
||||||
|
|
||||||
if (op == VT_MOVETO || op == VT_LINETO) {
|
if (op == VT_MOVETO || op == VT_LINETO) {
|
||||||
for (unsigned k = 0; k < count; k++) {
|
for (size_t k = 0; k < count; k++) {
|
||||||
px += dezig(feat.geometry(g + 1));
|
px += dezig(feat.geometry(g + 1));
|
||||||
py += dezig(feat.geometry(g + 2));
|
py += dezig(feat.geometry(g + 2));
|
||||||
g += 2;
|
g += 2;
|
||||||
@ -220,7 +220,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
printf("\"type\": \"Point\", \"coordinates\": [ %f, %f ]", ops[0].lon, ops[0].lat);
|
printf("\"type\": \"Point\", \"coordinates\": [ %f, %f ]", ops[0].lon, ops[0].lat);
|
||||||
} else {
|
} else {
|
||||||
printf("\"type\": \"MultiPoint\", \"coordinates\": [ ");
|
printf("\"type\": \"MultiPoint\", \"coordinates\": [ ");
|
||||||
for (unsigned i = 0; i < ops.size(); i++) {
|
for (size_t i = 0; i < ops.size(); i++) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
printf(", ");
|
printf(", ");
|
||||||
}
|
}
|
||||||
@ -230,7 +230,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
}
|
}
|
||||||
} else if (feat.type() == VT_LINE) {
|
} else if (feat.type() == VT_LINE) {
|
||||||
int movetos = 0;
|
int movetos = 0;
|
||||||
for (unsigned i = 0; i < ops.size(); i++) {
|
for (size_t i = 0; i < ops.size(); i++) {
|
||||||
if (ops[i].op == VT_MOVETO) {
|
if (ops[i].op == VT_MOVETO) {
|
||||||
movetos++;
|
movetos++;
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
|
|
||||||
if (movetos < 2) {
|
if (movetos < 2) {
|
||||||
printf("\"type\": \"LineString\", \"coordinates\": [ ");
|
printf("\"type\": \"LineString\", \"coordinates\": [ ");
|
||||||
for (unsigned i = 0; i < ops.size(); i++) {
|
for (size_t i = 0; i < ops.size(); i++) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
printf(", ");
|
printf(", ");
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
} else {
|
} else {
|
||||||
printf("\"type\": \"MultiLineString\", \"coordinates\": [ [ ");
|
printf("\"type\": \"MultiLineString\", \"coordinates\": [ [ ");
|
||||||
int state = 0;
|
int state = 0;
|
||||||
for (unsigned i = 0; i < ops.size(); i++) {
|
for (size_t i = 0; i < ops.size(); i++) {
|
||||||
if (ops[i].op == VT_MOVETO) {
|
if (ops[i].op == VT_MOVETO) {
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
printf("[ %f, %f ]", ops[i].lon, ops[i].lat);
|
||||||
@ -268,7 +268,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
std::vector<std::vector<draw> > rings;
|
std::vector<std::vector<draw> > rings;
|
||||||
std::vector<double> areas;
|
std::vector<double> areas;
|
||||||
|
|
||||||
for (unsigned i = 0; i < ops.size(); i++) {
|
for (size_t i = 0; i < ops.size(); i++) {
|
||||||
if (ops[i].op == VT_MOVETO) {
|
if (ops[i].op == VT_MOVETO) {
|
||||||
rings.push_back(std::vector<draw>());
|
rings.push_back(std::vector<draw>());
|
||||||
areas.push_back(0);
|
areas.push_back(0);
|
||||||
@ -282,9 +282,9 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
|
|
||||||
int outer = 0;
|
int outer = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < rings.size(); i++) {
|
for (size_t i = 0; i < rings.size(); i++) {
|
||||||
double area = 0;
|
double area = 0;
|
||||||
for (unsigned k = 0; k < rings[i].size(); k++) {
|
for (size_t k = 0; k < rings[i].size(); k++) {
|
||||||
if (rings[i][k].op != VT_CLOSEPATH) {
|
if (rings[i][k].op != VT_CLOSEPATH) {
|
||||||
area += rings[i][k].lon * rings[i][(k + 1) % rings[i].size()].lat;
|
area += rings[i][k].lon * rings[i][(k + 1) % rings[i].size()].lat;
|
||||||
area -= rings[i][k].lat * rings[i][(k + 1) % rings[i].size()].lon;
|
area -= rings[i][k].lat * rings[i][(k + 1) % rings[i].size()].lon;
|
||||||
@ -306,7 +306,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
for (unsigned i = 0; i < rings.size(); i++) {
|
for (size_t i = 0; i < rings.size(); i++) {
|
||||||
if (areas[i] <= 0) {
|
if (areas[i] <= 0) {
|
||||||
if (state != 0) {
|
if (state != 0) {
|
||||||
// new multipolygon
|
// new multipolygon
|
||||||
@ -320,7 +320,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, int describe) {
|
|||||||
printf(" ], [ ");
|
printf(" ], [ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned j = 0; j < rings[i].size(); j++) {
|
for (size_t j = 0; j < rings[i].size(); j++) {
|
||||||
if (rings[i][j].op != VT_CLOSEPATH) {
|
if (rings[i][j].op != VT_CLOSEPATH) {
|
||||||
if (j != 0) {
|
if (j != 0) {
|
||||||
printf(", ");
|
printf(", ");
|
||||||
|
160
geojson.c
160
geojson.c
@ -19,6 +19,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#include "jsonpull.h"
|
#include "jsonpull.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
@ -28,13 +29,16 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "memfile.h"
|
#include "memfile.h"
|
||||||
|
|
||||||
int low_detail = 12;
|
static int low_detail = 12;
|
||||||
int full_detail = -1;
|
static int full_detail = -1;
|
||||||
int min_detail = 7;
|
static int min_detail = 7;
|
||||||
int quiet = 0;
|
|
||||||
|
|
||||||
|
int quiet = 0;
|
||||||
int geometry_scale = 0;
|
int geometry_scale = 0;
|
||||||
|
|
||||||
|
static int prevent[256];
|
||||||
|
static int additional[256];
|
||||||
|
|
||||||
#define GEOM_POINT 0 /* array of positions */
|
#define GEOM_POINT 0 /* array of positions */
|
||||||
#define GEOM_MULTIPOINT 1 /* array of arrays of positions */
|
#define GEOM_MULTIPOINT 1 /* array of arrays of positions */
|
||||||
#define GEOM_LINESTRING 2 /* array of arrays of positions */
|
#define GEOM_LINESTRING 2 /* array of arrays of positions */
|
||||||
@ -43,11 +47,11 @@ int geometry_scale = 0;
|
|||||||
#define GEOM_MULTIPOLYGON 5 /* array of arrays of arrays of arrays of positions */
|
#define GEOM_MULTIPOLYGON 5 /* array of arrays of arrays of arrays of positions */
|
||||||
#define GEOM_TYPES 6
|
#define GEOM_TYPES 6
|
||||||
|
|
||||||
const char *geometry_names[GEOM_TYPES] = {
|
static const char *geometry_names[GEOM_TYPES] = {
|
||||||
"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon",
|
"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon",
|
||||||
};
|
};
|
||||||
|
|
||||||
int geometry_within[GEOM_TYPES] = {
|
static int geometry_within[GEOM_TYPES] = {
|
||||||
-1, /* point */
|
-1, /* point */
|
||||||
GEOM_POINT, /* multipoint */
|
GEOM_POINT, /* multipoint */
|
||||||
GEOM_POINT, /* linestring */
|
GEOM_POINT, /* linestring */
|
||||||
@ -56,7 +60,7 @@ int geometry_within[GEOM_TYPES] = {
|
|||||||
GEOM_POLYGON, /* multipolygon */
|
GEOM_POLYGON, /* multipolygon */
|
||||||
};
|
};
|
||||||
|
|
||||||
int mb_geometry[GEOM_TYPES] = {
|
static int mb_geometry[GEOM_TYPES] = {
|
||||||
VT_POINT, VT_POINT, VT_LINE, VT_LINE, VT_POLYGON, VT_POLYGON,
|
VT_POINT, VT_POINT, VT_LINE, VT_LINE, VT_POLYGON, VT_POLYGON,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,7 +150,7 @@ void parse_geometry(int t, json_object *j, long long *bbox, long long *fpos, FIL
|
|||||||
|
|
||||||
int within = geometry_within[t];
|
int within = geometry_within[t];
|
||||||
if (within >= 0) {
|
if (within >= 0) {
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < j->length; i++) {
|
for (i = 0; i < j->length; i++) {
|
||||||
if (within == GEOM_POINT) {
|
if (within == GEOM_POINT) {
|
||||||
if (i == 0 || mb_geometry[t] == GEOM_MULTIPOINT) {
|
if (i == 0 || mb_geometry[t] == GEOM_MULTIPOINT) {
|
||||||
@ -299,7 +303,7 @@ struct merge {
|
|||||||
struct merge *next;
|
struct merge *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void insert(struct merge *m, struct merge **head, unsigned char *map, int bytes) {
|
static void insert(struct merge *m, struct merge **head, unsigned char *map) {
|
||||||
while (*head != NULL && indexcmp(map + m->start, map + (*head)->start) > 0) {
|
while (*head != NULL && indexcmp(map + m->start, map + (*head)->start) > 0) {
|
||||||
head = &((*head)->next);
|
head = &((*head)->next);
|
||||||
}
|
}
|
||||||
@ -316,7 +320,7 @@ static void merge(struct merge *merges, int nmerges, unsigned char *map, FILE *f
|
|||||||
|
|
||||||
for (i = 0; i < nmerges; i++) {
|
for (i = 0; i < nmerges; i++) {
|
||||||
if (merges[i].start < merges[i].end) {
|
if (merges[i].start < merges[i].end) {
|
||||||
insert(&(merges[i]), &head, map, bytes);
|
insert(&(merges[i]), &head, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +337,7 @@ static void merge(struct merge *merges, int nmerges, unsigned char *map, FILE *f
|
|||||||
m->next = NULL;
|
m->next = NULL;
|
||||||
|
|
||||||
if (m->start < m->end) {
|
if (m->start < m->end) {
|
||||||
insert(m, &head, map, bytes);
|
insert(m, &head, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
along++;
|
along++;
|
||||||
@ -445,7 +449,7 @@ long long addpool(struct memfile *poolfile, struct memfile *treefile, char *s, c
|
|||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
int serialize_geometry(json_object *geometry, json_object *properties, const char *reading, int line, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int maxzoom, int basezoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
int serialize_geometry(json_object *geometry, json_object *properties, const char *reading, int line, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, const char *fname, int basezoom, int layer, double droprate, long long *file_bbox, json_object *tippecanoe, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
||||||
json_object *geometry_type = json_hash_get(geometry, "type");
|
json_object *geometry_type = json_hash_get(geometry, "type");
|
||||||
if (geometry_type == NULL) {
|
if (geometry_type == NULL) {
|
||||||
static int warned = 0;
|
static int warned = 0;
|
||||||
@ -646,7 +650,7 @@ int serialize_geometry(json_object *geometry, json_object *properties, const cha
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_json(json_pull *jp, const char *reading, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int maxzoom, int basezoom, int layer, double droprate, long long *file_bbox, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
void parse_json(json_pull *jp, const char *reading, volatile long long *layer_seq, volatile long long *progress_seq, long long *metapos, long long *geompos, long long *indexpos, struct pool *exclude, struct pool *include, int exclude_all, FILE *metafile, FILE *geomfile, FILE *indexfile, struct memfile *poolfile, struct memfile *treefile, char *fname, int basezoom, int layer, double droprate, long long *file_bbox, int segment, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
||||||
long long found_hashes = 0;
|
long long found_hashes = 0;
|
||||||
long long found_features = 0;
|
long long found_features = 0;
|
||||||
long long found_geometries = 0;
|
long long found_geometries = 0;
|
||||||
@ -711,7 +715,7 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
|
|||||||
}
|
}
|
||||||
found_geometries++;
|
found_geometries++;
|
||||||
|
|
||||||
serialize_geometry(j, NULL, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, NULL, segment, initialized, initial_x, initial_y);
|
serialize_geometry(j, NULL, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, NULL, segment, initialized, initial_x, initial_y);
|
||||||
json_free(j);
|
json_free(j);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -744,12 +748,12 @@ void parse_json(json_pull *jp, const char *reading, volatile long long *layer_se
|
|||||||
|
|
||||||
json_object *geometries = json_hash_get(geometry, "geometries");
|
json_object *geometries = json_hash_get(geometry, "geometries");
|
||||||
if (geometries != NULL) {
|
if (geometries != NULL) {
|
||||||
int g;
|
size_t g;
|
||||||
for (g = 0; g < geometries->length; g++) {
|
for (g = 0; g < geometries->length; g++) {
|
||||||
serialize_geometry(geometries->array[g], properties, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y);
|
serialize_geometry(geometries->array[g], properties, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serialize_geometry(geometry, properties, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, maxzoom, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y);
|
serialize_geometry(geometry, properties, reading, jp->line, layer_seq, progress_seq, metapos, geompos, indexpos, exclude, include, exclude_all, metafile, geomfile, indexfile, poolfile, treefile, fname, basezoom, layer, droprate, file_bbox, tippecanoe, segment, initialized, initial_x, initial_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
json_free(j);
|
json_free(j);
|
||||||
@ -775,7 +779,6 @@ struct parse_json_args {
|
|||||||
struct memfile *poolfile;
|
struct memfile *poolfile;
|
||||||
struct memfile *treefile;
|
struct memfile *treefile;
|
||||||
char *fname;
|
char *fname;
|
||||||
int maxzoom;
|
|
||||||
int basezoom;
|
int basezoom;
|
||||||
int layer;
|
int layer;
|
||||||
double droprate;
|
double droprate;
|
||||||
@ -789,18 +792,18 @@ struct parse_json_args {
|
|||||||
void *run_parse_json(void *v) {
|
void *run_parse_json(void *v) {
|
||||||
struct parse_json_args *pja = v;
|
struct parse_json_args *pja = v;
|
||||||
|
|
||||||
parse_json(pja->jp, pja->reading, pja->layer_seq, pja->progress_seq, pja->metapos, pja->geompos, pja->indexpos, pja->exclude, pja->include, pja->exclude_all, pja->metafile, pja->geomfile, pja->indexfile, pja->poolfile, pja->treefile, pja->fname, pja->maxzoom, pja->basezoom, pja->layer, pja->droprate, pja->file_bbox, pja->segment, pja->initialized, pja->initial_x, pja->initial_y);
|
parse_json(pja->jp, pja->reading, pja->layer_seq, pja->progress_seq, pja->metapos, pja->geompos, pja->indexpos, pja->exclude, pja->include, pja->exclude_all, pja->metafile, pja->geomfile, pja->indexfile, pja->poolfile, pja->treefile, pja->fname, pja->basezoom, pja->layer, pja->droprate, pja->file_bbox, pja->segment, pja->initialized, pja->initial_x, pja->initial_y);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct jsonmap {
|
struct jsonmap {
|
||||||
char *map;
|
char *map;
|
||||||
long long off;
|
unsigned long long off;
|
||||||
long long end;
|
unsigned long long end;
|
||||||
};
|
};
|
||||||
|
|
||||||
int json_map_read(struct json_pull *jp, char *buffer, int n) {
|
ssize_t json_map_read(struct json_pull *jp, char *buffer, size_t n) {
|
||||||
struct jsonmap *jm = jp->source;
|
struct jsonmap *jm = jp->source;
|
||||||
|
|
||||||
if (jm->off + n >= jm->end) {
|
if (jm->off + n >= jm->end) {
|
||||||
@ -815,6 +818,10 @@ int json_map_read(struct json_pull *jp, char *buffer, int n) {
|
|||||||
|
|
||||||
struct json_pull *json_begin_map(char *map, long long len) {
|
struct json_pull *json_begin_map(char *map, long long len) {
|
||||||
struct jsonmap *jm = malloc(sizeof(struct jsonmap));
|
struct jsonmap *jm = malloc(sizeof(struct jsonmap));
|
||||||
|
if (jm == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
jm->map = map;
|
jm->map = map;
|
||||||
jm->off = 0;
|
jm->off = 0;
|
||||||
@ -888,7 +895,7 @@ void *run_sort(void *v) {
|
|||||||
// MAP_PRIVATE to avoid disk writes if it fits in memory
|
// MAP_PRIVATE to avoid disk writes if it fits in memory
|
||||||
void *map = mmap(NULL, end - start, PROT_READ | PROT_WRITE, MAP_PRIVATE, a->indexfd, start);
|
void *map = mmap(NULL, end - start, PROT_READ | PROT_WRITE, MAP_PRIVATE, a->indexfd, start);
|
||||||
if (map == MAP_FAILED) {
|
if (map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap in run_sort");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +919,7 @@ void *run_sort(void *v) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_read_parallel(char *map, long long len, long long initial_offset, const char *reading, struct reader *reader, volatile long long *progress_seq, struct pool *exclude, struct pool *include, int exclude_all, char *fname, int maxzoom, int basezoom, int source, int nlayers, double droprate, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
void do_read_parallel(char *map, long long len, long long initial_offset, const char *reading, struct reader *reader, volatile long long *progress_seq, struct pool *exclude, struct pool *include, int exclude_all, char *fname, int basezoom, int source, int nlayers, double droprate, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
||||||
long long segs[CPUS + 1];
|
long long segs[CPUS + 1];
|
||||||
segs[0] = 0;
|
segs[0] = 0;
|
||||||
segs[CPUS] = len;
|
segs[CPUS] = len;
|
||||||
@ -953,7 +960,6 @@ void do_read_parallel(char *map, long long len, long long initial_offset, const
|
|||||||
pja[i].poolfile = reader[i].poolfile;
|
pja[i].poolfile = reader[i].poolfile;
|
||||||
pja[i].treefile = reader[i].treefile;
|
pja[i].treefile = reader[i].treefile;
|
||||||
pja[i].fname = fname;
|
pja[i].fname = fname;
|
||||||
pja[i].maxzoom = maxzoom;
|
|
||||||
pja[i].basezoom = basezoom;
|
pja[i].basezoom = basezoom;
|
||||||
pja[i].layer = source < nlayers ? source : 0;
|
pja[i].layer = source < nlayers ? source : 0;
|
||||||
pja[i].droprate = droprate;
|
pja[i].droprate = droprate;
|
||||||
@ -1023,7 +1029,7 @@ void *run_read_parallel(void *v) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_read_parallel(map, a->len, a->offset, a->reading, a->reader, a->progress_seq, a->exclude, a->include, a->exclude_all, a->fname, a->maxzoom, a->basezoom, a->source, a->nlayers, a->droprate, a->initialized, a->initial_x, a->initial_y);
|
do_read_parallel(map, a->len, a->offset, a->reading, a->reader, a->progress_seq, a->exclude, a->include, a->exclude_all, a->fname, a->basezoom, a->source, a->nlayers, a->droprate, a->initialized, a->initial_x, a->initial_y);
|
||||||
|
|
||||||
if (munmap(map, a->len) != 0) {
|
if (munmap(map, a->len) != 0) {
|
||||||
perror("munmap source file");
|
perror("munmap source file");
|
||||||
@ -1038,7 +1044,7 @@ void *run_read_parallel(void *v) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_parsing(int fd, FILE *fp, long long offset, long long len, volatile int *is_parsing, pthread_t *parallel_parser, const char *reading, struct reader *reader, volatile long long *progress_seq, struct pool *exclude, struct pool *include, int exclude_all, char *fname, int maxzoom, int basezoom, int source, int nlayers, double droprate, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
void start_parsing(int fd, FILE *fp, long long offset, long long len, volatile int *is_parsing, pthread_t *parallel_parser, const char *reading, struct reader *reader, volatile long long *progress_seq, struct pool *exclude, struct pool *include, int exclude_all, char *fname, int basezoom, int source, int nlayers, double droprate, int *initialized, unsigned *initial_x, unsigned *initial_y) {
|
||||||
// This has to kick off an intermediate thread to start the parser threads,
|
// This has to kick off an intermediate thread to start the parser threads,
|
||||||
// so the main thread can get back to reading the next input stage while
|
// so the main thread can get back to reading the next input stage while
|
||||||
// the intermediate thread waits for the completion of the parser threads.
|
// the intermediate thread waits for the completion of the parser threads.
|
||||||
@ -1046,6 +1052,11 @@ void start_parsing(int fd, FILE *fp, long long offset, long long len, volatile i
|
|||||||
*is_parsing = 1;
|
*is_parsing = 1;
|
||||||
|
|
||||||
struct read_parallel_arg *rpa = malloc(sizeof(struct read_parallel_arg));
|
struct read_parallel_arg *rpa = malloc(sizeof(struct read_parallel_arg));
|
||||||
|
if (rpa == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
rpa->fd = fd;
|
rpa->fd = fd;
|
||||||
rpa->fp = fp;
|
rpa->fp = fp;
|
||||||
rpa->offset = offset;
|
rpa->offset = offset;
|
||||||
@ -1059,7 +1070,6 @@ void start_parsing(int fd, FILE *fp, long long offset, long long len, volatile i
|
|||||||
rpa->include = include;
|
rpa->include = include;
|
||||||
rpa->exclude_all = exclude_all;
|
rpa->exclude_all = exclude_all;
|
||||||
rpa->fname = fname;
|
rpa->fname = fname;
|
||||||
rpa->maxzoom = maxzoom;
|
|
||||||
rpa->basezoom = basezoom;
|
rpa->basezoom = basezoom;
|
||||||
rpa->source = source;
|
rpa->source = source;
|
||||||
rpa->nlayers = nlayers;
|
rpa->nlayers = nlayers;
|
||||||
@ -1074,7 +1084,7 @@ void start_parsing(int fd, FILE *fp, long long offset, long long len, volatile i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, char *prevent, char *additional, int read_parallel, int forcetable) {
|
int read_json(int argc, char **argv, char *fname, const char *layername, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, struct pool *exclude, struct pool *include, int exclude_all, double droprate, int buffer, const char *tmpdir, double gamma, int *prevent, int *additional, int read_parallel, int forcetable) {
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
|
|
||||||
struct reader reader[CPUS];
|
struct reader reader[CPUS];
|
||||||
@ -1088,6 +1098,11 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
r->geomname = malloc(strlen(tmpdir) + strlen("/geom.XXXXXXXX") + 1);
|
r->geomname = malloc(strlen(tmpdir) + strlen("/geom.XXXXXXXX") + 1);
|
||||||
r->indexname = malloc(strlen(tmpdir) + strlen("/index.XXXXXXXX") + 1);
|
r->indexname = malloc(strlen(tmpdir) + strlen("/index.XXXXXXXX") + 1);
|
||||||
|
|
||||||
|
if (r->metaname == NULL || r->poolname == NULL || r->treename == NULL || r->geomname == NULL || r->indexname == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(r->metaname, "%s%s", tmpdir, "/meta.XXXXXXXX");
|
sprintf(r->metaname, "%s%s", tmpdir, "/meta.XXXXXXXX");
|
||||||
sprintf(r->poolname, "%s%s", tmpdir, "/pool.XXXXXXXX");
|
sprintf(r->poolname, "%s%s", tmpdir, "/pool.XXXXXXXX");
|
||||||
sprintf(r->treename, "%s%s", tmpdir, "/tree.XXXXXXXX");
|
sprintf(r->treename, "%s%s", tmpdir, "/tree.XXXXXXXX");
|
||||||
@ -1162,6 +1177,10 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
}
|
}
|
||||||
|
|
||||||
r->file_bbox = malloc(4 * sizeof(long long));
|
r->file_bbox = malloc(4 * sizeof(long long));
|
||||||
|
if (r->file_bbox == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
r->file_bbox[0] = r->file_bbox[1] = UINT_MAX;
|
r->file_bbox[0] = r->file_bbox[1] = UINT_MAX;
|
||||||
r->file_bbox[2] = r->file_bbox[3] = 0;
|
r->file_bbox[2] = r->file_bbox[3] = 0;
|
||||||
}
|
}
|
||||||
@ -1222,7 +1241,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (map != NULL && map != MAP_FAILED) {
|
if (map != NULL && map != MAP_FAILED) {
|
||||||
do_read_parallel(map, st.st_size - off, overall_offset, reading, reader, &progress_seq, exclude, include, exclude_all, fname, maxzoom, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
do_read_parallel(map, st.st_size - off, overall_offset, reading, reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
||||||
overall_offset += st.st_size - off;
|
overall_offset += st.st_size - off;
|
||||||
|
|
||||||
if (munmap(map, st.st_size - off) != 0) {
|
if (munmap(map, st.st_size - off) != 0) {
|
||||||
@ -1276,7 +1295,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
}
|
}
|
||||||
|
|
||||||
fflush(readfp);
|
fflush(readfp);
|
||||||
start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, reading, reader, &progress_seq, exclude, include, exclude_all, fname, maxzoom, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, reading, reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
||||||
|
|
||||||
initial_offset += ahead;
|
initial_offset += ahead;
|
||||||
overall_offset += ahead;
|
overall_offset += ahead;
|
||||||
@ -1310,7 +1329,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
fflush(readfp);
|
fflush(readfp);
|
||||||
|
|
||||||
if (ahead > 0) {
|
if (ahead > 0) {
|
||||||
start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, reading, reader, &progress_seq, exclude, include, exclude_all, fname, maxzoom, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
start_parsing(readfd, readfp, initial_offset, ahead, &is_parsing, ¶llel_parser, reading, reader, &progress_seq, exclude, include, exclude_all, fname, basezoom, source, nlayers, droprate, initialized, initial_x, initial_y);
|
||||||
|
|
||||||
if (pthread_join(parallel_parser, NULL) != 0) {
|
if (pthread_join(parallel_parser, NULL) != 0) {
|
||||||
perror("pthread_join");
|
perror("pthread_join");
|
||||||
@ -1323,7 +1342,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
|
|
||||||
long long layer_seq = overall_offset;
|
long long layer_seq = overall_offset;
|
||||||
json_pull *jp = json_begin_file(fp);
|
json_pull *jp = json_begin_file(fp);
|
||||||
parse_json(jp, reading, &layer_seq, &progress_seq, &reader[0].metapos, &reader[0].geompos, &reader[0].indexpos, exclude, include, exclude_all, reader[0].metafile, reader[0].geomfile, reader[0].indexfile, reader[0].poolfile, reader[0].treefile, fname, maxzoom, basezoom, source < nlayers ? source : 0, droprate, reader[0].file_bbox, 0, &initialized[0], &initial_x[0], &initial_y[0]);
|
parse_json(jp, reading, &layer_seq, &progress_seq, &reader[0].metapos, &reader[0].geompos, &reader[0].indexpos, exclude, include, exclude_all, reader[0].metafile, reader[0].geomfile, reader[0].indexfile, reader[0].poolfile, reader[0].treefile, fname, basezoom, source < nlayers ? source : 0, droprate, reader[0].file_bbox, 0, &initialized[0], &initial_x[0], &initial_y[0]);
|
||||||
json_end(jp);
|
json_end(jp);
|
||||||
overall_offset = layer_seq;
|
overall_offset = layer_seq;
|
||||||
}
|
}
|
||||||
@ -1364,6 +1383,10 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
for (i = 0; i < nlayers; i++) {
|
for (i = 0; i < nlayers; i++) {
|
||||||
if (layername != NULL) {
|
if (layername != NULL) {
|
||||||
layernames[i] = strdup(layername);
|
layernames[i] = strdup(layername);
|
||||||
|
if (layernames[i] == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char *src = argv[i];
|
char *src = argv[i];
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
@ -1371,6 +1394,11 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *trunc = layernames[i] = malloc(strlen(src) + 1);
|
char *trunc = layernames[i] = malloc(strlen(src) + 1);
|
||||||
|
if (trunc == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
const char *ocp, *use = src;
|
const char *ocp, *use = src;
|
||||||
for (ocp = src; *ocp; ocp++) {
|
for (ocp = src; *ocp; ocp++) {
|
||||||
if (*ocp == '/' && ocp[1] != '\0') {
|
if (*ocp == '/' && ocp[1] != '\0') {
|
||||||
@ -1426,7 +1454,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
if (reader[i].indexpos > 0) {
|
if (reader[i].indexpos > 0) {
|
||||||
void *map = mmap(NULL, reader[i].indexpos, PROT_READ, MAP_PRIVATE, reader[i].indexfd, 0);
|
void *map = mmap(NULL, reader[i].indexpos, PROT_READ, MAP_PRIVATE, reader[i].indexfd, 0);
|
||||||
if (map == MAP_FAILED) {
|
if (map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap reunifying index");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (fwrite(map, reader[i].indexpos, 1, indexfile) != 1) {
|
if (fwrite(map, reader[i].indexpos, 1, indexfile) != 1) {
|
||||||
@ -1444,6 +1472,11 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
}
|
}
|
||||||
fclose(indexfile);
|
fclose(indexfile);
|
||||||
|
|
||||||
|
if (indexpos == 0) {
|
||||||
|
fprintf(stderr, "Did not read any valid geometries\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
char geomname[strlen(tmpdir) + strlen("/geom.XXXXXXXX") + 1];
|
char geomname[strlen(tmpdir) + strlen("/geom.XXXXXXXX") + 1];
|
||||||
|
|
||||||
FILE *geomfile;
|
FILE *geomfile;
|
||||||
@ -1462,6 +1495,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
perror(geomname);
|
perror(geomname);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
unlink(geomname);
|
||||||
int geomfd2;
|
int geomfd2;
|
||||||
|
|
||||||
/* Sort the index by geometry */
|
/* Sort the index by geometry */
|
||||||
@ -1520,7 +1554,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
|
|
||||||
char *map = mmap(NULL, indexpos, PROT_READ | PROT_WRITE, MAP_SHARED, indexfd, 0);
|
char *map = mmap(NULL, indexpos, PROT_READ | PROT_WRITE, MAP_SHARED, indexfd, 0);
|
||||||
if (map == MAP_FAILED) {
|
if (map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap unified index");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,7 +1609,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
long long pre_merged_geompos = geompos;
|
long long pre_merged_geompos = geompos;
|
||||||
char *geom_map = mmap(NULL, geompos, PROT_READ, MAP_PRIVATE, geomfd, 0);
|
char *geom_map = mmap(NULL, geompos, PROT_READ, MAP_PRIVATE, geomfd, 0);
|
||||||
if (geom_map == MAP_FAILED) {
|
if (geom_map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap geometry");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,6 +1630,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
perror(geomname);
|
perror(geomname);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
unlink(geomname);
|
||||||
|
|
||||||
for (i = 0; i < CPUS; i++) {
|
for (i = 0; i < CPUS; i++) {
|
||||||
if (reader[i].geomst.st_size > 0) {
|
if (reader[i].geomst.st_size > 0) {
|
||||||
@ -1640,7 +1675,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
if (basezoom < 0 || droprate < 0) {
|
if (basezoom < 0 || droprate < 0) {
|
||||||
struct index *map = mmap(NULL, indexpos, PROT_READ, MAP_PRIVATE, indexfd, 0);
|
struct index *map = mmap(NULL, indexpos, PROT_READ, MAP_PRIVATE, indexfd, 0);
|
||||||
if (map == MAP_FAILED) {
|
if (map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap index for basezoom");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1891,7 +1926,7 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max
|
|||||||
if (reader[i].metapos > 0) {
|
if (reader[i].metapos > 0) {
|
||||||
void *map = mmap(NULL, reader[i].metapos, PROT_READ, MAP_PRIVATE, reader[i].metafd, 0);
|
void *map = mmap(NULL, reader[i].metapos, PROT_READ, MAP_PRIVATE, reader[i].metafd, 0);
|
||||||
if (map == MAP_FAILED) {
|
if (map == MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap unmerged meta");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (fwrite(map, reader[i].metapos, 1, metafile) != 1) {
|
if (fwrite(map, reader[i].metapos, 1, metafile) != 1) {
|
||||||
@ -2077,8 +2112,6 @@ int main(int argc, char **argv) {
|
|||||||
double gamma = 0;
|
double gamma = 0;
|
||||||
int buffer = 5;
|
int buffer = 5;
|
||||||
const char *tmpdir = "/tmp";
|
const char *tmpdir = "/tmp";
|
||||||
char prevent[256];
|
|
||||||
char additional[256];
|
|
||||||
|
|
||||||
struct pool exclude, include;
|
struct pool exclude, include;
|
||||||
pool_init(&exclude, 0);
|
pool_init(&exclude, 0);
|
||||||
@ -2091,8 +2124,53 @@ int main(int argc, char **argv) {
|
|||||||
additional[i] = 0;
|
additional[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((i = getopt(argc, argv, "l:n:z:Z:d:D:m:o:x:y:r:b:fFXt:g:p:vqa:B:P")) != -1) {
|
static struct option long_options[] = {
|
||||||
|
{"name", required_argument, 0, 'n'},
|
||||||
|
{"layer", required_argument, 0, 'l'},
|
||||||
|
{"maximum-zoom", required_argument, 0, 'z'},
|
||||||
|
{"minimum-zoom", required_argument, 0, 'Z'},
|
||||||
|
{"base-zoom", required_argument, 0, 'B'},
|
||||||
|
{"full-detail", required_argument, 0, 'd'},
|
||||||
|
{"low-detail", required_argument, 0, 'D'},
|
||||||
|
{"minimum-detail", required_argument, 0, 'm'},
|
||||||
|
{"output", required_argument, 0, 'o'},
|
||||||
|
{"exclude", required_argument, 0, 'x'},
|
||||||
|
{"include", required_argument, 0, 'y'},
|
||||||
|
{"drop-rate", required_argument, 0, 'r'},
|
||||||
|
{"buffer", required_argument, 0, 'b'},
|
||||||
|
{"temporary-directory", required_argument, 0, 't'},
|
||||||
|
{"gamma", required_argument, 0, 'g'},
|
||||||
|
{"prevent", required_argument, 0, 'p'},
|
||||||
|
{"additional", required_argument, 0, 'a'},
|
||||||
|
|
||||||
|
{"exclude-all", no_argument, 0, 'X'},
|
||||||
|
{"force", no_argument, 0, 'f'},
|
||||||
|
{"allow-existing", no_argument, 0, 'F'},
|
||||||
|
{"quiet", no_argument, 0, 'q'},
|
||||||
|
{"version", no_argument, 0, 'v'},
|
||||||
|
{"read-parallel", no_argument, 0, 'P'},
|
||||||
|
|
||||||
|
{"coalesce", no_argument, &additional[A_COALESCE], 1},
|
||||||
|
{"reverse", no_argument, &additional[A_REVERSE], 1},
|
||||||
|
{"reorder", no_argument, &additional[A_REORDER], 1},
|
||||||
|
{"drop-lines", no_argument, &additional[A_LINE_DROP], 1},
|
||||||
|
|
||||||
|
{"no-line-simplification", no_argument, &prevent[P_SIMPLIFY], 1},
|
||||||
|
{"simplify-only-low-zooms", no_argument, &prevent[P_SIMPLIFY_LOW], 1},
|
||||||
|
{"no-feature-limit", no_argument, &prevent[P_FEATURE_LIMIT], 1},
|
||||||
|
{"no-tile-size-limit", no_argument, &prevent[P_KILOBYTE_LIMIT], 1},
|
||||||
|
{"force-feature-limit", no_argument, &prevent[P_DYNAMIC_DROP], 1},
|
||||||
|
{"preseve-input-order", no_argument, &prevent[P_INPUT_ORDER], 1},
|
||||||
|
{"no-polygon-splitting", no_argument, &prevent[P_POLYGON_SPLIT], 1},
|
||||||
|
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
while ((i = getopt_long(argc, argv, "n:l:z:Z:B:d:D:m:o:x:y:r:b:t:g:p:a:XfFqvP", long_options, NULL)) != -1) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
name = optarg;
|
name = optarg;
|
||||||
break;
|
break;
|
||||||
|
95
geometry.cc
95
geometry.cc
@ -77,9 +77,7 @@ drawvec decode_geometry(char **meta, int z, unsigned tx, unsigned ty, int detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
void to_tile_scale(drawvec &geom, int z, int detail) {
|
void to_tile_scale(drawvec &geom, int z, int detail) {
|
||||||
unsigned i;
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
|
||||||
geom[i].x >>= (32 - detail - z);
|
geom[i].x >>= (32 - detail - z);
|
||||||
geom[i].y >>= (32 - detail - z);
|
geom[i].y >>= (32 - detail - z);
|
||||||
}
|
}
|
||||||
@ -90,9 +88,8 @@ drawvec remove_noop(drawvec geom, int type, int shift) {
|
|||||||
|
|
||||||
long long x = 0, y = 0;
|
long long x = 0, y = 0;
|
||||||
drawvec out;
|
drawvec out;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_LINETO && (geom[i].x >> shift) == x && (geom[i].y >> shift) == y) {
|
if (geom[i].op == VT_LINETO && (geom[i].x >> shift) == x && (geom[i].y >> shift) == y) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -112,7 +109,7 @@ drawvec remove_noop(drawvec geom, int type, int shift) {
|
|||||||
geom = out;
|
geom = out;
|
||||||
out.resize(0);
|
out.resize(0);
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
if (i + 1 >= geom.size()) {
|
if (i + 1 >= geom.size()) {
|
||||||
continue;
|
continue;
|
||||||
@ -139,7 +136,7 @@ drawvec remove_noop(drawvec geom, int type, int shift) {
|
|||||||
geom = out;
|
geom = out;
|
||||||
out.resize(0);
|
out.resize(0);
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
if (i > 0 && geom[i - 1].op == VT_LINETO && (geom[i - 1].x >> shift) == (geom[i].x >> shift) && (geom[i - 1].y >> shift) == (geom[i].y >> shift)) {
|
if (i > 0 && geom[i - 1].op == VT_LINETO && (geom[i - 1].x >> shift) == (geom[i].x >> shift) && (geom[i - 1].y >> shift) == (geom[i].y >> shift)) {
|
||||||
continue;
|
continue;
|
||||||
@ -159,10 +156,9 @@ drawvec shrink_lines(drawvec &geom, int z, int detail, int basezoom, long long *
|
|||||||
long long res = 200LL << (32 - 8 - z);
|
long long res = 200LL << (32 - 8 - z);
|
||||||
long long portion = res / exp(log(sqrt(droprate)) * (basezoom - z));
|
long long portion = res / exp(log(sqrt(droprate)) * (basezoom - z));
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) {
|
if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) {
|
||||||
double dx = (geom[i].x - geom[i - 1].x);
|
double dx = (geom[i].x - geom[i - 1].x);
|
||||||
double dy = (geom[i].y - geom[i - 1].y);
|
double dy = (geom[i].y - geom[i - 1].y);
|
||||||
@ -241,8 +237,8 @@ static void decode_clipped(ClipperLib::PolyNode *t, drawvec &out) {
|
|||||||
// to do any outer-ring children of those children as a new top level.
|
// to do any outer-ring children of those children as a new top level.
|
||||||
|
|
||||||
ClipperLib::Path p = t->Contour;
|
ClipperLib::Path p = t->Contour;
|
||||||
unsigned before = out.size();
|
size_t before = out.size();
|
||||||
for (unsigned i = 0; i < p.size(); i++) {
|
for (size_t i = 0; i < p.size(); i++) {
|
||||||
out.push_back(draw((i == 0) ? VT_MOVETO : VT_LINETO, p[i].X, p[i].Y));
|
out.push_back(draw((i == 0) ? VT_MOVETO : VT_LINETO, p[i].X, p[i].Y));
|
||||||
}
|
}
|
||||||
if (p.size() > 0) {
|
if (p.size() > 0) {
|
||||||
@ -254,7 +250,7 @@ static void decode_clipped(ClipperLib::PolyNode *t, drawvec &out) {
|
|||||||
|
|
||||||
for (int n = 0; n < t->ChildCount(); n++) {
|
for (int n = 0; n < t->ChildCount(); n++) {
|
||||||
ClipperLib::Path p = t->Childs[n]->Contour;
|
ClipperLib::Path p = t->Childs[n]->Contour;
|
||||||
for (unsigned i = 0; i < p.size(); i++) {
|
for (size_t i = 0; i < p.size(); i++) {
|
||||||
out.push_back(draw((i == 0) ? VT_MOVETO : VT_LINETO, p[i].X, p[i].Y));
|
out.push_back(draw((i == 0) ? VT_MOVETO : VT_LINETO, p[i].X, p[i].Y));
|
||||||
}
|
}
|
||||||
if (p.size() > 0) {
|
if (p.size() > 0) {
|
||||||
@ -278,9 +274,9 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl
|
|||||||
|
|
||||||
bool has_area = false;
|
bool has_area = false;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -288,7 +284,7 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
double area = 0;
|
double area = 0;
|
||||||
for (unsigned k = i; k < j; k++) {
|
for (size_t k = i; k < j; k++) {
|
||||||
area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y;
|
area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y;
|
||||||
area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x;
|
area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x;
|
||||||
}
|
}
|
||||||
@ -300,14 +296,14 @@ drawvec clean_or_clip_poly(drawvec &geom, int z, int detail, int buffer, bool cl
|
|||||||
ClipperLib::Path path;
|
ClipperLib::Path path;
|
||||||
|
|
||||||
drawvec tmp;
|
drawvec tmp;
|
||||||
for (unsigned k = i; k < j; k++) {
|
for (size_t k = i; k < j; k++) {
|
||||||
path.push_back(ClipperLib::IntPoint(geom[k].x, geom[k].y));
|
path.push_back(ClipperLib::IntPoint(geom[k].x, geom[k].y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clipper.AddPath(path, ClipperLib::ptSubject, true)) {
|
if (!clipper.AddPath(path, ClipperLib::ptSubject, true)) {
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stderr, "Couldn't add polygon for clipping:");
|
fprintf(stderr, "Couldn't add polygon for clipping:");
|
||||||
for (unsigned k = i; k < j; k++) {
|
for (size_t k = i; k < j; k++) {
|
||||||
fprintf(stderr, " %lld,%lld", geom[k].x, geom[k].y);
|
fprintf(stderr, " %lld,%lld", geom[k].x, geom[k].y);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@ -392,9 +388,9 @@ void check_polygon(drawvec &geom) {
|
|||||||
drawvec close_poly(drawvec &geom) {
|
drawvec close_poly(drawvec &geom) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -407,7 +403,7 @@ drawvec close_poly(drawvec &geom) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned n = i; n < j - 1; n++) {
|
for (size_t n = i; n < j - 1; n++) {
|
||||||
out.push_back(geom[n]);
|
out.push_back(geom[n]);
|
||||||
}
|
}
|
||||||
out.push_back(draw(VT_CLOSEPATH, 0, 0));
|
out.push_back(draw(VT_CLOSEPATH, 0, 0));
|
||||||
@ -486,7 +482,7 @@ static drawvec clip_poly1(drawvec &geom, long long minx, long long miny, long lo
|
|||||||
|
|
||||||
draw S = in[in.size() - 1];
|
draw S = in[in.size() - 1];
|
||||||
|
|
||||||
for (unsigned e = 0; e < in.size(); e++) {
|
for (size_t e = 0; e < in.size(); e++) {
|
||||||
draw E = in[e];
|
draw E = in[e];
|
||||||
|
|
||||||
if (inside(E, edge, minx, miny, maxx, maxy)) {
|
if (inside(E, edge, minx, miny, maxx, maxy)) {
|
||||||
@ -520,7 +516,7 @@ static drawvec clip_poly1(drawvec &geom, long long minx, long long miny, long lo
|
|||||||
}
|
}
|
||||||
|
|
||||||
out[0].op = VT_MOVETO;
|
out[0].op = VT_MOVETO;
|
||||||
for (unsigned i = 1; i < out.size(); i++) {
|
for (size_t i = 1; i < out.size(); i++) {
|
||||||
out[i].op = VT_LINETO;
|
out[i].op = VT_LINETO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,9 +527,9 @@ static drawvec clip_poly1(drawvec &geom, long long minx, long long miny, long lo
|
|||||||
drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long long maxx, long long maxy) {
|
drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long long maxx, long long maxy) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -541,7 +537,7 @@ drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long lon
|
|||||||
}
|
}
|
||||||
|
|
||||||
drawvec tmp;
|
drawvec tmp;
|
||||||
for (unsigned k = i; k < j; k++) {
|
for (size_t k = i; k < j; k++) {
|
||||||
tmp.push_back(geom[k]);
|
tmp.push_back(geom[k]);
|
||||||
}
|
}
|
||||||
tmp = clip_poly1(tmp, minx, miny, maxx, maxy);
|
tmp = clip_poly1(tmp, minx, miny, maxx, maxy);
|
||||||
@ -551,7 +547,7 @@ drawvec simple_clip_poly(drawvec &geom, long long minx, long long miny, long lon
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned k = 0; k < tmp.size(); k++) {
|
for (size_t k = 0; k < tmp.size(); k++) {
|
||||||
out.push_back(tmp[k]);
|
out.push_back(tmp[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,9 +579,9 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
*reduced = true;
|
*reduced = true;
|
||||||
bool included_last_outer = false;
|
bool included_last_outer = false;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -593,7 +589,7 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
}
|
}
|
||||||
|
|
||||||
double area = 0;
|
double area = 0;
|
||||||
for (unsigned k = i; k < j; k++) {
|
for (size_t k = i; k < j; k++) {
|
||||||
area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y;
|
area += (long double) geom[k].x * (long double) geom[i + ((k - i + 1) % (j - i))].y;
|
||||||
area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x;
|
area -= (long double) geom[k].y * (long double) geom[i + ((k - i + 1) % (j - i))].x;
|
||||||
}
|
}
|
||||||
@ -632,7 +628,7 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
} else {
|
} else {
|
||||||
// printf("area is %f so keeping instead of %lld\n", area, pixel * pixel);
|
// printf("area is %f so keeping instead of %lld\n", area, pixel * pixel);
|
||||||
|
|
||||||
for (unsigned k = i; k <= j && k < geom.size(); k++) {
|
for (size_t k = i; k <= j && k < geom.size(); k++) {
|
||||||
out.push_back(geom[k]);
|
out.push_back(geom[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +644,7 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "how did we get here with %d in %d?\n", geom[i].op, (int) geom.size());
|
fprintf(stderr, "how did we get here with %d in %d?\n", geom[i].op, (int) geom.size());
|
||||||
|
|
||||||
for (unsigned n = 0; n < geom.size(); n++) {
|
for (size_t n = 0; n < geom.size(); n++) {
|
||||||
fprintf(stderr, "%d/%lld/%lld ", geom[n].op, geom[n].x, geom[n].y);
|
fprintf(stderr, "%d/%lld/%lld ", geom[n].op, geom[n].x, geom[n].y);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@ -662,7 +658,6 @@ drawvec reduce_tiny_poly(drawvec &geom, int z, int detail, bool *reduced, double
|
|||||||
|
|
||||||
drawvec clip_point(drawvec &geom, int z, int detail, long long buffer) {
|
drawvec clip_point(drawvec &geom, int z, int detail, long long buffer) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
long long min = 0;
|
long long min = 0;
|
||||||
long long area = 0xFFFFFFFF;
|
long long area = 0xFFFFFFFF;
|
||||||
@ -673,7 +668,7 @@ drawvec clip_point(drawvec &geom, int z, int detail, long long buffer) {
|
|||||||
area += buffer * area / 256;
|
area += buffer * area / 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].x >= min && geom[i].y >= min && geom[i].x <= area && geom[i].y <= area) {
|
if (geom[i].x >= min && geom[i].y >= min && geom[i].x <= area && geom[i].y <= area) {
|
||||||
out.push_back(geom[i]);
|
out.push_back(geom[i]);
|
||||||
}
|
}
|
||||||
@ -711,7 +706,6 @@ int quick_check(long long *bbox, int z, int detail, long long buffer) {
|
|||||||
|
|
||||||
drawvec clip_lines(drawvec &geom, int z, int detail, long long buffer) {
|
drawvec clip_lines(drawvec &geom, int z, int detail, long long buffer) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
long long min = 0;
|
long long min = 0;
|
||||||
long long area = 0xFFFFFFFF;
|
long long area = 0xFFFFFFFF;
|
||||||
@ -722,7 +716,7 @@ drawvec clip_lines(drawvec &geom, int z, int detail, long long buffer) {
|
|||||||
area += buffer * area / 256;
|
area += buffer * area / 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) {
|
if (i > 0 && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO) && geom[i].op == VT_LINETO) {
|
||||||
double x1 = geom[i - 1].x;
|
double x1 = geom[i - 1].x;
|
||||||
double y1 = geom[i - 1].y;
|
double y1 = geom[i - 1].y;
|
||||||
@ -834,7 +828,7 @@ static void douglas_peucker(drawvec &geom, int start, int n, double e) {
|
|||||||
drawvec impose_tile_boundaries(drawvec &geom, long long extent) {
|
drawvec impose_tile_boundaries(drawvec &geom, long long extent) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (i > 0 && geom[i].op == VT_LINETO && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO)) {
|
if (i > 0 && geom[i].op == VT_LINETO && (geom[i - 1].op == VT_MOVETO || geom[i - 1].op == VT_LINETO)) {
|
||||||
double x1 = geom[i - 1].x;
|
double x1 = geom[i - 1].x;
|
||||||
double y1 = geom[i - 1].y;
|
double y1 = geom[i - 1].y;
|
||||||
@ -869,8 +863,7 @@ drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
|||||||
area = 1LL << (32 - z);
|
area = 1LL << (32 - z);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i;
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
for (i = 0; i < geom.size(); i++) {
|
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
geom[i].necessary = 1;
|
geom[i].necessary = 1;
|
||||||
} else if (geom[i].op == VT_LINETO) {
|
} else if (geom[i].op == VT_LINETO) {
|
||||||
@ -882,9 +875,9 @@ drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
|||||||
|
|
||||||
geom = impose_tile_boundaries(geom, area);
|
geom = impose_tile_boundaries(geom, area);
|
||||||
|
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -900,7 +893,7 @@ drawvec simplify_lines(drawvec &geom, int z, int detail) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drawvec out;
|
drawvec out;
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
if (geom[i].necessary) {
|
if (geom[i].necessary) {
|
||||||
out.push_back(geom[i]);
|
out.push_back(geom[i]);
|
||||||
}
|
}
|
||||||
@ -916,8 +909,7 @@ drawvec reorder_lines(drawvec &geom) {
|
|||||||
return geom;
|
return geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i;
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
for (i = 0; i < geom.size(); i++) {
|
|
||||||
if (geom[i].op == VT_MOVETO) {
|
if (geom[i].op == VT_MOVETO) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
return geom;
|
return geom;
|
||||||
@ -940,7 +932,7 @@ drawvec reorder_lines(drawvec &geom) {
|
|||||||
|
|
||||||
if (l1 > l2) {
|
if (l1 > l2) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
for (i = 0; i < geom.size(); i++) {
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
out.push_back(geom[geom.size() - 1 - i]);
|
out.push_back(geom[geom.size() - 1 - i]);
|
||||||
}
|
}
|
||||||
out[0].op = VT_MOVETO;
|
out[0].op = VT_MOVETO;
|
||||||
@ -955,14 +947,13 @@ drawvec fix_polygon(drawvec &geom) {
|
|||||||
int outer = 1;
|
int outer = 1;
|
||||||
drawvec out;
|
drawvec out;
|
||||||
|
|
||||||
unsigned i;
|
for (size_t i = 0; i < geom.size(); i++) {
|
||||||
for (i = 0; i < geom.size(); i++) {
|
|
||||||
if (geom[i].op == VT_CLOSEPATH) {
|
if (geom[i].op == VT_CLOSEPATH) {
|
||||||
outer = 1;
|
outer = 1;
|
||||||
} else if (geom[i].op == VT_MOVETO) {
|
} else if (geom[i].op == VT_MOVETO) {
|
||||||
// Find the end of the ring
|
// Find the end of the ring
|
||||||
|
|
||||||
unsigned j;
|
size_t j;
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[j].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
@ -973,7 +964,7 @@ drawvec fix_polygon(drawvec &geom) {
|
|||||||
// Close it if it isn't closed.
|
// Close it if it isn't closed.
|
||||||
|
|
||||||
drawvec ring;
|
drawvec ring;
|
||||||
for (unsigned a = i; a < j; a++) {
|
for (size_t a = i; a < j; a++) {
|
||||||
ring.push_back(geom[a]);
|
ring.push_back(geom[a]);
|
||||||
}
|
}
|
||||||
if (j - i != 0 && (ring[0].x != ring[j - i - 1].x || ring[0].y != ring[j - i - 1].y)) {
|
if (j - i != 0 && (ring[0].x != ring[j - i - 1].x || ring[0].y != ring[j - i - 1].y)) {
|
||||||
@ -984,7 +975,7 @@ drawvec fix_polygon(drawvec &geom) {
|
|||||||
// inner/outer expectation
|
// inner/outer expectation
|
||||||
|
|
||||||
double area = 0;
|
double area = 0;
|
||||||
for (unsigned k = 0; k < ring.size(); k++) {
|
for (size_t k = 0; k < ring.size(); k++) {
|
||||||
area += (long double) ring[k].x * (long double) ring[(k + 1) % ring.size()].y;
|
area += (long double) ring[k].x * (long double) ring[(k + 1) % ring.size()].y;
|
||||||
area -= (long double) ring[k].y * (long double) ring[(k + 1) % ring.size()].x;
|
area -= (long double) ring[k].y * (long double) ring[(k + 1) % ring.size()].x;
|
||||||
}
|
}
|
||||||
@ -1000,7 +991,7 @@ drawvec fix_polygon(drawvec &geom) {
|
|||||||
// Copy ring into output, fixing the moveto/lineto ops if necessary because of
|
// Copy ring into output, fixing the moveto/lineto ops if necessary because of
|
||||||
// reversal or closing
|
// reversal or closing
|
||||||
|
|
||||||
for (unsigned a = 0; a < ring.size(); a++) {
|
for (size_t a = 0; a < ring.size(); a++) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
out.push_back(draw(VT_MOVETO, ring[a].x, ring[a].y));
|
out.push_back(draw(VT_MOVETO, ring[a].x, ring[a].y));
|
||||||
} else {
|
} else {
|
||||||
@ -1027,7 +1018,7 @@ std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms) {
|
|||||||
bool again = false;
|
bool again = false;
|
||||||
std::vector<drawvec> out;
|
std::vector<drawvec> out;
|
||||||
|
|
||||||
for (unsigned i = 0; i < geoms.size(); i++) {
|
for (size_t i = 0; i < geoms.size(); i++) {
|
||||||
if (geoms[i].size() > 700) {
|
if (geoms[i].size() > 700) {
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
if (!warned) {
|
if (!warned) {
|
||||||
@ -1038,7 +1029,7 @@ std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms) {
|
|||||||
long long midx = 0, midy = 0, count = 0;
|
long long midx = 0, midy = 0, count = 0;
|
||||||
long long maxx = LLONG_MIN, maxy = LLONG_MIN, minx = LLONG_MAX, miny = LLONG_MAX;
|
long long maxx = LLONG_MIN, maxy = LLONG_MIN, minx = LLONG_MAX, miny = LLONG_MAX;
|
||||||
|
|
||||||
for (unsigned j = 0; j < geoms[i].size(); j++) {
|
for (size_t j = 0; j < geoms[i].size(); j++) {
|
||||||
if (geoms[i][j].op == VT_MOVETO || geoms[i][j].op == VT_LINETO) {
|
if (geoms[i][j].op == VT_MOVETO || geoms[i][j].op == VT_LINETO) {
|
||||||
midx += geoms[i][j].x;
|
midx += geoms[i][j].x;
|
||||||
midy += geoms[i][j].y;
|
midy += geoms[i][j].y;
|
||||||
|
93
jsonpull.c
93
jsonpull.c
@ -8,8 +8,12 @@
|
|||||||
|
|
||||||
#define BUFFER 10000
|
#define BUFFER 10000
|
||||||
|
|
||||||
json_pull *json_begin(int (*read)(struct json_pull *, char *buffer, int n), void *source) {
|
json_pull *json_begin(ssize_t (*read)(struct json_pull *, char *buffer, size_t n), void *source) {
|
||||||
json_pull *j = malloc(sizeof(json_pull));
|
json_pull *j = malloc(sizeof(json_pull));
|
||||||
|
if (j == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
j->error = NULL;
|
j->error = NULL;
|
||||||
j->line = 1;
|
j->line = 1;
|
||||||
@ -18,10 +22,15 @@ json_pull *json_begin(int (*read)(struct json_pull *, char *buffer, int n), void
|
|||||||
|
|
||||||
j->read = read;
|
j->read = read;
|
||||||
j->source = source;
|
j->source = source;
|
||||||
j->buffer = malloc(BUFFER);
|
|
||||||
j->buffer_head = 0;
|
j->buffer_head = 0;
|
||||||
j->buffer_tail = 0;
|
j->buffer_tail = 0;
|
||||||
|
|
||||||
|
j->buffer = malloc(BUFFER);
|
||||||
|
if (j->buffer == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +60,7 @@ static inline int next(json_pull *j) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_file(json_pull *j, char *buffer, int n) {
|
static ssize_t read_file(json_pull *j, char *buffer, size_t n) {
|
||||||
return fread(buffer, 1, n, j->source);
|
return fread(buffer, 1, n, j->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +68,7 @@ json_pull *json_begin_file(FILE *f) {
|
|||||||
return json_begin(read_file, f);
|
return json_begin(read_file, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_string(json_pull *j, char *buffer, int n) {
|
static ssize_t read_string(json_pull *j, char *buffer, size_t n) {
|
||||||
char *cp = j->source;
|
char *cp = j->source;
|
||||||
int out = 0;
|
int out = 0;
|
||||||
|
|
||||||
@ -91,10 +100,14 @@ static inline int read_wrap(json_pull *j) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SIZE_FOR(i) (((i) + 31) & ~31)
|
#define SIZE_FOR(i, size) ((size_t)((((i) + 31) & ~31) * size))
|
||||||
|
|
||||||
static json_object *fabricate_object(json_object *parent, json_type type) {
|
static json_object *fabricate_object(json_object *parent, json_type type) {
|
||||||
json_object *o = malloc(sizeof(struct json_object));
|
json_object *o = malloc(sizeof(struct json_object));
|
||||||
|
if (o == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
o->type = type;
|
o->type = type;
|
||||||
o->parent = parent;
|
o->parent = parent;
|
||||||
o->array = NULL;
|
o->array = NULL;
|
||||||
@ -111,8 +124,16 @@ static json_object *add_object(json_pull *j, json_type type) {
|
|||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
if (c->type == JSON_ARRAY) {
|
if (c->type == JSON_ARRAY) {
|
||||||
if (c->expect == JSON_ITEM) {
|
if (c->expect == JSON_ITEM) {
|
||||||
if (SIZE_FOR(c->length + 1) != SIZE_FOR(c->length)) {
|
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) != SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||||
c->array = realloc(c->array, SIZE_FOR(c->length + 1) * sizeof(json_object *));
|
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) < SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||||
|
fprintf(stderr, "Array size overflow\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
c->array = realloc(c->array, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||||
|
if (c->array == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c->array[c->length++] = o;
|
c->array[c->length++] = o;
|
||||||
@ -133,9 +154,17 @@ static json_object *add_object(json_pull *j, json_type type) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SIZE_FOR(c->length + 1) != SIZE_FOR(c->length)) {
|
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) != SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||||
c->keys = realloc(c->keys, SIZE_FOR(c->length + 1) * sizeof(json_object *));
|
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) < SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||||
c->values = realloc(c->values, SIZE_FOR(c->length + 1) * sizeof(json_object *));
|
fprintf(stderr, "Hash size overflow\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
c->keys = realloc(c->keys, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||||
|
c->values = realloc(c->values, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||||
|
if (c->keys == NULL || c->values == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c->keys[c->length] = o;
|
c->keys[c->length] = o;
|
||||||
@ -160,7 +189,7 @@ json_object *json_hash_get(json_object *o, const char *s) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < o->length; i++) {
|
for (i = 0; i < o->length; i++) {
|
||||||
if (o->keys[i] != NULL && o->keys[i]->type == JSON_STRING) {
|
if (o->keys[i] != NULL && o->keys[i]->type == JSON_STRING) {
|
||||||
if (strcmp(o->keys[i]->string, s) == 0) {
|
if (strcmp(o->keys[i]->string, s) == 0) {
|
||||||
@ -174,21 +203,34 @@ json_object *json_hash_get(json_object *o, const char *s) {
|
|||||||
|
|
||||||
struct string {
|
struct string {
|
||||||
char *buf;
|
char *buf;
|
||||||
int n;
|
size_t n;
|
||||||
int nalloc;
|
size_t nalloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void string_init(struct string *s) {
|
static void string_init(struct string *s) {
|
||||||
s->nalloc = 500;
|
s->nalloc = 500;
|
||||||
s->buf = malloc(s->nalloc);
|
s->buf = malloc(s->nalloc);
|
||||||
|
if (s->buf == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
s->n = 0;
|
s->n = 0;
|
||||||
s->buf[0] = '\0';
|
s->buf[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void string_append(struct string *s, char c) {
|
static void string_append(struct string *s, char c) {
|
||||||
if (s->n + 2 >= s->nalloc) {
|
if (s->n + 2 >= s->nalloc) {
|
||||||
|
size_t prev = s->nalloc;
|
||||||
s->nalloc += 500;
|
s->nalloc += 500;
|
||||||
|
if (s->nalloc <= prev) {
|
||||||
|
fprintf(stderr, "String size overflowed\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
s->buf = realloc(s->buf, s->nalloc);
|
s->buf = realloc(s->buf, s->nalloc);
|
||||||
|
if (s->buf == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->buf[s->n++] = c;
|
s->buf[s->n++] = c;
|
||||||
@ -196,11 +238,20 @@ static void string_append(struct string *s, char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void string_append_string(struct string *s, char *add) {
|
static void string_append_string(struct string *s, char *add) {
|
||||||
int len = strlen(add);
|
size_t len = strlen(add);
|
||||||
|
|
||||||
if (s->n + len + 1 >= s->nalloc) {
|
if (s->n + len + 1 >= s->nalloc) {
|
||||||
|
size_t prev = s->nalloc;
|
||||||
s->nalloc += 500 + len;
|
s->nalloc += 500 + len;
|
||||||
|
if (s->nalloc <= prev) {
|
||||||
|
fprintf(stderr, "String size overflowed\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
s->buf = realloc(s->buf, s->nalloc);
|
s->buf = realloc(s->buf, s->nalloc);
|
||||||
|
if (s->buf == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; *add != '\0'; add++) {
|
for (; *add != '\0'; add++) {
|
||||||
@ -541,7 +592,7 @@ json_object *json_read_tree(json_pull *p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void json_free(json_object *o) {
|
void json_free(json_object *o) {
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
if (o == NULL) {
|
if (o == NULL) {
|
||||||
return;
|
return;
|
||||||
@ -551,7 +602,7 @@ void json_free(json_object *o) {
|
|||||||
|
|
||||||
if (o->type == JSON_ARRAY) {
|
if (o->type == JSON_ARRAY) {
|
||||||
json_object **a = o->array;
|
json_object **a = o->array;
|
||||||
int n = o->length;
|
size_t n = o->length;
|
||||||
|
|
||||||
o->array = NULL;
|
o->array = NULL;
|
||||||
o->length = 0;
|
o->length = 0;
|
||||||
@ -564,7 +615,7 @@ void json_free(json_object *o) {
|
|||||||
} else if (o->type == JSON_HASH) {
|
} else if (o->type == JSON_HASH) {
|
||||||
json_object **k = o->keys;
|
json_object **k = o->keys;
|
||||||
json_object **v = o->values;
|
json_object **v = o->values;
|
||||||
int n = o->length;
|
size_t n = o->length;
|
||||||
|
|
||||||
o->keys = NULL;
|
o->keys = NULL;
|
||||||
o->values = NULL;
|
o->values = NULL;
|
||||||
@ -592,7 +643,7 @@ void json_disconnect(json_object *o) {
|
|||||||
|
|
||||||
if (o->parent != NULL) {
|
if (o->parent != NULL) {
|
||||||
if (o->parent->type == JSON_ARRAY) {
|
if (o->parent->type == JSON_ARRAY) {
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < o->parent->length; i++) {
|
for (i = 0; i < o->parent->length; i++) {
|
||||||
if (o->parent->array[i] == o) {
|
if (o->parent->array[i] == o) {
|
||||||
@ -607,7 +658,7 @@ void json_disconnect(json_object *o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o->parent->type == JSON_HASH) {
|
if (o->parent->type == JSON_HASH) {
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < o->parent->length; i++) {
|
for (i = 0; i < o->parent->length; i++) {
|
||||||
if (o->parent->keys[i] == o) {
|
if (o->parent->keys[i] == o) {
|
||||||
@ -683,7 +734,7 @@ static void json_print(struct string *val, json_object *o) {
|
|||||||
} else if (o->type == JSON_HASH) {
|
} else if (o->type == JSON_HASH) {
|
||||||
string_append(val, '{');
|
string_append(val, '{');
|
||||||
|
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < o->length; i++) {
|
for (i = 0; i < o->length; i++) {
|
||||||
json_print(val, o->keys[i]);
|
json_print(val, o->keys[i]);
|
||||||
string_append(val, ':');
|
string_append(val, ':');
|
||||||
@ -695,7 +746,7 @@ static void json_print(struct string *val, json_object *o) {
|
|||||||
string_append(val, '}');
|
string_append(val, '}');
|
||||||
} else if (o->type == JSON_ARRAY) {
|
} else if (o->type == JSON_ARRAY) {
|
||||||
string_append(val, '[');
|
string_append(val, '[');
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < o->length; i++) {
|
for (i = 0; i < o->length; i++) {
|
||||||
json_print(val, o->array[i]);
|
json_print(val, o->array[i]);
|
||||||
if (i + 1 < o->length) {
|
if (i + 1 < o->length) {
|
||||||
|
10
jsonpull.h
10
jsonpull.h
@ -28,7 +28,7 @@ typedef struct json_object {
|
|||||||
struct json_object **array;
|
struct json_object **array;
|
||||||
struct json_object **keys;
|
struct json_object **keys;
|
||||||
struct json_object **values;
|
struct json_object **values;
|
||||||
int length;
|
size_t length;
|
||||||
|
|
||||||
int expect;
|
int expect;
|
||||||
} json_object;
|
} json_object;
|
||||||
@ -37,11 +37,11 @@ typedef struct json_pull {
|
|||||||
char *error;
|
char *error;
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
int (*read)(struct json_pull *, char *buf, int n);
|
ssize_t (*read)(struct json_pull *, char *buf, size_t n);
|
||||||
void *source;
|
void *source;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int buffer_tail;
|
ssize_t buffer_tail;
|
||||||
int buffer_head;
|
ssize_t buffer_head;
|
||||||
|
|
||||||
json_object *container;
|
json_object *container;
|
||||||
json_object *root;
|
json_object *root;
|
||||||
@ -50,7 +50,7 @@ typedef struct json_pull {
|
|||||||
json_pull *json_begin_file(FILE *f);
|
json_pull *json_begin_file(FILE *f);
|
||||||
json_pull *json_begin_string(char *s);
|
json_pull *json_begin_string(char *s);
|
||||||
|
|
||||||
json_pull *json_begin(int (*read)(struct json_pull *, char *buffer, int n), void *source);
|
json_pull *json_begin(ssize_t (*read)(struct json_pull *, char *buffer, size_t n), void *source);
|
||||||
void json_end(json_pull *p);
|
void json_end(json_pull *p);
|
||||||
|
|
||||||
typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state);
|
typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state);
|
||||||
|
@ -118,6 +118,10 @@ static void aprintf(char **buf, const char *format, ...) {
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
*buf = realloc(*buf, strlen(*buf) + strlen(tmp) + 1);
|
*buf = realloc(*buf, strlen(*buf) + strlen(tmp) + 1);
|
||||||
|
if (*buf == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
strcat(*buf, tmp);
|
strcat(*buf, tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
@ -219,6 +223,10 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, char **layername,
|
|||||||
sqlite3_free(sql);
|
sqlite3_free(sql);
|
||||||
|
|
||||||
char *buf = strdup("{");
|
char *buf = strdup("{");
|
||||||
|
if (buf == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
aprintf(&buf, "\"vector_layers\": [ ");
|
aprintf(&buf, "\"vector_layers\": [ ");
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
61
tile-join.cc
61
tile-join.cc
@ -141,6 +141,10 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
|
|
||||||
pool_init(&((*file_keys)[ll]), 0);
|
pool_init(&((*file_keys)[ll]), 0);
|
||||||
(*layernames)[ll] = strdup(ln);
|
(*layernames)[ll] = strdup(ln);
|
||||||
|
if ((*layernames)[ll] == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
*nlayers = ll + 1;
|
*nlayers = ll + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +165,10 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
|
|
||||||
if (val.has_string_value()) {
|
if (val.has_string_value()) {
|
||||||
value = strdup(val.string_value().c_str());
|
value = strdup(val.string_value().c_str());
|
||||||
|
if (value == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
type = VT_STRING;
|
type = VT_STRING;
|
||||||
} else if (val.has_int_value()) {
|
} else if (val.has_int_value()) {
|
||||||
if (asprintf(&value, "%lld", (long long) val.int_value()) >= 0) {
|
if (asprintf(&value, "%lld", (long long) val.int_value()) >= 0) {
|
||||||
@ -196,7 +204,12 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
|
|
||||||
if (!is_pooled(exclude, key, VT_STRING)) {
|
if (!is_pooled(exclude, key, VT_STRING)) {
|
||||||
if (!is_pooled(&((*file_keys)[ll]), key, type)) {
|
if (!is_pooled(&((*file_keys)[ll]), key, type)) {
|
||||||
pool(&((*file_keys)[ll]), strdup(key), type);
|
char *copy = strdup(key);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
pool(&((*file_keys)[ll]), copy, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pool_val *k, *v;
|
struct pool_val *k, *v;
|
||||||
@ -204,13 +217,23 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
if (is_pooled(&keys, key, VT_STRING)) {
|
if (is_pooled(&keys, key, VT_STRING)) {
|
||||||
k = pool(&keys, key, VT_STRING);
|
k = pool(&keys, key, VT_STRING);
|
||||||
} else {
|
} else {
|
||||||
k = pool(&keys, strdup(key), VT_STRING);
|
char *copy = strdup(key);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
k = pool(&keys, copy, VT_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_pooled(&values, value, type)) {
|
if (is_pooled(&values, value, type)) {
|
||||||
v = pool(&values, value, type);
|
v = pool(&values, value, type);
|
||||||
} else {
|
} else {
|
||||||
v = pool(&values, strdup(value), type);
|
char *copy = strdup(value);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
v = pool(&values, copy, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
feature_tags.push_back(k->n);
|
feature_tags.push_back(k->n);
|
||||||
@ -224,7 +247,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
std::vector<std::string> fields = ii->second;
|
std::vector<std::string> fields = ii->second;
|
||||||
matched = 1;
|
matched = 1;
|
||||||
|
|
||||||
for (unsigned i = 1; i < fields.size(); i++) {
|
for (size_t i = 1; i < fields.size(); i++) {
|
||||||
std::string joinkey = header[i];
|
std::string joinkey = header[i];
|
||||||
std::string joinval = fields[i];
|
std::string joinval = fields[i];
|
||||||
int type = VT_STRING;
|
int type = VT_STRING;
|
||||||
@ -242,7 +265,12 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
|
|
||||||
if (!is_pooled(exclude, sjoinkey, VT_STRING)) {
|
if (!is_pooled(exclude, sjoinkey, VT_STRING)) {
|
||||||
if (!is_pooled(&((*file_keys)[ll]), sjoinkey, type)) {
|
if (!is_pooled(&((*file_keys)[ll]), sjoinkey, type)) {
|
||||||
pool(&((*file_keys)[ll]), strdup(sjoinkey), type);
|
char *copy = strdup(sjoinkey);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
pool(&((*file_keys)[ll]), copy, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pool_val *k, *v;
|
struct pool_val *k, *v;
|
||||||
@ -250,13 +278,23 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
if (is_pooled(&keys, sjoinkey, VT_STRING)) {
|
if (is_pooled(&keys, sjoinkey, VT_STRING)) {
|
||||||
k = pool(&keys, sjoinkey, VT_STRING);
|
k = pool(&keys, sjoinkey, VT_STRING);
|
||||||
} else {
|
} else {
|
||||||
k = pool(&keys, strdup(sjoinkey), VT_STRING);
|
char *copy = strdup(sjoinkey);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
k = pool(&keys, copy, VT_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_pooled(&values, sjoinval, type)) {
|
if (is_pooled(&values, sjoinval, type)) {
|
||||||
v = pool(&values, sjoinval, type);
|
v = pool(&values, sjoinval, type);
|
||||||
} else {
|
} else {
|
||||||
v = pool(&values, strdup(sjoinval), type);
|
char *copy = strdup(sjoinval);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
v = pool(&values, copy, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
feature_tags.push_back(k->n);
|
feature_tags.push_back(k->n);
|
||||||
@ -277,7 +315,7 @@ void handle(std::string message, int z, unsigned x, unsigned y, struct pool **fi
|
|||||||
outfeature->add_geometry(feat.geometry(g));
|
outfeature->add_geometry(feat.geometry(g));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature_tags.size(); i++) {
|
for (size_t i = 0; i < feature_tags.size(); i++) {
|
||||||
outfeature->add_tags(feature_tags[i]);
|
outfeature->add_tags(feature_tags[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,8 +485,7 @@ std::vector<std::string> split(char *s) {
|
|||||||
|
|
||||||
std::string dequote(std::string s) {
|
std::string dequote(std::string s) {
|
||||||
std::string out;
|
std::string out;
|
||||||
unsigned i;
|
for (size_t i = 0; i < s.size(); i++) {
|
||||||
for (i = 0; i < s.size(); i++) {
|
|
||||||
if (s[i] == '"') {
|
if (s[i] == '"') {
|
||||||
if (i + 1 < s.size() && s[i + 1] == '"') {
|
if (i + 1 < s.size() && s[i + 1] == '"') {
|
||||||
out.push_back('"');
|
out.push_back('"');
|
||||||
@ -471,7 +508,7 @@ void readcsv(char *fn, std::vector<std::string> &header, std::map<std::string, s
|
|||||||
if (fgets(s, MAXLINE, f)) {
|
if (fgets(s, MAXLINE, f)) {
|
||||||
header = split(s);
|
header = split(s);
|
||||||
|
|
||||||
for (unsigned i = 0; i < header.size(); i++) {
|
for (size_t i = 0; i < header.size(); i++) {
|
||||||
header[i] = dequote(header[i]);
|
header[i] = dequote(header[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,7 +518,7 @@ void readcsv(char *fn, std::vector<std::string> &header, std::map<std::string, s
|
|||||||
line[0] = dequote(line[0]);
|
line[0] = dequote(line[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < line.size() && i < header.size(); i++) {
|
for (size_t i = 0; i < line.size() && i < header.size(); i++) {
|
||||||
// printf("putting %s\n", line[0].c_str());
|
// printf("putting %s\n", line[0].c_str());
|
||||||
mapping.insert(std::pair<std::string, std::vector<std::string> >(line[0], line));
|
mapping.insert(std::pair<std::string, std::vector<std::string> >(line[0], line));
|
||||||
}
|
}
|
||||||
|
62
tile.cc
62
tile.cc
@ -165,8 +165,7 @@ int coalcmp(const void *v1, const void *v2) {
|
|||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i;
|
for (size_t i = 0; i < c1->meta.size() && i < c2->meta.size(); i++) {
|
||||||
for (i = 0; i < c1->meta.size() && i < c2->meta.size(); i++) {
|
|
||||||
cmp = c1->meta[i] - c2->meta[i];
|
cmp = c1->meta[i] - c2->meta[i];
|
||||||
|
|
||||||
if (cmp != 0) {
|
if (cmp != 0) {
|
||||||
@ -232,7 +231,12 @@ void decode_meta(char **meta, char *stringpool, struct pool *keys, struct pool *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dup to retain after munmap
|
// Dup to retain after munmap
|
||||||
pool(file_keys, strdup(key->s), value->type);
|
char *copy = strdup(key->s);
|
||||||
|
if (copy == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
pool(file_keys, copy, value->type);
|
||||||
|
|
||||||
if (pthread_mutex_unlock(&var_lock) != 0) {
|
if (pthread_mutex_unlock(&var_lock) != 0) {
|
||||||
perror("pthread_mutex_unlock");
|
perror("pthread_mutex_unlock");
|
||||||
@ -288,8 +292,7 @@ mapnik::vector::tile create_tile(char **layernames, int line_detail, std::vector
|
|||||||
layer->set_version(1);
|
layer->set_version(1);
|
||||||
layer->set_extent(1 << line_detail);
|
layer->set_extent(1 << line_detail);
|
||||||
|
|
||||||
unsigned x;
|
for (size_t x = 0; x < features[i].size(); x++) {
|
||||||
for (x = 0; x < features[i].size(); x++) {
|
|
||||||
if (features[i][x].type == VT_LINE || features[i][x].type == VT_POLYGON) {
|
if (features[i][x].type == VT_LINE || features[i][x].type == VT_POLYGON) {
|
||||||
features[i][x].geom = remove_noop(features[i][x].geom, features[i][x].type, 0);
|
features[i][x].geom = remove_noop(features[i][x].geom, features[i][x].type, 0);
|
||||||
}
|
}
|
||||||
@ -309,8 +312,7 @@ mapnik::vector::tile create_tile(char **layernames, int line_detail, std::vector
|
|||||||
to_feature(features[i][x].geom, feature);
|
to_feature(features[i][x].geom, feature);
|
||||||
*count += features[i][x].geom.size();
|
*count += features[i][x].geom.size();
|
||||||
|
|
||||||
unsigned y;
|
for (size_t y = 0; y < features[i][x].meta.size(); y++) {
|
||||||
for (y = 0; y < features[i][x].meta.size(); y++) {
|
|
||||||
feature->add_tags(features[i][x].meta[y]);
|
feature->add_tags(features[i][x].meta[y]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,7 +449,7 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
|||||||
serialize_long_long(geomfile[j], metastart, &geompos[j], fname);
|
serialize_long_long(geomfile[j], metastart, &geompos[j], fname);
|
||||||
long long wx = initial_x[segment], wy = initial_y[segment];
|
long long wx = initial_x[segment], wy = initial_y[segment];
|
||||||
|
|
||||||
for (unsigned u = 0; u < geom.size(); u++) {
|
for (size_t u = 0; u < geom.size(); u++) {
|
||||||
serialize_byte(geomfile[j], geom[u].op, &geompos[j], fname);
|
serialize_byte(geomfile[j], geom[u].op, &geompos[j], fname);
|
||||||
|
|
||||||
if (geom[u].op != VT_CLOSEPATH) {
|
if (geom[u].op != VT_CLOSEPATH) {
|
||||||
@ -478,8 +480,8 @@ struct partial {
|
|||||||
unsigned long long index2;
|
unsigned long long index2;
|
||||||
int z;
|
int z;
|
||||||
int line_detail;
|
int line_detail;
|
||||||
char *prevent;
|
int *prevent;
|
||||||
char *additional;
|
int *additional;
|
||||||
int maxzoom;
|
int maxzoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -493,14 +495,14 @@ void *partial_feature_worker(void *v) {
|
|||||||
struct partial_arg *a = (struct partial_arg *) v;
|
struct partial_arg *a = (struct partial_arg *) v;
|
||||||
std::vector<struct partial> *partials = a->partials;
|
std::vector<struct partial> *partials = a->partials;
|
||||||
|
|
||||||
for (unsigned i = a->task; i < (*partials).size(); i += a->tasks) {
|
for (size_t i = a->task; i < (*partials).size(); i += a->tasks) {
|
||||||
drawvec geom = (*partials)[i].geoms[0]; // XXX assumption of a single geometry at the beginning
|
drawvec geom = (*partials)[i].geoms[0]; // XXX assumption of a single geometry at the beginning
|
||||||
(*partials)[i].geoms.clear(); // avoid keeping two copies in memory
|
(*partials)[i].geoms.clear(); // avoid keeping two copies in memory
|
||||||
signed char t = (*partials)[i].t;
|
signed char t = (*partials)[i].t;
|
||||||
int z = (*partials)[i].z;
|
int z = (*partials)[i].z;
|
||||||
int line_detail = (*partials)[i].line_detail;
|
int line_detail = (*partials)[i].line_detail;
|
||||||
char *prevent = (*partials)[i].prevent;
|
int *prevent = (*partials)[i].prevent;
|
||||||
char *additional = (*partials)[i].additional;
|
int *additional = (*partials)[i].additional;
|
||||||
int maxzoom = (*partials)[i].maxzoom;
|
int maxzoom = (*partials)[i].maxzoom;
|
||||||
|
|
||||||
if ((t == VT_LINE || t == VT_POLYGON) && !(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]))) {
|
if ((t == VT_LINE || t == VT_POLYGON) && !(prevent[P_SIMPLIFY] || (z == maxzoom && prevent[P_SIMPLIFY_LOW]))) {
|
||||||
@ -535,7 +537,7 @@ void *partial_feature_worker(void *v) {
|
|||||||
if (t == VT_POLYGON) {
|
if (t == VT_POLYGON) {
|
||||||
// Scaling may have made the polygon degenerate.
|
// Scaling may have made the polygon degenerate.
|
||||||
// Give Clipper a chance to try to fix it.
|
// Give Clipper a chance to try to fix it.
|
||||||
for (unsigned i = 0; i < geoms.size(); i++) {
|
for (size_t i = 0; i < geoms.size(); i++) {
|
||||||
geoms[i] = clean_or_clip_poly(geoms[i], 0, 0, 0, false);
|
geoms[i] = clean_or_clip_poly(geoms[i], 0, 0, 0, false);
|
||||||
if (additional[A_DEBUG_POLYGON]) {
|
if (additional[A_DEBUG_POLYGON]) {
|
||||||
check_polygon(geoms[i]);
|
check_polygon(geoms[i]);
|
||||||
@ -598,7 +600,7 @@ int manage_gap(unsigned long long index, unsigned long long *previndex, double s
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, char *geomstart, volatile long long *along, double gamma, int nlayers, char *prevent, char *additional, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running) {
|
long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, char *geomstart, volatile long long *along, double gamma, int nlayers, int *prevent, int *additional, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running) {
|
||||||
int line_detail;
|
int line_detail;
|
||||||
double fraction = 1;
|
double fraction = 1;
|
||||||
|
|
||||||
@ -731,16 +733,16 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
// If the geometry extends off the edge of the world, concatenate on another copy
|
// If the geometry extends off the edge of the world, concatenate on another copy
|
||||||
// shifted by 360 degrees, and then make sure both copies get clipped down to size.
|
// shifted by 360 degrees, and then make sure both copies get clipped down to size.
|
||||||
|
|
||||||
unsigned n = geom.size();
|
size_t n = geom.size();
|
||||||
|
|
||||||
if (bbox[0] < 0) {
|
if (bbox[0] < 0) {
|
||||||
for (unsigned i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
geom.push_back(draw(geom[i].op, geom[i].x + (1LL << 32), geom[i].y));
|
geom.push_back(draw(geom[i].op, geom[i].x + (1LL << 32), geom[i].y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bbox[2] > 1LL << 32) {
|
if (bbox[2] > 1LL << 32) {
|
||||||
for (unsigned i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
geom.push_back(draw(geom[i].op, geom[i].x - (1LL << 32), geom[i].y));
|
geom.push_back(draw(geom[i].op, geom[i].x - (1LL << 32), geom[i].y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -871,7 +873,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is serial because decode_meta() unifies duplicates
|
// This is serial because decode_meta() unifies duplicates
|
||||||
for (unsigned i = 0; i < partials.size(); i++) {
|
for (size_t i = 0; i < partials.size(); i++) {
|
||||||
std::vector<drawvec> geoms = partials[i].geoms;
|
std::vector<drawvec> geoms = partials[i].geoms;
|
||||||
partials[i].geoms.clear(); // avoid keeping two copies in memory
|
partials[i].geoms.clear(); // avoid keeping two copies in memory
|
||||||
long long layer = partials[i].layer;
|
long long layer = partials[i].layer;
|
||||||
@ -881,7 +883,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
|
|
||||||
// A complex polygon may have been split up into multiple geometries.
|
// A complex polygon may have been split up into multiple geometries.
|
||||||
// Break them out into multiple features if necessary.
|
// Break them out into multiple features if necessary.
|
||||||
for (unsigned j = 0; j < geoms.size(); j++) {
|
for (size_t j = 0; j < geoms.size(); j++) {
|
||||||
if (t == VT_POINT || to_feature(geoms[j], NULL)) {
|
if (t == VT_POINT || to_feature(geoms[j], NULL)) {
|
||||||
struct coalesce c;
|
struct coalesce c;
|
||||||
char *meta = partials[i].meta;
|
char *meta = partials[i].meta;
|
||||||
@ -913,9 +915,8 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<coalesce> out;
|
std::vector<coalesce> out;
|
||||||
unsigned x;
|
for (size_t x = 0; x < features[j].size(); x++) {
|
||||||
for (x = 0; x < features[j].size(); x++) {
|
size_t y = out.size() - 1;
|
||||||
unsigned y = out.size() - 1;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (out.size() > 0 && coalcmp(&features[j][x], &out[y]) < 0) {
|
if (out.size() > 0 && coalcmp(&features[j][x], &out[y]) < 0) {
|
||||||
@ -924,8 +925,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (additional[A_COALESCE] && out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 700 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) {
|
if (additional[A_COALESCE] && out.size() > 0 && out[y].geom.size() + features[j][x].geom.size() < 700 && coalcmp(&features[j][x], &out[y]) == 0 && features[j][x].type != VT_POINT) {
|
||||||
unsigned z;
|
for (size_t z = 0; z < features[j][x].geom.size(); z++) {
|
||||||
for (z = 0; z < features[j][x].geom.size(); z++) {
|
|
||||||
out[y].geom.push_back(features[j][x].geom[z]);
|
out[y].geom.push_back(features[j][x].geom[z]);
|
||||||
}
|
}
|
||||||
out[y].coalesced = true;
|
out[y].coalesced = true;
|
||||||
@ -937,7 +937,7 @@ long long write_tile(char **geoms, char *metabase, char *stringpool, int z, unsi
|
|||||||
features[j] = out;
|
features[j] = out;
|
||||||
|
|
||||||
out.clear();
|
out.clear();
|
||||||
for (x = 0; x < features[j].size(); x++) {
|
for (size_t x = 0; x < features[j].size(); x++) {
|
||||||
if (features[j][x].coalesced && features[j][x].type == VT_LINE) {
|
if (features[j][x].coalesced && features[j][x].type == VT_LINE) {
|
||||||
features[j][x].geom = remove_noop(features[j][x].geom, features[j][x].type, 0);
|
features[j][x].geom = remove_noop(features[j][x].geom, features[j][x].type, 0);
|
||||||
features[j][x].geom = simplify_lines(features[j][x].geom, 32, 0);
|
features[j][x].geom = simplify_lines(features[j][x].geom, 32, 0);
|
||||||
@ -1052,8 +1052,8 @@ struct write_tile_args {
|
|||||||
volatile long long *along;
|
volatile long long *along;
|
||||||
double gamma;
|
double gamma;
|
||||||
int nlayers;
|
int nlayers;
|
||||||
char *prevent;
|
int *prevent;
|
||||||
char *additional;
|
int *additional;
|
||||||
int child_shards;
|
int child_shards;
|
||||||
int *geomfd;
|
int *geomfd;
|
||||||
off_t *geom_size;
|
off_t *geom_size;
|
||||||
@ -1112,6 +1112,10 @@ void *run_thread(void *vargs) {
|
|||||||
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
int *err = (int *) malloc(sizeof(int));
|
int *err = (int *) malloc(sizeof(int));
|
||||||
|
if (err == NULL) {
|
||||||
|
perror("Out of memory");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
*err = z - 1;
|
*err = z - 1;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -1156,7 +1160,7 @@ void *run_thread(void *vargs) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y) {
|
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i <= maxzoom; i++) {
|
for (i = 0; i <= maxzoom; i++) {
|
||||||
long long most = 0;
|
long long most = 0;
|
||||||
|
5
tile.h
5
tile.h
@ -25,13 +25,12 @@ void deserialize_uint(char **f, unsigned *n);
|
|||||||
void deserialize_byte(char **f, signed char *n);
|
void deserialize_byte(char **f, signed char *n);
|
||||||
struct pool_val *deserialize_string(char **f, struct pool *p, int type);
|
struct pool_val *deserialize_string(char **f, struct pool *p, int type);
|
||||||
|
|
||||||
long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, char *prevent, char *additional);
|
long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, struct pool **file_keys, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, int *prevent, int *additional);
|
||||||
|
|
||||||
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, char *prevent, char *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y);
|
int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, struct pool **file_keys, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y);
|
||||||
|
|
||||||
int manage_gap(unsigned long long index, unsigned long long *previndex, double scale, double gamma, double *gap);
|
int manage_gap(unsigned long long index, unsigned long long *previndex, double scale, double gamma, double *gap);
|
||||||
|
|
||||||
extern unsigned initial_x, initial_y;
|
|
||||||
extern int geometry_scale;
|
extern int geometry_scale;
|
||||||
extern int quiet;
|
extern int quiet;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user