root/FalconView/trunk/public/fvw_core/GeodataDataSources/LibkmlDataSource.h @ 2279

Revision 2279, 9.2 KB (checked in by gm78, 6 months ago)

Added threaded loading of KML images.

Line 
1// Copyright (c) 1994-2010 Georgia Tech Research Corporation, Atlanta, GA
2// This file is part of FalconView(tm).
3
4// FalconView(tm) is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// FalconView(tm) is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public License
15// along with FalconView(tm).  If not, see <http://www.gnu.org/licenses/>.
16
17// FalconView(tm) is a trademark of Georgia Tech Research Corporation.
18
19// LibkmlDataSource.h : Declaration of the CLibkmlDataSource
20
21#pragma once
22#include "resource.h"       // main symbols
23#include "ComErrorHandler.h"
24//#include "GeodataDataSources.h"
25#include "kml/dom.h"
26#include "kml/engine.h"
27#include "InternalObjectRegistry.h"
28#include "ComErrorObject.h"
29
30#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
31#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
32#endif
33
34
35class CKMLImageDataResource;
36
37class CKmlImageCache
38{
39   std::map<std::string, CKMLImageDataResource*> m_imageCache;
40   
41public:
42   void Insert(const std::string& imageId, CKMLImageDataResource *pResource);
43   CKMLImageDataResource* Find(const std::string& imageId);
44   void Clear();
45};
46
47// CLibkmlDataSource
48
49class ATL_NO_VTABLE CLibkmlDataSource :
50    public CComObjectRootEx<CComSingleThreadModel>,
51    public CComCoClass<CLibkmlDataSource, &CLSID_LibkmlDataSource>,
52    public IDispatchImpl<ILibkmlDataSource, &IID_ILibkmlDataSource, &LIBID_GeodataDataSourcesLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
53    public IDispatchImpl<IRegionatedKMLContainer, &IID_IRegionatedKMLContainer, &LIBID_GeodataDataSourcesLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
54   public IDispatchImpl<IFileDataSource, &__uuidof(IFileDataSource), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
55   public IDispatchImpl<IFvDataSource, &__uuidof(IFvDataSource), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
56   public IDispatchImpl<ISymbolFactory, &__uuidof(ISymbolFactory), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
57   public IDispatchImpl<IFvDataSourceEdit, &__uuidof(IFvDataSourceEdit), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
58   public IDispatchImpl<IUIState, &__uuidof(IUIState), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
59   public IDispatchImpl<IFvDataSourceCallback, &__uuidof(IUIState), &LIBID_FvDataSourcesLib, /* wMajor = */ 1, /* wMinor = */ 0>,
60   public CComErrorHandler
61{
62public:
63   CLibkmlDataSource() : m_root_element(NULL), m_internalRefs(0), m_factory(NULL), m_b_objectFinalReleased(false),
64      m_visible(VARIANT_TRUE), m_expanded(VARIANT_TRUE) {}
65
66   ULONG InternalRefCount() { return m_internalRefs; }
67
68   void __ensure_not_released()
69   {
70      // for debugging only
71      if (m_b_objectFinalReleased)
72         THROW_ERROR_MSG2(E_FAIL, "object already released");
73   }
74
75DECLARE_REGISTRY_RESOURCEID(IDR_LIBKMLDATASOURCE)
76
77BEGIN_COM_MAP(CLibkmlDataSource)
78    COM_INTERFACE_ENTRY(ILibkmlDataSource)
79    COM_INTERFACE_ENTRY2(IDispatch, IFileDataSource)
80   COM_INTERFACE_ENTRY(IFileDataSource)
81   COM_INTERFACE_ENTRY(IFvDataSource)
82    COM_INTERFACE_ENTRY(ISupportErrorInfo)
83   COM_INTERFACE_ENTRY(IFvDataSourceEdit)
84    COM_INTERFACE_ENTRY(ISymbolFactory)
85   COM_INTERFACE_ENTRY(IRegionatedKMLContainer)
86    COM_INTERFACE_ENTRY(IUIState)
87   COM_INTERFACE_ENTRY(IFvDataSourceCallback)
88END_COM_MAP()
89
90    DECLARE_PROTECT_FINAL_CONSTRUCT()
91
92    HRESULT FinalConstruct()
93    {
94      __ensure_not_released();
95      // register this object
96      m_handle = CInternalObjectRegistry::RegisterObject(this, "CLibkmlDataSource");
97        return S_OK;
98    }
99
100    void FinalRelease()
101    {
102      __ensure_not_released();
103      CInternalObjectRegistry::UnregisterObject(m_handle);
104      m_b_objectFinalReleased = true;
105
106      m_imageCache.Clear();
107    }
108
109   ULONG InternalAddRef()
110   {
111      ULONG refCountAfterAdd = CComObjectRootEx<_ThreadModel>::InternalAddRef();
112      return refCountAfterAdd;
113   }
114
115   ULONG InternalRelease()
116   {
117      // see comments in InternalRefAdding implementation
118      ULONG refCountAfterRelease = CComObjectRootEx<_ThreadModel>::InternalRelease();
119      if (refCountAfterRelease <= m_internalRefs)
120         m_root_element = NULL;
121      return refCountAfterRelease;
122   }
123
124   HRESULT WINAPI InternalQueryInterface(void* pThis, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
125   {
126      return CComObjectRootBase::InternalQueryInterface(pThis, pEntries, iid, ppvObject);
127   }
128
129public:
130   static IUnknown* WrapKMLElement(kmldom::ElementPtr element, kmlengine::KmlFilePtr kml_file, ILibkmlDataSource* rootDS);
131   static kmldom::GeometryPtr WrapGeometryInGeometry(IGeometry* geometry, kmldom::KmlFactory* factory);
132   static kmldom::PlacemarkPtr WrapFeatureInPlacemark(IFeature* feature, kmldom::KmlFactory* factory);
133
134   static void FireDataSourceChanged(LONG sourceHandle);
135
136   void FetchDataRelativeToDataSource(const char* path, std::string& out_string);
137   kmlengine::KmlFilePtr LoadKML(std::string &kml, const char* path);
138   void WrapKMLFile(const kmlengine::KmlFilePtr& kml_file);
139
140   void SetKmlFilePath(const std::string& path) { m_kml_file_path = path; }
141
142   // ILibkmlDataSource Methods
143public:
144   STDMETHOD(raw_InternalRefAdding)();
145   STDMETHOD(raw_InternalRefReleasing)();
146   STDMETHOD(raw_OpenFromURL)(BSTR url);
147   STDMETHOD(get_Handle)(LONG* handle);
148   STDMETHOD(get_URL)(BSTR* url);
149
150   // IFileDataSource Methods
151public:
152   STDMETHOD(raw_Open)(BSTR file);
153   STDMETHOD(raw_CheckFile)(BSTR path, VARIANT_BOOL confirmFileExists, VARIANT_BOOL* valid);
154   STDMETHOD(raw_CloseFile)();
155   STDMETHOD(raw_CreateNewFile)(BSTR file);
156
157   // IFvDataSource Methods
158public:
159   STDMETHOD(get_DataSetCount)(LONG* count);
160   STDMETHOD(raw_GetDataSet)(LONG index, IFvDataSet** dataSet);
161   STDMETHOD(get_Name)(BSTR* name);
162   STDMETHOD(raw_GetDataSetByName)(BSTR name, IFvDataSet** dataSet);
163   STDMETHOD(get_DataSourceCount)(LONG* count);
164   STDMETHOD(raw_GetDataSource)(LONG index, IFvDataSource** dataSource);
165   STDMETHOD(raw_GetDataSourceByName)(BSTR name, IFvDataSource** dataSource);
166   STDMETHOD(raw_Extent2D)(double* minX, double* minY, double* maxX, double* maxY);
167   STDMETHOD(get_Description)(BSTR* description);
168   STDMETHOD(raw_RegisterForCallbacks)(IFvDataSourceCallback* fvDataSourceCallback);
169   STDMETHOD(raw_UnregisterForCallbacks)(IFvDataSourceCallback* fvDataSourceCallback);
170   STDMETHOD(raw_CheckConnectString)(BSTR connectString, VARIANT_BOOL* valid);
171
172   // ISymbolFactory Methods
173public:
174   STDMETHOD(raw_GetImageByIdentifier)(BSTR identifier, VARIANT* imageData);
175
176   // IFvDataSourceCallback Methods
177public:
178   STDMETHOD(raw_DataSourceChanged)();
179
180   // IFvDataSourceEdit Methods
181public:
182    STDMETHOD(raw_StartEditing)();
183    STDMETHOD(raw_CreateEmptyFeatureDataSet)(BSTR name, BSTR description, IFeatureDataSetEdit** dataSetEdit);
184    STDMETHOD(raw_CopyDataSource)(IFvDataSource *dataSource);
185    STDMETHOD(raw_FinishEditing)();
186
187   // IRegionatedKMLContainer Methods
188public:
189    STDMETHOD(raw_SetRegionationParameters)(
190      DOUBLE leftLon, DOUBLE bottomLat, DOUBLE rightLon, DOUBLE topLat,
191      DOUBLE degreesPerPixelX, DOUBLE degreesPerPixelY);
192
193   // IUIState Methods
194public:
195   STDMETHOD(get_Visible)(VARIANT_BOOL *visible);
196   STDMETHOD(put_Visible)(VARIANT_BOOL visible);
197   STDMETHOD(get_Expanded)(VARIANT_BOOL *expanded);
198   STDMETHOD(put_Expanded)(VARIANT_BOOL expanded);
199
200private:
201   std::string SanitizeKMLString(std::string in_string);
202
203   LONG m_handle;
204   IFvDataSourcePtr m_root_element;
205   std::string m_kml_file_path; // this may be a file path our a URL, may be NULL if KMZ
206   kmlengine::KmzFilePtr m_kmz_file; // populate this if KMZ
207   ULONG m_internalRefs;
208   CKmlImageCache m_imageCache;
209   DATA_SOURCE_CALLBACK_VECTOR m_callbacks;
210   bool m_b_objectFinalReleased;
211   VARIANT_BOOL m_visible, m_expanded;
212
213   // stuff related to KML edit sessions
214   kmldom::KmlFactory* m_factory; // NULL if not in an editing session
215   kmldom::DocumentPtr m_document_being_edited; // the <Document> being edited
216   std::string m_editing_file_name;
217   void CopyDataSourceToDocument(IFvDataSource* dataSource, kmldom::DocumentPtr document);
218
219   // stuff for Easter egg to dump raw KML for problem solving
220   static BOOL s_bEnvironmentTested;
221   static std::string s_dumpFile;
222   static void MaybeDumpKML(std::string& kml);
223};
224
225OBJECT_ENTRY_AUTO(__uuidof(LibkmlDataSource), CLibkmlDataSource)
Note: See TracBrowser for help on using the browser.