@@ -85,26 +85,21 @@ void mbtiles_write_tile(sqlite3 *outdb, int z, int tx, int ty, const char *data,
85
85
}
86
86
}
87
87
88
- static void quote (std::string *buf, const char *s) {
89
- char tmp[strlen (s) * 8 + 1 ];
90
- char *out = tmp;
91
-
92
- for (; *s != ' \0 ' ; s++) {
93
- unsigned char ch = (unsigned char ) *s;
88
+ static void quote (std::string &buf, std::string const &s) {
89
+ for (size_t i = 0 ; i < s.size (); i++) {
90
+ unsigned char ch = s[i];
94
91
95
92
if (ch == ' \\ ' || ch == ' \" ' ) {
96
- *out++ = ' \\ ' ;
97
- *out++ = ch ;
93
+ buf. push_back ( ' \\ ' ) ;
94
+ buf. push_back (ch) ;
98
95
} else if (ch < ' ' ) {
99
- sprintf (out, " \\ u%04x" , ch);
100
- out = out + strlen (out);
96
+ char tmp[7 ];
97
+ sprintf (tmp, " \\ u%04x" , ch);
98
+ buf.append (std::string (tmp));
101
99
} else {
102
- *out++ = ch ;
100
+ buf. push_back (ch) ;
103
101
}
104
102
}
105
-
106
- *out = ' \0 ' ;
107
- buf->append (tmp, strlen (tmp));
108
103
}
109
104
110
105
void aprintf (std::string *buf, const char *format, ...) {
@@ -142,7 +137,7 @@ bool type_and_string::operator!=(const type_and_string &o) const {
142
137
return false ;
143
138
}
144
139
145
- std::string tilestats (std::map<std::string, layermap_entry> const &layermap1) {
140
+ std::string tilestats (std::map<std::string, layermap_entry> const &layermap1, size_t elements ) {
146
141
// Consolidate layers/attributes whose names are truncated
147
142
std::vector<std::map<std::string, layermap_entry>> lmv;
148
143
lmv.push_back (layermap1);
@@ -166,7 +161,7 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
166
161
out.append (" \t\t {\n " );
167
162
168
163
out.append (" \t\t\t\" layer\" : \" " );
169
- quote (& out, layer.first .c_str ());
164
+ quote (out, layer.first .c_str ());
170
165
out.append (" \" ,\n " );
171
166
172
167
out.append (" \t\t\t\" count\" : " );
@@ -181,7 +176,7 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
181
176
}
182
177
183
178
out.append (" \t\t\t\" geometry\" : \" " );
184
- quote (& out, geomtype.c_str ());
179
+ quote (out, geomtype.c_str ());
185
180
out.append (" \" ,\n " );
186
181
187
182
size_t attrib_count = layer.second .file_keys .size ();
@@ -197,7 +192,7 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
197
192
198
193
size_t attrs = 0 ;
199
194
for (auto attribute : layer.second .file_keys ) {
200
- if (attrs == 100 ) {
195
+ if (attrs == elements ) {
201
196
break ;
202
197
}
203
198
if (attrs != 0 ) {
@@ -208,7 +203,7 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
208
203
out.append (" \t\t\t\t {\n " );
209
204
210
205
out.append (" \t\t\t\t\t\" attribute\" : \" " );
211
- quote (& out, attribute.first .c_str ());
206
+ quote (out, attribute.first .c_str ());
212
207
out.append (" \" ,\n " );
213
208
214
209
size_t val_count = attribute.second .sample_values .size ();
@@ -238,30 +233,36 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
238
233
}
239
234
240
235
out.append (" \t\t\t\t\t\" type\" : \" " );
241
- quote (& out, type_str.c_str ());
236
+ quote (out, type_str.c_str ());
242
237
out.append (" \" ,\n " );
243
238
244
239
out.append (" \t\t\t\t\t\" values\" : [\n " );
245
240
246
241
size_t vals = 0 ;
247
242
for (auto value : attribute.second .sample_values ) {
248
- if (vals == 100 ) {
243
+ if (vals == elements ) {
249
244
break ;
250
245
}
251
- if (vals != 0 ) {
252
- out.append (" ,\n " );
253
- }
254
- vals++;
255
246
256
247
if (value.type == mvt_double || value.type == mvt_bool) {
248
+ if (vals != 0 ) {
249
+ out.append (" ,\n " );
250
+ }
251
+ vals++;
252
+
257
253
out.append (" \t\t\t\t\t\t " );
258
254
out.append (value.string );
259
255
} else {
260
256
std::string trunc = truncate16 (value.string , 256 );
261
257
262
258
if (trunc .size () == value.string .size ()) {
259
+ if (vals != 0 ) {
260
+ out.append (" ,\n " );
261
+ }
262
+ vals++;
263
+
263
264
out.append (" \t\t\t\t\t\t\" " );
264
- quote (& out, value.string .c_str ());
265
+ quote (out, value.string .c_str ());
265
266
out.append (" \" " );
266
267
}
267
268
}
@@ -304,7 +305,7 @@ std::string tilestats(std::map<std::string, layermap_entry> const &layermap1) {
304
305
return out2;
305
306
}
306
307
307
- void mbtiles_write_metadata (sqlite3 *outdb, const char *outdir, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map<std::string, layermap_entry> const &layermap, bool vector, const char *description) {
308
+ void mbtiles_write_metadata (sqlite3 *outdb, const char *outdir, const char *fname, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, int forcetable, const char *attribution, std::map<std::string, layermap_entry> const &layermap, bool vector, const char *description, bool do_tilestats ) {
308
309
char *sql, *err;
309
310
310
311
sqlite3 *db = outdb;
@@ -412,57 +413,66 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *outdir, const char *fnam
412
413
sqlite3_free (sql);
413
414
414
415
if (vector) {
415
- std::string buf ( " { " ) ;
416
- aprintf (&buf, " \" vector_layers \" : [ " ) ;
416
+ size_t elements = 100 ;
417
+ std::string buf ;
417
418
418
- std::vector<std::string> lnames;
419
- for (auto ai = layermap.begin (); ai != layermap.end (); ++ai) {
420
- lnames.push_back (ai->first );
421
- }
419
+ {
420
+ buf = " {" ;
421
+ aprintf (&buf, " \" vector_layers\" : [ " );
422
422
423
- for ( size_t i = 0 ; i < lnames. size (); i++) {
424
- if (i != 0 ) {
425
- aprintf (&buf, " , " );
423
+ std::vector<std::string> lnames;
424
+ for ( auto ai = layermap. begin (); ai != layermap. end (); ++ai ) {
425
+ lnames. push_back (ai-> first );
426
426
}
427
427
428
- auto fk = layermap.find (lnames[i]);
429
- aprintf (&buf, " { \" id\" : \" " );
430
- quote (&buf, lnames[i].c_str ());
431
- aprintf (&buf, " \" , \" description\" : \"\" , \" minzoom\" : %d, \" maxzoom\" : %d, \" fields\" : {" , fk->second .minzoom , fk->second .maxzoom );
432
-
433
- bool first = true ;
434
- for (auto j = fk->second .file_keys .begin (); j != fk->second .file_keys .end (); ++j) {
435
- if (first) {
436
- first = false ;
437
- } else {
428
+ for (size_t i = 0 ; i < lnames.size (); i++) {
429
+ if (i != 0 ) {
438
430
aprintf (&buf, " , " );
439
431
}
440
432
441
- aprintf (&buf, " \" " );
442
- quote (&buf, j->first .c_str ());
433
+ auto fk = layermap.find (lnames[i]);
434
+ aprintf (&buf, " { \" id\" : \" " );
435
+ quote (buf, lnames[i]);
436
+ aprintf (&buf, " \" , \" description\" : \"\" , \" minzoom\" : %d, \" maxzoom\" : %d, \" fields\" : {" , fk->second .minzoom , fk->second .maxzoom );
437
+
438
+ bool first = true ;
439
+ for (auto j = fk->second .file_keys .begin (); j != fk->second .file_keys .end (); ++j) {
440
+ if (first) {
441
+ first = false ;
442
+ } else {
443
+ aprintf (&buf, " , " );
444
+ }
445
+
446
+ aprintf (&buf, " \" " );
447
+ quote (buf, j->first .c_str ());
443
448
444
- int type = 0 ;
445
- for (auto s : j->second .sample_values ) {
446
- type |= (1 << s.type );
447
- }
449
+ int type = 0 ;
450
+ for (auto s : j->second .sample_values ) {
451
+ type |= (1 << s.type );
452
+ }
448
453
449
- if (type == (1 << mvt_double)) {
450
- aprintf (&buf, " \" : \" Number\" " );
451
- } else if (type == (1 << mvt_bool)) {
452
- aprintf (&buf, " \" : \" Boolean\" " );
453
- } else if (type == (1 << mvt_string)) {
454
- aprintf (&buf, " \" : \" String\" " );
455
- } else {
456
- aprintf (&buf, " \" : \" Mixed\" " );
454
+ if (type == (1 << mvt_double)) {
455
+ aprintf (&buf, " \" : \" Number\" " );
456
+ } else if (type == (1 << mvt_bool)) {
457
+ aprintf (&buf, " \" : \" Boolean\" " );
458
+ } else if (type == (1 << mvt_string)) {
459
+ aprintf (&buf, " \" : \" String\" " );
460
+ } else {
461
+ aprintf (&buf, " \" : \" Mixed\" " );
462
+ }
457
463
}
464
+
465
+ aprintf (&buf, " } }" );
458
466
}
459
467
460
- aprintf (&buf, " } }" );
461
- }
468
+ aprintf (&buf, " ]" );
469
+
470
+ if (do_tilestats && elements > 0 ) {
471
+ aprintf (&buf, " ,\" tilestats\" : %s" , tilestats (layermap, elements).c_str ());
472
+ }
462
473
463
- aprintf (&buf, " ]," );
464
- aprintf (&buf, " \" tilestats\" : %s" , tilestats (layermap).c_str ());
465
- aprintf (&buf, " }" );
474
+ aprintf (&buf, " }" );
475
+ }
466
476
467
477
sql = sqlite3_mprintf (" INSERT INTO metadata (name, value) VALUES ('json', %Q);" , buf.c_str ());
468
478
if (sqlite3_exec (db, sql, NULL , NULL , &err) != SQLITE_OK) {
@@ -490,8 +500,8 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *outdir, const char *fnam
490
500
while (sqlite3_step (stmt) == SQLITE_ROW) {
491
501
std::string key, value;
492
502
493
- quote (& key, (const char *) sqlite3_column_text (stmt, 0 ));
494
- quote (& value, (const char *) sqlite3_column_text (stmt, 1 ));
503
+ quote (key, (const char *) sqlite3_column_text (stmt, 0 ));
504
+ quote (value, (const char *) sqlite3_column_text (stmt, 1 ));
495
505
496
506
if (!first) {
497
507
fprintf (fp, " ,\n " );
@@ -536,6 +546,10 @@ std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::
536
546
537
547
for (size_t i = 0 ; i < maps.size (); i++) {
538
548
for (auto map = maps[i].begin (); map != maps[i].end (); ++map) {
549
+ if (map->second .points + map->second .lines + map->second .polygons == 0 ) {
550
+ continue ;
551
+ }
552
+
539
553
std::string layername = map->first ;
540
554
if (trunc ) {
541
555
layername = truncate16 (layername, 256 );
0 commit comments