LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/pmtiles - ogrpmtilesdriver.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 73 87.7 %
Date: 2024-05-13 13:33:37 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implementation of PMTiles
       5             :  * Author:   Even Rouault <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Planet Labs
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "ogr_pmtiles.h"
      30             : 
      31             : #include "vsipmtiles.h"
      32             : 
      33             : #include "ogrpmtilesfrommbtiles.h"
      34             : 
      35             : #ifdef HAVE_MVT_WRITE_SUPPORT
      36             : #include "mvtutils.h"
      37             : #endif
      38             : 
      39             : /************************************************************************/
      40             : /*                     OGRPMTilesDriverIdentify()                       */
      41             : /************************************************************************/
      42             : 
      43       40495 : static int OGRPMTilesDriverIdentify(GDALOpenInfo *poOpenInfo)
      44             : {
      45       40495 :     if (poOpenInfo->nHeaderBytes < 127 || !poOpenInfo->fpL)
      46       39853 :         return FALSE;
      47         642 :     return memcmp(poOpenInfo->pabyHeader, "PMTiles\x03", 8) == 0;
      48             : }
      49             : 
      50             : /************************************************************************/
      51             : /*                       OGRPMTilesDriverOpen()                         */
      52             : /************************************************************************/
      53             : 
      54          42 : static GDALDataset *OGRPMTilesDriverOpen(GDALOpenInfo *poOpenInfo)
      55             : {
      56          42 :     if (!OGRPMTilesDriverIdentify(poOpenInfo))
      57           0 :         return nullptr;
      58          84 :     auto poDS = std::make_unique<OGRPMTilesDataset>();
      59          42 :     if (!poDS->Open(poOpenInfo))
      60           8 :         return nullptr;
      61          34 :     return poDS.release();
      62             : }
      63             : 
      64             : /************************************************************************/
      65             : /*                   OGRPMTilesDriverCanVectorTranslateFrom()           */
      66             : /************************************************************************/
      67             : 
      68           5 : static bool OGRPMTilesDriverCanVectorTranslateFrom(
      69             :     const char * /*pszDestName*/, GDALDataset *poSourceDS,
      70             :     CSLConstList papszVectorTranslateArguments, char ***ppapszFailureReasons)
      71             : {
      72           5 :     auto poSrcDriver = poSourceDS->GetDriver();
      73           5 :     if (!(poSrcDriver && EQUAL(poSrcDriver->GetDescription(), "MBTiles")))
      74             :     {
      75           1 :         if (ppapszFailureReasons)
      76           1 :             *ppapszFailureReasons = CSLAddString(
      77             :                 *ppapszFailureReasons, "Source driver is not MBTiles");
      78           1 :         return false;
      79             :     }
      80             : 
      81           4 :     if (papszVectorTranslateArguments)
      82             :     {
      83           2 :         const int nArgs = CSLCount(papszVectorTranslateArguments);
      84           4 :         for (int i = 0; i < nArgs; ++i)
      85             :         {
      86           2 :             if (i + 1 < nArgs &&
      87           2 :                 (strcmp(papszVectorTranslateArguments[i], "-f") == 0 ||
      88           0 :                  strcmp(papszVectorTranslateArguments[i], "-of") == 0))
      89             :             {
      90           2 :                 ++i;
      91             :             }
      92             :             else
      93             :             {
      94           0 :                 if (ppapszFailureReasons)
      95           0 :                     *ppapszFailureReasons =
      96           0 :                         CSLAddString(*ppapszFailureReasons,
      97             :                                      "Direct copy from MBTiles does not "
      98             :                                      "support GDALVectorTranslate() options");
      99           0 :                 return false;
     100             :             }
     101             :         }
     102             :     }
     103             : 
     104           4 :     return true;
     105             : }
     106             : 
     107             : /************************************************************************/
     108             : /*                   OGRPMTilesDriverVectorTranslateFrom()              */
     109             : /************************************************************************/
     110             : 
     111           2 : static GDALDataset *OGRPMTilesDriverVectorTranslateFrom(
     112             :     const char *pszDestName, GDALDataset *poSourceDS,
     113             :     CSLConstList papszVectorTranslateArguments,
     114             :     GDALProgressFunc /* pfnProgress */, void * /* pProgressData */)
     115             : {
     116           2 :     if (!OGRPMTilesDriverCanVectorTranslateFrom(
     117             :             pszDestName, poSourceDS, papszVectorTranslateArguments, nullptr))
     118             :     {
     119           0 :         return nullptr;
     120             :     }
     121             : 
     122           2 :     if (!OGRPMTilesConvertFromMBTiles(pszDestName,
     123           2 :                                       poSourceDS->GetDescription()))
     124             :     {
     125           0 :         return nullptr;
     126             :     }
     127             : 
     128           4 :     GDALOpenInfo oOpenInfo(pszDestName, GA_ReadOnly);
     129           2 :     return OGRPMTilesDriverOpen(&oOpenInfo);
     130             : }
     131             : 
     132             : #ifdef HAVE_MVT_WRITE_SUPPORT
     133             : /************************************************************************/
     134             : /*                                Create()                              */
     135             : /************************************************************************/
     136             : 
     137          34 : static GDALDataset *OGRPMTilesDriverCreate(const char *pszFilename, int nXSize,
     138             :                                            int nYSize, int nBandsIn,
     139             :                                            GDALDataType eDT,
     140             :                                            char **papszOptions)
     141             : {
     142          34 :     if (nXSize == 0 && nYSize == 0 && nBandsIn == 0 && eDT == GDT_Unknown)
     143             :     {
     144          68 :         auto poDS = std::make_unique<OGRPMTilesWriterDataset>();
     145          34 :         if (!poDS->Create(pszFilename, papszOptions))
     146           1 :             return nullptr;
     147          33 :         return poDS.release();
     148             :     }
     149           0 :     return nullptr;
     150             : }
     151             : #endif
     152             : 
     153             : /************************************************************************/
     154             : /*                          RegisterOGRPMTiles()                        */
     155             : /************************************************************************/
     156             : 
     157        1522 : void RegisterOGRPMTiles()
     158             : {
     159        1522 :     if (GDALGetDriverByName("PMTiles") != nullptr)
     160         301 :         return;
     161             : 
     162        1221 :     VSIPMTilesRegister();
     163             : 
     164        1221 :     GDALDriver *poDriver = new GDALDriver();
     165             : 
     166        1221 :     poDriver->SetDescription("PMTiles");
     167        1221 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     168        1221 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "ProtoMap Tiles");
     169        1221 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "pmtiles");
     170        1221 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC,
     171        1221 :                               "drivers/vector/pmtiles.html");
     172             : 
     173        1221 :     poDriver->SetMetadataItem(
     174             :         GDAL_DMD_OPENOPTIONLIST,
     175             :         "<OpenOptionList>"
     176             :         "  <Option name='ZOOM_LEVEL' type='integer' "
     177             :         "description='Zoom level of full resolution. If not specified, maximum "
     178             :         "non-empty zoom level'/>"
     179             :         "  <Option name='CLIP' type='boolean' "
     180             :         "description='Whether to clip geometries to tile extent' "
     181             :         "default='YES'/>"
     182             :         "  <Option name='ZOOM_LEVEL_AUTO' type='boolean' "
     183             :         "description='Whether to auto-select the zoom level for vector layers "
     184             :         "according to spatial filter extent. Only for display purpose' "
     185             :         "default='NO'/>"
     186             :         "  <Option name='JSON_FIELD' type='boolean' "
     187             :         "description='For vector layers, "
     188             :         "whether to put all attributes as a serialized JSon dictionary'/>"
     189        1221 :         "</OpenOptionList>");
     190             : 
     191        1221 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     192             : 
     193        1221 :     poDriver->pfnOpen = OGRPMTilesDriverOpen;
     194        1221 :     poDriver->pfnIdentify = OGRPMTilesDriverIdentify;
     195        1221 :     poDriver->pfnCanVectorTranslateFrom =
     196             :         OGRPMTilesDriverCanVectorTranslateFrom;
     197        1221 :     poDriver->pfnVectorTranslateFrom = OGRPMTilesDriverVectorTranslateFrom;
     198             : 
     199             : #ifdef HAVE_MVT_WRITE_SUPPORT
     200        1221 :     poDriver->SetMetadataItem(
     201             :         GDAL_DMD_CREATIONOPTIONLIST,
     202             :         "<CreationOptionList>"
     203             :         "  <Option name='NAME' scope='raster,vector' type='string' "
     204             :         "description='Tileset name'/>"
     205             :         "  <Option name='DESCRIPTION' scope='raster,vector' type='string' "
     206             :         "description='A description of the layer'/>"
     207             :         "  <Option name='TYPE' scope='raster,vector' type='string-select' "
     208             :         "description='Layer type' default='overlay'>"
     209             :         "    <Value>overlay</Value>"
     210             :         "    <Value>baselayer</Value>"
     211        1221 :         "  </Option>" MVT_MBTILES_PMTILES_COMMON_DSCO "</CreationOptionList>");
     212             : 
     213        1221 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     214        1221 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     215        1221 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     216        1221 :                               "Integer Integer64 Real String");
     217        1221 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATASUBTYPES,
     218        1221 :                               "Boolean Float32");
     219             : 
     220        1221 :     poDriver->SetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST, MVT_LCO);
     221             : 
     222        1221 :     poDriver->pfnCreate = OGRPMTilesDriverCreate;
     223             : #endif
     224             : 
     225        1221 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     226             : }

Generated by: LCOV version 1.14