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