LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/libkml - ogr_libkml.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 34 42 81.0 %
Date: 2026-01-23 20:24:11 Functions: 16 19 84.2 %

          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             :  * Copyright (c) 2010-2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  *****************************************************************************/
      13             : 
      14             : #ifndef HAVE_OGR_LIBKML_H
      15             : #define HAVE_OGR_LIBKML_H
      16             : 
      17             : #include "ogrsf_frmts.h"
      18             : 
      19             : #include "libkml_headers.h"
      20             : #include "fieldconfig.h"
      21             : 
      22             : #include <map>
      23             : 
      24             : class OGRLIBKMLDataSource;
      25             : 
      26             : CPLString OGRLIBKMLGetSanitizedNCName(const char *pszName);
      27             : 
      28             : /******************************************************************************
      29             :   layer class
      30             : ******************************************************************************/
      31             : 
      32             : class OGRLIBKMLLayer final : public OGRLayer,
      33             :                              public OGRGetNextFeatureThroughRaw<OGRLIBKMLLayer>
      34             : {
      35             :     bool m_bNew = false;
      36             :     bool bUpdate = false;
      37             : 
      38             :     int nFeatures = 0;
      39             :     int iFeature = 0;
      40             :     GIntBig nFID = 1;
      41             :     const char *m_pszName;
      42             :     const char *m_pszFileName;
      43             :     std::string m_osSanitizedNCName;
      44             : 
      45             :     kmldom::ContainerPtr m_poKmlLayer;
      46             :     kmldom::ElementPtr m_poKmlLayerRoot;
      47             :     kmldom::UpdatePtr m_poKmlUpdate;
      48             : 
      49             :     fieldconfig m_oFieldConfig;
      50             :     OGRLIBKMLDataSource *m_poOgrDS;
      51             :     OGRFeatureDefn *m_poOgrFeatureDefn;
      52             :     kmldom::SchemaPtr m_poKmlSchema;
      53             :     OGRSpatialReference *m_poOgrSRS;
      54             :     std::unique_ptr<OGRCoordinateTransformation> m_poCT{};
      55             : 
      56             :     bool m_bReadGroundOverlay;
      57             :     bool m_bUseSimpleField;
      58             : 
      59             :     bool m_bWriteRegion;
      60             :     bool m_bRegionBoundsAuto;
      61             :     double m_dfRegionMinLodPixels;
      62             :     double m_dfRegionMaxLodPixels;
      63             :     double m_dfRegionMinFadeExtent;
      64             :     double m_dfRegionMaxFadeExtent;
      65             :     double m_dfRegionMinX;
      66             :     double m_dfRegionMinY;
      67             :     double m_dfRegionMaxX;
      68             :     double m_dfRegionMaxY;
      69             : 
      70             :     CPLString osListStyleType;
      71             :     CPLString osListStyleIconHref;
      72             : 
      73             :     bool m_bUpdateIsFolder;
      74             : 
      75             :     bool m_bAllReadAtLeastOnce = false;
      76             :     std::map<GIntBig, std::string> m_oMapOGRIdToKmlId{};
      77             :     std::map<std::string, GIntBig> m_oMapKmlIdToOGRId{};
      78             :     std::map<std::string, int> m_oMapSimpleFieldNameToOgrFieldIx{};
      79             : 
      80             :     void ScanAllFeatures();
      81             :     OGRFeature *GetNextRawFeature();
      82             : 
      83             :   public:
      84             :     OGRLIBKMLLayer(const char *pszLayerName, OGRwkbGeometryType eGType,
      85             :                    const OGRSpatialReference *poSRSIn,
      86             :                    OGRLIBKMLDataSource *poOgrDS, kmldom::ElementPtr poKmlRoot,
      87             :                    kmldom::ContainerPtr poKmlContainer,
      88             :                    kmldom::UpdatePtr poKmlUpdate, const char *pszFileName,
      89             :                    bool bNew, bool bUpdate);
      90             :     ~OGRLIBKMLLayer() override;
      91             : 
      92         962 :     void ResetReading() override
      93             :     {
      94         962 :         iFeature = 0;
      95         962 :         nFID = 1;
      96         962 :     }
      97        1376 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRLIBKMLLayer)
      98             : 
      99        4407 :     const OGRFeatureDefn *GetLayerDefn() const override
     100             :     {
     101        4407 :         return m_poOgrFeatureDefn;
     102             :     }
     103             : 
     104             :     // OGRErr                    SetAttributeFilter(const char * );
     105             :     OGRErr ICreateFeature(OGRFeature *poOgrFeat) override;
     106             :     OGRErr ISetFeature(OGRFeature *poOgrFeat) override;
     107             :     OGRErr DeleteFeature(GIntBig nFID) override;
     108             : 
     109             :     GIntBig GetFeatureCount(int bForce = TRUE) override;
     110             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     111             :                       bool bForce) override;
     112             : 
     113             :     // const char               *GetInfo( const char * );
     114             : 
     115             :     OGRErr CreateField(const OGRFieldDefn *poField,
     116             :                        int bApproxOK = TRUE) override;
     117             : 
     118             :     OGRErr SyncToDisk() override;
     119             : 
     120             :     OGRStyleTable *GetStyleTable() override;
     121             :     void SetStyleTableDirectly(OGRStyleTable *poStyleTable) override;
     122             :     void SetStyleTable(OGRStyleTable *poStyleTable) override;
     123             : 
     124         240 :     const char *GetName() const override
     125             :     {
     126         240 :         return m_pszName;
     127             :     }
     128             : 
     129             :     int TestCapability(const char *) const override;
     130             : 
     131             :     GDALDataset *GetDataset() override;
     132             : 
     133         297 :     kmldom::ContainerPtr GetKmlLayer()
     134             :     {
     135         297 :         return m_poKmlLayer;
     136             :     }
     137             : 
     138          46 :     kmldom::ElementPtr GetKmlLayerRoot()
     139             :     {
     140          46 :         return m_poKmlLayerRoot;
     141             :     }
     142             : 
     143         316 :     kmldom::SchemaPtr GetKmlSchema()
     144             :     {
     145         316 :         return m_poKmlSchema;
     146             :     }
     147             : 
     148          78 :     const char *GetFileName()
     149             :     {
     150          78 :         return m_pszFileName;
     151             :     }
     152             : 
     153        1554 :     const fieldconfig &GetFieldConfig() const
     154             :     {
     155        1554 :         return m_oFieldConfig;
     156             :     }
     157             : 
     158             :     void SetLookAt(const char *pszLookatLongitude,
     159             :                    const char *pszLookatLatitude, const char *pszLookatAltitude,
     160             :                    const char *pszLookatHeading, const char *pszLookatTilt,
     161             :                    const char *pszLookatRange,
     162             :                    const char *pszLookatAltitudeMode);
     163             :     void SetCamera(const char *pszCameraLongitude,
     164             :                    const char *pszCameraLatitude, const char *pszCameraAltitude,
     165             :                    const char *pszCameraHeading, const char *pszCameraTilt,
     166             :                    const char *pszCameraRoll,
     167             :                    const char *pszCameraAltitudeMode);
     168             : 
     169             :     static CPLString LaunderFieldNames(CPLString osName);
     170             : 
     171             :     void SetWriteRegion(double dfMinLodPixels, double dfMaxLodPixels,
     172             :                         double dfMinFadeExtent, double dfMaxFadeExtent);
     173             :     void SetRegionBounds(double dfMinX, double dfMinY, double dfMaxX,
     174             :                          double dfMaxY);
     175             : 
     176             :     void SetScreenOverlay(const char *pszSOHref, const char *pszSOName,
     177             :                           const char *pszSODescription,
     178             :                           const char *pszSOOverlayX, const char *pszSOOverlayY,
     179             :                           const char *pszSOOverlayXUnits,
     180             :                           const char *pszSOOverlayYUnits,
     181             :                           const char *pszSOScreenX, const char *pszSOScreenY,
     182             :                           const char *pszSOScreenXUnits,
     183             :                           const char *pszSOScreenYUnits, const char *pszSOSizeX,
     184             :                           const char *pszSOSizeY, const char *pszSOSizeXUnits,
     185             :                           const char *pszSOSizeYUnits);
     186             : 
     187             :     void SetListStyle(const char *pszListStyleType,
     188             :                       const char *pszListStyleIconHref);
     189             : 
     190             :     void Finalize(kmldom::DocumentPtr poKmlDocument);
     191             : 
     192           0 :     void SetUpdateIsFolder(int bUpdateIsFolder)
     193             :     {
     194           0 :         m_bUpdateIsFolder = CPL_TO_BOOL(bUpdateIsFolder);
     195           0 :     }
     196             : };
     197             : 
     198             : /******************************************************************************
     199             :   datasource class
     200             : ******************************************************************************/
     201             : 
     202             : class OGRLIBKMLDataSource final : public GDALDataset
     203             : {
     204             :     bool m_bIssuedCTError = false;
     205             : 
     206             :     /***** layers *****/
     207             :     OGRLIBKMLLayer **papoLayers;
     208             :     int nLayers;
     209             :     int nAllocated;
     210             :     std::map<CPLString, OGRLIBKMLLayer *> m_oMapLayers;
     211             : 
     212             :     bool bUpdate;
     213             :     bool bUpdated;
     214             :     CPLString osUpdateTargetHref;
     215             : 
     216             :     char **m_papszOptions;
     217             : 
     218             :     /***** for kml files *****/
     219             :     bool m_isKml;
     220             :     kmldom::KmlPtr m_poKmlDSKml;
     221             :     kmldom::ContainerPtr m_poKmlDSContainer;
     222             :     kmldom::UpdatePtr m_poKmlUpdate;
     223             : 
     224             :     /***** for kmz files *****/
     225             :     bool m_isKmz;
     226             :     kmldom::ContainerPtr m_poKmlDocKml;
     227             :     kmldom::ElementPtr m_poKmlDocKmlRoot;
     228             :     kmldom::ContainerPtr m_poKmlStyleKml;
     229             :     std::string m_osStylePath{};
     230             : 
     231             :     /***** for dir *****/
     232             :     int m_isDir;
     233             : 
     234             :     /***** the kml factory *****/
     235             :     kmldom::KmlFactory *m_poKmlFactory;
     236             : 
     237             :     /***** style table pointer *****/
     238             :     void SetCommonOptions(kmldom::ContainerPtr poKmlContainer,
     239             :                           CSLConstList papszOptions);
     240             : 
     241             :     void ParseDocumentOptions(kmldom::KmlPtr poKml,
     242             :                               kmldom::DocumentPtr poKmlDocument);
     243             : 
     244             :   public:
     245             :     explicit OGRLIBKMLDataSource(kmldom::KmlFactory *poKmlFactory);
     246             :     ~OGRLIBKMLDataSource() override;
     247             : 
     248          27 :     int GetLayerCount() const override
     249             :     {
     250          27 :         return nLayers;
     251             :     }
     252             : 
     253             :     const OGRLayer *GetLayer(int) const override;
     254             :     OGRLayer *GetLayerByName(const char *) override;
     255             :     OGRErr DeleteLayer(int) override;
     256             : 
     257             :     OGRLayer *ICreateLayer(const char *pszName,
     258             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     259             :                            CSLConstList papszOptions) override;
     260             : 
     261             :     OGRStyleTable *GetStyleTable() override;
     262             :     void SetStyleTableDirectly(OGRStyleTable *poStyleTable) override;
     263             :     void SetStyleTable(OGRStyleTable *poStyleTable) override;
     264             : 
     265             :     int Open(const char *pszFilename, bool bUpdate);
     266             :     int Create(const char *pszFilename, char **papszOptions);
     267             : 
     268             :     CPLErr FlushCache(bool bAtClosing) override;
     269             :     int TestCapability(const char *) const override;
     270             : 
     271         568 :     kmldom::KmlFactory *GetKmlFactory()
     272             :     {
     273         568 :         return m_poKmlFactory;
     274             :     }
     275             : 
     276         487 :     const std::string &GetStylePath() const
     277             :     {
     278         487 :         return m_osStylePath;
     279             :     }
     280             : 
     281             :     int ParseIntoStyleTable(std::string *oKmlStyleKml,
     282             :                             const char *pszStylePath);
     283             : 
     284             :     // KmzFile                  *GetKmz() { return m_poKmlKmzfile; }
     285             : 
     286         286 :     int IsKml() const
     287             :     {
     288         286 :         return m_isKml;
     289             :     }
     290             : 
     291         315 :     int IsKmz() const
     292             :     {
     293         315 :         return m_isKmz;
     294             :     }
     295             : 
     296         225 :     int IsDir() const
     297             :     {
     298         225 :         return m_isDir;
     299             :     }
     300             : 
     301         400 :     void Updated()
     302             :     {
     303         400 :         bUpdated = true;
     304         400 :     }
     305             : 
     306             :     int ParseLayers(kmldom::ContainerPtr poKmlContainer, bool bRecurse);
     307             :     kmldom::SchemaPtr FindSchema(const char *pszSchemaUrl);
     308             : 
     309           0 :     bool IsFirstCTError() const
     310             :     {
     311           0 :         return !m_bIssuedCTError;
     312             :     }
     313             : 
     314           0 :     void IssuedFirstCTError()
     315             :     {
     316           0 :         m_bIssuedCTError = true;
     317           0 :     }
     318             : 
     319             :   private:
     320             :     /***** methods to write out various datasource types at destroy *****/
     321             :     bool WriteKml();
     322             :     bool WriteKmz();
     323             :     bool WriteDir();
     324             : 
     325             :     /***** methods to open various datasource types *****/
     326             :     int OpenKmz(const char *pszFilename, int bUpdate);
     327             :     int OpenKml(const char *pszFilename, int bUpdate);
     328             :     int OpenDir(const char *pszFilename, int bUpdate);
     329             : 
     330             :     /***** methods to create various datasource types *****/
     331             :     int CreateKml(const char *pszFilename, char **papszOptions);
     332             :     int CreateKmz(const char *pszFilename, char **papszOptions);
     333             :     int CreateDir(const char *pszFilename, char **papszOptions);
     334             : 
     335             :     /***** methods to create layers on various datasource types *****/
     336             :     OGRLIBKMLLayer *CreateLayerKml(const char *pszLayerName,
     337             :                                    const OGRSpatialReference *poOgrSRS,
     338             :                                    OGRwkbGeometryType eGType,
     339             :                                    CSLConstList papszOptions);
     340             :     OGRLIBKMLLayer *CreateLayerKmz(const char *pszLayerName,
     341             :                                    const OGRSpatialReference *poOgrSRS,
     342             :                                    OGRwkbGeometryType eGType,
     343             :                                    CSLConstList papszOptions);
     344             : 
     345             :     /***** methods to delete layers on various datasource types *****/
     346             :     OGRErr DeleteLayerKml(int);
     347             :     OGRErr DeleteLayerKmz(int);
     348             : 
     349             :     /***** methods to write a styletable to various datasource types *****/
     350             :     void SetStyleTable2Kml(OGRStyleTable *poStyleTable);
     351             :     void SetStyleTable2Kmz(OGRStyleTable *poStyleTable);
     352             : 
     353             :     OGRLIBKMLLayer *
     354             :     AddLayer(const char *pszLayerName, OGRwkbGeometryType eGType,
     355             :              const OGRSpatialReference *poSRS, OGRLIBKMLDataSource *poOgrDS,
     356             :              kmldom::ElementPtr poKmlRoot, kmldom::ContainerPtr poKmlContainer,
     357             :              const char *pszFileName, bool bNew, bool bUpdate, int nGuess);
     358             : };
     359             : 
     360             : #endif

Generated by: LCOV version 1.14