LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/libkml - ogrlibkmldrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 46 47 97.9 %
Date: 2024-05-02 22:57:13 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  KML Translator
       4             :  * Purpose:  Implements OGRLIBKMLDriver
       5             :  * Author:   Brian Case, rush at winkey dot org
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2010, Brian Case
       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 "ogrsf_frmts.h"
      30             : 
      31             : #include "ogrlibkmldrivercore.h"
      32             : 
      33             : /************************************************************************/
      34             : /*                    OGRLIBKMLDriverIdentify()                         */
      35             : /************************************************************************/
      36             : 
      37       43772 : int OGRLIBKMLDriverIdentify(GDALOpenInfo *poOpenInfo)
      38             : 
      39             : {
      40       43772 :     if (!poOpenInfo->bStatOK)
      41       40271 :         return FALSE;
      42        3501 :     if (poOpenInfo->bIsDirectory)
      43         343 :         return -1;
      44             : 
      45        3158 :     const char *pszExt = CPLGetExtension(poOpenInfo->pszFilename);
      46        3158 :     if (EQUAL(pszExt, "kml") || EQUAL(pszExt, "kmz"))
      47             :     {
      48         159 :         return TRUE;
      49             :     }
      50             : 
      51        2999 :     if (poOpenInfo->pabyHeader &&
      52        2994 :         (strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader), "<kml") !=
      53        2994 :              nullptr ||
      54        2994 :          strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader), "<kml:kml") !=
      55             :              nullptr))
      56             :     {
      57           0 :         return TRUE;
      58             :     }
      59             : 
      60        2999 :     return FALSE;
      61             : }
      62             : 
      63             : /************************************************************************/
      64             : /*                  OGRLIBKMLDriverSetCommonMetadata()                  */
      65             : /************************************************************************/
      66             : 
      67        1234 : void OGRLIBKMLDriverSetCommonMetadata(GDALDriver *poDriver)
      68             : {
      69        1234 :     poDriver->SetDescription(DRIVER_NAME);
      70        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
      71        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
      72        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_DELETE_LAYER, "YES");
      73        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
      74        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
      75        1234 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
      76        1234 :                               "Keyhole Markup Language (LIBKML)");
      77        1234 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "kml kmz");
      78        1234 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/libkml.html");
      79        1234 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
      80             : 
      81        1234 :     poDriver->SetMetadataItem(
      82             :         GDAL_DMD_CREATIONOPTIONLIST,
      83             :         "<CreationOptionList>"
      84             :         "  <Option name='DOCUMENT_ID' type='string' description='Id of the "
      85             :         "root &lt;Document&gt; node' default='root_doc'/>"
      86             :         "  <Option name='AUTHOR_NAME' type='string' description='Name in "
      87             :         "&lt;atom:Author&gt; element'/>"
      88             :         "  <Option name='AUTHOR_URI' type='string' description='URI in "
      89             :         "&lt;atom:Author&gt; element'/>"
      90             :         "  <Option name='AUTHOR_EMAIL' type='string' description='Email in "
      91             :         "&lt;atom:Author&gt; element'/>"
      92             :         "  <Option name='LINK' type='string' description='Href of "
      93             :         "&lt;atom:link&gt; element'/>"
      94             :         "  <Option name='PHONENUMBER' type='string' description='Value of "
      95             :         "&lt;phoneNumber&gt; element'/>"
      96             :         "  <Option name='NAME' type='string' description='Value of "
      97             :         "&lt;name&gt; element of top container'/>"
      98             :         "  <Option name='VISIBILITY' type='integer' description='Value of "
      99             :         "&lt;visibility&gt; element of top container (0/1)'/>"
     100             :         "  <Option name='OPEN' type='integer' description='Value of "
     101             :         "&lt;open&gt; element of top container (0/1)'/>"
     102             :         "  <Option name='SNIPPET' type='string' description='Value of "
     103             :         "&lt;snippet&gt; element of top container'/>"
     104             :         "  <Option name='DESCRIPTION' type='string' description='Value of "
     105             :         "&lt;description&gt; element of top container'/>"
     106             :         "  <Option name='LISTSTYLE_TYPE' type='string-select' "
     107             :         "description='Value of &lt;listItemType&gt; element of top container'>"
     108             :         "    <Value>check</Value>"
     109             :         "    <Value>radioFolder</Value>"
     110             :         "    <Value>checkOffOnly</Value>"
     111             :         "    <Value>checkHideChildren</Value>"
     112             :         "  </Option>"
     113             :         "  <Option name='LISTSTYLE_ICON_HREF' type='string' description='URL "
     114             :         "of the icon to display for the main folder. Sets the href element of "
     115             :         "the &lt;ItemIcon&gt; element'/>"
     116             :         "  <Option name='*_BALLOONSTYLE_BGCOLOR' type='string' "
     117             :         "description='Background color of a &lt;BallonStyle&gt; element if a "
     118             :         "style X is defined'/>"
     119             :         "  <Option name='*_BALLOONSTYLE_TEXT' type='string' description='Text "
     120             :         "of a &lt;BallonStyle&gt; element if a style X is defined'/>"
     121             :         "  <Option name='NLC_MINREFRESHPERIOD' type='float' "
     122             :         "description='&lt;minRefreshPeriod&gt; element of a "
     123             :         "&lt;NetworkLinkControl&gt; element'/>"
     124             :         "  <Option name='NLC_MAXSESSIONLENGTH' type='float' "
     125             :         "description='&lt;maxSessionLength&gt; element of a "
     126             :         "&lt;NetworkLinkControl&gt; element'/>"
     127             :         "  <Option name='NLC_COOKIE' type='string' description='&lt;cookie&gt; "
     128             :         "element of a &lt;NetworkLinkControl&gt; element'/>"
     129             :         "  <Option name='NLC_MESSAGE' type='string' "
     130             :         "description='&lt;message&gt; element of a &lt;NetworkLinkControl&gt; "
     131             :         "element'/>"
     132             :         "  <Option name='NLC_LINKNAME' type='string' "
     133             :         "description='&lt;linkName&gt; element of a &lt;NetworkLinkControl&gt; "
     134             :         "element'/>"
     135             :         "  <Option name='NLC_LINKDESCRIPTION' type='string' "
     136             :         "description='&lt;linkDescription&gt; element of a "
     137             :         "&lt;NetworkLinkControl&gt; element'/>"
     138             :         "  <Option name='NLC_LINKSNIPPET' type='string' "
     139             :         "description='&lt;linkSnippet&gt; element of a "
     140             :         "&lt;NetworkLinkControl&gt; element'/>"
     141             :         "  <Option name='NLC_EXPIRES' type='string' description='Date to set "
     142             :         "in &lt;expires&gt; element of a &lt;NetworkLinkControl&gt; element'/>"
     143             :         "  <Option name='UPDATE_TARGETHREF' type='string' description='If set, "
     144             :         "a NetworkLinkControl KML file with an &lt;Update&gt; element will be "
     145             :         "generated'/>"
     146        1234 :         "</CreationOptionList>");
     147             : 
     148        1234 :     poDriver->SetMetadataItem(
     149             :         GDAL_DS_LAYER_CREATIONOPTIONLIST,
     150             :         "<LayerCreationOptionList>"
     151             :         "  <Option name='NAME' type='string' description='Value of "
     152             :         "&lt;name&gt; element of layer container'/>"
     153             :         "  <Option name='VISIBILITY' type='integer' description='Value of "
     154             :         "&lt;visibility&gt; element of layer container (0/1)'/>"
     155             :         "  <Option name='OPEN' type='integer' description='Value of "
     156             :         "&lt;open&gt; element of layer container (0/1)'/>"
     157             :         "  <Option name='SNIPPET' type='string' description='Value of "
     158             :         "&lt;snippet&gt; element of layer container'/>"
     159             :         "  <Option name='DESCRIPTION' type='string' description='Value of "
     160             :         "&lt;description&gt; element of layer container'/>"
     161             :         "  <Option name='LOOKAT_LONGITUDE' type='float' "
     162             :         "description='&lt;longitude&gt; of a &lt;LookAt&gt; element at layer "
     163             :         "level' min='-180' max='180'/>"
     164             :         "  <Option name='LOOKAT_LATITUDE' type='float' "
     165             :         "description='&lt;latitude&gt; of a &lt;LookAt&gt; element at layer "
     166             :         "level' min='-90' max='90'/>"
     167             :         "  <Option name='LOOKAT_RANGE' type='float' description='&lt;range&gt; "
     168             :         "of a &lt;LookAt&gt; element at layer level' min='0'/>"
     169             :         "  <Option name='LOOKAT_HEADING' type='float' "
     170             :         "description='&lt;heading&gt; of a &lt;LookAt&gt; element at layer "
     171             :         "level'/>"
     172             :         "  <Option name='LOOKAT_TILT' type='float' description='&lt;tilt&gt; "
     173             :         "of a &lt;LookAt&gt; element at layer level'/>"
     174             :         "  <Option name='LOOKAT_ALTITUDE' type='float' "
     175             :         "description='&lt;altitude&gt; of a &lt;LookAt&gt; element at layer "
     176             :         "level'/>"
     177             :         "  <Option name='LOOKAT_ALTITUDEMODE' type='string-select' "
     178             :         "description='&lt;altitudeMode&gt; of a &lt;LookAt&gt; element at "
     179             :         "layer level'>"
     180             :         "    <Value>clampToGround</Value>"
     181             :         "    <Value>relativeToGround</Value>"
     182             :         "    <Value>absolute</Value>"
     183             :         "    <Value>clampToSeaFloor</Value>"
     184             :         "    <Value>relativeToSeaFloor</Value>"
     185             :         "  </Option>"
     186             :         "  <Option name='CAMERA_LONGITUDE' type='float' "
     187             :         "description='&lt;longitude&gt; of a &lt;Camera&gt; element at layer "
     188             :         "level' min='-180' max='180'/>"
     189             :         "  <Option name='CAMERA_LATITUDE' type='float' "
     190             :         "description='&lt;latitude&gt; of a &lt;Camera&gt; element at layer "
     191             :         "level' min='-90' max='90'/>"
     192             :         "  <Option name='CAMERA_HEADING' type='float' "
     193             :         "description='&lt;heading&gt; of a &lt;Camera&gt; element at layer "
     194             :         "level'/>"
     195             :         "  <Option name='CAMERA_TILT' type='float' description='&lt;tilt&gt; "
     196             :         "of a &lt;Camera&gt; element at layer level'/>"
     197             :         "  <Option name='CAMERA_ROLL' type='float' description='&lt;roll&gt; "
     198             :         "of a &lt;Camera&gt; element at layer level'/>"
     199             :         "  <Option name='CAMERA_ALTITUDE' type='float' "
     200             :         "description='&lt;altitude&gt; of a &lt;Camera&gt; element at layer "
     201             :         "level'/>"
     202             :         "  <Option name='CAMERA_ALTITUDEMODE' type='string-select' "
     203             :         "description='&lt;altitudeMode&gt; of a &lt;Camera&gt; element at "
     204             :         "layer level'>"
     205             :         "    <Value>clampToGround</Value>"
     206             :         "    <Value>relativeToGround</Value>"
     207             :         "    <Value>absolute</Value>"
     208             :         "    <Value>clampToSeaFloor</Value>"
     209             :         "    <Value>relativeToSeaFloor</Value>"
     210             :         "  </Option>"
     211             :         "  <Option name='ADD_REGION' type='boolean' description='Whether to "
     212             :         "generate a &lt;Region&gt; element to control when objects of the "
     213             :         "layer are visible or not' default='NO'/>"
     214             :         "  <Option name='REGION_XMIN' type='float' description='West "
     215             :         "coordinate of the region' min='-180' max='180'/>"
     216             :         "  <Option name='REGION_YMIN' type='float' description='South "
     217             :         "coordinate of the region' min='-90' max='90'/>"
     218             :         "  <Option name='REGION_XMAX' type='float' description='East "
     219             :         "coordinate of the region' min='-180' max='180'/>"
     220             :         "  <Option name='REGION_YMAX' type='float' description='North "
     221             :         "coordinate of the region' min='-90' max='90'/>"
     222             :         "  <Option name='REGION_MIN_LOD_PIXELS' type='float' "
     223             :         "description='minimum size in pixels of the region so that it is "
     224             :         "displayed' default='256'/>"
     225             :         "  <Option name='REGION_MAX_LOD_PIXELS' type='float' "
     226             :         "description='maximum size in pixels of the region so that it is "
     227             :         "displayed (-1=infinite)' default='-1'/>"
     228             :         "  <Option name='REGION_MIN_FADE_EXTENT' type='float' "
     229             :         "description='distance over which the geometry fades, from fully "
     230             :         "opaque to fully transparent' default='0'/>"
     231             :         "  <Option name='REGION_MAX_FADE_EXTENT' type='float' "
     232             :         "description='distance over which the geometry fades, from fully "
     233             :         "transparent to fully opaque' default='0'/>"
     234             :         "  <Option name='SO_HREF' type='string' description='URL of the image "
     235             :         "to display in a &lt;ScreenOverlay&gt;'/>"
     236             :         "  <Option name='SO_NAME' type='string' description='&lt;name&gt; of a "
     237             :         "&lt;ScreenOverlay&gt;'/>"
     238             :         "  <Option name='SO_DESCRIPTION' type='string' "
     239             :         "description='&lt;description&gt; of a &lt;ScreenOverlay&gt;'/>"
     240             :         "  <Option name='SO_OVERLAY_X' type='float' description='x attribute "
     241             :         "of the &lt;overlayXY&gt; of a &lt;ScreenOverlay&gt;'/>"
     242             :         "  <Option name='SO_OVERLAY_Y' type='float' description='y attribute "
     243             :         "of the &lt;overlayXY&gt; of a &lt;ScreenOverlay&gt;'/>"
     244             :         "  <Option name='SO_OVERLAY_XUNITS' type='string-select' "
     245             :         "description='xunits attribute of the &lt;overlayXY&gt; of a "
     246             :         "&lt;ScreenOverlay&gt;'>"
     247             :         "    <Value>fraction</Value>"
     248             :         "    <Value>pixels</Value>"
     249             :         "    <Value>insetPixels</Value>"
     250             :         "  </Option>"
     251             :         "  <Option name='SO_OVERLAY_YUNITS' type='string-select' "
     252             :         "description='yunits attribute of the &lt;overlayXY&gt; of a "
     253             :         "&lt;ScreenOverlay&gt;'>"
     254             :         "    <Value>fraction</Value>"
     255             :         "    <Value>pixels</Value>"
     256             :         "    <Value>insetPixels</Value>"
     257             :         "  </Option>"
     258             :         "  <Option name='SO_SCREEN_X' type='float' description='x attribute of "
     259             :         "the &lt;screenXY&gt; of a &lt;ScreenOverlay&gt;' default='0.05'/>"
     260             :         "  <Option name='SO_SCREEN_Y' type='float' description='y attribute of "
     261             :         "the &lt;screenXY&gt; of a &lt;ScreenOverlay&gt;' default='0.05'/>"
     262             :         "  <Option name='SO_SCREEN_XUNITS' type='string-select' "
     263             :         "description='xunits attribute of the &lt;screenXY&gt; of a "
     264             :         "&lt;ScreenOverlay&gt;' default='fraction'>"
     265             :         "    <Value>fraction</Value>"
     266             :         "    <Value>pixels</Value>"
     267             :         "    <Value>insetPixels</Value>"
     268             :         "  </Option>"
     269             :         "  <Option name='SO_SCREEN_YUNITS' type='string-select' "
     270             :         "description='yunits attribute of the &lt;screenXY&gt; of a "
     271             :         "&lt;ScreenOverlay&gt;' default='fraction'>"
     272             :         "    <Value>fraction</Value>"
     273             :         "    <Value>pixels</Value>"
     274             :         "    <Value>insetPixels</Value>"
     275             :         "  </Option>"
     276             :         "  <Option name='SO_SIZE_X' type='float' description='x attribute of "
     277             :         "the &lt;sizeXY&gt; of a &lt;ScreenOverlay&gt;'/>"
     278             :         "  <Option name='SO_SIZE_Y' type='float' description='y attribute of "
     279             :         "the &lt;sizeXY&gt; of a &lt;ScreenOverlay&gt;'/>"
     280             :         "  <Option name='SO_SIZE_XUNITS' type='string-select' "
     281             :         "description='xunits attribute of the &lt;sizeXY&gt; of a "
     282             :         "&lt;ScreenOverlay&gt;'>"
     283             :         "    <Value>fraction</Value>"
     284             :         "    <Value>pixels</Value>"
     285             :         "    <Value>insetPixels</Value>"
     286             :         "  </Option>"
     287             :         "  <Option name='SO_SIZE_YUNITS' type='string-select' "
     288             :         "description='yunits attribute of the &lt;sizeXY&gt; of a "
     289             :         "&lt;ScreenOverlay&gt;'>"
     290             :         "    <Value>fraction</Value>"
     291             :         "    <Value>pixels</Value>"
     292             :         "    <Value>insetPixels</Value>"
     293             :         "  </Option>"
     294             :         "  <Option name='FOLDER' type='boolean' description='Whether to "
     295             :         "generate a &lt;Folder&gt; element for layers, instead of a "
     296             :         "&lt;Document&gt;' default='NO'/>"
     297             :         "  <Option name='LISTSTYLE_TYPE' type='string-select' "
     298             :         "description='Value of &lt;listItemType&gt; element of layer "
     299             :         "container'>"
     300             :         "    <Value>check</Value>"
     301             :         "    <Value>radioFolder</Value>"
     302             :         "    <Value>checkOffOnly</Value>"
     303             :         "    <Value>checkHideChildren</Value>"
     304             :         "  </Option>"
     305             :         "  <Option name='LISTSTYLE_ICON_HREF' type='string' description='URL "
     306             :         "of the icon to display for the layer folder. Sets the href element of "
     307             :         "the &lt;ItemIcon&gt; element'/>"
     308        1234 :         "</LayerCreationOptionList>");
     309             : 
     310        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     311        1234 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES,
     312        1234 :                               "Integer Real String");
     313        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES, "YES");
     314        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_READ, "YES");
     315        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_WRITE, "YES");
     316        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES");
     317             : 
     318        1234 :     poDriver->pfnIdentify = OGRLIBKMLDriverIdentify;
     319        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     320        1234 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
     321        1234 : }
     322             : 
     323             : /************************************************************************/
     324             : /*                   DeclareDeferredOGRLIBKMLPlugin()                   */
     325             : /************************************************************************/
     326             : 
     327             : #ifdef PLUGIN_FILENAME
     328        1512 : void DeclareDeferredOGRLIBKMLPlugin()
     329             : {
     330        1512 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     331             :     {
     332         295 :         return;
     333             :     }
     334        1217 :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     335             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     336             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     337             :                               PLUGIN_INSTALLATION_MESSAGE);
     338             : #endif
     339        1217 :     OGRLIBKMLDriverSetCommonMetadata(poDriver);
     340        1217 :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     341             : }
     342             : #endif

Generated by: LCOV version 1.14