Tips for Importing Data into the Geodatabase
I spent some time recently writing some C# ArcObjects code to convert geographic data from a another system into the geodatabase. It's been an interesting project because I've had to handle the translation of a different geometry structure into ArcObjects geometry. Okay, it's still points/lines/polys, so it's not that different, but you know what I mean. I've also gotten 'way deep' into coordinate systems as part of this process, and learned a bit about best practices when loading/deleting geodatabase features.
Geometry
Ok, so I started with points and I still have lines and polys on my todo list. What this means is that I' m the type of person that likes to build from small successes...
Coordinate Systems
I was pretty familiar with how ArcObjects treats projections and coordinate systems. Every feature class has, or should have, a SpatialReference, which is in turn comprised of (at least this is how I think about it), a coordinate system with an XYZ domain. The coordinate system may be a ProjectedCoordinateSystem (e.g. Albers Equal Area, State Plane, UTM), or it may be a GeographicCoordinateSystem (e.g. WGS 84, or NAD 27).
Also, if a SpatialReference is a ProjectedCoordinateSystem, then the PCS has a GeographicCoordinateSystem (acces thru IProjectedCoordinateSystem::GeographicCoordinateSystem).
You can build up coordinate systems from scratch, but this can be, quite frankly, a pain in the azimuth (sorry).
It's much easier if you know the name of the PCS or GCS that you want to create, to use ISpatialReferenceFactory::CreateProjectedCoordinateSystem or ISpatialReferenceFactory::CreateGeographicCoordinateSystem. These methods take a long parameter that represents the factory code for the coordinate system. You can look up factory codes based on coordinate system names in the ArcObjects documentation.
For a GCS see the enums esriSRGeoCSType, esriSRGeoCS2Type, and esriSRGeoCS3Type
For a PCS see the enums esriSRProjCSType, esriSRProjCS2Type, and esriSRProjCS3Type
MOST convenient for me however, because I was being handed a factory code that could be either a GCS or a PCS, was to use ISpatialReferenceFactory2::CreateSpatialReference. This method lets creates either a GCS or a PCS depending on what factory code you give it.
You can read more about coordinate systems in the ArcObjects Geometry Library Overview.
Deleting Geodatabase Features
I needed to implement some functionality to delete features from an SDE geodatabase feature class. I looked through the online doc, and found, well, man ways to do this. But, I wanted to know the best way to do this, so I asked my colleague MC. at ESRI.
The conversation went something like this.
Cory - "Hey, can I delete features from a non-versioned feature class, or do I need to version it?"
MC - "You don't need to version your data"
C - "Coolness" (or something like that) "I'm doing my delete in the context of a workspace edit session, like this:
workspaceEdit = (IWorkspaceEdit) mySdeWs;
workspaceEdit.StartEditing (false);
workspaceEdit.StartEditOperation();
// do my delete
workspaceEdit.StopEditOperation();
workspaceEdit.StopEditing(true);
Do I need the workspace edit stuff? If so, why?"
MC - "I always put in the edit session code. That way, if the data does become versioned, my code will still work."
C - "Ok, thanks. Now, there appear to be seventy nine ways to delete a feature.
IFeature.Delete
IFeatureCursor.DeleteFeature
ITable.DeleteSearchedRows
IRowEdit.DeleteSet
...
Which should I use, given that: my features are simple, don't
participate in relationships, and they're not versioned. Also, I don't
need any 'rollback', and I may be deleting a lot of features?"
MC - "I would recommend using ITable.DeleteSearchedRows since this is the "simplest" call and should do the fastest thing. My second choice would be IFeatureCursor.DeleteFeature called on an update cursor because if you use buffering it can batch up features to delete to minimize database queries. IFeature.Delete is generally the slowest since it happens for each feature."
UPDATE: - After trying to implement MC's suggestion to use buffering in combination with IFeatureCursor.DeleteFeature, I had to ask him a follow up question: How exactly do you do this? I couldn't see a way to do this through the API. Well, it turns out that this is done behind the scenes for you. When you use IFeatureCursor.DeleteFeature, the cursor is flushed every 100 features or so...
-Cory (5/26/06)
C - "Great, thanks."
Talk to you soon,
-Cory
