arcgis使用Python脚本进行批量截图功能实现
作者:孙霸天
最近公司数据部那边有个需求,需要结合矢量数据和影像数据,进行批量截图,并且截图中只能有一个图斑,还要添加上相应的水印,这篇文章主要介绍了arcgis使用Python脚本进行批量截图,需要的朋友可以参考下
arcgis使用Python脚本进行批量截图
介绍
最近公司数据部那边有个需求,需要结合矢量数据和影像数据,进行批量截图,并且截图中只能有一个图斑,还要添加上相应的水印。
思路
一开始我是准备使用QGIS直接进行批量出图,但我发现使用布局管理器进行批量出图会有问题,截图时没办法将周边的其他图斑隐藏掉。然后考虑使用python调用QGIS的方法来进行操作,结果我是没找到什么示例或方法,如果其他人有方法可以分享一下。
最终还是准备使用arcpy进行批量截图,arcpy的例子就比较多了,这里我就展示一下我的方法和思路。个人认为比较low,勿喷!
- 使用mxd先设置好矢量图层和影像图层
- python加载矢量图层,并读取出所有的矢量数据唯一字段值
- 结合唯一字段值进行循环遍历,在mxd中的矢量图层中进行条件匹配,匹配到后定位到对应图斑上并设置层级缩放
- 设置了选中状态,选中的会蓝色(选中状态这个颜色和样式我不知道在哪改,如果有人知道请告知一下)
- 然后进行截图
准备
- 系统:win11
- ArcMap:10.2
- Python:2.7(arcmap自带的)
实现
mxd文件准备
提前准备好矢量图层和遥感影像数据,设置好需要样式
python代码
# -*- coding:utf-8 -*- """ 实现arcpy按照图斑自动截图,要使用python2.7,需要提前设置好mxd工程,并进行保存,如果进行前后时相截图,需要设置好label与所需季度影像 """ import arcpy #import os #截图地图文件路径 input = "D:\\data\\tb_1.shp" mxd_path = u"D:\\data\\tb_1.mxd" mxd = arcpy.mapping.MapDocument(mxd_path)#通过MapDocument函数来引用地图文档 df = arcpy.mapping.ListDataFrames(mxd)[0]#返回名为Layers的数据框对象 for lyr in arcpy.mapping.ListLayers(mxd): #遍历地图文档的图层 if lyr.name.startswith("tb_"):#指定图层文件,搜索为tb开头的文件夹,startwith函数用于检查字符串是否已指定字符串为开头,正确返回Trur,错误返回False。 layermain = lyr#主要图层指定为layermain #输出lyr.name10(输出指定图层的名称(需要截图图层)) print "Layer name: " + layermain.name #循环 fields = ['TBBH']#根据field这个字段进行截图,field必须为唯一字段 values1 = [row[0] for row in arcpy.da.SearchCursor(input, fields)]#使用游标访问其中的字段,返回已fields字段的列表 #print values1 #清空选择 #arcpy.SelectLayerByAttribute_management(layermain, "CLEAR_SELECTION")#按属性选择图层工具,选择要素与行,并移除所有选择内容 #arcpy.RefreshActiveView()#刷新当前的地图文档的活动视图和内容列表 delimfield = arcpy.AddFieldDelimiters(input, 'TBBH')#生成相应的sql语句 #print delimfield #循环 for val in values1:#遍历字段列表 try: # 状态是0的图斑 whereClause0 = delimfield+" = '"+str(val)+"'"#whereClause为"TBBH=val"字符串 print(whereClause0) arcpy.SelectLayerByAttribute_management(layermain, "NEW_SELECTION", whereClause0)#按属性选择图层,创建一个新的选择内容,默认选择方式为后边字符串 df.zoomToSelectedFeatures()#缩放至图层,按照当前图斑缩放 df.scale = df.scale*2.5#图版按位置缩放距离图片边界3倍位置,根据图斑大小进行调节 save_path = "D:\\data\\pic\\"+str(val)+".jpg"#保存图片为JPEG格式路径 arcpy.mapping.ExportToJPEG(mxd,save_path)#按照val为文件名称进行保存,保存格式为JPEG格式 # arcpy.mapping.ExportToJPEG(mxd,save_path,resolution = 200)#按照val为文件名称进行保存,保存格式为PNG格式 arcpy.SelectLayerByAttribute_management(layermain, "CLEAR_SELECTION")#按照属性选择图层,并移除所有选择内容 arcpy.RefreshActiveView()#刷新当前活动视图和内容列表 except: print 'wrong' del mxd print "Beautiful!"
截图效果如下:
图片添加需要的水印
图片上需要添加上一些水印,这里我使用Java代码进行操作也比较方便:
@Test void pic() { String srcDirStr = "D:\\data\\output"; String destDirStr = "D:\\data\\res"; File srcDir = new File(srcDirStr); String[] srcList = srcDir.list(); String year = "2020年影像"; for (String srcFileStr : srcList) { File srcFile = new File(srcFileStr); String fileName = getFileNameNoEx(srcFile.getName()); List<String> markList = new ArrayList<String>(); markList.add(fileName); markList.add(year); String srcFilePath = srcDirStr + File.separator + srcFile.getName(); String destFilePath = destDirStr + File.separator + srcFile.getName(); pressText(markList, srcFilePath, destFilePath, "黑体", Font.TYPE1_FONT, new Color(0, 255, 255), 0.9f); } } /** * 获取不带扩展名的文件名 * * @param filename 文件名 * @return 不带扩展名的文件名 */ public String getFileNameNoEx(String filename) { if ((filename != null) && (filename.length() > 0)) { int dot = filename.lastIndexOf('.'); if ((dot > -1) && (dot < (filename.length()))) { return filename.substring(0, dot); } } return filename; } /** * 给图片添加文字水印 * * @param pressTextList 水印文字(一个集合一个值对应一条水印) * @param srcImageFile 源图像地址 * @param destImageFile 目标图像地址 * @param fontName 水印的字体名称 * @param fontStyle 水印的字体样式 * @param color 水印的字体颜色 * @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 */ public void pressText(List<String> pressTextList, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int width = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); // 计算水印字体大小 首先找出最长的水印文字 //如果需要加水印的文字没有超过18个就按18个计算 int maxLength = 18; for (String pressText : pressTextList) { if (getLength(pressText) > maxLength) { maxLength = getLength(pressText); } } //根据图片宽度计算水字体大小 int fontSize = (int) (((width) / (maxLength)) * 0.8); g.drawImage(src, 0, 0, width, height, null); g.setColor(color); g.setFont(new Font(fontName, fontStyle, fontSize)); // g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, // alpha)); // 循环在指定坐标绘制水印文字 int count = pressTextList.size(); for (int i = 0; i < pressTextList.size(); i++) { if (i == 0) { g.drawString(pressTextList.get(0), (int) ((width * 0.43) - (2 * fontSize)), (int) ((height * 0.05) + fontSize * count)); // g.drawString(pressTextList.get(0), (int) ((width * 0.35) - (2 * fontSize)), (int) ((height * 0.05) + fontSize * count)); } if (i == 1) { g.drawString(pressTextList.get(1), (int) ((width * 0.48) - (2 * fontSize)), (int) ((height * 0.90) - fontSize * count)); } count--; } g.dispose(); ImageIO.write(image, "JPEG", new File(destImageFile));// 输出到文件流 } catch (Exception e) { e.printStackTrace(); } } /** * 计算text的长度(一个中文算两个字符) * * @param text 文本 * @return int */ public int getLength(String text) { int length = 0; for (int i = 0; i < text.length(); i++) { if (new String(text.charAt(i) + "").getBytes().length > 1) { length += 2; } else { length += 1; } } return length / 2; }
水印效果如下:
到此这篇关于arcgis使用Python脚本进行批量截图功能实现的文章就介绍到这了,更多相关Python批量截图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!