1 / 26

Advanced geodatabase customization

Advanced geodatabase customization. Lesson 5 overview. Accessing features with COM Geodatabase customization directions Class extensions Custom features Exercise 5: MudBank custom feature. Application. Application. GeoDatabase API. Geodatabase API. COM. COM. Database. Database.

kayla
Download Presentation

Advanced geodatabase customization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced geodatabase customization

  2. Lesson 5 overview • Accessing features with COM • Geodatabase customization directions • Class extensions • Custom features • Exercise 5: MudBank custom feature

  3. Application Application GeoDatabase API Geodatabase API COM COM Database Database Accessing features

  4. Application Clients GDB API COM Database Levels of geodatabase customization • Application • ArcMap Editor • Database • Class extensions • Custom features • Some application customizations can be accomplished at the database level • Example: Event handling for feature creation

  5. Database-level customizations • Change the default behavior of a feature class (e.g., new validation rules, custom database updates) • Two ways to implement behavior • Class extensions: Only loaded once when class is created • Custom features/objects: Applies to feature when created • Only applies to feature classes in a Personal or ArcSDE geodatabase

  6. Class extensions • Adds class-level behavior to object classes • Higher-level customization than custom features • Object is created when data is accessed • Common uses • Custom editing behavior • Custom rules and validation • Custom drawing: Renderers • Custom property inspector • Related object notification • Custom split policies

  7. Relationship between a class and an extension • Only one extension can be associated with a class • Component requires registration • On each client system • In categories: ESRI GeoObject Class Extension • Must associate class with new class extension • Insert GUID with UML or ArcObjects code ClassExtension ID Name CLSID EXTCLSID Feature classes 1 Laterals {3070721… {0368CF51… 2 Mains {3070721…

  8. Accessing the class from the extension • IClassExtension::Init() • IClassHelper – Reference is passed in • IClassHelper::Class – Acquire a reference to the class (e.g., m_ipClass) • IClassExtension::Shutdown() • Release m_ipClass reference STDMETHODIMP CMBClassExtension::Init(IClassHelper *pClassHelper,IPropertySet *pPropSet) { if (!pClassHelper) return E_POINTER; HRESULT hr; IClassPtr ipClass; hr = pClassHelper->get_Class(&m_ipClass); return S_OK; }

  9. Accessing data with a class extension • Data can be stored with a feature class • Clients can access data via extension • PropertySet is passed in upon initialization • Can also write data (property set) to the class • IClassSchemaEdit::AlterClassExtensionProperties STDMETHODIMP CMBClassExtension::Init(IClassHelper *pClassHelper,IPropertySet *pPropSet) { // Read stored symbol from property set CComVariant vSymbol; pPropSet->GetProperty(CComBstr("symbol"), &vSymbol); IUnknownPtr ipUnk(vSymbol.ppUnkVal); m_ipSymbolForFeatures = ipUnk; }

  10. ClassExtensions and object events • Implement IObjectClassEvents • Not an outbound interface • Similar to Editor events // TrackLifecycleExt.h class ATL_NO_VTABLE CTrackLifecycleExt : public ITrackLifecycleExt, public IClassExtension, public IObjectClassEvents {… // TrackLifecycleExt.cpp // IClassExtension STDMETHODIMP TrackLifecycleExt::Init (IClassHelper * pClassHelper, IPropertySet * pExtensionProperties) {… IClassPtr ipClass; ipFeatureClass->FindField (CComBSTR( L"CreationDate"),&m_creationDate)))… } // IObjectClassEvents STDMETHODIMP CTrackLifecycleExt::OnCreate (IObject * obj) {… SYSTEMTIME systemTime; DOUBLE dTime; ::GetLocalTime(&systemTime); ::SystemTimeToVariantTime(&systemTime, &dTime); CComVariant vTime(dTime); if (FAILED(hr = obj->put_Value (m_creationDate, vTime))) }

  11. ClassExtensions and custom drawing • Basic requirements 1. Implement IFeatureClassDraw 2. Renderer: esriCore or a custom renderer 3. Property page: esriCore or custom page • IFeatureClassDraw members • HasCustomRenderer – You have written your own renderer • CustomRenderer – Reference render to use always • ExclusiveCustomRenderer – User can change renderers via GUI • CustomRendererPropPageCLSID – Your custom property page

  12. Custom renderers • Implement IFeatureRenderer • Draw, PrepareFilter, ExclusionSet • ILegendInfo – Create symbols for the TOC • IPersistStream – Store LegendGroup and symbols STDMETHODIMP CMBRenderer::Draw(IFeatureCursor *pFeatureCursor,esriDrawPhase drawPhase,IDisplay *pDisplay,ITrackCancel *pTrackCancel) { // Just draw special if Geography, otherwise use default if (drawPhase != esriDPGeography) return E_NOTIMPL; // Loop through all the MudBanks, unioning all the Mudbanks into one polygon IGeometryPtr ipMudBankGeom(CLSID_Polygon); IFeaturePtr ipFeature; IMBClassExtensionPtr ipClassExtension; while (pFeatureCursor->NextFeature(&ipFeature) == S_OK) { // Do specialized drawing here… ipFeature->get_Shape(&ipFeatureGeom); ::Draw(pDisplay, ipSym, ipLandGeom) } … }

  13. Methods of applying class extensions • During creation • IFeatureWorkspace::CreateFeatureClass(pExtCLSID…) • After creation • IClassSchemaEdit::AlterClassExtensionCLSID(pExtCLSID…) • After creation and class extension is missing • IFeatureWorkspaceSchemaEdit::AlterClassExtensionCLSID • When modeling and designing in Visio • Create class extension and make association via UML • Set the CLSID tagged value to the component

  14. Custom objects • Extends row-level behavior for a class • Requires aggregation of an esriCore::Feature • Why create custom objects? • Complex network features: Switch gear • Custom features: Drawing, row updating • ESRI: Feature-link annotation and dimension • The reality… • Most customizations can be accomplishedwith class extensions • Do not want to compromise GDB integrity

  15. COM containment • Simplest form of binary reuse • Delegate requests to inner object • Provide custom behavior for selected members • Can wrap any coclass (e.g., esriCore commands) IUnknown MyAddDataCmd IUnknown (inner) IMyAddDataCmd esriCore. AddDataCommand ICommand ICommand Instructor Demo

  16. COM aggregation • Use to create custom features • Exposes interfaces of inner object directly • Provide implementation for contained interface/methods IUnknown (controlling Unknown) CustomFeature ICustomFeature IUnknown (inner) Feature IFeature IFeatureBuffer IFeatureDraw IFeatureDraw IFeatureEdit IFeatureEvents

  17. ATL macros for aggregation • One macro exposes controlling IUnknown (outer) • Another allows the class to be aggregated • Implement the interfaces you wish to contain // MBFeature.h : Declaration of the CMBFeature public: CMBFeature() : m_pInnerUnk(NULL) { } DECLARE_GET_CONTROLLING_UNKNOWN() … BEGIN_COM_MAP(CMBFeature) COM_INTERFACE_ENTRY(IMBFeature) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(IFeatureDraw) COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnk) END_COM_MAP() BEGIN_CATEGORY_MAP(CMBFeature) // Register in this component category IMPLEMENTED_CATEGORY(CATID_GeoObjects) END_CATEGORY_MAP() };

  18. Aggregating an esriCore::Feature in ATL • Cocreate esriCore object in FinalConstruct() • Hook inner and outer objects together via IUnknown • Get a reference to inner interface for containment // MBFeature.cpp HRESULT CMBFeature::FinalConstruct() { // Get outer object since this object may be aggregated in as well. IUnknown * pOuter = GetControllingUnknown(); // Aggregate in ESRI's simple Feature object if (FAILED (CoCreateInstance(CLSID_Feature, pOuter, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**) &m_pInnerUnk))) return E_FAIL; // Get reference to inner feature IFeatureDraw if (FAILED(m_pInnerUnk->QueryInterface(IID_IFeatureDraw, (void**)&m_pFeatureDraw))) return E_FAIL; return S_OK; }

  19. Custom drawing behavior • Call Draw() function in IFeature::Draw // MBFeature.cpp … // IFeatureDraw STDMETHODIMP CMBFeature::get_InvalidArea(IInvalidArea** ppInvalidArea) { return m_pFeatureDraw->get_InvalidArea(ppInvalidArea); // Use containment } STDMETHODIMP CMBFeature::putref_InvalidArea(IInvalidArea* pInvalidArea) { return m_pFeatureDraw->putref_InvalidArea(pInvalidArea); // Use containment } // Override the Draw method of IFeatureDraw STDMETHODIMP CMBFeature::Draw(esriDrawPhase drawPhase, IDisplay* pDisplay, ISymbol* pSymbol, VARIANT_BOOL SymbolInstalled, IGeometry* pGeometry, esriDrawStyle drawStyle) { … // Get the ClassExtension because it has the symbols and methods ipClassExtension->get_LandSymbol(&ipSym); ipClassExtension->get_IntersectingLandGeometry(ipMudBankGeom,&ipLandGeom); ::Draw(pDisplay, ipSym, ipLandGeom); return S_OK; }

  20. Relationship between a feature and a class • One feature object can be associated with a class • Component requires registration • On each client system • In categories: ESRI GeoObjects • Must associate feature with class • Insert GUID with UML or ArcObjects code CustomFeature ID Name CLSID EXTCLSID Feature classes 1 Laterals {3070721… {0368CF51… 2 Mains {8881110…

  21. Registering a custom feature • Use the selected object in ArcCatalog • Access IClassSchemaEdit, just like class extensions Public Sub LoadClassExtension() Dim pGxApp As IGxApplication Dim pGxCatalog As IGxCatalog Dim pGxSelection As IGxSelection Set pGxApp = Application Set pGxCatalog = pGxApp.Catalog Set pGxSelection = pGxCatalog.Selection Dim pGxEnum As IEnumGxObject Set pGxEnum = pGxSelection.SelectedObjects pGxEnum.Reset Dim pGxObject As IGxObject Set pGxObject = pGxEnum.Next If (pGxObject Is Nothing) Then Set pGxObject = pGxCatalog.SelectedObject If (TypeOf pGxObject Is IGxDataset) Then Dim pGxDataset As IGxDataset Dim pObjectClass As IObjectClass Dim pClassSchemaEdit As IClassSchemaEdit Set pGxDataset = pGxObject ' QI Set pObjectClass = pGxDataset.Dataset Set pClassSchemaEdit = pObjectClass Dim pUid As New UID pUid.Value = "{82F517DC-C600-11D4-9601-0080C7E61A96}" //pClassSchemaEdit.AlterClassExtensionCLSID pUid, Nothing pClassSchemaEdit.AlterInstanceCLSID pUid End If End Sub

  22. Modeling custom features in Visio • Inherit from esriCore::Feature • Assign custom feature via tagged values (CLSID) • Define other public members if necessary • Export to repository

  23. Building a Visual Studio workspace • Use ESRI Code Generation add-in to import repository • Creates an ATL project • Aggregates an esriCore::Feature object • Choose interface and members to contain • Adds public members modeled in Visio • Example: IBuilding::Age() and IBuilding::Owner() • Create the schema • Import repository to a database in ArcCatalog • Automatically applies GUIDs modeled • See Case Tools tutorial for more details

  24. Exercise 5 overview IUnknown • Aggregate in an esriCore::Feature • Implement IFeatureDraw • Implement a class extension • Add a renderer and property page • Challenge: Persistence IFeatureDraw CMBFeature esriCore::Feature IFeature CMBClassExtension IMBClassExtension IClassExtension IFeatureClassExtension IFeatureClassDraw IFeatureRenderer CMBRenderer ILegendInfo IPersistStream IPropertyPage CMBRendererPropertyPage IPropertyPageContext

  25. Review • When should you write a custom feature? • How do you register a custom feature with a feature class? • What other objects are often created with custom features or extensions? • When should you use IEditorEvents versus IObjectClassEvents? • What happens when a client application accesses a feature class, but does not have the custom feature DLL registered on their system?

More Related