2

I need to determine the WorkspaceCategory string (IGxDialog.FinalLocation.WorkspaceCategory) for a given path. I need this to create appropriate WorkspaceFactory and finally be able to create multiple feature classes / shapefiles in a given location.

Right now I'm using IGxDialog with GxFilterContainers to select final location, but when I select a file geodatabase, the pGxDialog.FinalLocation.WorkspaceCategory returns "Folder" (the parent folder of the selected container), not the category of the selected container.

    Dim pGxDialog As IGxDialog = New GxDialog
    Dim pFilterCol As IGxObjectFilterCollection
    Dim pGxFilter As IGxObjectFilter
    Dim pEnumGx As IEnumGxObject
    pGxDialog.AllowMultiSelect = False
    pFilterCol = pGxDialog
    pGxFilter = New ESRI.ArcGIS.Catalog.GxFilterContainers
    pFilterCol.AddFilter(pGxFilter, True)

    If (pGxDialog.DoModalOpen(0, pEnumGx) = True) Then
        sOutputPath = pGxDialog.FinalLocation.FullName
        sOutputName = pEnumGx.Next.Name
        workspaceCat = pGxDialog.FinalLocation.Category
    End If

So, the questions are:

  • how can I get the WorkspaceCategory string for a given path?
  • are there any other ways of creating appropriate WorkspaceFactory for a given location (e.g. if my output location is a folder, I would need to create ShapefileWorkspaceFactory, if the output location is a file geodatabase, I would need a FileGDBWorkspaceFactory etc.).
4

The GPUtilities class provides all sorts of methods useful when dealing with paths and dataset information. Your goal can be achieved in many ways such leveraging light-weight name objects:

Sub WorkspaceFactoryForPath()    
    Dim pGPUtilities As IGPUtilities
    Dim pName As IName
    Dim pWorkspaceName As IWorkspaceName
    Dim sCatalogPath As String      
    sCatalogPath = "C:\data\File Geodatabase.gdb\"

    Set pGPUtilities = New GPUtilities
    Set pName = pGPUtilities.GetNameObjectFromLocation(sCatalogPath)

    If TypeOf pName Is IWorkspaceName Then  ' the location refers to a workspace
        Set pWorkspaceName = pName          
        Debug.Print pWorkspaceName.WorkspaceFactoryProgID ' access the workspace factory ProgID
        Debug.Print pWorkspaceName.WorkspaceFactory.WorkspaceDescription(False) ' or access the workspace factory directly      
    End If
End Sub
  • Thanks Petr. How would this handle feature dataset in a geodatabase as an output workspace? "TypeOf pName Is IWorkspaceName" condition would not be met? – jan_b Mar 21 '14 at 19:29
  • It would not, since feature datasets are not workspaces, they live IN a workspace. Anyway, the name object would then be an IFeatureDatasetName instance. – Petr Krebs Mar 22 '14 at 7:05
  • Also, note that you can always get from any name object to the actual geodatabase object it represents by using IName.Open() method. – Petr Krebs Mar 22 '14 at 7:06
  • @PetrKrebs If sCatalogPath is a folder (i.e. for a shapefile) pName is not IWorkspaceName. Is there a workaround for working with shapefiles as well? – Barbarossa Oct 5 '18 at 13:44
2

This is a function I use to get the type of workspace. This has the benefit of working correctly when the code is being used on computer set to a different language. A problem I ran into when using FinalLocation was it returns the name in the local language.

Public Function GetCategory(ByVal pWorkspace As ESRI.ArcGIS.Geodatabase.IWorkspace) As String

    Dim sClassID As String
    sClassID = pWorkspace.WorkspaceFactory.GetClassID.Value

    Select Case sClassID
        Case "{DD48C96A-D92A-11D1-AA81-00C04FA33A15}" ' pGDB
            GetCategory = "Personal Geodatabase"

        Case "{71FE75F0-EA0C-4406-873E-B7D53748AE7E}" ' fGDB
            GetCategory = "File Geodatabase"          '

        Case "{D9B4FA40-D6D9-11D1-AA81-00C04FA33A15}" ' GDB
            GetCategory = "SDE Database"

        Case "{A06ADB96-D95C-11D1-AA81-00C04FA33A15}" ' Shape
            GetCategory = "Shapefile Workspace"

        Case "{34DAE34F-DBE2-409C-8F85-DDBB46138011}" ' SDC
            GetCategory = "SDC Workspace"

        Case "{1D887452-D9F2-11D1-AA81-00C04FA33A15}" ' Coverage
            GetCategory = "ArcInfo Coverage Workspace"

        Case "{7F2BC55C-B902-43D0-A566-AA47EA9FDA2C}" ' InMemory
            GetCategory = "InMemory Workspace"

        Case "{59158055-3171-11D2-AA94-00C04FA37849}" 'OLEDB Workspace
            GetCategory = "OLEDB Workspace"

        Case "{30F6F271-852B-4EE8-BD2D-099F51D6B238}" 'Excel Workspace
            GetCategory = "Excel Workspace"

        Case Else
            GetCategory = "Unknown Workspace Category"
    End Select
End Function

To use this with the DoModalOpen method on a GXDialog, I use this code.

Dim pGxDialog As New ESRI.ArcGIS.CatalogUI.GxDialog
Dim pEnumGxObj As ESRI.ArcGIS.Catalog.IEnumGxObject
Dim pGxObj As ESRI.ArcGIS.Catalog.IGxObject
Dim pGxDataset As ESRI.ArcGIS.Catalog.IGxDataset
Dim pDataset As ESRI.ArcGIS.Geodatabase.IDataset
Dim Category As String

If Not pGxDialog.DoModalOpen(My.ArcMap.Application.hWnd, pEnumGxObj) Then Exit Sub
pGxObj = pEnumGxObj.Next
If pGxObj Is Nothing Then Exit Sub
pGxDataset = pGxObj
pDataset = pGxDataset.Dataset

Category = GetCategory(pDataset.Workspace))

That being said, you can also get around specifying the WorkSpaceFactory by using the Geoprocessing Tool "CreateFeatureclass". This is one way to do it.

Friend Function CreateFeatureClass(ByVal FCLocation As String, ByVal FCName As String, ByVal pSR As ESRI.ArcGIS.Geometry.ISpatialReference3, ByVal GeometryType As String, Optional ByVal AddLayer As Boolean = False) As ESRI.ArcGIS.Geodatabase.IFeatureClass

    Dim CreateFClass As New ESRI.ArcGIS.DataManagementTools.CreateFeatureclass
    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Try
        Using releaser As New ESRI.ArcGIS.ADF.ComReleaser
            releaser.ManageLifetime(CreateFClass)

            CreateFClass.out_path = FCLocation
            CreateFClass.out_name = FCName
            CreateFClass.spatial_reference = pSR
            CreateFClass.geometry_type = GeometryType

            Result = RunTool(CreateFClass, Nothing, AddLayer)
            If Result Is Nothing Then Return Nothing

            Return ReturnObjectfromResult(Result, "Feature Class")

        End Using
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString & vbNewLine & ex.StackTrace.ToString, "Create Feature Class")
        Return Nothing
    End Try

End Function

Friend Function RunTool(ByVal Process As ESRI.ArcGIS.Geoprocessor.IGPProcess, ByVal TC As ESRI.ArcGIS.esriSystem.ITrackCancel2, Optional ByVal AddOutput As Boolean = False) As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Dim Result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2

    Try
        System.Windows.Forms.Cursor.Current = Windows.Forms.Cursors.WaitCursor
        Dim GP As New ESRI.ArcGIS.Geoprocessor.Geoprocessor

        GP.AddOutputsToMap = AddOutput

        Result = CType(GP.Execute(Process, Nothing), ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2)
        If Result.Status <> ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded Then ReturnMessages(Result, "Geoprocessing Error")
        GP.ClearMessages()
    Catch ex As Exception
        ReturnMessages(Result, "Fail")
        System.Windows.Forms.MessageBox.Show(ex.ToString, "Run Geoprocessor")
    End Try

    Return Result
End Function

Private Sub ReturnMessages(ByVal pResult As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2, ByVal Title As String)

    If pResult Is Nothing Then Exit Sub

    Dim ErrorMessage As String

    If pResult.MessageCount > 0 Then
        For Count As Integer = 0 To pResult.MessageCount - 1
            ErrorMessage += pResult.GetMessage(Count)
        Next
    End If

    System.Windows.Forms.MessageBox.Show(ErrorMessage, Title)

End Sub

Friend Function ReturnObjectfromResult(ByVal result As ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult2, ByVal Type As String) As Object

    Dim GPVal As ESRI.ArcGIS.Geodatabase.IGPValue
    Dim InMemFC As String
    Dim GPUtil As ESRI.ArcGIS.Geoprocessing.IGPUtilities3 = New ESRI.ArcGIS.Geoprocessing.GPUtilities

    Try
        GPVal = result.GetOutput(0)
        InMemFC = GPVal.GetAsText()

        Select Case Type
            Case "Feature Class"
                Return GPUtil.OpenFeatureClassFromString(InMemFC)
            Case "Table"
                Return GPUtil.OpenTableFromString(InMemFC)
            Case "Feature Layer"
                Return GPUtil.OpenFeatureLayerFromString(InMemFC)
            Case Else
                Return Nothing
        End Select

    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.ToString, "ReturnObjectfromResult error")
        Return Nothing
    End Try
End Function
  • What a hint! I was dealing with this problem for a few days and couldn't find out why there was a problem creating output feature class on some machines. Now I know - language settings, as I was using FinalLocation strings! But why ESRI has localized this..?! Thanks for the enlightening hint and the code. I will give it a try and get back. – jan_b Mar 21 '14 at 19:45
0

Thanks for both answers. Ken's hint on language issues regarding WorkspaceCategory was great, though the GetCategory function did not fit my particular need, as my goal was to use full path name (not the IWorskpace) to recognize the appropriate WorkspaceFactory, i.e.:

  • "C:\Project\fclass" -> shapefile in a folder ->
  • "C:\Project.gdb\fclass" -> feature class in a file geodatabase
  • "C:\Project.gdb\fd\fclass" -> feature class in a feature dataset within a file geodatabase

I ended up using GPUtilities. Still, I'm not sure why the file folder is not recognized as IWorkspaceName, i.e.:

pName = pGPUtilities.GetNameObjectFromLocation("C:\Project")
If TypeOf pName Is IWorkspaceName Then 'returns False for "C:\Project"
...
End If

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.