Layer Property - Data Type

865
5
05-05-2020 02:31 PM
ChrisHolmes
Occasional Contributor III

Hi everyone,

Could someone share with me code that I could use to get the Data Type for a layer. In this example below, I would want returned "CAD Polyline Feature Class".

Thanks!

Tags (2)
0 Kudos
5 Replies
DanPatterson_Retired
MVP Esteemed Contributor

from arcpy you can use Describe to find out what object types you have

Describe—Data Access module | Documentation 

then burrow in further

CAD FeatureClass properties—ArcPy Functions | Documentation 

only to discover that CAD featureclasses return FeatureClass as the DataType

but

Dataset properties—ArcPy Functions | Documentation 

allows you to determine whether a dataset type

ChrisHolmes
Occasional Contributor III

Thanks Dan. I’m going through the links you sent to see if there’s a way I can workaround with the describe object to get at what I’m looking for as it seems I can’t directly get at what I want using arcpy (according to Joshua).

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

maybe skip Arc* altogether and just use windows file explorer  

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The short answer is that you can't get that specific value from within ArcPy.

The Data Type value of the Data Source tab comes from IFeatureLayer.DataSourceType, i.e., it is a layer value/description and not a dataset value/description.  Unfortunately, ArcPy does not expose that layer property through the Describe object.

If you are willing to install a Python com package, like GitHub - enthought/comtypes: A pure Python, lightweight COM client and server framework, based on th... , then you can use ArcObjects to access the value.

The code below, when pasted in the interactive Python window, will enumerate all the feature layers in the MXD and print their names and layer-based DataSourceType.

import arcpy
import os
from comtypes.client import CreateObject, GetModule

mxd = "" # path to MXD file (if run outside ArcMap)

# Function for casting COM objects to interfaces
def CType(obj, interface):
    """Casts obj to interface and returns comtypes POINTER or None"""
    try:
        newobj = obj.QueryInterface(interface)
        return newobj
    except:
        return None

# Path to ArcGIS Desktop COM files
comDirectory = os.path.join(  
    os.path.join(arcpy.GetInstallInfo()['InstallDir']), 'com'  
)

# References to needed ArcGIS Desktop COM components
esriSystem = GetModule(os.path.join(comDirectory, 'esriSystem.olb'))
esriFramework = GetModule(os.path.join(comDirectory, 'esriFramework.olb'))
esriArcMapUI = GetModule(os.path.join(comDirectory, 'esriArcMapUI.olb'))
esriCarto = GetModule(os.path.join(comDirectory, 'esriCarto.olb'))

# Create filter for layers that support IGeoFeatureLayer
pUID = CreateObject(esriSystem.UID)
pUID.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"

# Section for running within ArcGIS Desktop application
# Confirm code is being run within ArcMap (Interactive, Addin, Toolbox)
try:
    pApp = CreateObject(esriFramework.AppRef)
    assert pApp.Name == 'ArcMap', 'Code must be run within ArcMap'
    pMxDoc = CType(pApp.Document, esriArcMapUI.IMxDocument)
except WindowsError:
    assert False, 'Code must be run within an ArcGIS Desktop application'
    

## Section for running outside of ArcGIS Desktop application
## Open MXD file
#try:
#    pMapDoc = CreateObject(esriCarto.MapDocument, interface=esriCarto.IMapDocument)
#    assert pMapDoc.IsMapDocument(mxd), 'Valid MXD required'
#    pMapDoc.Open(mxd)
#    pMap = pMapDoc.Map(0)
#except:
#    assert False, 'Unable to open MXD and retrieve map'


# Loop over layers that support IGeoFeatureLayer (first line from in ArcMap, second line outside of ArcMap)
pEnumLayer = pMxDoc.FocusMap.Layers(pUID, True)
# pEnumLayer = pMap.Layers(pUID, True)

results = ["LayerName, DataSourceType"]
pEnumLayer.Reset()
pLayer = pEnumLayer.Next()
while pLayer:
    pFeatureLayer = CType(pLayer, esriCarto.IFeatureLayer2)
        
    # Append results and move to next layer
    results.append("{}, {}".format(pLayer.Name, pFeatureLayer.DataSourceType))
    pLayer = pEnumLayer.Next()

for res in results:
    print(res)
ChrisHolmes
Occasional Contributor III

Thanks Joshua. I think that opens a whole new can of worms I don’t really want to get into ideally.

0 Kudos