ClipShapefileByEnv.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 "ClipShapefileByEnv.h" // Hardcode in the clipping extent const double c_xMin = -130.0; const double c_xMax = -114.0; const double c_yMin = 31.0; const double c_yMax = 41.5; int main(int argc, char **argv) { std::cerr << "ClipShapefileByEnv - Environmental Systems Research Institute" << std::endl << std::endl; if (argc != 3) { std::cerr << "Usage: ClipShapefileByEnv [input shapefile] [output shapefile]" << std::endl; AoExit(0); } char* input = argv[1]; char* output = argv[2]; if (!InitializeApp()) { AoExit(0); } ClipFile(input, output); ShutdownApp(); AoExit(0); } HRESULT ClipFile(char* input, char* output) { // path parsing CComBSTR srcPath; CComBSTR srcName; CComBSTR outPath; CComBSTR outName; HRESULT hr = GetParentDirFromFullPath(input, &srcPath); if (FAILED(hr) || srcPath.Length() <= 0) { std::cerr << "Couldn't get input path." << std::endl; return E_FAIL; } hr = GetFileFromFullPath(input, &srcName); if (FAILED(hr) || srcName.Length() <= 0) { std::cerr << "Couldn't get input file name." << std::endl; return E_FAIL; } hr = GetParentDirFromFullPath(output, &outPath); if (FAILED(hr) || outPath.Length() <= 0) { std::cerr << "Couldn't get output path." << std::endl; return E_FAIL; } hr = GetFileFromFullPath(output, &outName); if (FAILED(hr) || outName.Length() <= 0) { std::cerr << "Couldn't get output file name." << std::endl; return E_FAIL; } // Open the Source shapefile IWorkspaceFactoryPtr ipWkspFactory(CLSID_ShapefileWorkspaceFactory); IWorkspacePtr ipWksp; hr = ipWkspFactory->OpenFromFile(srcPath, 0, &ipWksp); if (FAILED(hr) || ipWksp == 0) { std::wcerr << L"Couldn't open workspace " << (BSTR) srcPath << std::endl; return E_FAIL; } IFeatureClassPtr ipSrcFeatureClass; hr = ((IFeatureWorkspacePtr) ipWksp)->OpenFeatureClass(srcName, &ipSrcFeatureClass); if (FAILED(hr) || ipSrcFeatureClass == 0) { std::wcerr << L"Couldn't open feature class " << (BSTR) srcName << std::endl; return E_FAIL; } // Create the target clip shapefile IWorkspaceFactoryPtr ipTargetWkspFac(CLSID_ShapefileWorkspaceFactory); IWorkspacePtr ipTargetWksp; hr = ipTargetWkspFac->OpenFromFile(outPath, 0, &ipTargetWksp); if (FAILED(hr) || ipTargetWksp == 0) { std::wcerr << L"Couldn't open target workspace " << (BSTR) outPath << std::endl; return E_FAIL; } // Get all the details of the source feature class to // create the target feature class IFieldsPtr ipSrcFields; ipSrcFeatureClass->get_Fields(&ipSrcFields); IUIDPtr ipSrcUID; ipSrcFeatureClass->get_CLSID(&ipSrcUID); IUIDPtr ipSrcExtUID; ipSrcFeatureClass->get_EXTCLSID(&ipSrcExtUID); esriFeatureType eFeatureType; ipSrcFeatureClass->get_FeatureType(&eFeatureType); CComBSTR bstrName; ipSrcFeatureClass->get_ShapeFieldName(&bstrName); // Create the target shape file IFeatureClassPtr ipTargetFC; ((IFeatureWorkspacePtr) ipTargetWksp)->CreateFeatureClass(outName, ipSrcFields, ipSrcUID, ipSrcExtUID, eFeatureType, bstrName, CComBSTR(L""), &ipTargetFC); // Create Clip Envelop IEnvelopePtr ipEnv(CLSID_Envelope); ipEnv->PutCoords(c_xMin, c_yMin, c_xMax, c_yMax); // Define a spatial query to get only the clip area ISpatialFilterPtr ipFilter(CLSID_SpatialFilter); IEnvelopePtr ipNewEnv; ipEnv->get_Envelope(&ipNewEnv); ipFilter->putref_Geometry((IGeometryPtr) ipNewEnv); ipFilter->put_GeometryField(bstrName); ipFilter->put_SpatialRel(esriSpatialRelIntersects); // IFeatureCursor interface provides access to a set of features in a feature // class. Get a cursor based on the spatial query IFeatureCursorPtr ipFeatureCursor; ipSrcFeatureClass->Search((IQueryFilterPtr) ipFilter, VARIANT_TRUE, &ipFeatureCursor); // Loop over all the features and copy them over to the new shapefile // Use a feature buffer to insert copied features for performance benefit IFeatureCursorPtr ipInsertCursor; ipTargetFC->Insert(VARIANT_TRUE, &ipInsertCursor); IGeometryPtr ipGeometry; IFeatureBufferPtr ipBuffer; ipTargetFC->CreateFeatureBuffer(&ipBuffer); IFeaturePtr ipFeature; IGeometryPtr ipOutGeom; while (ipFeatureCursor->NextFeature(&ipFeature) == S_OK && (ipFeature != 0)) { std::cerr << " . "; // Get the shape and source to clip it ipFeature->get_ShapeCopy(&ipGeometry); ((ITopologicalOperatorPtr) ipGeometry)->Clip(ipEnv); ((ITopologicalOperatorPtr) ipGeometry)->Buffer(0, &ipOutGeom); ipBuffer->putref_Shape(ipOutGeom); // Get the field count IFieldsPtr ipFeatureFields; ipFeature->get_Fields(&ipFeatureFields); long lNumFields; ipFeatureFields->get_FieldCount(&lNumFields); for (long i = 0; i < lNumFields; i++) { IFieldPtr ipField; ipFeatureFields->get_Field(i, &ipField); esriFieldType eType; ipField->get_Type(&eType); // Ignore the Geometry and the OID field, the geometry is dealt // with earlier and the OID will be generated automatically if ((eType != esriFieldTypeOID) && (eType != esriFieldTypeGeometry)) { CComBSTR bstrFieldName; ipField->get_Name(&bstrFieldName); long lFieldIndex; ipFeatureFields->FindField(bstrFieldName, &lFieldIndex); IFieldsPtr ipBufferFields; ipBuffer->get_Fields(&ipBufferFields); long lNewFieldIndex; ipBufferFields->FindField(bstrFieldName, &lNewFieldIndex); CComVariant vFeatureVal; ipFeature->get_Value(lFieldIndex, &vFeatureVal); ipBuffer->put_Value(lNewFieldIndex, vFeatureVal); } } CComVariant vID; ipInsertCursor->InsertFeature(ipBuffer, &vID); } // Flush the inserts ipInsertCursor->Flush(); std::cerr << std::endl; return S_OK; }