This is not possible in pure arcpy.
It can be done in python, but requires the use of arcobjects. One way to access arcobjects in python is to use the comtypes
package.
Firstly install comtypes
and get set up with the arcobjects snippets module. See this question for links to the snippets module and for more information on accessing arcobjects from python.
Below is some code, derived from the ArcGIS documentation and the ArcMap CSW Client to generate a layer file of the WMS. You need to write the layer file to disk to be able to use ArcPy to add it to an MXD, but you can delete the file once it's been added to the map.
import sys
import arcview,arcpy
from comtypes import COMError
from snippets import GetModule, CType, NewObj
def ConnectWMS(url):
GetModule("esriSystem.olb")
GetModule("esriCarto.olb")
GetModule("esriGISClient.olb")
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriGISClient as esriGISClient
##Create an WMSMapLayer Instance - this will be added to the map later
pWMSGroupLayer = NewObj(esriCarto.WMSMapLayer, esriCarto.IWMSGroupLayer)
##Create and configure wms connection name, this is used to store the connection properties
pPropSet = NewObj(esriSystem.PropertySet, esriSystem.IPropertySet)
pPropSet.SetProperty("URL", url)
pConnName = NewObj(esriGISClient.WMSConnectionName, esriGISClient.IWMSConnectionName)
pConnName.ConnectionProperties = pPropSet
##Use the name information to connect to the service
pDataLayer = CType(pWMSGroupLayer, esriCarto.IDataLayer)
pName = CType(pConnName, esriSystem.IName)
pDataLayer.Connect(pName)
##Get service description, which includes the categories of wms layers
pServiceDesc = pWMSGroupLayer.WMSServiceDescription
return pWMSGroupLayer,pServiceDesc
def CreateWMSGroupLayer(url, outpath, visible, *layernames):
GetModule("esriCarto.olb")
import comtypes.gen.esriCarto as esriCarto
# Connect to WMS
pWMSGroupLayer,pServiceDesc = ConnectWMS(url)
#Find matching layers
if layernames:
pLayerDescs=[find_layer(pServiceDesc,l) for l in layernames]
##Configure the layer before adding it to the map
pWMSGroupLayer.Clear()
for i,pLayerDesc in enumerate(pLayerDescs):
if pLayerDesc is None:
# raise Exception('Unable to find layer "%s"'%layernames[i])
# warnings.warn('Unable to find layer "%s"'%layernames[i])
sys.stderr.write('Warning: Unable to find layer "%s"\n'%layernames[i])
continue
pWMSMapLayer = pWMSGroupLayer.CreateWMSLayer(pLayerDesc)
CType(pWMSMapLayer, esriCarto.ILayer).Visible=visible
pWMSGroupLayer.InsertLayer(pWMSMapLayer, i)
pLayer = CType(pWMSGroupLayer, esriCarto.ILayer)
pLayer.Visible=visible
##create a new LayerFile and populate it with the layer
pLayerFile = NewObj(esriCarto.LayerFile, esriCarto.ILayerFile)
pLayerFile.New(outpath)
pLayerFile.ReplaceContents(pLayer)
pLayerFile.Save()
return outpath
def find_layer(servicedesc, layername):
'''Recursive layer matching.
Recursion is necessary to handle non data (folder/subfolder) "layers"'''
layer = None
for i in range(servicedesc.LayerDescriptionCount):
layerdesc = servicedesc.LayerDescription(i)
if layerdesc.LayerDescriptionCount == 0:
if layerdesc.Name == layername: return layerdesc
else: continue
layer = find_layer(layerdesc, layername)
if layer:break
return layer
if __name__ == '__main__':
url = 'http://someserver/ogc/wms?'
path1 = r'C:\Temp\test1.lyr'
path2 = r'C:\Temp\test2.lyr'
path3 = r'C:\Temp\test3.lyr'
try:
#All layers
lyr = CreateWMSGroupLayer(url, path1, visible=False)
#A couple of layers
lyr = CreateWMSGroupLayer(url, path2, False, 'lyr0', 'lyr1')
#A single layer
lyr = CreateWMSGroupLayer(url, path3, False, 'lyr2')
except COMError as e:
print('Unable to add WMS')