Points2Dto3D.cpp
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // #include "Points2Dto3D.h" int main(int argc, char** argv) { std::cerr << "Points2Dto3D: ArcGIS Engine Developer Sample" << std::endl; if (argc != 4) { std::cerr << "Usage: Points2Dto3D " << "[Input Shapefile] " << "[Z Attribute Field Name] " << "[Output Shapefile]" << std::endl; AoExit(0); } char* inputFile = argv[1]; char* zFieldName = argv[2]; char* outputFile = argv[3]; if (!InitializeApp()) { AoExit(0); } HRESULT hr = Create3DShape(inputFile, zFieldName, outputFile); if (FAILED(hr)) std::cerr << "Failed 3D Creation" << std::endl; else std::cerr << "Successful 3D Creation" << std::endl; ShutdownApp(); AoExit(0); } HRESULT Create3DShape(char* inputFile, char* zFieldName, char* outputFile) { // data location variables CComBSTR inShapePath; CComBSTR inShapeName; CComBSTR outShapePath; CComBSTR outShapeName; // Parse the input and output paths HRESULT hr = GetParentDirFromFullPath(inputFile, &inShapePath); if (FAILED(hr) || inShapePath.Length() <= 0) { std::cerr << "Couldn't get input path." << std::endl; return E_FAIL; } hr = GetFileFromFullPath(inputFile, &inShapeName); if (FAILED(hr) || inShapeName.Length() <= 0) { std::cerr << "Couldn't get input file." << std::endl; return E_FAIL; } hr = GetParentDirFromFullPath(outputFile, &outShapePath); if (FAILED(hr) || outShapePath.Length() <= 0) { std::cerr << "Couldn't get output path." << std::endl; return E_FAIL; } hr = GetFileFromFullPath(outputFile, &outShapeName); if (FAILED(hr) || outShapeName.Length() <= 0) { std::cerr << "Couldn't get output file." << std::endl; return E_FAIL; } IWorkspaceFactoryPtr ipWkspFac(CLSID_ShapefileWorkspaceFactory); IWorkspacePtr ipWksp; hr = ipWkspFac->OpenFromFile(inShapePath, 0, &ipWksp); if (FAILED(hr) || ipWksp == 0) { std::wcerr << L"Could not open the workspace " << (BSTR) inShapePath << std::endl; return hr; } IFeatureClassPtr ipInFeatureClass; hr = ((IFeatureWorkspacePtr) ipWksp)->OpenFeatureClass(inShapeName, &ipInFeatureClass); if (FAILED(hr) || ipInFeatureClass ==0) { std::wcerr << L"Could not open the feature class " << (BSTR) inShapeName << std::endl; return hr; } // Only support points esriGeometryType shape; ipInFeatureClass->get_ShapeType(&shape); if (shape != esriGeometryPoint) { std::cerr << "This is not a shapefile of points." << std::endl; return E_FAIL; } else std::cerr << "Proceeding on the points shapefile." << std::endl; // Create the output feature class if no such on exists already (else error) ISpatialReferencePtr ipSpatialRef(CLSID_UnknownCoordinateSystem); IFeatureClassPtr ipOutFeatureClass; CreateShapefile(esriGeometryPoint, VARIANT_TRUE, VARIANT_TRUE, ipSpatialRef, 1000, &ipOutFeatureClass, outShapePath, outShapeName); // Copy input fields to output feature class w/out overwriting system fields IFieldsPtr ipFields; ipInFeatureClass->get_Fields(&ipFields); long numFields; ipFields->get_FieldCount(&numFields); IFieldPtr ipFieldTest; VARIANT_BOOL varBool; esriFieldType fieldType; IFieldPtr ipField; for (int i = 0; i < numFields - 1; ++i) { ipFields->get_Field(i, &ipFieldTest); ipFieldTest->get_Editable(&varBool); ipFieldTest->get_Type(&fieldType); if (varBool && !(fieldType == esriFieldTypeGeometry)) { ipFields->get_Field(i, &ipField); ipOutFeatureClass->AddField(ipField); } } // Get a cursor off the input feature class IFeatureCursorPtr ipInFeatureCursor; ipInFeatureClass->Search(NULL, VARIANT_FALSE, &ipInFeatureCursor); // Get a cursor off the output feature class IFeatureBufferPtr ipFeatureBuffer; ipOutFeatureClass->CreateFeatureBuffer(&ipFeatureBuffer); IFeatureCursorPtr ipEditCursor; ipOutFeatureClass->Insert(VARIANT_TRUE, &ipEditCursor); // loop through the input features, cloning the geometry, looking up and // adding the z value from the input table and adding the new feature // to the output feature class IFeaturePtr ipFeature; ipInFeatureCursor->NextFeature(&ipFeature); IGeometryPtr ipGeom; IClonePtr ipOutClone; int counter = 1; while(ipFeature != NULL) { // Get the input geometry and clone it to a z aware geometry ipFeature->get_Shape(&ipGeom); ((IClonePtr) ipGeom)->Clone(&ipOutClone); ((IZAwarePtr) ipOutClone)->put_ZAware(VARIANT_TRUE); IFieldsPtr ipFields2Ptr; ipFeature->get_Fields(&ipFields2Ptr); long zFieldLoc; ipFields2Ptr->FindField(CComBSTR(zFieldName), &zFieldLoc); if (zFieldLoc < 0) { std::cerr << "Field " << zFieldName << " was not found in the input feature class" << std::endl; return E_FAIL; } // Get the z values from the attribute table IRowBufferPtr ipRowBuffer(ipFeature); CComVariant outZ; ipRowBuffer->get_Value(zFieldLoc, &outZ); double inZ = outZ.dblVal; IPointPtr ipOutPoint(ipOutClone); ipOutPoint->put_Z(inZ); double x, y, z; ipOutPoint->get_X(&x); ipOutPoint->get_Y(&y); ipOutPoint->get_Z(&z); std::cerr << "Point #: " << counter << " = (" << x << ", " << y << ", " << z << ")" << std::endl; ++counter; ipFeatureBuffer->putref_Shape((IGeometryPtr) ipOutPoint); long index; for (int i = 0; i < numFields - 1; ++i) { IFieldsPtr ipBufferFields; ipFeatureBuffer->get_Fields(&ipBufferFields); IFieldsPtr ipInFCFields; ipInFeatureClass->get_Fields(&ipInFCFields); IFieldPtr ipInField; ipInFCFields->get_Field(i, &ipInField); CComBSTR fieldName; ipInField->get_Name(&fieldName); ipBufferFields->FindField(fieldName, &index); if (index >= 0) { IFieldPtr ipTempField; ipBufferFields->get_Field(index, &ipTempField); VARIANT_BOOL tempBool; ipTempField->get_Editable(&tempBool); esriFieldType tempType; ipTempField->get_Type(&tempType); if (tempBool && tempType != esriFieldTypeGeometry) { VARIANT varBufferVal; ipRowBuffer->get_Value(i, &varBufferVal); ipFeatureBuffer->put_Value(index, varBufferVal); } } } CComVariant varID; ipEditCursor->InsertFeature(ipFeatureBuffer, &varID); ipInFeatureCursor->NextFeature(&ipFeature); } return S_OK; } HRESULT CreateShapefile(esriGeometryType shapeType, VARIANT_BOOL hasM, VARIANT_BOOL hasZ, ISpatialReference* pSpatialRef, int gridSize, IFeatureClass** ppOutFeatureClass, BSTR outShapePath, BSTR outShapeName) { IWorkspaceFactoryPtr ipShapeWkspFac(CLSID_ShapefileWorkspaceFactory); IPropertySetPtr ipConnectionProperties(CLSID_PropertySet); ipConnectionProperties->SetProperty(CComBSTR(L"DATABASE"), CComVariant(outShapePath)); IWorkspacePtr ipShapeWksp; HRESULT hr = ipShapeWkspFac->Open(ipConnectionProperties, 0, &ipShapeWksp); if (FAILED(hr) || ipShapeWksp == 0) { std::cerr << "Couldn't open the workspace to create a shapefile." << std::endl; } IFieldsPtr ipFields(CLSID_Fields); IFieldsEditPtr ipFieldsEdit(ipFields); IFieldPtr ipField(CLSID_Field); IFieldEditPtr ipFieldEdit(ipField); IGeometryDefEditPtr ipGeoDefEdit(CLSID_GeometryDef); ipGeoDefEdit->put_GeometryType(shapeType); ipGeoDefEdit->put_HasM(hasM); ipGeoDefEdit->put_HasZ(hasZ); ipGeoDefEdit->putref_SpatialReference(pSpatialRef); ipGeoDefEdit->put_GridCount(1); ipGeoDefEdit->put_GridSize(0, gridSize); ipFieldEdit = IFieldPtr(CLSID_Field); ipFieldEdit->put_Name(CComBSTR(L"OBJECTID")); ipFieldEdit->put_AliasName(CComBSTR(L"OBJECTID")); ipFieldEdit->put_Type(esriFieldTypeOID); ipField = ipFieldEdit; ipFieldsEdit->AddField(ipField); ipFieldEdit.CreateInstance(CLSID_Field); ipFieldEdit->put_Name(CComBSTR(L"SHAPE")); ipFieldEdit->put_IsNullable(VARIANT_TRUE); ipFieldEdit->put_Type(esriFieldTypeGeometry); IGeometryDefPtr ipGeoDef(ipGeoDefEdit); ipFieldEdit->putref_GeometryDef(ipGeoDef); ipFieldEdit->put_Required(VARIANT_TRUE); ipField = ipFieldEdit; ipFieldsEdit->AddField(ipField); ((IFeatureWorkspacePtr) ipShapeWksp)->CreateFeatureClass(outShapeName, ipFields, NULL, NULL, esriFTSimple, CComBSTR(L"Shape"), CComBSTR(L""), ppOutFeatureClass); return S_OK; }