int _tmain(int argc, _TCHAR* argv[]) { //This comes from the LicenseUtilities.h, not included with this code. if (!InitializeApp()) { AoExit(0); } try{ //These are the fields I am updating in addition to the location of the feature and the feature itself. const CComBSTR dataPath = "C:\\Users\\alex7370\\Documents\\CPPSample.gdb"; const CComBSTR featureClassName = "PointFeature"; const CComBSTR helloField = "Hello"; std::cerr << "Environmental Systems Reasearch Institute" << std::endl << std::endl; std::cerr << "Creating the workspace..." << std::endl; IWorkspaceFactory2Ptr workspacePtr(CLSID_FileGDBWorkspaceFactory); IWorkspacePtr workspace; HRESULT hr = workspacePtr->OpenFromFile(dataPath, 0, &workspace); if (FAILED(hr) || workspace == 0) { std::cerr << "Could not open the workspace." << std::endl; return E_FAIL; } std::cerr << "Casting to a feature workspace..." << std::endl; IFeatureWorkspacePtr featureWorkspace = workspace; IFeatureClassPtr featureClass; std::cerr << "Opening the feature class..." << std::endl; hr = featureWorkspace->OpenFeatureClass(featureClassName, &featureClass); if (FAILED(hr) || featureClass == 0) { std::cerr << "Could not open the feature class." << std::endl; return E_FAIL; } IFeatureBufferPtr featureBuffer; std::cerr << "Creating the feature buffer..." << std::endl; hr = featureClass->CreateFeatureBuffer(&featureBuffer); if (FAILED(hr) || featureClass == 0) { std::cerr << "Could not create the feature class." << std::endl; return E_FAIL; } IFeatureCursorPtr cursor; std::cerr << "Opening the feature Cursor..." << std::endl; hr = featureClass->Insert(VARIANT_TRUE, &cursor); if (FAILED(hr) || cursor == 0) { std::cerr << "Could not create the feature cursor." << std::endl; return E_FAIL; } IFieldsPtr fields; long index; CComVariant helloFieldMessage("Hello World"); std::cerr << "Finding Hello Field and placing value..." << std::endl; featureBuffer->get_Fields(&fields); fields->FindField(helloField, &index); featureBuffer->put_Value(index, helloFieldMessage); std::cerr << "Creating the point geometry to place in my feature class..." << std::endl; IPointPtr point(CLSID_Point); point->put_X(0); point->put_Y(0); IGeometryPtr geometry = point; std::cerr << "Placing the point in the buffer..." << std::endl; featureBuffer->putref_Shape(geometry); VARIANT id; std::cerr << "Inserting buffer into the table..." << std::endl; cursor->InsertFeature(featureBuffer, &id); std::cerr << "Feature " << id.intVal << " inserted..." << std::endl; cursor->Flush(); std::cerr << "Done." << std::endl; } catch (_com_error e) { TCHAR str[255]; BSTR bstr = BSTR(e.Description()); if (bstr) wsprintf(str, _T("Known Error : \n %ls"), bstr); else wsprintf(str, _T("Unknown Error..\n")); return E_FAIL; } AoExit(0); return 0; }
STDMETHODIMP CSimplePointDatasetHelper::get_Bounds(IEnvelope **Bounds) { HRESULT hr; if (! Bounds) return E_POINTER; // Get an envelope for the extent of the dataset // We will have to calculate the extent by opening a cursor // on the dataset, and building up a minimum bounding rectangle // Prepare to open a cursor. // Make the fieldmap, with values of -1 (attributes do not need fetching) long lNumFields; IFieldsPtr ipFields; hr = get_Fields(0, &ipFields); if (FAILED(hr)) return hr; hr = ipFields->get_FieldCount(&lNumFields); if (FAILED(hr)) return hr; CComVariant vFieldMap; vFieldMap.vt = VT_ARRAY | VT_I4; vFieldMap.parray = ::SafeArrayCreateVector(VT_I4, 0, lNumFields); long HUGEP *pMap = 0; // raw pointer to array hr = SafeArrayAccessData(vFieldMap.parray, (void HUGEP **)&pMap); if (FAILED(hr)) return hr; long i; for (i=0; i < lNumFields; i++) pMap[i] = -1; SafeArrayUnaccessData(vFieldMap.parray); // Open the cursor IPlugInCursorHelperPtr ipPlugInCursor; hr = FetchAll(0, L"", vFieldMap, &ipPlugInCursor); if (FAILED(hr)) return hr; // loop through the data recording min/max X and Y values. double dxMin = 9999999; double dxMax = -9999999; double dyMin = 9999999; double dyMax = -9999999; double x,y; VARIANT_BOOL bEOF = VARIANT_FALSE; IGeometryPtr ipGeom; hr = ipGeom.CreateInstance(CLSID_Point); if (FAILED(hr)) return hr; IPointPtr ipPoint; long lNumRecords = 0; do { lNumRecords++; hr = ipPlugInCursor->QueryShape(ipGeom); if (FAILED(hr)) return hr; ipPoint = ipGeom; if (ipPoint == NULL) return E_FAIL; hr = ipPoint->QueryCoords(&x, &y); if (FAILED(hr)) return hr; if (x > dxMax) dxMax = x; if (x < dxMin) dxMin = x; if (y > dyMax) dyMax = y; if (y < dyMin) dyMin = y; hr = ipPlugInCursor->NextRecord(); if (hr != S_OK) { hr = ipPlugInCursor->IsFinished(&bEOF); if (FAILED(hr)) return hr; } } while (!bEOF); // Handle special case of single point in file // - add a small amount, so that we will end up with an envelope rather than a point if (lNumRecords == 1) { double dDelta = 0.01; if (dxMax != 0) dDelta = dxMax / 1000; dxMax += dDelta; dyMax += dDelta; } // Create the envelope object, setting the appropriate spatial reference IEnvelopePtr ipEnv; hr = ipEnv.CreateInstance(CLSID_Envelope); if (FAILED(hr)) return hr; ISpatialReferencePtr ipSR; hr = ipSR.CreateInstance(CLSID_UnknownCoordinateSystem); if (FAILED(hr)) return hr; hr = ipEnv->putref_SpatialReference(ipSR); if (FAILED(hr)) return hr; hr = ipEnv->PutCoords(dxMin, dyMin, dxMax, dyMax); if (FAILED(hr)) return hr; *Bounds = ipEnv.Detach(); // pass ownership of object to client return S_OK; }
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); }