如何使用 Python 将 Extent、Scale 和 RefreshView 从 ArcMap 转换为 ArcPro

问题描述 投票:0回答:3

我使用 Python (2.7) ArcMap 脚本多年,现在我尝试将其转换为与 ArcPro (Python 3) 一起使用。我已将 ArcMap 脚本的一半转换为 ArcPro(使用 Visual Studio),但在修改其定义查询后仍坚持修改代码以缩放到图层范围。

地图名称为“邮件列表地图”。

我想用来导出 pdf 地图的布局称为:“Irrigation_Services_Maps”

我要更改地图标题的表名称是一个名为 irrStats 的变量。它有两列,客户名称和频率(客户名称的数量 - 每条记录代表一个灌溉点。单个客户可以有多个灌溉点)

我想创建一个以客户名称为标题以及与该客户关联的所有灌溉点的地图,并将其导出为 pdf 格式。

有人可以指导我重写这个吗?我花了一整天的时间来审查这个问题,但没有找到明显的解决方案。你可能会认为这比这更容易。

代码问题从 ##### 开始的行开始。我不知道如何添加行号。

谢谢

import arcpy, os
from datetime import datetime
startTime = datetime.now()

print ((datetime.now() - startTime))

irrFile = arcpy.GetParameterAsText(0)  # Gets the irrigation file with the data in it
pdfFolder = arcpy.GetParameterAsText(1)  # Asks for folder location to put the pdf output files
arcpy.AddMessage(pdfFolder)
pdflist = [f for f in os.listdir(pdfFolder) if f.endswith(".pdf")]
for f in pdflist:
    os.remove(os.path.join(pdfFolder, f))
arcpy.env.overwriteOutput = True  # Allows us to run the script repeatedly without deleting the intermediate files
aprx = arcpy.mp.ArcGISProject("CURRENT")
aprxMap = aprx.listMaps("Mailing List Map")[0]
lyt=aprx.listLayouts("Irrigation_Services_Maps")[0]
scratchDir = pdfFolder + "\\scratch"  # Temporary folder to store temp data
arcpy.AddMessage(scratchDir)

if not os.path.exists(scratchDir):
   os.makedirs(scratchDir)
arcpy.env.workspace = scratchDir

arcpy.env.overwriteOutput = True
tempFGDB = arcpy.CreateFileGDB_management(scratchDir, "scratchGDB").getOutput(0)

arcpy.AddMessage(tempFGDB)
arcpy.env.workspace = tempFGDB
irrStats = "irr_stats"
if arcpy.Exists(irrStats):
   arcpy.Delete_management(irrStats)

arcpy.Frequency_analysis(irrFile, irrStats, "cus_name")
with arcpy.da.SearchCursor(irrStats, ("FREQUENCY", "cus_name")) as rows: # Goes through the irrStats table
   for row in rows:
      cusName = row[1]
      cusFreq = row[0]
      if len(cusName) > 1:
         arcpy.AddMessage(cusName)
         lyr = aprxMap.listLayers(irrFile)[0]
         lyr.definitionQuery = ""       
         lyr.definitionQuery = "\"cus_name\" = " + "'" + cusName + "'"
         for xyz in aprx.listLayouts():   
             for elm in xyz.listElements("TEXT_ELEMENT"):
                if elm.name == "customer":
                    elm.text = (cusName) # and changes the title (text element "Customer") to selected name in table 
                    
###### Don't know how to code Extent, Scale and Refresh View for ArcPro
###### Old ArcMap code needing rewrite below this point

        pdfMap = pdfFolder + "\\" + cusName + ".pdf"
         if cusFreq == 1:  # if there is only one customer record
            arcpy.AddMessage("Name : " + cusName)
            ext = lyr.getExtent()
            df.extent = ext
            arcpy.RefreshActiveView()  # redraw the map
            df.scale = 1000   # set the scale to 1000
            arcpy.RefreshActiveView()  # redraw the map
            arcpy.mapping.ExportToPDF(mxd, pdfMap)
         elif cusFreq > 1:  # if there is more than 1 record
            arcpy.AddMessage("Name2 : " + cusName)
            ext = lyr.getExtent() # Find out the extent
            df.extent = ext # zoom to it
            arcpy.RefreshActiveView()  # redraw the map

            if df.scale < 1000: #set the scale to 1000 is extent is < 1000
               df.scale = 1000
            else:
               df.scale = df.scale * 1.2  # otherwise make the scale 1.2 times the layers extent

            arcpy.RefreshActiveView()  # refresh the map
            arcpy.mapping.ExportToPDF(mxd, pdfMap) # export the map 
            arcpy.AddMessage("more than one")
         else:
            arcpy.AddMessage("Name3 : " + cusName)
         lyr.definitionQuery = ""    
python arcgis arcpy
3个回答
0
投票

有几件事你必须注意。

  1. 刷新ActiveView

对于 ArcGIS Pro 和“CURRENT”工程,对 arcpy.mp-API 的所有更改都会导致 ArcGIS Pro 中的直接更新,因此无需调用

refreshActiveView
函数。

  1. 图层范围

可以使用 arcpy.Describe 检索数据元素的属性(例如图层):

    desc = arcpy.Describe(lyr)
    etxent = desc.extent
  1. 地图框架/地图视图

在 ArcGIS Pro 中,您不再使用 DataFrame,而是使用类

MapFrame
(页面布局元素)和
MapView
(活动地图)。 在这两个类上,您都有一个属性
camera
,它使您可以访问比例尺:

    map_view = aprxMap.activeView
    camera = map_view.camera
    
    #get current extent:
    current_extent = camera.getExtent()
    
    #set extent
    camera.setExtent(extent)
  1. 规模

比例尺也是相机类的一个属性(读和写):

    camera = map_view.camera
    
    #read
    scl = camera.scale
    
    #write
    camera.scale *= 1.5

也许您可以使用此缩小转换为 ArcGIS Pro 时出现的问题范围。


0
投票

我发布了我的最终代码,因为我在网上找不到很多这样的例子。我希望它能有所帮助,因为我发现在线文档很难理解。

import arcpy, os
from datetime import datetime
startTime = datetime.now()

print ((datetime.now() - startTime))

irrFile = arcpy.GetParameterAsText(0)  # Gets the irrigation file with the data in it
pdfFolder = arcpy.GetParameterAsText(1)  # Asks for folder location to put the pdf output files
arcpy.AddMessage(irrFile)
pdflist = [f for f in os.listdir(pdfFolder) if f.endswith(".pdf")]
for f in pdflist:
    os.remove(os.path.join(pdfFolder, f))
arcpy.env.overwriteOutput = True  # Allows us to run the script repeatedly without deleting the intermediate files
aprx = arcpy.mp.ArcGISProject("CURRENT")
aprxMap = aprx.listMaps("Mailing List Map")[0]
scratchDir = pdfFolder + "\\scratch"  # Temporary folder to store temp data
arcpy.AddMessage(scratchDir)

if not os.path.exists(scratchDir):
   os.makedirs(scratchDir)
arcpy.env.workspace = scratchDir

arcpy.env.overwriteOutput = True
tempFGDB = arcpy.CreateFileGDB_management(scratchDir, "scratchGDB").getOutput(0)

arcpy.AddMessage(tempFGDB)
arcpy.env.workspace = tempFGDB
irrStats = "irr_stats"
if arcpy.Exists(irrStats):
   arcpy.Delete_management(irrStats)

arcpy.Frequency_analysis(irrFile, irrStats, "cust_name")
lyt=aprx.listLayouts("Irrigation_Services_Maps")[0]

with arcpy.da.SearchCursor(irrStats, ("FREQUENCY", "cust_name")) as rows:
   for row in rows:
      cusName = row[1]
      cusFreq = row[0]
      if len(cusName) > 1:
         arcpy.AddMessage(cusName)
         lyr = aprxMap.listLayers(irrFile)[0]
         lyr.definitionQuery = ""       
         lyr.definitionQuery = "\"cust_name\" = " + "'" + cusName + "'"
         if cusName == 'DEPT OF TRANSPORTATION':
             cusName = "DOT"
             arcpy.AddMessage(cusName)
         for xyz in aprx.listLayouts():   
             for elm in xyz.listElements("TEXT_ELEMENT"):
                if elm.name == "customer":
                    elm.text = (cusName)

         pdfMap = pdfFolder + "\\" + cusName + ".pdf"
         mf = lyt.listElements('mapframe_element')[0]

         if cusFreq == 1:  # if there is only one customer record
            arcpy.AddMessage("Name : " + cusName)
            mf.camera.setExtent(mf.getLayerExtent(lyr, False, True))
            mf.camera.scale = 1000
            lyt.exportToPDF(pdfMap)
         elif cusFreq > 1:  # if there is more than 1 record
            arcpy.AddMessage("Name2 : " + cusName)
            mf.camera.setExtent(mf.getLayerExtent(lyr, False, True))
            if mf.camera.scale < 1000: #set the scale to 1000 is extent is < 1000
               mf.camera.scale = 1000
            else:
               mf.camera.scale = mf.camera.scale * 1.2  # otherwise make the scale 1.2 times the layers extent

            lyt.exportToPDF(pdfMap) # export the map 
            arcpy.AddMessage("more than one")
         else:
            arcpy.AddMessage("Name3 : " + cusName)
         lyr.definitionQuery = ""

0
投票
mf.panToExtent(mf.getLayerExtent(lyr, False, True))

将避免每次重新检查并将比例设置为 1000。因为看起来它停留在那里,您可以按该比例设置地图框而不改变。

© www.soinside.com 2019 - 2024. All rights reserved.