~ubuntu-branches/ubuntu/precise/spatialite/precise

« back to all changes in this revision

Viewing changes to spatialite-tools/spatialite_osm_map.c

  • Committer: Package Import Robot
  • Author(s): David Paleino, Francesco Paolo Lovergine, David Paleino
  • Date: 2011-11-21 12:10:43 UTC
  • mfrom: (4.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20111121121043-0g14o2uf0r343a82
Tags: 3.0.0~beta20110817-3
[ Francesco Paolo Lovergine ]
* Fixed linking order for sqlite3 in debian patch 00-systemlibs.patch.
  (closes: #638929)

[ David Paleino ]
* Conditionally disable full EPSG initialization (for srs_init.c)
  on powerpc, and document what projections are available on that
  architecture (Closes: #649302)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
/ spatialite_osm_map
 
3
/
 
4
/ a tool loading OSM-XML maps into a SpatiaLite DB
 
5
/
 
6
/ version 1.0, 2010 April 8
 
7
/
 
8
/ Author: Sandro Furieri a.furieri@lqt.it
 
9
/
 
10
/ Copyright (C) 2010  Alessandro Furieri
 
11
/
 
12
/    This program is free software: you can redistribute it and/or modify
 
13
/    it under the terms of the GNU General Public License as published by
 
14
/    the Free Software Foundation, either version 3 of the License, or
 
15
/    (at your option) any later version.
 
16
/
 
17
/    This program is distributed in the hope that it will be useful,
 
18
/    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
/    GNU General Public License for more details.
 
21
/
 
22
/    You should have received a copy of the GNU General Public License
 
23
/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
24
/
 
25
*/
 
26
 
 
27
#if defined(_WIN32) && !defined(__MINGW32__)
 
28
/* MSVC strictly requires this include [off_t] */
 
29
#include <sys/types.h>
 
30
#endif
 
31
 
 
32
#include <stdlib.h>
 
33
#include <stdio.h>
 
34
#include <string.h>
 
35
#include <float.h>
 
36
 
 
37
#include <expat.h>
 
38
 
 
39
#ifdef SPATIALITE_AMALGAMATION
 
40
#include <spatialite/sqlite3.h>
 
41
#else
 
42
#include <sqlite3.h>
 
43
#endif
 
44
 
 
45
#include <spatialite/gaiageo.h>
 
46
#include <spatialite.h>
 
47
 
 
48
#define ARG_NONE                0
 
49
#define ARG_OSM_PATH    1
 
50
#define ARG_DB_PATH             2
 
51
#define ARG_CACHE_SIZE  3
 
52
 
 
53
#define MAX_TAG         16
 
54
 
 
55
#if defined(_WIN32) && !defined(__MINGW32__)
 
56
#define strcasecmp      _stricmp
 
57
#endif /* not WIN32 */
 
58
 
 
59
#if defined(_WIN32)
 
60
#define atol_64         _atoi64
 
61
#else
 
62
#define atol_64         atoll
 
63
#endif
 
64
 
 
65
#define BUFFSIZE        8192
 
66
 
 
67
#define CURRENT_TAG_UNKNOWN     0
 
68
#define CURRENT_TAG_IS_NODE     1
 
69
#define CURRENT_TAG_IS_WAY      2
 
70
#define CURRENT_TAG_IS_RELATION 3
 
71
 
 
72
struct aux_params
 
73
{
 
74
/* an auxiliary struct used for XML parsing */
 
75
    sqlite3 *db_handle;
 
76
    sqlite3_stmt *ins_tmp_nodes_stmt;
 
77
    sqlite3_stmt *ins_tmp_ways_stmt;
 
78
    sqlite3_stmt *ins_generic_point_stmt;
 
79
    sqlite3_stmt *ins_addresses_stmt;
 
80
    sqlite3_stmt *ins_generic_linestring_stmt;
 
81
    sqlite3_stmt *ins_generic_polygon_stmt;
 
82
    int current_tag;
 
83
};
 
84
 
 
85
struct layers
 
86
{
 
87
    const char *name;
 
88
    int ok_point;
 
89
    int ok_linestring;
 
90
    int ok_polygon;
 
91
    sqlite3_stmt *ins_point_stmt;
 
92
    sqlite3_stmt *ins_linestring_stmt;
 
93
    sqlite3_stmt *ins_polygon_stmt;
 
94
} base_layers[] =
 
95
{
 
96
    {
 
97
    "highway", 0, 0, 0, NULL, NULL, NULL},
 
98
    {
 
99
    "junction", 0, 0, 0, NULL, NULL, NULL},
 
100
    {
 
101
    "traffic_calming", 0, 0, 0, NULL, NULL, NULL},
 
102
    {
 
103
    "traffic_sign", 0, 0, 0, NULL, NULL, NULL},
 
104
    {
 
105
    "service", 0, 0, 0, NULL, NULL, NULL},
 
106
    {
 
107
    "barrier", 0, 0, 0, NULL, NULL, NULL},
 
108
    {
 
109
    "cycleway", 0, 0, 0, NULL, NULL, NULL},
 
110
    {
 
111
    "tracktype", 0, 0, 0, NULL, NULL, NULL},
 
112
    {
 
113
    "waterway", 0, 0, 0, NULL, NULL, NULL},
 
114
    {
 
115
    "railway", 0, 0, 0, NULL, NULL, NULL},
 
116
    {
 
117
    "aeroway", 0, 0, 0, NULL, NULL, NULL},
 
118
    {
 
119
    "aerialway", 0, 0, 0, NULL, NULL, NULL},
 
120
    {
 
121
    "power", 0, 0, 0, NULL, NULL, NULL},
 
122
    {
 
123
    "man_made", 0, 0, 0, NULL, NULL, NULL},
 
124
    {
 
125
    "leisure", 0, 0, 0, NULL, NULL, NULL},
 
126
    {
 
127
    "amenity", 0, 0, 0, NULL, NULL, NULL},
 
128
    {
 
129
    "shop", 0, 0, 0, NULL, NULL, NULL},
 
130
    {
 
131
    "tourism", 0, 0, 0, NULL, NULL, NULL},
 
132
    {
 
133
    "historic", 0, 0, 0, NULL, NULL, NULL},
 
134
    {
 
135
    "landuse", 0, 0, 0, NULL, NULL, NULL},
 
136
    {
 
137
    "military", 0, 0, 0, NULL, NULL, NULL},
 
138
    {
 
139
    "natural", 0, 0, 0, NULL, NULL, NULL},
 
140
    {
 
141
    "geological", 0, 0, 0, NULL, NULL, NULL},
 
142
    {
 
143
    "route", 0, 0, 0, NULL, NULL, NULL},
 
144
    {
 
145
    "boundary", 0, 0, 0, NULL, NULL, NULL},
 
146
    {
 
147
    "sport", 0, 0, 0, NULL, NULL, NULL},
 
148
    {
 
149
    "abutters", 0, 0, 0, NULL, NULL, NULL},
 
150
    {
 
151
    "accessories", 0, 0, 0, NULL, NULL, NULL},
 
152
    {
 
153
    "properties", 0, 0, 0, NULL, NULL, NULL},
 
154
    {
 
155
    "restrictions", 0, 0, 0, NULL, NULL, NULL},
 
156
    {
 
157
    "place", 0, 0, 0, NULL, NULL, NULL},
 
158
    {
 
159
    "building", 0, 0, 0, NULL, NULL, NULL},
 
160
    {
 
161
    "parking", 0, 0, 0, NULL, NULL, NULL},
 
162
    {
 
163
NULL, 0, 0, 0, NULL, NULL, NULL},};
 
164
 
 
165
struct tag
 
166
{
 
167
    char *k;
 
168
    char *v;
 
169
    struct tag *next;
 
170
};
 
171
 
 
172
struct node
 
173
{
 
174
    sqlite3_int64 id;
 
175
    double lat;
 
176
    double lon;
 
177
    struct tag *first;
 
178
    struct tag *last;
 
179
} glob_node;
 
180
 
 
181
struct nd
 
182
{
 
183
    sqlite3_int64 ref;
 
184
    char found;
 
185
    struct nd *next;
 
186
};
 
187
 
 
188
struct way
 
189
{
 
190
    sqlite3_int64 id;
 
191
    struct nd *first_nd;
 
192
    struct nd *last_nd;
 
193
    struct tag *first;
 
194
    struct tag *last;
 
195
} glob_way;
 
196
 
 
197
struct member
 
198
{
 
199
    sqlite3_int64 ref;
 
200
    int is_node;
 
201
    int is_way;
 
202
    char found;
 
203
    char *role;
 
204
    gaiaGeomCollPtr geom;
 
205
    struct member *next;
 
206
};
 
207
 
 
208
struct relation
 
209
{
 
210
    sqlite3_int64 id;
 
211
    struct member *first_member;
 
212
    struct member *last_member;
 
213
    struct tag *first;
 
214
    struct tag *last;
 
215
} glob_relation;
 
216
 
 
217
static void
 
218
create_point_table (struct aux_params *params, struct layers *layer)
 
219
{
 
220
    int ret;
 
221
    char *err_msg = NULL;
 
222
    char sql[1024];
 
223
    sqlite3_stmt *stmt;
 
224
 
 
225
/* creating a POINT table */
 
226
    sprintf (sql, "CREATE TABLE pt_%s (\n", layer->name);
 
227
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
228
    strcat (sql, "sub_type TEXT,\n");
 
229
    strcat (sql, "name TEXT)\n");
 
230
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
231
    if (ret != SQLITE_OK)
 
232
      {
 
233
          fprintf (stderr, "CREATE TABLE 'pt_%s' error: %s\n", layer->name,
 
234
                   err_msg);
 
235
          sqlite3_free (err_msg);
 
236
          return;
 
237
      }
 
238
    sprintf (sql,
 
239
             "SELECT AddGeometryColumn('pt_%s', 'Geometry', 4326, 'POINT', 'XY')",
 
240
             layer->name);
 
241
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
242
    if (ret != SQLITE_OK)
 
243
      {
 
244
          fprintf (stderr, "CREATE TABLE 'pt_%s' error: %s\n", layer->name,
 
245
                   err_msg);
 
246
          sqlite3_free (err_msg);
 
247
          return;
 
248
      }
 
249
 
 
250
/* creating the insert SQL statement */
 
251
    sprintf (sql, "INSERT INTO pt_%s (id, sub_type, name, Geometry) ",
 
252
             layer->name);
 
253
    strcat (sql, "VALUES (?, ?, ?, ?)");
 
254
    ret =
 
255
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql), &stmt, NULL);
 
256
    if (ret != SQLITE_OK)
 
257
      {
 
258
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
259
                   sqlite3_errmsg (params->db_handle));
 
260
          return;
 
261
      }
 
262
    layer->ins_point_stmt = stmt;
 
263
}
 
264
 
 
265
static void
 
266
create_linestring_table (struct aux_params *params, struct layers *layer)
 
267
{
 
268
    int ret;
 
269
    char *err_msg = NULL;
 
270
    char sql[1024];
 
271
    sqlite3_stmt *stmt;
 
272
 
 
273
/* creating a LINESTRING table */
 
274
    sprintf (sql, "CREATE TABLE ln_%s (\n", layer->name);
 
275
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
276
    strcat (sql, "sub_type TEXT,\n");
 
277
    strcat (sql, "name TEXT)\n");
 
278
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
279
    if (ret != SQLITE_OK)
 
280
      {
 
281
          fprintf (stderr, "CREATE TABLE 'ln_%s' error: %s\n", layer->name,
 
282
                   err_msg);
 
283
          sqlite3_free (err_msg);
 
284
          return;
 
285
      }
 
286
    sprintf (sql,
 
287
             "SELECT AddGeometryColumn('ln_%s', 'Geometry', 4326, 'MULTILINESTRING', 'XY')",
 
288
             layer->name);
 
289
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
290
    if (ret != SQLITE_OK)
 
291
      {
 
292
          fprintf (stderr, "CREATE TABLE 'ln_%s' error: %s\n", layer->name,
 
293
                   err_msg);
 
294
          sqlite3_free (err_msg);
 
295
          return;
 
296
      }
 
297
 
 
298
/* creating the insert SQL statement */
 
299
    sprintf (sql, "INSERT INTO ln_%s (id, sub_type, name, Geometry) ",
 
300
             layer->name);
 
301
    strcat (sql, "VALUES (?, ?, ?, ?)");
 
302
    ret =
 
303
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql), &stmt, NULL);
 
304
    if (ret != SQLITE_OK)
 
305
      {
 
306
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
307
                   sqlite3_errmsg (params->db_handle));
 
308
          return;
 
309
      }
 
310
    layer->ins_linestring_stmt = stmt;
 
311
}
 
312
 
 
313
static void
 
314
create_polygon_table (struct aux_params *params, struct layers *layer)
 
315
{
 
316
    int ret;
 
317
    char *err_msg = NULL;
 
318
    char sql[1024];
 
319
    sqlite3_stmt *stmt;
 
320
 
 
321
/* creating a POLYGON table */
 
322
    sprintf (sql, "CREATE TABLE pg_%s (\n", layer->name);
 
323
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
324
    strcat (sql, "sub_type TEXT,\n");
 
325
    strcat (sql, "name TEXT)\n");
 
326
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
327
    if (ret != SQLITE_OK)
 
328
      {
 
329
          fprintf (stderr, "CREATE TABLE 'pg_%s' error: %s\n", layer->name,
 
330
                   err_msg);
 
331
          sqlite3_free (err_msg);
 
332
          return;
 
333
      }
 
334
    sprintf (sql,
 
335
             "SELECT AddGeometryColumn('pg_%s', 'Geometry', 4326, 'MULTIPOLYGON', 'XY')",
 
336
             layer->name);
 
337
    ret = sqlite3_exec (params->db_handle, sql, NULL, NULL, &err_msg);
 
338
    if (ret != SQLITE_OK)
 
339
      {
 
340
          fprintf (stderr, "CREATE TABLE 'pg_%s' error: %s\n", layer->name,
 
341
                   err_msg);
 
342
          sqlite3_free (err_msg);
 
343
          return;
 
344
      }
 
345
 
 
346
/* creating the insert SQL statement */
 
347
    sprintf (sql, "INSERT INTO pg_%s (id, sub_type, name, Geometry) ",
 
348
             layer->name);
 
349
    strcat (sql, "VALUES (?, ?, ?, ?)");
 
350
    ret =
 
351
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql), &stmt, NULL);
 
352
    if (ret != SQLITE_OK)
 
353
      {
 
354
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
355
                   sqlite3_errmsg (params->db_handle));
 
356
          return;
 
357
      }
 
358
    layer->ins_polygon_stmt = stmt;
 
359
}
 
360
 
 
361
static void
 
362
free_tag (struct tag *p)
 
363
{
 
364
    if (p->k)
 
365
        free (p->k);
 
366
    if (p->v)
 
367
        free (p->v);
 
368
    free (p);
 
369
}
 
370
 
 
371
static void
 
372
free_member (struct member *p)
 
373
{
 
374
    if (p->role)
 
375
        free (p->role);
 
376
    free (p);
 
377
}
 
378
 
 
379
static void
 
380
start_node (struct aux_params *params, const char **attr)
 
381
{
 
382
    int i;
 
383
    glob_node.id = -1;
 
384
    glob_node.lat = DBL_MAX;
 
385
    glob_node.lon = DBL_MAX;
 
386
    glob_node.first = NULL;
 
387
    glob_node.last = NULL;
 
388
    for (i = 0; attr[i]; i += 2)
 
389
      {
 
390
          if (strcmp (attr[i], "id") == 0)
 
391
              glob_node.id = atol_64 (attr[i + 1]);
 
392
          if (strcmp (attr[i], "lat") == 0)
 
393
              glob_node.lat = atof (attr[i + 1]);
 
394
          if (strcmp (attr[i], "lon") == 0)
 
395
              glob_node.lon = atof (attr[i + 1]);
 
396
      }
 
397
    params->current_tag = CURRENT_TAG_IS_NODE;
 
398
}
 
399
 
 
400
static void
 
401
point_layer_insert (struct aux_params *params, const char *layer_name,
 
402
                    sqlite3_int64 id, double lat, double lon,
 
403
                    const char *sub_type, const char *name)
 
404
{
 
405
    struct layers *layer;
 
406
    int i = 0;
 
407
    while (1)
 
408
      {
 
409
          layer = &(base_layers[i++]);
 
410
          if (layer->name == NULL)
 
411
              return;
 
412
          if (strcmp (layer->name, layer_name) == 0)
 
413
            {
 
414
                if (layer->ok_point == 0)
 
415
                  {
 
416
                      layer->ok_point = 1;
 
417
                      create_point_table (params, layer);
 
418
                  }
 
419
                if (layer->ins_point_stmt)
 
420
                  {
 
421
                      int ret;
 
422
                      unsigned char *blob;
 
423
                      int blob_size;
 
424
                      gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
 
425
                      geom->Srid = 4326;
 
426
                      gaiaAddPointToGeomColl (geom, lon, lat);
 
427
                      sqlite3_reset (layer->ins_point_stmt);
 
428
                      sqlite3_clear_bindings (layer->ins_point_stmt);
 
429
                      sqlite3_bind_int64 (layer->ins_point_stmt, 1, id);
 
430
                      if (sub_type == NULL)
 
431
                          sqlite3_bind_null (layer->ins_point_stmt, 2);
 
432
                      else
 
433
                          sqlite3_bind_text (layer->ins_point_stmt, 2,
 
434
                                             sub_type, strlen (sub_type),
 
435
                                             SQLITE_STATIC);
 
436
                      if (name == NULL)
 
437
                          sqlite3_bind_null (layer->ins_point_stmt, 3);
 
438
                      else
 
439
                          sqlite3_bind_text (layer->ins_point_stmt, 3, name,
 
440
                                             strlen (name), SQLITE_STATIC);
 
441
                      gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
442
                      gaiaFreeGeomColl (geom);
 
443
                      sqlite3_bind_blob (layer->ins_point_stmt, 4, blob,
 
444
                                         blob_size, free);
 
445
                      ret = sqlite3_step (layer->ins_point_stmt);
 
446
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
447
                          return;
 
448
                      fprintf (stderr, "sqlite3_step() error: INS_POINT %s\n",
 
449
                               layer_name);
 
450
                      sqlite3_finalize (layer->ins_point_stmt);
 
451
                      layer->ins_point_stmt = NULL;
 
452
                  }
 
453
                return;
 
454
            }
 
455
      }
 
456
}
 
457
 
 
458
static void
 
459
point_generic_insert (struct aux_params *params, sqlite3_int64 id, double lat,
 
460
                      double lon, const char *name)
 
461
{
 
462
    if (params->ins_generic_point_stmt)
 
463
      {
 
464
          int ret;
 
465
          unsigned char *blob;
 
466
          int blob_size;
 
467
          gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
 
468
          geom->Srid = 4326;
 
469
          gaiaAddPointToGeomColl (geom, lon, lat);
 
470
          sqlite3_reset (params->ins_generic_point_stmt);
 
471
          sqlite3_clear_bindings (params->ins_generic_point_stmt);
 
472
          sqlite3_bind_int64 (params->ins_generic_point_stmt, 1, id);
 
473
          if (name == NULL)
 
474
              sqlite3_bind_null (params->ins_generic_point_stmt, 2);
 
475
          else
 
476
              sqlite3_bind_text (params->ins_generic_point_stmt, 2, name,
 
477
                                 strlen (name), SQLITE_STATIC);
 
478
          gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
479
          gaiaFreeGeomColl (geom);
 
480
          sqlite3_bind_blob (params->ins_generic_point_stmt, 3, blob,
 
481
                             blob_size, free);
 
482
          ret = sqlite3_step (params->ins_generic_point_stmt);
 
483
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
484
              return;
 
485
          fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POINT\n");
 
486
          sqlite3_finalize (params->ins_generic_point_stmt);
 
487
          params->ins_generic_point_stmt = NULL;
 
488
      }
 
489
}
 
490
 
 
491
static void
 
492
address_insert (struct aux_params *params, sqlite3_int64 id, double lat,
 
493
                double lon, const char *country, const char *city,
 
494
                const char *postcode,
 
495
                const char *street,
 
496
                const char *housename, const char *housenumber)
 
497
{
 
498
    if (params->ins_addresses_stmt)
 
499
      {
 
500
          int ret;
 
501
          unsigned char *blob;
 
502
          int blob_size;
 
503
          gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
 
504
          geom->Srid = 4326;
 
505
          gaiaAddPointToGeomColl (geom, lon, lat);
 
506
          sqlite3_reset (params->ins_addresses_stmt);
 
507
          sqlite3_clear_bindings (params->ins_addresses_stmt);
 
508
          sqlite3_bind_int64 (params->ins_addresses_stmt, 1, id);
 
509
          if (country == NULL)
 
510
              sqlite3_bind_null (params->ins_addresses_stmt, 2);
 
511
          else
 
512
              sqlite3_bind_text (params->ins_addresses_stmt, 2, country,
 
513
                                 strlen (country), SQLITE_STATIC);
 
514
          if (city == NULL)
 
515
              sqlite3_bind_null (params->ins_addresses_stmt, 3);
 
516
          else
 
517
              sqlite3_bind_text (params->ins_addresses_stmt, 3, city,
 
518
                                 strlen (city), SQLITE_STATIC);
 
519
          if (postcode == NULL)
 
520
              sqlite3_bind_null (params->ins_addresses_stmt, 4);
 
521
          else
 
522
              sqlite3_bind_text (params->ins_addresses_stmt, 4, postcode,
 
523
                                 strlen (postcode), SQLITE_STATIC);
 
524
          if (street == NULL)
 
525
              sqlite3_bind_null (params->ins_addresses_stmt, 5);
 
526
          else
 
527
              sqlite3_bind_text (params->ins_addresses_stmt, 5, street,
 
528
                                 strlen (street), SQLITE_STATIC);
 
529
          if (housename == NULL)
 
530
              sqlite3_bind_null (params->ins_addresses_stmt, 6);
 
531
          else
 
532
              sqlite3_bind_text (params->ins_addresses_stmt, 6, housename,
 
533
                                 strlen (housename), SQLITE_STATIC);
 
534
          if (housenumber == NULL)
 
535
              sqlite3_bind_null (params->ins_addresses_stmt, 7);
 
536
          else
 
537
              sqlite3_bind_text (params->ins_addresses_stmt, 7, housenumber,
 
538
                                 strlen (housenumber), SQLITE_STATIC);
 
539
          gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
540
          gaiaFreeGeomColl (geom);
 
541
          sqlite3_bind_blob (params->ins_addresses_stmt, 8, blob, blob_size,
 
542
                             free);
 
543
          ret = sqlite3_step (params->ins_addresses_stmt);
 
544
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
545
              return;
 
546
          fprintf (stderr, "sqlite3_step() error: INS_ADDRESSES\n");
 
547
          sqlite3_finalize (params->ins_addresses_stmt);
 
548
          params->ins_addresses_stmt = NULL;
 
549
      }
 
550
}
 
551
 
 
552
static void
 
553
eval_node (struct aux_params *params)
 
554
{
 
555
    struct tag *p_tag;
 
556
    const char *p;
 
557
    int i = 0;
 
558
    const char *layer_name = NULL;
 
559
    char *sub_type = NULL;
 
560
    char *name = NULL;
 
561
    char *country = NULL;
 
562
    char *city = NULL;
 
563
    char *postcode = NULL;
 
564
    char *street = NULL;
 
565
    char *housename = NULL;
 
566
    char *housenumber = NULL;
 
567
    if (glob_node.first == NULL)
 
568
        return;
 
569
    while (1)
 
570
      {
 
571
          p = base_layers[i++].name;
 
572
          if (!p)
 
573
              break;
 
574
          p_tag = glob_node.first;
 
575
          while (p_tag)
 
576
            {
 
577
                if (strcmp (p_tag->k, p) == 0)
 
578
                  {
 
579
                      layer_name = p;
 
580
                      sub_type = p_tag->v;
 
581
                  }
 
582
                if (strcmp (p_tag->k, "name") == 0)
 
583
                    name = p_tag->v;
 
584
                p_tag = p_tag->next;
 
585
            }
 
586
          if (layer_name)
 
587
              break;
 
588
      }
 
589
    if (layer_name)
 
590
      {
 
591
          point_layer_insert (params, layer_name, glob_node.id, glob_node.lat,
 
592
                              glob_node.lon, sub_type, name);
 
593
          return;
 
594
      }
 
595
    else if (name != NULL)
 
596
      {
 
597
          point_generic_insert (params, glob_node.id, glob_node.lat,
 
598
                                glob_node.lon, name);
 
599
          return;
 
600
      }
 
601
 
 
602
/* may be an house address */
 
603
    p_tag = glob_node.first;
 
604
    while (p_tag)
 
605
      {
 
606
          if (strcmp (p_tag->k, "addr:country") == 0)
 
607
              country = p_tag->v;
 
608
          if (strcmp (p_tag->k, "addr:city") == 0)
 
609
              city = p_tag->v;
 
610
          if (strcmp (p_tag->k, "addr:postcode") == 0)
 
611
              postcode = p_tag->v;
 
612
          if (strcmp (p_tag->k, "addr:street") == 0)
 
613
              street = p_tag->v;
 
614
          if (strcmp (p_tag->k, "addr:housename") == 0)
 
615
              housename = p_tag->v;
 
616
          if (strcmp (p_tag->k, "addr:housenumber") == 0)
 
617
              housenumber = p_tag->v;
 
618
          p_tag = p_tag->next;
 
619
      }
 
620
    if (country || city || postcode || street || housename || housenumber)
 
621
        address_insert (params, glob_node.id, glob_node.lat, glob_node.lon,
 
622
                        country, city, postcode, street, housename,
 
623
                        housenumber);
 
624
}
 
625
 
 
626
static void
 
627
tmp_nodes_insert (struct aux_params *params, sqlite3_int64 id, double lat,
 
628
                  double lon)
 
629
{
 
630
    int ret;
 
631
    if (params->ins_tmp_nodes_stmt == NULL)
 
632
        return;
 
633
    sqlite3_reset (params->ins_tmp_nodes_stmt);
 
634
    sqlite3_clear_bindings (params->ins_tmp_nodes_stmt);
 
635
    sqlite3_bind_int64 (params->ins_tmp_nodes_stmt, 1, id);
 
636
    sqlite3_bind_double (params->ins_tmp_nodes_stmt, 2, lat);
 
637
    sqlite3_bind_double (params->ins_tmp_nodes_stmt, 3, lon);
 
638
    ret = sqlite3_step (params->ins_tmp_nodes_stmt);
 
639
    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
640
        return;
 
641
    fprintf (stderr, "sqlite3_step() error: INS_TMP_NODES\n");
 
642
    sqlite3_finalize (params->ins_tmp_nodes_stmt);
 
643
    params->ins_tmp_nodes_stmt = NULL;
 
644
}
 
645
 
 
646
static void
 
647
end_node (struct aux_params *params)
 
648
{
 
649
    struct tag *p_tag;
 
650
    struct tag *p_tag2;
 
651
 
 
652
    tmp_nodes_insert (params, glob_node.id, glob_node.lat, glob_node.lon);
 
653
    eval_node (params);
 
654
    p_tag = glob_node.first;
 
655
    while (p_tag)
 
656
      {
 
657
          p_tag2 = p_tag->next;
 
658
          free_tag (p_tag);
 
659
          p_tag = p_tag2;
 
660
      }
 
661
    glob_node.id = -1;
 
662
    glob_node.lat = DBL_MAX;
 
663
    glob_node.lon = DBL_MAX;
 
664
    glob_node.first = NULL;
 
665
    glob_node.last = NULL;
 
666
    params->current_tag = CURRENT_TAG_UNKNOWN;
 
667
}
 
668
 
 
669
static void
 
670
start_way (struct aux_params *params, const char **attr)
 
671
{
 
672
    int i;
 
673
    glob_way.id = -1;
 
674
    glob_way.first_nd = NULL;
 
675
    glob_way.last_nd = NULL;
 
676
    glob_way.first = NULL;
 
677
    glob_way.last = NULL;
 
678
    for (i = 0; attr[i]; i += 2)
 
679
      {
 
680
          if (strcmp (attr[i], "id") == 0)
 
681
              glob_way.id = atol_64 (attr[i + 1]);
 
682
      }
 
683
    params->current_tag = CURRENT_TAG_IS_WAY;
 
684
}
 
685
 
 
686
static gaiaGeomCollPtr
 
687
build_linestring (sqlite3 * db_handle)
 
688
{
 
689
    gaiaGeomCollPtr geom;
 
690
    gaiaLinestringPtr ln;
 
691
    int points = 0;
 
692
    int tbd;
 
693
    int block = 128;
 
694
    int base = 0;
 
695
    int how_many;
 
696
    int ind;
 
697
    int ret;
 
698
    int count;
 
699
    char sql[8192];
 
700
    sqlite3_stmt *stmt;
 
701
    sqlite3_int64 id;
 
702
    double lat;
 
703
    double lon;
 
704
    struct nd *p_nd = glob_way.first_nd;
 
705
    while (p_nd)
 
706
      {
 
707
          points++;
 
708
          p_nd = p_nd->next;
 
709
      }
 
710
    if (!points)
 
711
        return NULL;
 
712
    geom = gaiaAllocGeomColl ();
 
713
    geom->Srid = 4326;
 
714
    ln = gaiaAddLinestringToGeomColl (geom, points);
 
715
    tbd = points;
 
716
    while (tbd > 0)
 
717
      {
 
718
          /* 
 
719
             / fetching node coords
 
720
             / requesting max 128 points at each time 
 
721
           */
 
722
          if (tbd < block)
 
723
              how_many = tbd;
 
724
          else
 
725
              how_many = block;
 
726
          strcpy (sql, "SELECT id, lat, lon FROM osm_tmp_nodes ");
 
727
          strcat (sql, "WHERE id IN (");
 
728
          for (ind = 0; ind < how_many; ind++)
 
729
            {
 
730
                if (ind == 0)
 
731
                    strcat (sql, "?");
 
732
                else
 
733
                    strcat (sql, ",?");
 
734
            }
 
735
          strcat (sql, ")");
 
736
          ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
 
737
          if (ret != SQLITE_OK)
 
738
            {
 
739
                fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
740
                         sqlite3_errmsg (db_handle));
 
741
                gaiaFreeGeomColl (geom);
 
742
                return NULL;
 
743
            }
 
744
          sqlite3_reset (stmt);
 
745
          sqlite3_clear_bindings (stmt);
 
746
          ind = 1;
 
747
          count = 0;
 
748
          p_nd = glob_way.first_nd;
 
749
          while (p_nd)
 
750
            {
 
751
                if (count < base)
 
752
                  {
 
753
                      count++;
 
754
                      p_nd = p_nd->next;
 
755
                      continue;
 
756
                  }
 
757
                if (count >= (base + how_many))
 
758
                    break;
 
759
                sqlite3_bind_int64 (stmt, ind, p_nd->ref);
 
760
                ind++;
 
761
                count++;
 
762
                p_nd = p_nd->next;
 
763
            }
 
764
          while (1)
 
765
            {
 
766
                /* scrolling the result set */
 
767
                ret = sqlite3_step (stmt);
 
768
                if (ret == SQLITE_DONE)
 
769
                  {
 
770
                      /* there are no more rows to fetch - we can stop looping */
 
771
                      break;
 
772
                  }
 
773
                if (ret == SQLITE_ROW)
 
774
                  {
 
775
                      /* ok, we've just fetched a valid row */
 
776
                      id = sqlite3_column_int64 (stmt, 0);
 
777
                      lat = sqlite3_column_double (stmt, 1);
 
778
                      lon = sqlite3_column_double (stmt, 2);
 
779
                      p_nd = glob_way.first_nd;
 
780
                      count = 0;
 
781
                      while (p_nd)
 
782
                        {
 
783
                            if (p_nd->ref == id)
 
784
                              {
 
785
                                  p_nd->found = 1;
 
786
                                  gaiaSetPoint (ln->Coords, count, lon, lat);
 
787
                              }
 
788
                            count++;
 
789
                            p_nd = p_nd->next;
 
790
                        }
 
791
                  }
 
792
                else
 
793
                  {
 
794
                      /* some unexpected error occurred */
 
795
                      fprintf (stderr, "sqlite3_step() error: %s\n",
 
796
                               sqlite3_errmsg (db_handle));
 
797
                      sqlite3_finalize (stmt);
 
798
                      gaiaFreeGeomColl (geom);
 
799
                  }
 
800
            }
 
801
          sqlite3_finalize (stmt);
 
802
          tbd -= how_many;
 
803
          base += how_many;
 
804
      }
 
805
 
 
806
/* final checkout */
 
807
    p_nd = glob_way.first_nd;
 
808
    while (p_nd)
 
809
      {
 
810
          if (p_nd->found == 0)
 
811
            {
 
812
#if defined(_WIN32) || defined(__MINGW32__)
 
813
                /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
 
814
                fprintf (stderr, "UNRESOLVED-NODE %I64d\n", p_nd->ref);
 
815
#else
 
816
                fprintf (stderr, "UNRESOLVED-NODE %lld\n", p_nd->ref);
 
817
#endif
 
818
                gaiaFreeGeomColl (geom);
 
819
                return NULL;
 
820
            }
 
821
          p_nd = p_nd->next;
 
822
      }
 
823
    return geom;
 
824
}
 
825
 
 
826
static void
 
827
line_layer_insert (struct aux_params *params, const char *layer_name,
 
828
                   sqlite3_int64 id, unsigned char *blob, int blob_size,
 
829
                   const char *sub_type, const char *name)
 
830
{
 
831
    struct layers *layer;
 
832
    int i = 0;
 
833
    while (1)
 
834
      {
 
835
          layer = &(base_layers[i++]);
 
836
          if (layer->name == NULL)
 
837
              return;
 
838
          if (strcmp (layer->name, layer_name) == 0)
 
839
            {
 
840
                if (layer->ok_linestring == 0)
 
841
                  {
 
842
                      layer->ok_linestring = 1;
 
843
                      create_linestring_table (params, layer);
 
844
                  }
 
845
                if (layer->ins_linestring_stmt)
 
846
                  {
 
847
                      int ret;
 
848
                      sqlite3_reset (layer->ins_linestring_stmt);
 
849
                      sqlite3_clear_bindings (layer->ins_linestring_stmt);
 
850
                      sqlite3_bind_int64 (layer->ins_linestring_stmt, 1, id);
 
851
                      if (sub_type == NULL)
 
852
                          sqlite3_bind_null (layer->ins_linestring_stmt, 2);
 
853
                      else
 
854
                          sqlite3_bind_text (layer->ins_linestring_stmt, 2,
 
855
                                             sub_type, strlen (sub_type),
 
856
                                             SQLITE_STATIC);
 
857
                      if (name == NULL)
 
858
                          sqlite3_bind_null (layer->ins_linestring_stmt, 3);
 
859
                      else
 
860
                          sqlite3_bind_text (layer->ins_linestring_stmt, 3,
 
861
                                             name, strlen (name),
 
862
                                             SQLITE_STATIC);
 
863
                      sqlite3_bind_blob (layer->ins_linestring_stmt, 4, blob,
 
864
                                         blob_size, SQLITE_STATIC);
 
865
                      ret = sqlite3_step (layer->ins_linestring_stmt);
 
866
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
867
                          return;
 
868
                      fprintf (stderr,
 
869
                               "sqlite3_step() error: INS_LINESTRING %s\n",
 
870
                               layer_name);
 
871
                      sqlite3_finalize (layer->ins_linestring_stmt);
 
872
                      layer->ins_linestring_stmt = NULL;
 
873
                  }
 
874
                return;
 
875
            }
 
876
      }
 
877
}
 
878
 
 
879
static void
 
880
polygon_layer_insert (struct aux_params *params, const char *layer_name,
 
881
                      sqlite3_int64 id, unsigned char *blob, int blob_size,
 
882
                      const char *sub_type, const char *name)
 
883
{
 
884
    struct layers *layer;
 
885
    int i = 0;
 
886
    while (1)
 
887
      {
 
888
          layer = &(base_layers[i++]);
 
889
          if (layer->name == NULL)
 
890
              return;
 
891
          if (strcmp (layer->name, layer_name) == 0)
 
892
            {
 
893
                if (layer->ok_polygon == 0)
 
894
                  {
 
895
                      layer->ok_polygon = 1;
 
896
                      create_polygon_table (params, layer);
 
897
                  }
 
898
                if (layer->ins_polygon_stmt)
 
899
                  {
 
900
                      int ret;
 
901
                      sqlite3_reset (layer->ins_polygon_stmt);
 
902
                      sqlite3_clear_bindings (layer->ins_polygon_stmt);
 
903
                      sqlite3_bind_int64 (layer->ins_polygon_stmt, 1, id);
 
904
                      if (sub_type == NULL)
 
905
                          sqlite3_bind_null (layer->ins_polygon_stmt, 2);
 
906
                      else
 
907
                          sqlite3_bind_text (layer->ins_polygon_stmt, 2,
 
908
                                             sub_type, strlen (sub_type),
 
909
                                             SQLITE_STATIC);
 
910
                      if (name == NULL)
 
911
                          sqlite3_bind_null (layer->ins_polygon_stmt, 3);
 
912
                      else
 
913
                          sqlite3_bind_text (layer->ins_polygon_stmt, 3, name,
 
914
                                             strlen (name), SQLITE_STATIC);
 
915
                      sqlite3_bind_blob (layer->ins_polygon_stmt, 4, blob,
 
916
                                         blob_size, SQLITE_STATIC);
 
917
                      ret = sqlite3_step (layer->ins_polygon_stmt);
 
918
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
919
                          return;
 
920
                      fprintf (stderr,
 
921
                               "sqlite3_step() error: INS_POLYGON %s\n",
 
922
                               layer_name);
 
923
                      sqlite3_finalize (layer->ins_polygon_stmt);
 
924
                      layer->ins_polygon_stmt = NULL;
 
925
                  }
 
926
                return;
 
927
            }
 
928
      }
 
929
}
 
930
 
 
931
static void
 
932
line_generic_insert (struct aux_params *params, sqlite3_int64 id,
 
933
                     unsigned char *blob, int blob_size, const char *name)
 
934
{
 
935
    if (params->ins_generic_linestring_stmt)
 
936
      {
 
937
          int ret;
 
938
          sqlite3_reset (params->ins_generic_linestring_stmt);
 
939
          sqlite3_clear_bindings (params->ins_generic_linestring_stmt);
 
940
          sqlite3_bind_int64 (params->ins_generic_linestring_stmt, 1, id);
 
941
          if (name == NULL)
 
942
              sqlite3_bind_null (params->ins_generic_linestring_stmt, 2);
 
943
          else
 
944
              sqlite3_bind_text (params->ins_generic_linestring_stmt, 2, name,
 
945
                                 strlen (name), SQLITE_STATIC);
 
946
          sqlite3_bind_blob (params->ins_generic_linestring_stmt, 3, blob,
 
947
                             blob_size, SQLITE_STATIC);
 
948
          ret = sqlite3_step (params->ins_generic_linestring_stmt);
 
949
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
950
              return;
 
951
          fprintf (stderr, "sqlite3_step() error: INS_GENERIC_LINESTRING\n");
 
952
          sqlite3_finalize (params->ins_generic_linestring_stmt);
 
953
          params->ins_generic_linestring_stmt = NULL;
 
954
      }
 
955
}
 
956
 
 
957
static void
 
958
polygon_generic_insert (struct aux_params *params, sqlite3_int64 id,
 
959
                        unsigned char *blob, int blob_size, const char *name)
 
960
{
 
961
    if (params->ins_generic_polygon_stmt)
 
962
      {
 
963
          int ret;
 
964
          sqlite3_reset (params->ins_generic_polygon_stmt);
 
965
          sqlite3_clear_bindings (params->ins_generic_polygon_stmt);
 
966
          sqlite3_bind_int64 (params->ins_generic_polygon_stmt, 1, id);
 
967
          if (name == NULL)
 
968
              sqlite3_bind_null (params->ins_generic_polygon_stmt, 2);
 
969
          else
 
970
              sqlite3_bind_text (params->ins_generic_polygon_stmt, 2, name,
 
971
                                 strlen (name), SQLITE_STATIC);
 
972
          sqlite3_bind_blob (params->ins_generic_polygon_stmt, 3, blob,
 
973
                             blob_size, SQLITE_STATIC);
 
974
          ret = sqlite3_step (params->ins_generic_polygon_stmt);
 
975
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
976
              return;
 
977
          fprintf (stderr, "sqlite3_step() error: INS_GENERIC_POLYGON\n");
 
978
          sqlite3_finalize (params->ins_generic_polygon_stmt);
 
979
          params->ins_generic_polygon_stmt = NULL;
 
980
      }
 
981
}
 
982
 
 
983
static void
 
984
tmp_ways_insert (struct aux_params *params, sqlite3_int64 id, int area,
 
985
                 unsigned char *blob, int blob_size)
 
986
{
 
987
    int ret;
 
988
    if (params->ins_tmp_ways_stmt == NULL)
 
989
        return;
 
990
    sqlite3_reset (params->ins_tmp_ways_stmt);
 
991
    sqlite3_clear_bindings (params->ins_tmp_ways_stmt);
 
992
    sqlite3_bind_int64 (params->ins_tmp_ways_stmt, 1, id);
 
993
    sqlite3_bind_int (params->ins_tmp_ways_stmt, 2, area);
 
994
    sqlite3_bind_blob (params->ins_tmp_ways_stmt, 3, blob, blob_size,
 
995
                       SQLITE_STATIC);
 
996
    ret = sqlite3_step (params->ins_tmp_ways_stmt);
 
997
 
 
998
    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
999
        return;
 
1000
    fprintf (stderr, "sqlite3_step() error: INS_TMP_WAYS\n");
 
1001
    sqlite3_finalize (params->ins_tmp_ways_stmt);
 
1002
    params->ins_tmp_ways_stmt = NULL;
 
1003
}
 
1004
 
 
1005
static void
 
1006
eval_way (struct aux_params *params, int area, unsigned char *blob,
 
1007
          int blob_size)
 
1008
{
 
1009
    struct tag *p_tag;
 
1010
    const char *p;
 
1011
    int i = 0;
 
1012
    const char *layer_name = NULL;
 
1013
    char *sub_type = NULL;
 
1014
    char *name = NULL;
 
1015
    if (glob_way.first == NULL)
 
1016
        return;
 
1017
    while (1)
 
1018
      {
 
1019
          p = base_layers[i++].name;
 
1020
          if (!p)
 
1021
              break;
 
1022
          p_tag = glob_way.first;
 
1023
          while (p_tag)
 
1024
            {
 
1025
                if (strcmp (p_tag->k, p) == 0)
 
1026
                  {
 
1027
                      layer_name = p;
 
1028
                      sub_type = p_tag->v;
 
1029
                  }
 
1030
                if (strcmp (p_tag->k, "name") == 0)
 
1031
                    name = p_tag->v;
 
1032
                p_tag = p_tag->next;
 
1033
            }
 
1034
          if (layer_name)
 
1035
              break;
 
1036
      }
 
1037
    if (layer_name)
 
1038
      {
 
1039
          if (area)
 
1040
              polygon_layer_insert (params, layer_name, glob_way.id, blob,
 
1041
                                    blob_size, sub_type, name);
 
1042
          else
 
1043
              line_layer_insert (params, layer_name, glob_way.id, blob,
 
1044
                                 blob_size, sub_type, name);
 
1045
          return;
 
1046
      }
 
1047
    else if (name != NULL)
 
1048
      {
 
1049
          if (area)
 
1050
              polygon_generic_insert (params, glob_way.id, blob, blob_size,
 
1051
                                      name);
 
1052
          else
 
1053
              line_generic_insert (params, glob_way.id, blob, blob_size, name);
 
1054
          return;
 
1055
      }
 
1056
}
 
1057
 
 
1058
static gaiaGeomCollPtr
 
1059
convert_to_polygon (gaiaGeomCollPtr old)
 
1060
{
 
1061
/* converting a LINESTRING as MULTIPOLYGON */
 
1062
    gaiaLinestringPtr ln = old->FirstLinestring;
 
1063
    gaiaPolygonPtr pg;
 
1064
    gaiaRingPtr rng;
 
1065
    int iv;
 
1066
    double x;
 
1067
    double y;
 
1068
    gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
 
1069
    geom->Srid = old->Srid;
 
1070
    geom->DeclaredType = GAIA_MULTIPOLYGON;
 
1071
    pg = gaiaAddPolygonToGeomColl (geom, ln->Points, 0);
 
1072
    rng = pg->Exterior;
 
1073
    for (iv = 0; iv < rng->Points; iv++)
 
1074
      {
 
1075
          gaiaGetPoint (ln->Coords, iv, &x, &y);
 
1076
          gaiaSetPoint (rng->Coords, iv, x, y);
 
1077
      }
 
1078
    gaiaFreeGeomColl (old);
 
1079
    return geom;
 
1080
}
 
1081
 
 
1082
static void
 
1083
end_way (struct aux_params *params)
 
1084
{
 
1085
    struct tag *p_tag;
 
1086
    struct tag *p_tag2;
 
1087
    struct nd *p_nd;
 
1088
    struct nd *p_nd2;
 
1089
    unsigned char *blob;
 
1090
    int blob_size;
 
1091
    int area;
 
1092
 
 
1093
    gaiaGeomCollPtr geom = build_linestring (params->db_handle);
 
1094
    if (geom)
 
1095
      {
 
1096
          geom->DeclaredType = GAIA_MULTILINESTRING;
 
1097
          gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1098
          tmp_ways_insert (params, glob_way.id, area, blob, blob_size);
 
1099
          area = 0;
 
1100
          p_tag = glob_way.first;
 
1101
          while (p_tag)
 
1102
            {
 
1103
                if (strcmp (p_tag->k, "area") == 0
 
1104
                    && strcmp (p_tag->v, "yes") == 0)
 
1105
                    area = 1;
 
1106
                p_tag = p_tag->next;
 
1107
            }
 
1108
          if (area)
 
1109
            {
 
1110
                free (blob);
 
1111
                geom = convert_to_polygon (geom);
 
1112
                gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1113
            }
 
1114
          gaiaFreeGeomColl (geom);
 
1115
          eval_way (params, area, blob, blob_size);
 
1116
          free (blob);
 
1117
      }
 
1118
    p_tag = glob_way.first;
 
1119
    while (p_tag)
 
1120
      {
 
1121
          p_tag2 = p_tag->next;
 
1122
          free_tag (p_tag);
 
1123
          p_tag = p_tag2;
 
1124
      }
 
1125
    p_nd = glob_way.first_nd;
 
1126
    while (p_nd)
 
1127
      {
 
1128
          p_nd2 = p_nd->next;
 
1129
          free (p_nd);
 
1130
          p_nd = p_nd2;
 
1131
      }
 
1132
    glob_way.id = -1;
 
1133
    glob_way.first_nd = NULL;
 
1134
    glob_way.last_nd = NULL;
 
1135
    glob_way.first = NULL;
 
1136
    glob_way.last = NULL;
 
1137
    params->current_tag = CURRENT_TAG_UNKNOWN;
 
1138
}
 
1139
 
 
1140
static void
 
1141
start_nd (const char **attr)
 
1142
{
 
1143
    struct nd *p_nd = malloc (sizeof (struct nd));
 
1144
    int i;
 
1145
    p_nd->ref = -1;
 
1146
    p_nd->found = 0;
 
1147
    p_nd->next = NULL;
 
1148
    for (i = 0; attr[i]; i += 2)
 
1149
      {
 
1150
          if (strcmp (attr[i], "ref") == 0)
 
1151
              p_nd->ref = atol_64 (attr[i + 1]);
 
1152
      }
 
1153
    if (glob_way.first_nd == NULL)
 
1154
        glob_way.first_nd = p_nd;
 
1155
    if (glob_way.last_nd != NULL)
 
1156
        glob_way.last_nd->next = p_nd;
 
1157
    glob_way.last_nd = p_nd;
 
1158
}
 
1159
 
 
1160
static void
 
1161
start_xtag (struct aux_params *params, const char **attr)
 
1162
{
 
1163
    struct tag *p_tag = malloc (sizeof (struct tag));
 
1164
    int i;
 
1165
    int len;
 
1166
    p_tag->k = NULL;
 
1167
    p_tag->v = NULL;
 
1168
    p_tag->next = NULL;
 
1169
    for (i = 0; attr[i]; i += 2)
 
1170
      {
 
1171
          if (strcmp (attr[i], "k") == 0)
 
1172
            {
 
1173
                len = strlen (attr[i + 1]);
 
1174
                p_tag->k = malloc (len + 1);
 
1175
                strcpy (p_tag->k, attr[i + 1]);
 
1176
            }
 
1177
          if (strcmp (attr[i], "v") == 0)
 
1178
            {
 
1179
                len = strlen (attr[i + 1]);
 
1180
                p_tag->v = malloc (len + 1);
 
1181
                strcpy (p_tag->v, attr[i + 1]);
 
1182
            }
 
1183
      }
 
1184
    if (params->current_tag == CURRENT_TAG_IS_NODE)
 
1185
      {
 
1186
          if (glob_node.first == NULL)
 
1187
              glob_node.first = p_tag;
 
1188
          if (glob_node.last != NULL)
 
1189
              glob_node.last->next = p_tag;
 
1190
          glob_node.last = p_tag;
 
1191
      }
 
1192
    if (params->current_tag == CURRENT_TAG_IS_WAY)
 
1193
      {
 
1194
          if (glob_way.first == NULL)
 
1195
              glob_way.first = p_tag;
 
1196
          if (glob_way.last != NULL)
 
1197
              glob_way.last->next = p_tag;
 
1198
          glob_way.last = p_tag;
 
1199
      }
 
1200
    if (params->current_tag == CURRENT_TAG_IS_RELATION)
 
1201
      {
 
1202
          if (glob_relation.first == NULL)
 
1203
              glob_relation.first = p_tag;
 
1204
          if (glob_relation.last != NULL)
 
1205
              glob_relation.last->next = p_tag;
 
1206
          glob_relation.last = p_tag;
 
1207
      }
 
1208
}
 
1209
 
 
1210
static void
 
1211
start_member (const char **attr)
 
1212
{
 
1213
    struct member *p_member = malloc (sizeof (struct member));
 
1214
    int i;
 
1215
    int len;
 
1216
    p_member->ref = -1;
 
1217
    p_member->is_node = 0;
 
1218
    p_member->is_way = 0;
 
1219
    p_member->found = 0;
 
1220
    p_member->role = NULL;
 
1221
    p_member->next = NULL;
 
1222
    for (i = 0; attr[i]; i += 2)
 
1223
      {
 
1224
          if (strcmp (attr[i], "type") == 0)
 
1225
            {
 
1226
                if (strcmp (attr[i + 1], "node") == 0)
 
1227
                  {
 
1228
                      p_member->is_node = 1;
 
1229
                      p_member->is_way = 0;
 
1230
                  }
 
1231
                else if (strcmp (attr[i + 1], "way") == 0)
 
1232
                  {
 
1233
                      p_member->is_node = 0;
 
1234
                      p_member->is_way = 1;
 
1235
                  }
 
1236
                else
 
1237
                  {
 
1238
                      p_member->is_node = 0;
 
1239
                      p_member->is_way = 0;
 
1240
                  }
 
1241
            }
 
1242
          if (strcmp (attr[i], "ref") == 0)
 
1243
              p_member->ref = atol_64 (attr[i + 1]);
 
1244
          if (strcmp (attr[i], "role") == 0)
 
1245
            {
 
1246
                len = strlen (attr[i + 1]);
 
1247
                p_member->role = malloc (len + 1);
 
1248
                strcpy (p_member->role, attr[i + 1]);
 
1249
            }
 
1250
      }
 
1251
    if (glob_relation.first_member == NULL)
 
1252
        glob_relation.first_member = p_member;
 
1253
    if (glob_relation.last_member != NULL)
 
1254
        glob_relation.last_member->next = p_member;
 
1255
    glob_relation.last_member = p_member;
 
1256
}
 
1257
 
 
1258
static void
 
1259
start_relation (struct aux_params *params, const char **attr)
 
1260
{
 
1261
    int i;
 
1262
    glob_relation.id = -1;
 
1263
    glob_relation.first_member = NULL;
 
1264
    glob_relation.last_member = NULL;
 
1265
    glob_relation.first = NULL;
 
1266
    glob_relation.last = NULL;
 
1267
    for (i = 0; attr[i]; i += 2)
 
1268
      {
 
1269
          if (strcmp (attr[i], "id") == 0)
 
1270
              glob_relation.id = atol_64 (attr[i + 1]);
 
1271
      }
 
1272
    params->current_tag = CURRENT_TAG_IS_RELATION;
 
1273
}
 
1274
 
 
1275
static gaiaGeomCollPtr
 
1276
build_multilinestring (sqlite3 * db_handle)
 
1277
{
 
1278
    gaiaGeomCollPtr geom;
 
1279
    int lines = 0;
 
1280
    int tbd;
 
1281
    int block = 128;
 
1282
    int base = 0;
 
1283
    int how_many;
 
1284
    int ind;
 
1285
    int ret;
 
1286
    int count;
 
1287
    char sql[8192];
 
1288
    sqlite3_stmt *stmt;
 
1289
    sqlite3_int64 id;
 
1290
    const unsigned char *blob = NULL;
 
1291
    int blob_size;
 
1292
    gaiaGeomCollPtr org_geom;
 
1293
    struct member *p_member = glob_relation.first_member;
 
1294
    while (p_member)
 
1295
      {
 
1296
          lines++;
 
1297
          p_member = p_member->next;
 
1298
      }
 
1299
    if (!lines)
 
1300
        return NULL;
 
1301
    geom = gaiaAllocGeomColl ();
 
1302
    geom->Srid = 4326;
 
1303
    geom->DeclaredType = GAIA_MULTILINESTRING;
 
1304
    tbd = lines;
 
1305
    while (tbd > 0)
 
1306
      {
 
1307
          /* 
 
1308
             / fetching ways
 
1309
             / requesting max 128 points at each time 
 
1310
           */
 
1311
          if (tbd < block)
 
1312
              how_many = tbd;
 
1313
          else
 
1314
              how_many = block;
 
1315
          strcpy (sql, "SELECT id, Geometry FROM osm_tmp_ways ");
 
1316
          strcat (sql, "WHERE id IN (");
 
1317
          for (ind = 0; ind < how_many; ind++)
 
1318
            {
 
1319
                if (ind == 0)
 
1320
                    strcat (sql, "?");
 
1321
                else
 
1322
                    strcat (sql, ",?");
 
1323
            }
 
1324
          strcat (sql, ")");
 
1325
          ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
 
1326
          if (ret != SQLITE_OK)
 
1327
            {
 
1328
                fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
1329
                         sqlite3_errmsg (db_handle));
 
1330
                gaiaFreeGeomColl (geom);
 
1331
                return NULL;
 
1332
            }
 
1333
          sqlite3_reset (stmt);
 
1334
          sqlite3_clear_bindings (stmt);
 
1335
          ind = 1;
 
1336
          count = 0;
 
1337
          p_member = glob_relation.first_member;
 
1338
          while (p_member)
 
1339
            {
 
1340
                if (count < base)
 
1341
                  {
 
1342
                      count++;
 
1343
                      p_member = p_member->next;
 
1344
                      continue;
 
1345
                  }
 
1346
                if (count >= (base + how_many))
 
1347
                    break;
 
1348
                sqlite3_bind_int64 (stmt, ind, p_member->ref);
 
1349
                ind++;
 
1350
                count++;
 
1351
                p_member = p_member->next;
 
1352
            }
 
1353
          while (1)
 
1354
            {
 
1355
                /* scrolling the result set */
 
1356
                ret = sqlite3_step (stmt);
 
1357
                if (ret == SQLITE_DONE)
 
1358
                  {
 
1359
                      /* there are no more rows to fetch - we can stop looping */
 
1360
                      break;
 
1361
                  }
 
1362
                if (ret == SQLITE_ROW)
 
1363
                  {
 
1364
                      /* ok, we've just fetched a valid row */
 
1365
                      id = sqlite3_column_int64 (stmt, 0);
 
1366
                      blob = sqlite3_column_blob (stmt, 1);
 
1367
                      blob_size = sqlite3_column_bytes (stmt, 1);
 
1368
                      org_geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_size);
 
1369
 
 
1370
                      if (org_geom)
 
1371
                        {
 
1372
                            p_member = glob_relation.first_member;
 
1373
                            count = 0;
 
1374
                            while (p_member)
 
1375
                              {
 
1376
                                  if (p_member->ref == id)
 
1377
                                    {
 
1378
                                        gaiaLinestringPtr ln1;
 
1379
                                        p_member->found = 1;
 
1380
                                        ln1 = org_geom->FirstLinestring;
 
1381
                                        while (ln1)
 
1382
                                          {
 
1383
                                              int iv;
 
1384
                                              gaiaLinestringPtr ln2 =
 
1385
                                                  gaiaAddLinestringToGeomColl
 
1386
                                                  (geom, ln1->Points);
 
1387
                                              for (iv = 0; iv < ln2->Points;
 
1388
                                                   iv++)
 
1389
                                                {
 
1390
                                                    double x;
 
1391
                                                    double y;
 
1392
                                                    gaiaGetPoint (ln1->Coords,
 
1393
                                                                  iv, &x, &y);
 
1394
                                                    gaiaSetPoint (ln2->Coords,
 
1395
                                                                  iv, x, y);
 
1396
                                                }
 
1397
                                              ln1 = ln1->Next;
 
1398
                                          }
 
1399
                                    }
 
1400
                                  count++;
 
1401
                                  p_member = p_member->next;
 
1402
                              }
 
1403
                            gaiaFreeGeomColl (org_geom);
 
1404
                        }
 
1405
                  }
 
1406
                else
 
1407
                  {
 
1408
                      /* some unexpected error occurred */
 
1409
                      fprintf (stderr, "sqlite3_step() error: %s\n",
 
1410
                               sqlite3_errmsg (db_handle));
 
1411
                      sqlite3_finalize (stmt);
 
1412
                      gaiaFreeGeomColl (geom);
 
1413
                  }
 
1414
            }
 
1415
          sqlite3_finalize (stmt);
 
1416
          tbd -= how_many;
 
1417
          base += how_many;
 
1418
      }
 
1419
 
 
1420
/* final checkout */
 
1421
    p_member = glob_relation.first_member;
 
1422
    while (p_member)
 
1423
      {
 
1424
          if (p_member->found == 0)
 
1425
            {
 
1426
#if defined(_WIN32) || defined(__MINGW32__)
 
1427
                /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
 
1428
                fprintf (stderr, "UNRESOLVED-WAY %I64d\n", p_member->ref);
 
1429
#else
 
1430
                fprintf (stderr, "UNRESOLVED-WAY %lld\n", p_member->ref);
 
1431
#endif
 
1432
                gaiaFreeGeomColl (geom);
 
1433
                return NULL;
 
1434
            }
 
1435
          p_member = p_member->next;
 
1436
      }
 
1437
    return geom;
 
1438
}
 
1439
 
 
1440
static void
 
1441
multiline_layer_insert (struct aux_params *params, const char *layer_name,
 
1442
                        const char *sub_type, const char *name)
 
1443
{
 
1444
    gaiaGeomCollPtr geom;
 
1445
    unsigned char *blob = NULL;
 
1446
    int blob_size;
 
1447
    struct layers *layer;
 
1448
    int i = 0;
 
1449
    while (1)
 
1450
      {
 
1451
          layer = &(base_layers[i++]);
 
1452
          if (layer->name == NULL)
 
1453
              return;
 
1454
          if (strcmp (layer->name, layer_name) == 0)
 
1455
            {
 
1456
                if (layer->ok_linestring == 0)
 
1457
                  {
 
1458
                      layer->ok_linestring = 1;
 
1459
                      create_linestring_table (params, layer);
 
1460
                  }
 
1461
                geom = build_multilinestring (params->db_handle);
 
1462
                if (geom)
 
1463
                  {
 
1464
                      gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1465
                      gaiaFreeGeomColl (geom);
 
1466
                  }
 
1467
                if (layer->ins_linestring_stmt && blob)
 
1468
                  {
 
1469
                      int ret;
 
1470
                      sqlite3_reset (layer->ins_linestring_stmt);
 
1471
                      sqlite3_clear_bindings (layer->ins_linestring_stmt);
 
1472
                      sqlite3_bind_int64 (layer->ins_linestring_stmt, 1,
 
1473
                                          glob_relation.id);
 
1474
                      if (sub_type == NULL)
 
1475
                          sqlite3_bind_null (layer->ins_linestring_stmt, 2);
 
1476
                      else
 
1477
                          sqlite3_bind_text (layer->ins_linestring_stmt, 2,
 
1478
                                             sub_type, strlen (sub_type),
 
1479
                                             SQLITE_STATIC);
 
1480
                      if (name == NULL)
 
1481
                          sqlite3_bind_null (layer->ins_linestring_stmt, 3);
 
1482
                      else
 
1483
                          sqlite3_bind_text (layer->ins_linestring_stmt, 3,
 
1484
                                             name, strlen (name),
 
1485
                                             SQLITE_STATIC);
 
1486
                      sqlite3_bind_blob (layer->ins_linestring_stmt, 4, blob,
 
1487
                                         blob_size, free);
 
1488
                      ret = sqlite3_step (layer->ins_linestring_stmt);
 
1489
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
1490
                          return;
 
1491
                      fprintf (stderr,
 
1492
                               "sqlite3_step() error: INS_MULTILINESTRING %s\n",
 
1493
                               layer_name);
 
1494
                      sqlite3_finalize (layer->ins_linestring_stmt);
 
1495
                      layer->ins_linestring_stmt = NULL;
 
1496
                  }
 
1497
                return;
 
1498
            }
 
1499
      }
 
1500
}
 
1501
 
 
1502
static gaiaGeomCollPtr
 
1503
build_multipolygon (sqlite3 * db_handle)
 
1504
{
 
1505
    gaiaGeomCollPtr geom;
 
1506
    gaiaPolygonPtr pg2 = NULL;
 
1507
    int rings = 0;
 
1508
    int interiors = 0;
 
1509
    int exteriors = 0;
 
1510
    int ext_pts;
 
1511
    int ib = 0;
 
1512
    int tbd;
 
1513
    int block = 128;
 
1514
    int base = 0;
 
1515
    int how_many;
 
1516
    int ind;
 
1517
    int ret;
 
1518
    int count;
 
1519
    char sql[8192];
 
1520
    sqlite3_stmt *stmt;
 
1521
    sqlite3_int64 id;
 
1522
    int area;
 
1523
 
 
1524
    const unsigned char *blob = NULL;
 
1525
    int blob_size;
 
1526
    gaiaGeomCollPtr org_geom;
 
1527
    struct member *p_member = glob_relation.first_member;
 
1528
    while (p_member)
 
1529
      {
 
1530
          rings++;
 
1531
          if (p_member->role)
 
1532
            {
 
1533
                if (strcmp (p_member->role, "inner") == 0)
 
1534
                    interiors++;
 
1535
                if (strcmp (p_member->role, "outer") == 0)
 
1536
                    exteriors++;
 
1537
            }
 
1538
          p_member = p_member->next;
 
1539
      }
 
1540
    if (!rings)
 
1541
        return NULL;
 
1542
    if (exteriors != 1)
 
1543
        return NULL;
 
1544
    if (interiors + 1 != rings)
 
1545
        return NULL;
 
1546
    geom = gaiaAllocGeomColl ();
 
1547
    geom->Srid = 4326;
 
1548
    geom->DeclaredType = GAIA_MULTIPOLYGON;
 
1549
    tbd = rings;
 
1550
    while (tbd > 0)
 
1551
      {
 
1552
          /* 
 
1553
             / fetching ways
 
1554
             / requesting max 128 points at each time 
 
1555
           */
 
1556
          if (tbd < block)
 
1557
              how_many = tbd;
 
1558
          else
 
1559
              how_many = block;
 
1560
          strcpy (sql, "SELECT id, area, Geometry FROM osm_tmp_ways ");
 
1561
          strcat (sql, "WHERE id IN (");
 
1562
          for (ind = 0; ind < how_many; ind++)
 
1563
            {
 
1564
                if (ind == 0)
 
1565
                    strcat (sql, "?");
 
1566
                else
 
1567
                    strcat (sql, ",?");
 
1568
            }
 
1569
          strcat (sql, ")");
 
1570
          ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
 
1571
          if (ret != SQLITE_OK)
 
1572
            {
 
1573
                fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
1574
                         sqlite3_errmsg (db_handle));
 
1575
                gaiaFreeGeomColl (geom);
 
1576
                return NULL;
 
1577
            }
 
1578
          sqlite3_reset (stmt);
 
1579
          sqlite3_clear_bindings (stmt);
 
1580
          ind = 1;
 
1581
          count = 0;
 
1582
          p_member = glob_relation.first_member;
 
1583
          while (p_member)
 
1584
            {
 
1585
                if (count < base)
 
1586
                  {
 
1587
                      count++;
 
1588
                      p_member = p_member->next;
 
1589
                      continue;
 
1590
                  }
 
1591
                if (count >= (base + how_many))
 
1592
                    break;
 
1593
                sqlite3_bind_int64 (stmt, ind, p_member->ref);
 
1594
                ind++;
 
1595
                count++;
 
1596
                p_member = p_member->next;
 
1597
            }
 
1598
          while (1)
 
1599
            {
 
1600
                /* scrolling the result set */
 
1601
                ret = sqlite3_step (stmt);
 
1602
                if (ret == SQLITE_DONE)
 
1603
                  {
 
1604
                      /* there are no more rows to fetch - we can stop looping */
 
1605
                      break;
 
1606
                  }
 
1607
                if (ret == SQLITE_ROW)
 
1608
                  {
 
1609
                      /* ok, we've just fetched a valid row */
 
1610
                      id = sqlite3_column_int64 (stmt, 0);
 
1611
                      area = sqlite3_column_int (stmt, 1);
 
1612
                      blob = sqlite3_column_blob (stmt, 2);
 
1613
                      blob_size = sqlite3_column_bytes (stmt, 2);
 
1614
                      org_geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_size);
 
1615
                      if (org_geom)
 
1616
                        {
 
1617
                            while (p_member)
 
1618
                              {
 
1619
                                  if (p_member->ref == id)
 
1620
                                    {
 
1621
                                        p_member->geom = org_geom;
 
1622
                                        p_member->found = 1;
 
1623
                                    }
 
1624
                                  p_member = p_member->next;
 
1625
                              }
 
1626
                        }
 
1627
                  }
 
1628
                else
 
1629
                  {
 
1630
                      /* some unexpected error occurred */
 
1631
                      fprintf (stderr, "sqlite3_step() error: %s\n",
 
1632
                               sqlite3_errmsg (db_handle));
 
1633
                      sqlite3_finalize (stmt);
 
1634
                      gaiaFreeGeomColl (geom);
 
1635
                  }
 
1636
            }
 
1637
          sqlite3_finalize (stmt);
 
1638
          tbd -= how_many;
 
1639
          base += how_many;
 
1640
      }
 
1641
 
 
1642
/* final checkout */
 
1643
    ext_pts = 0;
 
1644
    p_member = glob_relation.first_member;
 
1645
    while (p_member)
 
1646
      {
 
1647
          if (p_member->found == 0)
 
1648
            {
 
1649
#if defined(_WIN32) || defined(__MINGW32__)
 
1650
                /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
 
1651
                fprintf (stderr, "UNRESOLVED-WAY %I64d\n", p_member->ref);
 
1652
#else
 
1653
                fprintf (stderr, "UNRESOLVED-WAY %lld\n", p_member->ref);
 
1654
#endif
 
1655
                gaiaFreeGeomColl (geom);
 
1656
                return NULL;
 
1657
            }
 
1658
          if (strcmp (p_member->role, "outer") == 0)
 
1659
            {
 
1660
                if (p_member->geom)
 
1661
                  {
 
1662
                      if (p_member->geom->FirstPolygon)
 
1663
                          ext_pts =
 
1664
                              p_member->geom->FirstPolygon->Exterior->Points;
 
1665
                  }
 
1666
            }
 
1667
          p_member = p_member->next;
 
1668
      }
 
1669
    if (!ext_pts)
 
1670
      {
 
1671
#if defined(_WIN32) || defined(__MINGW32__)
 
1672
          /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
 
1673
          fprintf (stderr, "ILLEGAL MULTIPOLYGON %I64d\n", p_member->ref);
 
1674
#else
 
1675
          fprintf (stderr, "ILLEGAL MULTIPOLYGON %lld\n", p_member->ref);
 
1676
#endif
 
1677
          gaiaFreeGeomColl (geom);
 
1678
          return NULL;
 
1679
      }
 
1680
 
 
1681
    pg2 = gaiaAddPolygonToGeomColl (geom, ext_pts, interiors);
 
1682
    p_member = glob_relation.first_member;
 
1683
    while (p_member)
 
1684
      {
 
1685
          gaiaPolygonPtr pg1;
 
1686
          pg1 = org_geom->FirstPolygon;
 
1687
          while (pg1)
 
1688
            {
 
1689
                int iv;
 
1690
                gaiaRingPtr rng1 = pg1->Exterior;
 
1691
                gaiaRingPtr rng2;
 
1692
                if (strcmp (p_member->role, "outer") == 0)
 
1693
                    rng2 = pg2->Exterior;
 
1694
                else
 
1695
                    rng2 = pg2->Interiors + ib++;
 
1696
                for (iv = 0; iv < rng2->Points; iv++)
 
1697
                  {
 
1698
                      double x;
 
1699
                      double y;
 
1700
                      gaiaGetPoint (rng1->Coords, iv, &x, &y);
 
1701
                      gaiaSetPoint (rng2->Coords, iv, x, y);
 
1702
                  }
 
1703
                pg1 = pg1->Next;
 
1704
            }
 
1705
          p_member = p_member->next;
 
1706
      }
 
1707
    return geom;
 
1708
}
 
1709
 
 
1710
static void
 
1711
multipolygon_layer_insert (struct aux_params *params, const char *layer_name,
 
1712
                           const char *sub_type, const char *name)
 
1713
{
 
1714
    gaiaGeomCollPtr geom;
 
1715
    unsigned char *blob = NULL;
 
1716
    int blob_size;
 
1717
    struct layers *layer;
 
1718
    int i = 0;
 
1719
    while (1)
 
1720
      {
 
1721
          layer = &(base_layers[i++]);
 
1722
          if (layer->name == NULL)
 
1723
              return;
 
1724
          if (strcmp (layer->name, layer_name) == 0)
 
1725
            {
 
1726
                if (layer->ok_polygon == 0)
 
1727
                  {
 
1728
                      layer->ok_polygon = 1;
 
1729
                      create_polygon_table (params, layer);
 
1730
                  }
 
1731
                geom = build_multipolygon (params->db_handle);
 
1732
                if (geom)
 
1733
                  {
 
1734
                      gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1735
                      gaiaFreeGeomColl (geom);
 
1736
                  }
 
1737
                if (layer->ins_polygon_stmt)
 
1738
                  {
 
1739
                      int ret;
 
1740
                      sqlite3_reset (layer->ins_polygon_stmt);
 
1741
                      sqlite3_clear_bindings (layer->ins_polygon_stmt);
 
1742
                      sqlite3_bind_int64 (layer->ins_polygon_stmt, 1,
 
1743
                                          glob_relation.id);
 
1744
                      if (sub_type == NULL)
 
1745
                          sqlite3_bind_null (layer->ins_polygon_stmt, 2);
 
1746
                      else
 
1747
                          sqlite3_bind_text (layer->ins_polygon_stmt, 2,
 
1748
                                             sub_type, strlen (sub_type),
 
1749
                                             SQLITE_STATIC);
 
1750
                      if (name == NULL)
 
1751
                          sqlite3_bind_null (layer->ins_polygon_stmt, 3);
 
1752
                      else
 
1753
                          sqlite3_bind_text (layer->ins_polygon_stmt, 3, name,
 
1754
                                             strlen (name), SQLITE_STATIC);
 
1755
                      sqlite3_bind_blob (layer->ins_polygon_stmt, 4, blob,
 
1756
                                         blob_size, SQLITE_STATIC);
 
1757
                      ret = sqlite3_step (layer->ins_polygon_stmt);
 
1758
                      if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
1759
                          return;
 
1760
                      fprintf (stderr,
 
1761
                               "sqlite3_step() error: INS_MULTIPOLYGON %s\n",
 
1762
                               layer_name);
 
1763
                      sqlite3_finalize (layer->ins_polygon_stmt);
 
1764
                      layer->ins_polygon_stmt = NULL;
 
1765
                  }
 
1766
                return;
 
1767
            }
 
1768
      }
 
1769
}
 
1770
 
 
1771
static void
 
1772
multiline_generic_insert (struct aux_params *params, const char *name)
 
1773
{
 
1774
    gaiaGeomCollPtr geom;
 
1775
    unsigned char *blob = NULL;
 
1776
    int blob_size;
 
1777
    geom = build_multilinestring (params->db_handle);
 
1778
    if (geom)
 
1779
      {
 
1780
          gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1781
          gaiaFreeGeomColl (geom);
 
1782
      }
 
1783
    if (params->ins_generic_linestring_stmt && blob)
 
1784
      {
 
1785
          int ret;
 
1786
          sqlite3_reset (params->ins_generic_linestring_stmt);
 
1787
          sqlite3_clear_bindings (params->ins_generic_linestring_stmt);
 
1788
          sqlite3_bind_int64 (params->ins_generic_linestring_stmt, 1,
 
1789
                              glob_relation.id);
 
1790
          if (name == NULL)
 
1791
              sqlite3_bind_null (params->ins_generic_linestring_stmt, 2);
 
1792
          else
 
1793
              sqlite3_bind_text (params->ins_generic_linestring_stmt, 2, name,
 
1794
                                 strlen (name), SQLITE_STATIC);
 
1795
          sqlite3_bind_blob (params->ins_generic_linestring_stmt, 3, blob,
 
1796
                             blob_size, SQLITE_STATIC);
 
1797
          ret = sqlite3_step (params->ins_generic_linestring_stmt);
 
1798
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
1799
              return;
 
1800
          fprintf (stderr,
 
1801
                   "sqlite3_step() error: INS_GENERIC_MULTILINESTRING\n");
 
1802
          sqlite3_finalize (params->ins_generic_linestring_stmt);
 
1803
          params->ins_generic_linestring_stmt = NULL;
 
1804
      }
 
1805
}
 
1806
 
 
1807
static void
 
1808
multipolygon_generic_insert (struct aux_params *params, const char *name)
 
1809
{
 
1810
    gaiaGeomCollPtr geom;
 
1811
    unsigned char *blob = NULL;
 
1812
    int blob_size;
 
1813
    geom = build_multipolygon (params->db_handle);
 
1814
    if (geom)
 
1815
      {
 
1816
          gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
 
1817
          gaiaFreeGeomColl (geom);
 
1818
      }
 
1819
    if (params->ins_generic_polygon_stmt && blob)
 
1820
      {
 
1821
          int ret;
 
1822
          sqlite3_reset (params->ins_generic_polygon_stmt);
 
1823
          sqlite3_clear_bindings (params->ins_generic_polygon_stmt);
 
1824
          sqlite3_bind_int64 (params->ins_generic_polygon_stmt, 1,
 
1825
                              glob_relation.id);
 
1826
          if (name == NULL)
 
1827
              sqlite3_bind_null (params->ins_generic_polygon_stmt, 2);
 
1828
          else
 
1829
              sqlite3_bind_text (params->ins_generic_polygon_stmt, 2, name,
 
1830
                                 strlen (name), SQLITE_STATIC);
 
1831
          sqlite3_bind_blob (params->ins_generic_polygon_stmt, 3, blob,
 
1832
                             blob_size, SQLITE_STATIC);
 
1833
          ret = sqlite3_step (params->ins_generic_polygon_stmt);
 
1834
          if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 
1835
              return;
 
1836
          fprintf (stderr, "sqlite3_step() error: INS_GENERIC_MULTIPOLYGON\n");
 
1837
          sqlite3_finalize (params->ins_generic_polygon_stmt);
 
1838
          params->ins_generic_polygon_stmt = NULL;
 
1839
      }
 
1840
}
 
1841
 
 
1842
static void
 
1843
eval_relation (struct aux_params *params)
 
1844
{
 
1845
    struct tag *p_tag;
 
1846
    const char *p;
 
1847
    int i = 0;
 
1848
    const char *layer_name = NULL;
 
1849
    char *sub_type = NULL;
 
1850
    char *name = NULL;
 
1851
    int multipolygon = 0;
 
1852
    if (glob_relation.first == NULL)
 
1853
        return;
 
1854
    while (1)
 
1855
      {
 
1856
          p = base_layers[i++].name;
 
1857
          if (!p)
 
1858
              break;
 
1859
          p_tag = glob_relation.first;
 
1860
          while (p_tag)
 
1861
            {
 
1862
                if (strcmp (p_tag->k, p) == 0)
 
1863
                  {
 
1864
                      layer_name = p;
 
1865
                      sub_type = p_tag->v;
 
1866
                  }
 
1867
                if (strcmp (p_tag->k, "name") == 0)
 
1868
                    name = p_tag->v;
 
1869
                if (strcmp (p_tag->k, "type") == 0
 
1870
                    && strcmp (p_tag->v, "multipolygon") == 0)
 
1871
                    multipolygon = 1;
 
1872
                p_tag = p_tag->next;
 
1873
            }
 
1874
          if (layer_name)
 
1875
              break;
 
1876
      }
 
1877
    if (layer_name)
 
1878
      {
 
1879
          if (multipolygon)
 
1880
              multipolygon_layer_insert (params, layer_name, sub_type, name);
 
1881
          else
 
1882
              multiline_layer_insert (params, layer_name, sub_type, name);
 
1883
          return;
 
1884
      }
 
1885
    else if (name != NULL)
 
1886
      {
 
1887
          if (multipolygon)
 
1888
              multipolygon_generic_insert (params, name);
 
1889
          else
 
1890
              multiline_generic_insert (params, name);
 
1891
          return;
 
1892
      }
 
1893
}
 
1894
 
 
1895
static void
 
1896
end_relation (struct aux_params *params)
 
1897
{
 
1898
    struct tag *p_tag;
 
1899
    struct tag *p_tag2;
 
1900
    struct member *p_member;
 
1901
    struct member *p_member2;
 
1902
    eval_relation (params);
 
1903
    p_tag = glob_relation.first;
 
1904
    while (p_tag)
 
1905
      {
 
1906
          p_tag2 = p_tag->next;
 
1907
          free_tag (p_tag);
 
1908
          p_tag = p_tag2;
 
1909
      }
 
1910
    p_member = glob_relation.first_member;
 
1911
    while (p_member)
 
1912
      {
 
1913
          p_member2 = p_member->next;
 
1914
          free_member (p_member);
 
1915
          p_member = p_member2;
 
1916
      }
 
1917
    glob_relation.id = -1;
 
1918
    glob_relation.first_member = NULL;
 
1919
    glob_relation.last_member = NULL;
 
1920
    glob_relation.first = NULL;
 
1921
    glob_relation.last = NULL;
 
1922
    params->current_tag = CURRENT_TAG_UNKNOWN;
 
1923
}
 
1924
 
 
1925
static void
 
1926
start_tag (void *data, const char *el, const char **attr)
 
1927
{
 
1928
    struct aux_params *params = (struct aux_params *) data;
 
1929
    if (strcmp (el, "node") == 0)
 
1930
        start_node (params, attr);
 
1931
    if (strcmp (el, "tag") == 0)
 
1932
        start_xtag (params, attr);
 
1933
    if (strcmp (el, "way") == 0)
 
1934
        start_way (params, attr);
 
1935
    if (strcmp (el, "nd") == 0)
 
1936
        start_nd (attr);
 
1937
    if (strcmp (el, "relation") == 0)
 
1938
        start_relation (params, attr);
 
1939
    if (strcmp (el, "member") == 0)
 
1940
        start_member (attr);
 
1941
}
 
1942
 
 
1943
static void
 
1944
end_tag (void *data, const char *el)
 
1945
{
 
1946
    struct aux_params *params = (struct aux_params *) data;
 
1947
    if (strcmp (el, "node") == 0)
 
1948
        end_node (params);
 
1949
    if (strcmp (el, "way") == 0)
 
1950
        end_way (params);
 
1951
    if (strcmp (el, "relation") == 0)
 
1952
        end_relation (params);
 
1953
}
 
1954
 
 
1955
static void
 
1956
db_vacuum (sqlite3 * db_handle)
 
1957
{
 
1958
    int ret;
 
1959
    char *sql_err = NULL;
 
1960
/* VACUUMing the DB */
 
1961
    printf ("\nVACUUMing the DB ... wait please ...\n");
 
1962
    ret = sqlite3_exec (db_handle, "VACUUM", NULL, NULL, &sql_err);
 
1963
    if (ret != SQLITE_OK)
 
1964
      {
 
1965
          fprintf (stderr, "VACUUM error: %s\n", sql_err);
 
1966
          sqlite3_free (sql_err);
 
1967
          return;
 
1968
      }
 
1969
    printf ("\tAll done: OSM map was successfully loaded\n");
 
1970
}
 
1971
 
 
1972
static void
 
1973
spatialite_autocreate (sqlite3 * db)
 
1974
{
 
1975
/* attempting to perform self-initialization for a newly created DB */
 
1976
    int ret;
 
1977
    char sql[1024];
 
1978
    char *err_msg = NULL;
 
1979
    int count;
 
1980
    int i;
 
1981
    char **results;
 
1982
    int rows;
 
1983
    int columns;
 
1984
 
 
1985
/* checking if this DB is really empty */
 
1986
    strcpy (sql, "SELECT Count(*) from sqlite_master");
 
1987
    ret = sqlite3_get_table (db, sql, &results, &rows, &columns, NULL);
 
1988
    if (ret != SQLITE_OK)
 
1989
        return;
 
1990
    if (rows < 1)
 
1991
        ;
 
1992
    else
 
1993
      {
 
1994
          for (i = 1; i <= rows; i++)
 
1995
              count = atoi (results[(i * columns) + 0]);
 
1996
      }
 
1997
    sqlite3_free_table (results);
 
1998
 
 
1999
    if (count > 0)
 
2000
        return;
 
2001
 
 
2002
/* all right, it's empty: proceding to initialize */
 
2003
    strcpy (sql, "SELECT InitSpatialMetadata()");
 
2004
    ret = sqlite3_exec (db, sql, NULL, NULL, &err_msg);
 
2005
    if (ret != SQLITE_OK)
 
2006
      {
 
2007
          fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
 
2008
          sqlite3_free (err_msg);
 
2009
          return;
 
2010
      }
 
2011
}
 
2012
 
 
2013
static void
 
2014
open_db (const char *path, sqlite3 ** handle, int cache_size)
 
2015
{
 
2016
/* opening the DB */
 
2017
    sqlite3 *db_handle;
 
2018
    int ret;
 
2019
    char sql[1024];
 
2020
    char *err_msg = NULL;
 
2021
    int spatialite_rs = 0;
 
2022
    int spatialite_gc = 0;
 
2023
    int rs_srid = 0;
 
2024
    int auth_name = 0;
 
2025
    int auth_srid = 0;
 
2026
    int ref_sys_name = 0;
 
2027
    int proj4text = 0;
 
2028
    int f_table_name = 0;
 
2029
    int f_geometry_column = 0;
 
2030
    int coord_dimension = 0;
 
2031
    int gc_srid = 0;
 
2032
    int type = 0;
 
2033
    int spatial_index_enabled = 0;
 
2034
    const char *name;
 
2035
    int i;
 
2036
    char **results;
 
2037
    int rows;
 
2038
    int columns;
 
2039
 
 
2040
    *handle = NULL;
 
2041
    spatialite_init (0);
 
2042
    printf ("SQLite version: %s\n", sqlite3_libversion ());
 
2043
    printf ("SpatiaLite version: %s\n\n", spatialite_version ());
 
2044
 
 
2045
    ret =
 
2046
        sqlite3_open_v2 (path, &db_handle,
 
2047
                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
 
2048
    if (ret != SQLITE_OK)
 
2049
      {
 
2050
          fprintf (stderr, "cannot open '%s': %s\n", path,
 
2051
                   sqlite3_errmsg (db_handle));
 
2052
          sqlite3_close (db_handle);
 
2053
          return;
 
2054
      }
 
2055
    spatialite_autocreate (db_handle);
 
2056
    if (cache_size > 0)
 
2057
      {
 
2058
          /* setting the CACHE-SIZE */
 
2059
          sprintf (sql, "PRAGMA cache_size=%d", cache_size);
 
2060
          sqlite3_exec (db_handle, sql, NULL, NULL, NULL);
 
2061
      }
 
2062
 
 
2063
/* checking the GEOMETRY_COLUMNS table */
 
2064
    strcpy (sql, "PRAGMA table_info(geometry_columns)");
 
2065
    ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
 
2066
    if (ret != SQLITE_OK)
 
2067
        goto unknown;
 
2068
    if (rows < 1)
 
2069
        ;
 
2070
    else
 
2071
      {
 
2072
          for (i = 1; i <= rows; i++)
 
2073
            {
 
2074
                name = results[(i * columns) + 1];
 
2075
                if (strcasecmp (name, "f_table_name") == 0)
 
2076
                    f_table_name = 1;
 
2077
                if (strcasecmp (name, "f_geometry_column") == 0)
 
2078
                    f_geometry_column = 1;
 
2079
                if (strcasecmp (name, "coord_dimension") == 0)
 
2080
                    coord_dimension = 1;
 
2081
                if (strcasecmp (name, "srid") == 0)
 
2082
                    gc_srid = 1;
 
2083
                if (strcasecmp (name, "type") == 0)
 
2084
                    type = 1;
 
2085
                if (strcasecmp (name, "spatial_index_enabled") == 0)
 
2086
                    spatial_index_enabled = 1;
 
2087
            }
 
2088
      }
 
2089
    sqlite3_free_table (results);
 
2090
    if (f_table_name && f_geometry_column && type && coord_dimension
 
2091
        && gc_srid && spatial_index_enabled)
 
2092
        spatialite_gc = 1;
 
2093
 
 
2094
/* checking the SPATIAL_REF_SYS table */
 
2095
    strcpy (sql, "PRAGMA table_info(spatial_ref_sys)");
 
2096
    ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
 
2097
    if (ret != SQLITE_OK)
 
2098
        goto unknown;
 
2099
    if (rows < 1)
 
2100
        ;
 
2101
    else
 
2102
      {
 
2103
          for (i = 1; i <= rows; i++)
 
2104
            {
 
2105
                name = results[(i * columns) + 1];
 
2106
                if (strcasecmp (name, "srid") == 0)
 
2107
                    rs_srid = 1;
 
2108
                if (strcasecmp (name, "auth_name") == 0)
 
2109
                    auth_name = 1;
 
2110
                if (strcasecmp (name, "auth_srid") == 0)
 
2111
                    auth_srid = 1;
 
2112
                if (strcasecmp (name, "ref_sys_name") == 0)
 
2113
                    ref_sys_name = 1;
 
2114
                if (strcasecmp (name, "proj4text") == 0)
 
2115
                    proj4text = 1;
 
2116
            }
 
2117
      }
 
2118
    sqlite3_free_table (results);
 
2119
    if (rs_srid && auth_name && auth_srid && ref_sys_name && proj4text)
 
2120
        spatialite_rs = 1;
 
2121
/* verifying the MetaData format */
 
2122
    if (spatialite_gc && spatialite_rs)
 
2123
        ;
 
2124
    else
 
2125
        goto unknown;
 
2126
 
 
2127
/* creating the OSM temporary nodes */
 
2128
    strcpy (sql, "CREATE TABLE osm_tmp_nodes (\n");
 
2129
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2130
    strcat (sql, "lat DOUBLE NOT NULL,\n");
 
2131
    strcat (sql, "lon DOUBLE NOT NULL)\n");
 
2132
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2133
    if (ret != SQLITE_OK)
 
2134
      {
 
2135
          fprintf (stderr, "CREATE TABLE 'osm_tmp_nodes' error: %s\n", err_msg);
 
2136
          sqlite3_free (err_msg);
 
2137
          sqlite3_close (db_handle);
 
2138
          return;
 
2139
      }
 
2140
/* creating the OSM temporary ways */
 
2141
    strcpy (sql, "CREATE TABLE osm_tmp_ways (\n");
 
2142
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2143
    strcat (sql, "area INTEGER NOT NULL)\n");
 
2144
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2145
    if (ret != SQLITE_OK)
 
2146
      {
 
2147
          fprintf (stderr, "CREATE TABLE 'osm_tmp_ways' error: %s\n", err_msg);
 
2148
          sqlite3_free (err_msg);
 
2149
          sqlite3_close (db_handle);
 
2150
          return;
 
2151
      }
 
2152
    strcpy (sql,
 
2153
            "SELECT AddGeometryColumn('osm_tmp_ways', 'Geometry', 4326, 'MULTILINESTRING', 'XY')");
 
2154
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2155
    if (ret != SQLITE_OK)
 
2156
      {
 
2157
          fprintf (stderr, "CREATE TABLE 'tmp_osm_ways' error: %s\n", err_msg);
 
2158
          sqlite3_free (err_msg);
 
2159
          sqlite3_close (db_handle);
 
2160
          return;
 
2161
      }
 
2162
/* creating the PT_GENERIC table */
 
2163
    strcpy (sql, "CREATE TABLE pt_generic (\n");
 
2164
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2165
    strcat (sql, "name TEXT)\n");
 
2166
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2167
    if (ret != SQLITE_OK)
 
2168
      {
 
2169
          fprintf (stderr, "CREATE TABLE 'pt_generic' error: %s\n", err_msg);
 
2170
          sqlite3_free (err_msg);
 
2171
          return;
 
2172
      }
 
2173
    strcpy (sql,
 
2174
            "SELECT AddGeometryColumn('pt_generic', 'Geometry', 4326, 'POINT', 'XY')");
 
2175
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2176
    if (ret != SQLITE_OK)
 
2177
      {
 
2178
          fprintf (stderr, "CREATE TABLE 'pt_generic' error: %s\n", err_msg);
 
2179
          sqlite3_free (err_msg);
 
2180
          sqlite3_close (db_handle);
 
2181
          return;
 
2182
      }
 
2183
/* creating the PT_ADDRESSES table */
 
2184
    strcpy (sql, "CREATE TABLE pt_addresses (\n");
 
2185
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2186
    strcat (sql, "country TEXT,\n");
 
2187
    strcat (sql, "city TEXT,\n");
 
2188
    strcat (sql, "postcode TEXT,\n");
 
2189
    strcat (sql, "street TEXT,\n");
 
2190
    strcat (sql, "housename TEXT,\n");
 
2191
    strcat (sql, "housenumber TEXT)\n");
 
2192
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2193
    if (ret != SQLITE_OK)
 
2194
      {
 
2195
          fprintf (stderr, "CREATE TABLE 'pt_addresses' error: %s\n", err_msg);
 
2196
          sqlite3_free (err_msg);
 
2197
          sqlite3_close (db_handle);
 
2198
          return;
 
2199
      }
 
2200
    strcpy (sql,
 
2201
            "SELECT AddGeometryColumn('pt_addresses', 'Geometry', 4326, 'POINT', 'XY')");
 
2202
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2203
    if (ret != SQLITE_OK)
 
2204
      {
 
2205
          fprintf (stderr, "CREATE TABLE 'pt_addresses' error: %s\n", err_msg);
 
2206
          sqlite3_free (err_msg);
 
2207
          sqlite3_close (db_handle);
 
2208
          return;
 
2209
      }
 
2210
/* creating the LN_GENERIC table */
 
2211
    strcpy (sql, "CREATE TABLE ln_generic (\n");
 
2212
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2213
    strcat (sql, "name TEXT)\n");
 
2214
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2215
    if (ret != SQLITE_OK)
 
2216
      {
 
2217
          fprintf (stderr, "CREATE TABLE 'ln_generic' error: %s\n", err_msg);
 
2218
          sqlite3_free (err_msg);
 
2219
          return;
 
2220
      }
 
2221
    strcpy (sql,
 
2222
            "SELECT AddGeometryColumn('ln_generic', 'Geometry', 4326, 'MULTILINESTRING', 'XY')");
 
2223
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2224
    if (ret != SQLITE_OK)
 
2225
      {
 
2226
          fprintf (stderr, "CREATE TABLE 'ln_generic' error: %s\n", err_msg);
 
2227
          sqlite3_free (err_msg);
 
2228
          sqlite3_close (db_handle);
 
2229
          return;
 
2230
      }
 
2231
/* creating the PG_GENERIC table */
 
2232
    strcpy (sql, "CREATE TABLE pg_generic (\n");
 
2233
    strcat (sql, "id INTEGER NOT NULL PRIMARY KEY,\n");
 
2234
    strcat (sql, "name TEXT)\n");
 
2235
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2236
    if (ret != SQLITE_OK)
 
2237
      {
 
2238
          fprintf (stderr, "CREATE TABLE 'pg_generic' error: %s\n", err_msg);
 
2239
          sqlite3_free (err_msg);
 
2240
          return;
 
2241
      }
 
2242
    strcpy (sql,
 
2243
            "SELECT AddGeometryColumn('pg_generic', 'Geometry', 4326, 'MULTIPOLYGON', 'XY')");
 
2244
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &err_msg);
 
2245
    if (ret != SQLITE_OK)
 
2246
      {
 
2247
          fprintf (stderr, "CREATE TABLE 'pg_generic' error: %s\n", err_msg);
 
2248
          sqlite3_free (err_msg);
 
2249
          sqlite3_close (db_handle);
 
2250
          return;
 
2251
      }
 
2252
 
 
2253
    *handle = db_handle;
 
2254
    return;
 
2255
 
 
2256
  unknown:
 
2257
    if (db_handle)
 
2258
        sqlite3_close (db_handle);
 
2259
    fprintf (stderr, "DB '%s'\n", path);
 
2260
    fprintf (stderr, "doesn't seems to contain valid Spatial Metadata ...\n\n");
 
2261
    fprintf (stderr, "Please, initialize Spatial Metadata\n\n");
 
2262
    return;
 
2263
}
 
2264
 
 
2265
static void
 
2266
finalize_sql_stmts (struct aux_params *params)
 
2267
{
 
2268
    int ret;
 
2269
    char *sql_err = NULL;
 
2270
    struct layers layer;
 
2271
    int i = 0;
 
2272
 
 
2273
    while (1)
 
2274
      {
 
2275
          layer = base_layers[i++];
 
2276
          if (layer.name == NULL)
 
2277
              break;
 
2278
          if (layer.ins_point_stmt)
 
2279
              sqlite3_finalize (layer.ins_point_stmt);
 
2280
          if (layer.ins_linestring_stmt)
 
2281
              sqlite3_finalize (layer.ins_linestring_stmt);
 
2282
          if (layer.ins_polygon_stmt)
 
2283
              sqlite3_finalize (layer.ins_polygon_stmt);
 
2284
          layer.ins_point_stmt = NULL;
 
2285
          layer.ins_linestring_stmt = NULL;
 
2286
          layer.ins_polygon_stmt = NULL;
 
2287
      }
 
2288
 
 
2289
    if (params->ins_tmp_nodes_stmt != NULL)
 
2290
        sqlite3_finalize (params->ins_tmp_nodes_stmt);
 
2291
    if (params->ins_tmp_ways_stmt != NULL)
 
2292
        sqlite3_finalize (params->ins_tmp_ways_stmt);
 
2293
    if (params->ins_generic_point_stmt != NULL)
 
2294
        sqlite3_finalize (params->ins_generic_point_stmt);
 
2295
    if (params->ins_addresses_stmt != NULL)
 
2296
        sqlite3_finalize (params->ins_addresses_stmt);
 
2297
    if (params->ins_generic_linestring_stmt != NULL)
 
2298
        sqlite3_finalize (params->ins_generic_linestring_stmt);
 
2299
    if (params->ins_generic_polygon_stmt != NULL)
 
2300
        sqlite3_finalize (params->ins_generic_polygon_stmt);
 
2301
 
 
2302
/* committing the still pending SQL Transaction */
 
2303
    ret = sqlite3_exec (params->db_handle, "COMMIT", NULL, NULL, &sql_err);
 
2304
    if (ret != SQLITE_OK)
 
2305
      {
 
2306
          fprintf (stderr, "COMMIT TRANSACTION error: %s\n", sql_err);
 
2307
          sqlite3_free (sql_err);
 
2308
          return;
 
2309
      }
 
2310
}
 
2311
 
 
2312
static void
 
2313
create_sql_stmts (struct aux_params *params)
 
2314
{
 
2315
    sqlite3_stmt *ins_tmp_nodes_stmt;
 
2316
    sqlite3_stmt *ins_tmp_ways_stmt;
 
2317
    sqlite3_stmt *ins_generic_point_stmt;
 
2318
    sqlite3_stmt *ins_addresses_stmt;
 
2319
    sqlite3_stmt *ins_generic_linestring_stmt;
 
2320
    sqlite3_stmt *ins_generic_polygon_stmt;
 
2321
    char sql[1024];
 
2322
    int ret;
 
2323
    char *sql_err = NULL;
 
2324
 
 
2325
/* the complete operation is handled as an unique SQL Transaction */
 
2326
    ret = sqlite3_exec (params->db_handle, "BEGIN", NULL, NULL, &sql_err);
 
2327
    if (ret != SQLITE_OK)
 
2328
      {
 
2329
          fprintf (stderr, "BEGIN TRANSACTION error: %s\n", sql_err);
 
2330
          sqlite3_free (sql_err);
 
2331
          return;
 
2332
      }
 
2333
    strcpy (sql, "INSERT INTO osm_tmp_nodes (id, lat, lon) ");
 
2334
    strcat (sql, "VALUES (?, ?, ?)");
 
2335
    ret =
 
2336
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2337
                            &ins_tmp_nodes_stmt, NULL);
 
2338
    if (ret != SQLITE_OK)
 
2339
      {
 
2340
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2341
                   sqlite3_errmsg (params->db_handle));
 
2342
          finalize_sql_stmts (params);
 
2343
          return;
 
2344
      }
 
2345
    strcpy (sql, "INSERT INTO osm_tmp_ways (id, area, geometry) ");
 
2346
    strcat (sql, "VALUES (?, ?, ?)");
 
2347
    ret =
 
2348
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2349
                            &ins_tmp_ways_stmt, NULL);
 
2350
    if (ret != SQLITE_OK)
 
2351
      {
 
2352
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2353
                   sqlite3_errmsg (params->db_handle));
 
2354
          finalize_sql_stmts (params);
 
2355
          return;
 
2356
      }
 
2357
    strcpy (sql, "INSERT INTO pt_generic (id, name, Geometry) ");
 
2358
    strcat (sql, "VALUES (?, ?, ?)");
 
2359
    ret =
 
2360
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2361
                            &ins_generic_point_stmt, NULL);
 
2362
    if (ret != SQLITE_OK)
 
2363
      {
 
2364
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2365
                   sqlite3_errmsg (params->db_handle));
 
2366
          finalize_sql_stmts (params);
 
2367
          return;
 
2368
      }
 
2369
    strcpy (sql,
 
2370
            "INSERT INTO pt_addresses (id, country, city, postcode, street, housename, housenumber, Geometry) ");
 
2371
    strcat (sql, "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
 
2372
    ret =
 
2373
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2374
                            &ins_addresses_stmt, NULL);
 
2375
    if (ret != SQLITE_OK)
 
2376
      {
 
2377
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2378
                   sqlite3_errmsg (params->db_handle));
 
2379
          finalize_sql_stmts (params);
 
2380
          return;
 
2381
      }
 
2382
    strcpy (sql, "INSERT INTO ln_generic (id, name, Geometry) ");
 
2383
    strcat (sql, "VALUES (?, ?, ?)");
 
2384
    ret =
 
2385
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2386
                            &ins_generic_linestring_stmt, NULL);
 
2387
    if (ret != SQLITE_OK)
 
2388
      {
 
2389
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2390
                   sqlite3_errmsg (params->db_handle));
 
2391
          finalize_sql_stmts (params);
 
2392
          return;
 
2393
      }
 
2394
    strcpy (sql, "INSERT INTO pg_generic (id, name, Geometry) ");
 
2395
    strcat (sql, "VALUES (?, ?, ?)");
 
2396
    ret =
 
2397
        sqlite3_prepare_v2 (params->db_handle, sql, strlen (sql),
 
2398
                            &ins_generic_polygon_stmt, NULL);
 
2399
    if (ret != SQLITE_OK)
 
2400
      {
 
2401
          fprintf (stderr, "SQL error: %s\n%s\n", sql,
 
2402
                   sqlite3_errmsg (params->db_handle));
 
2403
          finalize_sql_stmts (params);
 
2404
          return;
 
2405
      }
 
2406
 
 
2407
    params->ins_tmp_nodes_stmt = ins_tmp_nodes_stmt;
 
2408
    params->ins_tmp_ways_stmt = ins_tmp_ways_stmt;
 
2409
    params->ins_generic_point_stmt = ins_generic_point_stmt;
 
2410
    params->ins_addresses_stmt = ins_addresses_stmt;
 
2411
    params->ins_generic_linestring_stmt = ins_generic_linestring_stmt;
 
2412
    params->ins_generic_polygon_stmt = ins_generic_polygon_stmt;
 
2413
}
 
2414
 
 
2415
static void
 
2416
db_cleanup (sqlite3 * db_handle)
 
2417
{
 
2418
/* dropping temporary tables OSM_TMP_xxx */
 
2419
    int ret;
 
2420
    char *sql_err = NULL;
 
2421
 
 
2422
/* dropping OSM_TMP_NODES */
 
2423
    ret =
 
2424
        sqlite3_exec (db_handle, "DROP TABLE osm_tmp_nodes", NULL, NULL,
 
2425
                      &sql_err);
 
2426
    if (ret != SQLITE_OK)
 
2427
      {
 
2428
          fprintf (stderr, "DROP TABLE 'osm_tmp_nodes' error: %s\n", sql_err);
 
2429
          sqlite3_free (sql_err);
 
2430
      }
 
2431
 
 
2432
/* dropping OSM_TMP_WAYS */
 
2433
    ret =
 
2434
        sqlite3_exec (db_handle,
 
2435
                      "DELETE FROM geometry_columns WHERE f_table_name = 'osm_tmp_ways'",
 
2436
                      NULL, NULL, &sql_err);
 
2437
    if (ret != SQLITE_OK)
 
2438
      {
 
2439
          fprintf (stderr, "Dropping Geometry from 'osm_tmp_ways' error: %s\n",
 
2440
                   sql_err);
 
2441
          sqlite3_free (sql_err);
 
2442
      }
 
2443
    ret =
 
2444
        sqlite3_exec (db_handle, "DROP TABLE osm_tmp_ways", NULL, NULL,
 
2445
                      &sql_err);
 
2446
    if (ret != SQLITE_OK)
 
2447
      {
 
2448
          fprintf (stderr, "DROP TABLE 'osm_tmp_ways' error: %s\n", sql_err);
 
2449
          sqlite3_free (sql_err);
 
2450
      }
 
2451
}
 
2452
 
 
2453
static void
 
2454
do_spatial_index (sqlite3 * db_handle, const char *table, const char *geom)
 
2455
{
 
2456
/* creating some Spatial Index */
 
2457
    char sql[1024];
 
2458
    int ret;
 
2459
    char *sql_err = NULL;
 
2460
 
 
2461
    sprintf (sql, "SELECT CreateSpatialIndex('%s', '%s')", table, geom);
 
2462
    ret = sqlite3_exec (db_handle, sql, NULL, NULL, &sql_err);
 
2463
    if (ret != SQLITE_OK)
 
2464
      {
 
2465
          fprintf (stderr, "SpatialIndex %s'.'%s' error: %s\n", table, geom,
 
2466
                   sql_err);
 
2467
          sqlite3_free (sql_err);
 
2468
      }
 
2469
}
 
2470
 
 
2471
static void
 
2472
create_spatial_index (sqlite3 * db_handle)
 
2473
{
 
2474
/* attempting to create any Spatial Index */
 
2475
    const char *table;
 
2476
    const char *geom;
 
2477
    char sql[1024];
 
2478
    int i;
 
2479
    char **results;
 
2480
    int rows;
 
2481
    int columns;
 
2482
    int ret;
 
2483
 
 
2484
    strcpy (sql,
 
2485
            "SELECT f_table_name, f_geometry_column FROM geometry_columns");
 
2486
    ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
 
2487
    if (ret != SQLITE_OK)
 
2488
        return;
 
2489
    if (rows < 1)
 
2490
        ;
 
2491
    else
 
2492
      {
 
2493
          for (i = 1; i <= rows; i++)
 
2494
            {
 
2495
                table = results[(i * columns) + 0];
 
2496
                geom = results[(i * columns) + 1];
 
2497
                do_spatial_index (db_handle, table, geom);
 
2498
            }
 
2499
      }
 
2500
    sqlite3_free_table (results);
 
2501
}
 
2502
 
 
2503
static void
 
2504
do_help ()
 
2505
{
 
2506
/* printing the argument list */
 
2507
    fprintf (stderr, "\n\nusage: spatialite_osm_map ARGLIST\n");
 
2508
    fprintf (stderr,
 
2509
             "==============================================================\n");
 
2510
    fprintf (stderr,
 
2511
             "-h or --help                    print this help message\n");
 
2512
    fprintf (stderr, "-o or --osm-path pathname       the OSM-XML file path\n");
 
2513
    fprintf (stderr,
 
2514
             "-d or --db-path  pathname       the SpatiaLite DB path\n\n");
 
2515
    fprintf (stderr, "you can specify the following options as well\n");
 
2516
    fprintf (stderr,
 
2517
             "-cs or --cache-size    num      DB cache size (how many pages)\n");
 
2518
    fprintf (stderr,
 
2519
             "-m or --in-memory               using IN-MEMORY database\n");
 
2520
    fprintf (stderr,
 
2521
             "-n or --no-spatial-index        suppress R*Trees generation\n");
 
2522
}
 
2523
 
 
2524
int
 
2525
main (int argc, char *argv[])
 
2526
{
 
2527
/* the MAIN function simply perform arguments checking */
 
2528
    sqlite3 *handle;
 
2529
    int i;
 
2530
    int next_arg = ARG_NONE;
 
2531
    const char *osm_path = NULL;
 
2532
    const char *db_path = NULL;
 
2533
    int in_memory = 0;
 
2534
    int cache_size = 0;
 
2535
    int spatial_index = 1;
 
2536
    int error = 0;
 
2537
    char Buff[BUFFSIZE];
 
2538
    int done = 0;
 
2539
    int len;
 
2540
    XML_Parser parser;
 
2541
    struct aux_params params;
 
2542
    FILE *xml_file;
 
2543
 
 
2544
/* initializing the aux-struct */
 
2545
    params.db_handle = NULL;
 
2546
    params.ins_tmp_nodes_stmt = NULL;
 
2547
    params.ins_tmp_ways_stmt = NULL;
 
2548
    params.ins_generic_point_stmt = NULL;
 
2549
    params.ins_addresses_stmt = NULL;
 
2550
    params.ins_generic_linestring_stmt = NULL;
 
2551
    params.ins_generic_polygon_stmt = NULL;
 
2552
    params.current_tag = CURRENT_TAG_UNKNOWN;
 
2553
 
 
2554
    for (i = 1; i < argc; i++)
 
2555
      {
 
2556
          /* parsing the invocation arguments */
 
2557
          if (next_arg != ARG_NONE)
 
2558
            {
 
2559
                switch (next_arg)
 
2560
                  {
 
2561
                  case ARG_OSM_PATH:
 
2562
                      osm_path = argv[i];
 
2563
                      break;
 
2564
                  case ARG_DB_PATH:
 
2565
                      db_path = argv[i];
 
2566
                      break;
 
2567
                  case ARG_CACHE_SIZE:
 
2568
                      cache_size = atoi (argv[i]);
 
2569
                      break;
 
2570
                  };
 
2571
                next_arg = ARG_NONE;
 
2572
                continue;
 
2573
            }
 
2574
          if (strcasecmp (argv[i], "--help") == 0
 
2575
              || strcmp (argv[i], "-h") == 0)
 
2576
            {
 
2577
                do_help ();
 
2578
                return -1;
 
2579
            }
 
2580
          if (strcmp (argv[i], "-o") == 0)
 
2581
            {
 
2582
                next_arg = ARG_OSM_PATH;
 
2583
                continue;
 
2584
            }
 
2585
          if (strcasecmp (argv[i], "--osm-path") == 0)
 
2586
            {
 
2587
                next_arg = ARG_OSM_PATH;
 
2588
                continue;
 
2589
            }
 
2590
          if (strcmp (argv[i], "-d") == 0)
 
2591
            {
 
2592
                next_arg = ARG_DB_PATH;
 
2593
                continue;
 
2594
            }
 
2595
          if (strcasecmp (argv[i], "--db-path") == 0)
 
2596
            {
 
2597
                next_arg = ARG_DB_PATH;
 
2598
                continue;
 
2599
            }
 
2600
          if (strcasecmp (argv[i], "--cache-size") == 0
 
2601
              || strcmp (argv[i], "-cs") == 0)
 
2602
            {
 
2603
                next_arg = ARG_CACHE_SIZE;
 
2604
                continue;
 
2605
            }
 
2606
          if (strcasecmp (argv[i], "-m") == 0)
 
2607
            {
 
2608
                in_memory = 1;
 
2609
                next_arg = ARG_NONE;
 
2610
                continue;
 
2611
            }
 
2612
          if (strcasecmp (argv[i], "-in-memory") == 0)
 
2613
            {
 
2614
                in_memory = 1;
 
2615
                next_arg = ARG_NONE;
 
2616
                continue;
 
2617
            }
 
2618
          if (strcasecmp (argv[i], "-n") == 0)
 
2619
            {
 
2620
                spatial_index = 0;
 
2621
                next_arg = ARG_NONE;
 
2622
                continue;
 
2623
            }
 
2624
          if (strcasecmp (argv[i], "-no-spatial-index") == 0)
 
2625
            {
 
2626
                spatial_index = 0;
 
2627
                next_arg = ARG_NONE;
 
2628
                continue;
 
2629
            }
 
2630
          fprintf (stderr, "unknown argument: %s\n", argv[i]);
 
2631
          error = 1;
 
2632
      }
 
2633
    if (error)
 
2634
      {
 
2635
          do_help ();
 
2636
          return -1;
 
2637
      }
 
2638
 
 
2639
/* checking the arguments */
 
2640
    if (!osm_path)
 
2641
      {
 
2642
          fprintf (stderr,
 
2643
                   "did you forget setting the --osm-path argument ?\n");
 
2644
          error = 1;
 
2645
      }
 
2646
    if (!db_path)
 
2647
      {
 
2648
          fprintf (stderr, "did you forget setting the --db-path argument ?\n");
 
2649
          error = 1;
 
2650
      }
 
2651
 
 
2652
    if (error)
 
2653
      {
 
2654
          do_help ();
 
2655
          return -1;
 
2656
      }
 
2657
 
 
2658
/* opening the DB */
 
2659
    if (in_memory)
 
2660
        cache_size = 0;
 
2661
    open_db (db_path, &handle, cache_size);
 
2662
    if (!handle)
 
2663
        return -1;
 
2664
    params.db_handle = handle;
 
2665
    if (in_memory)
 
2666
      {
 
2667
          /* loading the DB in-memory */
 
2668
          sqlite3 *mem_db_handle;
 
2669
          sqlite3_backup *backup;
 
2670
          int ret;
 
2671
          ret =
 
2672
              sqlite3_open_v2 (":memory:", &mem_db_handle,
 
2673
                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
 
2674
                               NULL);
 
2675
          if (ret != SQLITE_OK)
 
2676
            {
 
2677
                fprintf (stderr, "cannot open 'MEMORY-DB': %s\n",
 
2678
                         sqlite3_errmsg (mem_db_handle));
 
2679
                sqlite3_close (mem_db_handle);
 
2680
                return -1;
 
2681
            }
 
2682
          backup = sqlite3_backup_init (mem_db_handle, "main", handle, "main");
 
2683
          if (!backup)
 
2684
            {
 
2685
                fprintf (stderr, "cannot load 'MEMORY-DB'\n");
 
2686
                sqlite3_close (handle);
 
2687
                sqlite3_close (mem_db_handle);
 
2688
                return -1;
 
2689
            }
 
2690
          while (1)
 
2691
            {
 
2692
                ret = sqlite3_backup_step (backup, 1024);
 
2693
                if (ret == SQLITE_DONE)
 
2694
                    break;
 
2695
            }
 
2696
          ret = sqlite3_backup_finish (backup);
 
2697
          sqlite3_close (handle);
 
2698
          handle = mem_db_handle;
 
2699
          printf ("\nusing IN-MEMORY database\n");
 
2700
      }
 
2701
 
 
2702
/* creating SQL prepared statements */
 
2703
    create_sql_stmts (&params);
 
2704
 
 
2705
/* XML parsing */
 
2706
    xml_file = fopen (osm_path, "rb");
 
2707
    if (!xml_file)
 
2708
      {
 
2709
          fprintf (stderr, "cannot open %s\n", osm_path);
 
2710
          sqlite3_close (handle);
 
2711
          return -1;
 
2712
      }
 
2713
    parser = XML_ParserCreate (NULL);
 
2714
    if (!parser)
 
2715
      {
 
2716
          fprintf (stderr, "Couldn't allocate memory for parser\n");
 
2717
          sqlite3_close (handle);
 
2718
          return -1;
 
2719
      }
 
2720
    XML_SetUserData (parser, &params);
 
2721
    XML_SetElementHandler (parser, start_tag, end_tag);
 
2722
    while (!done)
 
2723
      {
 
2724
          len = fread (Buff, 1, BUFFSIZE, xml_file);
 
2725
          if (ferror (xml_file))
 
2726
            {
 
2727
                fprintf (stderr, "XML Read error\n");
 
2728
                sqlite3_close (handle);
 
2729
                return -1;
 
2730
            }
 
2731
          done = feof (xml_file);
 
2732
          if (!XML_Parse (parser, Buff, len, done))
 
2733
            {
 
2734
                fprintf (stderr, "Parse error at line %d:\n%s\n",
 
2735
                         (int) XML_GetCurrentLineNumber (parser),
 
2736
                         XML_ErrorString (XML_GetErrorCode (parser)));
 
2737
                sqlite3_close (handle);
 
2738
                return -1;
 
2739
            }
 
2740
      }
 
2741
    XML_ParserFree (parser);
 
2742
    fclose (xml_file);
 
2743
 
 
2744
/* finalizing SQL prepared statements */
 
2745
    finalize_sql_stmts (&params);
 
2746
 
 
2747
/* dropping the OSM_TMP_xx tables */
 
2748
    db_cleanup (handle);
 
2749
 
 
2750
    if (spatial_index)
 
2751
      {
 
2752
          /* creating any Spatial Index */
 
2753
          create_spatial_index (handle);
 
2754
      }
 
2755
 
 
2756
    if (in_memory)
 
2757
      {
 
2758
          /* exporting the in-memory DB to filesystem */
 
2759
          sqlite3 *disk_db_handle;
 
2760
          sqlite3_backup *backup;
 
2761
          int ret;
 
2762
          printf ("\nexporting IN_MEMORY database ... wait please ...\n");
 
2763
          ret =
 
2764
              sqlite3_open_v2 (db_path, &disk_db_handle,
 
2765
                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
 
2766
                               NULL);
 
2767
          if (ret != SQLITE_OK)
 
2768
            {
 
2769
                fprintf (stderr, "cannot open '%s': %s\n", db_path,
 
2770
                         sqlite3_errmsg (disk_db_handle));
 
2771
                sqlite3_close (disk_db_handle);
 
2772
                return -1;
 
2773
            }
 
2774
          backup = sqlite3_backup_init (disk_db_handle, "main", handle, "main");
 
2775
          if (!backup)
 
2776
            {
 
2777
                fprintf (stderr, "Backup failure: 'MEMORY-DB' wasn't saved\n");
 
2778
                sqlite3_close (handle);
 
2779
                sqlite3_close (disk_db_handle);
 
2780
                return -1;
 
2781
            }
 
2782
          while (1)
 
2783
            {
 
2784
                ret = sqlite3_backup_step (backup, 1024);
 
2785
                if (ret == SQLITE_DONE)
 
2786
                    break;
 
2787
            }
 
2788
          ret = sqlite3_backup_finish (backup);
 
2789
          sqlite3_close (handle);
 
2790
          handle = disk_db_handle;
 
2791
          printf ("\tIN_MEMORY database successfully exported\n");
 
2792
      }
 
2793
 
 
2794
/* VACUUMing */
 
2795
    db_vacuum (handle);
 
2796
    sqlite3_close (handle);
 
2797
    return 0;
 
2798
}