POST
|
Hi, I am upgrading a legacy ArcObjects projects to VS2013, ArcGIS10.3.1 and ArcObjectsSDKNet, while still on Win 7 Pro. The project is a MFC DLL with ATL support, containing numerous MFC dialogs and one ATL COM class. The DLL is used by a VB.NET extension to provide custom tools for ArcMap. The extension communicates with the C++ DLL via the COM class. The model has been functioning since 2006, with upgrades along the way for ArcGIS and VS changes. The MFC DLL will not build, with an error in the main.cpp: error C2732: linkage specification contradicts earlier specification for 'DllGetClassObject' The error references the declaration of the class in main: // DllGetClassObject - Returns class factory STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (S_OK == _AtlModule.GetClassObject(rclsid, riid, ppv)) return S_OK; return AfxDllGetClassObject(rclsid, riid, ppv); } I tried creating a new MFC DLL project with static link to MFC, which builds fine as is without adding anything after the solution wizard completes. Then use class wizard to 'Add ATL support to MFC project' without changing anything else, and it fails with the same error. Has anyone seen this kind of error and have any ideas what it is related too? Secondly, is there a better way to write a C++ DLL that a VB extension can call into? Thank you for any help!
... View more
12-07-2016
12:06 PM
|
0
|
0
|
693
|
POST
|
Hi- I am upgrading a VS2010 C++ project for ArcGIS10.2 to VS2013 and ArcGIS10.3.1. Running on Win 7 Pro 64-bit and passed all hardware and OS recommendations for being able to run ArcGIS10.3. In stdafx.h, there are imports for all ESRI libs, such as: #import "c:\Program Files (x86)\ArcGIS\Desktop10.3\com\esriSystem.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids, exclude("OLE_COLOR", "OLE_HANDLE", "VARTYPE") On build, .\myprojectpath\debug\esrisystem.tlh(374): warning C4099: 'XMLSerializer' : type name first seen using 'class' now seen using 'struct' 1> C:\Program Files (x86)\Windows Kits\8.1\Include\um\mshtml.h(8463) : see declaration of 'XMLSerializer' .\myprojectpath\debug\esrisystem.tlh(4210): error C3121: cannot change GUID for class 'XMLSerializer' 1> C:\Program Files (x86)\Windows Kits\8.1\Include\um\mshtml.h(8463) : see declaration of 'XMLSerializer' ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== So the class/struct is multiply defined between esri and system libs, but does anyone have an idea what to do about it? Thank you for your help!
... View more
10-12-2016
09:48 AM
|
0
|
2
|
1034
|
POST
|
The ESRI sample, TOCLayerFilterVB2010, implements a custom TOC view for map layers. For my purposes, I need to be able to turn it on/off, meaning add and remove that view from the TOC horizontal icon bar programmatically. Can someone explain how the custom contents view in this sample gets instantiated? I find that if the dll is registered, it appears. The only way to get rid of it in any ArcMap document is to unregister it. Loading a blank document or deleting the Normal.mxt template does not have any effect. Ideally, I will have a command toggle that instantiates and destroys the view. I cannot figure out how to control its creation. The object gets created when ArcMap starts and before any document is loaded. The windows form initialization is a private method, created by the windows form designer automatically, and the tree view object itself is a private property as well. Thanks for your help!
... View more
04-29-2014
07:20 AM
|
0
|
0
|
650
|
POST
|
I am following the code in this thread, but I am unable to write rasters to File GDB (have written GRID rasters successfully for years). I cannot get the nodata value to stick in the output raster (blank in properties) and the data values are reported as nodata when interrogating with the Identify tool in ArcMap. With GRID rasters, it was necessary to compute statistics on the raster before writing. Something is clearly wrong here because the code fails when computing statistics. If I skip that step then I get a garbage raster. Any ideas would be much appreciated! (All result code testing removed for brevity) HRESULT WriteGDBRasterTest(CString rasterParentDir,
CString rasterName,
CString& sDatatype,
int nCols, int nRows, double Xmin, double Ymin,
float pixWidth, float pixHeight,
float noDataValue,
float* rData)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
CString sRaster = ExtractFileName(rasterName);
CString sWorkspaceDir = rasterParentDir;
long Width = nCols;
long Height = nRows;
double cellWidth = (double)pixWidth;
double cellHeight = (double)pixHeight;
double dXmin = (double)Xmin;
double dYmin = (double)Ymin;
double dXmax = dXmin + cellWidth*Width;
double dYmax = dYmin + cellHeight*Height;
IPointPtr ipPointOrigin(CLSID_Point);
ipPointOrigin->put_X(dXmin);
ipPointOrigin->put_Y(dYmin);
IPntPtr ipPntCellsize(CLSID_Pnt);
ipPntCellsize->put_X(cellWidth);
ipPntCellsize->put_Y(cellHeight);
IWorkspaceFactoryPtr ipWorkspaceFactory;
IWorkspacePtr ipWorkspace;
IRasterWorkspaceExPtr ipRasterWorkspaceEx;
hr = ipWorkspaceFactory.CreateInstance(CLSID_FileGDBWorkspaceFactory);
CComBSTR bWorkspaceDir = sWorkspaceDir.AllocSysString();
hr = ipWorkspaceFactory->OpenFromFile(bWorkspaceDir, 0, &ipWorkspace);
hr = ipWorkspace->QueryInterface(IID_IRasterWorkspaceEx, (void**)&ipRasterWorkspaceEx);
VARIANT_BOOL bPermanent = TRUE;
CComBSTR bsRaster = sRaster.AllocSysString();
IRasterDatasetPtr ipRasterDataset;
IRasterStorageDef3Ptr ipRasterStorageDef(CLSID_RasterStorageDef);
hr = ipRasterStorageDef->putref_CellSize(ipPntCellsize);
hr = ipRasterStorageDef->putref_Origin(ipPointOrigin);
CString ConfigKeyword = "";
CComBSTR bsConfigKeyword(ConfigKeyword);
IRasterDefPtr ipRasterDef(CLSID_RasterDef);
IGeometryDefPtr ipGeomDef = 0;
rstPixelType rasterPixelType = PT_FLOAT;
// Start with temp raster because need to use SaveAs to write raster correctly to FileGDB?
CComBSTR bsTempRaster = "temp";
hr = ipRasterWorkspaceEx->CreateRasterDataset(bsTempRaster, 1, rasterPixelType, ipRasterStorageDef,
bsConfigKeyword, ipRasterDef, ipGeomDef, &ipRasterDataset);
bsConfigKeyword.Empty();
ipRasterDef = 0;
ipRasterStorageDef = 0;
ipPntCellsize = 0;
ipPointOrigin = 0;
IRasterDataset3Ptr ipRasterDataset3(ipRasterDataset);
IRasterPtr ipRaster;
hr = ipRasterDataset3->CreateFullRaster(&ipRaster);
// If set props on raster then raster cursor works properly (but cannot set nodata)
IRasterPropsPtr ipRasterProps_fromRaster;
hr = ipRaster->QueryInterface(IID_IRasterProps, (void **) &ipRasterProps_fromRaster);
//// If set on dataset then raster cursor will NOT work (but can set nodata)
//IRasterPropsPtr ipRasterProps_fromDataset;
//IRasterBandPtr ipRasterBand;
//IRasterBandCollectionPtr ipRasterBandCollection;
//hr = ipRasterDataset->QueryInterface(IID_IRasterBandCollection, (void **)&ipRasterBandCollection);
//hr = ipRasterBandCollection->Item(0, &ipRasterBand);
//hr = ipRasterBand->QueryInterface(IID_IRasterProps, (void **) &ipRasterProps_fromDataset);
ipRasterProps_fromRaster->put_PixelType(rasterPixelType);
//ipRasterProps_fromDataset->put_PixelType(rasterPixelType);
IEnvelopePtr ipEnv(CLSID_Envelope);
ipEnv->PutCoords(dXmin, dYmin, dXmax, dYmax);
ipRasterProps_fromRaster->put_Extent(ipEnv);
ipRasterProps_fromRaster->put_Height((long)Height);
ipRasterProps_fromRaster->put_Width((long)Width);
CComVariant nodata(noDataValue);
//hr = ipRasterProps_fromDataset->put_NoDataValue(nodata);
hr = ipRasterProps_fromRaster->put_NoDataValue(nodata);
::VariantClear(&nodata);
// Why isn't nodata set in output layer????
//CComVariant nodata2;
//hr = ipRasterProps_fromDataset->get_NoDataValue(&nodata2);
//float test2 = nodata2.fltVal;
//VARTYPE vType = nodata2.vt; // This returns correctly {-9999., R4}
CComVariant nodata3((float)0); // Initializes vtype R4
hr = ipRasterProps_fromRaster->get_NoDataValue(&nodata3);
float test3 = nodata3.fltVal; // Comes back as safearray of R4, (with correct value in element 0)
VARTYPE vType3 = nodata3.vt; // 8196 = 0x2000 + 0x0004 (SafeArray + R4)
IRaster2Ptr ipRaster2(ipRaster);
IRasterCursorPtr ipRasterCursor;
hr = ipRaster2->CreateCursorEx(0, &ipRasterCursor); // Use default of full width x 128 rows
// Set up raster for writing
IRasterEditPtr ipRasterEdit(ipRaster2);
IPixelBlockPtr ipPixelBlock;
IPixelBlock3Ptr ipPixelBlock3;
long pixelBlockWidth = 0;
long pixelBlockHeight = 0;
IPntPtr ipTLC;
VARIANT_BOOL vNotFinished;
// Rotate through blocks using Raster Cursor
do {
hr = ipRasterCursor->get_PixelBlock(&ipPixelBlock);
hr = ipPixelBlock->QueryInterface(IID_IPixelBlock3, (void**)&ipPixelBlock3);
hr = ipPixelBlock3->get_Width(&pixelBlockWidth); // Should be same as ncols
hr = ipPixelBlock3->get_Height(&pixelBlockHeight); // Should be lesser of nrows and 128
hr = ipRasterCursor->get_TopLeft(&ipTLC);
double dTLRow;
hr = ipTLC->get_Y(&dTLRow);
int iTLRow = (int) dTLRow;
CComVariant varArray;
::VariantInit(&varArray);
hr = ipPixelBlock3->get_PixelDataByRef(0, &varArray); // Single band
SAFEARRAY *saArray = *(varArray.pparray);
hr = SafeArrayLock(saArray);
long long ij = 0;
long long lWidth = static_cast<long long>(Width);
for(int i = 0; i < pixelBlockHeight; i++) {
for(int j = 0; j < Width; j++) {
long ind[2];
ind[0]=j;
ind[1]=i;
ij = (i+iTLRow)*lWidth + j;
float val = rData[ij];
hr = ::SafeArrayPutElement(saArray, ind, (void*)&val);
}
}
hr = SafeArrayUnlock(saArray);
// Write out the new raster block
hr = ipRasterEdit->Write(ipTLC, ipPixelBlock);
hr = ipRasterEdit->Refresh();
// Advance the Raster Cursor
hr = ipRasterCursor->Next(&vNotFinished);
ipPixelBlock3 = 0;
ipPixelBlock = 0;
::VariantClear(&varArray);
} while (vNotFinished);
ipRasterCursor = 0;
ipRasterEdit = 0;
// New method to save to File GDB
ISaveAs2Ptr ipSaveAs(ipRaster2);
IDatasetPtr ipDS;
IWorkspacePtr ipWS(ipRasterWorkspaceEx);
hr = ipSaveAs->SaveAs(bsRaster, ipWS, CComBSTR("GDB"), &ipDS);
bsRaster.Empty();
ipDS = 0;
ipSaveAs = 0;
ipWS = 0;
//// Calculate RasterBand stats. MUST do to complete the band.(Was true for GRID anyway)
//hr = ipRasterBand->ComputeStatsAndHist(); // E_FAIL HERE (Also, NoData not getting set correctly)
//IRasterStatisticsPtr ipStats;
//hr = ipRasterBand->get_Statistics(&ipStats);
//double rMin, rMax;
//ipStats->get_Minimum(&rMin);
//ipStats->get_Maximum(&rMax);
//ipStats = 0;
// MUST release these pointers BEFORE creating and adding layer to map
ipRasterProps_fromRaster = 0;
//ipRasterProps_fromDataset = 0;
//ipRasterBand = 0;
//ipRasterBandCollection = 0;
ipRaster = 0;
ipRaster2 = 0;
ipRasterDataset = 0;
ipRasterDataset3 = 0;
ipRasterWorkspaceEx = 0;
ipWorkspace = 0;
// Must create new workspace and rasterdataset connections to get layer
hr = ipWorkspaceFactory->OpenFromFile(bWorkspaceDir, 0, &ipWorkspace);
bWorkspaceDir.Empty();
hr = ipWorkspace->QueryInterface(IID_IRasterWorkspaceEx, (void**)&ipRasterWorkspaceEx);
bWorkspaceDir.Empty();
// Delete temp raster
hr = ipRasterWorkspaceEx->DeleteRasterDataset(bsTempRaster);
bsTempRaster.Empty();
// Open saved raster
IRasterDatasetPtr ipRDS;
CComBSTR bRName = sRaster.AllocSysString();
hr = ipRasterWorkspaceEx->OpenRasterDataset(bRName, &ipRDS);
bRName.Empty();
IRasterLayerPtr ipRasterLayer(CLSID_RasterLayer);
hr = ipRasterLayer->CreateFromDataset(ipRDS);
// Add Raster Layer to current map
IMapPtr ipMap;
hr = m_ipMxDoc->get_FocusMap(&ipMap);
hr = ipMap->AddLayer(ipRasterLayer);
// Refresh TOC
IActiveViewPtr ipActiveView;
hr = m_ipMxDoc->get_ActiveView(&ipActiveView);
hr = ipActiveView->Refresh();
hr = ipActiveView->ContentsChanged();
// MUST Release smart pointers
ipRasterLayer = 0;
ipActiveView = 0;
ipMap = 0;
ipRasterWorkspaceEx = 0;
ipWorkspace = 0;
ipWorkspaceFactory = 0;
ipRDS = 0;
return hr;
}
... View more
02-07-2014
10:07 AM
|
0
|
0
|
162
|
POST
|
Thanks very much for replying- the book looks really helpful. Have you got a simple script you would be willing to share that I might modify to access my class? I haven't done that before. Cheers!
... View more
07-06-2012
11:08 AM
|
0
|
0
|
676
|
POST
|
To rlwatson- I have used a C++ ATL COM class from a dll successfully under VS 2005/2008. I cannot successfully create a project in VS2010 with an ATL simple object and have a public method visible from the Interface. The ESRI walk-through applied to VS2005 when ATL was attributed. Now the ATL auto-generated code looks different; using VS to add a method to the class doesn't achieve visibility in the interface. The following snippet is from a VB ArcGIS extension OnClick method for a custom tool. In the VB project (with Interop dll included as a resource), the Interface and class are recognized, but the Launch() method is not (and I see no methods in Object Browser). Back in the C++ dll project, I can see the Launch method on the Interface class in the Object Browser. Public Overrides Sub OnClick() Try Dim show As ICCTShowDlgATL show = New CCTShowDlgATL show.Launch(m_application, 500) Catch e As System.Exception MsgBox("Error from SIE DLL: " & e.Message & vbCrLf & _ e.Source & vbCrLf & _ "Stack Trace: " & vbCrLf & e.StackTrace) End Try End Sub Any ideas? I have very little understanding of ATL COM and relied previously on the walk-through to achieve success! Thanks in advance for your help.
... View more
07-06-2012
09:12 AM
|
0
|
0
|
676
|
POST
|
Thanks for that. I have been building in VS 2010 against .NET 4.0 with no trouble for my other ArcGIS 10.0 projects (ignorance has been bliss so far, but I shall take heed now). When in 2012 will ArcGIS 10.1 release? I only have the express version of VS C++ 2008, which does not have ATL (or MFC) libraries, so I cannot build the sample project (RasterSlope2010.sln). Has anyone else successfully run this VCPP sample (ie does it actually output the slope raster dataset)?
... View more
10-02-2011
08:17 AM
|
0
|
0
|
442
|
POST
|
Stilll stuck. Tried running the DevKit10.0/VCPP sample "Computing the Slope of a Raster Dataset". Changed the VS2010 project to target .NET 4.0 for VS2010 (it was 3.5). And changed product to bind to from esriArcGISEngine to esriArcGISDesktop. The program runs successfully with Admin privileges (says slope has been calculated) except that there is no output raster dataset. Does anyone know- do you need to bind to ArcGIS Engine to run standalone apps? Thanks for your help!
... View more
10-01-2011
06:29 AM
|
0
|
0
|
442
|
POST
|
Hi all, Can someone tell me how to bind a standalone C++ app to ArcGIS Desktop ? I have put the following include in stdafx.h along with other esri libraries. #import "C:/Program Files (x86)/Common Files/ArcGIS/bin/ArcGISVersion.dll" raw_interfaces_only raw_native_types no_namespace named_guids rename("esriProductCode","esriVersionProductCode" ) rename("VersionManager","esriVersionManager" ) And here is how I see others in forums binding to desktop in .NET: 'Add runtime management ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop) However, I cannot find a RuntimeManager class in the ArcGISVersion library to implement in C++. Do you have to do this in Arc 10.0 before running AoInitialize? If I just attempt to initialize using LicenseUtilities(.cpp), I get the error <no appropriate license available> Do you need to have ArcEngine if you only want to bind to Desktop? Thanks for your help!
... View more
09-21-2011
10:00 AM
|
0
|
6
|
3265
|
POST
|
Looking into this more... If I change the datatype of the elements written to the safearray to long, it works fine. The problem appears to be that IRasterWorkspace2->CreateRasterDataset is not creating a PT_SHORT file-based raster. If I check the pixel type of the raster immediately after creating a short int raster, it returns as PT_LONG. Anyone else having difficulty creating short int rasters ? I am working with VS2010, Win7 x64, ArcGIS 10. The method worked fine on VS2005, Win XP, ArcGIS 9.3 Thanks for any ideas!
... View more
02-07-2011
11:48 AM
|
0
|
0
|
152
|
POST
|
Hello- I have C++ code to write a raster that has been working fine on Arc 9.2/9.3, but only works partially on Arc 10. The migrated code to write a raster in chunks works on Arc 10 for floating point datatypes, but not for short integer. The pixel values in the output raster are large negative numbers but the least significant digits vary correctly. The output raster ends up getting written out as long integer because the values are outside the range of short int. It seems like the the lower two bytes might be correct, but garbage is getting written into the upper two bytes. The raster was created with pixel type PT_SHORT. Why is it getting interpreted as long int? Can anyone help identify what might have changed in Arc 10 that would make this not work properly anymore? Thanks for your help. // ============================================== // WRITE_GRID_BLOCK // ============================================== HRESULT WriteGRIDBlock(SPcontainer* SP, int iTLRow, int iTLCol, int PBHeight, int PBWidth, CString sDatatype, float* pDataBlock) { // Create a Pixelblock of size Width x Height IPntPtr ipPntSize(CLSID_DblPnt); ipPntSize->SetCoords(PBWidth, PBHeight); IPixelBlockPtr ipPixelBlock; HRESULT hr = SP->ipRawPixels->CreatePixelBlock(ipPntSize, &ipPixelBlock); if (FAILED(hr)) { return hr; } // MUST READ pixelblock before writing to complete initialization IPntPtr ipOrigin(CLSID_DblPnt); ipOrigin->put_X(iTLCol); ipOrigin->put_Y(iTLRow); hr = SP->ipRawPixels->Read(ipOrigin, ipPixelBlock); if (FAILED(hr)) { return hr; } // Read a SafeArray from the PixelBlock IPixelBlock3Ptr ipPixelBlock3; hr = ipPixelBlock->QueryInterface(IID_IPixelBlock3, (void**)&ipPixelBlock3); if (FAILED(hr)) { return hr; } // =========== From ESRI Support ============== //VARIANT varArray; CComVariant varArray; ::VariantInit(&varArray); hr = ipPixelBlock3->get_PixelDataByRef(0, &varArray); if (FAILED(hr)) { return hr; } SAFEARRAY *saArray = *(varArray.pparray); // ======================================== hr = SafeArrayLock(saArray); if (FAILED(hr)) { return hr; } // Input array is row-major (ie row by row, column-order) // Output Arc array is column-major (upper left 0,0, read down and to right) if ((sDatatype == "FLOAT") || (sDatatype == "PT_FLOAT")) { for(int i = 0; i < PBHeight; i++) { for(int j = 0; j < PBWidth; j++) { long ind[2]; ind[0]=j; ind[1]=i; float val = pDataBlock[i*PBWidth + j]; hr = ::SafeArrayPutElement(saArray, ind, (void*)&val); } } } else if ((sDatatype == "SHORT") || (sDatatype == "PT_SHORT")) { for(int i = 0; i < PBHeight; i++) { for(int j = 0; j < PBWidth; j++) { long ind[2]; ind[0]=j; ind[1]=i; short val = (short)pDataBlock[i*PBWidth + j]; hr = ::SafeArrayPutElement(saArray, ind, (void*)&val); } } } hr = SafeArrayUnlock(saArray); if (FAILED(hr)) { return hr; } hr = SP->ipRawPixels->Write(ipOrigin, ipPixelBlock); if (FAILED(hr)) { return hr; } ::VariantClear(&varArray); ipOrigin = 0; ipPntSize = 0; ipPixelBlock3 = 0; return hr; }
... View more
02-04-2011
11:21 AM
|
0
|
2
|
1794
|
POST
|
Thanks very much for your response, but sadly Delete_management does not do the trick. When SelectLayerByLocation is used, the lock file persists. Also, tried clearing the selection with SelectLayerByAttribute after selecting by location. No effect either.
... View more
01-14-2011
11:00 AM
|
0
|
0
|
176
|
POST
|
Hi all, When using the Geoprocessor, making a layer from a shapefile and then making a selection in the layer by location results in a persistent lock file associated with the original shapefile. If I do selection by attribute instead then the lock file will go away when the internal layer and shapefile are deleted. ArcMap has to be closed to run the geoprocessing operation more than once because the lock file persists. I have posted on this before for 9.2/9.3 in reference to multiple geoprocessing runs within a single ArcMap session. With the release of 10.0, the new lock files allowed me to further trace the problem. Any ideas on how to clean up would be great! Test function follows. HRESULT CVectorizationDlg::GPtest() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr; ::CoInitialize(NULL); // Before any ArcObjects AND must scope what follows before AoUninitialize() { IGeoProcessor2Ptr ipGP(CLSID_GeoProcessor); IGeoProcessorResultPtr ipResult; CComBSTR bsMessages; CString cMsg; // Don't add temp layers to map document VARIANT_BOOL bOut; bOut = FALSE; //bOut = TRUE; hr = ipGP->put_AddOutputsToMap(bOut); // Do overwrite temp layers on disk VARIANT_BOOL bOverwrite; bOverwrite = TRUE; hr = ipGP->put_OverwriteOutput(bOverwrite); // Temp map layers VARIANT_BOOL bTempMapLayers; bTempMapLayers = TRUE; hr = ipGP->put_TemporaryMapLayers(bTempMapLayers); // Singleton object!!! IGPUtilitiesPtr ipGPUtil(CLSID_GPUtilities); // Get scratch working directory CString sTempDir = "c:\\temp\\arcsie\\erikadade\\vector\\"; // A directory that you can delete sTempDir = TempDir(); // This creates it on a local preferred path if it doesn't exist if (sTempDir == "") return E_FAIL; CComBSTR bOldWorkPath; CComBSTR bTempDir(sTempDir); hr = ipGPUtil->get_Workspace(&bOldWorkPath); hr = ipGPUtil->put_Workspace(bTempDir); hr = ipGPUtil->put_RefreshCatalogParent(-1); // Keep track of all layers/files added so we can delete them at the end std::vector<CString> vShapefileList; int nShape = 0; // Build the array of variant paramters IVariantArrayPtr ipValues(CLSID_VarArray); // COPY FEATURES -- to a temp shapefile CString sIn = "C:\\users\\erika dade\\arcgis\\xunarc10.0\\vectors\\v.shp"; // Any old feature shapefile vShapefileList.push_back(sTempDir + "copy.shp"); hr = ipValues.CreateInstance(CLSID_VarArray); hr = ipValues->Add(_variant_t(sIn)); // Input Feature Class hr = ipValues->Add(_variant_t("copy.shp")); // Output Feature Class ipResult.CreateInstance(CLSID_GeoProcessorResult); hr = ipGP->Execute(L"CopyFeatures_management", ipValues, 0, &ipResult); if (FAILED(hr)) { ipResult->GetMessages(0, &bsMessages); cMsg = bsMessages; MessageBox(cMsg, "Vectorization (GP-test1)", MB_OK);::SysFreeString(bsMessages); ipResult = 0; ipGP = 0; return hr; } // MAKE LAYER -- this creates lock file on copy shapefile in temp directory hr = ipValues.CreateInstance(CLSID_VarArray); hr = ipValues->Add(_variant_t("copy.shp")); // Input Feature Class hr = ipValues->Add(_variant_t(L"copyL")); // Output Feature Layer vShapefileList.push_back("copyL"); ipResult.CreateInstance(CLSID_GeoProcessorResult); hr = ipGP->Execute(L"MakeFeatureLayer_management", ipValues, 0, &ipResult); if (FAILED(hr)) { ipResult->GetMessages(0, &bsMessages); cMsg = bsMessages; MessageBox(cMsg, "Vectorization (GP-test2)", MB_OK);::SysFreeString(bsMessages); ipResult = 0; ipGP = 0; return hr; } // SELECT INTERSECTION // -- do this BY LOCATION and it will not release lock file on shapefile if (MessageBox("Set another lock through SelectLayerByLOCATION?", "GP Test", MB_YESNO) == IDYES) { CString outerPoly = "C:\\users\\erika dade\\arcgis\\xunarc10.0\\vectors\\vOuter.shp"; // boundary of feature shapefile hr = ipValues.CreateInstance(CLSID_VarArray); hr = ipValues->Add(_variant_t(L"copyL")); // Input feature layer hr = ipValues->Add(_variant_t(L"SHARE_A_LINE_SEGMENT_WITH")); // No tol, NEW SELECTION hr = ipValues->Add(_variant_t(outerPoly)); // Intersect feature class hr = ipResult.CreateInstance(CLSID_GeoProcessorResult); hr = ipGP->Execute(L"SelectLayerByLocation_management", ipValues, 0, &ipResult); // This puts another? lock on shapefile "copy" !!! if (FAILED(hr)) { ipResult->GetMessages(0, &bsMessages); cMsg = bsMessages; MessageBox(cMsg, "Vectorization (GP-test3)", MB_OK);::SysFreeString(bsMessages); ipResult = 0; ipGP = 0; return hr; } } // -- do this BY ATTRIBUTE and it WILL release lock file on shapefile if (MessageBox("Set another lock through SelectLayerByATTRIBUTE?", "GP Test", MB_YESNO) == IDYES) { CString sSelect; sSelect.Format("\"ID\" <> -9999"); hr = ipValues.CreateInstance(CLSID_VarArray); hr = ipValues->Add(_variant_t(L"copyL")); // Input Feature Layer hr = ipValues->Add(_variant_t(L"NEW_SELECTION")); // Exclusive new selection hr = ipValues->Add(_variant_t(sSelect)); // SQL ipResult.CreateInstance(CLSID_GeoProcessorResult); hr = ipGP->Execute(L"SelectLayerByAttribute_management", ipValues, 0, &ipResult); if (FAILED(hr)) { ipResult->GetMessages(0, &bsMessages); cMsg = bsMessages; MessageBox(cMsg, "Vectorization (GP-test4)", MB_OK);::SysFreeString(bsMessages); ipResult = 0; ipGP = 0; return hr; } } //=================================================== // Tidy up //=================================================== ipResult = 0; // If you leave the temp shape files (with .LOCK file) then can overwrite successfully. // If delete the temp shape files (but not .LOCK file) then cannot write new shapefile by same name bool bDeleteTemp = true; if (MessageBox("Delete temp files/layers/dir?", "GP Test", MB_YESNO) == IDNO) bDeleteTemp = false; if (bDeleteTemp) { bool bDel = false; for (int i=0; i<vShapefileList.size(); i++) { CString name(vShapefileList.at(i)); CString layerName = dropFileSuffix(extractFileName(name)); CComBSTR bLayerName(layerName); hr = ipGPUtil->RemoveInternalLayer(bLayerName); bLayerName.Empty(); bDel = DeleteGPTempFile(name); } } vShapefileList.clear(); // Both of these things necessary for multiple geoprocessor runs hr = ipGPUtil->ReleaseInternals(); // Critical !!! 11/2008 hr = ipGPUtil->put_RefreshCatalogParent(-1); hr = ipGPUtil->put_Workspace(bOldWorkPath); ipValues = 0; ipResult = 0; ipGPUtil = 0; ipGP = 0; // Will need to delete temp directory for client //if (bDeleteTemp) DeleteFolder(sTempDir); } // Uninitialize COM ::CoUninitialize(); return hr; }
... View more
01-13-2011
08:41 AM
|
0
|
2
|
1890
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|