Solved! Go to Solution.
This is probably very simple. I can load a geodatabase featureclass with IWorkspace::OpenFromFile and the FileGDBWorkspaceFactory CoClass and likewise with ShapefileWorkspaceFactoryClass for shapefiles...is there a way to load both with the same generic workspace factory or do I have to set a different one based on what is selected in my custom Add data dialog?
The interface is generic (IWorkspaceFactory) but the classes that implement it are all specific to the data type.
You are correct sir.
I was being intentionally less obvious to the OP because I thought maybe they would see the difference between Interfaces and Classes and realize the answer to their question.
public static void listFeatureclass(String file) throws java.net.UnknownHostException, java.io.IOException { com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory factory = new com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory(); com.esri.arcgis.geodatabase.IWorkspace workspace = factory.openFromFile(file, 0); com.esri.arcgis.geodatabase.IEnumDataset enumDataset = workspace.getDatasets(com.esri.arcgis.geodatabase.esriDatasetType.esriDTFeatureClass); com.esri.arcgis.geodatabase.IDataset ds = null; ds = enumDataset.next(); while(ds != null){ com.esri.arcgis.geodatabase.IFeatureClass fClass = new com.esri.arcgis.geodatabase.IFeatureClassProxy(ds); int fCount = fClass.featureCount(null); System.out.println("FeatureClass "+ fClass.getAliasName() +" has "+fCount+ " features."); ds = enumDataset.next(); } } public static void listFeatureclass2(String file) throws java.net.UnknownHostException, java.io.IOException { com.esri.arcgis.geodatabase.WorkspaceFactory factory = new com.esri.arcgis.geodatabase.WorkspaceFactory(new com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory()); com.esri.arcgis.geodatabase.IWorkspace workspace = factory.openFromFile(file, 0); com.esri.arcgis.geodatabase.IEnumDataset enumDataset = workspace.getDatasets(com.esri.arcgis.geodatabase.esriDatasetType.esriDTFeatureClass); com.esri.arcgis.geodatabase.IDataset ds = null; ds = enumDataset.next(); while(ds != null){ com.esri.arcgis.geodatabase.IFeatureClass fClass = new com.esri.arcgis.geodatabase.IFeatureClassProxy(ds); int fCount = fClass.featureCount(null); System.out.println("FeatureClass "+ fClass.getAliasName() +" has "+fCount+ " features."); ds = enumDataset.next(); } }
I just got thinking about the class factory design pattern, in which the factory class decides what type of object to create. This is different from the workspace factory since you have to know what type of workspace you want (shapefile, file gdb, sde, etc.) before creating a specific type of workspace factory to get that same type of workspace. It strikes me as somewhat going against what the factory design pattern is supposed to be. Factories are supposed to decide the specific class type for you...
public static void createWorkspace(String filePath, IWorkspaceFactory temp, String shapefileName){ try { if(temp.getWorkspaceType() == esriWorkspaceType.esriFileSystemWorkspace){ com.esri.arcgis.geodatabase.WorkspaceFactory wsf = new com.esri.arcgis.geodatabase.WorkspaceFactory(temp); com.esri.arcgis.geodatabase.Workspace work = new com.esri.arcgis.geodatabase.Workspace(wsf.openFromFile(filePath, 0)); com.esri.arcgis.geodatabase.IFeatureClass featureClass = work.openFeatureClass(shapefileName); System.out.println(featureClass.getAliasName() + " " + featureClass.featureCount(null)); } if(temp.getWorkspaceType() == esriWorkspaceType.esriLocalDatabaseWorkspace){ com.esri.arcgis.geodatabase.WorkspaceFactory factory = new com.esri.arcgis.geodatabase.WorkspaceFactory(temp); com.esri.arcgis.geodatabase.IWorkspace workspace = factory.openFromFile(filePath, 0); com.esri.arcgis.geodatabase.IEnumDataset enumDataset = workspace.getDatasets(com.esri.arcgis.geodatabase.esriDatasetType.esriDTFeatureClass); com.esri.arcgis.geodatabase.IDataset ds = null; ds = enumDataset.next(); while(ds != null){ com.esri.arcgis.geodatabase.IFeatureClass fClass = new com.esri.arcgis.geodatabase.IFeatureClassProxy(ds); int fCount = fClass.featureCount(null); System.out.println(fClass.getAliasName() +" has "+fCount+ " features."); ds = enumDataset.next(); } } } catch (AutomationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
Are you talking about the Factory Method pattern? If yes, then you create an interface for creating objects, and let subclasses define what type of object is being created.
There is a really cool thing called the ArcObjects API. Granted, I can't hold it against anyone who tries to make sense of the ArcObjects .NET API, because you can't find anything without expanding, expanding, expanding..
This is a Java example, so sorry for that.
I opened eclipse and used the new project wizard to create a console application. Then I used the sample ArcGIS snippets for listing feature classes of a FGDB workspace.
Notice in listFeatureclass, they use the concrete class FileGeodatabaseWorkspaceFactory to create new FileGeodatabaseWorkspaceFactory.
Notice in listFeatureclass2, we're using the WorkspaceFactory class .. what? What kind of black magic is that?
Give them a try, pass in a file name of "c:\\myfgdb.gdb" and see what happens.public static void listFeatureclass(String file) throws java.net.UnknownHostException, java.io.IOException { com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory factory = new com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory(); com.esri.arcgis.geodatabase.IWorkspace workspace = factory.openFromFile(file, 0); com.esri.arcgis.geodatabase.IEnumDataset enumDataset = workspace.getDatasets(com.esri.arcgis.geodatabase.esriDatasetType.esriDTFeatureClass); com.esri.arcgis.geodatabase.IDataset ds = null; ds = enumDataset.next(); while(ds != null){ com.esri.arcgis.geodatabase.IFeatureClass fClass = new com.esri.arcgis.geodatabase.IFeatureClassProxy(ds); int fCount = fClass.featureCount(null); System.out.println("FeatureClass "+ fClass.getAliasName() +" has "+fCount+ " features."); ds = enumDataset.next(); } } public static void listFeatureclass2(String file) throws java.net.UnknownHostException, java.io.IOException { com.esri.arcgis.geodatabase.WorkspaceFactory factory = new com.esri.arcgis.geodatabase.WorkspaceFactory(new com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory()); com.esri.arcgis.geodatabase.IWorkspace workspace = factory.openFromFile(file, 0); com.esri.arcgis.geodatabase.IEnumDataset enumDataset = workspace.getDatasets(com.esri.arcgis.geodatabase.esriDatasetType.esriDTFeatureClass); com.esri.arcgis.geodatabase.IDataset ds = null; ds = enumDataset.next(); while(ds != null){ com.esri.arcgis.geodatabase.IFeatureClass fClass = new com.esri.arcgis.geodatabase.IFeatureClassProxy(ds); int fCount = fClass.featureCount(null); System.out.println("FeatureClass "+ fClass.getAliasName() +" has "+fCount+ " features."); ds = enumDataset.next(); } }
even if you know the exact type of class to which you have a reference, the .NET runtime still does not have the required metadata to cast the variable to a strongly typed RCW