LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitesqlfunctions.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 262 204 77.9 %
Date: 2013-03-30 Functions: 20 16 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitesqlfunctions.cpp 25462 2013-01-06 02:10:38Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Extension SQL functions
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : /* WARNING: VERY IMPORTANT NOTE: This file MUST not be directly compiled as */
      31                 : /* a standalone object. It must be included from ogrsqlitevirtualogr.cpp */
      32                 : #ifndef COMPILATION_ALLOWED
      33                 : #error See comment in file
      34                 : #endif
      35                 : 
      36                 : #include "ogrsqlitesqlfunctions.h"
      37                 : #include "ogr_geocoding.h"
      38                 : 
      39                 : #include "ogrsqliteregexp.cpp" /* yes the .cpp file, to make it work on Windows with load_extension('gdalXX.dll') */
      40                 : 
      41                 : #ifndef HAVE_SPATIALITE
      42                 : #define MINIMAL_SPATIAL_FUNCTIONS
      43                 : #endif
      44                 : 
      45                 : class OGRSQLiteExtensionData
      46                 : {
      47                 : #ifdef DEBUG
      48                 :     void* pDummy; /* to track memory leaks */
      49                 : #endif
      50                 :     std::map< std::pair<int,int>, OGRCoordinateTransformation*> oCachedTransformsMap;
      51                 : 
      52                 :     void* hRegExpCache;
      53                 : 
      54                 :     OGRGeocodingSessionH hGeocodingSession;
      55                 : 
      56                 :   public:
      57                 :                                  OGRSQLiteExtensionData(sqlite3* hDB);
      58                 :                                 ~OGRSQLiteExtensionData();
      59                 : 
      60                 :     OGRCoordinateTransformation* GetTransform(int nSrcSRSId, int nDstSRSId);
      61                 : 
      62             112 :     OGRGeocodingSessionH         GetGeocodingSession() { return hGeocodingSession; }
      63             112 :     void                         SetGeocodingSession(OGRGeocodingSessionH hGeocodingSessionIn) { hGeocodingSession = hGeocodingSessionIn; }
      64                 :     
      65             751 :     void                         SetRegExpCache(void* hRegExpCacheIn) { hRegExpCache = hRegExpCacheIn; }
      66                 : };
      67                 : 
      68                 : /************************************************************************/
      69                 : /*                     OGRSQLiteExtensionData()                         */
      70                 : /************************************************************************/
      71                 : 
      72             751 : OGRSQLiteExtensionData::OGRSQLiteExtensionData(sqlite3* hDB) :
      73             751 :         hRegExpCache(NULL), hGeocodingSession(NULL)
      74                 : {
      75                 : #ifdef DEBUG
      76             751 :     pDummy = CPLMalloc(1);
      77                 : #endif
      78             751 : }
      79                 : 
      80                 : /************************************************************************/
      81                 : /*                       ~OGRSQLiteExtensionData()                      */
      82                 : /************************************************************************/
      83                 : 
      84             751 : OGRSQLiteExtensionData::~OGRSQLiteExtensionData()
      85                 : {
      86                 : #ifdef DEBUG
      87             751 :     CPLFree(pDummy);
      88                 : #endif
      89                 : 
      90                 :     std::map< std::pair<int,int>, OGRCoordinateTransformation*>::iterator oIter =
      91             751 :         oCachedTransformsMap.begin();
      92             751 :     for(; oIter != oCachedTransformsMap.end(); ++oIter)
      93               0 :         delete oIter->second;
      94                 : 
      95             751 :     OGRSQLiteFreeRegExpCache(hRegExpCache);
      96                 :     
      97             751 :     OGRGeocodeDestroySession(hGeocodingSession);
      98             751 : }
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                          GetTransform()                              */
     102                 : /************************************************************************/
     103                 : 
     104               0 : OGRCoordinateTransformation* OGRSQLiteExtensionData::GetTransform(int nSrcSRSId,
     105                 :                                                                   int nDstSRSId)
     106                 : {
     107                 :     std::map< std::pair<int,int>, OGRCoordinateTransformation*>::iterator oIter =
     108               0 :         oCachedTransformsMap.find(std::pair<int,int>(nSrcSRSId, nDstSRSId));
     109               0 :     if( oIter == oCachedTransformsMap.end() )
     110                 :     {
     111               0 :         OGRCoordinateTransformation* poCT = NULL;
     112               0 :         OGRSpatialReference oSrcSRS, oDstSRS;
     113               0 :         if (oSrcSRS.importFromEPSG(nSrcSRSId) == OGRERR_NONE &&
     114                 :             oDstSRS.importFromEPSG(nDstSRSId) == OGRERR_NONE )
     115                 :         {
     116               0 :             poCT = OGRCreateCoordinateTransformation( &oSrcSRS, &oDstSRS );
     117                 :         }
     118               0 :         oCachedTransformsMap[std::pair<int,int>(nSrcSRSId, nDstSRSId)] = poCT;
     119               0 :         return poCT;
     120                 :     }
     121                 :     else
     122               0 :         return oIter->second;
     123                 : }
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                        OGR2SQLITE_ogr_version()                     */
     127                 : /************************************************************************/
     128                 : 
     129                 : static
     130               1 : void OGR2SQLITE_ogr_version(sqlite3_context* pContext,
     131                 :                             int argc, sqlite3_value** argv)
     132                 : {
     133               1 :     if( argc == 0 || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     134                 :     {
     135               1 :         sqlite3_result_text( pContext, GDAL_RELEASE_NAME, -1, SQLITE_STATIC );
     136                 :     }
     137                 :     else
     138                 :     {
     139                 :         sqlite3_result_text( pContext,
     140                 :                              GDALVersionInfo((const char*)sqlite3_value_text(argv[0])),
     141               0 :                              -1, SQLITE_TRANSIENT );
     142                 :     }
     143               1 : }
     144                 : 
     145                 : /************************************************************************/
     146                 : /*                          OGR2SQLITE_Transform()                      */
     147                 : /************************************************************************/
     148                 : 
     149                 : static
     150               0 : void OGR2SQLITE_Transform(sqlite3_context* pContext,
     151                 :                           int argc, sqlite3_value** argv)
     152                 : {
     153               0 :     if( argc != 3 )
     154                 :     {
     155               0 :         sqlite3_result_null (pContext);
     156               0 :         return;
     157                 :     }
     158                 : 
     159               0 :     if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
     160                 :     {
     161               0 :         sqlite3_result_null (pContext);
     162               0 :         return;
     163                 :     }
     164                 : 
     165               0 :     if( sqlite3_value_type (argv[1]) != SQLITE_INTEGER )
     166                 :     {
     167               0 :         sqlite3_result_null (pContext);
     168               0 :         return;
     169                 :     }
     170                 : 
     171               0 :     if( sqlite3_value_type (argv[2]) != SQLITE_INTEGER )
     172                 :     {
     173               0 :         sqlite3_result_null (pContext);
     174               0 :         return;
     175                 :     }
     176                 : 
     177               0 :     int nSrcSRSId = sqlite3_value_int(argv[1]);
     178               0 :     int nDstSRSId = sqlite3_value_int(argv[2]);
     179                 : 
     180                 :     OGRSQLiteExtensionData* poModule =
     181               0 :                     (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
     182                 :     OGRCoordinateTransformation* poCT =
     183               0 :                     poModule->GetTransform(nSrcSRSId, nDstSRSId);
     184               0 :     if( poCT == NULL )
     185                 :     {
     186               0 :         sqlite3_result_null (pContext);
     187               0 :         return;
     188                 :     }
     189                 : 
     190               0 :     GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
     191               0 :     int nBLOBLen = sqlite3_value_bytes (argv[0]);
     192               0 :     OGRGeometry* poGeom = NULL;
     193               0 :     if( OGRSQLiteLayer::ImportSpatiaLiteGeometry(
     194                 :                     pabySLBLOB, nBLOBLen, &poGeom ) == CE_None &&
     195               0 :         poGeom->transform(poCT) == OGRERR_NONE &&
     196                 :         OGRSQLiteLayer::ExportSpatiaLiteGeometry(
     197                 :                     poGeom, nDstSRSId, wkbNDR, FALSE,
     198                 :                     FALSE, FALSE, &pabySLBLOB, &nBLOBLen ) == CE_None )
     199                 :     {
     200               0 :         sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
     201                 :     }
     202                 :     else
     203                 :     {
     204               0 :         sqlite3_result_null (pContext);
     205                 :     }
     206               0 :     delete poGeom;
     207                 : }
     208                 : 
     209                 : /************************************************************************/
     210                 : /*                       OGR2SQLITE_ogr_deflate()                       */
     211                 : /************************************************************************/
     212                 : 
     213                 : static
     214               4 : void OGR2SQLITE_ogr_deflate(sqlite3_context* pContext,
     215                 :                             int argc, sqlite3_value** argv)
     216                 : {
     217               4 :     int nLevel = -1;
     218               4 :     if( !(argc == 1 || argc == 2) ||
     219                 :         !(sqlite3_value_type (argv[0]) == SQLITE_TEXT ||
     220                 :           sqlite3_value_type (argv[0]) == SQLITE_BLOB) )
     221                 :     {
     222               0 :         sqlite3_result_null (pContext);
     223               0 :         return;
     224                 :     }
     225               4 :     if( argc == 2 )
     226                 :     {
     227               2 :         if( sqlite3_value_type (argv[1]) != SQLITE_INTEGER )
     228                 :         {
     229               1 :             sqlite3_result_null (pContext);
     230               1 :             return;
     231                 :         }
     232               1 :         nLevel = sqlite3_value_int(argv[1]);
     233                 :     }
     234                 : 
     235               3 :     size_t nOutBytes = 0;
     236                 :     void* pOut;
     237               3 :     if( sqlite3_value_type (argv[0]) == SQLITE_TEXT )
     238                 :     {
     239               2 :         const char* pszVal = (const char*)sqlite3_value_text(argv[0]);
     240               2 :         pOut = CPLZLibDeflate( pszVal, strlen(pszVal) + 1, nLevel, NULL, 0, &nOutBytes);
     241                 :     }
     242                 :     else
     243                 :     {
     244               1 :         const void* pSrc = sqlite3_value_blob (argv[0]);
     245               1 :         int nLen = sqlite3_value_bytes (argv[0]);
     246               1 :         pOut = CPLZLibDeflate( pSrc, nLen, nLevel, NULL, 0, &nOutBytes);
     247                 :     }
     248               3 :     if( pOut != NULL )
     249                 :     {
     250               3 :         sqlite3_result_blob (pContext, pOut, nOutBytes, VSIFree);
     251                 :     }
     252                 :     else
     253                 :     {
     254               0 :         sqlite3_result_null (pContext);
     255                 :     }
     256                 :  
     257               3 :     return;
     258                 : }
     259                 : 
     260                 : /************************************************************************/
     261                 : /*                       OGR2SQLITE_ogr_inflate()                       */
     262                 : /************************************************************************/
     263                 : 
     264                 : static
     265               5 : void OGR2SQLITE_ogr_inflate(sqlite3_context* pContext,
     266                 :                             int argc, sqlite3_value** argv)
     267                 : {
     268               5 :     if( argc != 1 || 
     269                 :         sqlite3_value_type (argv[0]) != SQLITE_BLOB )
     270                 :     {
     271               1 :         sqlite3_result_null (pContext);
     272               1 :         return;
     273                 :     }
     274                 : 
     275               4 :     size_t nOutBytes = 0;
     276                 :     void* pOut;
     277                 : 
     278               4 :     const void* pSrc = sqlite3_value_blob (argv[0]);
     279               4 :     int nLen = sqlite3_value_bytes (argv[0]);
     280               4 :     pOut = CPLZLibInflate( pSrc, nLen, NULL, 0, &nOutBytes);
     281                 : 
     282               4 :     if( pOut != NULL )
     283                 :     {
     284               3 :         sqlite3_result_blob (pContext, pOut, nOutBytes, VSIFree);
     285                 :     }
     286                 :     else
     287                 :     {
     288               1 :         sqlite3_result_null (pContext);
     289                 :     }
     290                 : 
     291               4 :     return;
     292                 : }
     293                 : 
     294                 : /************************************************************************/
     295                 : /*                     OGR2SQLITE_ogr_geocode_set_result()              */
     296                 : /************************************************************************/
     297                 : 
     298                 : static
     299             112 : void OGR2SQLITE_ogr_geocode_set_result(sqlite3_context* pContext,
     300                 :                                        OGRLayerH hLayer,
     301                 :                                        const char* pszField)
     302                 : {
     303             112 :     if( hLayer == NULL )
     304               8 :         sqlite3_result_null (pContext);
     305                 :     else
     306                 :     {
     307             104 :         OGRLayer* poLayer = (OGRLayer*)hLayer;
     308             104 :         OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
     309             104 :         OGRFeature* poFeature = poLayer->GetNextFeature();
     310             104 :         int nIdx = -1;
     311             104 :         if( poFeature == NULL )
     312               8 :             sqlite3_result_null (pContext);
     313              96 :         else if( strcmp(pszField, "geometry") == 0 &&
     314                 :                  poFeature->GetGeometryRef() != NULL )
     315                 :         {
     316              32 :             GByte* pabyGeomBLOB = NULL;
     317              32 :             int nGeomBLOBLen = 0;
     318              32 :             if( OGRSQLiteLayer::ExportSpatiaLiteGeometry(
     319                 :                     poFeature->GetGeometryRef(), 4326, wkbNDR, FALSE, FALSE, FALSE,
     320                 :                     &pabyGeomBLOB,
     321                 :                     &nGeomBLOBLen ) != CE_None )
     322                 :             {
     323               0 :                 sqlite3_result_null (pContext);
     324                 :             }
     325                 :             else
     326                 :             {
     327              32 :                 sqlite3_result_blob (pContext, pabyGeomBLOB, nGeomBLOBLen, CPLFree);
     328                 :             }
     329                 :         }
     330              64 :         else if( (nIdx = poFDefn->GetFieldIndex(pszField)) >= 0 &&
     331                 :                  poFeature->IsFieldSet(nIdx) )
     332                 :         {
     333              62 :             OGRFieldType eType = poFDefn->GetFieldDefn(nIdx)->GetType();
     334              62 :             if( eType == OFTInteger )
     335                 :                 sqlite3_result_int(pContext,
     336               0 :                                    poFeature->GetFieldAsInteger(nIdx));
     337              62 :             else if( eType == OFTReal )
     338                 :                 sqlite3_result_double(pContext,
     339               0 :                                       poFeature->GetFieldAsDouble(nIdx));
     340                 :             else
     341                 :                 sqlite3_result_text(pContext,
     342                 :                                     poFeature->GetFieldAsString(nIdx),
     343              62 :                                     -1, SQLITE_TRANSIENT);
     344                 :         }
     345                 :         else
     346               2 :             sqlite3_result_null (pContext);
     347             104 :         delete poFeature;
     348             104 :         OGRGeocodeFreeResult(hLayer);
     349                 :     }
     350             112 : }
     351                 : 
     352                 : /************************************************************************/
     353                 : /*                       OGR2SQLITE_ogr_geocode()                       */
     354                 : /************************************************************************/
     355                 : 
     356                 : static
     357              80 : void OGR2SQLITE_ogr_geocode(sqlite3_context* pContext,
     358                 :                             int argc, sqlite3_value** argv)
     359                 : {
     360                 :     OGRSQLiteExtensionData* poModule =
     361              80 :                     (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
     362                 : 
     363              80 :     if( argc < 1 || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     364                 :     {
     365              16 :         sqlite3_result_null (pContext);
     366              16 :         return;
     367                 :     }
     368              64 :     const char* pszQuery = (const char*)sqlite3_value_text(argv[0]);
     369                 : 
     370              64 :     CPLString osField = "geometry";
     371              64 :     if( argc >= 2 && sqlite3_value_type (argv[1]) == SQLITE_TEXT )
     372                 :     {
     373              32 :         osField = (const char*)sqlite3_value_text(argv[1]);
     374                 :     }
     375                 : 
     376                 :     int i;
     377              64 :     char** papszOptions = NULL;
     378              72 :     for(i = 2; i < argc; i++)
     379                 :     {
     380               8 :         if( sqlite3_value_type (argv[i]) == SQLITE_TEXT )
     381                 :         {
     382                 :             papszOptions = CSLAddString(papszOptions,
     383               0 :                                         (const char*)sqlite3_value_text(argv[i]));
     384                 :         }
     385                 :     }
     386                 : 
     387              64 :     OGRGeocodingSessionH hSession = poModule->GetGeocodingSession();
     388              64 :     if( hSession == NULL )
     389                 :     {
     390              64 :         hSession = OGRGeocodeCreateSession(papszOptions);
     391              64 :         if( hSession == NULL )
     392                 :         {
     393               0 :             sqlite3_result_null (pContext);
     394               0 :             CSLDestroy(papszOptions);
     395                 :             return;
     396                 :         }
     397              64 :         poModule->SetGeocodingSession(hSession);
     398                 :     }
     399                 : 
     400              64 :     if( osField == "raw" )
     401               8 :         papszOptions = CSLAddString(papszOptions, "RAW_FEATURE=YES");
     402                 : 
     403              64 :     if( CSLFindString(papszOptions, "LIMIT") == -1 )
     404              64 :         papszOptions = CSLAddString(papszOptions, "LIMIT=1");
     405                 : 
     406              64 :     OGRLayerH hLayer = OGRGeocode(hSession, pszQuery, NULL, papszOptions);
     407                 : 
     408              64 :     OGR2SQLITE_ogr_geocode_set_result(pContext, hLayer, osField);
     409                 : 
     410              64 :     CSLDestroy(papszOptions);
     411                 : 
     412               0 :     return;
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                    OGR2SQLITE_GetValAsDouble()                       */
     417                 : /************************************************************************/
     418                 : 
     419             144 : static double OGR2SQLITE_GetValAsDouble(sqlite3_value* val, int* pbGotVal)
     420                 : {
     421             144 :     switch(sqlite3_value_type(val))
     422                 :     {
     423                 :         case SQLITE_FLOAT:
     424              32 :             if( pbGotVal ) *pbGotVal = TRUE;
     425              32 :             return sqlite3_value_double(val);
     426                 : 
     427                 :         case SQLITE_INTEGER:
     428              64 :             if( pbGotVal ) *pbGotVal = TRUE;
     429              64 :             return sqlite3_value_int64(val);
     430                 : 
     431                 :         default:
     432              48 :             if( pbGotVal ) *pbGotVal = FALSE;
     433              48 :             return 0.0;
     434                 :     }
     435                 : }
     436                 : 
     437                 : /************************************************************************/
     438                 : /*                      OGR2SQLITE_GetGeom()                            */
     439                 : /************************************************************************/
     440                 : 
     441              16 : static OGRGeometry* OGR2SQLITE_GetGeom(sqlite3_context* pContext,
     442                 :                                        int argc, sqlite3_value** argv,
     443                 :                                        int* pnSRSId)
     444                 : {
     445              16 :     if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
     446                 :     {
     447               0 :         return NULL;
     448                 :     }
     449                 : 
     450              16 :     GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
     451              16 :     int nBLOBLen = sqlite3_value_bytes (argv[0]);
     452              16 :     OGRGeometry* poGeom = NULL;
     453              16 :     if( OGRSQLiteLayer::ImportSpatiaLiteGeometry(
     454                 :                         pabySLBLOB, nBLOBLen, &poGeom, pnSRSId) != CE_None )
     455                 :     {
     456               0 :         return NULL;
     457                 :     }
     458                 : 
     459              16 :     return poGeom;
     460                 : }
     461                 : 
     462                 : /************************************************************************/
     463                 : /*                   OGR2SQLITE_ogr_geocode_reverse()                   */
     464                 : /************************************************************************/
     465                 : 
     466                 : static
     467              96 : void OGR2SQLITE_ogr_geocode_reverse(sqlite3_context* pContext,
     468                 :                                     int argc, sqlite3_value** argv)
     469                 : {
     470                 :     OGRSQLiteExtensionData* poModule =
     471              96 :                     (OGRSQLiteExtensionData*) sqlite3_user_data(pContext);
     472                 : 
     473              96 :     double dfLon = 0.0, dfLat = 0.0;
     474              96 :     int iAfterGeomIdx = 0;
     475              96 :     int bGotLon = FALSE, bGotLat = FALSE;
     476                 : 
     477              96 :     if( argc >= 2 )
     478                 :     {
     479              72 :         dfLon = OGR2SQLITE_GetValAsDouble(argv[0], &bGotLon);
     480              72 :         dfLat = OGR2SQLITE_GetValAsDouble(argv[1], &bGotLat);
     481                 :     }
     482                 : 
     483              96 :     if( argc >= 3 && bGotLon && bGotLat &&
     484                 :         sqlite3_value_type (argv[2]) == SQLITE_TEXT )
     485                 :     {
     486              32 :         iAfterGeomIdx = 2;
     487                 :     }
     488              64 :     else if( argc >= 2 && 
     489                 :              sqlite3_value_type (argv[0]) == SQLITE_BLOB &&
     490                 :              sqlite3_value_type (argv[1]) == SQLITE_TEXT )
     491                 :     {
     492              16 :         OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
     493              16 :         if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
     494                 :         {
     495              16 :             OGRPoint* poPoint = (OGRPoint*) poGeom;
     496              16 :             dfLon = poPoint->getX();
     497              16 :             dfLat = poPoint->getY();
     498              16 :             delete poGeom;
     499                 :         }
     500                 :         else
     501                 :         {
     502               0 :             delete poGeom;
     503               0 :             sqlite3_result_null (pContext);
     504               0 :             return;
     505                 :         }
     506              16 :         iAfterGeomIdx = 1;
     507                 :     }
     508                 :     else
     509                 :     {
     510              48 :         sqlite3_result_null (pContext);
     511              48 :         return;
     512                 :     }
     513                 : 
     514              48 :     const char* pszField = (const char*)sqlite3_value_text(argv[iAfterGeomIdx]);
     515                 : 
     516                 :     int i;
     517              48 :     char** papszOptions = NULL;
     518              64 :     for(i = iAfterGeomIdx + 1; i < argc; i++)
     519                 :     {
     520              16 :         if( sqlite3_value_type (argv[i]) == SQLITE_TEXT )
     521                 :         {
     522                 :             papszOptions = CSLAddString(papszOptions,
     523              16 :                                         (const char*)sqlite3_value_text(argv[i]));
     524                 :         }
     525                 :     }
     526                 : 
     527              48 :     OGRGeocodingSessionH hSession = poModule->GetGeocodingSession();
     528              48 :     if( hSession == NULL )
     529                 :     {
     530              48 :         hSession = OGRGeocodeCreateSession(papszOptions);
     531              48 :         if( hSession == NULL )
     532                 :         {
     533               0 :             sqlite3_result_null (pContext);
     534               0 :             CSLDestroy(papszOptions);
     535               0 :             return;
     536                 :         }
     537              48 :         poModule->SetGeocodingSession(hSession);
     538                 :     }
     539                 : 
     540              48 :     if( strcmp(pszField, "raw") == 0 )
     541               8 :         papszOptions = CSLAddString(papszOptions, "RAW_FEATURE=YES");
     542                 : 
     543              48 :     OGRLayerH hLayer = OGRGeocodeReverse(hSession, dfLon, dfLat, papszOptions);
     544                 : 
     545              48 :     OGR2SQLITE_ogr_geocode_set_result(pContext, hLayer, pszField);
     546                 : 
     547              48 :     CSLDestroy(papszOptions);
     548                 : 
     549              48 :     return;
     550                 : }
     551                 : 
     552                 : /************************************************************************/
     553                 : /*               OGR2SQLITE_ogr_datasource_load_layers()                */
     554                 : /************************************************************************/
     555                 : 
     556                 : static
     557               8 : void OGR2SQLITE_ogr_datasource_load_layers(sqlite3_context* pContext,
     558                 :                                            int argc, sqlite3_value** argv)
     559                 : {
     560               8 :     sqlite3* hDB = (sqlite3*) sqlite3_user_data(pContext);
     561                 : 
     562               8 :     if( (argc < 1 || argc > 3) || sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     563                 :     {
     564               1 :         sqlite3_result_int (pContext, 0);
     565               1 :         return;
     566                 :     }
     567               7 :     const char* pszDataSource = (const char*) sqlite3_value_text(argv[0]);
     568                 : 
     569               7 :     int bUpdate = FALSE;
     570               7 :     if( argc >= 2 )
     571                 :     {
     572               4 :         if( sqlite3_value_type(argv[1]) != SQLITE_INTEGER )
     573                 :         {
     574               1 :             sqlite3_result_int (pContext, 0);
     575               1 :             return;
     576                 :         }
     577               3 :         bUpdate = sqlite3_value_int(argv[1]);
     578                 :     }
     579                 : 
     580               6 :     const char* pszPrefix = NULL;
     581               6 :     if( argc >= 3 )
     582                 :     {
     583               2 :         if( sqlite3_value_type(argv[2]) != SQLITE_TEXT )
     584                 :         {
     585               1 :             sqlite3_result_int (pContext, 0);
     586               1 :             return;
     587                 :         }
     588               1 :         pszPrefix = (const char*) sqlite3_value_text(argv[2]);
     589                 :     }
     590                 : 
     591               5 :     OGRDataSource* poDS = (OGRDataSource*)OGROpenShared(pszDataSource, bUpdate, NULL);
     592               5 :     if( poDS == NULL )
     593                 :     {
     594               1 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s", pszDataSource);
     595               1 :         sqlite3_result_int (pContext, 0);
     596               1 :         return;
     597                 :     }
     598                 : 
     599               4 :     CPLString osEscapedDataSource = OGRSQLiteEscape(pszDataSource);
     600               8 :     for(int i=0;i<poDS->GetLayerCount();i++)
     601                 :     {
     602               4 :         const char* pszLayerName = poDS->GetLayer(i)->GetName();
     603               4 :         CPLString osEscapedLayerName = OGRSQLiteEscape(pszLayerName);
     604               4 :         CPLString osTableName;
     605               4 :         if( pszPrefix != NULL )
     606                 :         {
     607               1 :             osTableName = pszPrefix;
     608               1 :             osTableName += "_";
     609               1 :             osTableName += OGRSQLiteEscapeName(pszLayerName);
     610                 :         }
     611                 :         else
     612                 :         {
     613               3 :             osTableName = OGRSQLiteEscapeName(pszLayerName);
     614                 :         }
     615                 : 
     616               4 :         char* pszErrMsg = NULL;
     617               4 :         if( sqlite3_exec(hDB, CPLSPrintf(
     618                 :             "CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR('%s', %d, '%s')",
     619                 :                 osTableName.c_str(),
     620                 :                 osEscapedDataSource.c_str(),
     621                 :                 bUpdate,
     622                 :                 osEscapedLayerName.c_str()),
     623                 :             NULL, NULL, &pszErrMsg) != SQLITE_OK )
     624                 :         {
     625                 :             CPLError(CE_Failure, CPLE_AppDefined,
     626                 :                      "Cannot create table \"%s\" : %s",
     627               1 :                      osTableName.c_str(), pszErrMsg);
     628               1 :             sqlite3_free(pszErrMsg);
     629                 :         }
     630                 :     }
     631                 : 
     632               4 :     poDS->Release();
     633               4 :     sqlite3_result_int (pContext, 1);
     634                 : }
     635                 : 
     636                 : #ifdef notdef
     637                 : /************************************************************************/
     638                 : /*                  OGR2SQLITE_ogr_GetConfigOption()                    */
     639                 : /************************************************************************/
     640                 : 
     641                 : static
     642                 : void OGR2SQLITE_ogr_GetConfigOption(sqlite3_context* pContext,
     643                 :                             int argc, sqlite3_value** argv)
     644                 : {
     645                 :     if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     646                 :     {
     647                 :         sqlite3_result_null (pContext);
     648                 :         return;
     649                 :     }
     650                 :     
     651                 :     const char* pszKey = (const char*)sqlite3_value_text(argv[0]);
     652                 :     const char* pszVal = CPLGetConfigOption(pszKey, NULL);
     653                 :     if( pszVal == NULL )
     654                 :         sqlite3_result_null (pContext);
     655                 :     else
     656                 :         sqlite3_result_text( pContext, pszVal, -1, SQLITE_TRANSIENT );
     657                 : }
     658                 : 
     659                 : /************************************************************************/
     660                 : /*                  OGR2SQLITE_ogr_SetConfigOption()                    */
     661                 : /************************************************************************/
     662                 : 
     663                 : static
     664                 : void OGR2SQLITE_ogr_SetConfigOption(sqlite3_context* pContext,
     665                 :                             int argc, sqlite3_value** argv)
     666                 : {
     667                 :     if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     668                 :     {
     669                 :         sqlite3_result_null (pContext);
     670                 :         return;
     671                 :     }
     672                 :     if( sqlite3_value_type (argv[1]) != SQLITE_TEXT &&
     673                 :         sqlite3_value_type (argv[1]) != SQLITE_NULL )
     674                 :     {
     675                 :         sqlite3_result_null (pContext);
     676                 :         return;
     677                 :     }
     678                 : 
     679                 :     const char* pszKey = (const char*)sqlite3_value_text(argv[0]);
     680                 :     const char* pszVal = (sqlite3_value_type (argv[1]) == SQLITE_TEXT) ?
     681                 :         (const char*)sqlite3_value_text(argv[1]) : NULL;
     682                 :     CPLSetConfigOption(pszKey, pszVal);
     683                 :     sqlite3_result_null (pContext);
     684                 : }
     685                 : #endif // notdef
     686                 : 
     687                 : #ifdef MINIMAL_SPATIAL_FUNCTIONS
     688                 : 
     689                 : /************************************************************************/
     690                 : /*                     OGR2SQLITE_ST_AsText()                           */
     691                 : /************************************************************************/
     692                 : 
     693                 : static
     694                 : void OGR2SQLITE_ST_AsText(sqlite3_context* pContext,
     695                 :                             int argc, sqlite3_value** argv)
     696                 : {
     697                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
     698                 :     if( poGeom != NULL )
     699                 :     {
     700                 :         char* pszWKT = NULL;
     701                 :         if( poGeom->exportToWkt(&pszWKT) == OGRERR_NONE )
     702                 :             sqlite3_result_text( pContext, pszWKT, -1, CPLFree);
     703                 :         else
     704                 :             sqlite3_result_null (pContext);
     705                 :         delete poGeom;
     706                 :     }
     707                 :     else
     708                 :         sqlite3_result_null (pContext);
     709                 : }
     710                 : 
     711                 : /************************************************************************/
     712                 : /*                    OGR2SQLITE_ST_AsBinary()                          */
     713                 : /************************************************************************/
     714                 : 
     715                 : static
     716                 : void OGR2SQLITE_ST_AsBinary(sqlite3_context* pContext,
     717                 :                             int argc, sqlite3_value** argv)
     718                 : {
     719                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
     720                 :     if( poGeom != NULL )
     721                 :     {
     722                 :         int nBLOBLen = poGeom->WkbSize();
     723                 :         GByte* pabyGeomBLOB = (GByte*) VSIMalloc(nBLOBLen);
     724                 :         if( pabyGeomBLOB != NULL )
     725                 :         {
     726                 :             if( poGeom->exportToWkb(wkbNDR, pabyGeomBLOB) == OGRERR_NONE )
     727                 :                 sqlite3_result_blob( pContext, pabyGeomBLOB, nBLOBLen, CPLFree);
     728                 :             else
     729                 :             {
     730                 :                 VSIFree(pabyGeomBLOB);
     731                 :                 sqlite3_result_null (pContext);
     732                 :             }
     733                 :         }
     734                 :         else
     735                 :             sqlite3_result_null (pContext);
     736                 :         delete poGeom;
     737                 :     }
     738                 :     else
     739                 :         sqlite3_result_null (pContext);
     740                 : }
     741                 : 
     742                 : /************************************************************************/
     743                 : /*                OGR2SQLITE_SetGeom_AndDestroy()                       */
     744                 : /************************************************************************/
     745                 : 
     746                 : static void OGR2SQLITE_SetGeom_AndDestroy(sqlite3_context* pContext,
     747                 :                                           OGRGeometry* poGeom,
     748                 :                                           int nSRSId)
     749                 : {
     750                 :     GByte* pabySLBLOB = NULL;
     751                 :     int nBLOBLen = 0;
     752                 :     if( poGeom != NULL && OGRSQLiteLayer::ExportSpatiaLiteGeometry(
     753                 :                     poGeom, nSRSId, wkbNDR, FALSE,
     754                 :                     FALSE, FALSE, &pabySLBLOB, &nBLOBLen ) == CE_None )
     755                 :     {
     756                 :         sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
     757                 :     }
     758                 :     else
     759                 :     {
     760                 :         sqlite3_result_null(pContext);
     761                 :     }
     762                 :     delete poGeom;
     763                 : }
     764                 : 
     765                 : /************************************************************************/
     766                 : /*                   OGR2SQLITE_ST_GeomFromText()                       */
     767                 : /************************************************************************/
     768                 : 
     769                 : static
     770                 : void OGR2SQLITE_ST_GeomFromText(sqlite3_context* pContext,
     771                 :                                 int argc, sqlite3_value** argv)
     772                 : {
     773                 :     if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
     774                 :     {
     775                 :         sqlite3_result_null (pContext);
     776                 :         return;
     777                 :     }
     778                 :     char* pszWKT = (char*) sqlite3_value_text( argv[0] );
     779                 : 
     780                 :     int nSRID = -1;
     781                 :     if( argc == 2 && sqlite3_value_type (argv[1]) == SQLITE_INTEGER )
     782                 :         nSRID = sqlite3_value_int( argv[1] );
     783                 : 
     784                 :     OGRGeometry* poGeom = NULL;
     785                 :     if( OGRGeometryFactory::createFromWkt(&pszWKT, NULL, &poGeom) == OGRERR_NONE )
     786                 :     {
     787                 :         OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom, nSRID);
     788                 :     }
     789                 :     else
     790                 :         sqlite3_result_null (pContext);
     791                 : }
     792                 : 
     793                 : /************************************************************************/
     794                 : /*                   OGR2SQLITE_ST_GeomFromWKB()                        */
     795                 : /************************************************************************/
     796                 : 
     797                 : static
     798                 : void OGR2SQLITE_ST_GeomFromWKB(sqlite3_context* pContext,
     799                 :                                 int argc, sqlite3_value** argv)
     800                 : {
     801                 :     if( sqlite3_value_type (argv[0]) != SQLITE_BLOB )
     802                 :     {
     803                 :         sqlite3_result_null (pContext);
     804                 :         return;
     805                 :     }
     806                 : 
     807                 :     int nSRID = -1;
     808                 :     if( argc == 2 && sqlite3_value_type (argv[1]) == SQLITE_INTEGER )
     809                 :         nSRID = sqlite3_value_int( argv[1] );
     810                 : 
     811                 :     GByte* pabySLBLOB = (GByte *) sqlite3_value_blob (argv[0]);
     812                 :     int nBLOBLen = sqlite3_value_bytes (argv[0]);
     813                 :     OGRGeometry* poGeom = NULL;
     814                 : 
     815                 :     if( OGRGeometryFactory::createFromWkb(pabySLBLOB, NULL, &poGeom, nBLOBLen)
     816                 :             == OGRERR_NONE )
     817                 :     {
     818                 :         OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom, nSRID);
     819                 :     }
     820                 :     else
     821                 :         sqlite3_result_null (pContext);
     822                 : }
     823                 : 
     824                 : /************************************************************************/
     825                 : /*                         CheckSTFunctions()                           */
     826                 : /************************************************************************/
     827                 : 
     828                 : static int CheckSTFunctions(sqlite3_context* pContext,
     829                 :                             int argc, sqlite3_value** argv,
     830                 :                             OGRGeometry** ppoGeom1,
     831                 :                             OGRGeometry** ppoGeom2,
     832                 :                             int *pnSRSId )
     833                 : {
     834                 :     *ppoGeom1 = NULL;
     835                 :     *ppoGeom2 = NULL;
     836                 : 
     837                 :     if( argc != 2)
     838                 :     {
     839                 :         return FALSE;
     840                 :     }
     841                 : 
     842                 :     *ppoGeom1 = OGR2SQLITE_GetGeom(pContext, argc, argv, pnSRSId);
     843                 :     if( *ppoGeom1 == NULL )
     844                 :         return FALSE;
     845                 : 
     846                 :     *ppoGeom2 = OGR2SQLITE_GetGeom(pContext, argc - 1, argv + 1, NULL);
     847                 :     if( *ppoGeom2 == NULL )
     848                 :     {
     849                 :         delete *ppoGeom1;
     850                 :         *ppoGeom1 = NULL;
     851                 :         return FALSE;
     852                 :     }
     853                 : 
     854                 :     return TRUE;
     855                 : }
     856                 : 
     857                 : /************************************************************************/
     858                 : /*                 OGR2SQLITE_ST_int_geomgeom_op()                      */
     859                 : /************************************************************************/
     860                 : 
     861                 : #define OGR2SQLITE_ST_int_geomgeom_op(op) \
     862                 : static \
     863                 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
     864                 :                                 int argc, sqlite3_value** argv) \
     865                 : { \
     866                 :     OGRGeometry* poGeom1 = NULL; \
     867                 :     OGRGeometry* poGeom2 = NULL; \
     868                 :     if( !CheckSTFunctions(pContext, argc, argv, &poGeom1, &poGeom2, NULL) ) \
     869                 :     { \
     870                 :         sqlite3_result_int(pContext, 0); \
     871                 :         return; \
     872                 :     } \
     873                 :  \
     874                 :     sqlite3_result_int( pContext, poGeom1-> op (poGeom2) ); \
     875                 :  \
     876                 :     delete poGeom1; \
     877                 :     delete poGeom2; \
     878                 : }
     879                 : 
     880                 : OGR2SQLITE_ST_int_geomgeom_op(Intersects)
     881                 : OGR2SQLITE_ST_int_geomgeom_op(Equals)
     882                 : OGR2SQLITE_ST_int_geomgeom_op(Disjoint)
     883                 : OGR2SQLITE_ST_int_geomgeom_op(Touches)
     884                 : OGR2SQLITE_ST_int_geomgeom_op(Crosses)
     885                 : OGR2SQLITE_ST_int_geomgeom_op(Within)
     886                 : OGR2SQLITE_ST_int_geomgeom_op(Contains)
     887                 : OGR2SQLITE_ST_int_geomgeom_op(Overlaps)
     888                 : 
     889                 : /************************************************************************/
     890                 : /*                   OGR2SQLITE_ST_int_geom_op()                        */
     891                 : /************************************************************************/
     892                 : 
     893                 : #define OGR2SQLITE_ST_int_geom_op(op) \
     894                 : static \
     895                 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
     896                 :                                 int argc, sqlite3_value** argv) \
     897                 : { \
     898                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL); \
     899                 :     if( poGeom != NULL ) \
     900                 :         sqlite3_result_int( pContext, poGeom-> op () ); \
     901                 :     else \
     902                 :         sqlite3_result_int( pContext, 0 ); \
     903                 :  \
     904                 :     delete poGeom; \
     905                 : }
     906                 : 
     907                 : OGR2SQLITE_ST_int_geom_op(IsEmpty)
     908                 : OGR2SQLITE_ST_int_geom_op(IsSimple)
     909                 : OGR2SQLITE_ST_int_geom_op(IsValid)
     910                 : 
     911                 : /************************************************************************/
     912                 : /*                  OGR2SQLITE_ST_geom_geomgeom_op()                    */
     913                 : /************************************************************************/
     914                 : 
     915                 : #define OGR2SQLITE_ST_geom_geomgeom_op(op) \
     916                 : static \
     917                 : void OGR2SQLITE_ST_##op (sqlite3_context* pContext, \
     918                 :                                 int argc, sqlite3_value** argv) \
     919                 : { \
     920                 :     OGRGeometry* poGeom1 = NULL; \
     921                 :     OGRGeometry* poGeom2 = NULL; \
     922                 :     int nSRSId = -1; \
     923                 :     if( !CheckSTFunctions(pContext, argc, argv, &poGeom1, &poGeom2, &nSRSId) ) \
     924                 :     { \
     925                 :         sqlite3_result_null(pContext); \
     926                 :         return; \
     927                 :     } \
     928                 :  \
     929                 :     OGR2SQLITE_SetGeom_AndDestroy(pContext, \
     930                 :                            poGeom1-> op (poGeom2), \
     931                 :                            nSRSId); \
     932                 :  \
     933                 :     delete poGeom1; \
     934                 :     delete poGeom2; \
     935                 : }
     936                 : 
     937                 : OGR2SQLITE_ST_geom_geomgeom_op(Intersection)
     938                 : OGR2SQLITE_ST_geom_geomgeom_op(Difference)
     939                 : OGR2SQLITE_ST_geom_geomgeom_op(Union)
     940                 : OGR2SQLITE_ST_geom_geomgeom_op(SymDifference)
     941                 : 
     942                 : /************************************************************************/
     943                 : /*                      OGR2SQLITE_ST_SRID()                            */
     944                 : /************************************************************************/
     945                 : 
     946                 : static
     947                 : void OGR2SQLITE_ST_SRID(sqlite3_context* pContext,
     948                 :                         int argc, sqlite3_value** argv)
     949                 : {
     950                 :     int nSRSId = -1;
     951                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, &nSRSId);
     952                 :     if( poGeom != NULL )
     953                 :     {
     954                 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     955                 :         sqlite3_result_int( pContext, nSRSId );
     956                 :         CPLPopErrorHandler();
     957                 :     }
     958                 :     else
     959                 :         sqlite3_result_null(pContext);
     960                 :     delete poGeom;
     961                 : }
     962                 : 
     963                 : /************************************************************************/
     964                 : /*                      OGR2SQLITE_ST_Area()                            */
     965                 : /************************************************************************/
     966                 : 
     967                 : static
     968                 : void OGR2SQLITE_ST_Area(sqlite3_context* pContext,
     969                 :                         int argc, sqlite3_value** argv)
     970                 : {
     971                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
     972                 :     if( poGeom != NULL )
     973                 :     {
     974                 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     975                 :         sqlite3_result_double( pContext, OGR_G_Area((OGRGeometryH)poGeom) );
     976                 :         CPLPopErrorHandler();
     977                 :     }
     978                 :     else
     979                 :         sqlite3_result_null(pContext);
     980                 :     delete poGeom;
     981                 : }
     982                 : 
     983                 : /************************************************************************/
     984                 : /*                     OGR2SQLITE_ST_Buffer()                           */
     985                 : /************************************************************************/
     986                 : 
     987                 : static
     988                 : void OGR2SQLITE_ST_Buffer(sqlite3_context* pContext,
     989                 :                           int argc, sqlite3_value** argv)
     990                 : {
     991                 :     int nSRSId = -1;
     992                 :     OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, &nSRSId);
     993                 :     int bGotVal;
     994                 :     double dfDist = OGR2SQLITE_GetValAsDouble(argv[1], &bGotVal);
     995                 :     if( poGeom != NULL && bGotVal )
     996                 :         OGR2SQLITE_SetGeom_AndDestroy(pContext, poGeom->Buffer(dfDist), nSRSId);
     997                 :     else
     998                 :         sqlite3_result_null(pContext);
     999                 :     delete poGeom;
    1000                 : }
    1001                 : 
    1002                 : /************************************************************************/
    1003                 : /*                    OGR2SQLITE_ST_MakePoint()                         */
    1004                 : /************************************************************************/
    1005                 : 
    1006                 : static
    1007                 : void OGR2SQLITE_ST_MakePoint(sqlite3_context* pContext,
    1008                 :                              int argc, sqlite3_value** argv)
    1009                 : {
    1010                 :     double dfX, dfY = 0.0;
    1011                 :     int bGotVal;
    1012                 :     dfX = OGR2SQLITE_GetValAsDouble(argv[0], &bGotVal);
    1013                 :     if( bGotVal )
    1014                 :         dfY = OGR2SQLITE_GetValAsDouble(argv[1], &bGotVal);
    1015                 :     if( !bGotVal )
    1016                 :     {
    1017                 :         sqlite3_result_null(pContext);
    1018                 :         return;
    1019                 :     }
    1020                 : 
    1021                 :     OGRPoint* poPoint;
    1022                 :     if( argc == 3 )
    1023                 :     {
    1024                 :         double dfZ = OGR2SQLITE_GetValAsDouble(argv[2], &bGotVal);
    1025                 :         if( !bGotVal )
    1026                 :         {
    1027                 :             sqlite3_result_null(pContext);
    1028                 :             return;
    1029                 :         }
    1030                 : 
    1031                 :         poPoint = new OGRPoint(dfX, dfY, dfZ);
    1032                 :     }
    1033                 :     else
    1034                 :         poPoint = new OGRPoint(dfX, dfY);
    1035                 : 
    1036                 :     OGR2SQLITE_SetGeom_AndDestroy(pContext, poPoint, -1);
    1037                 : }
    1038                 : 
    1039                 : #endif // #ifdef MINIMAL_SPATIAL_FUNCTIONS
    1040                 : 
    1041                 : /************************************************************************/
    1042                 : /*                   OGRSQLiteRegisterSQLFunctions()                    */
    1043                 : /************************************************************************/
    1044                 : 
    1045                 : static
    1046             751 : void* OGRSQLiteRegisterSQLFunctions(sqlite3* hDB)
    1047                 : {
    1048             751 :     OGRSQLiteExtensionData* pData = new OGRSQLiteExtensionData(hDB);
    1049                 : 
    1050                 :     sqlite3_create_function(hDB, "ogr_version", 0, SQLITE_ANY, NULL,
    1051             751 :                            OGR2SQLITE_ogr_version, NULL, NULL);
    1052                 : 
    1053                 :     sqlite3_create_function(hDB, "ogr_version", 1, SQLITE_ANY, NULL,
    1054             751 :                            OGR2SQLITE_ogr_version, NULL, NULL);
    1055                 : 
    1056                 :     sqlite3_create_function(hDB, "ogr_deflate", 1, SQLITE_ANY, NULL,
    1057             751 :                             OGR2SQLITE_ogr_deflate, NULL, NULL);
    1058                 : 
    1059                 :     sqlite3_create_function(hDB, "ogr_deflate", 2, SQLITE_ANY, NULL,
    1060             751 :                             OGR2SQLITE_ogr_deflate, NULL, NULL);
    1061                 : 
    1062                 :     sqlite3_create_function(hDB, "ogr_inflate", 1, SQLITE_ANY, NULL,
    1063             751 :                             OGR2SQLITE_ogr_inflate, NULL, NULL);
    1064                 : 
    1065                 :     sqlite3_create_function(hDB, "ogr_geocode", -1, SQLITE_ANY, pData,
    1066             751 :                             OGR2SQLITE_ogr_geocode, NULL, NULL);
    1067                 : 
    1068                 :     sqlite3_create_function(hDB, "ogr_geocode_reverse", -1, SQLITE_ANY, pData,
    1069             751 :                             OGR2SQLITE_ogr_geocode_reverse, NULL, NULL);
    1070                 : 
    1071                 :     sqlite3_create_function(hDB, "ogr_datasource_load_layers", 1, SQLITE_ANY, hDB,
    1072             751 :                             OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
    1073                 : 
    1074                 :     sqlite3_create_function(hDB, "ogr_datasource_load_layers", 2, SQLITE_ANY, hDB,
    1075             751 :                             OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
    1076                 : 
    1077                 :     sqlite3_create_function(hDB, "ogr_datasource_load_layers", 3, SQLITE_ANY, hDB,
    1078             751 :                             OGR2SQLITE_ogr_datasource_load_layers, NULL, NULL);
    1079                 : 
    1080                 : #if notdef
    1081                 :     sqlite3_create_function(hDB, "ogr_GetConfigOption", 1, SQLITE_ANY, NULL,
    1082                 :                             OGR2SQLITE_ogr_GetConfigOption, NULL, NULL);
    1083                 : 
    1084                 :     sqlite3_create_function(hDB, "ogr_SetConfigOption", 2, SQLITE_ANY, NULL,
    1085                 :                             OGR2SQLITE_ogr_SetConfigOption, NULL, NULL);
    1086                 : #endif
    1087                 : 
    1088                 :     // Custom and undocumented function, not sure I'll keep it.
    1089                 :     sqlite3_create_function(hDB, "Transform3", 3, SQLITE_ANY, pData,
    1090             751 :                             OGR2SQLITE_Transform, NULL, NULL);
    1091                 : 
    1092                 : #ifdef MINIMAL_SPATIAL_FUNCTIONS
    1093                 :     /* Check if spatialite is available */
    1094                 :     int rc = sqlite3_exec(hDB, "SELECT spatialite_version()", NULL, NULL, NULL);
    1095                 :     
    1096                 :     /* Reset error flag */
    1097                 :     sqlite3_exec(hDB, "SELECT 1", NULL, NULL, NULL);
    1098                 :     
    1099                 :     if( rc != SQLITE_OK &&
    1100                 :         CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_SPATIAL_FUNCTIONS", "YES")) )
    1101                 :     {
    1102                 :         CPLDebug("SQLITE",
    1103                 :                  "Spatialite not available. Implementing a few functions");
    1104                 : 
    1105                 : #define REGISTER_ST_op(argc, op) \
    1106                 :         sqlite3_create_function(hDB, #op, argc, SQLITE_ANY, NULL, \
    1107                 :                                 OGR2SQLITE_ST_##op, NULL, NULL); \
    1108                 :         sqlite3_create_function(hDB, "ST_" #op, argc, SQLITE_ANY, NULL, \
    1109                 :                                 OGR2SQLITE_ST_##op, NULL, NULL);
    1110                 : 
    1111                 :         REGISTER_ST_op(1, AsText);
    1112                 :         REGISTER_ST_op(1, AsBinary);
    1113                 :         REGISTER_ST_op(1, GeomFromText);
    1114                 :         REGISTER_ST_op(2, GeomFromText);
    1115                 :         REGISTER_ST_op(1, GeomFromWKB);
    1116                 :         REGISTER_ST_op(2, GeomFromWKB);
    1117                 : 
    1118                 :         REGISTER_ST_op(1, IsEmpty);
    1119                 :         REGISTER_ST_op(1, IsSimple);
    1120                 :         REGISTER_ST_op(1, IsValid);
    1121                 : 
    1122                 :         REGISTER_ST_op(2, Intersects);
    1123                 :         REGISTER_ST_op(2, Equals);
    1124                 :         REGISTER_ST_op(2, Disjoint);
    1125                 :         REGISTER_ST_op(2, Touches);
    1126                 :         REGISTER_ST_op(2, Crosses);
    1127                 :         REGISTER_ST_op(2, Within);
    1128                 :         REGISTER_ST_op(2, Contains);
    1129                 :         REGISTER_ST_op(2, Overlaps);
    1130                 : 
    1131                 :         REGISTER_ST_op(2, Intersection);
    1132                 :         REGISTER_ST_op(2, Difference);
    1133                 :         // Union() is invalid
    1134                 :         sqlite3_create_function(hDB, "ST_Union", 2, SQLITE_ANY, NULL,
    1135                 :                                 OGR2SQLITE_ST_Union, NULL, NULL);
    1136                 :         REGISTER_ST_op(2, SymDifference);
    1137                 : 
    1138                 :         REGISTER_ST_op(1, SRID);
    1139                 :         REGISTER_ST_op(1, Area);
    1140                 :         REGISTER_ST_op(2, Buffer);
    1141                 :         REGISTER_ST_op(2, MakePoint);
    1142                 :         REGISTER_ST_op(3, MakePoint);
    1143                 :     }
    1144                 : #endif // #ifdef MINIMAL_SPATIAL_FUNCTIONS
    1145                 : 
    1146             751 :     pData->SetRegExpCache(OGRSQLiteRegisterRegExpFunction(hDB));
    1147                 : 
    1148             751 :     return pData;
    1149                 : }
    1150                 : 
    1151                 : /************************************************************************/
    1152                 : /*                   OGRSQLiteUnregisterSQLFunctions()                  */
    1153                 : /************************************************************************/
    1154                 : 
    1155                 : static
    1156             751 : void OGRSQLiteUnregisterSQLFunctions(void* hHandle)
    1157                 : {
    1158             751 :     OGRSQLiteExtensionData* pData = (OGRSQLiteExtensionData* )hHandle;
    1159             751 :     delete pData;
    1160             751 : }

Generated by: LCOV version 1.7