26
26
27
27
QgsSpatialRefSys::QgsSpatialRefSys () : mMapUnits(QGis::UNKNOWN) {}
28
28
29
- QgsSpatialRefSys::QgsSpatialRefSys (QString theWkt) : mMapUnits(QGis::UNKNOWN)
29
+ QgsSpatialRefSys::QgsSpatialRefSys (QString theWkt) : mMapUnits(QGis::UNKNOWN)
30
30
{
31
31
createFromWkt (theWkt);
32
32
}
@@ -39,10 +39,10 @@ QgsSpatialRefSys::QgsSpatialRefSys(long theSrsId,
39
39
long theSRID,
40
40
long theEpsg,
41
41
bool theGeoFlag)
42
- : mMapUnits(QGis::UNKNOWN)
42
+ : mMapUnits(QGis::UNKNOWN)
43
43
{}
44
44
45
- QgsSpatialRefSys::QgsSpatialRefSys (const long theId, SRS_TYPE theType) : mMapUnits(QGis::UNKNOWN)
45
+ QgsSpatialRefSys::QgsSpatialRefSys (const long theId, SRS_TYPE theType) : mMapUnits(QGis::UNKNOWN)
46
46
{
47
47
switch (theType)
48
48
{
@@ -70,7 +70,7 @@ void QgsSpatialRefSys::validate()
70
70
#ifdef QGISDEBUG
71
71
std::cout << " QgsSpatialRefSys::validate" << std::endl;
72
72
#endif
73
- // dont bother trying to do an initial test with gdal if
73
+ // dont bother trying to do an initial test with gdal if
74
74
// the proj4String is not even populated
75
75
if (QString::null!=mProj4String && !mProj4String .isEmpty ())
76
76
{
@@ -162,7 +162,7 @@ void QgsSpatialRefSys::validate()
162
162
163
163
}
164
164
165
- void QgsSpatialRefSys::createFromSrid (long theSrid)
165
+ bool QgsSpatialRefSys::createFromSrid (long theSrid)
166
166
{
167
167
#ifdef QGISDEBUG
168
168
std::cout << " QgsSpatialRefSys::createFromSrid" << std::endl;
@@ -232,17 +232,19 @@ void QgsSpatialRefSys::createFromSrid(long theSrid)
232
232
}
233
233
sqlite3_finalize (myPreparedStatement);
234
234
sqlite3_close (myDatabase);
235
+ return isValidFlag;
235
236
}
236
237
237
- void QgsSpatialRefSys::createFromWkt (QString theWkt)
238
+ bool QgsSpatialRefSys::createFromWkt (QString theWkt)
238
239
{
239
240
if (!theWkt)
240
241
{
241
242
std::cout << " QgsSpatialRefSys::createFromWkt -- theWkt is uninitialised, operation failed" << std::endl;
242
- return ;
243
+ isValidFlag==false ;
244
+ return false ;
243
245
}
244
246
#ifdef QGISDEBUG
245
- std::cout << " QgsSpatialRefSys::createFromWkt(QString theWkt) using: \n " << theWkt << std::endl;
247
+ std::cout << " QgsSpatialRefSys::createFromWkt(QString theWkt) using: \n " << theWkt << std::endl;
246
248
#endif
247
249
// this is really ugly but we need to get a QString to a char**
248
250
char *myCharArrayPointer = (char *)theWkt.latin1 ();
@@ -269,7 +271,8 @@ void QgsSpatialRefSys::createFromWkt(QString theWkt)
269
271
std::cout << " This SRS could *** NOT *** be set from the supplied WKT " << std::endl;
270
272
std::cout << " INPUT: " << std::endl << theWkt << std::endl;
271
273
std::cout << " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << std::endl;
272
- return ;
274
+ isValidFlag==false ;
275
+ return false ;
273
276
}
274
277
275
278
@@ -279,13 +282,15 @@ void QgsSpatialRefSys::createFromWkt(QString theWkt)
279
282
char *proj4src;
280
283
myOgrSpatialRef.exportToProj4 (&proj4src);
281
284
282
- // XXX TODO split out projext and ellipsoid acronym from the parameters
283
- mProj4String =QString (proj4src);
284
-
285
- setMapUnits ();
285
+ // now that we have the proj4string, delegate to createFromProj4String so
286
+ // that we can try to fill in the remaining class members...
287
+ // create from Proj wil set the isValidFalg
288
+ createFromProj4 (QString (proj4src));
289
+ return isValidFlag;
290
+ // setMapunits will be called by createfromproj above
286
291
}
287
292
288
- void QgsSpatialRefSys::createFromEpsg (long theEpsg)
293
+ bool QgsSpatialRefSys::createFromEpsg (long theEpsg)
289
294
{
290
295
#ifdef QGISDEBUG
291
296
std::cout << " QgsSpatialRefSys::createFromEpsg" << std::endl;
@@ -353,14 +358,15 @@ void QgsSpatialRefSys::createFromEpsg(long theEpsg)
353
358
}
354
359
sqlite3_finalize (myPreparedStatement);
355
360
sqlite3_close (myDatabase);
361
+ return isValidFlag;
356
362
}
357
363
358
364
359
- void QgsSpatialRefSys::createFromSrsId (long theSrsId)
365
+ bool QgsSpatialRefSys::createFromSrsId (long theSrsId)
360
366
{
361
367
#ifdef QGISDEBUG
362
368
std::cout << " QgsSpatialRefSys::createFromSrsId" << std::endl;
363
- #endif
369
+ #endif
364
370
QString myDatabaseFileName;
365
371
//
366
372
// Determine if this is a user projection or a system on
@@ -375,7 +381,7 @@ void QgsSpatialRefSys::createFromSrsId (long theSrsId)
375
381
{
376
382
isValidFlag==false ;
377
383
std::cout << " QgsSpatialRefSys::createFromSrid failed : users qgis.db not found" << std::endl;
378
- return ;
384
+ return isValidFlag ;
379
385
}
380
386
}
381
387
else // must be a system projection then
@@ -443,6 +449,7 @@ void QgsSpatialRefSys::createFromSrsId (long theSrsId)
443
449
}
444
450
sqlite3_finalize (myPreparedStatement);
445
451
sqlite3_close (myDatabase);
452
+ return isValidFlag;
446
453
}
447
454
448
455
@@ -467,51 +474,201 @@ bool QgsSpatialRefSys::isValid() const
467
474
}
468
475
}
469
476
470
- void QgsSpatialRefSys::createFromProj4 (const QString theProj4String)
477
+ bool QgsSpatialRefSys::createFromProj4 (const QString theProj4String)
471
478
{
472
479
//
473
480
// Example:
474
- // +proj=tmerc +lat_0=0 +lon_0=-62 +k=0.999500 +x_0=400000 +y_0=0
481
+ // +proj=tmerc +lat_0=0 +lon_0=-62 +k=0.999500 +x_0=400000 +y_0=0
475
482
// +ellps=clrk80 +towgs84=-255,-15,71,0,0,0,0 +units=m +no_defs
476
- //
483
+ //
477
484
478
- QRegExp myProjRegExp ( " \\ +proj=[a-zA-Z]* " );
485
+ QRegExp myProjRegExp ( " \\ +proj=[a-zA-Z]* " );
479
486
int myStart= 0 ;
480
487
int myLength=0 ;
481
488
myStart = myProjRegExp.search (theProj4String, myStart);
482
489
if (myStart==-1 )
483
490
{
484
491
std::cout << " QgsSpatialRefSys::createFromProj4 error proj string supplied has no +proj argument" << std::endl;
492
+ isValidFlag=false ;
493
+ return isValidFlag;
485
494
}
486
495
else
487
496
{
488
497
myLength = myProjRegExp.matchedLength ();
489
498
}
490
499
mProjectionAcronym = theProj4String.mid (myStart+PROJ_PREFIX_LEN,myLength);
491
-
492
- QRegExp myEllipseRegExp ( " \\ +ellps=[a-zA-Z]* " );
500
+
501
+ QRegExp myEllipseRegExp ( " \\ +ellps=[a-zA-Z]* " );
493
502
myStart= 0 ;
494
503
myLength=0 ;
495
504
myStart = myEllipseRegExp.search (theProj4String, myStart);
496
505
if (myStart==-1 )
497
506
{
498
507
std::cout << " QgsSpatialRefSys::createFromProj4 error proj string supplied has no +ellps argument" << std::endl;
508
+ isValidFlag=false ;
509
+ return isValidFlag;
499
510
}
500
511
else
501
512
{
502
513
myLength = myEllipseRegExp.matchedLength ();
503
514
}
504
515
mEllipsoidAcronym = theProj4String.mid (myStart+ELLPS_PREFIX_LEN,myLength);
516
+
517
+
518
+
519
+ /*
520
+ * We try to match the proj string to and srsid using the following logic:
521
+ *
522
+ * - perform a whole text search on srs name (if not null). The srs name will
523
+ * have been set if this method has been delegated to from createFromWkt.
524
+ */
525
+ getRecord (" select * from tbl_srs where where parameters='" + mProj4String + " '" );
526
+ /*
527
+ * - if the above does not match perform a whole text search on proj4 string (if not null)
528
+ */
529
+
530
+ /*
531
+ * - if none of the above match convert the proj4 string to an OGR SRS
532
+ * then check if its a geocs or a proj cs (using ogr isGeographic)
533
+ * then sequentially walk through the database (first users qgis.db srs tbl then
534
+ * system srs.db tbl), converting each entry into an ogr srs and using isSame
535
+ * or isSameGeocs (essentially calling the == overloaded operator). We'll try to
536
+ * be smart about this and first parse out the proj and ellpse strings and only
537
+ * check for a match in entities that have the same ellps and proj entries so
538
+ * that it doesnt munch yer cpu so much.
539
+ */
540
+
505
541
setMapUnits ();
542
+ isValidFlag=true ;
543
+ return isValidFlag;
506
544
}
507
- // Accessors -----------------------------------
508
545
546
+ QgsSpatialRefSys::RecordMap QgsSpatialRefSys::getRecord (QString theSql)
547
+ {
548
+
549
+ QString myDatabaseFileName;
550
+ QgsSpatialRefSys::RecordMap myMap;
551
+ QString myFieldName;
552
+ QString myFieldValue;
553
+ sqlite3 *myDatabase;
554
+ char *myErrorMessage = 0 ;
555
+ const char *myTail;
556
+ sqlite3_stmt *myPreparedStatement;
557
+ int myResult;
558
+
559
+ #ifdef QGISDEBUG
560
+ std::cout << " QgsSpatialRefSys::getRecord...running query:\n " << theSql << " \n " << std::endl;
561
+ std::cout << " QgsSpatialRefSys::getRecord...trying system srs.db" << std::endl;
562
+ #endif
563
+ // Get the package data path and set the full path name to the sqlite3 spatial reference
564
+ // database.
565
+ #if defined(Q_OS_MACX) || defined(WIN32)
566
+ QString PKGDATAPATH = qApp->applicationDirPath () + " /share/qgis" ;
567
+ #endif
568
+ myDatabaseFileName = PKGDATAPATH;
569
+ myDatabaseFileName += " /resources/srs.db" ;
570
+
571
+
572
+ // check the db is available
573
+ myResult = sqlite3_open (myDatabaseFileName.latin1 (), &myDatabase);
574
+ if (myResult)
575
+ {
576
+ std::cout << " Can't open database: " << sqlite3_errmsg (myDatabase) << std::endl;
577
+ // XXX This will likely never happen since on open, sqlite creates the
578
+ // database if it does not exist.
579
+ assert (myResult == 0 );
580
+ }
581
+
582
+
583
+ myResult = sqlite3_prepare (myDatabase, (const char *)theSql, theSql.length (), &myPreparedStatement, &myTail);
584
+ // XXX Need to free memory from the error msg if one is set
585
+ if (myResult == SQLITE_OK)
586
+ {
587
+ sqlite3_step (myPreparedStatement) == SQLITE_ROW;
588
+ int myColumnCount = sqlite3_column_count (myPreparedStatement);
589
+ // loop through each column in the record adding its field name and vvalue to the map
590
+ for (int myColNo=0 ;myColNo < myColumnCount;myColNo++)
591
+ {
592
+ myFieldName = QString ((char *)sqlite3_column_name (myPreparedStatement,myColNo));
593
+ myFieldValue = QString ((char *)sqlite3_column_text (myPreparedStatement,myColNo));
594
+ myMap[myFieldName]=myFieldValue;
595
+ }
596
+ }
597
+ else
598
+ {
599
+ #ifdef QGISDEBUG
600
+ std::cout << " QgsSpatialRefSys::getRecord...trying system users.db" << std::endl;
601
+ #endif
602
+ sqlite3_finalize (myPreparedStatement);
603
+ sqlite3_close (myDatabase);
604
+
605
+ myDatabaseFileName = QDir::homeDirPath () + " /.qgis/qgis.db" ;
606
+ QFileInfo myFileInfo;
607
+ myFileInfo.setFile (myDatabaseFileName);
608
+ if ( !myFileInfo.exists ( ) )
609
+ {
610
+ std::cout << " QgsSpatialRefSys::getRecord failed : users qgis.db not found" << std::endl;
611
+ return myMap;
612
+ }
613
+
614
+ // check the db is available
615
+ myResult = sqlite3_open (myDatabaseFileName.latin1 (), &myDatabase);
616
+ if (myResult)
617
+ {
618
+ std::cout << " Can't open database: " << sqlite3_errmsg (myDatabase) << std::endl;
619
+ // XXX This will likely never happen since on open, sqlite creates the
620
+ // database if it does not exist.
621
+ assert (myResult == 0 );
622
+ }
623
+
624
+
625
+ myResult = sqlite3_prepare (myDatabase, (const char *)theSql, theSql.length (), &myPreparedStatement, &myTail);
626
+ // XXX Need to free memory from the error msg if one is set
627
+ if (myResult == SQLITE_OK)
628
+ {
629
+
630
+ sqlite3_step (myPreparedStatement) == SQLITE_ROW;
631
+ int myColumnCount = sqlite3_column_count (myPreparedStatement);
632
+ // loop through each column in the record adding its field name and vvalue to the map
633
+ for (int myColNo=0 ;myColNo < myColumnCount;myColNo++)
634
+ {
635
+ myFieldName = QString ((char *)sqlite3_column_name (myPreparedStatement,myColNo));
636
+ myFieldValue = QString ((char *)sqlite3_column_text (myPreparedStatement,myColNo));
637
+ myMap[myFieldName]=myFieldValue;
638
+ }
639
+ }
640
+ else
641
+ {
642
+ #ifdef QGISDEBUG
643
+ std::cout << " QgsSpatialRefSys::getRecord failed : " << theSql << std::endl;
644
+ #endif
645
+
646
+ }
647
+ }
648
+ sqlite3_finalize (myPreparedStatement);
649
+ sqlite3_close (myDatabase);
650
+ return myMap;
651
+
652
+
653
+
654
+ }
655
+
656
+ // Accessors -----------------------------------
509
657
/* ! Get the SrsId
510
658
* @return long theSrsId The internal sqlite3 srs.db primary key for this srs
511
659
*/
660
+ long QgsSpatialRefSys::srsid () const
661
+ {
662
+ return mSrsId ;
663
+ }
664
+ /* ! Get the Postgis SRID - if possible
665
+ * @return long theSRID The internal postgis SRID for this SRS
666
+ */
512
667
long QgsSpatialRefSys::srid () const
513
668
{
669
+
514
670
return mSRID ;
671
+
515
672
}
516
673
/* ! Get the Description
517
674
* @return QString the Description A textual description of the srs.
@@ -534,7 +691,7 @@ QString QgsSpatialRefSys::ellipsoidAcronym () const
534
691
{
535
692
return mEllipsoidAcronym ;
536
693
}
537
- /* Get the Proj Proj4String.
694
+ /* Get the Proj Proj4String.
538
695
* @return QString theProj4String Proj4 format specifies that define this srs.
539
696
*/
540
697
QString QgsSpatialRefSys::proj4String () const
@@ -679,14 +836,16 @@ void QgsSpatialRefSys::setMapUnits()
679
836
#ifdef QGISDEBUG
680
837
std::cerr << " Projection has angular units of " << unit << ' \n ' ;
681
838
#endif
839
+
682
840
}
683
841
}
684
842
843
+
685
844
bool QgsSpatialRefSys::operator ==(const QgsSpatialRefSys &theSrs)
686
845
{
687
- qWarning (" QgsSpatialRefSys::operator== called " );
846
+ qWarning (" QgsSpatialRefSys::operator== called " );
688
847
689
- bool myMatchFlag = true ; // innocent until proven guilty
848
+ bool myMatchFlag = true ; // innocent until proven guilty
690
849
691
850
/* Here are the possible OGR error codes :
692
851
typedef int OGRErr;
@@ -708,7 +867,7 @@ bool QgsSpatialRefSys::operator==(const QgsSpatialRefSys &theSrs)
708
867
// same for the projections they define to be equivalent, which is why I dont just
709
868
// compare the proj parameter strings and return the result
710
869
711
-
870
+
712
871
// create the sr and populate it from a wkt proj definition
713
872
OGRSpatialReference myOgrSpatialRef1;
714
873
OGRSpatialReference myOgrSpatialRef2;
@@ -739,14 +898,14 @@ bool QgsSpatialRefSys::operator==(const QgsSpatialRefSys &theSrs)
739
898
740
899
741
900
742
- // placeholder to be replaced with ogr tests
743
- if (myMatchFlag)
744
- {
745
- qWarning (" QgsSpatialRefSys::operator== result: srs's are equal " );
746
- }
747
- else
748
- {
749
- qWarning (" QgsSpatialRefSys::operator== result: srs's are not equal " );
750
- }
751
- return myMatchFlag;
901
+ // placeholder to be replaced with ogr tests
902
+ if (myMatchFlag)
903
+ {
904
+ qWarning (" QgsSpatialRefSys::operator== result: srs's are equal " );
905
+ }
906
+ else
907
+ {
908
+ qWarning (" QgsSpatialRefSys::operator== result: srs's are not equal " );
909
+ }
910
+ return myMatchFlag;
752
911
}
0 commit comments