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