....This is a Java example, so sorry for that.
You would not want to pass a string, because that is not type safe. What if someone passed in a misspelled string?
Yes I was talking about Factory method pattern. I was thinking something along those lines. A class where you just pass a string in the constructor, no workspace factory, and it spit out the appropriate workspace.
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(); } }
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
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.
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(); } }
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.
The interface is generic (IWorkspaceFactory) but the classes that implement it are all specific to the data type.
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?
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.