In Pro 2.0 it does not appear it is possible to create a new map within the project. Please consider adding a method to the ArcGISProject object with the ability to create a new map with a name from arcpy.
Alternatively a copy map method on the existing Map object would be a workable alternative
You can copy/paste maps manually in a project so this functionality seems like a necessary addition for additional project automation.
This would be a welcome feature. In my case, I'd like to be able to pass a list of map names to a method that would generate new maps with the names from that list. For example using a hypothetical newMap() method.
aprx = arcpy.mp.ArcGISProject("CURRENT")
map_list = ['map1', 'map2', 'map3']
for m in map_list:
aprx.newMap(m)
for m in aprx.listMaps():
print("Map: " + m.name)
# Result
# Map: map1
# Map: map2
# Map: map3
In this example, 3 new maps (map1, map2, and map3) would be added to the current project.
This is the kind of process that would be nice to be able to automate:
It would be very useful to have the command. I wonder if there is a way to do it without waiting for the future versions.
I'm making a check to create a new map if the user is running an aprx without a map in it. Creating a new map when the script detects this would be very helpful.
it's not much to look it but:
#!/usr/bin/env python3
"""
make aprx file, 'add' some maps to it:
#comtypes:
#one of the following installed libraries are required:
#C:\Program Files (x86)\ArcGIS\Desktop10.7\com
#or
#C:\Program Files\ArcGIS\Server\com
"""
import arcpy
import tempfile
import os
import shutil
from shutil import make_archive
out_dir = os.environ["USERPROFILE"] + os.sep + "Desktop"
aprx_name_maps_in_pro = "aprx_with_maps"
## new empty map names:
map_list = ["map1", "map2", "map3"]
#from an empty project (may be able to minimize these items even futher
# but this does what i need.
cimdoc = """<CIMDocumentInfo xsi:type='typens:CIMDocumentInfo' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/2.4.0'>
<Version>2.4.0</Version><Build>19948</Build><DocumentTitle>New</DocumentTitle><SavePreview>false</SavePreview>
<UseRelativePath>true</UseRelativePath><Antialiasing>esriBGLAntialiasingNone</Antialiasing>
<TextAntialiasing>esriBGLTextAAliasForce</TextAntialiasing></CIMDocumentInfo>"""
#from an empty project
gisproj = """<CIMGISProject xsi:type="typens:CIMGISProject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://www.esri.com/schemas/ArcGIS/2.4.0"></CIMGISProject>"""
#from an empty project rb in python 3.
EMPTY_PROJECT_BYTES = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
def installComTypes():
"""
install comtypes in virtaul env at runtime, why not.
"""
install_com_types_string = """import subprocess
import sys
def install(package):
subprocess.call([sys.executable, "-m", "pip", "install", package])
install('comtypes')
"""
insall_scrpit_name = "install_comtypes"
install_file = insall_scrpit_name + ".py"
if os.path.exists(install_file):
os.remove(install_file)
with open(install_file, "w") as w_install:
w_install.write(install_com_types_string)
import install_comtypes
#or not
#hack number 1
installComTypes()
import comtypes
def CreateMXD(path):
GetModule('esriCarto.olb')
import comtypes.gen.esriCarto as esriCarto
#print("dir esriCarto:")
#print(dir(esriCarto))
pMapDocument = CreateObject(esriCarto.MapDocument, esriCarto.IMapDocument)
pMapDocument.New(path)
#print("dir pMapDocument:")
#print(dir(pMapDocument))
#print("dir pMapDocument.map:")
#print(dir(pMapDocument.Map))
pMapDocument.Save() #probably not required...
def GetLibPath():
""" Get the ArcObjects library path
It would be nice to just load the module directly instead of needing the path,
they are registered after all... But I just don't know enough about COM to do this
"""
thisCompath=os.path.join(arcpy.GetInstallInfo()['InstallDir'],'com')
desktopCompath = r"C:\Program Files (x86)\ArcGIS\Desktop10.7\com"
serverCompath = r"C:\Program Files\ArcGIS\Server\com"
if os.path.exists(thisCompath):
return thisCompath
elif os.path.exists(desktopCompath):
return desktopCompath
elif os.path.exists(serverCompath):
return serverCompath
else:
raise Exception("#must use desktop or server com libriary (or copy the com folder to a known location")
def GetModule(sModuleName):
""" Generate (if not already done) wrappers for COM modules
"""
from comtypes.client import GetModule
sLibPath = GetLibPath()
GetModule(os.path.join(sLibPath,sModuleName))
def CreateObject(COMClass, COMInterface):
""" Creates a new comtypes POINTER object where
COMClass is the class to be instantiated,
COMInterface is the interface to be assigned
"""
ptr = comtypes.client.CreateObject(COMClass, interface=COMInterface)
return ptr
def create_binary_file(_bytes, file_path):
"""
Create an 'empty' project file
"""
with open(file_path, 'wb') as fh:
fh.write(_bytes)
def create_xml_file(xml_string, file_path):
"""
create an xml file with string of input
"""
with open(file_path, "w") as xml:
xml.write(xml_string)
#temporary workspace (emptied at end)
tempDir = tempfile.mkdtemp()
#write xml to documentinfo.xml
create_xml_file(cimdoc, os.path.join(tempDir, "DocumentInfo.xml"))
#write xml to gisproject.xml
create_xml_file(gisproj, os.path.join(tempDir, "GISProject.xml"))
#hack number 2 write binary data to 007Index.ind
create_binary_file(EMPTY_PROJECT_BYTES, os.path.join(tempDir, "007Index.ind"))
#template pro map name
empty_pro_map = "aprx_empty"
#list of required files for creating aprx file
files = ["007Index.ind","GISProject.xml", "DocumentInfo.xml"]
#zip the files one at a time
for f in files:
shutil.make_archive(os.path.join(out_dir, empty_pro_map), "zip", tempDir)
#empty ArcGISProject
new_aprx_path = os.path.join(out_dir, empty_pro_map) + ".aprx"
#rename the .zip file to .aprx
os.rename(os.path.join(out_dir, empty_pro_map + ".zip"), new_aprx_path)
# everything below here requires python 3 arcpy
# you could split this code here.
# load aprx
aprx = arcpy.mp.ArcGISProject(new_aprx_path)
for m in map_list:
map_path = os.path.join(tempDir, m + ".mxd")
if os.path.exists(map_path):os.unlink(map_path)
#hack number 3
CreateMXD(map_path)
existing_maps = aprx.listMaps()
aprx.importDocument(map_path)
existing_maps_now = aprx.listMaps()
for ma in existing_maps_now:
if ma not in existing_maps:
ma.name = m
#output
aprx.saveACopy(os.path.join(out_dir, aprx_name_maps_in_pro + ".aprx"))
#clear temp files (comment the next line out if you want to review the temp files)
shutil.rmtree(tempDir)
print(tempDir)
save as:
<%path%>\add_maps_to_new_aprx.py
run it like:
C:\Program Files\ArcGIS\Pro\bin\Python\Scripts>propy.bat <%path%>add_maps_to_new_aprx.py
the associated toolboxes and geodatabases are created on initial launch, but you could set those if you want.
I think as Ryan demonstrates we would like access to the functionality of the catalog window, much of which is willy-nilly missing. Max gets points for causing my eyes to bleed staring at the CIM guts, but if that's the answer then Pro is not the right question.
Paul
haha. yeah, that is kind of overkill. alternatively you can have an empty template mxd file that you use and an empty aprx file and just:
templateMxd = "C:/admin/temp_mxd.mxd"
aprx = arcpy.mp.ArcGISProject("C:/admin/temp_aprx.aprx")
map_list = ["map1", "map2", "map3"]
for m in map_list:
existing_maps = aprx.listMaps()
aprx.importDocument(templateMxd)
existing_maps_now = aprx.listMaps()
# not going to assume these maps are being added at any one index position
for ma in existing_maps_now:
if ma not in existing_maps:
# set the name of the imported map
ma.name = m
# done adding new maps to aprx, save it
aprx.saveACopy("C:\admin\aprx_with_new_maps.aprx")
Is this seriously not available still???
Is there any functionality on how to create a whole new ArcGIS project within the arcpy.mp library of functions. It would be really nice if you didn't have to set up a project manually. Is there a function out there where you can create a project from scratch? Similar to arcpy.management.CreateFileGDB but for ArcGIS projects.
This would be a really helpful feature.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.