~ubuntu-branches/ubuntu/utopic/qgis/utopic

« back to all changes in this revision

Viewing changes to src/providers/spatialite/qgsspatialiteprovider.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-04-24 15:12:20 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120424151220-r88g00af5fpn5fc3
Tags: 1.7.4+1.7.5~20120320-1
The "Sometimes they come back" release.

* Branching from Qgis tree and adapting to current Debian Policy and
  standards. The target tree is currently set to release-1.7.
  (closes: #661491, #606304, #615683, #616182, #600308)
* Policy bumped to 3.9.3.
* Moving to debhelper compatibility level 9.
* Source format is now 3.0 with quilt support.
* Merged with 2bf42287 upstream git snapshot.
* Migrated to dh_python2 instead of python-central.
  (closes: #617048)
* Snapshot in qgis.org release-1.7: c936d031
* Added an automagic creation of a lintian override for sqlite embedding.
  This is required for uploading currently.
* Added missing ${misc:Depends} to make lintian happy.
* Copyright notes updated and debian/copyright moved to format 1.0.
* More licenses notices now reported in debian/copyright. Thanks ftpmasters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 *                                                                         *
15
15
 ***************************************************************************/
16
16
 
17
 
#include <cassert>
18
 
 
19
17
#include <qgis.h>
20
18
#include <qgsapplication.h>
21
19
#include <qgsfeature.h>
25
23
#include <qgsrectangle.h>
26
24
#include <qgscoordinatereferencesystem.h>
27
25
 
28
 
#include "qgsprovidercountcalcevent.h"
29
 
#include "qgsproviderextentcalcevent.h"
30
 
 
31
26
#include "qgsspatialiteprovider.h"
32
27
 
33
28
#include "qgslogger.h"
41
36
 
42
37
QMap < QString, QgsSpatiaLiteProvider::SqliteHandles * >QgsSpatiaLiteProvider::SqliteHandles::handles;
43
38
 
44
 
QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri ): QgsVectorDataProvider( uri ),
45
 
    geomType( QGis::WKBUnknown ), sqliteHandle( NULL ), sqliteStatement( NULL ), mSrid( -1 ), spatialIndexRTree( false ), spatialIndexMbrCache( false )
 
39
QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri )
 
40
    : QgsVectorDataProvider( uri )
 
41
    , geomType( QGis::WKBUnknown )
 
42
    , sqliteHandle( NULL )
 
43
    , sqliteStatement( NULL )
 
44
    , mSrid( -1 )
 
45
    , spatialIndexRTree( false )
 
46
    , spatialIndexMbrCache( false )
46
47
{
 
48
  nDims = GAIA_XY;
47
49
  QgsDataSourceURI anUri = QgsDataSourceURI( uri );
48
50
 
49
51
  // parsing members from the uri structure
51
53
  mGeometryColumn = anUri.geometryColumn();
52
54
  mSqlitePath = anUri.database();
53
55
  mSubsetString = anUri.sql();
 
56
  mPrimaryKey = anUri.keyColumn();
 
57
  mQuery = mTableName;
54
58
 
55
59
  // trying to open the SQLite DB
56
60
  spatialite_init( 0 );
69
73
    numberFeatures = 0;
70
74
    valid = false;
71
75
 
72
 
    QgsLogger::critical( "Invalid SpatiaLite layer" );
 
76
    QgsDebugMsg( "Invalid SpatiaLite layer" );
73
77
    closeDb();
74
78
    return;
75
79
  }
90
94
    numberFeatures = 0;
91
95
    valid = false;
92
96
 
93
 
    QgsLogger::critical( "Invalid SpatiaLite layer" );
 
97
    QgsDebugMsg( "Invalid SpatiaLite layer" );
94
98
    closeDb();
95
99
    return;
96
100
  }
99
103
    numberFeatures = 0;
100
104
    valid = false;
101
105
 
102
 
    QgsLogger::critical( "Invalid SpatiaLite layer" );
 
106
    QgsDebugMsg( "Invalid SpatiaLite layer" );
103
107
    closeDb();
104
108
    return;
105
109
  }
109
113
  {
110
114
    valid = false;
111
115
 
112
 
    QgsLogger::critical( "Invalid SpatiaLite layer" );
 
116
    QgsDebugMsg( "Invalid SpatiaLite layer" );
113
117
    return;
114
118
  }
115
119
  //fill type names into sets
130
134
{
131
135
  int ret;
132
136
  int i;
 
137
  sqlite3_stmt *stmt = NULL;
133
138
  char **results;
134
139
  int rows;
135
140
  int columns;
137
142
  QString pkName;
138
143
  int pkCount = 0;
139
144
  int fldNo = 0;
 
145
  QString sql;
140
146
 
141
147
  attributeFields.clear();
142
 
  mPrimaryKey.clear();
143
 
 
144
 
  QString sql = QString( "PRAGMA table_info(\"%1\")" ).arg( mTableName );
145
 
 
146
 
  ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
147
 
  if ( ret != SQLITE_OK )
148
 
    goto error;
149
 
  if ( rows < 1 )
150
 
    ;
 
148
 
 
149
  if ( !isQuery )
 
150
  {
 
151
    mPrimaryKey.clear();
 
152
 
 
153
    sql = QString( "PRAGMA table_info(%1)" ).arg( quotedIdentifier( mTableName ) );
 
154
 
 
155
    ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
 
156
    if ( ret != SQLITE_OK )
 
157
      goto error;
 
158
    if ( rows < 1 )
 
159
      ;
 
160
    else
 
161
    {
 
162
      for ( i = 1; i <= rows; i++ )
 
163
      {
 
164
        QString name = QString::fromUtf8( results[( i * columns ) + 1] );
 
165
        const char *type = results[( i * columns ) + 2];
 
166
        QString pk = results[( i * columns ) + 5];
 
167
        if ( pk.toInt() != 0 )
 
168
        {
 
169
          // found a Primary Key column
 
170
          pkCount++;
 
171
          pkName = name;
 
172
        }
 
173
 
 
174
        if ( name != mGeometryColumn )
 
175
        {
 
176
          // for sure any SQLite value can be represented as SQLITE_TEXT
 
177
          QVariant::Type fieldType = QVariant::String;
 
178
 
 
179
          // making some assumptions in order to guess a more realistic type
 
180
          if ( strcasecmp( type, "int" ) == 0 ||
 
181
               strcasecmp( type, "integer" ) == 0 ||
 
182
               strcasecmp( type, "bigint" ) == 0 ||
 
183
               strcasecmp( type, "smallint" ) == 0 ||
 
184
               strcasecmp( type, "tinyint" ) == 0 ||
 
185
               strcasecmp( type, "boolean" ) == 0 )
 
186
          {
 
187
            fieldType = QVariant::Int;
 
188
          }
 
189
          else if ( strcasecmp( type, "real" ) == 0 ||
 
190
                    strcasecmp( type, "double" ) == 0 ||
 
191
                    strcasecmp( type, "double precision" ) == 0 ||
 
192
                    strcasecmp( type, "float" ) == 0 )
 
193
          {
 
194
            fieldType = QVariant::Double;
 
195
          }
 
196
 
 
197
          attributeFields.insert( fldNo++, QgsField( name, fieldType, type, 0, 0, "" ) );
 
198
        }
 
199
      }
 
200
    }
 
201
    sqlite3_free_table( results );
 
202
  }
151
203
  else
152
204
  {
153
 
    for ( i = 1; i <= rows; i++ )
154
 
    {
155
 
      QString name = QString::fromUtf8( results[( i * columns ) + 1] );
156
 
      const char *type = results[( i * columns ) + 2];
157
 
      QString pk = results[( i * columns ) + 5];
158
 
      if ( pk.toInt() != 0 )
159
 
      {
160
 
        // found a Primary Key column
161
 
        pkCount++;
162
 
        pkName = name;
163
 
      }
164
 
 
165
 
      if ( name != mGeometryColumn )
166
 
      {
167
 
        // for sure any SQLite value can be represented as SQLITE_TEXT
168
 
        QVariant::Type fieldType = QVariant::String;
169
 
 
170
 
        // making some assumptions in order to guess a more realistic type
171
 
        if ( strcasecmp( type, "int" ) == 0 ||
172
 
             strcasecmp( type, "integer" ) == 0 ||
173
 
             strcasecmp( type, "bigint" ) == 0 ||
174
 
             strcasecmp( type, "smallint" ) == 0 || strcasecmp( type, "tinyint" ) == 0 || strcasecmp( type, "boolean" ) == 0 )
175
 
        {
176
 
          fieldType = QVariant::Int;
177
 
        }
178
 
        else if ( strcasecmp( type, "real" ) == 0 ||
179
 
                  strcasecmp( type, "double" ) == 0 ||
180
 
                  strcasecmp( type, "double precision" ) == 0 || strcasecmp( type, "float" ) == 0 )
181
 
        {
182
 
          fieldType = QVariant::Double;
183
 
        }
184
 
 
185
 
        attributeFields.insert( fldNo++, QgsField( name, fieldType, type, 0, 0, "" ) );
186
 
      }
187
 
    }
 
205
    sql = QString( "select * from %1 limit 1" ).arg( mQuery );
 
206
 
 
207
    if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
 
208
    {
 
209
      // some error occurred
 
210
      QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" )
 
211
                   .arg( sql )
 
212
                   .arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
 
213
      return;
 
214
    }
 
215
 
 
216
    ret = sqlite3_step( stmt );
 
217
    if ( ret == SQLITE_DONE )
 
218
    {
 
219
      // there are no rows to fetch
 
220
      sqlite3_finalize( stmt );
 
221
      return;
 
222
    }
 
223
 
 
224
    if ( ret == SQLITE_ROW )
 
225
    {
 
226
      // one valid row has been fetched from the result set
 
227
      columns = sqlite3_column_count( stmt );
 
228
      for ( i = 0; i < columns; i++ )
 
229
      {
 
230
        QString name = QString::fromUtf8( sqlite3_column_name( stmt, i ) );
 
231
        const char *type = sqlite3_column_decltype( stmt, i );
 
232
        if ( type == NULL )
 
233
          type = "TEXT";
 
234
 
 
235
        if ( name == mPrimaryKey )
 
236
        {
 
237
          pkCount++;
 
238
          pkName = name;
 
239
        }
 
240
 
 
241
        if ( name != mGeometryColumn )
 
242
        {
 
243
          // for sure any SQLite value can be represented as SQLITE_TEXT
 
244
          QVariant::Type fieldType = QVariant::String;
 
245
 
 
246
          // making some assumptions in order to guess a more realistic type
 
247
          if ( strcasecmp( type, "int" ) == 0 ||
 
248
               strcasecmp( type, "integer" ) == 0 ||
 
249
               strcasecmp( type, "bigint" ) == 0 ||
 
250
               strcasecmp( type, "smallint" ) == 0 ||
 
251
               strcasecmp( type, "tinyint" ) == 0 ||
 
252
               strcasecmp( type, "boolean" ) == 0 )
 
253
          {
 
254
            fieldType = QVariant::Int;
 
255
          }
 
256
          else if ( strcasecmp( type, "real" ) == 0 ||
 
257
                    strcasecmp( type, "double" ) == 0 ||
 
258
                    strcasecmp( type, "double precision" ) == 0 ||
 
259
                    strcasecmp( type, "float" ) == 0 )
 
260
          {
 
261
            fieldType = QVariant::Double;
 
262
          }
 
263
 
 
264
          attributeFields.insert( fldNo++, QgsField( name, fieldType, type, 0, 0, "" ) );
 
265
        }
 
266
      }
 
267
    }
 
268
    sqlite3_finalize( stmt );
188
269
  }
189
 
  sqlite3_free_table( results );
190
270
 
191
271
  if ( pkCount == 1 )
192
272
  {
200
280
  // unexpected error
201
281
  if ( errMsg != NULL )
202
282
  {
203
 
    QString error = "loadFields() SQL error: ";
204
 
    error = errMsg;
205
 
    QgsLogger::critical( error );
 
283
    QgsDebugMsg( QString( "SQL error: %1" ).arg( QString::fromUtf8( errMsg ) ) );
206
284
    sqlite3_free( errMsg );
207
285
  }
208
286
}
218
296
{
219
297
  sqlite3_stmt *stmt = NULL;
220
298
 
221
 
  QString sql = "SELECT ROWID";
 
299
  feature.setValid( false );
 
300
 
 
301
  QString primaryKey = !isQuery ? "ROWID" : quotedIdentifier( mPrimaryKey );
 
302
 
 
303
  QString sql = QString( "SELECT %1" ).arg( primaryKey );
222
304
  for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
223
305
  {
224
306
    const QgsField & fld = field( *it );
225
307
    const QString & fieldname = fld.name();
226
 
    sql += ", \"";
227
 
    sql += fieldname;
228
 
    sql += "\"";
 
308
    sql += "," + quotedIdentifier( fieldname );
229
309
  }
230
310
  if ( fetchGeometry )
231
311
  {
232
 
    sql += QString( ", AsBinary(\"%1\")" ).arg( mGeometryColumn );
 
312
    sql += QString( ", AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
233
313
  }
234
 
  sql += QString( " FROM \"%1\" WHERE ROWID = %2" ).arg( mTableName ).arg( featureId );
 
314
  sql += QString( " FROM %1 WHERE %2 = %3" )
 
315
         .arg( mQuery )
 
316
         .arg( primaryKey )
 
317
         .arg( featureId );
235
318
 
236
319
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
237
320
  {
238
321
    // some error occurred
239
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
240
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
241
 
    QgsLogger::critical( msg );
 
322
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" )
 
323
                 .arg( sql )
 
324
                 .arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
242
325
    return false;
243
326
  }
244
327
 
258
341
      feature.setGeometryAndOwnership( 0, 0 );
259
342
    }
260
343
 
 
344
    feature.clearAttributeMap();
 
345
 
261
346
    int ic;
262
347
    int n_columns = sqlite3_column_count( stmt );
263
348
    for ( ic = 0; ic < n_columns; ic++ )
264
349
    {
265
350
      if ( ic == 0 )
266
351
      {
267
 
        // first column always contains the ROWID
 
352
        // first column always contains the ROWID (or the primary key)
268
353
        feature.setFeatureId( sqlite3_column_int( stmt, ic ) );
269
354
      }
270
355
      else
312
397
        }
313
398
        if ( mFetchGeom )
314
399
        {
315
 
          QString geoCol = QString( "AsBinary(\"%1\")" ).arg( mGeometryColumn );
 
400
          QString geoCol = QString( "AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
316
401
          if ( strcasecmp( geoCol.toUtf8().constData(), sqlite3_column_name( stmt, ic ) ) == 0 )
317
402
          {
318
403
            if ( sqlite3_column_type( stmt, ic ) == SQLITE_BLOB )
319
404
            {
 
405
              unsigned char *featureGeom = NULL;
 
406
              size_t geom_size = 0;
320
407
              const void *blob = sqlite3_column_blob( stmt, ic );
321
408
              size_t blob_size = sqlite3_column_bytes( stmt, ic );
322
 
              unsigned char *featureGeom = new unsigned char[blob_size + 1];
323
 
              memset( featureGeom, '\0', blob_size + 1 );
324
 
              memcpy( featureGeom, blob, blob_size );
325
 
              feature.setGeometryAndOwnership( featureGeom, blob_size + 1 );
 
409
              convertToGeosWKB ( (const unsigned char *)blob, blob_size, 
 
410
                                 &featureGeom, &geom_size );
 
411
              if ( featureGeom )
 
412
                   feature.setGeometryAndOwnership( featureGeom, geom_size );
 
413
              else
 
414
                   feature.setGeometryAndOwnership( 0, 0 );
326
415
            }
327
416
            else
328
417
            {
337
426
  else
338
427
  {
339
428
    // some unexpected error occurred
340
 
    QString error = "sqlite3_step() error: ";
341
 
    error += sqlite3_errmsg( sqliteHandle );
342
 
    QgsLogger::critical( error );
 
429
    QgsDebugMsg( QString( "sqlite3_step() error: %1" ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
343
430
    sqlite3_finalize( stmt );
344
431
    return false;
345
432
  }
346
433
  sqlite3_finalize( stmt );
347
434
 
 
435
  feature.setValid( true );
 
436
 
348
437
  return true;
349
438
}
350
439
 
353
442
  feature.setValid( false );
354
443
  if ( !valid )
355
444
  {
356
 
    QgsLogger::critical( "Read attempt on an invalid SpatiaLite data source" );
 
445
    QgsDebugMsg( "Read attempt on an invalid SpatiaLite data source" );
357
446
    return false;
358
447
  }
359
448
 
360
449
  if ( sqliteStatement == NULL )
361
450
  {
362
 
    QgsLogger::critical( "Invalid current SQLite statement" );
 
451
    QgsDebugMsg( "Invalid current SQLite statement" );
363
452
    return false;
364
453
  }
365
454
 
380
469
      feature.setGeometryAndOwnership( 0, 0 );
381
470
    }
382
471
 
 
472
    feature.clearAttributeMap();
 
473
 
383
474
    int ic;
384
475
    int n_columns = sqlite3_column_count( sqliteStatement );
385
476
    for ( ic = 0; ic < n_columns; ic++ )
386
477
    {
387
478
      if ( ic == 0 )
388
479
      {
389
 
        // first column always contains the ROWID
 
480
        // first column always contains the ROWID (or the primary key)
390
481
        feature.setFeatureId( sqlite3_column_int( sqliteStatement, ic ) );
391
482
      }
392
483
      else
434
525
        }
435
526
        if ( mFetchGeom )
436
527
        {
437
 
          QString geoCol = QString( "AsBinary(\"%1\")" ).arg( mGeometryColumn );
 
528
          QString geoCol = QString( "AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
438
529
          if ( strcasecmp( geoCol.toUtf8().constData(), sqlite3_column_name( sqliteStatement, ic ) ) == 0 )
439
530
          {
440
531
            if ( sqlite3_column_type( sqliteStatement, ic ) == SQLITE_BLOB )
441
532
            {
 
533
              unsigned char *featureGeom = NULL;
 
534
              size_t geom_size = 0;
442
535
              const void *blob = sqlite3_column_blob( sqliteStatement, ic );
443
536
              size_t blob_size = sqlite3_column_bytes( sqliteStatement, ic );
444
 
              unsigned char *featureGeom = new unsigned char[blob_size + 1];
445
 
              memset( featureGeom, '\0', blob_size + 1 );
446
 
              memcpy( featureGeom, blob, blob_size );
447
 
              feature.setGeometryAndOwnership( featureGeom, blob_size + 1 );
 
537
              convertToGeosWKB ( (const unsigned char *)blob, blob_size, 
 
538
                                  &featureGeom, &geom_size );
 
539
              if ( featureGeom )
 
540
                   feature.setGeometryAndOwnership( featureGeom, geom_size );
 
541
              else
 
542
                   feature.setGeometryAndOwnership( 0, 0 );
448
543
            }
449
544
            else
450
545
            {
459
554
  else
460
555
  {
461
556
    // some unexpected error occurred
462
 
    QString error = "sqlite3_step() error: ";
463
 
    error += sqlite3_errmsg( sqliteHandle );
464
 
    QgsLogger::critical( error );
 
557
    QgsDebugMsg( QString( "sqlite3_step() error: %1" ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
465
558
    sqlite3_finalize( sqliteStatement );
466
559
    sqliteStatement = NULL;
467
560
    return false;
471
564
  return true;
472
565
}
473
566
 
 
567
int QgsSpatiaLiteProvider::computeSizeFromGeosWKB2D( const unsigned char *blob,
 
568
                                  size_t size, int type, int nDims, 
 
569
                                  int little_endian, int endian_arch )
 
570
{
 
571
// calculating the size required to store this WKB 
 
572
    int rings;
 
573
    int points;
 
574
    int ib;
 
575
    const unsigned char *p_in = blob;
 
576
    int gsize = 5;
 
577
 
 
578
    p_in = blob + 5;
 
579
    switch ( type )
 
580
    {
 
581
    // compunting the required size
 
582
        case GAIA_POINT:
 
583
            switch ( nDims )
 
584
            {
 
585
                case GAIA_XY_Z_M:
 
586
                    gsize += 4 * sizeof(double);
 
587
                    break;
 
588
                case GAIA_XY_M:
 
589
                case GAIA_XY_Z:
 
590
                    gsize += 3 * sizeof(double);
 
591
                    break;
 
592
                default:
 
593
                    gsize += 2 * sizeof(double);
 
594
                    break;
 
595
            }
 
596
            break;
 
597
        case GAIA_LINESTRING:
 
598
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
599
            gsize += 4;
 
600
            switch ( nDims )
 
601
            {
 
602
                case GAIA_XY_Z_M:
 
603
                    gsize += points * ( 4 * sizeof(double) );
 
604
                    break;
 
605
                case GAIA_XY_M:
 
606
                case GAIA_XY_Z:
 
607
                    gsize += points * ( 3 * sizeof(double) );
 
608
                    break;
 
609
                default:
 
610
                    gsize += points * ( 2 * sizeof(double) );
 
611
                    break;
 
612
            }
 
613
            break;
 
614
        case GAIA_POLYGON:
 
615
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
616
            p_in += 4;
 
617
            gsize += 4;
 
618
            for ( ib = 0; ib < rings; ib++ )
 
619
            {
 
620
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
621
                p_in += 4;
 
622
                gsize += 4;
 
623
                switch ( nDims )
 
624
                {
 
625
                    case GAIA_XY_Z_M:
 
626
                        gsize += points * ( 4 * sizeof(double) );
 
627
                        break;
 
628
                    case GAIA_XY_M:
 
629
                    case GAIA_XY_Z:
 
630
                        gsize += points * ( 3 * sizeof(double) );
 
631
                        break;
 
632
                    default:
 
633
                        gsize += points * ( 2 * sizeof(double) );
 
634
                        break;
 
635
                }
 
636
                p_in += points * ( 2 * sizeof(double) );
 
637
            }
 
638
            break;
 
639
        default:
 
640
            gsize += computeSizeFromMultiWKB2D( p_in, nDims, little_endian, 
 
641
                                                endian_arch );
 
642
            break;
 
643
    }
 
644
        
 
645
    return gsize;
 
646
}
 
647
 
 
648
int QgsSpatiaLiteProvider::computeSizeFromMultiWKB2D( const unsigned char *p_in,
 
649
                                                      int nDims, 
 
650
                                                      int little_endian, 
 
651
                                                      int endian_arch )
 
652
{
 
653
// calculating the size required to store this WKB
 
654
    int entities;
 
655
    int type;
 
656
    int rings;
 
657
    int points;
 
658
    int ie;
 
659
    int ib;
 
660
    int size = 0;
 
661
        
 
662
    entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
663
    p_in += 4;
 
664
    size += 4;
 
665
    for ( ie = 0; ie < entities; ie++ )
 
666
    {
 
667
        type = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
668
        p_in += 5;
 
669
        size += 5;
 
670
        switch ( type )
 
671
        {
 
672
        // compunting the required size
 
673
            case GAIA_POINT:
 
674
                switch ( nDims )
 
675
                {
 
676
                    case GAIA_XY_Z_M:
 
677
                        size += 4 * sizeof(double);
 
678
                        break;
 
679
                    case GAIA_XY_Z:
 
680
                    case GAIA_XY_M:
 
681
                        size += 3 * sizeof(double);
 
682
                        break;
 
683
                    default:
 
684
                        size += 2 * sizeof(double);
 
685
                        break;
 
686
                }
 
687
                p_in += 2 * sizeof(double);
 
688
                break;
 
689
            case GAIA_LINESTRING:
 
690
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
691
                p_in += 4;
 
692
                size += 4;
 
693
                switch ( nDims )
 
694
                {
 
695
                    case GAIA_XY_Z_M:
 
696
                        size += points * ( 4 * sizeof(double) );
 
697
                        break;
 
698
                    case GAIA_XY_Z:
 
699
                    case GAIA_XY_M:
 
700
                        size += points * ( 3 * sizeof(double) );
 
701
                        break;
 
702
                    default:
 
703
                        size += points * ( 2 * sizeof(double) );
 
704
                        break;
 
705
                }
 
706
                p_in += points * ( 2 * sizeof(double) );
 
707
                break;
 
708
            case GAIA_POLYGON:
 
709
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
710
                p_in += 4;
 
711
                size += 4;
 
712
                for ( ib = 0; ib < rings; ib++ )
 
713
                {
 
714
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
715
                    p_in += 4;
 
716
                    size += 4;
 
717
                    switch ( nDims )
 
718
                    {
 
719
                        case GAIA_XY_Z_M:
 
720
                            size += points * ( 4 * sizeof(double) );
 
721
                            break;
 
722
                        case GAIA_XY_Z:
 
723
                        case GAIA_XY_M:
 
724
                            size += points * ( 3 * sizeof(double) );
 
725
                            break;
 
726
                        default:
 
727
                            size += points * ( 2 * sizeof(double) );
 
728
                            break;
 
729
                    }
 
730
                    p_in += points * ( 2 * sizeof(double) );
 
731
                }
 
732
                break;
 
733
        }
 
734
    }
 
735
 
 
736
    return size;
 
737
}
 
738
 
 
739
int QgsSpatiaLiteProvider::computeSizeFromGeosWKB3D( const unsigned char *blob,
 
740
                                  size_t size, int type, int nDims, 
 
741
                                  int little_endian, int endian_arch )
 
742
{
 
743
// calculating the size required to store this WKB 
 
744
    int rings;
 
745
    int points;
 
746
    int ib;
 
747
    const unsigned char *p_in = blob;
 
748
    int gsize = 5;
 
749
 
 
750
    p_in = blob + 5;
 
751
    switch ( type )
 
752
    {
 
753
    // compunting the required size
 
754
        case GEOS_3D_POINT:
 
755
            switch ( nDims )
 
756
            {
 
757
                case GAIA_XY_Z_M:
 
758
                    gsize += 4 * sizeof(double);
 
759
                    break;
 
760
                case GAIA_XY_M:
 
761
                case GAIA_XY_Z:
 
762
                    gsize += 3 * sizeof(double);
 
763
                    break;
 
764
                default:
 
765
                    gsize += 2 * sizeof(double);
 
766
                    break;
 
767
            }
 
768
            break;
 
769
        case GEOS_3D_LINESTRING:
 
770
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
771
            gsize += 4;
 
772
            switch ( nDims )
 
773
            {
 
774
                case GAIA_XY_Z_M:
 
775
                    gsize += points * ( 4 * sizeof(double) );
 
776
                    break;
 
777
                case GAIA_XY_M:
 
778
                case GAIA_XY_Z:
 
779
                    gsize += points * ( 3 * sizeof(double) );
 
780
                    break;
 
781
                default:
 
782
                    gsize += points * ( 2 * sizeof(double) );
 
783
                    break;
 
784
            }
 
785
            break;
 
786
        case GEOS_3D_POLYGON:
 
787
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
788
            p_in += 4;
 
789
            gsize += 4;
 
790
            for ( ib = 0; ib < rings; ib++ )
 
791
            {
 
792
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
793
                p_in += 4;
 
794
                gsize += 4;
 
795
                switch ( nDims )
 
796
                {
 
797
                    case GAIA_XY_Z_M:
 
798
                        gsize += points * ( 4 * sizeof(double) );
 
799
                        break;
 
800
                    case GAIA_XY_M:
 
801
                    case GAIA_XY_Z:
 
802
                        gsize += points * ( 3 * sizeof(double) );
 
803
                        break;
 
804
                    default:
 
805
                        gsize += points * ( 2 * sizeof(double) );
 
806
                        break;
 
807
                }
 
808
                p_in += points * ( 3 * sizeof(double) );
 
809
            }
 
810
            break;
 
811
        default:
 
812
            gsize += computeSizeFromMultiWKB3D( p_in, nDims, little_endian, 
 
813
                                                endian_arch );
 
814
            break;
 
815
    }
 
816
        
 
817
    return gsize;
 
818
}
 
819
 
 
820
int QgsSpatiaLiteProvider::computeSizeFromMultiWKB3D( const unsigned char *p_in,
 
821
                                                      int nDims, 
 
822
                                                      int little_endian, 
 
823
                                                      int endian_arch )
 
824
{
 
825
// calculating the size required to store this WKB
 
826
    int entities;
 
827
    int type;
 
828
    int rings;
 
829
    int points;
 
830
    int ie;
 
831
    int ib;
 
832
    int size = 0;
 
833
        
 
834
    entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
835
    p_in += 4;
 
836
    size += 4;
 
837
    for ( ie = 0; ie < entities; ie++ )
 
838
    {
 
839
        type = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
840
        p_in += 5;
 
841
        size += 5;
 
842
        switch ( type )
 
843
        {
 
844
        // compunting the required size
 
845
            case GEOS_3D_POINT:
 
846
                switch ( nDims )
 
847
                {
 
848
                    case GAIA_XY_Z_M:
 
849
                        size += 4 * sizeof(double);
 
850
                        break;
 
851
                    case GAIA_XY_Z:
 
852
                    case GAIA_XY_M:
 
853
                        size += 3 * sizeof(double);
 
854
                        break;
 
855
                    default:
 
856
                        size += 2 * sizeof(double);
 
857
                        break;
 
858
                }
 
859
                p_in += 3 * sizeof(double);
 
860
                break;
 
861
            case GEOS_3D_LINESTRING:
 
862
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
863
                p_in += 4;
 
864
                size += 4;
 
865
                switch ( nDims )
 
866
                {
 
867
                    case GAIA_XY_Z_M:
 
868
                        size += points * ( 4 * sizeof(double) );
 
869
                        break;
 
870
                    case GAIA_XY_Z:
 
871
                    case GAIA_XY_M:
 
872
                        size += points * ( 3 * sizeof(double) );
 
873
                        break;
 
874
                    default:
 
875
                        size += points * ( 2 * sizeof(double) );
 
876
                        break;
 
877
                }
 
878
                p_in += points * ( 3 * sizeof(double) );
 
879
                break;
 
880
            case GEOS_3D_POLYGON:
 
881
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
882
                p_in += 4;
 
883
                size += 4;
 
884
                for ( ib = 0; ib < rings; ib++ )
 
885
                {
 
886
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
887
                    p_in += 4;
 
888
                    size += 4;
 
889
                    switch ( nDims )
 
890
                    {
 
891
                        case GAIA_XY_Z_M:
 
892
                            size += points * ( 4 * sizeof(double) );
 
893
                            break;
 
894
                        case GAIA_XY_Z:
 
895
                        case GAIA_XY_M:
 
896
                            size += points * ( 3 * sizeof(double) );
 
897
                            break;
 
898
                        default:
 
899
                            size += points * ( 2 * sizeof(double) );
 
900
                            break;
 
901
                    }
 
902
                    p_in += points * ( 3 * sizeof(double) );
 
903
                }
 
904
                break;
 
905
        }
 
906
    }
 
907
 
 
908
    return size;
 
909
}
 
910
 
 
911
void QgsSpatiaLiteProvider::convertFromGeosWKB ( const unsigned char *blob, 
 
912
                                                 size_t blob_size, 
 
913
                                                 unsigned char **wkb, 
 
914
                                                 size_t *geom_size, 
 
915
                                                 int nDims )
 
916
{
 
917
// attempting to convert from 2D/3D GEOS own WKB
 
918
    int type;
 
919
    int gDims;
 
920
    int gsize;
 
921
    int little_endian;
 
922
    int endian_arch = gaiaEndianArch ();
 
923
        
 
924
    *wkb = NULL;
 
925
    *geom_size = 0;
 
926
    if ( blob_size < 5 )
 
927
        return;
 
928
    if ( *( blob + 0 ) == 0x01 )
 
929
        little_endian = GAIA_LITTLE_ENDIAN;
 
930
    else
 
931
        little_endian = GAIA_BIG_ENDIAN;
 
932
    type = gaiaImport32 ( blob + 1, little_endian, endian_arch );
 
933
    if (type == GEOS_3D_POINT || type == GEOS_3D_LINESTRING 
 
934
        || type == GEOS_3D_POLYGON
 
935
        || type == GEOS_3D_MULTIPOINT || type == GEOS_3D_MULTILINESTRING
 
936
        || type == GEOS_3D_MULTIPOLYGON || type == GEOS_3D_GEOMETRYCOLLECTION)
 
937
        gDims = 3;
 
938
    else if (type == GAIA_POINT || type == GAIA_LINESTRING
 
939
        || type == GAIA_POLYGON || type == GAIA_MULTIPOINT
 
940
        || type == GAIA_MULTILINESTRING || type == GAIA_MULTIPOLYGON
 
941
        || type == GAIA_GEOMETRYCOLLECTION)
 
942
        gDims = 2;
 
943
    else
 
944
        return;
 
945
                
 
946
    if ( gDims == 2 && nDims == GAIA_XY )
 
947
    {
 
948
    // already 2D: simply copying is required
 
949
        unsigned char *wkbGeom = new unsigned char[blob_size + 1];
 
950
        memset( wkbGeom, '\0', blob_size + 1 );
 
951
        memcpy( wkbGeom, blob, blob_size );
 
952
        *wkb = wkbGeom;
 
953
        *geom_size = blob_size + 1;
 
954
        return;
 
955
    }   
 
956
        
 
957
// we need creating a GAIA WKB
 
958
    if ( gDims == 3 )
 
959
        gsize = computeSizeFromGeosWKB3D( blob, blob_size, type, nDims, 
 
960
                                          little_endian, endian_arch );
 
961
    else
 
962
        gsize = computeSizeFromGeosWKB2D( blob, blob_size, type, nDims, 
 
963
                                          little_endian, endian_arch );
 
964
    
 
965
    unsigned char *wkbGeom = new unsigned char[gsize];
 
966
    memset( wkbGeom, '\0', gsize );
 
967
        
 
968
    if ( gDims == 3 )
 
969
        convertFromGeosWKB3D( blob, blob_size, wkbGeom, gsize, nDims, 
 
970
                              little_endian, endian_arch );
 
971
    else
 
972
        convertFromGeosWKB2D( blob, blob_size, wkbGeom, gsize, nDims, 
 
973
                              little_endian, endian_arch );
 
974
                                                          
 
975
        *wkb = wkbGeom;
 
976
    *geom_size = gsize;
 
977
}
 
978
 
 
979
void QgsSpatiaLiteProvider::convertFromGeosWKB2D ( const unsigned char *blob, 
 
980
                                                   size_t blob_size, 
 
981
                                                   unsigned char *wkb, 
 
982
                                                   size_t geom_size,  
 
983
                                                   int nDims, 
 
984
                                                   int little_endian, 
 
985
                                                   int endian_arch )
 
986
{
 
987
// attempting to convert from 2D GEOS own WKB
 
988
    int type;
 
989
    int entities;
 
990
    int rings;
 
991
    int points;
 
992
    int ie;
 
993
    int ib;
 
994
    int iv;
 
995
    const unsigned char *p_in;
 
996
    unsigned char *p_out = wkb;
 
997
    double coord;
 
998
        
 
999
// building from GEOS 2D WKB
 
1000
    *p_out++ = 0x01;            // little endian byte order
 
1001
    type = gaiaImport32 ( blob + 1, little_endian, endian_arch );
 
1002
    switch ( type )
 
1003
    {
 
1004
    // setting Geometry TYPE
 
1005
        case GAIA_POINT:
 
1006
            switch ( nDims )
 
1007
            {    
 
1008
                case GAIA_XY_Z_M:
 
1009
                    gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1010
                    break;
 
1011
                case GAIA_XY_Z:
 
1012
                    gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1013
                    break;
 
1014
                case GAIA_XY_M:
 
1015
                    gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1016
                    break;
 
1017
                default:
 
1018
                    gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1019
                    break;
 
1020
            }
 
1021
            break;
 
1022
        case GAIA_LINESTRING:
 
1023
            switch ( nDims )
 
1024
            {
 
1025
                case GAIA_XY_Z_M:
 
1026
                    gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1027
                    break;
 
1028
                case GAIA_XY_Z:
 
1029
                    gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1030
                    break;
 
1031
                case GAIA_XY_M:
 
1032
                    gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1033
                    break;
 
1034
                default:
 
1035
                    gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1036
                    break;
 
1037
            }
 
1038
            break;
 
1039
        case GAIA_POLYGON:
 
1040
            switch ( nDims )
 
1041
            {
 
1042
                case GAIA_XY_Z_M:
 
1043
                    gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1044
                    break;
 
1045
                case GAIA_XY_Z:
 
1046
                    gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1047
                    break;
 
1048
                case GAIA_XY_M:
 
1049
                    gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1050
                    break;
 
1051
                default:
 
1052
                    gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1053
                    break;
 
1054
            }
 
1055
            break;
 
1056
        case GAIA_MULTIPOINT:
 
1057
            switch ( nDims )
 
1058
            {
 
1059
                case GAIA_XY_Z_M:
 
1060
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTZM, 1, endian_arch);
 
1061
                    break;
 
1062
                case GAIA_XY_Z:
 
1063
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTZ, 1, endian_arch);
 
1064
                    break;
 
1065
                case GAIA_XY_M:
 
1066
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTM, 1, endian_arch);
 
1067
                    break;
 
1068
                default:
 
1069
                    gaiaExport32 ( p_out, GAIA_MULTIPOINT, 1, endian_arch);
 
1070
                    break;
 
1071
            }
 
1072
            break;
 
1073
        case GAIA_MULTILINESTRING:
 
1074
            switch ( nDims )
 
1075
            {
 
1076
                case GAIA_XY_Z_M:
 
1077
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGZM, 1, endian_arch);
 
1078
                    break;
 
1079
                case GAIA_XY_Z:
 
1080
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGZ, 1, endian_arch);
 
1081
                    break;
 
1082
                case GAIA_XY_M:
 
1083
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGM, 1, endian_arch);
 
1084
                    break;
 
1085
                default:
 
1086
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRING, 1, endian_arch);
 
1087
                    break;
 
1088
            }
 
1089
            break;
 
1090
        case GAIA_MULTIPOLYGON:
 
1091
            switch ( nDims )
 
1092
            {
 
1093
                case GAIA_XY_Z_M:
 
1094
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONZM, 1, endian_arch);
 
1095
                    break;
 
1096
                case GAIA_XY_Z:
 
1097
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONZ, 1, endian_arch);
 
1098
                    break;
 
1099
                case GAIA_XY_M:
 
1100
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONM, 1, endian_arch);
 
1101
                    break;
 
1102
                default:
 
1103
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGON, 1, endian_arch);
 
1104
                    break;
 
1105
            }
 
1106
            break;
 
1107
        case GAIA_GEOMETRYCOLLECTION:
 
1108
            switch ( nDims )
 
1109
            {
 
1110
                case GAIA_XY_Z_M:
 
1111
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONZM, 1, endian_arch);
 
1112
                    break;
 
1113
                case GAIA_XY_Z:
 
1114
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONZ, 1, endian_arch);
 
1115
                    break;
 
1116
                case GAIA_XY_M:
 
1117
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONM, 1, endian_arch);
 
1118
                    break;
 
1119
                default:
 
1120
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTION, 1, endian_arch);
 
1121
                    break;
 
1122
            }
 
1123
            break;
 
1124
    }
 
1125
    p_in = blob + 5;
 
1126
    p_out += 4;
 
1127
    switch ( type )
 
1128
    {
 
1129
    // setting Geometry values
 
1130
        case GAIA_POINT:
 
1131
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1132
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1133
            p_in += sizeof(double);
 
1134
            p_out += sizeof(double);
 
1135
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1136
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1137
            p_in += sizeof(double);
 
1138
            p_out += sizeof(double);
 
1139
            if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1140
            {
 
1141
                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
1142
                p_out += sizeof(double);
 
1143
            }
 
1144
            if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1145
            {
 
1146
                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1147
                p_out += sizeof(double);
 
1148
            }
 
1149
            break;
 
1150
        case GAIA_LINESTRING:                   
 
1151
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1152
            p_in += 4;
 
1153
            gaiaExport32 ( p_out, points, 1, endian_arch);
 
1154
            p_out += 4;
 
1155
            for ( iv = 0; iv < points; iv++ )
 
1156
            {
 
1157
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1158
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1159
                p_in += sizeof(double);
 
1160
                p_out += sizeof(double);
 
1161
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1162
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1163
                p_in += sizeof(double);
 
1164
                p_out += sizeof(double);
 
1165
                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1166
                {
 
1167
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
1168
                    p_out += sizeof(double);
 
1169
                }
 
1170
                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1171
                {
 
1172
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1173
                    p_out += sizeof(double);
 
1174
                }
 
1175
            }
 
1176
            break;
 
1177
        case GAIA_POLYGON:
 
1178
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1179
            p_in += 4;
 
1180
            gaiaExport32 ( p_out, rings, 1, endian_arch);
 
1181
            p_out += 4;
 
1182
            for ( ib = 0; ib < rings; ib++ )
 
1183
            {
 
1184
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1185
                p_in += 4;
 
1186
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
1187
                p_out += 4;
 
1188
                for ( iv = 0; iv < points; iv++ )
 
1189
                {
 
1190
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1191
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1192
                    p_in += sizeof(double);
 
1193
                    p_out += sizeof(double);
 
1194
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1195
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1196
                    p_in += sizeof(double);
 
1197
                    p_out += sizeof(double);
 
1198
                    if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1199
                    {
 
1200
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
1201
                        p_out += sizeof(double);
 
1202
                    }
 
1203
                    if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1204
                    {
 
1205
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1206
                        p_out += sizeof(double);
 
1207
                    }
 
1208
                }
 
1209
            }
 
1210
            break;
 
1211
        case GAIA_MULTIPOINT:
 
1212
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1213
            p_in += 4;
 
1214
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1215
            p_out += 4;
 
1216
            for ( ie = 0; ie < entities; ie++ )
 
1217
            {
 
1218
                p_in += 5;
 
1219
                *p_out++ = 0x01;
 
1220
                switch ( nDims )
 
1221
                {
 
1222
                    case GAIA_XY_Z_M:
 
1223
                        gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1224
                        break;
 
1225
                    case GAIA_XY_Z:
 
1226
                        gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1227
                        break;
 
1228
                    case GAIA_XY_M:
 
1229
                        gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1230
                        break;
 
1231
                    default:
 
1232
                        gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1233
                        break;
 
1234
                }
 
1235
                p_out += 4;
 
1236
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1237
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1238
                p_in += sizeof(double);
 
1239
                p_out += sizeof(double);
 
1240
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1241
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1242
                p_in += sizeof(double);
 
1243
                p_out += sizeof(double);
 
1244
                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1245
                {
 
1246
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
1247
                    p_out += sizeof(double);
 
1248
                }
 
1249
                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1250
                {
 
1251
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1252
                    p_out += sizeof(double);
 
1253
                }
 
1254
            }
 
1255
            break;
 
1256
        case GAIA_MULTILINESTRING:                      
 
1257
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1258
            p_in += 4;
 
1259
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1260
            p_out += 4;
 
1261
            for ( ie = 0; ie < entities; ie++ )
 
1262
            {
 
1263
                p_in += 5;
 
1264
                *p_out++ = 0x01;
 
1265
                switch ( nDims )
 
1266
                {
 
1267
                    case GAIA_XY_Z_M:
 
1268
                        gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1269
                        break;
 
1270
                    case GAIA_XY_Z:
 
1271
                        gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1272
                        break;
 
1273
                    case GAIA_XY_M:
 
1274
                        gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1275
                        break;
 
1276
                    default:
 
1277
                        gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1278
                        break;
 
1279
                }
 
1280
                p_out += 4;
 
1281
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1282
                p_in += 4;
 
1283
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
1284
                p_out += 4;
 
1285
                for ( iv = 0; iv < points; iv++ )
 
1286
                {
 
1287
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1288
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1289
                    p_in += sizeof(double);
 
1290
                    p_out += sizeof(double);
 
1291
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1292
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1293
                    p_in += sizeof(double);
 
1294
                    p_out += sizeof(double);
 
1295
                    if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1296
                    {
 
1297
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
1298
                        p_out += sizeof(double);
 
1299
                    }
 
1300
                    if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1301
                    {
 
1302
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1303
                        p_out += sizeof(double);
 
1304
                    }
 
1305
                }
 
1306
            }
 
1307
            break;
 
1308
        case GAIA_MULTIPOLYGON:
 
1309
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1310
            p_in += 4;
 
1311
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1312
            p_out += 4;
 
1313
            for ( ie = 0; ie < entities; ie++ )
 
1314
            {
 
1315
                p_in += 5;
 
1316
                *p_out++ = 0x01;
 
1317
                switch ( nDims )
 
1318
                {
 
1319
                    case GAIA_XY_Z_M:
 
1320
                        gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1321
                        break;
 
1322
                    case GAIA_XY_Z:
 
1323
                        gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1324
                        break;
 
1325
                    case GAIA_XY_M:
 
1326
                        gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1327
                        break;
 
1328
                    default:
 
1329
                        gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1330
                        break;
 
1331
                }
 
1332
                p_out += 4;
 
1333
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1334
                p_in += 4;
 
1335
                gaiaExport32 ( p_out, rings, 1, endian_arch);
 
1336
                p_out += 4;
 
1337
                for ( ib = 0; ib < rings; ib++ )
 
1338
                {
 
1339
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1340
                    p_in += 4;
 
1341
                    gaiaExport32 ( p_out, points, 1, endian_arch);
 
1342
                    p_out += 4;
 
1343
                    for ( iv = 0; iv < points; iv++ )
 
1344
                    {
 
1345
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1346
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1347
                        p_in += sizeof(double);
 
1348
                        p_out += sizeof(double);
 
1349
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1350
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1351
                        p_in += sizeof(double);
 
1352
                        p_out += sizeof(double);
 
1353
                        if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1354
                        {
 
1355
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
1356
                            p_out += sizeof(double);
 
1357
                        }
 
1358
                        if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1359
                        {
 
1360
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1361
                            p_out += sizeof(double);
 
1362
                        }
 
1363
                    }
 
1364
                }
 
1365
            }
 
1366
            break;
 
1367
        case GAIA_GEOMETRYCOLLECTION:
 
1368
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1369
            p_in += 4;
 
1370
            gaiaExport32 ( p_out, entities, 1, endian_arch );
 
1371
            p_out += 4;
 
1372
                        for ( ie = 0; ie < entities; ie++ )
 
1373
                        {
 
1374
                int type2 = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
1375
                p_in += 5;
 
1376
                *p_out++ = 0x01;
 
1377
                switch (type2)
 
1378
                {
 
1379
                    case GAIA_POINT:
 
1380
                        switch ( nDims )
 
1381
                        {
 
1382
                            case GAIA_XY_Z_M:
 
1383
                                gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1384
                                break;
 
1385
                            case GAIA_XY_Z:
 
1386
                                gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1387
                                break;
 
1388
                            case GAIA_XY_M:
 
1389
                                gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1390
                                break;
 
1391
                            default:
 
1392
                                gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1393
                                break;
 
1394
                        }
 
1395
                        break;
 
1396
                    case GAIA_LINESTRING:                              
 
1397
                        switch ( nDims )
 
1398
                        {
 
1399
                            case GAIA_XY_Z_M:
 
1400
                                gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1401
                                break;
 
1402
                            case GAIA_XY_Z:
 
1403
                                gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1404
                                break;
 
1405
                            case GAIA_XY_M:
 
1406
                                gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1407
                                break;
 
1408
                            default:
 
1409
                                gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1410
                                break;
 
1411
                        }
 
1412
                        break;
 
1413
                    case GAIA_POLYGON:
 
1414
                        switch ( nDims )
 
1415
                        {
 
1416
                            case GAIA_XY_Z_M:
 
1417
                                gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1418
                                break;
 
1419
                            case GAIA_XY_Z:
 
1420
                                gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1421
                                break;
 
1422
                            case GAIA_XY_M:
 
1423
                                gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1424
                                break;
 
1425
                            default:
 
1426
                                gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1427
                                break;
 
1428
                        }
 
1429
                        break;
 
1430
                }
 
1431
                p_out += 4;
 
1432
                switch ( type2 )
 
1433
                {
 
1434
                // setting sub-Geometry values
 
1435
                    case GAIA_POINT:
 
1436
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1437
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1438
                        p_in += sizeof(double);
 
1439
                        p_out += sizeof(double);
 
1440
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1441
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1442
                        p_in += sizeof(double);
 
1443
                        p_out += sizeof(double);
 
1444
                        if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1445
                        {
 
1446
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
1447
                            p_out += sizeof(double);
 
1448
                        }
 
1449
                        if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1450
                        {
 
1451
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1452
                            p_out += sizeof(double);
 
1453
                        }
 
1454
                        break;
 
1455
                    case GAIA_LINESTRING:                       
 
1456
                        points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1457
                        p_in += 4;
 
1458
                        gaiaExport32 ( p_out, points, 1, endian_arch);
 
1459
                        p_out += 4;
 
1460
                        for ( iv = 0; iv < points; iv++ )
 
1461
                        {
 
1462
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1463
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1464
                            p_in += sizeof(double);
 
1465
                            p_out += sizeof(double);
 
1466
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1467
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1468
                            p_in += sizeof(double);
 
1469
                            p_out += sizeof(double);
 
1470
                            if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1471
                            {
 
1472
                                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
1473
                                p_out += sizeof(double);
 
1474
                            }
 
1475
                            if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1476
                            {
 
1477
                                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1478
                                p_out += sizeof(double);
 
1479
                            }
 
1480
                        }
 
1481
                        break;
 
1482
                    case GAIA_POLYGON:
 
1483
                        rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1484
                        p_in += 4;
 
1485
                        gaiaExport32 ( p_out, rings, 1, endian_arch);
 
1486
                        p_out += 4;
 
1487
                        for ( ib = 0; ib < rings; ib++ )
 
1488
                        {
 
1489
                            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1490
                            p_in += 4;
 
1491
                            gaiaExport32 ( p_out, points, 1, endian_arch);
 
1492
                            p_out += 4;
 
1493
                            for ( iv = 0; iv < points; iv++ )
 
1494
                            {
 
1495
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1496
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1497
                                p_in += sizeof(double);
 
1498
                                p_out += sizeof(double);
 
1499
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1500
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1501
                                p_in += sizeof(double);
 
1502
                                p_out += sizeof(double);
 
1503
                                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1504
                                {
 
1505
                                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
1506
                                    p_out += sizeof(double);
 
1507
                                }
 
1508
                                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1509
                                {
 
1510
                                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1511
                                    p_out += sizeof(double);
 
1512
                                }
 
1513
                            }
 
1514
                        }
 
1515
                        break;
 
1516
                }
 
1517
            }
 
1518
            break;
 
1519
    }
 
1520
}
 
1521
 
 
1522
void QgsSpatiaLiteProvider::convertFromGeosWKB3D ( const unsigned char *blob, 
 
1523
                                                   size_t blob_size, 
 
1524
                                                   unsigned char *wkb, 
 
1525
                                                   size_t geom_size,  
 
1526
                                                   int nDims, 
 
1527
                                                   int little_endian, 
 
1528
                                                   int endian_arch )
 
1529
{
 
1530
// attempting to convert from 3D GEOS own WKB
 
1531
    int type;
 
1532
    int entities;
 
1533
    int rings;
 
1534
    int points;
 
1535
    int ie;
 
1536
    int ib;
 
1537
    int iv;
 
1538
    const unsigned char *p_in;
 
1539
    unsigned char *p_out = wkb;
 
1540
    double coord;
 
1541
        
 
1542
// building from GEOS 3D WKB
 
1543
    *p_out++ = 0x01;            // little endian byte order
 
1544
    type = gaiaImport32 ( blob + 1, little_endian, endian_arch );
 
1545
    switch ( type )
 
1546
    {
 
1547
    // setting Geometry TYPE
 
1548
        case GEOS_3D_POINT:
 
1549
            switch ( nDims )
 
1550
            {    
 
1551
                case GAIA_XY_Z_M:
 
1552
                    gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1553
                    break;
 
1554
                case GAIA_XY_Z:
 
1555
                    gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1556
                    break;
 
1557
                case GAIA_XY_M:
 
1558
                    gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1559
                    break;
 
1560
                default:
 
1561
                    gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1562
                    break;
 
1563
            }
 
1564
            break;
 
1565
        case GEOS_3D_LINESTRING:
 
1566
            switch ( nDims )
 
1567
            {
 
1568
                case GAIA_XY_Z_M:
 
1569
                    gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1570
                    break;
 
1571
                case GAIA_XY_Z:
 
1572
                    gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1573
                    break;
 
1574
                case GAIA_XY_M:
 
1575
                    gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1576
                    break;
 
1577
                default:
 
1578
                    gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1579
                    break;
 
1580
            }
 
1581
            break;
 
1582
        case GEOS_3D_POLYGON:
 
1583
            switch ( nDims )
 
1584
            {
 
1585
                case GAIA_XY_Z_M:
 
1586
                    gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1587
                    break;
 
1588
                case GAIA_XY_Z:
 
1589
                    gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1590
                    break;
 
1591
                case GAIA_XY_M:
 
1592
                    gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1593
                    break;
 
1594
                default:
 
1595
                    gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1596
                    break;
 
1597
            }
 
1598
            break;
 
1599
        case GEOS_3D_MULTIPOINT:
 
1600
            switch ( nDims )
 
1601
            {
 
1602
                case GAIA_XY_Z_M:
 
1603
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTZM, 1, endian_arch);
 
1604
                    break;
 
1605
                case GAIA_XY_Z:
 
1606
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTZ, 1, endian_arch);
 
1607
                    break;
 
1608
                case GAIA_XY_M:
 
1609
                    gaiaExport32 ( p_out, GAIA_MULTIPOINTM, 1, endian_arch);
 
1610
                    break;
 
1611
                default:
 
1612
                    gaiaExport32 ( p_out, GAIA_MULTIPOINT, 1, endian_arch);
 
1613
                    break;
 
1614
            }
 
1615
            break;
 
1616
        case GEOS_3D_MULTILINESTRING:
 
1617
            switch ( nDims )
 
1618
            {
 
1619
                case GAIA_XY_Z_M:
 
1620
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGZM, 1, endian_arch);
 
1621
                    break;
 
1622
                case GAIA_XY_Z:
 
1623
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGZ, 1, endian_arch);
 
1624
                    break;
 
1625
                case GAIA_XY_M:
 
1626
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRINGM, 1, endian_arch);
 
1627
                    break;
 
1628
                default:
 
1629
                    gaiaExport32 ( p_out, GAIA_MULTILINESTRING, 1, endian_arch);
 
1630
                    break;
 
1631
            }
 
1632
            break;
 
1633
        case GEOS_3D_MULTIPOLYGON:
 
1634
            switch ( nDims )
 
1635
            {
 
1636
                case GAIA_XY_Z_M:
 
1637
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONZM, 1, endian_arch);
 
1638
                    break;
 
1639
                case GAIA_XY_Z:
 
1640
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONZ, 1, endian_arch);
 
1641
                    break;
 
1642
                case GAIA_XY_M:
 
1643
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGONM, 1, endian_arch);
 
1644
                    break;
 
1645
                default:
 
1646
                    gaiaExport32 ( p_out, GAIA_MULTIPOLYGON, 1, endian_arch);
 
1647
                    break;
 
1648
            }
 
1649
            break;
 
1650
        case GEOS_3D_GEOMETRYCOLLECTION:
 
1651
            switch ( nDims )
 
1652
            {
 
1653
                case GAIA_XY_Z_M:
 
1654
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONZM, 1, endian_arch);
 
1655
                    break;
 
1656
                case GAIA_XY_Z:
 
1657
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONZ, 1, endian_arch);
 
1658
                    break;
 
1659
                case GAIA_XY_M:
 
1660
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTIONM, 1, endian_arch);
 
1661
                    break;
 
1662
                default:
 
1663
                    gaiaExport32 ( p_out, GAIA_GEOMETRYCOLLECTION, 1, endian_arch);
 
1664
                    break;
 
1665
            }
 
1666
            break;
 
1667
    }
 
1668
    p_in = blob + 5;
 
1669
    p_out += 4;
 
1670
    switch ( type )
 
1671
    {
 
1672
    // setting Geometry values
 
1673
        case GEOS_3D_POINT:
 
1674
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1675
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1676
            p_in += sizeof(double);
 
1677
            p_out += sizeof(double);
 
1678
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1679
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1680
            p_in += sizeof(double);
 
1681
            p_out += sizeof(double);
 
1682
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1683
            p_in += sizeof(double);
 
1684
            if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1685
            {
 
1686
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
1687
                p_out += sizeof(double);
 
1688
            }
 
1689
            if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1690
            {
 
1691
                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1692
                p_out += sizeof(double);
 
1693
            }
 
1694
            break;
 
1695
        case GEOS_3D_LINESTRING:                        
 
1696
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1697
            p_in += 4;
 
1698
            gaiaExport32 ( p_out, points, 1, endian_arch);
 
1699
            p_out += 4;
 
1700
            for ( iv = 0; iv < points; iv++ )
 
1701
            {
 
1702
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1703
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1704
                p_in += sizeof(double);
 
1705
                p_out += sizeof(double);
 
1706
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1707
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1708
                p_in += sizeof(double);
 
1709
                p_out += sizeof(double);
 
1710
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1711
                p_in += sizeof(double);
 
1712
                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1713
                {
 
1714
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
1715
                    p_out += sizeof(double);
 
1716
                }
 
1717
                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1718
                {
 
1719
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1720
                    p_out += sizeof(double);
 
1721
                }
 
1722
            }
 
1723
            break;
 
1724
        case GEOS_3D_POLYGON:
 
1725
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1726
            p_in += 4;
 
1727
            gaiaExport32 ( p_out, rings, 1, endian_arch);
 
1728
            p_out += 4;
 
1729
            for ( ib = 0; ib < rings; ib++ )
 
1730
            {
 
1731
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1732
                p_in += 4;
 
1733
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
1734
                p_out += 4;
 
1735
                for ( iv = 0; iv < points; iv++ )
 
1736
                {
 
1737
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1738
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1739
                    p_in += sizeof(double);
 
1740
                    p_out += sizeof(double);
 
1741
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1742
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1743
                    p_in += sizeof(double);
 
1744
                    p_out += sizeof(double);
 
1745
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1746
                    p_in += sizeof(double);
 
1747
                    if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1748
                    {
 
1749
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
1750
                        p_out += sizeof(double);
 
1751
                    }
 
1752
                    if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1753
                    {
 
1754
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1755
                        p_out += sizeof(double);
 
1756
                    }
 
1757
                }
 
1758
            }
 
1759
            break;
 
1760
        case GEOS_3D_MULTIPOINT:
 
1761
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1762
            p_in += 4;
 
1763
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1764
            p_out += 4;
 
1765
            for ( ie = 0; ie < entities; ie++ )
 
1766
            {
 
1767
                p_in += 5;
 
1768
                *p_out++ = 0x01;
 
1769
                switch ( nDims )
 
1770
                {
 
1771
                    case GAIA_XY_Z_M:
 
1772
                        gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1773
                        break;
 
1774
                    case GAIA_XY_Z:
 
1775
                        gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1776
                        break;
 
1777
                    case GAIA_XY_M:
 
1778
                        gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1779
                        break;
 
1780
                    default:
 
1781
                        gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1782
                        break;
 
1783
                }
 
1784
                p_out += 4;
 
1785
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1786
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1787
                p_in += sizeof(double);
 
1788
                p_out += sizeof(double);
 
1789
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1790
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1791
                p_in += sizeof(double);
 
1792
                p_out += sizeof(double);
 
1793
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1794
                p_in += sizeof(double);
 
1795
                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1796
                {
 
1797
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
1798
                    p_out += sizeof(double);
 
1799
                }
 
1800
                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1801
                {
 
1802
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1803
                    p_out += sizeof(double);
 
1804
                }
 
1805
            }
 
1806
            break;
 
1807
        case GEOS_3D_MULTILINESTRING:                   
 
1808
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1809
            p_in += 4;
 
1810
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1811
            p_out += 4;
 
1812
            for ( ie = 0; ie < entities; ie++ )
 
1813
            {
 
1814
                p_in += 5;
 
1815
                *p_out++ = 0x01;
 
1816
                switch ( nDims )
 
1817
                {
 
1818
                    case GAIA_XY_Z_M:
 
1819
                        gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1820
                        break;
 
1821
                    case GAIA_XY_Z:
 
1822
                        gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1823
                        break;
 
1824
                    case GAIA_XY_M:
 
1825
                        gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1826
                        break;
 
1827
                    default:
 
1828
                        gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1829
                        break;
 
1830
                }
 
1831
                p_out += 4;
 
1832
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1833
                p_in += 4;
 
1834
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
1835
                p_out += 4;
 
1836
                for ( iv = 0; iv < points; iv++ )
 
1837
                {
 
1838
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1839
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
1840
                    p_in += sizeof(double);
 
1841
                    p_out += sizeof(double);
 
1842
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1843
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
1844
                    p_in += sizeof(double);
 
1845
                    p_out += sizeof(double);
 
1846
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1847
                    p_in += sizeof(double);
 
1848
                    if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1849
                    {
 
1850
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
1851
                        p_out += sizeof(double);
 
1852
                    }
 
1853
                    if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1854
                    {
 
1855
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
1856
                        p_out += sizeof(double);
 
1857
                    }
 
1858
                }
 
1859
            }
 
1860
            break;
 
1861
        case GEOS_3D_MULTIPOLYGON:
 
1862
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1863
            p_in += 4;
 
1864
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
1865
            p_out += 4;
 
1866
            for ( ie = 0; ie < entities; ie++ )
 
1867
            {
 
1868
                p_in += 5;
 
1869
                *p_out++ = 0x01;
 
1870
                switch ( nDims )
 
1871
                {
 
1872
                    case GAIA_XY_Z_M:
 
1873
                        gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1874
                        break;
 
1875
                    case GAIA_XY_Z:
 
1876
                        gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1877
                        break;
 
1878
                    case GAIA_XY_M:
 
1879
                        gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1880
                        break;
 
1881
                    default:
 
1882
                        gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1883
                        break;
 
1884
                }
 
1885
                p_out += 4;
 
1886
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1887
                p_in += 4;
 
1888
                gaiaExport32 ( p_out, rings, 1, endian_arch);
 
1889
                p_out += 4;
 
1890
                for ( ib = 0; ib < rings; ib++ )
 
1891
                {
 
1892
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1893
                    p_in += 4;
 
1894
                    gaiaExport32 ( p_out, points, 1, endian_arch);
 
1895
                    p_out += 4;
 
1896
                    for ( iv = 0; iv < points; iv++ )
 
1897
                    {
 
1898
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1899
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1900
                        p_in += sizeof(double);
 
1901
                        p_out += sizeof(double);
 
1902
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1903
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1904
                        p_in += sizeof(double);
 
1905
                        p_out += sizeof(double);
 
1906
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1907
                        p_in += sizeof(double);
 
1908
                        if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
1909
                        {
 
1910
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
1911
                            p_out += sizeof(double);
 
1912
                        }
 
1913
                        if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
1914
                        {
 
1915
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
1916
                            p_out += sizeof(double);
 
1917
                        }
 
1918
                    }
 
1919
                }
 
1920
            }
 
1921
            break;
 
1922
        case GEOS_3D_GEOMETRYCOLLECTION:
 
1923
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
1924
            p_in += 4;
 
1925
            gaiaExport32 ( p_out, entities, 1, endian_arch );
 
1926
            p_out += 4;
 
1927
                        for ( ie = 0; ie < entities; ie++ )
 
1928
                        {
 
1929
                int type2 = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
1930
                p_in += 5;
 
1931
                *p_out++ = 0x01;
 
1932
                switch (type2)
 
1933
                {
 
1934
                    case GEOS_3D_POINT:
 
1935
                        switch ( nDims )
 
1936
                        {
 
1937
                            case GAIA_XY_Z_M:
 
1938
                                gaiaExport32 ( p_out, GAIA_POINTZM, 1, endian_arch);
 
1939
                                break;
 
1940
                            case GAIA_XY_Z:
 
1941
                                gaiaExport32 ( p_out, GAIA_POINTZ, 1, endian_arch);
 
1942
                                break;
 
1943
                            case GAIA_XY_M:
 
1944
                                gaiaExport32 ( p_out, GAIA_POINTM, 1, endian_arch);
 
1945
                                break;
 
1946
                            default:
 
1947
                                gaiaExport32 ( p_out, GAIA_POINT, 1, endian_arch);
 
1948
                                break;
 
1949
                        }
 
1950
                        break;
 
1951
                    case GEOS_3D_LINESTRING:                           
 
1952
                        switch ( nDims )
 
1953
                        {
 
1954
                            case GAIA_XY_Z_M:
 
1955
                                gaiaExport32 ( p_out, GAIA_LINESTRINGZM, 1, endian_arch);
 
1956
                                break;
 
1957
                            case GAIA_XY_Z:
 
1958
                                gaiaExport32 ( p_out, GAIA_LINESTRINGZ, 1, endian_arch);
 
1959
                                break;
 
1960
                            case GAIA_XY_M:
 
1961
                                gaiaExport32 ( p_out, GAIA_LINESTRINGM, 1, endian_arch);
 
1962
                                break;
 
1963
                            default:
 
1964
                                gaiaExport32 ( p_out, GAIA_LINESTRING, 1, endian_arch);
 
1965
                                break;
 
1966
                        }
 
1967
                        break;
 
1968
                    case GEOS_3D_POLYGON:
 
1969
                        switch ( nDims )
 
1970
                        {
 
1971
                            case GAIA_XY_Z_M:
 
1972
                                gaiaExport32 ( p_out, GAIA_POLYGONZM, 1, endian_arch);
 
1973
                                break;
 
1974
                            case GAIA_XY_Z:
 
1975
                                gaiaExport32 ( p_out, GAIA_POLYGONZ, 1, endian_arch);
 
1976
                                break;
 
1977
                            case GAIA_XY_M:
 
1978
                                gaiaExport32 ( p_out, GAIA_POLYGONM, 1, endian_arch);
 
1979
                                break;
 
1980
                            default:
 
1981
                                gaiaExport32 ( p_out, GAIA_POLYGON, 1, endian_arch);
 
1982
                                break;
 
1983
                        }
 
1984
                        break;
 
1985
                }
 
1986
                p_out += 4;
 
1987
                switch ( type2 )
 
1988
                {
 
1989
                // setting sub-Geometry values
 
1990
                    case GEOS_3D_POINT:
 
1991
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1992
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
1993
                        p_in += sizeof(double);
 
1994
                        p_out += sizeof(double);
 
1995
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
1996
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
1997
                        p_in += sizeof(double);
 
1998
                        p_out += sizeof(double);
 
1999
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2000
                        p_in += sizeof(double);
 
2001
                        if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
2002
                        {
 
2003
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2004
                            p_out += sizeof(double);
 
2005
                        }
 
2006
                        if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
2007
                        {
 
2008
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
2009
                            p_out += sizeof(double);
 
2010
                        }
 
2011
                        break;
 
2012
                    case GEOS_3D_LINESTRING:                    
 
2013
                        points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2014
                        p_in += 4;
 
2015
                        gaiaExport32 ( p_out, points, 1, endian_arch);
 
2016
                        p_out += 4;
 
2017
                        for ( iv = 0; iv < points; iv++ )
 
2018
                        {
 
2019
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2020
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2021
                            p_in += sizeof(double);
 
2022
                            p_out += sizeof(double);
 
2023
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2024
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2025
                            p_in += sizeof(double);
 
2026
                            p_out += sizeof(double);
 
2027
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2028
                            p_in += sizeof(double);
 
2029
                            if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
2030
                            {
 
2031
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2032
                                p_out += sizeof(double);
 
2033
                            }
 
2034
                            if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
2035
                            {
 
2036
                                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // M 
 
2037
                                p_out += sizeof(double);
 
2038
                            }
 
2039
                        }
 
2040
                        break;
 
2041
                    case GEOS_3D_POLYGON:
 
2042
                        rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2043
                        p_in += 4;
 
2044
                        gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2045
                        p_out += 4;
 
2046
                        for ( ib = 0; ib < rings; ib++ )
 
2047
                        {
 
2048
                            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2049
                            p_in += 4;
 
2050
                            gaiaExport32 ( p_out, points, 1, endian_arch);
 
2051
                            p_out += 4;
 
2052
                            for ( iv = 0; iv < points; iv++ )
 
2053
                            {
 
2054
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2055
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2056
                                p_in += sizeof(double);
 
2057
                                p_out += sizeof(double);
 
2058
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2059
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2060
                                p_in += sizeof(double);
 
2061
                                p_out += sizeof(double);
 
2062
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2063
                                p_in += sizeof(double);
 
2064
                                if ( nDims == GAIA_XY_Z || nDims == GAIA_XY_Z_M )
 
2065
                                {
 
2066
                                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2067
                                    p_out += sizeof(double);
 
2068
                                }
 
2069
                                if ( nDims == GAIA_XY_M || nDims == GAIA_XY_Z_M )
 
2070
                                {
 
2071
                                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // M 
 
2072
                                    p_out += sizeof(double);
 
2073
                                }
 
2074
                            }
 
2075
                        }
 
2076
                        break;
 
2077
                }
 
2078
            }
 
2079
            break;
 
2080
    }
 
2081
}
 
2082
 
 
2083
void QgsSpatiaLiteProvider::convertToGeosWKB ( const unsigned char *blob, 
 
2084
                                               size_t blob_size, 
 
2085
                                               unsigned char **wkb, 
 
2086
                                               size_t *geom_size )
 
2087
{
 
2088
// attempting to convert to 2D/3D GEOS own WKB
 
2089
    int type;
 
2090
    int dims;
 
2091
    int little_endian;
 
2092
    int endian_arch = gaiaEndianArch ();
 
2093
    int entities;
 
2094
    int rings;
 
2095
    int points;
 
2096
    int ie;
 
2097
    int ib;
 
2098
    int iv;
 
2099
    size_t gsize = 6;
 
2100
    const unsigned char *p_in;
 
2101
    unsigned char *p_out;
 
2102
    double coord;
 
2103
        
 
2104
    *wkb = NULL;
 
2105
    *geom_size = 0;
 
2106
    if ( blob_size < 5 )
 
2107
        return;
 
2108
    if ( *( blob + 0 ) == 0x01 )
 
2109
        little_endian = GAIA_LITTLE_ENDIAN;
 
2110
    else
 
2111
        little_endian = GAIA_BIG_ENDIAN;
 
2112
    type = gaiaImport32 ( blob + 1, little_endian, endian_arch );
 
2113
    if (type == GAIA_POINTZ || type == GAIA_LINESTRINGZ 
 
2114
        || type == GAIA_POLYGONZ
 
2115
        || type == GAIA_MULTIPOINTZ || type == GAIA_MULTILINESTRINGZ
 
2116
        || type == GAIA_MULTIPOLYGONZ || type == GAIA_GEOMETRYCOLLECTIONZ)
 
2117
        dims = 3;
 
2118
    else if (type == GAIA_POINTM || type == GAIA_LINESTRINGM
 
2119
        || type == GAIA_POLYGONM || type == GAIA_MULTIPOINTM
 
2120
        || type == GAIA_MULTILINESTRINGM || type == GAIA_MULTIPOLYGONM
 
2121
        || type == GAIA_GEOMETRYCOLLECTIONM)
 
2122
        dims = 3;
 
2123
    else if (type == GAIA_POINTZM || type == GAIA_LINESTRINGZM
 
2124
        || type == GAIA_POLYGONZM || type == GAIA_MULTIPOINTZM
 
2125
        || type == GAIA_MULTILINESTRINGZM || type == GAIA_MULTIPOLYGONZM
 
2126
        || type == GAIA_GEOMETRYCOLLECTIONZM)
 
2127
        dims = 4;
 
2128
    else if (type == GAIA_POINT || type == GAIA_LINESTRING
 
2129
        || type == GAIA_POLYGON || type == GAIA_MULTIPOINT
 
2130
        || type == GAIA_MULTILINESTRING || type == GAIA_MULTIPOLYGON
 
2131
        || type == GAIA_GEOMETRYCOLLECTION)
 
2132
        dims = 2;
 
2133
    else
 
2134
        return;
 
2135
                
 
2136
    if ( dims == 2 )
 
2137
    {
 
2138
    // already 2D: simply copying is required
 
2139
        unsigned char *wkbGeom = new unsigned char[blob_size + 1];
 
2140
        memset( wkbGeom, '\0', blob_size + 1 );
 
2141
        memcpy( wkbGeom, blob, blob_size );
 
2142
        *wkb = wkbGeom;
 
2143
        *geom_size = blob_size + 1;
 
2144
        return;
 
2145
    }
 
2146
        
 
2147
// we need creating a 3D GEOS WKB
 
2148
    p_in = blob + 5;
 
2149
    switch ( type )
 
2150
    {
 
2151
    // compunting the required size
 
2152
        case GAIA_POINTZ:
 
2153
        case GAIA_POINTM: 
 
2154
        case GAIA_POINTZM:
 
2155
            gsize += 3 * sizeof(double);
 
2156
            break;
 
2157
        case GAIA_LINESTRINGZ:
 
2158
        case GAIA_LINESTRINGM:
 
2159
        case GAIA_LINESTRINGZM:
 
2160
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2161
            gsize += 4;
 
2162
            gsize += points * ( 3 * sizeof(double) );
 
2163
            break;
 
2164
        case GAIA_POLYGONZ:
 
2165
        case GAIA_POLYGONM:
 
2166
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2167
            p_in += 4;
 
2168
            gsize += 4;
 
2169
            for ( ib = 0; ib < rings; ib++ )
 
2170
            {
 
2171
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2172
                p_in += 4;
 
2173
                gsize += 4;
 
2174
                gsize += points * ( 3 * sizeof(double) );
 
2175
                p_in += points * ( 3 * sizeof(double) );
 
2176
            }
 
2177
            break;
 
2178
        case GAIA_POLYGONZM:
 
2179
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2180
            p_in += 4;
 
2181
            gsize += 4;
 
2182
            for ( ib = 0; ib < rings; ib++ )
 
2183
            {
 
2184
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2185
                p_in += 4;
 
2186
                gsize += 4;
 
2187
                gsize += points * ( 3 * sizeof(double) );
 
2188
                p_in += points * ( 4 * sizeof(double) );
 
2189
            }
 
2190
            break;
 
2191
        default:
 
2192
            gsize += computeMultiWKB3Dsize( p_in, little_endian, endian_arch );
 
2193
            break;
 
2194
    }
 
2195
 
 
2196
    unsigned char *wkbGeom = new unsigned char[gsize];
 
2197
    memset( wkbGeom, '\0', gsize );
 
2198
        
 
2199
// building GEOS 3D WKB
 
2200
    *wkbGeom = 0x01;            // little endian byte order
 
2201
    type = gaiaImport32 ( blob + 1, little_endian, endian_arch );
 
2202
    switch ( type )
 
2203
    {
 
2204
    // setting Geometry TYPE
 
2205
        case GAIA_POINTZ:
 
2206
        case GAIA_POINTM: 
 
2207
        case GAIA_POINTZM:
 
2208
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_POINT, 1, endian_arch);
 
2209
            break;
 
2210
        case GAIA_LINESTRINGZ:
 
2211
        case GAIA_LINESTRINGM:
 
2212
        case GAIA_LINESTRINGZM:                 
 
2213
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_LINESTRING, 1, endian_arch);
 
2214
            break;
 
2215
        case GAIA_POLYGONZ:
 
2216
        case GAIA_POLYGONM:
 
2217
        case GAIA_POLYGONZM:
 
2218
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_POLYGON, 1, endian_arch);
 
2219
            break;
 
2220
        case GAIA_MULTIPOINTZ:
 
2221
        case GAIA_MULTIPOINTM: 
 
2222
        case GAIA_MULTIPOINTZM:
 
2223
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_MULTIPOINT, 1, endian_arch);
 
2224
            break;
 
2225
        case GAIA_MULTILINESTRINGZ:
 
2226
        case GAIA_MULTILINESTRINGM:
 
2227
        case GAIA_MULTILINESTRINGZM:                    
 
2228
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_MULTILINESTRING, 1, endian_arch);
 
2229
            break;
 
2230
        case GAIA_MULTIPOLYGONZ:
 
2231
        case GAIA_MULTIPOLYGONM:
 
2232
        case GAIA_MULTIPOLYGONZM:
 
2233
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_MULTIPOLYGON, 1, endian_arch);
 
2234
            break;
 
2235
        case GAIA_GEOMETRYCOLLECTIONZ:
 
2236
        case GAIA_GEOMETRYCOLLECTIONM:
 
2237
        case GAIA_GEOMETRYCOLLECTIONZM:
 
2238
            gaiaExport32 ( wkbGeom + 1, GEOS_3D_GEOMETRYCOLLECTION, 1, endian_arch);
 
2239
            break;
 
2240
    }
 
2241
    p_in = blob + 5;
 
2242
    p_out = wkbGeom + 5;
 
2243
    switch ( type )
 
2244
    {
 
2245
    // setting Geometry values
 
2246
        case GAIA_POINTM:
 
2247
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2248
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2249
            p_in += sizeof(double);
 
2250
            p_out += sizeof(double);
 
2251
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2252
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2253
            p_in += sizeof(double);
 
2254
            p_out += sizeof(double);
 
2255
            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
2256
            p_in += sizeof(double);
 
2257
            p_out += sizeof(double);
 
2258
            break;
 
2259
        case GAIA_POINTZ:
 
2260
        case GAIA_POINTZM:
 
2261
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2262
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2263
            p_in += sizeof(double);
 
2264
            p_out += sizeof(double);
 
2265
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2266
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2267
            p_in += sizeof(double);
 
2268
            p_out += sizeof(double);
 
2269
            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2270
            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2271
            p_in += sizeof(double);
 
2272
            p_out += sizeof(double);
 
2273
            if (type == GAIA_POINTZM)
 
2274
                p_in += sizeof(double);
 
2275
            break;
 
2276
        case GAIA_LINESTRINGM:                  
 
2277
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2278
            p_in += 4;
 
2279
            gaiaExport32 ( p_out, points, 1, endian_arch);
 
2280
            p_out += 4;
 
2281
            for ( iv = 0; iv < points; iv++ )
 
2282
            {
 
2283
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2284
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2285
                p_in += sizeof(double);
 
2286
                p_out += sizeof(double);
 
2287
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2288
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2289
                p_in += sizeof(double);
 
2290
                p_out += sizeof(double);
 
2291
                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
2292
                p_in += sizeof(double);
 
2293
                p_out += sizeof(double);
 
2294
            }
 
2295
            break;
 
2296
        case GAIA_LINESTRINGZ:
 
2297
        case GAIA_LINESTRINGZM:                 
 
2298
            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2299
            p_in += 4;
 
2300
            gaiaExport32 ( p_out, points, 1, endian_arch);
 
2301
            p_out += 4;
 
2302
            for ( iv = 0; iv < points; iv++ )
 
2303
            {
 
2304
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2305
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2306
                p_in += sizeof(double);
 
2307
                p_out += sizeof(double);
 
2308
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2309
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2310
                p_in += sizeof(double);
 
2311
                p_out += sizeof(double);
 
2312
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2313
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2314
                p_in += sizeof(double);
 
2315
                p_out += sizeof(double);
 
2316
                if (type == GAIA_LINESTRINGZM)
 
2317
                    p_in += sizeof(double);
 
2318
            }
 
2319
            break;
 
2320
        case GAIA_POLYGONM:
 
2321
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2322
            p_in += 4;
 
2323
            gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2324
            p_out += 4;
 
2325
            for ( ib = 0; ib < rings; ib++ )
 
2326
            {
 
2327
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2328
                p_in += 4;
 
2329
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
2330
                p_out += 4;
 
2331
                for ( iv = 0; iv < points; iv++ )
 
2332
                {
 
2333
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2334
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2335
                    p_in += sizeof(double);
 
2336
                    p_out += sizeof(double);
 
2337
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2338
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2339
                    p_in += sizeof(double);
 
2340
                    p_out += sizeof(double);
 
2341
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
2342
                    p_in += sizeof(double);
 
2343
                    p_out += sizeof(double);
 
2344
                }
 
2345
            }
 
2346
            break;
 
2347
        case GAIA_POLYGONZ:
 
2348
        case GAIA_POLYGONZM:
 
2349
            rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2350
            p_in += 4;
 
2351
            gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2352
            p_out += 4;
 
2353
            for ( ib = 0; ib < rings; ib++ )
 
2354
            {
 
2355
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2356
                p_in += 4;
 
2357
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
2358
                p_out += 4;
 
2359
                for ( iv = 0; iv < points; iv++ )
 
2360
                {
 
2361
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2362
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2363
                    p_in += sizeof(double);
 
2364
                    p_out += sizeof(double);
 
2365
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2366
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2367
                    p_in += sizeof(double);
 
2368
                    p_out += sizeof(double);
 
2369
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2370
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2371
                    p_in += sizeof(double);
 
2372
                    p_out += sizeof(double);
 
2373
                    if (type == GAIA_POLYGONZM)
 
2374
                        p_in += sizeof(double);
 
2375
                }
 
2376
            }
 
2377
            break;
 
2378
        case GAIA_MULTIPOINTM:
 
2379
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2380
            p_in += 4;
 
2381
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2382
            p_out += 4;
 
2383
            for ( ie = 0; ie < entities; ie++ )
 
2384
            {
 
2385
                p_in += 5;
 
2386
                *p_out++ = 0x01;
 
2387
                gaiaExport32 ( p_out, GEOS_3D_POINT, 1, endian_arch);
 
2388
                p_out += 4;
 
2389
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2390
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2391
                p_in += sizeof(double);
 
2392
                p_out += sizeof(double);
 
2393
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2394
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2395
                p_in += sizeof(double);
 
2396
                p_out += sizeof(double);
 
2397
                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
2398
                p_in += sizeof(double);
 
2399
                p_out += sizeof(double);
 
2400
            }
 
2401
            break; 
 
2402
        case GAIA_MULTIPOINTZ:
 
2403
        case GAIA_MULTIPOINTZM:
 
2404
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2405
            p_in += 4;
 
2406
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2407
            p_out += 4;
 
2408
            for ( ie = 0; ie < entities; ie++ )
 
2409
            {
 
2410
                p_in += 5;
 
2411
                *p_out++ = 0x01;
 
2412
                gaiaExport32 ( p_out, GEOS_3D_POINT, 1, endian_arch);
 
2413
                p_out += 4;
 
2414
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2415
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2416
                p_in += sizeof(double);
 
2417
                p_out += sizeof(double);
 
2418
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2419
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2420
                p_in += sizeof(double);
 
2421
                p_out += sizeof(double);
 
2422
                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2423
                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2424
                p_in += sizeof(double);
 
2425
                p_out += sizeof(double);
 
2426
                if (type == GAIA_MULTIPOINTZM)
 
2427
                    p_in += sizeof(double);
 
2428
            }
 
2429
            break;
 
2430
        case GAIA_MULTILINESTRINGM:                     
 
2431
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2432
            p_in += 4;
 
2433
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2434
            p_out += 4;
 
2435
            for ( ie = 0; ie < entities; ie++ )
 
2436
            {
 
2437
                p_in += 5;
 
2438
                *p_out++ = 0x01;
 
2439
                gaiaExport32 ( p_out, GEOS_3D_LINESTRING, 1, endian_arch);
 
2440
                p_out += 4;
 
2441
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2442
                p_in += 4;
 
2443
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
2444
                p_out += 4;
 
2445
                for ( iv = 0; iv < points; iv++ )
 
2446
                {
 
2447
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2448
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2449
                    p_in += sizeof(double);
 
2450
                    p_out += sizeof(double);
 
2451
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2452
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2453
                    p_in += sizeof(double);
 
2454
                    p_out += sizeof(double);
 
2455
                    gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
2456
                    p_in += sizeof(double);
 
2457
                    p_out += sizeof(double);
 
2458
                }
 
2459
            }
 
2460
            break;
 
2461
        case GAIA_MULTILINESTRINGZ:
 
2462
        case GAIA_MULTILINESTRINGZM:                    
 
2463
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2464
            p_in += 4;
 
2465
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2466
            p_out += 4;
 
2467
            for ( ie = 0; ie < entities; ie++ )
 
2468
            {
 
2469
                p_in += 5;
 
2470
                *p_out++ = 0x01;
 
2471
                gaiaExport32 ( p_out, GEOS_3D_LINESTRING, 1, endian_arch);
 
2472
                p_out += 4;
 
2473
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2474
                p_in += 4;
 
2475
                gaiaExport32 ( p_out, points, 1, endian_arch);
 
2476
                p_out += 4;
 
2477
                for ( iv = 0; iv < points; iv++ )
 
2478
                {
 
2479
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2480
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2481
                    p_in += sizeof(double);
 
2482
                    p_out += sizeof(double);
 
2483
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2484
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2485
                    p_in += sizeof(double);
 
2486
                    p_out += sizeof(double);
 
2487
                    coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2488
                    gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2489
                    p_in += sizeof(double);
 
2490
                    p_out += sizeof(double);
 
2491
                    if (type == GAIA_MULTILINESTRINGZM)
 
2492
                        p_in += sizeof(double);
 
2493
                }
 
2494
            }
 
2495
            break;
 
2496
        case GAIA_MULTIPOLYGONM:
 
2497
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2498
            p_in += 4;
 
2499
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2500
            p_out += 4;
 
2501
            for ( ie = 0; ie < entities; ie++ )
 
2502
            {
 
2503
                p_in += 5;
 
2504
                *p_out++ = 0x01;
 
2505
                gaiaExport32 ( p_out, GEOS_3D_POLYGON, 1, endian_arch);
 
2506
                p_out += 4;
 
2507
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2508
                p_in += 4;
 
2509
                gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2510
                p_out += 4;
 
2511
                for ( ib = 0; ib < rings; ib++ )
 
2512
                {
 
2513
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2514
                    p_in += 4;
 
2515
                    gaiaExport32 ( p_out, points, 1, endian_arch);
 
2516
                    p_out += 4;
 
2517
                    for ( iv = 0; iv < points; iv++ )
 
2518
                    {
 
2519
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2520
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2521
                        p_in += sizeof(double);
 
2522
                        p_out += sizeof(double);
 
2523
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2524
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2525
                        p_in += sizeof(double);
 
2526
                        p_out += sizeof(double);
 
2527
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
2528
                        p_in += sizeof(double);
 
2529
                        p_out += sizeof(double);
 
2530
                    }
 
2531
                }
 
2532
            }
 
2533
            break;
 
2534
        case GAIA_MULTIPOLYGONZ:
 
2535
        case GAIA_MULTIPOLYGONZM:
 
2536
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2537
            p_in += 4;
 
2538
            gaiaExport32 ( p_out, entities, 1, endian_arch);
 
2539
            p_out += 4;
 
2540
            for ( ie = 0; ie < entities; ie++ )
 
2541
            {
 
2542
                p_in += 5;
 
2543
                *p_out++ = 0x01;
 
2544
                gaiaExport32 ( p_out, GEOS_3D_POLYGON, 1, endian_arch);
 
2545
                p_out += 4;
 
2546
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2547
                p_in += 4;
 
2548
                gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2549
                p_out += 4;
 
2550
                for ( ib = 0; ib < rings; ib++ )
 
2551
                {
 
2552
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2553
                    p_in += 4;
 
2554
                    gaiaExport32 ( p_out, points, 1, endian_arch);
 
2555
                    p_out += 4;
 
2556
                    for ( iv = 0; iv < points; iv++ )
 
2557
                    {
 
2558
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2559
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2560
                        p_in += sizeof(double);
 
2561
                        p_out += sizeof(double);
 
2562
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2563
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2564
                        p_in += sizeof(double);
 
2565
                        p_out += sizeof(double);
 
2566
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2567
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2568
                        p_in += sizeof(double);
 
2569
                        p_out += sizeof(double);
 
2570
                        if (type == GAIA_MULTIPOLYGONZM)
 
2571
                            p_in += sizeof(double);
 
2572
                    }
 
2573
                }
 
2574
            }
 
2575
            break;
 
2576
        case GAIA_GEOMETRYCOLLECTIONM:
 
2577
        case GAIA_GEOMETRYCOLLECTIONZ:
 
2578
        case GAIA_GEOMETRYCOLLECTIONZM:
 
2579
            entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2580
            p_in += 4;
 
2581
            gaiaExport32 ( p_out, entities, 1, endian_arch );
 
2582
            p_out += 4;
 
2583
                        for ( ie = 0; ie < entities; ie++ )
 
2584
                        {
 
2585
                int type2 = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
2586
                p_in += 5;
 
2587
                *p_out++ = 0x01;
 
2588
                switch (type2)
 
2589
                {
 
2590
                    case GAIA_POINTZ:
 
2591
                    case GAIA_POINTM: 
 
2592
                    case GAIA_POINTZM:
 
2593
                        gaiaExport32 ( p_out, GEOS_3D_POINT, 1, endian_arch);
 
2594
                        break;
 
2595
                    case GAIA_LINESTRINGZ:
 
2596
                    case GAIA_LINESTRINGM:
 
2597
                    case GAIA_LINESTRINGZM:                     
 
2598
                        gaiaExport32 ( p_out, GEOS_3D_LINESTRING, 1, endian_arch);
 
2599
                        break;
 
2600
                    case GAIA_POLYGONZ:
 
2601
                    case GAIA_POLYGONM:
 
2602
                    case GAIA_POLYGONZM:
 
2603
                        gaiaExport32 ( p_out, GEOS_3D_POLYGON, 1, endian_arch);
 
2604
                        break;
 
2605
                }
 
2606
                p_out += 4;
 
2607
                switch ( type2 )
 
2608
                {
 
2609
                // setting sub-Geometry values
 
2610
                    case GAIA_POINTM:
 
2611
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2612
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2613
                        p_in += sizeof(double);
 
2614
                        p_out += sizeof(double);
 
2615
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2616
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2617
                        p_in += sizeof(double);
 
2618
                        p_out += sizeof(double);
 
2619
                        gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
2620
                        p_in += sizeof(double);
 
2621
                        p_out += sizeof(double);
 
2622
                        break;
 
2623
                    case GAIA_POINTZ:
 
2624
                    case GAIA_POINTZM:
 
2625
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2626
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2627
                        p_in += sizeof(double);
 
2628
                        p_out += sizeof(double);
 
2629
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2630
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2631
                        p_in += sizeof(double);
 
2632
                        p_out += sizeof(double);
 
2633
                        coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2634
                        gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2635
                        p_in += sizeof(double);
 
2636
                        p_out += sizeof(double);
 
2637
                        if (type2 == GAIA_POINTZM)
 
2638
                            p_in += sizeof(double);
 
2639
                        break;
 
2640
                    case GAIA_LINESTRINGM:                      
 
2641
                        points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2642
                        p_in += 4;
 
2643
                        gaiaExport32 ( p_out, points, 1, endian_arch);
 
2644
                        p_out += 4;
 
2645
                        for ( iv = 0; iv < points; iv++ )
 
2646
                        {
 
2647
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2648
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2649
                            p_in += sizeof(double);
 
2650
                            p_out += sizeof(double);
 
2651
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2652
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2653
                            p_in += sizeof(double);
 
2654
                            p_out += sizeof(double);
 
2655
                            gaiaExport64 ( p_out, 0.0, 1, endian_arch );        // Z 
 
2656
                            p_in += sizeof(double);
 
2657
                            p_out += sizeof(double);
 
2658
                        }
 
2659
                        break;
 
2660
                    case GAIA_LINESTRINGZ:
 
2661
                    case GAIA_LINESTRINGZM:                     
 
2662
                        points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2663
                        p_in += 4;
 
2664
                        gaiaExport32 ( p_out, points, 1, endian_arch);
 
2665
                        p_out += 4;
 
2666
                        for ( iv = 0; iv < points; iv++ )
 
2667
                        {
 
2668
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2669
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // X 
 
2670
                            p_in += sizeof(double);
 
2671
                            p_out += sizeof(double);
 
2672
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2673
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Y 
 
2674
                            p_in += sizeof(double);
 
2675
                            p_out += sizeof(double);
 
2676
                            coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2677
                            gaiaExport64 ( p_out, coord, 1, endian_arch );      // Z 
 
2678
                            p_in += sizeof(double);
 
2679
                            p_out += sizeof(double);
 
2680
                            if (type2 == GAIA_LINESTRINGZM)
 
2681
                                p_in += sizeof(double);
 
2682
                        }
 
2683
                        break;
 
2684
                    case GAIA_POLYGONM:
 
2685
                        rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2686
                        p_in += 4;
 
2687
                        gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2688
                        p_out += 4;
 
2689
                        for ( ib = 0; ib < rings; ib++ )
 
2690
                        {
 
2691
                            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2692
                            p_in += 4;
 
2693
                            gaiaExport32 ( p_out, points, 1, endian_arch);
 
2694
                            p_out += 4;
 
2695
                            for ( iv = 0; iv < points; iv++ )
 
2696
                            {
 
2697
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2698
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2699
                                p_in += sizeof(double);
 
2700
                                p_out += sizeof(double);
 
2701
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2702
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2703
                                p_in += sizeof(double);
 
2704
                                p_out += sizeof(double);
 
2705
                                gaiaExport64 ( p_out, 0.0, 1, endian_arch );    // Z 
 
2706
                                p_in += sizeof(double);
 
2707
                                p_out += sizeof(double);
 
2708
                            }
 
2709
                        }
 
2710
                        break;
 
2711
                    case GAIA_POLYGONZ:
 
2712
                    case GAIA_POLYGONZM:
 
2713
                        rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2714
                        p_in += 4;
 
2715
                        gaiaExport32 ( p_out, rings, 1, endian_arch);
 
2716
                        p_out += 4;
 
2717
                        for ( ib = 0; ib < rings; ib++ )
 
2718
                        {
 
2719
                            points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2720
                            p_in += 4;
 
2721
                            gaiaExport32 ( p_out, points, 1, endian_arch);
 
2722
                            p_out += 4;
 
2723
                            for ( iv = 0; iv < points; iv++ )
 
2724
                            {
 
2725
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2726
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // X 
 
2727
                                p_in += sizeof(double);
 
2728
                                p_out += sizeof(double);
 
2729
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2730
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Y 
 
2731
                                p_in += sizeof(double);
 
2732
                                p_out += sizeof(double);
 
2733
                                coord = gaiaImport64 ( p_in, little_endian, endian_arch );
 
2734
                                gaiaExport64 ( p_out, coord, 1, endian_arch );  // Z 
 
2735
                                p_in += sizeof(double);
 
2736
                                p_out += sizeof(double);
 
2737
                                if (type2 == GAIA_POLYGONZM)
 
2738
                                    p_in += sizeof(double);
 
2739
                            }
 
2740
                        }
 
2741
                        break;
 
2742
                }
 
2743
            }
 
2744
            break;
 
2745
    }
 
2746
 
 
2747
    *wkb = wkbGeom;
 
2748
    *geom_size = gsize;
 
2749
}
 
2750
 
 
2751
int QgsSpatiaLiteProvider::computeMultiWKB3Dsize( const unsigned char *p_in, int little_endian, int endian_arch )
 
2752
{
 
2753
// computing the required size to store a GEOS 3D MultiXX
 
2754
    int entities;
 
2755
    int type;
 
2756
    int rings;
 
2757
    int points;
 
2758
    int ie;
 
2759
    int ib;
 
2760
    int size = 0;
 
2761
        
 
2762
    entities = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2763
    p_in += 4;
 
2764
    size += 4;
 
2765
    for ( ie = 0; ie < entities; ie++ )
 
2766
    {
 
2767
        type = gaiaImport32 ( p_in + 1, little_endian, endian_arch );
 
2768
        p_in += 5;
 
2769
        size += 5;
 
2770
        switch ( type )
 
2771
        {
 
2772
        // compunting the required size
 
2773
            case GAIA_POINTZ:
 
2774
            case GAIA_POINTM: 
 
2775
                size += 3 * sizeof(double);
 
2776
                p_in += 3 * sizeof(double);
 
2777
                break;
 
2778
            case GAIA_POINTZM:
 
2779
                size += 3 * sizeof(double);
 
2780
                p_in += 4 * sizeof(double);
 
2781
                break;
 
2782
            case GAIA_LINESTRINGZ:
 
2783
            case GAIA_LINESTRINGM:
 
2784
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2785
                p_in += 4;
 
2786
                size += 4;
 
2787
                size += points * ( 3 * sizeof(double) );
 
2788
                p_in += points * ( 3 * sizeof(double) );
 
2789
                break;
 
2790
            case GAIA_LINESTRINGZM:
 
2791
                points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2792
                p_in += 4;
 
2793
                size += 4;
 
2794
                size += points * ( 3 * sizeof(double) );
 
2795
                p_in += points * ( 4 * sizeof(double) );
 
2796
                break;
 
2797
            case GAIA_POLYGONZ:
 
2798
            case GAIA_POLYGONM:
 
2799
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2800
                p_in += 4;
 
2801
                size += 4;
 
2802
                for ( ib = 0; ib < rings; ib++ )
 
2803
                {
 
2804
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2805
                    p_in += 4;
 
2806
                    size += 4;
 
2807
                    size += points * ( 3 * sizeof(double) );
 
2808
                    p_in += points * ( 3 * sizeof(double) );
 
2809
                }
 
2810
                break;
 
2811
            case GAIA_POLYGONZM:
 
2812
                rings = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2813
                p_in += 4;
 
2814
                size += 4;
 
2815
                for ( ib = 0; ib < rings; ib++ )
 
2816
                {
 
2817
                    points = gaiaImport32 ( p_in, little_endian, endian_arch );
 
2818
                    p_in += 4;
 
2819
                    size += 4;
 
2820
                    size += points * ( 3 * sizeof(double) );
 
2821
                    p_in += points * ( 4 * sizeof(double) );
 
2822
                }
 
2823
                break;
 
2824
        }
 
2825
    }
 
2826
 
 
2827
    return size;
 
2828
}
 
2829
 
474
2830
QString QgsSpatiaLiteProvider::subsetString()
475
2831
{
476
2832
  return mSubsetString;
477
2833
}
478
2834
 
479
 
bool QgsSpatiaLiteProvider::setSubsetString( QString theSQL )
 
2835
bool QgsSpatiaLiteProvider::setSubsetString( QString theSQL, bool updateFeatureCount )
480
2836
{
481
2837
  QString prevSubsetString = mSubsetString;
482
2838
  mSubsetString = theSQL;
487
2843
  setDataSourceUri( uri.uri() );
488
2844
 
489
2845
  // update feature count and extents
490
 
  if ( getTableSummary() )
 
2846
  if ( updateFeatureCount && getTableSummary() )
 
2847
  {
491
2848
    return true;
 
2849
  }
492
2850
 
493
2851
  mSubsetString = prevSubsetString;
494
2852
 
508
2866
 
509
2867
  if ( !valid )
510
2868
  {
511
 
    QgsLogger::critical( "Read attempt on an invalid SpatiaLite data source" );
 
2869
    QgsDebugMsg( "Read attempt on an invalid SpatiaLite data source" );
512
2870
    return;
513
2871
  }
514
2872
 
519
2877
    sqliteStatement = NULL;
520
2878
  }
521
2879
 
522
 
  QString sql = "SELECT ROWID";
 
2880
  QString primaryKey = !isQuery ? "ROWID" : quotedIdentifier( mPrimaryKey );
 
2881
 
 
2882
  QString sql = QString( "SELECT %1" ).arg( primaryKey );
523
2883
  for ( QgsAttributeList::const_iterator it = fetchAttributes.constBegin(); it != fetchAttributes.constEnd(); ++it )
524
2884
  {
525
2885
    const QgsField & fld = field( *it );
526
2886
    const QString & fieldname = fld.name();
527
 
    sql += ", \"";
528
 
    sql += fieldname;
529
 
    sql += "\"";
 
2887
    sql += "," + quotedIdentifier( fieldname );
530
2888
  }
531
2889
  if ( fetchGeometry )
532
2890
  {
533
 
    sql += QString( ", AsBinary(\"%1\")" ).arg( mGeometryColumn );
 
2891
    sql += QString( ", AsBinary(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
534
2892
  }
535
 
  sql += QString( " FROM \"%1\"" ).arg( mTableName );
 
2893
  sql += QString( " FROM %1" ).arg( mQuery );
536
2894
 
537
2895
  QString whereClause;
538
2896
 
547
2905
                    arg( QString::number( rect.xMinimum(), 'f', 6 ) ).
548
2906
                    arg( QString::number( rect.yMinimum(), 'f', 6 ) ).
549
2907
                    arg( QString::number( rect.xMaximum(), 'f', 6 ) ).arg( QString::number( rect.yMaximum(), 'f', 6 ) );
550
 
      whereClause += QString( "Intersects(\"%1\", BuildMbr(%2)) AND " ).arg( mGeometryColumn ).arg( mbr );
 
2908
      whereClause += QString( "Intersects(%1, BuildMbr(%2)) AND " ).arg( quotedIdentifier( mGeometryColumn ) ).arg( mbr );
551
2909
    }
552
2910
    if ( mVShapeBased )
553
2911
    {
556
2914
                    arg( QString::number( rect.xMinimum(), 'f', 6 ) ).
557
2915
                    arg( QString::number( rect.yMinimum(), 'f', 6 ) ).
558
2916
                    arg( QString::number( rect.xMaximum(), 'f', 6 ) ).arg( QString::number( rect.yMaximum(), 'f', 6 ) );
559
 
      whereClause += QString( "MbrIntersects(\"%1\", BuildMbr(%2))" ).arg( mGeometryColumn ).arg( mbr );
 
2917
      whereClause += QString( "MbrIntersects(%1, BuildMbr(%2))" ).arg( quotedIdentifier( mGeometryColumn ) ).arg( mbr );
560
2918
    }
561
2919
    else
562
2920
    {
568
2926
        mbrFilter += QString( "ymin <= %1 AND " ).arg( QString::number( rect.yMaximum(), 'f', 6 ) );
569
2927
        mbrFilter += QString( "ymax >= %1" ).arg( QString::number( rect.yMinimum(), 'f', 6 ) );
570
2928
        QString idxName = QString( "idx_%1_%2" ).arg( mIndexTable ).arg( mIndexGeometry );
571
 
        whereClause += QString( "ROWID IN (SELECT pkid FROM \"%1\" WHERE %2)" ).arg( idxName ).arg( mbrFilter );
 
2929
        whereClause += QString( "%1 IN (SELECT pkid FROM %2 WHERE %3)" )
 
2930
                       .arg( quotedIdentifier( primaryKey ) )
 
2931
                       .arg( quotedIdentifier( idxName ) )
 
2932
                       .arg( mbrFilter );
572
2933
      }
573
2934
      else if ( spatialIndexMbrCache )
574
2935
      {
578
2939
                      arg( QString::number( rect.yMinimum(), 'f', 6 ) ).
579
2940
                      arg( QString::number( rect.xMaximum(), 'f', 6 ) ).arg( QString::number( rect.yMaximum(), 'f', 6 ) );
580
2941
        QString idxName = QString( "cache_%1_%2" ).arg( mIndexTable ).arg( mIndexGeometry );
581
 
        whereClause += QString( "ROWID IN (SELECT rowid FROM \"%1\" WHERE mbr = FilterMbrIntersects(%2))" ).arg( idxName ).arg( mbr );
 
2942
        whereClause += QString( "%1 IN (SELECT rowid FROM %2 WHERE mbr = FilterMbrIntersects(%3))" )
 
2943
                       .arg( quotedIdentifier( primaryKey ) )
 
2944
                       .arg( quotedIdentifier( idxName ) )
 
2945
                       .arg( mbr );
582
2946
      }
583
2947
      else
584
2948
      {
587
2951
                      arg( QString::number( rect.xMinimum(), 'f', 6 ) ).
588
2952
                      arg( QString::number( rect.yMinimum(), 'f', 6 ) ).
589
2953
                      arg( QString::number( rect.xMaximum(), 'f', 6 ) ).arg( QString::number( rect.yMaximum(), 'f', 6 ) );
590
 
        whereClause += QString( "MbrIntersects(\"%1\", BuildMbr(%2))" ).arg( mGeometryColumn ).arg( mbr );
 
2954
        whereClause += QString( "MbrIntersects(%1, BuildMbr(%2))" ).arg( quotedIdentifier( mGeometryColumn ) ).arg( mbr );
591
2955
      }
592
2956
    }
593
2957
  }
613
2977
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &sqliteStatement, NULL ) != SQLITE_OK )
614
2978
  {
615
2979
    // some error occurred
616
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
617
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
618
 
    QgsLogger::critical( msg );
 
2980
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
619
2981
    sqliteStatement = NULL;
620
2982
  }
621
2983
}
712
3074
  // get the field name
713
3075
  const QgsField & fld = field( index );
714
3076
 
715
 
  QString sql = QString( "SELECT Min(\"%1\") FROM \"%2\"" ).arg( fld.name() ).arg( mTableName );
 
3077
  QString sql = QString( "SELECT Min(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );
716
3078
 
717
3079
  if ( !mSubsetString.isEmpty() )
718
3080
  {
740
3102
  }
741
3103
  else
742
3104
  {
743
 
    // returning as DOUBLE
744
 
    return minValue.toDouble();
 
3105
    return convertValue( fld.type(), minValue );
745
3106
  }
746
3107
 
747
3108
error:
748
3109
  // unexpected error
749
3110
  if ( errMsg != NULL )
750
3111
  {
751
 
    QString error = "minValue() SQL error: ";
752
 
    error = errMsg;
753
 
    QgsLogger::critical( error );
 
3112
    QgsDebugMsg( QString( "SQL error: %1" ).arg( QString::fromUtf8( errMsg ) ) );
754
3113
    sqlite3_free( errMsg );
755
3114
  }
756
3115
  return QVariant( QString::null );
770
3129
  // get the field name
771
3130
  const QgsField & fld = field( index );
772
3131
 
773
 
  QString sql = QString( "SELECT Max(\"%1\") FROM \"%2\"" ).arg( fld.name() ).arg( mTableName );
 
3132
  QString sql = QString( "SELECT Max(%1) FROM %2" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );
774
3133
 
775
3134
  if ( !mSubsetString.isEmpty() )
776
3135
  {
798
3157
  }
799
3158
  else
800
3159
  {
801
 
    // returning as DOUBLE
802
 
    return maxValue.toDouble();
 
3160
    return convertValue( fld.type(), maxValue );
803
3161
  }
804
3162
 
805
3163
error:
806
3164
  // unexpected error
807
3165
  if ( errMsg != NULL )
808
3166
  {
809
 
    QString error = "maxValue() SQL error: ";
810
 
    error = errMsg;
811
 
    QgsLogger::critical( error );
 
3167
    QgsDebugMsg( QString( "SQL error: %1" ).arg( QString::fromUtf8( errMsg ) ) );
812
3168
    sqlite3_free( errMsg );
813
3169
  }
814
3170
  return QVariant( QString::null );
818
3174
void QgsSpatiaLiteProvider::uniqueValues( int index, QList < QVariant > &uniqueValues, int limit )
819
3175
{
820
3176
  sqlite3_stmt *stmt = NULL;
821
 
  char *errMsg = NULL;
822
3177
  QString sql;
823
3178
  QString txt;
824
3179
 
825
3180
  uniqueValues.clear();
826
3181
 
827
3182
  // get the field name
828
 
  const QgsField & fld = field( index );
 
3183
  QgsFieldMap::const_iterator fieldIt = attributeFields.find( index );
 
3184
  if ( fieldIt == attributeFields.constEnd() )
 
3185
  {
 
3186
    return; //invalid field
 
3187
  }
 
3188
  const QgsField& fld = fieldIt.value();
829
3189
 
830
 
  sql = QString( "SELECT DISTINCT \"%1\" FROM \"%2\" ORDER BY \"%1\"" ).arg( fld.name() ).arg( mTableName );
 
3190
  sql = QString( "SELECT DISTINCT %1 FROM %2 ORDER BY %1" ).arg( quotedIdentifier( fld.name() ) ).arg( mQuery );
831
3191
 
832
3192
  if ( !mSubsetString.isEmpty() )
833
3193
  {
843
3203
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
844
3204
  {
845
3205
    // some error occurred
846
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
847
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
848
 
    QgsLogger::critical( msg );
 
3206
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
849
3207
    return;
850
3208
  }
851
3209
 
881
3239
    }
882
3240
    else
883
3241
    {
884
 
      // some unexpected error occurred
885
 
      const char *err = sqlite3_errmsg( sqliteHandle );
886
 
      int len = strlen( err );
887
 
      errMsg = ( char * ) sqlite3_malloc( len + 1 );
888
 
      strcpy( errMsg, err );
889
 
      goto abort;
 
3242
      QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
 
3243
      sqlite3_finalize( stmt );
 
3244
      return;
890
3245
    }
891
3246
  }
 
3247
 
892
3248
  sqlite3_finalize( stmt );
893
3249
 
894
3250
  return;
895
 
 
896
 
abort:
897
 
  QString msg = QString( "getUniqueValues SQL error:\n%1\n" ).arg( sql );
898
 
  if ( errMsg )
899
 
  {
900
 
    msg += errMsg;
901
 
    sqlite3_free( errMsg );
902
 
  }
903
 
  else
904
 
    msg += "unknown cause";
905
 
  QgsLogger::critical( msg );
906
3251
}
907
3252
 
908
3253
bool QgsSpatiaLiteProvider::addFeatures( QgsFeatureList & flist )
928
3273
 
929
3274
  if ( !mPrimaryKey.isEmpty() )
930
3275
  {
931
 
    sql = QString( "INSERT INTO \"%1\" (\"%2\", \"%3\"" ).
932
 
          arg( mTableName ).arg( mPrimaryKey ).arg( mGeometryColumn );
933
 
    values = QString( ") VALUES (NULL, GeomFromWKB(?, %1)" ).arg( mSrid );
 
3276
    sql = QString( "INSERT INTO %1(%2,%3" )
 
3277
          .arg( quotedIdentifier( mTableName ) )
 
3278
          .arg( quotedIdentifier( mPrimaryKey ) )
 
3279
          .arg( quotedIdentifier( mGeometryColumn ) );
 
3280
    values = QString( ") VALUES (NULL, GeomFromWKB(?,%1)" ).arg( mSrid );
934
3281
  }
935
3282
  else
936
3283
  {
937
 
    sql = QString( "INSERT INTO \"%1\" (\"%2\"" ).arg( mTableName ).arg( mGeometryColumn );
 
3284
    sql = QString( "INSERT INTO %1(%2" )
 
3285
          .arg( quotedIdentifier( mTableName ) )
 
3286
          .arg( quotedIdentifier( mGeometryColumn ) );
938
3287
    values = QString( ") VALUES (GeomFromWKB(?, %1)" ).arg( mSrid );
939
3288
  }
940
3289
 
948
3297
    if ( fieldname.isEmpty() || fieldname == mGeometryColumn || fieldname == mPrimaryKey )
949
3298
      continue;
950
3299
 
951
 
    sql += ", \"";
952
 
    sql += fieldname;
953
 
    sql += "\"";
954
 
    values += ", ?";
 
3300
    sql += "," + quotedIdentifier( fieldname );
 
3301
    values += ",?";
955
3302
  }
956
3303
 
957
3304
  sql += values;
961
3308
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
962
3309
  {
963
3310
    // some error occurred
964
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
965
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
966
 
    QgsLogger::critical( msg );
 
3311
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( sqlite3_errmsg( sqliteHandle ) ) );
967
3312
    return false;
968
3313
  }
969
3314
 
977
3322
    sqlite3_clear_bindings( stmt );
978
3323
 
979
3324
    // binding GEOMETRY to Prepared Statement
980
 
    const unsigned char *wkb = features->geometry()->asWkb();
981
 
    sqlite3_bind_blob( stmt, 1, wkb, features->geometry()->wkbSize(), SQLITE_STATIC );
 
3325
    unsigned char *wkb = NULL;
 
3326
    size_t wkb_size;
 
3327
    convertFromGeosWKB ( features->geometry()->asWkb(), 
 
3328
                         features->geometry()->wkbSize(), 
 
3329
                         &wkb, &wkb_size, nDims );
 
3330
    if (wkb == NULL )
 
3331
        sqlite3_bind_null( stmt, 1 );
 
3332
    else
 
3333
        sqlite3_bind_blob( stmt, 1, wkb, wkb_size, free );
982
3334
 
983
3335
    // initializing the column counter
984
3336
    ia = 1;
1014
3366
      else if ( type == QVariant::String )
1015
3367
      {
1016
3368
        // binding a TEXT value
1017
 
        QString txt = it->toString();
1018
 
        int len = txt.toUtf8().length() + 1;
1019
 
        char *vl = new char [len];
1020
 
        strcpy( vl, txt.toUtf8().constData() );
1021
 
        sqlite3_bind_text( stmt, ++ia, vl, len, SQLITE_TRANSIENT );
1022
 
        delete [] vl;
 
3369
        QByteArray ba = it->toString().toUtf8();
 
3370
        sqlite3_bind_text( stmt, ++ia, ba.constData(), ba.size(), SQLITE_TRANSIENT );
1023
3371
      }
1024
3372
      else
1025
3373
      {
1057
3405
  return true;
1058
3406
 
1059
3407
abort:
1060
 
  QString msg = QString( "addFeatures SQL error:\n%1\n" ).arg( sql );
 
3408
  QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1061
3409
  if ( errMsg )
1062
3410
  {
1063
 
    msg += errMsg;
1064
3411
    sqlite3_free( errMsg );
1065
3412
  }
1066
 
  else
1067
 
    msg += "unknown cause";
1068
 
  QgsLogger::critical( msg );
1069
3413
 
1070
3414
  if ( toCommit )
1071
3415
  {
1091
3435
  }
1092
3436
  toCommit = true;
1093
3437
 
1094
 
  sql = QString( "DELETE FROM \"%1\" WHERE ROWID = ?" ).arg( mTableName );
 
3438
  sql = QString( "DELETE FROM %1 WHERE ROWID=?" ).arg( quotedIdentifier( mTableName ) );
1095
3439
 
1096
3440
  // SQLite prepared statement
1097
3441
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
1098
3442
  {
1099
3443
    // some error occurred
1100
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
1101
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
1102
 
    QgsLogger::critical( msg );
 
3444
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
1103
3445
    return false;
1104
3446
  }
1105
3447
 
1140
3482
  return true;
1141
3483
 
1142
3484
abort:
1143
 
  QString msg = QString( "deleteFeatures SQL error:\n%1\n" ).arg( sql );
 
3485
  QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1144
3486
  if ( errMsg )
1145
3487
  {
1146
 
    msg += errMsg;
1147
3488
    sqlite3_free( errMsg );
1148
3489
  }
1149
 
  else
1150
 
    msg += "unknown cause";
1151
 
  QgsLogger::critical( msg );
1152
3490
 
1153
3491
  if ( toCommit )
1154
3492
  {
1194
3532
    goto abort;
1195
3533
  }
1196
3534
 
 
3535
  // reload columns
 
3536
  rewind();
 
3537
 
1197
3538
  return true;
1198
3539
 
1199
3540
abort:
1200
 
  QString msg = QString( "addAttributes SQL error:\n%1\n" ).arg( sql );
 
3541
  QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1201
3542
  if ( errMsg )
1202
3543
  {
1203
 
    msg += errMsg;
1204
3544
    sqlite3_free( errMsg );
1205
3545
  }
1206
 
  else
1207
 
    msg += "unknown cause";
1208
 
  QgsLogger::critical( msg );
1209
3546
 
1210
3547
  if ( toCommit )
1211
3548
  {
1238
3575
    if ( fid < 0 )
1239
3576
      continue;
1240
3577
 
1241
 
    QString sql = QString( "UPDATE \"%1\" SET " ).arg( mTableName );
 
3578
    QString sql = QString( "UPDATE %1 SET " ).arg( quotedIdentifier( mTableName ) );
1242
3579
    bool first = true;
1243
3580
 
1244
3581
    const QgsAttributeMap & attrs = iter.value();
1263
3600
      if ( type == QVariant::Invalid )
1264
3601
      {
1265
3602
        // binding a NULL value
1266
 
        sql += QString( "\"%1\"=NULL" ).arg( fieldName );
 
3603
        sql += QString( "%1=NULL" ).arg( quotedIdentifier( fieldName ) );
1267
3604
      }
1268
3605
      else if ( type == QVariant::Int || type == QVariant::Double )
1269
3606
      {
1270
3607
        // binding a NUMERIC value
1271
 
        sql += QString( "\"%1\"=%2" ).arg( fieldName ).arg( siter->toString() );
 
3608
        sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( siter->toString() );
1272
3609
      }
1273
3610
      else
1274
3611
      {
1275
3612
        // binding a TEXT value
1276
 
        sql += QString( "\"%1\"=%2" ).arg( fieldName ).arg( quotedValue( siter->toString() ) );
 
3613
        sql += QString( "%1=%2" ).arg( quotedIdentifier( fieldName ) ).arg( quotedValue( siter->toString() ) );
1277
3614
      }
1278
3615
    }
1279
3616
    sql += QString( " WHERE ROWID=%1" ).arg( fid );
1296
3633
  return true;
1297
3634
 
1298
3635
abort:
1299
 
  QString msg = QString( "changeAttributeValues SQL error:\n%1\n" ).arg( sql );
 
3636
  QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1300
3637
  if ( errMsg )
1301
3638
  {
1302
 
    msg += errMsg;
1303
3639
    sqlite3_free( errMsg );
1304
3640
  }
1305
 
  else
1306
 
    msg += "unknown cause";
1307
 
  QgsLogger::critical( msg );
1308
3641
 
1309
3642
  if ( toCommit )
1310
3643
  {
1331
3664
  toCommit = true;
1332
3665
 
1333
3666
  sql =
1334
 
    QString( "UPDATE \"%1\" SET \"%2\" = GeomFromWKB(?, %3) WHERE ROWID = ?" ).
1335
 
    arg( mTableName ).arg( mGeometryColumn ).arg( mSrid );
 
3667
    QString( "UPDATE %1 SET %2=GeomFromWKB(?, %3) WHERE ROWID = ?" )
 
3668
    .arg( quotedIdentifier( mTableName ) )
 
3669
    .arg( quotedIdentifier( mGeometryColumn ) )
 
3670
    .arg( mSrid );
1336
3671
 
1337
3672
  // SQLite prepared statement
1338
3673
  if ( sqlite3_prepare_v2( sqliteHandle, sql.toUtf8().constData(), -1, &stmt, NULL ) != SQLITE_OK )
1339
3674
  {
1340
3675
    // some error occurred
1341
 
    QString errCause = sqlite3_errmsg( sqliteHandle );
1342
 
    QString msg = tr( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( errCause );
1343
 
    QgsLogger::critical( msg );
 
3676
    QgsDebugMsg( QString( "SQLite error: %1\n\nSQL: %2" ).arg( sql ).arg( QString::fromUtf8( sqlite3_errmsg( sqliteHandle ) ) ) );
1344
3677
    return false;
1345
3678
  }
1346
3679
 
1355
3688
      sqlite3_clear_bindings( stmt );
1356
3689
 
1357
3690
      // binding GEOMETRY to Prepared Statement
1358
 
      const unsigned char *wkb = iter->asWkb();
1359
 
      sqlite3_bind_blob( stmt, 1, wkb, iter->wkbSize(), SQLITE_STATIC );
 
3691
      unsigned char *wkb = NULL;
 
3692
      size_t wkb_size;
 
3693
      convertFromGeosWKB ( iter->asWkb(), iter->wkbSize(), &wkb, &wkb_size, 
 
3694
                           nDims );
 
3695
      if (wkb == NULL )
 
3696
          sqlite3_bind_null( stmt, 1 );
 
3697
      else
 
3698
          sqlite3_bind_blob( stmt, 1, wkb, wkb_size, free );
1360
3699
      sqlite3_bind_int( stmt, 2, iter.key() );
1361
3700
 
1362
3701
      // performing actual row update
1386
3725
  return true;
1387
3726
 
1388
3727
abort:
1389
 
  QString msg = QString( "addFeatures SQL error:\n%1\n" ).arg( sql );
 
3728
  QgsDebugMsg( QString( "SQL error:\n%1\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1390
3729
  if ( errMsg )
1391
3730
  {
1392
 
    msg += errMsg;
1393
3731
    sqlite3_free( errMsg );
1394
3732
  }
1395
 
  else
1396
 
    msg += "unknown cause";
1397
 
  QgsLogger::critical( msg );
1398
3733
 
1399
3734
  if ( toCommit )
1400
3735
  {
1467
3802
  if ( sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE, NULL ) )
1468
3803
  {
1469
3804
    // failure
1470
 
 
1471
 
    QString errCause = sqlite3_errmsg( sqlite_handle );
1472
 
    QString msg = tr( "Failure while connecting to: %1\n\n%2" ).arg( dbPath ).arg( errCause );
1473
 
    QgsLogger::critical( msg );
 
3805
    QgsDebugMsg( QString( "Failure while connecting to: %1\n%2" )
 
3806
                 .arg( dbPath )
 
3807
                 .arg( QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) ) ) );
1474
3808
    return NULL;
1475
3809
  }
1476
3810
 
1477
3811
  // checking the DB for sanity
1478
 
  if ( checkMetadata( sqlite_handle ) == false )
 
3812
  if ( !checkMetadata( sqlite_handle ) )
1479
3813
  {
1480
3814
    // failure
1481
 
 
1482
 
    QString errCause = tr( "invalid metadata tables" );
1483
 
    QString msg = tr( "Failure while connecting to: %1\n\n%2" ).arg( dbPath ).arg( errCause );
1484
 
    QgsLogger::critical( msg );
 
3815
    QgsDebugMsg( QString( "Failure while connecting to: %1\n\ninvalid metadata tables" ).arg( dbPath ) );
1485
3816
    sqlite3_close( sqlite_handle );
1486
3817
    return NULL;
1487
3818
  }
1507
3838
  for ( i = handles.begin(); i != handles.end() && i.value() != handle; i++ )
1508
3839
    ;
1509
3840
 
1510
 
  assert( i.value() == handle );
1511
 
  assert( i.value()->ref > 0 );
 
3841
  Q_ASSERT( i.value() == handle );
 
3842
  Q_ASSERT( i.value()->ref > 0 );
1512
3843
 
1513
3844
  if ( --i.value()->ref == 0 )
1514
3845
  {
1529
3860
  }
1530
3861
}
1531
3862
 
 
3863
QString QgsSpatiaLiteProvider::quotedIdentifier( QString id ) const
 
3864
{
 
3865
  id.replace( "\"", "\"\"" );
 
3866
  return id.prepend( "\"" ).append( "\"" );
 
3867
}
 
3868
 
1532
3869
QString QgsSpatiaLiteProvider::quotedValue( QString value ) const
1533
3870
{
1534
3871
  if ( value.isNull() )
1551
3888
  mTableBased = false;
1552
3889
  mViewBased = false;
1553
3890
  mVShapeBased = false;
 
3891
  isQuery = false;
1554
3892
 
1555
3893
// checking if this one is a Table-based layer
1556
3894
  QString sql = QString( "SELECT read_only FROM geometry_columns "
1557
3895
                         "LEFT JOIN geometry_columns_auth "
1558
3896
                         "USING (f_table_name, f_geometry_column) "
1559
 
                         "WHERE f_table_name=%1 and f_geometry_column=%2" ).arg( quotedValue( mTableName ) ).
1560
 
                arg( quotedValue( mGeometryColumn ) );
 
3897
                         "WHERE f_table_name=%1 and f_geometry_column=%2" )
 
3898
                .arg( quotedValue( mTableName ) )
 
3899
                .arg( quotedValue( mGeometryColumn ) );
1561
3900
 
1562
3901
  ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
1563
3902
  if ( ret != SQLITE_OK )
1564
 
    goto error;
1565
 
  if ( rows < 1 )
1566
 
    ;
1567
 
  else
 
3903
  {
 
3904
    if ( errMsg && strcmp( errMsg, "no such table: geometry_columns_auth" ) == 0 )
 
3905
    {
 
3906
      sqlite3_free( errMsg );
 
3907
      sql = QString( "SELECT 0 FROM geometry_columns WHERE f_table_name=%1 and f_geometry_column=%2" )
 
3908
            .arg( quotedValue( mTableName ) )
 
3909
            .arg( quotedValue( mGeometryColumn ) );
 
3910
      ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
 
3911
    }
 
3912
  }
 
3913
  if ( ret == SQLITE_OK && rows == 1 )
1568
3914
  {
1569
3915
    mTableBased = true;
1570
3916
    mReadOnly = false;
1578
3924
    }
1579
3925
    count++;
1580
3926
  }
 
3927
  if ( errMsg )
 
3928
  {
 
3929
    QgsDebugMsg( QString( "sqlite error %1 [%2]" ).arg( sql ).arg( errMsg ) );
 
3930
    sqlite3_free( errMsg );
 
3931
    errMsg = 0;
 
3932
  }
1581
3933
  sqlite3_free_table( results );
1582
3934
 
1583
3935
// checking if this one is a View-based layer
1586
3938
        arg( quotedValue( mGeometryColumn ) );
1587
3939
 
1588
3940
  ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
1589
 
  if ( ret != SQLITE_OK )
1590
 
    goto error;
1591
 
  if ( rows < 1 )
1592
 
    ;
1593
 
  else
 
3941
  if ( ret == SQLITE_OK && rows == 1 )
1594
3942
  {
1595
3943
    mViewBased = true;
1596
3944
    mReadOnly = true;
1597
3945
    count++;
1598
3946
  }
 
3947
  if ( errMsg )
 
3948
  {
 
3949
    QgsDebugMsg( QString( "sqlite error %1 [%2]" ).arg( sql ).arg( errMsg ) );
 
3950
    sqlite3_free( errMsg );
 
3951
    errMsg = 0;
 
3952
  }
1599
3953
  sqlite3_free_table( results );
1600
3954
 
1601
3955
// checking if this one is a VirtualShapefile-based layer
1604
3958
        arg( quotedValue( mGeometryColumn ) );
1605
3959
 
1606
3960
  ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
1607
 
  if ( ret != SQLITE_OK )
1608
 
    goto error;
1609
 
  if ( rows < 1 )
1610
 
    ;
1611
 
  else
 
3961
  if ( ret == SQLITE_OK && rows == 1 )
1612
3962
  {
1613
3963
    mVShapeBased = true;
1614
3964
    mReadOnly = true;
1615
3965
    count++;
1616
3966
  }
 
3967
  if ( errMsg )
 
3968
  {
 
3969
    QgsDebugMsg( QString( "sqlite error %1 [%2]" ).arg( sql ).arg( errMsg ) );
 
3970
    sqlite3_free( errMsg );
 
3971
    errMsg = 0;
 
3972
  }
1617
3973
  sqlite3_free_table( results );
1618
3974
 
1619
 
// cheching for validity
1620
 
  if ( count != 1 )
1621
 
    return false;
1622
 
 
1623
 
  return true;
1624
 
 
1625
 
error:
1626
 
  // unexpected error
1627
 
  if ( errMsg != NULL )
1628
 
  {
1629
 
    QString errCause = errMsg;
1630
 
    QString msg = QString( "checkLayerType SQL error: %1\n\n%2" ).arg( sql ).arg( errCause );
1631
 
    QgsLogger::critical( msg );
1632
 
    sqlite3_free( errMsg );
1633
 
  }
1634
 
  return false;
 
3975
  // checking if this one is a select query
 
3976
  if ( mQuery.startsWith( "(select", Qt::CaseInsensitive ) &&
 
3977
       mQuery.endsWith( ")" ) )
 
3978
  {
 
3979
    // get a new alias for the subquery
 
3980
    int index = 0;
 
3981
    QString alias;
 
3982
    QRegExp regex;
 
3983
    do
 
3984
    {
 
3985
      alias = QString( "subQuery_%1" ).arg( QString::number( index++ ) );
 
3986
      QString pattern = QString( "(\\\"?)%1\\1" ).arg( QRegExp::escape( alias ) );
 
3987
      regex.setPattern( pattern );
 
3988
      regex.setCaseSensitivity( Qt::CaseInsensitive );
 
3989
    }
 
3990
    while ( mQuery.contains( regex ) );
 
3991
 
 
3992
    // convert the custom query into a subquery
 
3993
    mQuery = QString( "%1 as %2" )
 
3994
             .arg( mQuery )
 
3995
             .arg( quotedIdentifier( alias ) );
 
3996
 
 
3997
    sql = QString( "SELECT 0 FROM %1 LIMIT 1" ).arg( mQuery );
 
3998
    ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
 
3999
    if ( ret == SQLITE_OK && rows == 1 )
 
4000
    {
 
4001
      isQuery = true;
 
4002
      mReadOnly = true;
 
4003
      count++;
 
4004
    }
 
4005
    if ( errMsg )
 
4006
    {
 
4007
      QgsDebugMsg( QString( "sqlite error %1 [%2]" ).arg( sql ).arg( errMsg ) );
 
4008
      sqlite3_free( errMsg );
 
4009
      errMsg = 0;
 
4010
    }
 
4011
    sqlite3_free_table( results );
 
4012
  }
 
4013
  else
 
4014
  {
 
4015
    mQuery = quotedIdentifier( mTableName );
 
4016
  }
 
4017
 
 
4018
// checking for validity
 
4019
  return count == 1;
1635
4020
}
1636
4021
 
1637
4022
bool QgsSpatiaLiteProvider::getGeometryDetails()
1643
4028
    ret = getViewGeometryDetails();
1644
4029
  if ( mVShapeBased )
1645
4030
    ret = getVShapeGeometryDetails();
 
4031
  if ( isQuery )
 
4032
    ret = getQueryGeometryDetails();
1646
4033
  return ret;
1647
4034
}
1648
4035
 
1658
4045
  mIndexTable = mTableName;
1659
4046
  mIndexGeometry = mGeometryColumn;
1660
4047
 
1661
 
  QString sql = QString( "SELECT type, srid, spatial_index_enabled FROM geometry_columns"
 
4048
  QString sql = QString( "SELECT type, srid, spatial_index_enabled, coord_dimension FROM geometry_columns"
1662
4049
                         " WHERE f_table_name=%1 and f_geometry_column=%2" ).arg( quotedValue( mTableName ) ).
1663
4050
                arg( quotedValue( mGeometryColumn ) );
1664
4051
 
1674
4061
      QString fType = results[( i * columns ) + 0];
1675
4062
      QString xSrid = results[( i * columns ) + 1];
1676
4063
      QString spatialIndex = results[( i * columns ) + 2];
 
4064
      QString dims = results[( i * columns ) + 3];
1677
4065
 
1678
4066
      if ( fType == "POINT" )
1679
4067
      {
1708
4096
      {
1709
4097
        spatialIndexMbrCache = true;
1710
4098
      }
 
4099
      if ( dims == "XY" || dims == "2" )
 
4100
      {
 
4101
        nDims = GAIA_XY;
 
4102
      }
 
4103
      else if ( dims == "XYZ" || dims == "3" )
 
4104
      {
 
4105
        nDims = GAIA_XY_Z;
 
4106
      }
 
4107
      else if ( dims == "XYM" )
 
4108
      {
 
4109
        nDims = GAIA_XY_M;
 
4110
      }
 
4111
      else if ( dims == "XYZM" )
 
4112
      {
 
4113
        nDims = GAIA_XY_Z_M;
 
4114
      }
1711
4115
 
1712
4116
    }
1713
4117
  }
1722
4126
  // unexpected error
1723
4127
  if ( errMsg != NULL )
1724
4128
  {
1725
 
    QString errCause = errMsg;
1726
 
    QString msg = QString( "getTableGeometryDetails SQL error: %1\n\n%2" ).arg( sql ).arg( errCause );
1727
 
    QgsLogger::critical( msg );
 
4129
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1728
4130
    sqlite3_free( errMsg );
1729
4131
  }
1730
4132
  return false;
1807
4209
  // unexpected error
1808
4210
  if ( errMsg != NULL )
1809
4211
  {
1810
 
    QString errCause = errMsg;
1811
 
    QString msg = QString( "getViewGeometryDetails SQL error: %1\n\n%2" ).arg( sql ).arg( errCause );
1812
 
    QgsLogger::critical( msg );
 
4212
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1813
4213
    sqlite3_free( errMsg );
1814
4214
  }
1815
4215
  return false;
1879
4279
  // unexpected error
1880
4280
  if ( errMsg != NULL )
1881
4281
  {
1882
 
    QString errCause = errMsg;
1883
 
    QString msg = QString( "getVShapeGeometryDetails SQL error: %1\n\n%2" ).arg( sql ).arg( errCause );
1884
 
    QgsLogger::critical( msg );
 
4282
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
 
4283
    sqlite3_free( errMsg );
 
4284
  }
 
4285
  return false;
 
4286
}
 
4287
 
 
4288
bool QgsSpatiaLiteProvider::getQueryGeometryDetails()
 
4289
{
 
4290
  int ret;
 
4291
  int i;
 
4292
  char **results;
 
4293
  int rows;
 
4294
  int columns;
 
4295
  char *errMsg = NULL;
 
4296
 
 
4297
  QString fType( "" );
 
4298
  QString xSrid( "" );
 
4299
 
 
4300
  // get stuff from the relevant column instead. This may (will?)
 
4301
  // fail if there is no data in the relevant table.
 
4302
  QString sql = QString( "select srid(%1), geometrytype(%1) from %2" )
 
4303
                .arg( quotedIdentifier( mGeometryColumn ) )
 
4304
                .arg( mQuery );
 
4305
 
 
4306
  //it is possible that the where clause restricts the feature type
 
4307
  if ( !mSubsetString.isEmpty() )
 
4308
  {
 
4309
    sql += " WHERE " + mSubsetString;
 
4310
  }
 
4311
 
 
4312
  sql += " limit 1";
 
4313
 
 
4314
  ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
 
4315
  if ( ret != SQLITE_OK )
 
4316
    goto error;
 
4317
  if ( rows < 1 )
 
4318
    ;
 
4319
  else
 
4320
  {
 
4321
    for ( i = 1; i <= rows; i++ )
 
4322
    {
 
4323
      xSrid = results[( i * columns ) + 0];
 
4324
      fType = results[( i * columns ) + 1];
 
4325
    }
 
4326
  }
 
4327
  sqlite3_free_table( results );
 
4328
 
 
4329
  if ( !xSrid.isEmpty() && !fType.isEmpty() )
 
4330
  {
 
4331
    if ( fType == "GEOMETRY" )
 
4332
    {
 
4333
      // check to see if there is a unique geometry type
 
4334
      sql = QString( "select distinct "
 
4335
                     "case"
 
4336
                     " when geometrytype(%1) IN ('POINT','MULTIPOINT') THEN 'POINT'"
 
4337
                     " when geometrytype(%1) IN ('LINESTRING','MULTILINESTRING') THEN 'LINESTRING'"
 
4338
                     " when geometrytype(%1) IN ('POLYGON','MULTIPOLYGON') THEN 'POLYGON'"
 
4339
                     " end "
 
4340
                     "from %2" )
 
4341
            .arg( quotedIdentifier( mGeometryColumn ) )
 
4342
            .arg( mQuery );
 
4343
 
 
4344
      if ( !mSubsetString.isEmpty() )
 
4345
        sql += " where " + mSubsetString;
 
4346
 
 
4347
      ret = sqlite3_get_table( sqliteHandle, sql.toUtf8().constData(), &results, &rows, &columns, &errMsg );
 
4348
      if ( ret != SQLITE_OK )
 
4349
        goto error;
 
4350
      if ( rows != 1 )
 
4351
        ;
 
4352
      else
 
4353
      {
 
4354
        for ( i = 1; i <= rows; i++ )
 
4355
        {
 
4356
          fType = results[( 1 * columns ) + 0];
 
4357
        }
 
4358
      }
 
4359
      sqlite3_free_table( results );
 
4360
    }
 
4361
 
 
4362
    if ( fType == "POINT" )
 
4363
    {
 
4364
      geomType = QGis::WKBPoint;
 
4365
    }
 
4366
    else if ( fType == "MULTIPOINT" )
 
4367
    {
 
4368
      geomType = QGis::WKBMultiPoint;
 
4369
    }
 
4370
    else if ( fType == "LINESTRING" )
 
4371
    {
 
4372
      geomType = QGis::WKBLineString;
 
4373
    }
 
4374
    else if ( fType == "MULTILINESTRING" )
 
4375
    {
 
4376
      geomType = QGis::WKBMultiLineString;
 
4377
    }
 
4378
    else if ( fType == "POLYGON" )
 
4379
    {
 
4380
      geomType = QGis::WKBPolygon;
 
4381
    }
 
4382
    else if ( fType == "MULTIPOLYGON" )
 
4383
    {
 
4384
      geomType = QGis::WKBMultiPolygon;
 
4385
    }
 
4386
    mSrid = xSrid.toInt();
 
4387
  }
 
4388
 
 
4389
  if ( geomType == QGis::WKBUnknown || mSrid < 0 )
 
4390
    goto error;
 
4391
 
 
4392
  return getSridDetails();
 
4393
 
 
4394
error:
 
4395
  // unexpected error
 
4396
  if ( errMsg != NULL )
 
4397
  {
 
4398
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1885
4399
    sqlite3_free( errMsg );
1886
4400
  }
1887
4401
  return false;
1918
4432
  // unexpected error
1919
4433
  if ( errMsg != NULL )
1920
4434
  {
1921
 
    QString errCause = errMsg;
1922
 
    QString msg = QString( "getSridDetails SQL error: %1\n\n%2" ).arg( sql ).arg( errCause );
1923
 
    QgsLogger::critical( msg );
 
4435
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1924
4436
    sqlite3_free( errMsg );
1925
4437
  }
1926
4438
  return false;
1935
4447
  int columns;
1936
4448
  char *errMsg = NULL;
1937
4449
 
1938
 
  QString sql = QString( "SELECT Min(MbrMinX(\"%1\")), Min(MbrMinY(\"%1\")), "
1939
 
                         "Max(MbrMaxX(\"%1\")), Max(MbrMaxY(\"%1\")), Count(*) " "FROM \"%2\"" ).arg( mGeometryColumn ).arg( mTableName );
 
4450
  QString sql = QString( "SELECT Min(MbrMinX(%1)), Min(MbrMinY(%1)), "
 
4451
                         "Max(MbrMaxX(%1)), Max(MbrMaxY(%1)), Count(*) " "FROM %2" )
 
4452
                .arg( quotedIdentifier( mGeometryColumn ) )
 
4453
                .arg( mQuery );
1940
4454
 
1941
4455
  if ( !mSubsetString.isEmpty() )
1942
4456
  {
1969
4483
  // unexpected error
1970
4484
  if ( errMsg != NULL )
1971
4485
  {
1972
 
    QString error = "getTableSummary() SQL error: ";
1973
 
    error = errMsg;
1974
 
    QgsLogger::critical( error );
 
4486
    QgsDebugMsg( QString( "SQL error: %1\n\n%2" ).arg( sql ).arg( errMsg ? QString::fromUtf8( errMsg ) : "unknown cause" ) );
1975
4487
    sqlite3_free( errMsg );
1976
4488
  }
1977
4489
  return false;
1983
4495
 
1984
4496
  if ( it == attributeFields.constEnd() )
1985
4497
  {
1986
 
    QgsLogger::critical( "Field " + QString::number( index ) + " not found." );
 
4498
    QgsDebugMsg( QString( "Field %1 not found." ).arg( index ) );
1987
4499
  }
1988
4500
 
1989
4501
  return it.value();