|
POST
|
Neil, As it turns out, there are two bottlenecks, methods GetAppInfo and DetermineOverlapArea (below). DetermineOverlapArea calculates how much overlap two polygons have. If it's greater than 5%, we record it, otherwise, skip it. No idea why a simple area calculation would slow things down so much. public static bool DetermineOverlapArea(IFeature pFeature1, IFeature pFeature2)
{
try
{
IArea pFeature1Area = pFeature1.Shape as IArea;
IArea pFeature2Area = pFeature2.Shape as IArea;
ITopologicalOperator2 pTopologicalOperator = pFeature2.Shape as ITopologicalOperator2;
pTopologicalOperator.IsKnownSimple_2 = false;
pTopologicalOperator.Simplify();
IArea pIntersectArea = pTopologicalOperator.Intersect(pFeature1.Shape, esriGeometryDimension.esriGeometry2Dimension) as IArea;
int appOverlap = Convert.ToInt32((pIntersectArea.Area / pFeature1Area.Area) * 100);
int ensOverlap = Convert.ToInt32((pIntersectArea.Area / pFeature2Area.Area) * 100);
if (appOverlap > 5 || ensOverlap > 5)
return true;
else
return false;
}
catch (Exception ex)
{
LogError(ex.StackTrace, ex.Message, "DetermineOverlapArea", null);
return false;
}
} Use something like this to measure how long a block of code takes to execute. Dim startTime As Date = Now
' execute a block of code here
Dim span As TimeSpan = Now.Subtract(startTime)
Debug.Print("time to execute block: " & span.Seconds & " seconds")
Just modify the print statement so you can identify what's what in the debug window.
... View more
07-27-2011
12:35 PM
|
0
|
0
|
1853
|
|
POST
|
I commented out both GetAppInfo and PopAppCmgenTables methods and stopped the code after 20 minutes because it took the same amount of time to get through 7 of 17 records as the original code so it looks like the bottle neck is somewhere in there. I am including the code for both GetAppInfo and PopAppCmgenTables methods in case you see ways of improving them. GetAppInfo does a bunch of queries against Access tables and PopAppCmgenTables populates a few tables in another Access database. I have to admit, GetAppInfo is quite large, convoluted and ugly. It's evolved over the years with patches upon patches to deal with quirky data out of my control. When I started converting it to C# from VBA, I thought about trying to redo the method as a clean start but decided against it because I know the original code works well and fast. I will write out to a text file at the start and end of pieces of code with time stamps and see if I can narrow down the bottleneck. I had to zip the code up because it was too large to fit in this window and too large to send as a plain text file, sorry.
... View more
07-27-2011
11:39 AM
|
0
|
0
|
1853
|
|
POST
|
Thanks for the reply Neil! All the fields I query are indexed as I learned that lesson from you a couple of years ago. I will try your suggestions and see what happens. In the case of the two layers I am querying, the outter cursor (basin name) layer has only 17 features and there are no duplicate values of basin name. The inner cursor (app_no) has 76,000+ features and they are already merged by app_no to minimize queries so I guess there is no performance improvement there. I have very little VB6 experience, mostly using examples as reference for VBA or C# and no C++ so I will try to convert the code to VB inside of Visual Studio 2008 and see if it runs better there. If you have any other suggestions, I'm all ears. Thanks again for your time! Carlos .NET code using ArcObjects will almost always run slower than code written in VBA/VB6. This is because .NET does not directly support COM and VBA/VB6 does. Any call into a COM object in .NET must pass through a runtime callable wrapper (RCW) that acts as a middleman between COM and .NET. Naturally, this slows things down. The more ArcObjects calls you make, the slower it will run. That being said, there are several things you may be able to do to speed things up. The first is to make sure your data is properly indexed. Aside from a spatial index on the feature class, all attribute fields involved in the process should also be indexed. When you execute your queries, setting the Subfields property on the query/spatial filter will help. You should set this property to include only the fields that you need to be populated in the cursor. You should also review your logic to see if there is a way to reduce the number of queries you have to make. I don't know exactly what your code is doing but it looks like you are performing a spatial query on one layer for each feature in the other layer that has a basin name. Could you possibly combine the geometries of all features with the same basin name into a single spatial query? For instance, let's say there are 100 features in the layer with a single basin name. If you add these 100 geometries into a geometry bag and use it to execute a single spatial query then you will eliminate 99 spatial queries from the process. Of course, depending on what it is that you're doing with the query results you may not be able to do this but this is the type of thing you should look for. If all else fails, you may be better off writing this procedure in VB6 or C++ and compiling it into a library that you can then call from your .NET application.
... View more
07-27-2011
10:47 AM
|
0
|
0
|
1853
|
|
POST
|
Hi everyone, I am writing an stand alone C# application and I am having a performance issue. The following code was converted from VBA literally line by line. I am doing a spatial query between two layers. The VBA code runs in between 10 and 15 minutes. The C# code below takes just over 3 hours to do the same query on the same layers as the VBA code. The code below doesn't even start ArcMap, just accesses things directly. I also tried changing the code a bit to start ArcMap in code and then run the code but it still takes the same amount of time. Obviously, I am missing something/doing something wrong but I can't figure it out. Anyone have any ideas? Thanks, Carlos public static void AppsInBoundary()
{
try
{
IFeatureLayer pAppLayer = null;
IFeatureLayer pEnsLayer = null;
IFeatureCursor pEvgCursor = null;
IFeatureCursor pAppCursor = null;
IFeature pAppFeature = null;
IFeature pEnsFeature = null;
IArea pFeatureArea;
int featureCount = 0;
int appFieldIndex = 0;
string geometryFieldName = string.Empty;
//Get a reference to the two layers involved in the query.
pAppLayer = GetLayerReference("FILEGDB", "App_Merge", Scratch_Local + "temp.gdb", null) as IFeatureLayer;
pEnsLayer = GetLayerReference("SDE", "RIM.HYHDB_BSN_EVRGLDS_AREA", null, "gerrpsde") as IFeatureLayer;
//Make sure layers being queried have the same projection.
//Otherwise, topological operations later in the code (DetermineOverlapArea) fail.
SpatialReferenceCheck(pAppLayer, pEnsLayer);
//Find index of app no field in app_merge layer so query can run faster.
appFieldIndex = pAppLayer.FeatureClass.FindField("APP_NO");
//Select only polygons that have a basin name.
IQueryFilter pEnsQueryFilter = new QueryFilterClass();
pEnsQueryFilter.WhereClause = "basin_name <> ' '";
pEvgCursor = pEnsLayer.Search(pEnsQueryFilter, true);
pEnsFeature = pEvgCursor.NextFeature();
ISpatialFilter pAppSpatialFilter = new SpatialFilterClass();
while (pEnsFeature != null)
{
m_Label = pEnsFeature.get_Value(pEnsFeature.Fields.FindField("BASIN_NAME")).ToString();
pAppSpatialFilter.Geometry = pEnsFeature.Shape;
pAppSpatialFilter.GeometryField = "Shape";
pAppSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
pAppCursor = pAppLayer.Search(pAppSpatialFilter, true);
pAppFeature = pAppCursor.NextFeature();
while (pAppFeature != null)
{
if (pAppFeature.get_Value(appFieldIndex) != DBNull.Value)
{
m_AppNo = Convert.ToString(pAppFeature.get_Value(appFieldIndex));
pFeatureArea = pAppFeature.Shape as IArea;
m_AppArea = pFeatureArea.Area;
//Set relation type, in or adjacent.
if (DetermineOverlapArea(pAppFeature, pEnsFeature) == true)
m_Relation = "AI"; //Application In
else
m_Relation = "AA"; //Application Adjacent
//If app_no is not null, proceed, otherwise skip it.
if (m_AppNo != "")
{
//Check if app status is "no response", if it is not, proceed.
if (AppStatusCheck(m_AppNo) == true)
{
GetAppInfo(m_AppNo);
PopAppCmgenTables(m_AppNo, m_Relation);
}
}
pAppFeature = pAppCursor.NextFeature();
//Clear values.
m_AppNo = string.Empty;
m_AppArea = 0;
} //APP_NO != DBNull.Value
} //pAppFeature != null
pEnsFeature = pEvgCursor.NextFeature();
//Clear values.
m_AppNo = string.Empty;
m_Relation = string.Empty;
m_Label = string.Empty;
} //pEnsFeature != null
}
catch (Exception ex)
{
LogError(ex.StackTrace, ex.Message, "AppsInBoundary", null);
}
}
internal static ILayer GetLayerReference(string layerType, string featureClassName, string path, string serverName)
{
try
{
IWorkspaceFactory pWorkspaceFactory = null;
IFeatureWorkspace pFeatureWorkspace = null;
IFeatureClass pFeatureClass = null;
if (layerType == "SDE")
{
IPropertySet pPropertySet = new PropertySetClass();
pPropertySet = GetSdePropertySet(serverName, null);
pWorkspaceFactory = new SdeWorkspaceFactoryClass();
pFeatureWorkspace = pWorkspaceFactory.Open(pPropertySet, 0) as IFeatureWorkspace;
}
else if (layerType == "FILEGDB")
{
pWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
pFeatureWorkspace = pWorkspaceFactory.OpenFromFile(path, 0) as IFeatureWorkspace;
}
else if (layerType == "PGDB")
{
pWorkspaceFactory = new AccessWorkspaceFactoryClass();
pFeatureWorkspace = pWorkspaceFactory.OpenFromFile(path, 0) as IFeatureWorkspace;
}
pFeatureClass = pFeatureWorkspace.OpenFeatureClass(featureClassName);
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = pFeatureClass;
return pFeatureLayer;
}
catch (Exception ex)
{
LogError(ex.StackTrace, ex.Message, "GetGroupLayer", null);
return null;
}
}
... View more
07-27-2011
09:08 AM
|
0
|
19
|
5754
|
|
POST
|
Thanks, I'll see if I can make some sense out of it.
... View more
07-19-2011
08:35 AM
|
0
|
0
|
873
|
|
POST
|
Mr. Gray, Thanks for the reply. Do you know what I can do to fix this problem? This is an oracle problem, not a code problem. By default I think Oracle has 50 or so maximum cursors (not sure the exact number but it is low.) Now most applications use a 1 to 5 cursors so that is ok. ArcGIS uses much much more, I believe the recommended max is like 10 000 for an SDE database.
... View more
07-19-2011
07:25 AM
|
0
|
0
|
873
|
|
POST
|
Hi everyone, I have a standalone C# application that contains the following procedure which gets called to find a particular feature within an array of layers. This procedure gets called numerous times from inside a loop. Everything works fine for the first 25 passes but on the 26th pass, I get an error of "ORA-01000: maximum open cursors exceeded" on line pFeatureClass = pFeatureWorkspace.OpenFeatureClass(permitType). No matter where I try to do marshall release to free up the com objects, I keep getting the error. Been fighting with this for almost a day now and I'm out of ideas. Any insights are GREATLY appreciated! Carlos internal static void FindApplication(string appNo, out IFeature pOutFeature, out IFeatureClass pOutFeatureClass)
{
IPropertySet pPropertySet = new PropertySetClass();
IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
IFeatureWorkspace pFeatureWorkspace = null;
IFeatureClass pFeatureClass = null;
IQueryFilter pQueryFilter = new QueryFilterClass();
IFeatureCursor pFeatureCursor = null;
IFeature pFeature = null;
pOutFeature = null;
pOutFeatureClass = null;
string permitType = string.Empty;
try
{
pPropertySet.SetProperty("Server", "gerrdsde");
pPropertySet.SetProperty("Instance", "5154");
pPropertySet.SetProperty("Database", "gerrd");
pPropertySet.SetProperty("User", "rim");
pPropertySet.SetProperty("Password", "RPS4240sde");
pPropertySet.SetProperty("Version", "SDE.DEFAULT");
string[] layerArray = {"RIM.PRSTF_JDS_APP_AREA", "RIM.PRSTF_SBL_APP_AREA", "RIM.PRSTF_OST_APP_AREA",
"RIM.PRSTF_DAF_APP_AREA", "RIM.PRSTF_AQU_APP_AREA", "RIM.PRSTF_WDI_APP_AREA",
"RIM.PRSTF_MIT_APP_AREA", "RIM.PRSTF_WDF_APP_AREA", "RIM.PRSTF_WUP_PWS_APP_AREA",
"RIM.PRSTF_WUP_DEW_APP_AREA", "RIM.PRSTF_WUP_DIV_APP_AREA", "RIM.PRSTF_WUP_APP_AREA",
"RIM.PRSTF_SWM_APP_AREA", "RIM.PRSTF_ERP_APP_AREA", "RIM.PRSTF_LOK_APP_AREA",
"RIM.PRSTF_WQE_AREA"};
for (int i = 0; i < layerArray.Length; i++)
{
permitType = layerArray;
IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
pFeatureWorkspace = pWorkspaceFactory.Open(pPropertySet, 0) as IFeatureWorkspace;
pFeatureClass = pFeatureWorkspace.OpenFeatureClass(permitType);
pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = "APP_NO = '" + appNo + "'";
pFeatureCursor = pFeatureClass.Search(pQueryFilter, false);
pFeature = pFeatureCursor.NextFeature();
if (pFeature != null) break;
}
//If feature found, return feature and feature class feature is in.
if (pFeature != null && pFeatureClass != null)
{
pOutFeature = pFeature;
pOutFeatureClass = pFeatureClass;
}
}
catch (Exception ex)
{
MessageBox.Show("Procedure FindApplication " + ex.Message);
}
finally
{
if (pQueryFilter != null) { Marshal.ReleaseComObject(pQueryFilter); pQueryFilter = null; }
if (pFeatureCursor != null) { Marshal.ReleaseComObject(pFeatureCursor); pFeatureCursor = null; }
if (pPropertySet != null) { Marshal.ReleaseComObject(pPropertySet); pPropertySet = null; }
if (pWorkspaceFactory != null) { Marshal.ReleaseComObject(pWorkspaceFactory); pWorkspaceFactory = null; }
if (pFeatureWorkspace != null) { Marshal.ReleaseComObject(pFeatureWorkspace); pFeatureWorkspace = null; }
permitType = null;
}
}
... View more
07-19-2011
07:08 AM
|
0
|
4
|
4704
|
|
POST
|
Neil, Thanks for the reply! As you suggested, I changed the code and got it to work. The new code is below. Do you see any potential pitfalls in doing it this way? Thanks again, Carlos public static void AppendFeatureClasses()
{
try
{
//Delete connection file if it exists.
if (File.Exists(Scratch_Local + "gerrpsde.sde"))
File.Delete(Scratch_Local + "gerrpsde.sde");
//Create connection file.
IPropertySet pPropertySet = new PropertySetClass();
pPropertySet = GetSdePropertySet("gerrpsde", null);
IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
pWorkspaceFactory.Create(Scratch_Local, "gerrpsde.sde", pPropertySet, 0);
//Create App_Merge layer.
object[,] fieldsValuesArray = new object[1, 5];
fieldsValuesArray[0, 0] = "APP_NO";
fieldsValuesArray[0, 1] = esriFieldType.esriFieldTypeString;
fieldsValuesArray[0, 2] = true;
fieldsValuesArray[0, 3] = true;
fieldsValuesArray[0, 4] = 20;
IFields pFields = CreateFieldsCollection(fieldsValuesArray);
IWorkspaceFactory pFileGDBWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
IFeatureWorkspace pFeatureWorkspace = pFileGDBWorkspaceFactory.OpenFromFile(Scratch_Local + "temp.gdb", 0) as IFeatureWorkspace;
IFeatureClass pOutFeatureClass = CreateFeatureClass(pFeatureWorkspace, "App_Merge", esriFeatureType.esriFTSimple, esriGeometryType.esriGeometryPolygon, pFields, null, null, null);
// Create the layer.
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = pOutFeatureClass;
// Do Append.
ESRI.ArcGIS.DataManagementTools.Append pAppend = new ESRI.ArcGIS.DataManagementTools.Append();
pAppend.inputs = Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_SWM_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_ERP_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_PWS_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DEW_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DIV_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_APP_AREA";
pAppend.target = Scratch_Local + "temp.gdb" + "\\" + "App_Merge";
pAppend.schema_type = "NO_TEST";
ESRI.ArcGIS.Geoprocessor.Geoprocessor pGeoProcessor = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
ITrackCancel pTrackCancel = new CancelTrackerClass();
pTrackCancel.CancelOnClick = false;
pTrackCancel.CancelOnKeyPress = true;
pGeoProcessor.Execute(pAppend, pTrackCancel);
}
catch (Exception ex)
{
LogError(ex.StackTrace, ex.Message, "AppendFeatureClasses", null);
}
} You can only have an IApplication reference if ArcMap is running. If it's not running then you'll need to modify the code to work without an application reference. The first thing to do will be to get rid of the code that uses IObjectFactory. Another thing I see is the way you're running the geoprocessing tool. To run a geoprocessing tool, create an instance of the Geoprocessor class as well as an instance of the tool class you want to run. Set the parameters on the tool class then pass it into IGeoprocessor.Execute.
... View more
07-18-2011
06:41 AM
|
0
|
0
|
563
|
|
POST
|
Michael, Did you get this solved? I am stuck in the same spot you were. Thanks, Carlos Hi there, I'd like to append shapefiles into an SDE geodatabse. I've tried shp2sde, but I get all kinds of polygon-geometry errors and it fails. Using the DataManagement append tool seems to work, but I need to implement it in my .net application. I guess I could use model builder, and try to call the python script from .net, but I'd like to use the DataManagement library in .net. Problem is, I can't find any documentation for how to reference a SDE geodatabase as the ouput. Can anyone help, please?
var append = new Append();
append.field_mapping = @"\\server1\Perils\WindStorms\columnmatch.txt";
append.inputs = @"\\server1\Perils\WindStorms\201007N_wind_2010080503.shp";
append.output = "???";
append.schema_type = "NO_TEST";
... View more
07-18-2011
05:36 AM
|
0
|
0
|
612
|
|
POST
|
Hi everyone, I am writing a standalone C# application and have hit a snag using the Append command. The code below works fine if I first start ArcMap and then run the code. The problem with doing it this way is that the append command takes four or five times the amount of time to run from inside ArcMap than doing it manually in ArcToolBox and performance is of the upmost importance. If I try to run this code from outside of ArcMap, I hit a snag at line: IObjectFactory pObjectFactory = m_application as IObjectFactory because m_application is null. In the original code, I was getting a reference to it from the start up routine. Any idea how I can get a reference to m_applicaiton from outside ArcMap? Thanks, Carlos public static void AppendFeatureClasses()
{
try
{
IObjectFactory pObjectFactory = m_application as IObjectFactory;
//Delete connection file if it exists.
if (File.Exists(Scratch_Local + "gerrpsde.sde"))
File.Delete(Scratch_Local + "gerrpsde.sde");
//Create connection file.
//IPropertySet pPropertySet = new PropertySetClass();
Type propertySetType = typeof(PropertySetClass);
string typeClsID1 = propertySetType.GUID.ToString("B");
IPropertySet pPropertySet = (IPropertySet)pObjectFactory.Create(typeClsID1);
pPropertySet = GetSdePropertySet("gerrpsde", null);
Type SdeWorkspaceFactoryType = typeof(SdeWorkspaceFactoryClass);
string typeClsID2 = SdeWorkspaceFactoryType.GUID.ToString("B");
IWorkspaceFactory pWorkspaceFactory = (IWorkspaceFactory)pObjectFactory.Create(typeClsID2);
pWorkspaceFactory.Create(Scratch_Local, "gerrpsde.sde", pPropertySet, 0);
//Create App_Merge layer.
object[,] fieldsValuesArray = new object[1, 5];
fieldsValuesArray[0, 0] = "APP_NO";
fieldsValuesArray[0, 1] = esriFieldType.esriFieldTypeString;
fieldsValuesArray[0, 2] = true;
fieldsValuesArray[0, 3] = true;
fieldsValuesArray[0, 4] = 20;
IFields pFields = CreateFieldsCollection(fieldsValuesArray);
Type FileGDBWorkspaceFactoryType = typeof(FileGDBWorkspaceFactoryClass);
string typeFileGdbClsID = FileGDBWorkspaceFactoryType.GUID.ToString("B");
IWorkspaceFactory pFileGDBWorkspaceFactory = (IWorkspaceFactory)pObjectFactory.Create(typeFileGdbClsID);
IFeatureWorkspace pFeatureWorkspace = pFileGDBWorkspaceFactory.OpenFromFile(Scratch_Local + "temp.gdb", 0) as IFeatureWorkspace;
IFeatureClass pOutFeatureClass = CreateFeatureClass(pFeatureWorkspace, "App_Merge", esriFeatureType.esriFTSimple, esriGeometryType.esriGeometryPolygon, pFields, null, null, null);
// Create the layer.
Type featureLayerType = typeof(FeatureLayerClass);
string typeClsID3 = featureLayerType.GUID.ToString("B");
IFeatureLayer pFeatureLayer = (IFeatureLayer)pObjectFactory.Create(typeClsID3);
pFeatureLayer.FeatureClass = pOutFeatureClass;
// Do Append.
//UIDClass uid = new UIDClass();
Type uidType = typeof(UIDClass);
string typeClsID4 = uidType.GUID.ToString("B");
UID uid = (UID)pObjectFactory.Create(typeClsID4);
uid.Value = "esriGeoprocessingUI.ArcToolBoxExtension";
IArcToolboxExtension tbExtension = (IArcToolboxExtension)m_application.FindExtensionByCLSID(uid);
IArcToolbox toolbox = tbExtension.ArcToolbox;
IGPTool appendTool = toolbox.GetToolbyNameString("Append_management");
IArray parametersArray = appendTool.ParameterInfo;
// GP Parameter
IGPParameter parameter;
IGPParameterEdit parameterEdit;
IGPDataType dataType;
string parameterValue;
// Set first parameter (input layers).
parameter = (IGPParameter)parametersArray.get_Element(0);
dataType = parameter.DataType;
parameterEdit = (IGPParameterEdit)parameter;
parameterValue = Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_SWM_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_ERP_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_PWS_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DEW_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_DIV_APP_AREA;" +
Scratch_Local + "\\gerrpsde.sde\\RIM.PRSTF_WUP_APP_AREA";
parameterEdit.Value = dataType.CreateValue(parameterValue);
// Set up second parameter (output file).
parameter = (IGPParameter)parametersArray.get_Element(1);
dataType = parameter.DataType;
parameterEdit = (IGPParameterEdit)parameter;
parameterValue = Scratch_Local + "temp.gdb" + "\\" + "App_Merge";
parameterEdit.Value = dataType.CreateValue(parameterValue);
parameter = (IGPParameter)parametersArray.get_Element(2);
dataType = parameter.DataType;
parameterEdit = (IGPParameterEdit)parameter;
parameterValue = "NO_TEST";
parameterEdit.Value = dataType.CreateValue(parameterValue);
//ITrackCancel pTrackCancel = new CancelTrackerClass();
Type CancelTrackerType = typeof(CancelTrackerClass);
string typeClsID5 = CancelTrackerType.GUID.ToString("B");
ITrackCancel pTrackCancel = (ITrackCancel)pObjectFactory.Create(typeClsID5);
pTrackCancel.CancelOnClick = false;
pTrackCancel.CancelOnKeyPress = true;
Type GPEnvironmentManagerType = typeof(GPEnvironmentManagerClass);
string typeClsID6 = GPEnvironmentManagerType.GUID.ToString("B");
IGPEnvironmentManager pGPEnvironmentManager = (IGPEnvironmentManager)pObjectFactory.Create(typeClsID6);
Type IGPMessagesType = typeof(GPMessagesClass);
string typeClsID7 = IGPMessagesType.GUID.ToString("B");
IGPMessages pGPMessages = (IGPMessages)pObjectFactory.Create(typeClsID7);
// Execute the tool.
appendTool.Execute(parametersArray, pTrackCancel, pGPEnvironmentManager, pGPMessages);
}
catch (Exception ex)
{
LogError(ex.StackTrace, ex.Message, "AppendFeatureClasses", null);
}
}
... View more
07-18-2011
05:27 AM
|
0
|
2
|
1205
|
|
POST
|
Neil, You are correct, I was getting a map reference from IMxDocument.FocusMap. Thanks for pointing me in the right direction, I will give it a try. Carlos You just create a new map object. I'm assuming your original code worked with a map reference that you got from IMxDocument.FocusMap. None of that code logic would change except that you're creating a new map instead of using one you got from ArcMap. Dim map As IMap = new Map The code to create the layer objects should be pretty much the same as what you were originally doing, just add them to this map instead. Also use this map to get your IActiveView references and any others that you were originally getting from the ArcMap document's FocusMap.
... View more
07-13-2011
06:48 AM
|
0
|
0
|
2039
|
|
POST
|
No I haven't tried that. To be honest, not sure I know how to do that. Do you have some sample code I could look at to get started even if it's VB6, VB.NET or VBA? Have you tried creating a new instance of the Map class and adding a couple of layers to it then exporting it as a jpg image? If that works, then you can add all of the additional code.
... View more
07-13-2011
06:35 AM
|
0
|
0
|
2039
|
|
POST
|
Yeah, I would prefer to avoid using ArcMap altogether if I can get away with it. Unfortunately, no I don't have a map document that has layers, symbology, etc. that I need. In the original VBA code, the mxd had all the code in it and it would fire off from OpenDocument. First it would load all necessary layers, then run queries and finally, apply layer files to the desired layers and produce jpg maps. It worked fantastic in VBA but unfortunately, the transfer to C# isn't going so smoothly. Yes, you need to use IObjectFactory to create all instances of the ArcObjects that will be used in conjunction with the ArcMap application. If you have a map document created that has all of the layers, symbology, layout elements, etc that you need then you can use IMapDocument to open the document and work with it. This includes zooming the map frames to various extents and exporting the layout. You can also manipulate the layout by adding elements or modifying existing elements. Things can get complicated if you need to create layouts from scratch every time but it's about the same level of effort trying to do the same thing by automating ArcMap. I've never run into a case where automating ArcMap was needed and I would try to avoid it like the plague. ArcMap wasn't designed to be automated and the whole process is flaky and, in my opinion, a lot more trouble than it's worth.
... View more
07-13-2011
06:19 AM
|
0
|
0
|
2039
|
|
POST
|
Thanks Neil, I am looking at the developer sample Automation example now. Does this mean I have to use IObjectFactory for every new ArcObject I create? One more question if you don't mind, a few months ago you got me on the right track of writing the stand alone C# application I was refering to in my original message where I didn't need to load ArcMap to do what I needed to do, queries and edits. Do you know if can use the same approach in my new application where I will be producing automated maps in jpg format or if I need to start ArcMap to get to layout, graphics, etc.? Thanks again for you help!!! Carlos You can't use New to create instances of the objects you will be using in conjunction with the ArcMap application.. You need to be using IObjectFactory. Your application and ArcMap are running in seperate processes. All ArcObjects are single apartment threaded, meaning they will not marshal correctly when used across process boundaries. Therefore, you will need to create the ArcObjects instances in ArcMap's process space, not your application's process space. IObjectFactory will do this for you. There is a developer sample on Automation that you might want to look at.
... View more
07-13-2011
06:01 AM
|
0
|
0
|
2039
|
|
POST
|
Hi everyone, I am writing a standalone application in C# for creating automated jpg maps. Originally, the code was in VBA and I am converting it to C#. I've written a couple of other standalone applications in C# where I queried and edited data but in those I was able to do it without having to call up ArcMap. Unforunately, I think for working with layouts, graphics, etc., I have to use ArcMap. If I am mistaken in this, please correct me. Anyhow, here's my problem. I can start ArcMap in code and load seveal SDE layers into it. The problem occurs when I try to do anything with the layers in the TOC. If I try to open an attribute table or change symbology, the screen flashes, all of the names of the layers in the TOC go away and all I am left with is the on/off checkbox with the red broken link exclamation mark next to each layer. After a few seconds, ArcMap crashes. I've seen a couple of similiar posts in the old forums but no solutions. Anyone have an idea of what I am doing wrong? Below is my code for starting ArcMap and loading SDE layers plus a screen capture of the error when ArcMap crashes. Thanks for your time, Carlos internal static void StartArcMap()
{
try
{
m_MxDocument = new MxDocumentClass();
m_application = ((IDocument)m_MxDocument).Parent;
m_application.Visible = true;
// Wait for ArcMap to initialize before continuing.
System.Windows.Forms.Application.DoEvents();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} internal static ILayer AddSDEFeatureClass(string server, string instance, string user,
string password, string version, string featureClassName,
string tocName, short transparency, bool labels,
bool visibility, bool selectability)
{
try
{
IPropertySet pPropertySet = new PropertySetClass();
pPropertySet.SetProperty("SERVER", server);
pPropertySet.SetProperty("INSTANCE", instance);
pPropertySet.SetProperty("USER", user);
pPropertySet.SetProperty("PASSWORD", password);
pPropertySet.SetProperty("VERSION", version);
IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
IFeatureWorkspace pFeatureWorkspace = pWorkspaceFactory.Open(pPropertySet, 0) as IFeatureWorkspace;
IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(featureClassName);
IFeatureLayer pFeatureLayer = new FeatureLayerClass();
pFeatureLayer.FeatureClass = pFeatureClass;
m_MxDocument.FocusMap.AddLayer(pFeatureLayer);
IGeoFeatureLayer pGeoFeatureLayerOut = pFeatureLayer as IGeoFeatureLayer;
// Apply TOC name.
pGeoFeatureLayerOut.Name = tocName;
// Set transparency.
ILayerEffects pLayerEffects = pFeatureLayer as ILayerEffects;
pLayerEffects.Transparency = transparency;
// Collapse the layer in the TOC.
ILegendInfo pLegendInfo = pGeoFeatureLayerOut as ILegendInfo;
ILegendGroup pLegendGroup = new LegendGroupClass();
pLegendGroup = pLegendInfo.get_LegendGroup(0);
pLegendGroup.Visible = false;
// if labels = true, turn labels on, otherwise off.
if (labels == true)
pGeoFeatureLayerOut.DisplayAnnotation = true;
else
pGeoFeatureLayerOut.DisplayAnnotation = false;
// If visibility = true, turn layer on, otherwise off.
if (visibility == true)
pGeoFeatureLayerOut.Visible = true;
else
pGeoFeatureLayerOut.Visible = false;
// If selectability = true, turn layer on, otherwise off.
if (selectability == true)
pGeoFeatureLayerOut.Selectable = true;
else
pGeoFeatureLayerOut.Selectable = false;
m_MxDocument.ActiveView.Refresh();
m_MxDocument.UpdateContents();
return pGeoFeatureLayerOut;
} //end try
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
... View more
07-13-2011
03:08 AM
|
0
|
9
|
5139
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 02-11-2016 06:06 AM | |
| 1 | 08-07-2015 10:13 AM | |
| 2 | 06-29-2015 12:45 PM |
| Online Status |
Offline
|
| Date Last Visited |
11-11-2020
02:23 AM
|