1 /*
2 / Exif.cpp
3 / methods related to EXIF import and XmlBLOB import/export
4 /
5 / version 1.7, 2013 May 8
6 /
7 / Author: Sandro Furieri a-furieri@lqt.it
8 /
9 / Copyright (C) 2008-2013 Alessandro Furieri
10 /
11 / This program is free software: you can redistribute it and/or modify
12 / it under the terms of the GNU General Public License as published by
13 / the Free Software Foundation, either version 3 of the License, or
14 / (at your option) any later version.
15 /
16 / This program is distributed in the hope that it will be useful,
17 / but WITHOUT ANY WARRANTY; without even the implied warranty of
18 / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 / GNU General Public License for more details.
20 /
21 / You should have received a copy of the GNU General Public License
22 / along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /
24 */
25
26 #include "Classdef.h"
27
28 #include <sys/types.h>
29 #if defined(_WIN32) && !defined(__MINGW32__)
30 #include <io.h>
31 #include <direct.h>
32 #else
33 #include <dirent.h>
34 #endif
35 #include <float.h>
36
37 #include <wx/filename.h>
38
39 #include <spatialite/gg_dxf.h>
40
41 #if defined(_WIN32) && !defined(__MINGW32__)
42 #define strcasecmp _stricmp
43 #endif
44
ImportExifPhotos(wxString & path,bool folder,bool metadata,bool gps_only)45 void MyFrame::ImportExifPhotos(wxString & path, bool folder, bool metadata,
46 bool gps_only)
47 {
48 //
49 // trying to import EXIF photos
50 //
51 int cnt;
52 char msg[256];
53 ::wxBeginBusyCursor();
54 if (CheckExifTables() == false)
55 {
56 ::wxEndBusyCursor();
57 wxMessageBox(wxT
58 ("An EXIF table is already defined, but has incompatibles columns"),
59 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
60 return;
61 }
62 if (folder == true)
63 cnt = ExifLoadDir(path, gps_only, metadata);
64 else
65 cnt = ExifLoadFile(path, gps_only, metadata);
66 ::wxEndBusyCursor();
67 sprintf(msg, "%d EXIF photo%s succesfully inserted into the DB\n", cnt,
68 (cnt > 1) ? "s where" : " was");
69 wxMessageBox(wxString::FromUTF8(msg), wxT("spatialite_gui"),
70 wxOK | wxICON_INFORMATION, this);
71 InitTableTree();
72 }
73
CheckExifTables()74 bool MyFrame::CheckExifTables()
75 {
76 //
77 // creates the EXIF DB tables / or checks existing ones for validity
78 //
79 int ret;
80 wxString sql;
81 char xsql[1024];
82 char *errMsg;
83 bool ok_photoId;
84 bool ok_photo;
85 bool ok_pixelX;
86 bool ok_pixelY;
87 bool ok_cameraMake;
88 bool ok_cameraModel;
89 bool ok_shotDateTime;
90 bool ok_gpsGeometry;
91 bool ok_gpsDirection;
92 bool ok_gpsTimestamp;
93 bool ok_fromPath;
94 bool ok_tagId;
95 bool ok_tagName;
96 bool ok_gpsTag;
97 bool ok_valueType;
98 bool ok_typeName;
99 bool ok_countValues;
100 bool ok_valueIndex;
101 bool ok_byteValue;
102 bool ok_stringValue;
103 bool ok_numValue;
104 bool ok_numValueBis;
105 bool ok_doubleValue;
106 bool ok_humanReadable;
107 bool err_pk;
108 bool ok_photoIdPk;
109 bool ok_tagIdPk;
110 bool ok_valueIndexPk;
111 bool pKey;
112 const char *name;
113 int i;
114 char **results;
115 int rows;
116 int columns;
117 // creating the ExifPhoto table
118 sql = wxT("CREATE TABLE IF NOT EXISTS ExifPhoto (\n");
119 sql += wxT("PhotoId INTEGER PRIMARY KEY AUTOINCREMENT,\n");
120 sql += wxT("Photo BLOB NOT NULL,\n");
121 sql += wxT("PixelX INTEGER,\n");
122 sql += wxT("PixelY INTEGER,\n");
123 sql += wxT("CameraMake TEXT,\n");
124 sql += wxT("CameraModel TEXT,\n");
125 sql += wxT("ShotDateTime DOUBLE,\n");
126 sql += wxT("GpsGeometry BLOB,\n");
127 sql += wxT("GpsDirection DOUBLE, ");
128 sql += wxT("GpsSatellites TEXT,\n");
129 sql += wxT("GpsTimestamp DOUBLE,\n");
130 sql += wxT("FromPath TEXT");
131 sql += wxT(")");
132 strcpy(xsql, sql.ToUTF8());
133 ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
134 if (ret != SQLITE_OK)
135 {
136 wxMessageBox(wxT("CREATE TABLE ExifPhoto error: ") +
137 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
138 wxOK | wxICON_ERROR, this);
139 sqlite3_free(errMsg);
140 goto abort;
141 }
142 // checking the ExifPhoto table for sanity
143 ok_photoId = false;
144 ok_photo = false;
145 ok_pixelX = false;
146 ok_pixelY = false;
147 ok_cameraMake = false;
148 ok_cameraModel = false;
149 ok_shotDateTime = false;
150 ok_gpsGeometry = false;
151 ok_gpsDirection = false;
152 ok_gpsTimestamp = false;
153 ok_fromPath = false;
154 ok_photoIdPk = false;
155 err_pk = false;
156 strcpy(xsql, "PRAGMA table_info(ExifPhoto)");
157 ret =
158 sqlite3_get_table(SqliteHandle, xsql, &results, &rows, &columns, &errMsg);
159 if (ret != SQLITE_OK)
160 {
161 wxMessageBox(wxT("PRAGMA table_info(ExifPhoto) error: ") +
162 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
163 wxOK | wxICON_ERROR, this);
164 sqlite3_free(errMsg);
165 goto abort;
166 }
167 if (rows < 1)
168 ;
169 else
170 {
171 for (i = 1; i <= rows; i++)
172 {
173 name = results[(i * columns) + 1];
174 if (atoi(results[(i * columns) + 5]) == 0)
175 pKey = false;
176 else
177 pKey = true;
178 if (strcasecmp(name, "PhotoId") == 0)
179 ok_photoId = true;
180 if (strcasecmp(name, "Photo") == 0)
181 ok_photo = true;
182 if (strcasecmp(name, "PixelX") == 0)
183 ok_pixelX = true;
184 if (strcasecmp(name, "PixelY") == 0)
185 ok_pixelY = true;
186 if (strcasecmp(name, "CameraMake") == 0)
187 ok_cameraMake = true;
188 if (strcasecmp(name, "CameraModel") == 0)
189 ok_cameraModel = true;
190 if (strcasecmp(name, "ShotDateTime") == 0)
191 ok_shotDateTime = true;
192 if (strcasecmp(name, "GpsGeometry") == 0)
193 ok_gpsGeometry = true;
194 if (strcasecmp(name, "GpsDirection") == 0)
195 ok_gpsDirection = true;
196 if (strcasecmp(name, "GpsTimestamp") == 0)
197 ok_gpsTimestamp = true;
198 if (strcasecmp(name, "FromPath") == 0)
199 ok_fromPath = true;
200 if (pKey == true)
201 {
202 if (strcasecmp(name, "PhotoId") == 0)
203 ok_photoIdPk = true;
204 else
205 err_pk = true;
206 }
207 }
208 }
209 sqlite3_free_table(results);
210 if (ok_photoId == true && ok_photo == true && ok_pixelX == true
211 && ok_pixelY == true && ok_cameraMake == true && ok_cameraModel == true
212 && ok_shotDateTime == true && ok_gpsGeometry == true
213 && ok_gpsDirection == true && ok_gpsTimestamp == true
214 && ok_fromPath == true && ok_photoIdPk == true && err_pk == false)
215 ;
216 else
217 {
218 wxMessageBox(wxT
219 ("ERROR: table ExifPhoto already exists, but has incompatible columns"),
220 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
221 sqlite3_free(errMsg);
222 goto abort;
223 }
224 // creating the ExifTags table
225 sql = wxT("CREATE TABLE IF NOT EXISTS ExifTags (\n");
226 sql += wxT("PhotoId INTEGER NOT NULL,\n");
227 sql += wxT("TagId INTEGER NOT NULL,\n");
228 sql += wxT("TagName TEXT NOT NULL,\n");
229 sql += wxT("GpsTag INTEGER NOT NULL CHECK (GpsTag IN (0, 1)),\n");
230 sql +=
231 wxT
232 ("ValueType INTEGER NOT NULL CHECK (ValueType IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)),\n");
233 sql += wxT("TypeName TEXT NOT NULL,\n");
234 sql += wxT("CountValues INTEGER NOT NULL,\n");
235 sql += wxT("PRIMARY KEY (PhotoId, TagId)");
236 sql += wxT(")");
237 strcpy(xsql, sql.ToUTF8());
238 ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
239 if (ret != SQLITE_OK)
240 {
241 wxMessageBox(wxT("CREATE TABLE ExifTags error: ") +
242 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
243 wxOK | wxICON_ERROR, this);
244 sqlite3_free(errMsg);
245 goto abort;
246 }
247 // checking the ExifTags table for sanity
248 ok_photoId = false;
249 ok_tagId = false;
250 ok_tagName = false;
251 ok_gpsTag = false;
252 ok_valueType = false;
253 ok_typeName = false;
254 ok_countValues = false;
255 ok_photoIdPk = false;
256 ok_tagIdPk = false;
257 err_pk = false;
258 strcpy(xsql, "PRAGMA table_info(ExifTags)");
259 ret =
260 sqlite3_get_table(SqliteHandle, xsql, &results, &rows, &columns, &errMsg);
261 if (ret != SQLITE_OK)
262 {
263 wxMessageBox(wxT("PRAGMA table_info(ExifTags) error: ") +
264 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
265 wxOK | wxICON_ERROR, this);
266 sqlite3_free(errMsg);
267 goto abort;
268 }
269 if (rows < 1)
270 ;
271 else
272 {
273 for (i = 1; i <= rows; i++)
274 {
275 name = results[(i * columns) + 1];
276 if (atoi(results[(i * columns) + 5]) == 0)
277 pKey = false;
278 else
279 pKey = true;
280 if (strcasecmp(name, "PhotoId") == 0)
281 ok_photoId = true;
282 if (strcasecmp(name, "TagId") == 0)
283 ok_tagId = true;
284 if (strcasecmp(name, "TagName") == 0)
285 ok_tagName = true;
286 if (strcasecmp(name, "GpsTag") == 0)
287 ok_gpsTag = true;
288 if (strcasecmp(name, "ValueType") == 0)
289 ok_valueType = true;
290 if (strcasecmp(name, "TypeName") == 0)
291 ok_typeName = true;
292 if (strcasecmp(name, "CountValues") == 0)
293 ok_countValues = true;
294 if (pKey == true)
295 {
296 if (strcasecmp(name, "PhotoId") == 0)
297 ok_photoIdPk = true;
298 else if (strcasecmp(name, "TagId") == 0)
299 ok_tagIdPk = true;
300 else
301 err_pk = true;
302 }
303 }
304 }
305 sqlite3_free_table(results);
306 if (ok_photoId == true && ok_tagId == true && ok_tagName == true
307 && ok_gpsTag == true && ok_valueType == true && ok_typeName == true
308 && ok_countValues == true && ok_photoIdPk == true && ok_tagIdPk == true
309 && err_pk == false)
310 ;
311 else
312 {
313 wxMessageBox(wxT
314 ("ERROR: table ExifTags already exists, but has incompatible columns"),
315 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
316 sqlite3_free(errMsg);
317 goto abort;
318 }
319 // creating the ExifValues table
320 sql = wxT("CREATE TABLE IF NOT EXISTS ExifValues (\n");
321 sql += wxT("PhotoId INTEGER NOT NULL,\n");
322 sql += wxT("TagId INTEGER NOT NULL,\n");
323 sql += wxT("ValueIndex INTEGER NOT NULL,\n");
324 sql += wxT("ByteValue BLOB,\n");
325 sql += wxT("StringValue TEXT,\n");
326 sql += wxT("NumValue INTEGER,\n");
327 sql += wxT("NumValueBis INTEGER,\n");
328 sql += wxT("DoubleValue DOUBLE,\n");
329 sql += wxT("HumanReadable TEXT,\n");
330 sql += wxT("PRIMARY KEY (PhotoId, TagId, ValueIndex)");
331 sql += wxT(")");
332 strcpy(xsql, sql.ToUTF8());
333 ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
334 if (ret != SQLITE_OK)
335 {
336 wxMessageBox(wxT("CREATE TABLE ExifValues error: ") +
337 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
338 wxOK | wxICON_ERROR, this);
339 sqlite3_free(errMsg);
340 goto abort;
341 }
342 // checking the ExifValues table for sanity
343 ok_photoId = false;
344 ok_tagId = false;
345 ok_valueIndex = false;
346 ok_byteValue = false;
347 ok_stringValue = false;
348 ok_numValue = false;
349 ok_numValueBis = false;
350 ok_doubleValue = false;
351 ok_humanReadable = false;
352 ok_photoIdPk = false;
353 ok_tagIdPk = false;
354 ok_valueIndexPk = false;
355 err_pk = false;
356 strcpy(xsql, "PRAGMA table_info(ExifValues)");
357 ret =
358 sqlite3_get_table(SqliteHandle, xsql, &results, &rows, &columns, &errMsg);
359 if (ret != SQLITE_OK)
360 {
361 wxMessageBox(wxT("PRAGMA table_info(ExifValues) error: ") +
362 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
363 wxOK | wxICON_ERROR, this);
364 sqlite3_free(errMsg);
365 goto abort;
366 }
367 if (rows < 1)
368 ;
369 else
370 {
371 for (i = 1; i <= rows; i++)
372 {
373 name = results[(i * columns) + 1];
374 if (atoi(results[(i * columns) + 5]) == 0)
375 pKey = false;
376 else
377 pKey = true;
378 if (strcasecmp(name, "PhotoId") == 0)
379 ok_photoId = true;
380 if (strcasecmp(name, "TagId") == 0)
381 ok_tagId = true;
382 if (strcasecmp(name, "ValueIndex") == 0)
383 ok_valueIndex = true;
384 if (strcasecmp(name, "ByteValue") == 0)
385 ok_byteValue = true;
386 if (strcasecmp(name, "StringValue") == 0)
387 ok_stringValue = true;
388 if (strcasecmp(name, "NumValue") == 0)
389 ok_numValue = true;
390 if (strcasecmp(name, "NumValueBis") == 0)
391 ok_numValueBis = true;
392 if (strcasecmp(name, "DoubleValue") == 0)
393 ok_doubleValue = true;
394 if (strcasecmp(name, "HumanReadable") == 0)
395 ok_humanReadable = true;
396 if (pKey == true)
397 {
398 if (strcasecmp(name, "PhotoId") == 0)
399 ok_photoIdPk = true;
400 else if (strcasecmp(name, "TagId") == 0)
401 ok_tagIdPk = true;
402 else if (strcasecmp(name, "ValueIndex") == 0)
403 ok_valueIndexPk = true;
404 else
405 err_pk = true;
406 }
407 }
408 }
409 sqlite3_free_table(results);
410 if (ok_photoId == true && ok_tagId == true && ok_valueIndex == true
411 && ok_byteValue == true && ok_stringValue == true && ok_numValue == true
412 && ok_numValueBis == true && ok_doubleValue == true
413 && ok_humanReadable == true && ok_photoIdPk == true && ok_tagIdPk == true
414 && ok_valueIndexPk == true && err_pk == false)
415 ;
416 else
417 {
418 wxMessageBox(wxT
419 ("ERROR: table ExifValues already exists, but has incompatible columns"),
420 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
421 sqlite3_free(errMsg);
422 goto abort;
423 }
424 // creating the ExifView view
425 sql = wxT("CREATE VIEW IF NOT EXISTS ExifMetadata AS\n");
426 sql += wxT("SELECT p.PhotoId AS PhotoId, ");
427 sql += wxT("t.TagId AS TagId, ");
428 sql += wxT("t.TagName AS TagName,");
429 sql += wxT("t.GpsTag AS GpsTag,\n");
430 sql += wxT("t.ValueType AS ValueType,");
431 sql += wxT("t.TypeName AS TypeName, ");
432 sql += wxT("t.CountValues AS CountValues, ");
433 sql += wxT("v.ValueIndex AS ValueIndex,\n");
434 sql += wxT("v.ByteValue AS ByteValue, ");
435 sql += wxT("v.StringValue AS StringValue, ");
436 sql += wxT("v.NumValue AS NumValue, ");
437 sql += wxT("v.NumValueBis AS NumValueBis,\n");
438 sql += wxT("v.DoubleValue AS DoubleValue, ");
439 sql += wxT("v.HumanReadable AS HumanReadable\n");
440 sql += wxT("FROM ExifPhoto AS p, ExifTags AS t, ExifValues AS v\n");
441 sql +=
442 wxT
443 ("WHERE t.PhotoId = p.PhotoId AND v.PhotoId = t.PhotoId AND v.TagId = t.TagId");
444 strcpy(xsql, sql.ToUTF8());
445 ret = sqlite3_exec(SqliteHandle, xsql, NULL, NULL, &errMsg);
446 if (ret != SQLITE_OK)
447 {
448 wxMessageBox(wxT("CREATE VIEW ExifMetadata error: ") +
449 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
450 wxOK | wxICON_ERROR, this);
451 sqlite3_free(errMsg);
452 goto abort;
453 }
454 return true;
455 abort:
456 return false;
457 }
458
ExifLoadDir(wxString & path,bool gps_only,bool metadata)459 int MyFrame::ExifLoadDir(wxString & path, bool gps_only, bool metadata)
460 {
461 //
462 // importing EXIF files from a whole DIRECTORY
463 //
464 #if defined(_WIN32) && !defined(__MINGW32__)
465 /* Visual Studio .NET */
466 struct _finddata_t c_file;
467 intptr_t hFile;
468 int cnt = 0;
469 wxString filePath;
470 if (_chdir(path.ToUTF8()) < 0)
471 return 0;
472 if ((hFile = _findfirst("*.*", &c_file)) == -1L)
473 ;
474 else
475 {
476 while (1)
477 {
478 if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
479 || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
480 {
481 filePath = path;
482 filePath += wxT("/") + wxString::FromUTF8(c_file.name);
483 cnt += ExifLoadFile(filePath, gps_only, metadata);
484 }
485 if (_findnext(hFile, &c_file) != 0)
486 break;
487 };
488 _findclose(hFile);
489 }
490 return cnt;
491 #else
492 /* not Visual Studio .NET */
493 int cnt = 0;
494 wxString filePath;
495 struct dirent *entry;
496 DIR *dir = opendir(path.ToUTF8());
497 if (!dir)
498 return 0;
499 while (1)
500 {
501 // scanning dir-entries
502 entry = readdir(dir);
503 if (!entry)
504 break;
505 filePath = path;
506 filePath += wxT("/") + wxString::FromUTF8(entry->d_name);
507 cnt += ExifLoadFile(filePath, gps_only, metadata);
508 }
509 closedir(dir);
510 return cnt;
511 #endif
512 }
513
ExifLoadFile(wxString & path,bool gps_only,bool metadata)514 int MyFrame::ExifLoadFile(wxString & path, bool gps_only, bool metadata)
515 {
516 //
517 // importing a single EXIF file
518 //
519 FILE *fl;
520 int sz = 0;
521 int rd;
522 int loaded = 0;
523 unsigned char *blob = NULL;
524 gaiaExifTagListPtr tag_list = NULL;
525 fl = fopen(path.ToUTF8(), "rb");
526 if (!fl)
527 return 0;
528 if (fseek(fl, 0, SEEK_END) == 0)
529 sz = ftell(fl);
530 if (sz > 14)
531 {
532 blob = (unsigned char *) malloc(sz);
533 rewind(fl);
534 rd = fread(blob, 1, sz, fl);
535 if (rd == sz)
536 {
537 tag_list = gaiaGetExifTags(blob, sz);
538 if (tag_list)
539 {
540 if (gps_only && IsExifGps(tag_list) == false)
541 goto stop;
542 if (UpdateExifTables(blob, sz, tag_list, metadata, path) == false)
543 goto stop;
544 loaded = 1;
545 }
546 }
547 }
548 stop:
549 if (blob)
550 free(blob);
551 if (tag_list)
552 gaiaExifTagsFree(tag_list);
553 fclose(fl);
554 return loaded;
555 }
556
IsExifGps(gaiaExifTagListPtr tag_list)557 bool MyFrame::IsExifGps(gaiaExifTagListPtr tag_list)
558 {
559 //
560 // checks if this one is a GPS-tagged EXIF
561 //
562 bool gps_lat = false;
563 bool gps_long = false;
564 gaiaExifTagPtr pT = tag_list->First;
565 while (pT)
566 {
567 if (pT->Gps && pT->TagId == 0x04)
568 gps_long = true;
569 if (pT->Gps && pT->TagId == 0x02)
570 gps_lat = true;
571 if (gps_long == true && gps_lat == true)
572 return true;
573 pT = pT->Next;
574 }
575 return false;
576 }
577
UpdateExifTables(unsigned char * blob,int sz,gaiaExifTagListPtr tag_list,bool metadata,wxString & path)578 bool MyFrame::UpdateExifTables(unsigned char *blob, int sz,
579 gaiaExifTagListPtr tag_list, bool metadata,
580 wxString & path)
581 {
582 //
583 // inserting an EXIF photo into the DB
584 //
585 int i;
586 int iv;
587 bool ok;
588 int xok;
589 int ok_human;
590 char tag_name[128];
591 gaiaExifTagPtr pT;
592 int ret;
593 char sql[1024];
594 char human[1024];
595 wxString make;
596 wxString model;
597 wxString satellites;
598 wxString date;
599 wxString timestamp;
600 char *errMsg = NULL;
601 sqlite3_stmt *stmt;
602 sqlite3_int64 pk = 0;
603 sqlite3_int64 val64;
604 double dblval;
605 const char *type_desc;
606 double longitude;
607 double latitude;
608 gaiaGeomCollPtr geom;
609 unsigned char *geoblob;
610 int geosize;
611 // starts a transaction
612 strcpy(sql, "BEGIN");
613 ret = sqlite3_exec(SqliteHandle, sql, NULL, NULL, &errMsg);
614 if (ret != SQLITE_OK)
615 {
616 wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
617 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
618 sqlite3_free(errMsg);
619 goto abort;
620 }
621 // feeding the ExifPhoto table; preparing the SQL statement
622 strcpy(sql,
623 "INSERT INTO ExifPhoto (PhotoId, Photo, PixelX, PixelY, CameraMake, CameraModel, ");
624 strcat(sql,
625 "ShotDateTime, GpsGeometry, GpsDirection, GpsSatellites, GpsTimestamp, FromPath) ");
626 strcat(sql,
627 "VALUES (NULL, ?, ?, ?, ?, ?, JulianDay(?), ?, ?, ?, JulianDay(?), ?)");
628 ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
629 if (ret != SQLITE_OK)
630 {
631 wxMessageBox(wxT("INSERT INTO ExifPhoto error: ") +
632 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
633 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
634 goto abort;
635 }
636 sqlite3_bind_blob(stmt, 1, blob, sz, SQLITE_STATIC);
637 val64 = GetPixelX(tag_list, &ok);
638 if (ok == true)
639 sqlite3_bind_int64(stmt, 2, val64);
640 else
641 sqlite3_bind_null(stmt, 2);
642 val64 = GetPixelY(tag_list, &ok);
643 if (ok == true)
644 sqlite3_bind_int64(stmt, 3, val64);
645 else
646 sqlite3_bind_null(stmt, 3);
647 GetMake(tag_list, make, &ok);
648 if (ok == true)
649 sqlite3_bind_text(stmt, 4, make.ToUTF8(), make.Len(), SQLITE_TRANSIENT);
650 else
651 sqlite3_bind_null(stmt, 4);
652 GetModel(tag_list, model, &ok);
653 if (ok == true)
654 sqlite3_bind_text(stmt, 5, model.ToUTF8(), model.Len(), SQLITE_TRANSIENT);
655 else
656 sqlite3_bind_null(stmt, 5);
657 GetDate(tag_list, date, &ok);
658 if (ok == true)
659 sqlite3_bind_text(stmt, 6, date.ToUTF8(), date.Len(), SQLITE_TRANSIENT);
660 else
661 sqlite3_bind_text(stmt, 6, "0000-00-00 00:00:00", 19, SQLITE_TRANSIENT);
662 GetGpsCoords(tag_list, &longitude, &latitude, &ok);
663 if (ok == true)
664 {
665 geom = gaiaAllocGeomColl();
666 geom->Srid = 4326;
667 gaiaAddPointToGeomColl(geom, longitude, latitude);
668 gaiaToSpatiaLiteBlobWkb(geom, &geoblob, &geosize);
669 gaiaFreeGeomColl(geom);
670 sqlite3_bind_blob(stmt, 7, geoblob, geosize, SQLITE_TRANSIENT);
671 free(geoblob);
672 } else
673 sqlite3_bind_null(stmt, 7);
674 dblval = GetGpsDirection(tag_list, &ok);
675 if (ok == true)
676 sqlite3_bind_double(stmt, 8, dblval);
677 else
678 sqlite3_bind_null(stmt, 8);
679 GetGpsSatellites(tag_list, satellites, &ok);
680 if (ok == true)
681 sqlite3_bind_text(stmt, 9, satellites.ToUTF8(), satellites.Len(),
682 SQLITE_TRANSIENT);
683 else
684 sqlite3_bind_null(stmt, 9);
685 GetGpsTimestamp(tag_list, timestamp, &ok);
686 if (ok == true)
687 sqlite3_bind_text(stmt, 10, timestamp.ToUTF8(), timestamp.Len(),
688 SQLITE_TRANSIENT);
689 else
690 sqlite3_bind_text(stmt, 10, "0000-00-00 00:00:00", 19, SQLITE_TRANSIENT);
691 sqlite3_bind_text(stmt, 11, path.ToUTF8(), path.Len(), SQLITE_TRANSIENT);
692 ret = sqlite3_step(stmt);
693 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
694 ;
695 else
696 {
697 wxMessageBox(wxT("sqlite3_step() error: ") +
698 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
699 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
700 sqlite3_finalize(stmt);
701 goto abort;
702 }
703 sqlite3_finalize(stmt);
704 pk = sqlite3_last_insert_rowid(SqliteHandle);
705 if (metadata)
706 {
707 // feeding the ExifTags table; preparing the SQL statement
708 strcpy(sql,
709 "INSERT OR IGNORE INTO ExifTags (PhotoId, TagId, TagName, GpsTag, ValueType, ");
710 strcat(sql, "TypeName, CountValues) VALUES (?, ?, ?, ?, ?, ?, ?)");
711 ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
712 if (ret != SQLITE_OK)
713 {
714 wxMessageBox(wxT("INSERT INTO ExifTags error: ") +
715 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
716 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
717 goto abort;
718 }
719 for (i = 0; i < gaiaGetExifTagsCount(tag_list); i++)
720 {
721 pT = gaiaGetExifTagByPos(tag_list, i);
722 if (pT)
723 {
724 gaiaExifTagGetName(pT, tag_name, 128);
725 switch (gaiaExifTagGetValueType(pT))
726 {
727 case 1:
728 type_desc = "BYTE";
729 break;
730 case 2:
731 type_desc = "STRING";
732 break;
733 case 3:
734 type_desc = "SHORT";
735 break;
736 case 4:
737 type_desc = "LONG";
738 break;
739 case 5:
740 type_desc = "RATIONAL";
741 break;
742 case 6:
743 type_desc = "SBYTE";
744 break;
745 case 7:
746 type_desc = "UNDEFINED";
747 break;
748 case 8:
749 type_desc = "SSHORT";
750 break;
751 case 9:
752 type_desc = "SLONG";
753 break;
754 case 10:
755 type_desc = "SRATIONAL";
756 break;
757 case 11:
758 type_desc = "FLOAT";
759 break;
760 case 12:
761 type_desc = "DOUBLE";
762 break;
763 default:
764 type_desc = "UNKNOWN";
765 break;
766 };
767 // INSERTing an Exif Tag
768 sqlite3_reset(stmt);
769 sqlite3_clear_bindings(stmt);
770 sqlite3_bind_int64(stmt, 1, pk);
771 sqlite3_bind_int(stmt, 2, gaiaExifTagGetId(pT));
772 sqlite3_bind_text(stmt, 3, tag_name, strlen(tag_name),
773 SQLITE_STATIC);
774 sqlite3_bind_int(stmt, 4, gaiaIsExifGpsTag(pT));
775 sqlite3_bind_int(stmt, 5, gaiaExifTagGetValueType(pT));
776 sqlite3_bind_text(stmt, 6, type_desc, strlen(type_desc),
777 SQLITE_STATIC);
778 sqlite3_bind_int(stmt, 7, gaiaExifTagGetNumValues(pT));
779 ret = sqlite3_step(stmt);
780 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
781 ;
782 else
783 {
784 wxMessageBox(wxT("sqlite3_step() error: ") +
785 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
786 wxT("spatialite_gui"), wxOK | wxICON_ERROR,
787 this);
788 sqlite3_finalize(stmt);
789 goto abort;
790 }
791 }
792 }
793 sqlite3_finalize(stmt);
794 // feeding the ExifValues table; preparing the SQL statement
795 strcpy(sql,
796 "INSERT OR IGNORE INTO ExifValues (PhotoId, TagId, ValueIndex, ByteValue, ");
797 strcat(sql,
798 "StringValue, NumValue, NumValueBis, DoubleValue, HumanReadable) VALUES ");
799 strcat(sql, "(?, ?, ?, ?, ?, ?, ?, ?, ?)");
800 ret = sqlite3_prepare_v2(SqliteHandle, sql, strlen(sql), &stmt, NULL);
801 if (ret != SQLITE_OK)
802 {
803 wxMessageBox(wxT("NSERT INTO ExifValues error: ") +
804 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
805 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
806 goto abort;
807 }
808 for (i = 0; i < gaiaGetExifTagsCount(tag_list); i++)
809 {
810 pT = gaiaGetExifTagByPos(tag_list, i);
811 if (pT)
812 {
813 gaiaExifTagGetHumanReadable(pT, human, 1024, &ok_human);
814 for (iv = 0; iv < gaiaExifTagGetNumValues(pT); iv++)
815 {
816 // INSERTing an Exif Tag
817 sqlite3_reset(stmt);
818 sqlite3_clear_bindings(stmt);
819 sqlite3_bind_int64(stmt, 1, pk);
820 sqlite3_bind_int(stmt, 2, gaiaExifTagGetId(pT));
821 sqlite3_bind_int(stmt, 3, iv);
822 if (gaiaExifTagGetValueType(pT) == 1
823 || gaiaExifTagGetValueType(pT) == 6
824 || gaiaExifTagGetValueType(pT) == 7)
825 {
826 sqlite3_bind_blob(stmt, 4, pT->ByteValue, pT->Count,
827 SQLITE_STATIC);
828 sqlite3_bind_null(stmt, 5);
829 sqlite3_bind_null(stmt, 6);
830 sqlite3_bind_null(stmt, 7);
831 sqlite3_bind_null(stmt, 8);
832 }
833 if (gaiaExifTagGetValueType(pT) == 2)
834 {
835 sqlite3_bind_null(stmt, 4);
836 sqlite3_bind_text(stmt, 5, pT->StringValue,
837 strlen(pT->StringValue), SQLITE_STATIC);
838 sqlite3_bind_null(stmt, 6);
839 sqlite3_bind_null(stmt, 7);
840 sqlite3_bind_null(stmt, 8);
841 }
842 if (gaiaExifTagGetValueType(pT) == 3)
843 {
844 sqlite3_bind_null(stmt, 4);
845 sqlite3_bind_null(stmt, 5);
846 val64 = gaiaExifTagGetShortValue(pT, iv, &xok);
847 if (!ok)
848 sqlite3_bind_null(stmt, 6);
849 else
850 sqlite3_bind_int64(stmt, 6, val64);
851 sqlite3_bind_null(stmt, 7);
852 sqlite3_bind_null(stmt, 8);
853 }
854 if (gaiaExifTagGetValueType(pT) == 4)
855 {
856 sqlite3_bind_null(stmt, 4);
857 sqlite3_bind_null(stmt, 5);
858 val64 = gaiaExifTagGetLongValue(pT, iv, &xok);
859 if (!ok)
860 sqlite3_bind_null(stmt, 6);
861 else
862 sqlite3_bind_int64(stmt, 6, val64);
863 sqlite3_bind_null(stmt, 7);
864 sqlite3_bind_null(stmt, 8);
865 }
866 if (gaiaExifTagGetValueType(pT) == 5)
867 {
868 sqlite3_bind_null(stmt, 4);
869 sqlite3_bind_null(stmt, 5);
870 val64 = gaiaExifTagGetRational1Value(pT, iv, &xok);
871 if (!ok)
872 sqlite3_bind_null(stmt, 6);
873 else
874 sqlite3_bind_int64(stmt, 6, val64);
875 val64 = gaiaExifTagGetRational2Value(pT, iv, &xok);
876 if (!ok)
877 sqlite3_bind_null(stmt, 7);
878 else
879 sqlite3_bind_int64(stmt, 7, val64);
880 dblval = gaiaExifTagGetRationalValue(pT, iv, &xok);
881 if (!ok)
882 sqlite3_bind_null(stmt, 8);
883 else
884 sqlite3_bind_double(stmt, 8, dblval);
885 }
886 if (gaiaExifTagGetValueType(pT) == 9)
887 {
888 sqlite3_bind_null(stmt, 4);
889 sqlite3_bind_null(stmt, 5);
890 val64 = gaiaExifTagGetSignedLongValue(pT, iv, &xok);
891 if (!ok)
892 sqlite3_bind_null(stmt, 6);
893 else
894 sqlite3_bind_int64(stmt, 6, val64);
895 sqlite3_bind_null(stmt, 7);
896 sqlite3_bind_null(stmt, 8);
897 }
898 if (gaiaExifTagGetValueType(pT) == 10)
899 {
900 sqlite3_bind_null(stmt, 4);
901 sqlite3_bind_null(stmt, 5);
902 val64 = gaiaExifTagGetSignedRational1Value(pT, iv, &xok);
903 if (!ok)
904 sqlite3_bind_null(stmt, 6);
905 else
906 sqlite3_bind_int64(stmt, 6, val64);
907 val64 = gaiaExifTagGetSignedRational2Value(pT, iv, &xok);
908 if (!ok)
909 sqlite3_bind_null(stmt, 7);
910 else
911 sqlite3_bind_int64(stmt, 7, val64);
912 dblval = gaiaExifTagGetSignedRationalValue(pT, iv, &xok);
913 if (!ok)
914 sqlite3_bind_null(stmt, 8);
915 else
916 sqlite3_bind_double(stmt, 8, dblval);
917 }
918 if (gaiaExifTagGetValueType(pT) == 11)
919 {
920 sqlite3_bind_null(stmt, 4);
921 sqlite3_bind_null(stmt, 5);
922 sqlite3_bind_null(stmt, 6);
923 sqlite3_bind_null(stmt, 7);
924 dblval = gaiaExifTagGetFloatValue(pT, iv, &xok);
925 if (!ok)
926 sqlite3_bind_null(stmt, 8);
927 else
928 sqlite3_bind_double(stmt, 8, dblval);
929 }
930 if (gaiaExifTagGetValueType(pT) == 12)
931 {
932 sqlite3_bind_null(stmt, 4);
933 sqlite3_bind_null(stmt, 5);
934 sqlite3_bind_null(stmt, 6);
935 sqlite3_bind_null(stmt, 7);
936 dblval = gaiaExifTagGetDoubleValue(pT, iv, &xok);
937 if (!ok)
938 sqlite3_bind_null(stmt, 8);
939 else
940 sqlite3_bind_double(stmt, 8, dblval);
941 }
942 if (!ok_human)
943 sqlite3_bind_null(stmt, 9);
944 else
945 sqlite3_bind_text(stmt, 9, human, strlen(human),
946 SQLITE_STATIC);
947 ret = sqlite3_step(stmt);
948 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
949 ;
950 else
951 {
952 wxMessageBox(wxT("sqlite3_step() error: ") +
953 wxString::FromUTF8(sqlite3_errmsg
954 (SqliteHandle)),
955 wxT("spatialite_gui"), wxOK | wxICON_ERROR,
956 this);
957 sqlite3_finalize(stmt);
958 goto abort;
959 }
960 if (gaiaExifTagGetValueType(pT) == 1
961 || gaiaExifTagGetValueType(pT) == 2
962 || gaiaExifTagGetValueType(pT) == 6
963 || gaiaExifTagGetValueType(pT) == 7)
964 break;
965 ok_human = 0;
966 }
967 }
968 }
969 sqlite3_finalize(stmt);
970 }
971 // commits the transaction
972 strcpy(sql, "COMMIT");
973 ret = sqlite3_exec(SqliteHandle, sql, NULL, NULL, &errMsg);
974 if (ret != SQLITE_OK)
975 {
976 wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
977 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
978 sqlite3_free(errMsg);
979 }
980 return true;
981 abort:
982 // rolling back the transaction
983 strcpy(sql, "ROLLBACK");
984 ret = sqlite3_exec(SqliteHandle, sql, NULL, NULL, &errMsg);
985 if (ret != SQLITE_OK)
986 {
987 wxMessageBox(wxT("ROLLBACK error: ") + wxString::FromUTF8(errMsg),
988 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
989 sqlite3_free(errMsg);
990 }
991 return false;
992 }
993
GetPixelX(gaiaExifTagListPtr tag_list,bool * ok)994 sqlite3_int64 MyFrame::GetPixelX(gaiaExifTagListPtr tag_list, bool * ok)
995 {
996 //
997 // trying to retrieve the ExifImageWidth
998 //
999 *ok = false;
1000 if (!tag_list)
1001 return 0;
1002 gaiaExifTagPtr tag = tag_list->First;
1003 while (tag)
1004 {
1005 if (tag->TagId == 0xA002)
1006 {
1007 // ok, this one is the ExifImageWidth tag
1008 if (tag->Type == 3 && tag->Count == 1)
1009 {
1010 *ok = true;
1011 return *(tag->ShortValues + 0);
1012 } else if (tag->Type == 4 && tag->Count == 1)
1013 {
1014 *ok = true;
1015 return *(tag->LongValues + 0);
1016 }
1017 }
1018 tag = tag->Next;
1019 }
1020 return false;
1021 }
1022
GetPixelY(gaiaExifTagListPtr tag_list,bool * ok)1023 sqlite3_int64 MyFrame::GetPixelY(gaiaExifTagListPtr tag_list, bool * ok)
1024 {
1025 //
1026 // trying to retrieve the ExifImageLength
1027 //
1028 *ok = false;
1029 if (!tag_list)
1030 return 0;
1031 gaiaExifTagPtr tag = tag_list->First;
1032 while (tag)
1033 {
1034 if (tag->TagId == 0xA003)
1035 {
1036 // ok, this one is the ExifImageLength tag
1037 if (tag->Type == 3 && tag->Count == 1)
1038 {
1039 *ok = true;
1040 return *(tag->ShortValues + 0);
1041 } else if (tag->Type == 4 && tag->Count == 1)
1042 {
1043 *ok = true;
1044 return *(tag->LongValues + 0);
1045 }
1046 }
1047 tag = tag->Next;
1048 }
1049 return false;
1050 }
1051
GetMake(gaiaExifTagListPtr tag_list,wxString & str,bool * ok)1052 void MyFrame::GetMake(gaiaExifTagListPtr tag_list, wxString & str, bool * ok)
1053 {
1054 //
1055 // trying to retrieve the Make
1056 //
1057 *ok = false;
1058 if (!tag_list)
1059 return;
1060 gaiaExifTagPtr tag = tag_list->First;
1061 while (tag)
1062 {
1063 if (tag->TagId == 0x010F)
1064 {
1065 // ok, this one is the Make tag
1066 if (tag->Type == 2)
1067 {
1068 *ok = true;
1069 str = wxString::FromUTF8(tag->StringValue);
1070 return;
1071 }
1072 }
1073 tag = tag->Next;
1074 }
1075 return;
1076 }
1077
GetModel(gaiaExifTagListPtr tag_list,wxString & str,bool * ok)1078 void MyFrame::GetModel(gaiaExifTagListPtr tag_list, wxString & str, bool * ok)
1079 {
1080 //
1081 // trying to retrieve the Model
1082 //
1083 *ok = false;
1084 if (!tag_list)
1085 return;
1086 gaiaExifTagPtr tag = tag_list->First;
1087 while (tag)
1088 {
1089 if (tag->TagId == 0x0110)
1090 {
1091 // ok, this one is the Model tag
1092 if (tag->Type == 2)
1093 {
1094 *ok = true;
1095 str = wxString::FromUTF8(tag->StringValue);
1096 return;
1097 }
1098 }
1099 tag = tag->Next;
1100 }
1101 return;
1102 }
1103
GetDate(gaiaExifTagListPtr tag_list,wxString & str,bool * ok)1104 void MyFrame::GetDate(gaiaExifTagListPtr tag_list, wxString & str, bool * ok)
1105 {
1106 //
1107 // trying to retrieve the Date
1108 //
1109 *ok = false;
1110 if (!tag_list)
1111 return;
1112 gaiaExifTagPtr tag = tag_list->First;
1113 while (tag)
1114 {
1115 if (tag->TagId == 0x9003)
1116 {
1117 // ok, this one is the DateTimeOriginal tag
1118 if (tag->Type == 2)
1119 {
1120 *ok = true;
1121 str = wxString::FromUTF8(tag->StringValue);
1122 if (str.Len() >= 19)
1123 {
1124 str.SetChar(4, '-');
1125 str.SetChar(7, '-');
1126 }
1127 return;
1128 }
1129 }
1130 tag = tag->Next;
1131 }
1132 return;
1133 }
1134
GetGpsCoords(gaiaExifTagListPtr tag_list,double * longitude,double * latitude,bool * ok)1135 void MyFrame::GetGpsCoords(gaiaExifTagListPtr tag_list, double *longitude,
1136 double *latitude, bool * ok)
1137 {
1138 //
1139 // trying to retrieve the GPS coordinates
1140 //
1141 char lat_ref = '\0';
1142 char long_ref = '\0';
1143 double lat_degs = DBL_MIN;
1144 double lat_mins = DBL_MIN;
1145 double lat_secs = DBL_MIN;
1146 double long_degs = DBL_MIN;
1147 double long_mins = DBL_MIN;
1148 double long_secs = DBL_MIN;
1149 double dblval;
1150 double sign;
1151 double dblLatitude = DBL_MIN;
1152 double dblLongitude = DBL_MIN;
1153 int xok;
1154 wxString str;
1155 *ok = false;
1156 if (!tag_list)
1157 return;
1158 gaiaExifTagPtr tag = tag_list->First;
1159 while (tag)
1160 {
1161 if (tag->Gps && tag->TagId == 0x01)
1162 {
1163 // ok, this one is the GPSLatitudeRef tag
1164 if (tag->Type == 2)
1165 lat_ref = *(tag->StringValue);
1166 }
1167 if (tag->Gps && tag->TagId == 0x03)
1168 {
1169 // ok, this one is the GPSLongitudeRef tag
1170 if (tag->Type == 2)
1171 long_ref = *(tag->StringValue);
1172 }
1173 if (tag->Gps && tag->TagId == 0x02)
1174 {
1175 // ok, this one is the GPSLatitude tag
1176 if (tag->Type == 5 && tag->Count == 3)
1177 {
1178 dblval = gaiaExifTagGetRationalValue(tag, 0, &xok);
1179 if (xok)
1180 lat_degs = dblval;
1181 dblval = gaiaExifTagGetRationalValue(tag, 1, &xok);
1182 if (xok)
1183 lat_mins = dblval;
1184 dblval = gaiaExifTagGetRationalValue(tag, 2, &xok);
1185 if (xok)
1186 lat_secs = dblval;
1187 }
1188 if (tag->Type == 2)
1189 {
1190 str = wxString::FromUTF8(tag->StringValue);
1191 if (str.ToDouble(&dblval) == true)
1192 dblLatitude = dblval;
1193 }
1194 }
1195 if (tag->Gps && tag->TagId == 0x04)
1196 {
1197 // ok, this one is the GPSLongitude tag
1198 if (tag->Type == 5 && tag->Count == 3)
1199 {
1200 dblval = gaiaExifTagGetRationalValue(tag, 0, &xok);
1201 if (xok)
1202 long_degs = dblval;
1203 dblval = gaiaExifTagGetRationalValue(tag, 1, &xok);
1204 if (xok)
1205 long_mins = dblval;
1206 dblval = gaiaExifTagGetRationalValue(tag, 2, &xok);
1207 if (xok)
1208 long_secs = dblval;
1209 }
1210 if (tag->Type == 2)
1211 {
1212 str = wxString::FromUTF8(tag->StringValue);
1213 if (str.ToDouble(&dblval) == true)
1214 dblLongitude = dblval;
1215 }
1216 }
1217 tag = tag->Next;
1218 }
1219 if ((lat_ref == 'N' || lat_ref == 'S' || long_ref == 'E' || long_ref == 'W')
1220 && lat_degs != DBL_MIN && lat_mins != DBL_MIN && lat_secs != DBL_MIN
1221 && long_degs != DBL_MIN && long_mins != DBL_MIN && long_secs != DBL_MIN)
1222 {
1223 *ok = true;
1224 if (lat_ref == 'S')
1225 sign = -1.0;
1226 else
1227 sign = 1.0;
1228 lat_degs = math_round(lat_degs * 1000000.0);
1229 lat_mins = math_round(lat_mins * 1000000.0);
1230 lat_secs = math_round(lat_secs * 1000000.0);
1231 dblval =
1232 math_round(lat_degs + (lat_mins / 60.0) +
1233 (lat_secs / 3600.0)) * (sign / 1000000.0);
1234 *latitude = dblval;
1235 if (long_ref == 'W')
1236 sign = -1.0;
1237 else
1238 sign = 1.0;
1239 long_degs = math_round(long_degs * 1000000.0);
1240 long_mins = math_round(long_mins * 1000000.0);
1241 long_secs = math_round(long_secs * 1000000.0);
1242 dblval =
1243 math_round(long_degs + (long_mins / 60.0) +
1244 (long_secs / 3600.0)) * (sign / 1000000.0);
1245 *longitude = dblval;
1246 } else if (dblLatitude != DBL_MIN && dblLongitude != DBL_MIN)
1247 {
1248 *ok = true;
1249 *latitude = dblLatitude;
1250 *longitude = dblLongitude;
1251 }
1252 return;
1253 }
1254
GetGpsSatellites(gaiaExifTagListPtr tag_list,wxString & str,bool * ok)1255 void MyFrame::GetGpsSatellites(gaiaExifTagListPtr tag_list, wxString & str,
1256 bool * ok)
1257 {
1258 //
1259 // trying to retrieve the GPSSatellites
1260 //
1261 *ok = false;
1262 if (!tag_list)
1263 return;
1264 gaiaExifTagPtr tag = tag_list->First;
1265 while (tag)
1266 {
1267 if (tag->Gps && tag->TagId == 0x08)
1268 {
1269 // ok, this one is the GPSSatellites tag
1270 if (tag->Type == 2)
1271 {
1272 *ok = true;
1273 str = wxString::FromUTF8(tag->StringValue);
1274 return;
1275 }
1276 }
1277 tag = tag->Next;
1278 }
1279 return;
1280 }
1281
GetGpsDirection(gaiaExifTagListPtr tag_list,bool * ok)1282 double MyFrame::GetGpsDirection(gaiaExifTagListPtr tag_list, bool * ok)
1283 {
1284 //
1285 // trying to retrieve the GPS direction
1286 //
1287 char dir_ref = '\0';
1288 double direction = DBL_MIN;
1289 double dblval;
1290 int xok;
1291 *ok = false;
1292 if (!tag_list)
1293 return direction;
1294 gaiaExifTagPtr tag = tag_list->First;
1295 while (tag)
1296 {
1297 if (tag->Gps && tag->TagId == 0x10)
1298 {
1299 // ok, this one is the GPSDirectionRef tag
1300 if (tag->Type == 2)
1301 dir_ref = *(tag->StringValue);
1302 }
1303 if (tag->Gps && tag->TagId == 0x11)
1304 {
1305 // ok, this one is the GPSDirection tag
1306 if (tag->Type == 5 && tag->Count == 1)
1307 {
1308 dblval = gaiaExifTagGetRationalValue(tag, 0, &xok);
1309 if (xok)
1310 direction = dblval;
1311 }
1312 }
1313 tag = tag->Next;
1314 }
1315 if ((dir_ref == 'T' || dir_ref == 'M') && direction != DBL_MIN)
1316 *ok = true;
1317 return direction;
1318 }
1319
GetGpsTimestamp(gaiaExifTagListPtr tag_list,wxString & str,bool * ok)1320 void MyFrame::GetGpsTimestamp(gaiaExifTagListPtr tag_list, wxString & str,
1321 bool * ok)
1322 {
1323 //
1324 // trying to retrieve the GPS Timestamp
1325 //
1326 char date[16];
1327 char timestamp[32];
1328 double hours = DBL_MIN;
1329 double mins = DBL_MIN;
1330 double secs = DBL_MIN;
1331 double dblval;
1332 int xok;
1333 int hh;
1334 int mm;
1335 int ss;
1336 int millis;
1337 *ok = false;
1338 if (!tag_list)
1339 return;
1340 strcpy(date, "0000-00-00");
1341 gaiaExifTagPtr tag = tag_list->First;
1342 while (tag)
1343 {
1344 if (tag->Gps && tag->TagId == 0x1D)
1345 {
1346 // ok, this one is the GPSDateStamp tag
1347 if (tag->Type == 2)
1348 {
1349 strcpy(date, tag->StringValue);
1350 date[4] = '-';
1351 date[7] = '-';
1352 }
1353 }
1354 if (tag->Gps && tag->TagId == 0x07)
1355 {
1356 // ok, this one is the GPSTimeStamp tag
1357 if (tag->Type == 5 && tag->Count == 3)
1358 {
1359 dblval = gaiaExifTagGetRationalValue(tag, 0, &xok);
1360 if (xok)
1361 hours = dblval;
1362 dblval = gaiaExifTagGetRationalValue(tag, 1, &xok);
1363 if (xok)
1364 mins = dblval;
1365 dblval = gaiaExifTagGetRationalValue(tag, 2, &xok);
1366 if (xok)
1367 secs = dblval;
1368 }
1369 }
1370 tag = tag->Next;
1371 }
1372 if (hours != DBL_MIN && mins != DBL_MIN && secs != DBL_MIN)
1373 {
1374 *ok = true;
1375 hh = (int) floor(hours);
1376 mm = (int) floor(mins);
1377 ss = (int) floor(secs);
1378 millis = (int) ((secs - ss) * 1000);
1379 sprintf(timestamp, "%s %02d:%02d:%02d.%03d", date, hh, mm, ss, millis);
1380 str = wxString::FromUTF8(timestamp);
1381 }
1382 return;
1383 }
1384
ImportXmlDocuments(wxString & path,bool folder,wxString & suffix,wxString & table,wxString & pkName,wxString & xmlColumn,wxString & inPathColumn,wxString & schemaUriColumn,wxString & parseErrColumn,wxString & validateErrColumn,int compressed,const char * schemaURI,bool isInternalSchemaUri)1385 void MyFrame::ImportXmlDocuments(wxString & path, bool folder,
1386 wxString & suffix, wxString & table,
1387 wxString & pkName, wxString & xmlColumn,
1388 wxString & inPathColumn,
1389 wxString & schemaUriColumn,
1390 wxString & parseErrColumn,
1391 wxString & validateErrColumn, int compressed,
1392 const char *schemaURI,
1393 bool isInternalSchemaUri)
1394 {
1395 //
1396 // trying to import XML Documents
1397 //
1398 int cnt;
1399 char msg[256];
1400 wxString sql;
1401 sqlite3_stmt *stmt;
1402 char *errMsg;
1403 char xsql[8192];
1404 char *qname;
1405 int ret;
1406 int failed;
1407 if (CheckOrCreateXmlTable
1408 (table, pkName, xmlColumn, inPathColumn, schemaUriColumn, parseErrColumn,
1409 validateErrColumn) == false)
1410 return;
1411 // preparing the SQL INSERT statement
1412 sql = wxT("INSERT OR IGNORE INTO \"");
1413 strcpy(xsql, table.ToUTF8());
1414 qname = gaiaDoubleQuotedSql(xsql);
1415 sql += wxString::FromUTF8(qname);
1416 free(qname);
1417 sql += wxT("\" (\"");
1418 strcpy(xsql, pkName.ToUTF8());
1419 qname = gaiaDoubleQuotedSql(xsql);
1420 sql += wxString::FromUTF8(qname);
1421 free(qname);
1422 sql += wxT("\", \"");
1423 strcpy(xsql, xmlColumn.ToUTF8());
1424 qname = gaiaDoubleQuotedSql(xsql);
1425 sql += wxString::FromUTF8(qname);
1426 free(qname);
1427 if (inPathColumn.Len() > 0)
1428 {
1429 // appending the InPath column
1430 sql += wxT("\", \"");
1431 strcpy(xsql, inPathColumn.ToUTF8());
1432 qname = gaiaDoubleQuotedSql(xsql);
1433 sql += wxString::FromUTF8(qname);
1434 free(qname);
1435 }
1436 if (schemaUriColumn.Len() > 0)
1437 {
1438 // appending the SchemaURI column
1439 sql += wxT("\", \"");
1440 strcpy(xsql, schemaUriColumn.ToUTF8());
1441 qname = gaiaDoubleQuotedSql(xsql);
1442 sql += wxString::FromUTF8(qname);
1443 free(qname);
1444 }
1445 if (parseErrColumn.Len() > 0)
1446 {
1447 // appending the ParseError column
1448 sql += wxT("\", \"");
1449 strcpy(xsql, parseErrColumn.ToUTF8());
1450 qname = gaiaDoubleQuotedSql(xsql);
1451 sql += wxString::FromUTF8(qname);
1452 free(qname);
1453 }
1454 if (validateErrColumn.Len() > 0)
1455 {
1456 // appending the ValidateError column
1457 sql += wxT("\", \"");
1458 strcpy(xsql, validateErrColumn.ToUTF8());
1459 qname = gaiaDoubleQuotedSql(xsql);
1460 sql += wxString::FromUTF8(qname);
1461 free(qname);
1462 }
1463 sql += wxT("\") VALUES (NULL, ?");
1464 if (inPathColumn.Len() > 0)
1465 sql += wxT(", ?");
1466 if (schemaUriColumn.Len() > 0)
1467 sql += wxT(", ?");
1468 if (parseErrColumn.Len() > 0)
1469 sql += wxT(", ?");
1470 if (validateErrColumn.Len() > 0)
1471 sql += wxT(", ?");
1472 sql += wxT(")");
1473 ret = sqlite3_prepare_v2(SqliteHandle, sql.ToUTF8(), sql.Len(), &stmt, NULL);
1474 if (ret != SQLITE_OK)
1475 {
1476 wxMessageBox(wxT("INSERT INTO XML target table error: ") +
1477 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
1478 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1479 return;
1480 }
1481 // stating a transaction
1482 ret = sqlite3_exec(SqliteHandle, "BEGIN", NULL, NULL, &errMsg);
1483 if (ret != SQLITE_OK)
1484 {
1485 wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
1486 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1487 sqlite3_free(errMsg);
1488 }
1489
1490 if (folder == true)
1491 cnt =
1492 XmlDocumentLoadDir(path, suffix, compressed, schemaURI,
1493 isInternalSchemaUri, inPathColumn, parseErrColumn,
1494 validateErrColumn, schemaUriColumn, stmt, &failed);
1495 else
1496 cnt =
1497 XmlDocumentLoadFile(path, compressed, schemaURI, isInternalSchemaUri,
1498 inPathColumn, schemaUriColumn, parseErrColumn,
1499 validateErrColumn, stmt, &failed);
1500
1501 // commits the transaction
1502 ret = sqlite3_exec(SqliteHandle, "COMMIT", NULL, NULL, &errMsg);
1503 if (ret != SQLITE_OK)
1504 {
1505 wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
1506 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1507 sqlite3_free(errMsg);
1508 }
1509 sqlite3_finalize(stmt);
1510 sprintf(msg, "%d XML Document%s processed\n\n", cnt,
1511 (cnt > 1) ? "s were" : " was");
1512 wxString message = wxString::FromUTF8(msg);
1513 sprintf(msg, "Valid XMLDocuments: %d\n", cnt - failed);
1514 message += wxString::FromUTF8(msg);
1515 sprintf(msg, "Failures: %d\n", failed);
1516 message += wxString::FromUTF8(msg);
1517 wxMessageBox(message, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
1518 }
1519
InsertIntoXmlTable(sqlite3_stmt * stmt,char * blob,int sz,wxString & inPathColumn,wxString & path,wxString & schemaUriColumn,const char * schemaUri,wxString & parseErrColumn,const char * parseError,wxString & validateErrColumn,const char * validateError)1520 bool MyFrame::InsertIntoXmlTable(sqlite3_stmt * stmt, char *blob,
1521 int sz, wxString & inPathColumn,
1522 wxString & path, wxString & schemaUriColumn,
1523 const char *schemaUri,
1524 wxString & parseErrColumn,
1525 const char *parseError,
1526 wxString & validateErrColumn,
1527 const char *validateError)
1528 {
1529 //
1530 // attemping to insert into the XML target table
1531 //
1532 int ret;
1533 int i_col = 2;
1534 sqlite3_reset(stmt);
1535 sqlite3_clear_bindings(stmt);
1536 sqlite3_bind_blob(stmt, 1, blob, sz, free);
1537 if (inPathColumn.Len() > 0)
1538 {
1539 // binding the InPath value
1540 char x_path[1024];
1541 wxFileName fn = wxFileName(path);
1542 wxString name = fn.GetName();
1543 if (fn.GetExt().Len() > 0)
1544 name += wxT(".") + fn.GetExt();
1545 strcpy(x_path, name.ToUTF8());
1546 sqlite3_bind_text(stmt, i_col++, x_path, strlen(x_path),
1547 SQLITE_TRANSIENT);
1548 }
1549 if (schemaUriColumn.Len() > 0)
1550 {
1551 // binding the SchemaURI value
1552 if (schemaUri == NULL)
1553 sqlite3_bind_null(stmt, i_col++);
1554 else
1555 sqlite3_bind_text(stmt, i_col++, schemaUri, strlen(schemaUri),
1556 SQLITE_STATIC);
1557 }
1558 if (parseErrColumn.Len() > 0)
1559 {
1560 // binding the ParseError value
1561 if (parseError == NULL)
1562 sqlite3_bind_null(stmt, i_col++);
1563 else
1564 sqlite3_bind_text(stmt, i_col++, parseError, strlen(parseError),
1565 SQLITE_STATIC);
1566 }
1567 if (validateErrColumn.Len() > 0)
1568 {
1569 // binding the ValidateError value
1570 if (validateError == NULL)
1571 sqlite3_bind_null(stmt, i_col++);
1572 else
1573 sqlite3_bind_text(stmt, i_col++, validateError, strlen(validateError),
1574 SQLITE_STATIC);
1575 }
1576 ret = sqlite3_step(stmt);
1577 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
1578 return true;
1579 wxMessageBox(wxT("XML-INSERT: sqlite3_step() error: ") +
1580 wxString::FromUTF8(sqlite3_errmsg(SqliteHandle)),
1581 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1582 return false;
1583 }
1584
CheckOrCreateXmlTable(wxString & table,wxString & pkName,wxString & xmlColumn,wxString & inPathColumn,wxString & schemaUriColumn,wxString & parseErrColumn,wxString & validateErrColumn)1585 bool MyFrame::CheckOrCreateXmlTable(wxString & table, wxString & pkName,
1586 wxString & xmlColumn,
1587 wxString & inPathColumn,
1588 wxString & schemaUriColumn,
1589 wxString & parseErrColumn,
1590 wxString & validateErrColumn)
1591 {
1592 //
1593 // creates the XML DB table / or checks an existing one for validity
1594 //
1595 int ret;
1596 wxString sql;
1597 char *errMsg;
1598 char xsql[8192];
1599 char *qname;
1600 bool ok_xmlblob = false;
1601 bool ok_inPath = false;
1602 bool ok_schemaURI = false;
1603 bool ok_parseErr = false;
1604 bool ok_validateErr = false;
1605 const char *name;
1606 int i;
1607 char **results;
1608 int rows;
1609 int columns;
1610 sql = wxT("CREATE TABLE IF NOT EXISTS \"");
1611 strcpy(xsql, table.ToUTF8());
1612 qname = gaiaDoubleQuotedSql(xsql);
1613 sql += wxString::FromUTF8(qname);
1614 free(qname);
1615 sql += wxT("\" (\n\"");
1616 strcpy(xsql, pkName.ToUTF8());
1617 qname = gaiaDoubleQuotedSql(xsql);
1618 sql += wxString::FromUTF8(qname);
1619 free(qname);
1620 sql += wxT("\" INTEGER PRIMARY KEY AUTOINCREMENT,\n\"");
1621 strcpy(xsql, xmlColumn.ToUTF8());
1622 qname = gaiaDoubleQuotedSql(xsql);
1623 sql += wxString::FromUTF8(qname);
1624 free(qname);
1625 sql += wxT("\" BLOB NOT NULL");
1626 if (inPathColumn.Len() > 0)
1627 {
1628 // adding the InPath Column
1629 sql += wxT("\n,\"");
1630 strcpy(xsql, inPathColumn.ToUTF8());
1631 qname = gaiaDoubleQuotedSql(xsql);
1632 sql += wxString::FromUTF8(qname);
1633 free(qname);
1634 sql += wxT("\" TEXT NOT NULL");
1635 }
1636 if (schemaUriColumn.Len() > 0)
1637 {
1638 // adding the SchemaURI Column
1639 sql += wxT("\n,\"");
1640 strcpy(xsql, schemaUriColumn.ToUTF8());
1641 qname = gaiaDoubleQuotedSql(xsql);
1642 sql += wxString::FromUTF8(qname);
1643 free(qname);
1644 sql += wxT("\" TEXT");
1645 }
1646 if (parseErrColumn.Len() > 0)
1647 {
1648 // adding the ParseError Column
1649 sql += wxT("\n,\"");
1650 strcpy(xsql, parseErrColumn.ToUTF8());
1651 qname = gaiaDoubleQuotedSql(xsql);
1652 sql += wxString::FromUTF8(qname);
1653 free(qname);
1654 sql += wxT("\" TEXT");
1655 }
1656 if (validateErrColumn.Len() > 0)
1657 {
1658 // adding the validateError Column
1659 sql += wxT("\n,\"");
1660 strcpy(xsql, validateErrColumn.ToUTF8());
1661 qname = gaiaDoubleQuotedSql(xsql);
1662 sql += wxString::FromUTF8(qname);
1663 free(qname);
1664 sql += wxT("\" TEXT");
1665 }
1666 sql += wxT(")");
1667 ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, NULL, &errMsg);
1668 if (ret != SQLITE_OK)
1669 {
1670 wxMessageBox(wxT("CREATE XML Target Table error: ") +
1671 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
1672 wxOK | wxICON_ERROR, this);
1673 sqlite3_free(errMsg);
1674 return false;
1675 }
1676
1677 sql = wxT("PRAGMA table_info(\"");
1678 strcpy(xsql, table.ToUTF8());
1679 qname = gaiaDoubleQuotedSql(xsql);
1680 sql += wxString::FromUTF8(qname);
1681 free(qname);
1682 sql += wxT("\")");
1683 ret =
1684 sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows, &columns,
1685 &errMsg);
1686 if (ret != SQLITE_OK)
1687 {
1688 wxMessageBox(wxT("PRAGMA table_info(xmlTargetTable) error: ") +
1689 wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
1690 wxOK | wxICON_ERROR, this);
1691 sqlite3_free(errMsg);
1692 goto abort;
1693 }
1694 if (rows < 1)
1695 ;
1696 else
1697 {
1698 strcpy(xsql, xmlColumn.ToUTF8());
1699 for (i = 1; i <= rows; i++)
1700 {
1701 name = results[(i * columns) + 1];
1702 if (strcasecmp(name, xsql) == 0)
1703 ok_xmlblob = true;
1704 }
1705 if (schemaUriColumn.Len() == 0)
1706 ok_schemaURI = true;
1707 else
1708 {
1709 strcpy(xsql, schemaUriColumn.ToUTF8());
1710 for (i = 1; i <= rows; i++)
1711 {
1712 name = results[(i * columns) + 1];
1713 if (strcasecmp(name, xsql) == 0)
1714 ok_schemaURI = true;
1715 }
1716 }
1717 if (inPathColumn.Len() == 0)
1718 ok_inPath = true;
1719 else
1720 {
1721 strcpy(xsql, inPathColumn.ToUTF8());
1722 for (i = 1; i <= rows; i++)
1723 {
1724 name = results[(i * columns) + 1];
1725 if (strcasecmp(name, xsql) == 0)
1726 ok_inPath = true;
1727 }
1728 }
1729 if (parseErrColumn.Len() == 0)
1730 ok_parseErr = true;
1731 else
1732 {
1733 strcpy(xsql, parseErrColumn.ToUTF8());
1734 for (i = 1; i <= rows; i++)
1735 {
1736 name = results[(i * columns) + 1];
1737 if (strcasecmp(name, xsql) == 0)
1738 ok_parseErr = true;
1739 }
1740 }
1741 if (validateErrColumn.Len() == 0)
1742 ok_validateErr = true;
1743 else
1744 {
1745 strcpy(xsql, validateErrColumn.ToUTF8());
1746 for (i = 1; i <= rows; i++)
1747 {
1748 name = results[(i * columns) + 1];
1749 if (strcasecmp(name, xsql) == 0)
1750 ok_validateErr = true;
1751 }
1752 }
1753 }
1754 sqlite3_free_table(results);
1755 if (ok_xmlblob == true && ok_inPath == true && ok_schemaURI == true
1756 && ok_parseErr == true && ok_validateErr == true)
1757 ;
1758 else
1759 {
1760 wxMessageBox(wxT
1761 ("ERROR: XML target table already exists, but has incompatible columns"),
1762 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1763 sqlite3_free(errMsg);
1764 goto abort;
1765 }
1766 return true;
1767 abort:
1768 return false;
1769 }
1770
XmlDocumentLoadDir(wxString & path,wxString & suffix,int compressed,const char * schemaURI,bool isInternalSchemaUri,wxString & inPathColumn,wxString & schemaUriColumn,wxString & parseErrColumn,wxString & validateErrColumn,sqlite3_stmt * stmt,int * failed)1771 int MyFrame::XmlDocumentLoadDir(wxString & path, wxString & suffix,
1772 int compressed, const char *schemaURI,
1773 bool isInternalSchemaUri,
1774 wxString & inPathColumn,
1775 wxString & schemaUriColumn,
1776 wxString & parseErrColumn,
1777 wxString & validateErrColumn,
1778 sqlite3_stmt * stmt, int *failed)
1779 {
1780 //
1781 // importing XML Document files from a whole DIRECTORY
1782 //
1783 int fails;
1784 *failed = 0;
1785 #if defined(_WIN32) && !defined(__MINGW32__)
1786 /* Visual Studio .NET */
1787 struct _finddata_t c_file;
1788 intptr_t hFile;
1789 int cnt = 0;
1790 wxString filePath;
1791 if (_chdir(path.ToUTF8()) < 0)
1792 return 0;
1793 if ((hFile = _findfirst("*.*", &c_file)) == -1L)
1794 ;
1795 else
1796 {
1797 while (1)
1798 {
1799 if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
1800 || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
1801 {
1802 if (IsValidSuffix(c_file.name, suffix))
1803 {
1804 filePath = path;
1805 filePath += wxT("/") + wxString::FromUTF8(c_file.name);
1806 cnt +=
1807 XmlDocumentLoadFile(filePath, compressed, schemaURI,
1808 isInternalSchemaUri, inPathColumn,
1809 schemaUriColumn, parseErrColumn,
1810 validateErrColumn, stmt, &fails);
1811 *failed += fails;
1812 }
1813 }
1814 if (_findnext(hFile, &c_file) != 0)
1815 break;
1816 };
1817 _findclose(hFile);
1818 }
1819 return cnt;
1820 #else
1821 /* not Visual Studio .NET */
1822 int cnt = 0;
1823 wxString filePath;
1824 struct dirent *entry;
1825 DIR *dir = opendir(path.ToUTF8());
1826 if (!dir)
1827 return 0;
1828 while (1)
1829 {
1830 // scanning dir-entries
1831 entry = readdir(dir);
1832 if (!entry)
1833 break;
1834 if (IsValidSuffix(entry->d_name, suffix))
1835 {
1836 filePath = path;
1837 filePath += wxT("/") + wxString::FromUTF8(entry->d_name);
1838 cnt +=
1839 XmlDocumentLoadFile(filePath, compressed, schemaURI,
1840 isInternalSchemaUri, inPathColumn,
1841 schemaUriColumn, parseErrColumn,
1842 validateErrColumn, stmt, &fails);
1843 *failed += fails;
1844 }
1845 }
1846 closedir(dir);
1847 return cnt;
1848 #endif
1849 }
1850
IsValidSuffix(const char * fileName,wxString & suffix)1851 bool MyFrame::IsValidSuffix(const char *fileName, wxString & suffix)
1852 {
1853 // testing if a FileName ends with the expected suffix
1854 if (suffix.Len() == 0)
1855 return true;
1856
1857 char suf[1024];
1858 strcpy(suf, suffix.ToUTF8());
1859 int len1 = strlen(fileName);
1860 int len2 = strlen(suf);
1861 int off = len1 - len2;
1862 if (off >= 1)
1863 {
1864 if (strcasecmp(fileName + off, suf) == 0)
1865 return true;
1866 }
1867 return false;
1868 }
1869
XmlDocumentLoadFile(wxString & path,int compressed,const char * schemaURI,bool isInternalSchemaUri,wxString & inPathColumn,wxString & schemaUriColumn,wxString & parseErrColumn,wxString & validateErrColumn,sqlite3_stmt * stmt,int * failed)1870 int MyFrame::XmlDocumentLoadFile(wxString & path, int compressed,
1871 const char *schemaURI,
1872 bool isInternalSchemaUri,
1873 wxString & inPathColumn,
1874 wxString & schemaUriColumn,
1875 wxString & parseErrColumn,
1876 wxString & validateErrColumn,
1877 sqlite3_stmt * stmt, int *failed)
1878 {
1879 //
1880 // importing a single XML Document file
1881 //
1882 #ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */
1883 FILE *fl;
1884 int sz = 0;
1885 int rd;
1886 int loaded = 0;
1887 unsigned char *blob = NULL;
1888 char *xml = NULL;
1889 int xml_size;
1890 char *parseError = NULL;
1891 char *validateError = NULL;
1892 char *p_schemaURI = NULL;
1893 int len;
1894 *failed = 0;
1895
1896 fl = fopen(path.ToUTF8(), "rb");
1897 if (!fl)
1898 return 0;
1899 if (fseek(fl, 0, SEEK_END) == 0)
1900 sz = ftell(fl);
1901 blob = (unsigned char *) malloc(sz);
1902 rewind(fl);
1903 rd = fread(blob, 1, sz, fl);
1904 if (rd == sz)
1905 {
1906 // attempting to parse (and possibly validate) the XMLDocument
1907 if (isInternalSchemaUri)
1908 {
1909 // attempting to retrieve an internally defined SchemaURI
1910 char *internalSchemaURI =
1911 gaiaXmlGetInternalSchemaURI(InternalCache, blob, rd);
1912 if (internalSchemaURI == NULL)
1913 {
1914 // unable to identify the SchemaURI
1915 xml = NULL;
1916 } else
1917 {
1918 // ok, attempting to validate using the internal SchemaURI
1919 len = strlen(internalSchemaURI);
1920 p_schemaURI = (char *) malloc(len + 1);
1921 strcpy(p_schemaURI, internalSchemaURI);
1922 gaiaXmlToBlob(InternalCache, blob, rd, compressed,
1923 internalSchemaURI, (unsigned char **) (&xml),
1924 &xml_size, &parseError, &validateError);
1925 free(internalSchemaURI);
1926 }
1927 } else
1928 {
1929 // possibly validating against the externally defined SchemaURI
1930 if (schemaURI)
1931 {
1932 len = strlen(schemaURI);
1933 p_schemaURI = (char *) malloc(len + 1);
1934 strcpy(p_schemaURI, schemaURI);
1935 }
1936 gaiaXmlToBlob(InternalCache, blob, rd, compressed, schemaURI,
1937 (unsigned char **) (&xml), &xml_size, &parseError,
1938 &validateError);
1939 }
1940 if (xml == NULL)
1941 {
1942 /* creating an empty BLOB as a placeholder */
1943 xml_size = 1;
1944 xml = (char *) malloc(xml_size);
1945 *xml = '\0';
1946 *failed = 1;
1947 }
1948 if (InsertIntoXmlTable
1949 (stmt, xml, xml_size, inPathColumn, path, schemaUriColumn,
1950 p_schemaURI, parseErrColumn, parseError, validateErrColumn,
1951 validateError) == false)
1952 goto stop;
1953 loaded = 1;
1954 }
1955 stop:
1956 if (p_schemaURI)
1957 free(p_schemaURI);
1958 if (blob)
1959 free(blob);
1960 fclose(fl);
1961 return loaded;
1962
1963 #else
1964
1965 wxMessageBox(wxT
1966 ("Sorry, spatialite_gui was built disabling LIBXML2\n\nUnsupported operation"),
1967 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1968
1969 #endif /* end LIBXML2 conditionals */
1970 }
1971
ImportDXFfiles(wxString & path,bool folder,wxString & prefix,wxString & layer,int srid,bool force2d,bool force3d,bool mixed,bool linked,bool unlinked,bool append)1972 void MyFrame::ImportDXFfiles(wxString & path, bool folder, wxString & prefix,
1973 wxString & layer, int srid, bool force2d,
1974 bool force3d, bool mixed, bool linked,
1975 bool unlinked, bool append)
1976 {
1977 //
1978 // trying to import DXF drawing files
1979 //
1980 int cnt;
1981 int failed;
1982 char msg[256];
1983 if (folder == true)
1984 cnt =
1985 DxfLoadDir(path, prefix, layer, srid, force2d, force3d, mixed, linked,
1986 unlinked, append, &failed);
1987 else
1988 cnt =
1989 DxfLoadFile(path, prefix, layer, srid, force2d, force3d, mixed, linked,
1990 unlinked, append, &failed);
1991 wxString message = wxString::FromUTF8(msg);
1992 sprintf(msg, "Imported DXF files: %d\n", cnt - failed);
1993 message += wxString::FromUTF8(msg);
1994 sprintf(msg, "Failures: %d\n", failed);
1995 message += wxString::FromUTF8(msg);
1996 wxMessageBox(message, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
1997 }
1998
DxfLoadDir(wxString & path,wxString & prefix,wxString & layer,int srid,bool force2d,bool force3d,bool mixed,bool linked,bool unlinked,bool append,int * failed)1999 int MyFrame::DxfLoadDir(wxString & path, wxString & prefix, wxString & layer,
2000 int srid, bool force2d, bool force3d, bool mixed,
2001 bool linked, bool unlinked, bool append, int *failed)
2002 {
2003 //
2004 // importing DXF files from a whole DIRECTORY
2005 //
2006 wxString suffix = wxT(".dxf");
2007 int fails;
2008 *failed = 0;
2009 #if defined(_WIN32) && !defined(__MINGW32__)
2010 /* Visual Studio .NET */
2011 struct _finddata_t c_file;
2012 intptr_t hFile;
2013 int cnt = 0;
2014 wxString filePath;
2015 if (_chdir(path.ToUTF8()) < 0)
2016 return 0;
2017 if ((hFile = _findfirst("*.*", &c_file)) == -1L)
2018 ;
2019 else
2020 {
2021 while (1)
2022 {
2023 if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
2024 || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
2025 {
2026 if (IsValidSuffix(entry->d_name, suffix))
2027 {
2028 filePath = path;
2029 filePath += wxT("/") + wxString::FromUTF8(c_file.name);
2030 cnt +=
2031 DxfLoadFile(filePath, prefix, layer, srid, force2d, force3d,
2032 mixed, linked, unlinked, append, &fails);
2033 *failed += fails;
2034 }
2035 }
2036 if (_findnext(hFile, &c_file) != 0)
2037 break;
2038 };
2039 _findclose(hFile);
2040 }
2041 return cnt;
2042 #else
2043 /* not Visual Studio .NET */
2044 int cnt = 0;
2045 wxString filePath;
2046 struct dirent *entry;
2047 DIR *dir = opendir(path.ToUTF8());
2048 if (!dir)
2049 return 0;
2050 while (1)
2051 {
2052 // scanning dir-entries
2053 entry = readdir(dir);
2054 if (!entry)
2055 break;
2056 if (IsValidSuffix(entry->d_name, suffix))
2057 {
2058 filePath = path;
2059 filePath += wxT("/") + wxString::FromUTF8(entry->d_name);
2060 cnt +=
2061 DxfLoadFile(filePath, prefix, layer, srid, force2d, force3d, mixed,
2062 linked, unlinked, append, &fails);
2063 *failed += fails;
2064 }
2065 }
2066 closedir(dir);
2067 return cnt;
2068 #endif
2069 }
2070
DxfLoadFile(wxString & path,wxString & prefix,wxString & layer,int srid,bool force2d,bool force3d,bool mixed,bool linked,bool unlinked,bool append,int * failed)2071 int MyFrame::DxfLoadFile(wxString & path, wxString & prefix, wxString & layer,
2072 int srid, bool force2d, bool force3d, bool mixed,
2073 bool linked, bool unlinked, bool append, int *failed)
2074 {
2075 //
2076 // importing a single DXF file
2077 //
2078 int force_dims = GAIA_DXF_AUTO_2D_3D;
2079 int special_rings = GAIA_DXF_RING_NONE;
2080 char dxf_path[1024];
2081 char xprefix[1024];
2082 const char *xxprefix = NULL;
2083 char selected_layer[1024];
2084 const char *xselected_layer = NULL;
2085 gaiaDxfParserPtr dxf;
2086 bool error = false;
2087
2088 *failed = 0;
2089 // creating a DXF parser
2090 if (prefix.Len() > 0)
2091 {
2092 strcpy(xprefix, prefix.ToUTF8());
2093 xxprefix = xprefix;
2094 }
2095 if (layer.Len() > 0)
2096 {
2097 strcpy(selected_layer, layer.ToUTF8());
2098 xselected_layer = selected_layer;
2099 }
2100 if (force2d)
2101 force_dims = GAIA_DXF_FORCE_2D;
2102 else if (force3d)
2103 force_dims = GAIA_DXF_FORCE_3D;
2104 if (linked)
2105 special_rings = GAIA_DXF_RING_LINKED;
2106 else if (unlinked)
2107 special_rings = GAIA_DXF_RING_UNLINKED;
2108 dxf =
2109 gaiaCreateDxfParser(srid, force_dims, xxprefix, xselected_layer,
2110 special_rings);
2111 if (dxf == NULL)
2112 {
2113 *failed = 1;
2114 goto stop;
2115 }
2116 // attempting to parse the DXF input file
2117 strcpy(dxf_path, path.ToUTF8());
2118 if (gaiaParseDxfFile(dxf, dxf_path))
2119 {
2120 // loading into the DB
2121 int mode = GAIA_DXF_IMPORT_BY_LAYER;
2122 if (mixed)
2123 mode = GAIA_DXF_IMPORT_MIXED;
2124 if (!gaiaLoadFromDxfParser(GetSqlite(), dxf, mode, append))
2125 {
2126 wxMessageBox(wxT("DB error while loading: ") + path,
2127 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2128 *failed = 1;
2129 }
2130 } else
2131 {
2132 wxMessageBox(wxT("Unable to parse: ") + path, wxT("spatialite_gui"),
2133 wxOK | wxICON_ERROR, this);
2134 *failed = 1;
2135 }
2136
2137
2138 stop:
2139 // destroying the DXF parser
2140 gaiaDestroyDxfParser(dxf);
2141 return 1;
2142 }
2143