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

Generated by: LCOV version 1.14