STDMETHODIMP CSimplePointDatasetHelper::get_Fields(long ClassIndex, IFields **FieldSet) { if (! FieldSet) return E_POINTER; HRESULT hr; // First get the standard fields for an feature class IObjectClassDescriptionPtr ipOCDesc; hr = ipOCDesc.CreateInstance(CLSID_FeatureClassDescription); if (FAILED(hr)) return hr; IFieldsPtr ipFields; hr = ipOCDesc->get_RequiredFields(&ipFields); if (FAILED(hr)) return hr; IFieldPtr ipField; // We will have: a shape field name of "shape" // an UnknownCoordinateSystem // Just need to change the geometry type to Point long i; long lNumFields; esriFieldType eFieldType; hr = ipFields->get_FieldCount(&lNumFields); if (FAILED(hr)) return hr; for (i=0; i < lNumFields; i++) { hr = ipFields->get_Field(i, &ipField); if (FAILED(hr)) return hr; hr = ipField->get_Type(&eFieldType); if (eFieldType == esriFieldTypeGeometry) { IGeometryDefPtr ipGeomDef; hr = ipField->get_GeometryDef(&ipGeomDef); if (FAILED(hr)) return hr; IGeometryDefEditPtr ipGeomDefEdit = ipGeomDef; if (ipGeomDefEdit == NULL) return E_FAIL; hr = ipGeomDefEdit->put_GeometryType(esriGeometryPoint); if (FAILED(hr)) return hr; } } // Add the extra text field IFieldEditPtr ipFieldEdit; hr = ipFieldEdit.CreateInstance(CLSID_Field); if (FAILED(hr)) return hr; hr = ipFieldEdit->put_Name(L"Column1"); if (FAILED(hr)) return hr; hr = ipFieldEdit->put_Type(esriFieldTypeString); if (FAILED(hr)) return hr; hr = ipFieldEdit->put_Length(1); if (FAILED(hr)) return hr; IFieldsEditPtr ipFieldsEdit = ipFields; if (ipFieldsEdit == NULL) return E_FAIL; ipField = ipFieldEdit; if (ipField == NULL) return E_FAIL; hr = ipFieldsEdit->AddField(ipField); if (FAILED(hr)) return hr; *FieldSet = ipFields.Detach(); // pass ownership of object to client return S_OK; }
bool AOLayer::Initialize(ITable* pTable) { HRESULT hr; m_ipTable = pTable; CComBSTR temp; IDatasetPtr ipDataset = m_ipTable; if (FAILED(hr = ipDataset->get_Name(&temp))) return false; m_pFeatureDefn = new OGRFeatureDefn(CW2A(temp)); //Should I "new" an OGR smart pointer - sample says so, but it doesn't seem right //as long as we use the same compiler & settings in both the ogr build and this //driver, we should be OK m_pFeatureDefn->Reference(); IFeatureClassPtr ipFC = m_ipTable; VARIANT_BOOL hasOID = VARIANT_FALSE; ipFC->get_HasOID(&hasOID); if (hasOID == VARIANT_TRUE) { ipFC->get_OIDFieldName(&temp); m_strOIDFieldName = CW2A(temp); } if (FAILED(hr = ipFC->get_ShapeFieldName(&temp))) return AOErr(hr, "No shape field found!"); m_strShapeFieldName = CW2A(temp); IFieldsPtr ipFields; if (FAILED(hr = ipFC->get_Fields(&ipFields))) return AOErr(hr, "Fields not found!"); long shapeIndex = -1; if (FAILED(hr = ipFields->FindField(temp, &shapeIndex))) return AOErr(hr, "Shape field not found!"); IFieldPtr ipShapeField; if (FAILED(hr = ipFields->get_Field(shapeIndex, &ipShapeField))) return false; // Use GeometryDef to set OGR shapetype and Spatial Reference information // IGeometryDefPtr ipGeoDef; if (FAILED(hr = ipShapeField->get_GeometryDef(&ipGeoDef))) return false; OGRwkbGeometryType ogrGeoType; if (!AOToOGRGeometry(ipGeoDef, &ogrGeoType)) return false; m_pFeatureDefn->SetGeomType(ogrGeoType); if (wkbFlatten(ogrGeoType) == wkbMultiLineString || wkbFlatten(ogrGeoType) == wkbMultiPoint) m_forceMulti = true; // Mapping of Spatial Reference will be passive about errors // (it is possible we won't be able to map some ESRI-specific projections) esriGeometry::ISpatialReferencePtr ipSR = NULL; if (FAILED(hr = ipGeoDef->get_SpatialReference(&ipSR))) { AOErr(hr, "Failed Fetching ESRI spatial reference"); } else { if (!AOToOGRSpatialReference(ipSR, &m_pSRS)) { //report error, but be passive about it CPLError( CE_Warning, CPLE_AppDefined, "Failed Mapping ESRI Spatial Reference"); } } // Map fields // return AOToOGRFields(ipFields, m_pFeatureDefn, m_OGRFieldToESRIField); }