1 /*
2 / spatialite_osm_filter
3 /
4 / a tool loading OSM-XML maps into a SpatiaLite DB
5 /
6 / version 1.0, 2011 October 31
7 /
8 / Author: Sandro Furieri a.furieri@lqt.it
9 /
10 / Copyright (C) 2011 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
36 #if defined(_WIN32) && !defined(__MINGW32__)
37 #include "config-msvc.h"
38 #else
39 #include "config.h"
40 #endif
41
42 #ifdef SPATIALITE_AMALGAMATION
43 #include <spatialite/sqlite3.h>
44 #else
45 #include <sqlite3.h>
46 #endif
47
48 #include <spatialite/gaiageo.h>
49 #include <spatialite.h>
50
51
52 #define ARG_NONE 0
53 #define ARG_OSM_PATH 1
54 #define ARG_DB_PATH 2
55 #define ARG_CACHE_SIZE 3
56 #define ARG_MASK_PATH 4
57
58 #if defined(_WIN32) && !defined(__MINGW32__)
59 #define strcasecmp _stricmp
60 #endif /* not WIN32 */
61
62 static char *
clean_xml(const char * in)63 clean_xml (const char *in)
64 {
65 /* well formatting XML text strings */
66 int len = 0;
67 char *buf;
68 char *p_o;
69 const char *p_i = in;
70 while (*p_i != '\0')
71 {
72 /* calculating the output len */
73 if (*p_i == '"')
74 {
75 len += 6;
76 p_i++;
77 continue;
78 }
79 if (*p_i == '\'')
80 {
81 len += 6;
82 p_i++;
83 continue;
84 }
85 if (*p_i == '&')
86 {
87 len += 5;
88 p_i++;
89 continue;
90 }
91 if (*p_i == '<')
92 {
93 len += 4;
94 p_i++;
95 continue;
96 }
97 if (*p_i == '>')
98 {
99 len += 4;
100 p_i++;
101 continue;
102 }
103 len++;
104 p_i++;
105 }
106
107 buf = malloc (len + 1);
108 p_o = buf;
109 p_i = in;
110 while (*p_i != '\0')
111 {
112 if (*p_i == '"')
113 {
114 *p_o++ = '&';
115 *p_o++ = 'q';
116 *p_o++ = 'u';
117 *p_o++ = 'o';
118 *p_o++ = 't';
119 *p_o++ = ';';
120 p_i++;
121 continue;
122 }
123 if (*p_i == '\'')
124 {
125 *p_o++ = '&';
126 *p_o++ = 'a';
127 *p_o++ = 'p';
128 *p_o++ = 'o';
129 *p_o++ = 's';
130 *p_o++ = ';';
131 p_i++;
132 continue;
133 }
134 if (*p_i == '&')
135 {
136 *p_o++ = '&';
137 *p_o++ = 'a';
138 *p_o++ = 'm';
139 *p_o++ = 'p';
140 *p_o++ = ';';
141 p_i++;
142 continue;
143 }
144 if (*p_i == '<')
145 {
146 *p_o++ = '&';
147 *p_o++ = 'l';
148 *p_o++ = 't';
149 *p_o++ = ';';
150 p_i++;
151 continue;
152 }
153 if (*p_i == '>')
154 {
155 *p_o++ = '&';
156 *p_o++ = 'g';
157 *p_o++ = 't';
158 *p_o++ = ';';
159 p_i++;
160 continue;
161 }
162 *p_o++ = *p_i++;
163 }
164 *p_o = '\0';
165 return buf;
166 }
167
168 static int
do_output_nodes(FILE * out,sqlite3 * handle)169 do_output_nodes (FILE * out, sqlite3 * handle)
170 {
171 /* exporting any OSM node */
172 char sql[1024];
173 int ret;
174 int first;
175 int close_node;
176 sqlite3_stmt *node_query = NULL;
177 sqlite3_stmt *query = NULL;
178
179 /* preparing the QUERY filtered-NODES statement */
180 strcpy (sql, "SELECT node_id FROM osm_nodes WHERE filtered = 1");
181 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &node_query, NULL);
182 if (ret != SQLITE_OK)
183 {
184 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
185 return 0;
186 }
187
188 /* preparing the QUERY NODES statement */
189 strcpy (sql, "SELECT n.node_id, n.version, n.timestamp, ");
190 strcat (sql, "n.uid, n.user, n.changeset, ST_X(n.Geometry), ");
191 strcat (sql, "ST_Y(n.Geometry), t.k, t.v ");
192 strcat (sql, "FROM osm_nodes AS n ");
193 strcat (sql, "LEFT JOIN osm_node_tags AS t ON (t.node_id = n.node_id) ");
194 strcat (sql, "WHERE n.node_id = ? ");
195 strcat (sql, "ORDER BY n.node_id, t.sub");
196 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query, NULL);
197 if (ret != SQLITE_OK)
198 {
199 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
200 goto stop;
201 }
202
203 while (1)
204 {
205 /* scrolling the result set */
206 ret = sqlite3_step (node_query);
207 if (ret == SQLITE_DONE)
208 {
209 /* there are no more rows to fetch - we can stop looping */
210 break;
211 }
212 if (ret == SQLITE_ROW)
213 {
214 /* ok, we've just fetched a valid row */
215 sqlite3_int64 id = sqlite3_column_int64 (node_query, 0);
216
217 sqlite3_reset (query);
218 sqlite3_clear_bindings (query);
219 sqlite3_bind_int64 (query, 1, id);
220 first = 1;
221 close_node = 0;
222 while (1)
223 {
224 /* scrolling the result set */
225 ret = sqlite3_step (query);
226 if (ret == SQLITE_DONE)
227 {
228 /* there are no more rows to fetch - we can stop looping */
229 break;
230 }
231 if (ret == SQLITE_ROW)
232 {
233 /* ok, we've just fetched a valid row */
234 sqlite3_int64 id = sqlite3_column_int64 (query, 0);
235 int version = sqlite3_column_int (query, 1);
236 const char *p_timestamp =
237 (const char *) sqlite3_column_text (query, 2);
238 int uid = sqlite3_column_int (query, 3);
239 const char *p_user =
240 (const char *) sqlite3_column_text (query, 4);
241 const char *p_changeset =
242 (const char *) sqlite3_column_text (query, 5);
243 double x = sqlite3_column_double (query, 6);
244 double y = sqlite3_column_double (query, 7);
245 char *k = NULL;
246 char *v = NULL;
247 if (sqlite3_column_type (query, 8) != SQLITE_NULL)
248 k = clean_xml ((const char *)
249 sqlite3_column_text (query, 8));
250 if (sqlite3_column_type (query, 9) != SQLITE_NULL)
251 v = clean_xml ((const char *)
252 sqlite3_column_text (query, 9));
253
254 if (first)
255 {
256 /* first NODE row */
257 char *timestamp =
258 p_timestamp ? clean_xml (p_timestamp) :
259 NULL;
260 char *changeset =
261 p_changeset ? clean_xml (p_changeset) :
262 NULL;
263 char *user =
264 p_user ? clean_xml (p_user) : NULL;
265 first = 0;
266 #if defined(_WIN32) || defined(__MINGW32__)
267 /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
268 fprintf (out, "\t<node id=\"%I64d\"", id);
269 #else
270 fprintf (out, "\t<node id=\"%lld\"", id);
271 #endif
272 if (user)
273 {
274 fprintf (out, " user=\"%s\"", user);
275 free (user);
276 }
277 if (changeset)
278 {
279 fprintf (out, " changeset=\"%s\"",
280 changeset);
281 free (changeset);
282 }
283 if (timestamp)
284 {
285 fprintf (out, " timestamp=\"%s\"",
286 timestamp);
287 free (timestamp);
288 }
289 if (!version)
290 version = 1;
291 fprintf (out, " version=\"%d\"", version);
292 fprintf (out,
293 " lat=\"%1.7f\" lon=\"%1.7f\" uid=\"%d\" ",
294 y, x, uid);
295 if (k == NULL && v == NULL)
296 fprintf (out, "/>\n");
297 else
298 fprintf (out, ">\n");
299 }
300 if (k != NULL && v != NULL)
301 {
302 /* NODE tag */
303 fprintf (out,
304 "\t\t<tag k=\"%s\" v=\"%s\"/>\n", k,
305 v);
306 close_node = 1;
307 }
308 if (k)
309 free (k);
310 if (v)
311 free (v);
312 }
313 else
314 {
315 /* some unexpected error occurred */
316 fprintf (stderr, "sqlite3_step() error: %s\n",
317 sqlite3_errmsg (handle));
318 goto stop;
319 }
320 }
321 if (close_node)
322 fprintf (out, "\t</node>\n");
323 }
324 else
325 {
326 /* some unexpected error occurred */
327 fprintf (stderr, "sqlite3_step() error: %s\n",
328 sqlite3_errmsg (handle));
329 goto stop;
330 }
331 }
332 sqlite3_finalize (node_query);
333 sqlite3_finalize (query);
334
335 return 1;
336
337 stop:
338 sqlite3_finalize (node_query);
339 if (query)
340 sqlite3_finalize (query);
341 return 0;
342 }
343
344 static int
do_output_ways(FILE * out,sqlite3 * handle)345 do_output_ways (FILE * out, sqlite3 * handle)
346 {
347 /* exporting any OSM way */
348 char sql[1024];
349 int ret;
350 int first;
351 sqlite3_stmt *way_query = NULL;
352 sqlite3_stmt *query = NULL;
353 sqlite3_stmt *query_tag = NULL;
354
355 /* preparing the QUERY filtered-WAYS statement */
356 strcpy (sql, "SELECT way_id FROM osm_ways WHERE filtered = 1");
357 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &way_query, NULL);
358 if (ret != SQLITE_OK)
359 {
360 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
361 return 0;
362 }
363
364 /* preparing the QUERY WAY/NODES statement */
365 strcpy (sql, "SELECT w.way_id, w.version, w.timestamp, w.uid, ");
366 strcat (sql, "w.user, w.changeset, n.node_id ");
367 strcat (sql, "FROM osm_ways AS w ");
368 strcat (sql, "JOIN osm_way_refs AS n ON (n.way_id = w.way_id) ");
369 strcat (sql, "WHERE w.way_id = ? ");
370 strcat (sql, "ORDER BY w.way_id, n.sub");
371 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query, NULL);
372 if (ret != SQLITE_OK)
373 {
374 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
375 goto stop;
376 }
377
378 /* preparing the QUERY WAY/TAGS statement */
379 strcpy (sql, "SELECT t.k, t.v ");
380 strcat (sql, "FROM osm_ways AS w ");
381 strcat (sql, "JOIN osm_way_tags AS t ON (t.way_id = w.way_id) ");
382 strcat (sql, "WHERE w.way_id = ? ");
383 strcat (sql, "ORDER BY w.way_id, t.sub");
384 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query_tag, NULL);
385 if (ret != SQLITE_OK)
386 {
387 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
388 goto stop;
389 }
390
391 while (1)
392 {
393 /* scrolling the result set */
394 ret = sqlite3_step (way_query);
395 if (ret == SQLITE_DONE)
396 {
397 /* there are no more rows to fetch - we can stop looping */
398 break;
399 }
400 if (ret == SQLITE_ROW)
401 {
402 /* ok, we've just fetched a valid row */
403 sqlite3_int64 id = sqlite3_column_int64 (way_query, 0);
404
405 sqlite3_reset (query);
406 sqlite3_clear_bindings (query);
407 sqlite3_bind_int64 (query, 1, id);
408 first = 1;
409 while (1)
410 {
411 /* scrolling the result set */
412 ret = sqlite3_step (query);
413 if (ret == SQLITE_DONE)
414 {
415 /* there are no more rows to fetch - we can stop looping */
416 break;
417 }
418 if (ret == SQLITE_ROW)
419 {
420 /* ok, we've just fetched a valid row */
421 sqlite3_int64 id = sqlite3_column_int64 (query, 0);
422 int version = sqlite3_column_int (query, 1);
423 const char *p_timestamp =
424 (const char *) sqlite3_column_text (query, 2);
425 int uid = sqlite3_column_int (query, 3);
426 const char *p_user =
427 (const char *) sqlite3_column_text (query, 4);
428 const char *p_changeset =
429 (const char *) sqlite3_column_text (query, 5);
430 sqlite3_int64 node_id =
431 sqlite3_column_int64 (query, 6);
432
433 if (first)
434 {
435 /* first WAY row */
436 char *timestamp =
437 p_timestamp ? clean_xml (p_timestamp) :
438 NULL;
439 char *changeset =
440 p_changeset ? clean_xml (p_changeset) :
441 NULL;
442 char *user = NULL;
443 if (p_user)
444 user = clean_xml (p_user);
445 first = 0;
446 #if defined(_WIN32) || defined(__MINGW32__)
447 /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
448 fprintf (out, "\t<way id=\"%I64d\"", id);
449 #else
450 fprintf (out, "\t<way id=\"%lld\"", id);
451 #endif
452 if (user)
453 {
454 fprintf (out, " user=\"%s\"", user);
455 free (user);
456 }
457 if (changeset)
458 {
459 fprintf (out, " changeset=\"%s\"",
460 changeset);
461 free (changeset);
462 }
463 if (timestamp)
464 {
465 fprintf (out, " timestamp=\"%s\"",
466 timestamp);
467 free (timestamp);
468 }
469 if (!version)
470 version = 1;
471 fprintf (out, " version=\"%d\"", version);
472 fprintf (out, " uid=\"%d\" >\n", uid);
473 }
474 /* NODE REF tag */
475 #if defined(_WIN32) || defined(__MINGW32__)
476 /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
477 fprintf (out, "\t\t<nd ref=\"%I64d\"/>\n", node_id);
478 #else
479 fprintf (out, "\t\t<nd ref=\"%lld\"/>\n", node_id);
480 #endif
481 }
482 else
483 {
484 /* some unexpected error occurred */
485 fprintf (stderr, "sqlite3_step() error: %s\n",
486 sqlite3_errmsg (handle));
487 goto stop;
488 }
489 }
490 if (!first)
491 {
492 /* exporting WAY tags */
493 sqlite3_reset (query_tag);
494 sqlite3_clear_bindings (query_tag);
495 sqlite3_bind_int64 (query_tag, 1, id);
496 while (1)
497 {
498 /* scrolling the result set */
499 ret = sqlite3_step (query_tag);
500 if (ret == SQLITE_DONE)
501 {
502 /* there are no more rows to fetch - we can stop looping */
503 break;
504 }
505 if (ret == SQLITE_ROW)
506 {
507 /* ok, we've just fetched a valid row */
508 char *k =
509 clean_xml ((const char *)
510 sqlite3_column_text (query_tag,
511 0));
512 char *v =
513 clean_xml ((const char *)
514 sqlite3_column_text (query_tag,
515 1));
516 fprintf (out,
517 "\t\t<tag k=\"%s\" v=\"%s\"/>\n", k,
518 v);
519 free (k);
520 free (v);
521 }
522 else
523 {
524 /* some unexpected error occurred */
525 fprintf (stderr, "sqlite3_step() error: %s\n",
526 sqlite3_errmsg (handle));
527 goto stop;
528 }
529 }
530 }
531 fprintf (out, "\t</way>\n");
532 }
533 else
534 {
535 /* some unexpected error occurred */
536 fprintf (stderr, "sqlite3_step() error: %s\n",
537 sqlite3_errmsg (handle));
538 goto stop;
539 }
540 }
541 sqlite3_finalize (way_query);
542 sqlite3_finalize (query);
543 sqlite3_finalize (query_tag);
544
545 return 1;
546
547 stop:
548 sqlite3_finalize (way_query);
549 if (query)
550 sqlite3_finalize (query);
551 if (query_tag)
552 sqlite3_finalize (query_tag);
553 return 0;
554 }
555
556 static int
do_output_relations(FILE * out,sqlite3 * handle)557 do_output_relations (FILE * out, sqlite3 * handle)
558 {
559 /* exporting any OSM relation */
560 char sql[1024];
561 int ret;
562 int first;
563 sqlite3_stmt *rel_query = NULL;
564 sqlite3_stmt *query_nd = NULL;
565 sqlite3_stmt *query_way = NULL;
566 sqlite3_stmt *query_rel = NULL;
567 sqlite3_stmt *query_tag = NULL;
568
569 /* preparing the QUERY filtered-RELATIONS statement */
570 strcpy (sql, "SELECT rel_id FROM osm_relations WHERE filtered = 1");
571 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &rel_query, NULL);
572 if (ret != SQLITE_OK)
573 {
574 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
575 return 0;
576 }
577
578 /* preparing the QUERY RELATION/NODES statement */
579 strcpy (sql, "SELECT r.rel_id, r.version, r.timestamp, r.uid, ");
580 strcat (sql, "r.user, r.changeset, n.role, n.ref ");
581 strcat (sql, "FROM osm_relations AS r ");
582 strcat (sql,
583 "JOIN osm_relation_refs AS n ON (n.type = 'N' AND n.rel_id = r.rel_id) ");
584 strcat (sql, "WHERE r.rel_id = ? ");
585 strcat (sql, "ORDER BY r.rel_id, n.sub");
586 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query_nd, NULL);
587 if (ret != SQLITE_OK)
588 {
589 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
590 goto stop;
591 }
592
593 /* preparing the QUERY RELATION/WAYS statement */
594 strcpy (sql, "SELECT r.rel_id, r.version, r.timestamp, r.uid, ");
595 strcat (sql, "r.user, r.changeset, w.role, w.ref ");
596 strcat (sql, "FROM osm_relations AS r ");
597 strcat (sql,
598 "JOIN osm_relation_refs AS w ON (w.type = 'W' AND w.rel_id = r.rel_id) ");
599 strcat (sql, "WHERE r.rel_id = ? ");
600 strcat (sql, "ORDER BY r.rel_id, w.sub");
601 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query_way, NULL);
602 if (ret != SQLITE_OK)
603 {
604 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
605 goto stop;
606 }
607
608 /* preparing the QUERY RELATION/RELATIONS statement */
609 strcpy (sql, "SELECT r.rel_id, r.version, r.timestamp, r.uid, ");
610 strcat (sql, "r.user, r.changeset, x.role, x.ref ");
611 strcat (sql, "FROM osm_relations AS r ");
612 strcat (sql,
613 "JOIN osm_relation_refs AS x ON (x.type = 'R' AND x.rel_id = r.rel_id) ");
614 strcat (sql, "WHERE r.rel_id = ? ");
615 strcat (sql, "ORDER BY r.rel_id, x.sub");
616 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query_rel, NULL);
617 if (ret != SQLITE_OK)
618 {
619 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
620 goto stop;
621 }
622
623 /* preparing the QUERY RELATION/TAGS statement */
624 strcpy (sql, "SELECT t.k, t.v ");
625 strcat (sql, "FROM osm_relations AS r ");
626 strcat (sql, "JOIN osm_relation_tags AS t ON (t.rel_id = r.rel_id) ");
627 strcat (sql, "WHERE r.rel_id = ? ");
628 strcat (sql, "ORDER BY r.rel_id, t.sub");
629 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query_tag, NULL);
630 if (ret != SQLITE_OK)
631 {
632 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
633 goto stop;
634 }
635
636 while (1)
637 {
638 /* scrolling the result set */
639 ret = sqlite3_step (rel_query);
640 if (ret == SQLITE_DONE)
641 {
642 /* there are no more rows to fetch - we can stop looping */
643 break;
644 }
645 if (ret == SQLITE_ROW)
646 {
647 /* ok, we've just fetched a valid row */
648 sqlite3_int64 id = sqlite3_column_int64 (rel_query, 0);
649
650 sqlite3_reset (query_way);
651 sqlite3_clear_bindings (query_way);
652 sqlite3_bind_int64 (query_way, 1, id);
653 first = 1;
654 while (1)
655 {
656 /* scrolling the result set */
657 ret = sqlite3_step (query_way);
658 if (ret == SQLITE_DONE)
659 {
660 /* there are no more rows to fetch - we can stop looping */
661 break;
662 }
663 if (ret == SQLITE_ROW)
664 {
665 /* ok, we've just fetched a valid row */
666 sqlite3_int64 id =
667 sqlite3_column_int64 (query_way, 0);
668 int version = sqlite3_column_int (query_way, 1);
669 const char *p_timestamp =
670 (const char *) sqlite3_column_text (query_way,
671 2);
672 int uid = sqlite3_column_int (query_way, 3);
673 const char *p_user =
674 (const char *) sqlite3_column_text (query_way,
675 4);
676 const char *p_changeset =
677 (const char *) sqlite3_column_text (query_way,
678 5);
679 char *role =
680 clean_xml ((const char *)
681 sqlite3_column_text (query_way, 6));
682 sqlite3_int64 way_id =
683 sqlite3_column_int64 (query_way, 7);
684
685 if (first)
686 {
687 /* first RELATION row */
688 char *timestamp =
689 p_timestamp ? clean_xml (p_timestamp) :
690 NULL;
691 char *changeset =
692 p_changeset ? clean_xml (p_changeset) :
693 NULL;
694 char *user = NULL;
695 if (p_user)
696 user = clean_xml (p_user);
697 first = 0;
698 #if defined(_WIN32) || defined(__MINGW32__)
699 /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
700 fprintf (out, "\t<relation id=\"%I64d\"", id);
701 #else
702 fprintf (out, "\t<relation id=\"%lld\"", id);
703 #endif
704 if (user)
705 {
706 fprintf (out, " user=\"%s\"", user);
707 free (user);
708 }
709 if (changeset)
710 {
711 fprintf (out, " changeset=\"%s\"",
712 changeset);
713 free (changeset);
714 }
715 if (timestamp)
716 {
717 fprintf (out, " timestamp=\"%s\"",
718 timestamp);
719 free (timestamp);
720 }
721 if (!version)
722 version = 1;
723 fprintf (out, " version=\"%d\"", version);
724 fprintf (out, " uid=\"%d\" >\n", uid);
725 }
726 /* NODE REF tag */
727 #if defined(_WIN32) || defined(__MINGW32__)
728 /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
729 fprintf (out,
730 "\t\t<member type=\"way\" ref=\"%I64d\" role=\"%s\"/>\n",
731 way_id, role);
732 #else
733 fprintf (out,
734 "\t\t<member type = \"way\" ref=\"%lld\" role=\"%s\"/>\n",
735 way_id, role);
736 #endif
737 free (role);
738 }
739 else
740 {
741 /* some unexpected error occurred */
742 fprintf (stderr, "sqlite3_step() error: %s\n",
743 sqlite3_errmsg (handle));
744 goto stop;
745 }
746 }
747 if (!first)
748 {
749 /* exporting WAY tags */
750 sqlite3_reset (query_tag);
751 sqlite3_clear_bindings (query_tag);
752 sqlite3_bind_int64 (query_tag, 1, id);
753 while (1)
754 {
755 /* scrolling the result set */
756 ret = sqlite3_step (query_tag);
757 if (ret == SQLITE_DONE)
758 {
759 /* there are no more rows to fetch - we can stop looping */
760 break;
761 }
762 if (ret == SQLITE_ROW)
763 {
764 /* ok, we've just fetched a valid row */
765 char *k =
766 clean_xml ((const char *)
767 sqlite3_column_text (query_tag,
768 0));
769 char *v =
770 clean_xml ((const char *)
771 sqlite3_column_text (query_tag,
772 1));
773 fprintf (out,
774 "\t\t<tag k=\"%s\" v=\"%s\"/>\n", k,
775 v);
776 free (k);
777 free (v);
778 }
779 else
780 {
781 /* some unexpected error occurred */
782 fprintf (stderr, "sqlite3_step() error: %s\n",
783 sqlite3_errmsg (handle));
784 goto stop;
785 }
786 }
787 }
788 fprintf (out, "\t</relation>\n");
789 }
790 else
791 {
792 /* some unexpected error occurred */
793 fprintf (stderr, "sqlite3_step() error: %s\n",
794 sqlite3_errmsg (handle));
795 goto stop;
796 }
797 }
798 sqlite3_finalize (rel_query);
799 sqlite3_finalize (query_nd);
800 sqlite3_finalize (query_way);
801 sqlite3_finalize (query_rel);
802 sqlite3_finalize (query_tag);
803
804 return 1;
805
806 stop:
807 sqlite3_finalize (rel_query);
808 if (query_nd)
809 sqlite3_finalize (query_nd);
810 if (query_way)
811 sqlite3_finalize (query_way);
812 if (query_rel)
813 sqlite3_finalize (query_rel);
814 if (query_tag)
815 sqlite3_finalize (query_tag);
816 return 0;
817 }
818
819 static int
reset_filtered(sqlite3 * handle)820 reset_filtered (sqlite3 * handle)
821 {
822 /* resetting NODES, WAYS and RELATIONS */
823 char sql[1024];
824 int ret;
825 char *sql_err = NULL;
826
827 /* disabling transactions */
828 strcpy (sql, "PRAGMA journal_mode=OFF");
829 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
830 if (ret != SQLITE_OK)
831 {
832 fprintf (stderr, "PRAGMA journal_mode=OFF: %s\n", sql_err);
833 sqlite3_free (sql_err);
834 return 0;
835 }
836
837 /* resetting NODES */
838 strcpy (sql, "UPDATE osm_nodes SET filtered = 0");
839 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
840 if (ret != SQLITE_OK)
841 {
842 fprintf (stderr, "RESET osm_nodes error: %s\n", sql_err);
843 sqlite3_free (sql_err);
844 return 0;
845 }
846
847 /* resetting WAYS */
848 strcpy (sql, "UPDATE osm_ways SET filtered = 0");
849 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
850 if (ret != SQLITE_OK)
851 {
852 fprintf (stderr, "RESET osm_ways error: %s\n", sql_err);
853 sqlite3_free (sql_err);
854 return 0;
855 }
856
857 /* resetting RELATIONS */
858 strcpy (sql, "UPDATE osm_relations SET filtered = 0");
859 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
860 if (ret != SQLITE_OK)
861 {
862 fprintf (stderr, "RESET osm_relations error: %s\n", sql_err);
863 sqlite3_free (sql_err);
864 return 0;
865 }
866
867 /* enabling again transactions */
868 strcpy (sql, "PRAGMA journal_mode=DELETE");
869 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
870 if (ret != SQLITE_OK)
871 {
872 fprintf (stderr, "PRAGMA journal_mode=DELETE: %s\n", sql_err);
873 sqlite3_free (sql_err);
874 return 0;
875 }
876
877 return 1;
878 }
879
880 static int
filter_rel_relations(sqlite3 * handle)881 filter_rel_relations (sqlite3 * handle)
882 {
883 /* selecting any RELATION required by other selected RELATIONS */
884 char sql[1024];
885 int ret;
886 char *sql_err = NULL;
887
888 strcpy (sql, "UPDATE osm_relations SET filtered = 1 ");
889 strcat (sql, "WHERE rel_id IN (");
890 strcat (sql, "SELECT x.ref ");
891 strcat (sql, "FROM osm_relations AS r ");
892 strcat (sql,
893 "JOIN osm_relation_refs AS x ON (x.type = 'R' AND r.rel_id = x.rel_id) ");
894 strcat (sql, "WHERE r.filtered = 1)");
895 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
896 if (ret != SQLITE_OK)
897 {
898 fprintf (stderr, "UPDATE osm_relations error: %s\n", sql_err);
899 sqlite3_free (sql_err);
900 return 0;
901 }
902 return 1;
903 }
904
905 static int
filter_way_relations(sqlite3 * handle)906 filter_way_relations (sqlite3 * handle)
907 {
908 /* selecting any WAY required by selected RELATIONS */
909 char sql[1024];
910 int ret;
911 char *sql_err = NULL;
912
913 strcpy (sql, "UPDATE osm_ways SET filtered = 1 ");
914 strcat (sql, "WHERE way_id IN ( ");
915 strcat (sql, "SELECT w.ref ");
916 strcat (sql, "FROM osm_relations AS r ");
917 strcat (sql,
918 "JOIN osm_relation_refs AS w ON (w.type = 'W' AND r.rel_id = w.rel_id) ");
919 strcat (sql, "WHERE r.filtered = 1)");
920 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
921 if (ret != SQLITE_OK)
922 {
923 fprintf (stderr, "UPDATE osm_ways error: %s\n", sql_err);
924 sqlite3_free (sql_err);
925 return 0;
926 }
927 return 1;
928 }
929
930 static int
filter_node_relations(sqlite3 * handle)931 filter_node_relations (sqlite3 * handle)
932 {
933 /* selecting any NODE required by selected RELATIONS */
934 char sql[1024];
935 int ret;
936 char *sql_err = NULL;
937
938 strcpy (sql, "UPDATE osm_nodes SET filtered = 1 ");
939 strcat (sql, "WHERE node_id IN ( ");
940 strcat (sql, "SELECT n.ref ");
941 strcat (sql, "FROM osm_relations AS r ");
942 strcat (sql,
943 "JOIN osm_relation_refs AS n ON (n.type = 'N' AND r.rel_id = n.rel_id) ");
944 strcat (sql, "WHERE r.filtered = 1)");
945 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
946 if (ret != SQLITE_OK)
947 {
948 fprintf (stderr, "UPDATE osm_nodes error: %s\n", sql_err);
949 sqlite3_free (sql_err);
950 return 0;
951 }
952 return 1;
953 }
954
955 static int
filter_node_ways(sqlite3 * handle)956 filter_node_ways (sqlite3 * handle)
957 {
958 /* selecting any NODE required by selected WAYS */
959 char sql[1024];
960 int ret;
961 char *sql_err = NULL;
962
963 strcpy (sql, "UPDATE osm_nodes SET filtered = 1 ");
964 strcat (sql, "WHERE node_id IN ( SELECT n.node_id ");
965 strcat (sql, "FROM osm_ways AS w ");
966 strcat (sql, "JOIN osm_way_refs AS n ON (w.way_id = n.way_id) ");
967 strcat (sql, "WHERE w.filtered = 1)");
968 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
969 if (ret != SQLITE_OK)
970 {
971 fprintf (stderr, "UPDATE osm_nodes error: %s\n", sql_err);
972 sqlite3_free (sql_err);
973 return 0;
974 }
975 return 1;
976 }
977
978 static int
filter_nodes(sqlite3 * handle,void * mask,int mask_len)979 filter_nodes (sqlite3 * handle, void *mask, int mask_len)
980 {
981 /* filtering any NODE to be exported */
982 char sql[1024];
983 int ret;
984 sqlite3_stmt *query = NULL;
985 sqlite3_stmt *stmt_nodes = NULL;
986 sqlite3_stmt *stmt_ways = NULL;
987 sqlite3_stmt *stmt_rels = NULL;
988 char *sql_err = NULL;
989
990 /* the complete INSERT operation is handled as an unique SQL Transaction */
991 ret = sqlite3_exec (handle, "BEGIN", NULL, NULL, &sql_err);
992 if (ret != SQLITE_OK)
993 {
994 fprintf (stderr, "BEGIN TRANSACTION error: %s\n", sql_err);
995 sqlite3_free (sql_err);
996 return 0;
997 }
998
999 /* preparing the UPDATE NODES statement */
1000 strcpy (sql, "UPDATE osm_nodes SET filtered = 1 WHERE node_id = ?");
1001 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_nodes, NULL);
1002 if (ret != SQLITE_OK)
1003 {
1004 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1005 return 0;
1006 }
1007
1008 /* preparing the UPDATE WAYS statement */
1009 strcpy (sql, "UPDATE osm_ways SET filtered = 1 WHERE way_id IN (");
1010 strcat (sql, "SELECT way_id FROM osm_way_refs WHERE node_id = ?)");
1011 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_ways, NULL);
1012 if (ret != SQLITE_OK)
1013 {
1014 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1015 return 0;
1016 }
1017
1018 /* preparing the UPDATE RELATIONS statement */
1019 strcpy (sql, "UPDATE osm_relations SET filtered = 1 WHERE rel_id IN (");
1020 strcat (sql,
1021 "SELECT rel_id FROM osm_relation_refs WHERE type = 'N' AND ref = ?)");
1022 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_rels, NULL);
1023 if (ret != SQLITE_OK)
1024 {
1025 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1026 return 0;
1027 }
1028
1029 /* preparing the QUERY NODES statement */
1030 strcpy (sql, "SELECT node_id FROM osm_nodes ");
1031 strcat (sql, "WHERE MbrIntersects(Geometry, ?) = 1 ");
1032 strcat (sql, "AND ST_Intersects(Geometry, ?) = 1");
1033 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &query, NULL);
1034 if (ret != SQLITE_OK)
1035 {
1036 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1037 return 0;
1038 }
1039 sqlite3_bind_blob (query, 1, mask, mask_len, SQLITE_STATIC);
1040 sqlite3_bind_blob (query, 2, mask, mask_len, SQLITE_STATIC);
1041
1042 while (1)
1043 {
1044 /* scrolling the result set */
1045 ret = sqlite3_step (query);
1046 if (ret == SQLITE_DONE)
1047 {
1048 /* there are no more rows to fetch - we can stop looping */
1049 break;
1050 }
1051 if (ret == SQLITE_ROW)
1052 {
1053 /* ok, we've just fetched a valid row */
1054 sqlite3_int64 id = sqlite3_column_int64 (query, 0);
1055
1056 /* marking this NODE as filtered */
1057 sqlite3_reset (stmt_nodes);
1058 sqlite3_clear_bindings (stmt_nodes);
1059 sqlite3_bind_int64 (stmt_nodes, 1, id);
1060 ret = sqlite3_step (stmt_nodes);
1061 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1062 ;
1063 else
1064 {
1065 fprintf (stderr, "sqlite3_step() error: UPDATE NODES\n");
1066 goto stop;
1067 }
1068
1069 /* marking any dependent WAY as filtered */
1070 sqlite3_reset (stmt_ways);
1071 sqlite3_clear_bindings (stmt_ways);
1072 sqlite3_bind_int64 (stmt_ways, 1, id);
1073 ret = sqlite3_step (stmt_ways);
1074 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1075 ;
1076 else
1077 {
1078 fprintf (stderr, "sqlite3_step() error: UPDATE WAYS\n");
1079 goto stop;
1080 }
1081
1082 /* marking any dependent RELATION as filtered */
1083 sqlite3_reset (stmt_rels);
1084 sqlite3_clear_bindings (stmt_rels);
1085 sqlite3_bind_int64 (stmt_rels, 1, id);
1086 ret = sqlite3_step (stmt_rels);
1087 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1088 ;
1089 else
1090 {
1091 fprintf (stderr,
1092 "sqlite3_step() error: UPDATE RELATIONS\n");
1093 goto stop;
1094 }
1095 }
1096 else
1097 {
1098 /* some unexpected error occurred */
1099 fprintf (stderr, "sqlite3_step() error: %s\n",
1100 sqlite3_errmsg (handle));
1101 goto stop;
1102 }
1103 }
1104 sqlite3_finalize (query);
1105 sqlite3_finalize (stmt_nodes);
1106 sqlite3_finalize (stmt_ways);
1107 sqlite3_finalize (stmt_rels);
1108
1109 /* committing the still pending SQL Transaction */
1110 ret = sqlite3_exec (handle, "COMMIT", NULL, NULL, &sql_err);
1111 if (ret != SQLITE_OK)
1112 {
1113 fprintf (stderr, "COMMIT TRANSACTION error: %s\n", sql_err);
1114 sqlite3_free (sql_err);
1115 return 0;
1116 }
1117 return 1;
1118
1119 stop:
1120 if (query)
1121 sqlite3_finalize (query);
1122 if (stmt_nodes)
1123 sqlite3_finalize (stmt_nodes);
1124 if (stmt_ways)
1125 sqlite3_finalize (stmt_ways);
1126 if (stmt_rels)
1127 sqlite3_finalize (stmt_rels);
1128 return 0;
1129 }
1130
1131 static int
parse_wkt_mask(const char * wkt_path,void ** mask,int * mask_len)1132 parse_wkt_mask (const char *wkt_path, void **mask, int *mask_len)
1133 {
1134 /* acquiring the WKT mask */
1135 int cnt = 0;
1136 char *wkt_buf = NULL;
1137 char *p;
1138 int c;
1139 gaiaGeomCollPtr geom = NULL;
1140
1141 /* opening the text file containing the WKT mask */
1142 FILE *in = fopen (wkt_path, "r");
1143 if (in == NULL)
1144 {
1145 fprintf (stderr, "Unable to open: %s\n", wkt_path);
1146 return 0;
1147 }
1148
1149 /* counting how many chars are there */
1150 while (getc (in) != EOF)
1151 cnt++;
1152 if (cnt == 0)
1153 {
1154 fprintf (stderr, "Empty file: %s\n", wkt_path);
1155 fclose (in);
1156 return 0;
1157 }
1158
1159 /* allocating the WKT buffer */
1160 wkt_buf = malloc (cnt + 1);
1161 memset (wkt_buf, '\0', cnt + 1);
1162 p = wkt_buf;
1163 /* restarting the text file */
1164 rewind (in);
1165
1166 while ((c = getc (in)) != EOF)
1167 {
1168 /* loading the WKT buffer */
1169 if ((p - wkt_buf) <= cnt)
1170 *p++ = c;
1171 }
1172 *p = '\0';
1173 fclose (in);
1174
1175 /* attempting to parse the WKT expression */
1176 geom = gaiaParseWkt ((unsigned char *) wkt_buf, -1);
1177 free (wkt_buf);
1178 if (!geom)
1179 return 0;
1180
1181 /* converting to Binary Blob */
1182 gaiaToSpatiaLiteBlobWkb (geom, (unsigned char **) mask, mask_len);
1183 gaiaFreeGeomColl (geom);
1184 return 1;
1185 }
1186
1187 static void
open_db(const char * path,sqlite3 ** handle,int cache_size,void * cache)1188 open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache)
1189 {
1190 /* opening the DB */
1191 sqlite3 *db_handle;
1192 int ret;
1193 char sql[1024];
1194 int spatialite_rs = 0;
1195 int spatialite_gc = 0;
1196 int rs_srid = 0;
1197 int auth_name = 0;
1198 int auth_srid = 0;
1199 int ref_sys_name = 0;
1200 int proj4text = 0;
1201 int f_table_name = 0;
1202 int f_geometry_column = 0;
1203 int coord_dimension = 0;
1204 int gc_srid = 0;
1205 int type = 0;
1206 int geometry_type = 0;
1207 int spatial_index_enabled = 0;
1208 int node_id = 0;
1209 int version = 0;
1210 int timestamp = 0;
1211 int uid = 0;
1212 int user = 0;
1213 int changeset = 0;
1214 int filtered = 0;
1215 int geometry = 0;
1216 int sub = 0;
1217 int k = 0;
1218 int v = 0;
1219 int way_id = 0;
1220 int rel_id = 0;
1221 int role = 0;
1222 int ref = 0;
1223 const char *name;
1224 int i;
1225 char **results;
1226 int rows;
1227 int columns;
1228
1229 *handle = NULL;
1230 printf ("SQLite version: %s\n", sqlite3_libversion ());
1231 printf ("SpatiaLite version: %s\n\n", spatialite_version ());
1232
1233 ret = sqlite3_open_v2 (path, &db_handle, SQLITE_OPEN_READWRITE, NULL);
1234 if (ret != SQLITE_OK)
1235 {
1236 fprintf (stderr, "cannot open '%s': %s\n", path,
1237 sqlite3_errmsg (db_handle));
1238 sqlite3_close (db_handle);
1239 return;
1240 }
1241 spatialite_init_ex (db_handle, cache, 0);
1242 if (cache_size > 0)
1243 {
1244 /* setting the CACHE-SIZE */
1245 sprintf (sql, "PRAGMA cache_size=%d", cache_size);
1246 sqlite3_exec (db_handle, sql, NULL, NULL, NULL);
1247 }
1248
1249 /* checking the GEOMETRY_COLUMNS table */
1250 strcpy (sql, "PRAGMA table_info(geometry_columns)");
1251 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1252 if (ret != SQLITE_OK)
1253 goto unknown;
1254 if (rows < 1)
1255 ;
1256 else
1257 {
1258 for (i = 1; i <= rows; i++)
1259 {
1260 name = results[(i * columns) + 1];
1261 if (strcasecmp (name, "f_table_name") == 0)
1262 f_table_name = 1;
1263 if (strcasecmp (name, "f_geometry_column") == 0)
1264 f_geometry_column = 1;
1265 if (strcasecmp (name, "coord_dimension") == 0)
1266 coord_dimension = 1;
1267 if (strcasecmp (name, "srid") == 0)
1268 gc_srid = 1;
1269 if (strcasecmp (name, "type") == 0)
1270 type = 1;
1271 if (strcasecmp (name, "geometry_type") == 0)
1272 geometry_type = 1;
1273 if (strcasecmp (name, "spatial_index_enabled") == 0)
1274 spatial_index_enabled = 1;
1275 }
1276 }
1277 sqlite3_free_table (results);
1278 if (f_table_name && f_geometry_column && type && coord_dimension
1279 && gc_srid && spatial_index_enabled)
1280 spatialite_gc = 1;
1281 if (f_table_name && f_geometry_column && geometry_type && coord_dimension
1282 && gc_srid && spatial_index_enabled)
1283 spatialite_gc = 3;
1284
1285 /* checking the SPATIAL_REF_SYS table */
1286 strcpy (sql, "PRAGMA table_info(spatial_ref_sys)");
1287 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1288 if (ret != SQLITE_OK)
1289 goto unknown;
1290 if (rows < 1)
1291 ;
1292 else
1293 {
1294 for (i = 1; i <= rows; i++)
1295 {
1296 name = results[(i * columns) + 1];
1297 if (strcasecmp (name, "srid") == 0)
1298 rs_srid = 1;
1299 if (strcasecmp (name, "auth_name") == 0)
1300 auth_name = 1;
1301 if (strcasecmp (name, "auth_srid") == 0)
1302 auth_srid = 1;
1303 if (strcasecmp (name, "ref_sys_name") == 0)
1304 ref_sys_name = 1;
1305 if (strcasecmp (name, "proj4text") == 0)
1306 proj4text = 1;
1307 }
1308 }
1309 sqlite3_free_table (results);
1310 if (rs_srid && auth_name && auth_srid && ref_sys_name && proj4text)
1311 spatialite_rs = 1;
1312 /* verifying the MetaData format */
1313 if (spatialite_gc && spatialite_rs)
1314 ;
1315 else
1316 goto unknown;
1317
1318 /* checking the OSM_NODES table */
1319 strcpy (sql, "PRAGMA table_info(osm_nodes)");
1320 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1321 if (ret != SQLITE_OK)
1322 goto unknown;
1323 if (rows < 1)
1324 ;
1325 else
1326 {
1327 for (i = 1; i <= rows; i++)
1328 {
1329 name = results[(i * columns) + 1];
1330 if (strcasecmp (name, "node_id") == 0)
1331 node_id = 1;
1332 if (strcasecmp (name, "version") == 0)
1333 version = 1;
1334 if (strcasecmp (name, "timestamp") == 0)
1335 timestamp = 1;
1336 if (strcasecmp (name, "uid") == 0)
1337 uid = 1;
1338 if (strcasecmp (name, "user") == 0)
1339 user = 1;
1340 if (strcasecmp (name, "changeset") == 0)
1341 changeset = 1;
1342 if (strcasecmp (name, "filtered") == 0)
1343 filtered = 1;
1344 if (strcasecmp (name, "Geometry") == 0)
1345 geometry = 1;
1346 }
1347 }
1348 sqlite3_free_table (results);
1349 if (node_id && version && timestamp && uid && user && changeset && filtered
1350 && geometry)
1351 ;
1352 else
1353 goto unknown;
1354
1355 /* checking the OSM_NODE_TAGS table */
1356 strcpy (sql, "PRAGMA table_info(osm_node_tags)");
1357 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1358 if (ret != SQLITE_OK)
1359 goto unknown;
1360 if (rows < 1)
1361 ;
1362 else
1363 {
1364 node_id = 0;
1365 for (i = 1; i <= rows; i++)
1366 {
1367 name = results[(i * columns) + 1];
1368 if (strcasecmp (name, "node_id") == 0)
1369 node_id = 1;
1370 if (strcasecmp (name, "sub") == 0)
1371 sub = 1;
1372 if (strcasecmp (name, "k") == 0)
1373 k = 1;
1374 if (strcasecmp (name, "v") == 0)
1375 v = 1;
1376 }
1377 }
1378 sqlite3_free_table (results);
1379 if (node_id && sub && k && v)
1380 ;
1381 else
1382 goto unknown;
1383
1384 /* checking the OSM_WAYS table */
1385 strcpy (sql, "PRAGMA table_info(osm_ways)");
1386 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1387 if (ret != SQLITE_OK)
1388 goto unknown;
1389 if (rows < 1)
1390 ;
1391 else
1392 {
1393 version = 0;
1394 timestamp = 0;
1395 uid = 0;
1396 user = 0;
1397 changeset = 0;
1398 filtered = 0;
1399 for (i = 1; i <= rows; i++)
1400 {
1401 name = results[(i * columns) + 1];
1402 if (strcasecmp (name, "way_id") == 0)
1403 way_id = 1;
1404 if (strcasecmp (name, "version") == 0)
1405 version = 1;
1406 if (strcasecmp (name, "timestamp") == 0)
1407 timestamp = 1;
1408 if (strcasecmp (name, "uid") == 0)
1409 uid = 1;
1410 if (strcasecmp (name, "user") == 0)
1411 user = 1;
1412 if (strcasecmp (name, "changeset") == 0)
1413 changeset = 1;
1414 if (strcasecmp (name, "filtered") == 0)
1415 filtered = 1;
1416 }
1417 }
1418 sqlite3_free_table (results);
1419 if (way_id && version && timestamp && uid && user && changeset && filtered)
1420 ;
1421 else
1422 goto unknown;
1423
1424 /* checking the OSM_WAY_TAGS table */
1425 strcpy (sql, "PRAGMA table_info(osm_way_tags)");
1426 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1427 if (ret != SQLITE_OK)
1428 goto unknown;
1429 if (rows < 1)
1430 ;
1431 else
1432 {
1433 way_id = 0;
1434 sub = 0;
1435 k = 0;
1436 v = 0;
1437 for (i = 1; i <= rows; i++)
1438 {
1439 name = results[(i * columns) + 1];
1440 if (strcasecmp (name, "way_id") == 0)
1441 way_id = 1;
1442 if (strcasecmp (name, "sub") == 0)
1443 sub = 1;
1444 if (strcasecmp (name, "k") == 0)
1445 k = 1;
1446 if (strcasecmp (name, "v") == 0)
1447 v = 1;
1448 }
1449 }
1450 sqlite3_free_table (results);
1451 if (way_id && sub && k && v)
1452 ;
1453 else
1454 goto unknown;
1455
1456 /* checking the OSM_WAY_REFS table */
1457 strcpy (sql, "PRAGMA table_info(osm_way_refs)");
1458 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1459 if (ret != SQLITE_OK)
1460 goto unknown;
1461 if (rows < 1)
1462 ;
1463 else
1464 {
1465 way_id = 0;
1466 sub = 0;
1467 node_id = 0;
1468 for (i = 1; i <= rows; i++)
1469 {
1470 name = results[(i * columns) + 1];
1471 if (strcasecmp (name, "way_id") == 0)
1472 way_id = 1;
1473 if (strcasecmp (name, "sub") == 0)
1474 sub = 1;
1475 if (strcasecmp (name, "node_id") == 0)
1476 node_id = 1;
1477 }
1478 }
1479 sqlite3_free_table (results);
1480 if (way_id && sub && node_id)
1481 ;
1482 else
1483 goto unknown;
1484
1485 /* checking the OSM_RELATIONS table */
1486 strcpy (sql, "PRAGMA table_info(osm_relations)");
1487 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1488 if (ret != SQLITE_OK)
1489 goto unknown;
1490 if (rows < 1)
1491 ;
1492 else
1493 {
1494 version = 0;
1495 timestamp = 0;
1496 uid = 0;
1497 user = 0;
1498 changeset = 0;
1499 filtered = 0;
1500 for (i = 1; i <= rows; i++)
1501 {
1502 name = results[(i * columns) + 1];
1503 if (strcasecmp (name, "rel_id") == 0)
1504 rel_id = 1;
1505 if (strcasecmp (name, "version") == 0)
1506 version = 1;
1507 if (strcasecmp (name, "timestamp") == 0)
1508 timestamp = 1;
1509 if (strcasecmp (name, "uid") == 0)
1510 uid = 1;
1511 if (strcasecmp (name, "user") == 0)
1512 user = 1;
1513 if (strcasecmp (name, "changeset") == 0)
1514 changeset = 1;
1515 if (strcasecmp (name, "filtered") == 0)
1516 filtered = 1;
1517 }
1518 }
1519 sqlite3_free_table (results);
1520 if (rel_id && version && timestamp && uid && user && changeset && filtered)
1521 ;
1522 else
1523 goto unknown;
1524
1525 /* checking the OSM_RELATION_TAGS table */
1526 strcpy (sql, "PRAGMA table_info(osm_relation_tags)");
1527 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1528 if (ret != SQLITE_OK)
1529 goto unknown;
1530 if (rows < 1)
1531 ;
1532 else
1533 {
1534 rel_id = 0;
1535 sub = 0;
1536 k = 0;
1537 v = 0;
1538 for (i = 1; i <= rows; i++)
1539 {
1540 name = results[(i * columns) + 1];
1541 if (strcasecmp (name, "rel_id") == 0)
1542 rel_id = 1;
1543 if (strcasecmp (name, "sub") == 0)
1544 sub = 1;
1545 if (strcasecmp (name, "k") == 0)
1546 k = 1;
1547 if (strcasecmp (name, "v") == 0)
1548 v = 1;
1549 }
1550 }
1551 sqlite3_free_table (results);
1552 if (rel_id && sub && k && v)
1553 ;
1554 else
1555 goto unknown;
1556
1557 /* checking the OSM_RELATION_REFS table */
1558 strcpy (sql, "PRAGMA table_info(osm_relation_refs)");
1559 ret = sqlite3_get_table (db_handle, sql, &results, &rows, &columns, NULL);
1560 if (ret != SQLITE_OK)
1561 goto unknown;
1562 if (rows < 1)
1563 ;
1564 else
1565 {
1566 rel_id = 0;
1567 sub = 0;
1568 type = 0;
1569 for (i = 1; i <= rows; i++)
1570 {
1571 name = results[(i * columns) + 1];
1572 if (strcasecmp (name, "rel_id") == 0)
1573 rel_id = 1;
1574 if (strcasecmp (name, "sub") == 0)
1575 sub = 1;
1576 if (strcasecmp (name, "type") == 0)
1577 type = 1;
1578 if (strcasecmp (name, "ref") == 0)
1579 ref = 1;
1580 if (strcasecmp (name, "role") == 0)
1581 role = 1;
1582 }
1583 }
1584 sqlite3_free_table (results);
1585 if (rel_id && sub && type && ref && role)
1586 ;
1587 else
1588 goto unknown;
1589
1590 *handle = db_handle;
1591 return;
1592
1593 unknown:
1594 if (db_handle)
1595 sqlite3_close (db_handle);
1596 fprintf (stderr, "DB '%s'\n", path);
1597 fprintf (stderr, "doesn't seems to contain valid OSM-RAW data ...\n\n");
1598 return;
1599 }
1600
1601 static void
do_version()1602 do_version ()
1603 {
1604 /* printing version infos */
1605 fprintf( stderr, "\nVersion infos\n");
1606 fprintf( stderr, "===========================================\n");
1607 fprintf (stderr, "spatialite_osm_filter: %s\n", SPATIALITE_VERSION);
1608 fprintf (stderr, "target CPU ..........: %s\n", spatialite_target_cpu ());
1609 fprintf (stderr, "libspatialite .......: %s\n", spatialite_version ());
1610 fprintf (stderr, "libsqlite3 ..........: %s\n", sqlite3_libversion ());
1611 fprintf (stderr, "\n");
1612 }
1613
1614 static void
do_help()1615 do_help ()
1616 {
1617 /* printing the argument list */
1618 fprintf (stderr, "\n\nusage: spatialite_osm_filter ARGLIST\n");
1619 fprintf (stderr,
1620 "==============================================================\n");
1621 fprintf (stderr,
1622 "-h or --help print this help message\n");
1623 fprintf (stderr, "-v or --version print version infos\n");
1624 fprintf (stderr,
1625 "-o or --osm-path pathname the OSM-XML [output] file path\n");
1626 fprintf (stderr,
1627 "-w or --wkt-mask-path pathname path of text file [WKT mask]\n");
1628 fprintf (stderr,
1629 "-d or --db-path pathname the SpatiaLite DB path\n\n");
1630 fprintf (stderr, "you can specify the following options as well\n");
1631 fprintf (stderr,
1632 "-cs or --cache-size num DB cache size (how many pages)\n");
1633 fprintf (stderr,
1634 "-m or --in-memory using IN-MEMORY database\n");
1635 fprintf (stderr,
1636 "-jo or --journal-off unsafe [but faster] mode\n");
1637 }
1638
1639 int
main(int argc,char * argv[])1640 main (int argc, char *argv[])
1641 {
1642 /* the MAIN function simply perform arguments checking */
1643 sqlite3 *handle;
1644 int i;
1645 int next_arg = ARG_NONE;
1646 const char *osm_path = NULL;
1647 const char *wkt_path = NULL;
1648 const char *db_path = NULL;
1649 int in_memory = 0;
1650 int cache_size = 0;
1651 int journal_off = 0;
1652 int error = 0;
1653 void *mask = NULL;
1654 int mask_len = 0;
1655 FILE *out = NULL;
1656 char *sql_err = NULL;
1657 int ret;
1658 void *cache;
1659
1660 for (i = 1; i < argc; i++)
1661 {
1662 /* parsing the invocation arguments */
1663 if (next_arg != ARG_NONE)
1664 {
1665 switch (next_arg)
1666 {
1667 case ARG_OSM_PATH:
1668 osm_path = argv[i];
1669 break;
1670 case ARG_MASK_PATH:
1671 wkt_path = argv[i];
1672 break;
1673 case ARG_DB_PATH:
1674 db_path = argv[i];
1675 break;
1676 case ARG_CACHE_SIZE:
1677 cache_size = atoi (argv[i]);
1678 break;
1679 };
1680 next_arg = ARG_NONE;
1681 continue;
1682 }
1683 if (strcasecmp (argv[i], "--help") == 0
1684 || strcmp (argv[i], "-h") == 0)
1685 {
1686 do_help ();
1687 return -1;
1688 }
1689 if (strcasecmp (argv[i], "--version") == 0
1690 || strcmp (argv[i], "-v") == 0)
1691 {
1692 do_version ();
1693 return -1;
1694 }
1695 if (strcmp (argv[i], "-o") == 0)
1696 {
1697 next_arg = ARG_OSM_PATH;
1698 continue;
1699 }
1700 if (strcasecmp (argv[i], "--osm-path") == 0)
1701 {
1702 next_arg = ARG_OSM_PATH;
1703 continue;
1704 }
1705 if (strcmp (argv[i], "-w") == 0)
1706 {
1707 next_arg = ARG_MASK_PATH;
1708 continue;
1709 }
1710 if (strcasecmp (argv[i], "--wkt-mask-path") == 0)
1711 {
1712 next_arg = ARG_MASK_PATH;
1713 continue;
1714 }
1715 if (strcmp (argv[i], "-d") == 0)
1716 {
1717 next_arg = ARG_DB_PATH;
1718 continue;
1719 }
1720 if (strcasecmp (argv[i], "--db-path") == 0)
1721 {
1722 next_arg = ARG_DB_PATH;
1723 continue;
1724 }
1725 if (strcasecmp (argv[i], "--cache-size") == 0
1726 || strcmp (argv[i], "-cs") == 0)
1727 {
1728 next_arg = ARG_CACHE_SIZE;
1729 continue;
1730 }
1731 if (strcasecmp (argv[i], "-m") == 0)
1732 {
1733 in_memory = 1;
1734 next_arg = ARG_NONE;
1735 continue;
1736 }
1737 if (strcasecmp (argv[i], "--in-memory") == 0)
1738 {
1739 in_memory = 1;
1740 next_arg = ARG_NONE;
1741 continue;
1742 }
1743 if (strcasecmp (argv[i], "-jo") == 0)
1744 {
1745 journal_off = 1;
1746 next_arg = ARG_NONE;
1747 continue;
1748 }
1749 if (strcasecmp (argv[i], "--journal-off") == 0)
1750 {
1751 journal_off = 1;
1752 next_arg = ARG_NONE;
1753 continue;
1754 }
1755 fprintf (stderr, "unknown argument: %s\n", argv[i]);
1756 error = 1;
1757 }
1758 if (error)
1759 {
1760 do_help ();
1761 return -1;
1762 }
1763
1764 /* checking the arguments */
1765 if (!osm_path)
1766 {
1767 fprintf (stderr,
1768 "did you forget setting the --osm-path argument ?\n");
1769 error = 1;
1770 }
1771 if (!db_path)
1772 {
1773 fprintf (stderr, "did you forget setting the --db-path argument ?\n");
1774 error = 1;
1775 }
1776 if (!wkt_path)
1777 {
1778 fprintf (stderr,
1779 "did you forget setting the --wkt-mask-path argument ?\n");
1780 error = 1;
1781 }
1782
1783 if (error)
1784 {
1785 do_help ();
1786 return -1;
1787 }
1788
1789 if (!parse_wkt_mask (wkt_path, &mask, &mask_len))
1790 {
1791 fprintf (stderr,
1792 "ERROR: Invalid WKT mask [not a valid WKT expression]\n");
1793 return -1;
1794 }
1795
1796 /* opening the DB */
1797 if (in_memory)
1798 cache_size = 0;
1799 cache = spatialite_alloc_connection ();
1800 open_db (db_path, &handle, cache_size, cache);
1801 if (!handle)
1802 return -1;
1803 if (in_memory)
1804 {
1805 /* loading the DB in-memory */
1806 sqlite3 *mem_db_handle;
1807 sqlite3_backup *backup;
1808 ret =
1809 sqlite3_open_v2 (":memory:", &mem_db_handle,
1810 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1811 NULL);
1812 if (ret != SQLITE_OK)
1813 {
1814 fprintf (stderr, "cannot open 'MEMORY-DB': %s\n",
1815 sqlite3_errmsg (mem_db_handle));
1816 sqlite3_close (mem_db_handle);
1817 return -1;
1818 }
1819 backup = sqlite3_backup_init (mem_db_handle, "main", handle, "main");
1820 if (!backup)
1821 {
1822 fprintf (stderr, "cannot load 'MEMORY-DB'\n");
1823 sqlite3_close (handle);
1824 sqlite3_close (mem_db_handle);
1825 return -1;
1826 }
1827 while (1)
1828 {
1829 ret = sqlite3_backup_step (backup, 1024);
1830 if (ret == SQLITE_DONE)
1831 break;
1832 }
1833 ret = sqlite3_backup_finish (backup);
1834 sqlite3_close (handle);
1835 handle = mem_db_handle;
1836 printf ("\nusing IN-MEMORY database\n");
1837 spatialite_cleanup_ex (cache);
1838 cache = spatialite_alloc_connection ();
1839 spatialite_init_ex (handle, cache, 0);
1840 }
1841
1842 out = fopen (osm_path, "wb");
1843 if (out == NULL)
1844 goto stop;
1845
1846 if (journal_off)
1847 {
1848 /* disabling the journal: unsafe but faster */
1849 ret =
1850 sqlite3_exec (handle, "PRAGMA journal_mode = OFF", NULL, NULL,
1851 &sql_err);
1852 if (ret != SQLITE_OK)
1853 {
1854 fprintf (stderr, "PRAGMA journal_mode=OFF error: %s\n",
1855 sql_err);
1856 sqlite3_free (sql_err);
1857 goto stop;
1858 }
1859 }
1860
1861 /* resetting filtered nodes, ways and relations */
1862 if (!reset_filtered (handle))
1863 goto stop;
1864
1865 /* identifying filtered nodes */
1866 if (!filter_nodes (handle, mask, mask_len))
1867 goto stop;
1868
1869 /* identifying relations depending on other relations */
1870 if (!filter_rel_relations (handle))
1871 goto stop;
1872
1873 /* identifying ways depending on relations */
1874 if (!filter_way_relations (handle))
1875 goto stop;
1876
1877 /* identifying nodes depending on relations */
1878 if (!filter_node_relations (handle))
1879 goto stop;
1880
1881 /* identifying nodes depending on ways */
1882 if (!filter_node_ways (handle))
1883 goto stop;
1884
1885 /* writing the OSM header */
1886 fprintf (out, "<?xml version='1.0' encoding='UTF-8'?>\n");
1887 fprintf (out, "<osm version=\"0.6\" generator=\"splite2osm\">\n");
1888
1889 fprintf (stderr, "OutNodes\n");
1890 /* exporting OSM NODES */
1891 if (!do_output_nodes (out, handle))
1892 {
1893 fprintf (stderr, "\nThe output OSM file is corrupted !!!\n");
1894 goto stop;
1895 }
1896
1897 fprintf (stderr, "OutWays\n");
1898 /* exporting OSM WAYS */
1899 if (!do_output_ways (out, handle))
1900 {
1901 fprintf (stderr, "\nThe output OSM file is corrupted !!!\n");
1902 goto stop;
1903 }
1904
1905 fprintf (stderr, "OutRelations\n");
1906 /* exporting OSM RELATIONS */
1907 if (!do_output_relations (out, handle))
1908 {
1909 fprintf (stderr, "\nThe output OSM file is corrupted !!!\n");
1910 goto stop;
1911 }
1912
1913 /* writing the OSM footer */
1914 fprintf (out, "</osm>\n");
1915
1916 stop:
1917 free (mask);
1918 sqlite3_close (handle);
1919 spatialite_cleanup_ex (cache);
1920 if (out != NULL)
1921 fclose (out);
1922 spatialite_shutdown ();
1923 return 0;
1924 }
1925