arcgis实现截图/截屏功能

news2024/9/28 19:21:42

arcgis实现截图/截屏功能

文章目录

  • arcgis实现截图/截屏功能
  • 前言
  • 效果展示
  • 相关代码


前言

本篇将使用arcgis实现截图/截屏功能,类似于qq截图


效果展示

在这里插入图片描述


相关代码

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
	<title>4.5 地图截图</title>
	<style>
		html,
		body,
		#viewDiv {
			padding: 0;
			margin: 0;
			height: 100%;
			width: 100%;
		}
	</style>

	<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
	<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.2.min.js"></script>
	<script src="https://js.arcgis.com/4.5/"></script>

	<script>
    require([
		"esri/Map",
		"esri/views/MapView",
        "esri/geometry/Extent",
        "esri/geometry/Point",
        "esri/widgets/Print",
        "esri/Graphic",
        "dojo/on",
        "dojo/dom",
        "esri/layers/GraphicsLayer",
        "esri/tasks/PrintTask",
        "esri/tasks/support/PrintTemplate",
        "esri/tasks/support/PrintParameters",
        "esri/views/2d/draw/Draw",
        "esri/geometry/Polygon",
        "esri/geometry/Point",
		"dojo/domReady!"
    ], function(Map, MapView, Extent, Point, Print, Graphic, on, dom, GraphicsLayer, PrintTask, 
		PrintTemplate, PrintParameters, Draw, Polygon, Point) {

		let map = new Map({
			basemap: "streets"
		});
      
		let tempGraphicsLayer = new GraphicsLayer();
		map.add(tempGraphicsLayer);

		let view = new MapView({
			container: "viewDiv",
			map: map,
			zoom: 4,
			center: [15, 65] // longitude, latitude
		});
      
		view.ui.add("screenshot", "top-right");

		view.then(function () {
			let printTask = new PrintTask("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task");  
          
			let printTemplate = new PrintTemplate({
				format: "jpg",
				exportOptions: {
				   dpi: 96,
				   width: 700,
				   height: 1100
				},  
				layout: "MAP_ONLY",
				layoutOptions: {
					"titleText": "",
					"authorText": "",
					"copyrightText": "",
					"scalebarUnit": "",
				},
				showLabels: false,
				preserveScale: false,
				attributionVisible: false //是否显示地图属性
			});
                
			let draw = new Draw({
				view: view
			});
			
			let drawAction = null;
			//允许绘制矩形
			function enableCreateRectangle(draw, view) {
				isStartDraw = isEndDraw = false;
				// create() will return a reference to an instance of PolygonDrawAction
				drawAction = draw.create("polygon", {mode: "click"});

				// focus the view to activate keyboard shortcuts for drawing polygons
				view.focus();

				// listen to vertex-add event on the action
				drawAction.on("vertex-add", drawRectangle);

				drawAction.on("cursor-update", drawRectangle);

				drawAction.on("vertex-remove", drawRectangle);

				drawAction.on("draw-complete", endDraw);
			}
			
			let tempRectangle = [];
			//   是否开始绘制,是否结束绘制 , 是否最后一次绘制
			let isStartDraw = false, isEndDraw = false, isLastDraw = false;
			//   结束绘制        
			function endDraw(evt){
				isLastDraw = true;
				let graphics = drawRectangle(evt);
				isLastDraw = false;
				//  改变指针样式
				$(".esri-view-root").css("cursor", "default");
				let lonlat = graphics[graphics.length - 1].geometry.rings[0][3];
				
				//  添加 “取消”、“保存”按钮
				let submit = new Graphic({
					geometry: new Point({
						x: lonlat[0],
						y: lonlat[1],
						z: 0,
						spatialReference: view.spatialReference
					}),
					symbol: {
					  type: "text",
					  declaredClass: "clipBtn",
					  color: [0, 0, 0, 1],
					  haloColor: "black",
					  haloSize: "1px",
					  text: "截屏",
					  xoffset: -12,
					  yoffset: -24,
					  font: { // autocast as Font
						size: 12,
	//                            weight: "bold",
						family: "sans-serif"
					  }
					},
					attributes: {
						clipName: "确定"
					}
				});
				tempRectangle.push(submit);
				tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
				
				let cancel = new Graphic({
					geometry: new Point({
						x: lonlat[0],
						y: lonlat[1],
						z: 0,
						spatialReference: view.spatialReference
					}),
					symbol: {
					  type: "text",
					  declaredClass: "clipBtn",
					  color: "red",
					  haloColor: "black",
					  haloSize: "1px",
					  text: "取消",
					  xoffset: -48,
					  yoffset: -24,
					  font: { // autocast as Font
						size: 12,
	//                            weight: "bold",
						family: "sans-serif"
					  }
					},
					attributes: {
						clipName: "取消"
					}
				});
				tempRectangle.push(cancel);
				tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
				
				//绘制结束
				isEndDraw = true;
			}
			
			//   绘制多边形             	
			function drawRectangle(evt) {
				//顶点取第一个点和最后一个点
				let vertices = [evt.vertices[0], evt.vertices[evt.vertices.length - 1]];
			  
				//判断drawAction类型
				switch(evt.type){
					case "vertex-add":    //鼠标按下或鼠标拖动
						isStartDraw = true;
						break;
					case "cursor-update": //鼠标未按下状态时的鼠标移动
						//判断是否开始绘制,若开始绘制后鼠标抬起,则结束绘制
						if(isStartDraw){
							drawAction.complete();
							isStartDraw = false;
						}
						return;
						break;
					case "vertex-drag":
						isStartDraw = true;
						break;
					default:
						break;
			  }
				
			  //   若未开始绘制,则返回             	
			  if(!isStartDraw){
				  return;
			  }
			  
			  //remove existing graphic
			  clearGraphics();

			  // create a new rectangle
			  let polygon = createRectangle(vertices);

			  // create a new graphic representing the polygon, add it to the view
			  tempRectangle.push(createGraphic(polygon));
			  
			  tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
			  return tempRectangle;
			}
			
			//  创建矩形             
			function createRectangle(vertices) {
				let rectangle = new Polygon({
					rings: vertices,
					spatialReference: view.spatialReference
				});
				
				//  添加四个角的标记点         	
				let extent = rectangle.extent.clone();
				if(extent.xmin != extent.xmax && extent.ymin != extent.ymax){
					let rings = [];
					rings.push([extent.xmax, extent.ymax]);
					rings.push([extent.xmin, extent.ymax]);
					rings.push([extent.xmin, extent.ymin]);
					rings.push([extent.xmax, extent.ymin]);
					let rectangle = new Polygon({
						rings: rings,
						spatialReference: view.spatialReference
					})
					
					//   若不是最后一次绘制,则添加四个角点                     
	//                        if(!isLastDraw){
						for(let i=0; i<rings.length; i++){
							let marker = new Graphic({
								geometry: new Point({
									x: rings[i][0],
									y: rings[i][1],
									z: 0,
									spatialReference: view.spatialReference
								}),
								symbol: {
								  type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
								  color: [0, 0, 0],
								  outline: { // autocasts as new SimpleLineSymbol()
									color: [0, 0, 0],
									width: 0.5
								  }
								},
								attributes: {
									clipName: "extent_" + i
								}
							});
							tempRectangle.push(marker);
							tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
						}
	//                        }
					
					
					return rectangle;
				}
				return rectangle;
			}
			
			// 清除截屏的要素               
			function clearGraphics(){
				if(tempRectangle.length > 0){
					for(let i=0; i<tempRectangle.length; i++){
						tempGraphicsLayer.remove(tempRectangle[i]);
					}
				}
				tempRectangle = [];
			}
			
			//  创建截屏要素              
			function createGraphic(rectangle) {
			  graphic = new Graphic({
				geometry: rectangle,
				symbol: {
				  type: "simple-fill", // autocasts as SimpleFillSymbol
				  color: [0, 0, 0, 0.1],
				  style: "solid",
				  outline: { // autocasts as SimpleLineSymbol
					color: [0, 0, 0],
					width: 1
				  }
				},
				attributes: {
					clipName: "clipRectangle"
				}
			  });
			  return graphic;
			}
			// 截图按钮点击事件
			let screenshotBtn = document.getElementById("screenshot");
			screenshotBtn.addEventListener("click", function() {
				//清除已绘制图形
				clearGraphics();
				isEndDraw = false;
				enableCreateRectangle(draw, view);
				 
				view.focus();
				
				//  改变指针样式
				$(".esri-view-root").css("cursor", "crosshair");
			});
			  
			// 监听地图点击事件             
			view.on("click", function(event){
				let screenPoint = {
					x: event.x,
					y: event.y
				};

				// 开始截屏/取消截屏
				if(isEndDraw){
					view.hitTest(screenPoint).then(function(response){
						if(response.results[0].graphic){
							let graphic = response.results[0].graphic;
							if(graphic.attributes.clipName){
								switch(graphic.attributes.clipName){
									case "确定":
										let extent = tempRectangle[4].geometry.extent;
										clearGraphics();
	//	       				                	let height = printTemplate.exportOptions.width*extent.height/extent.width;
										let minPoint = view.toScreen({x: extent.xmin, y: extent.ymin});
										let maxPoint = view.toScreen({x: extent.xmax, y: extent.ymax});
										let width = Math.abs(maxPoint.x - minPoint.x);
										let height = Math.abs(maxPoint.y - minPoint.y);
										printTemplate.exportOptions.width = width;
										printTemplate.exportOptions.height = height;
										   
										//	开始打印       									
										let printParams = new PrintParameters({
											view: view,
											template: printTemplate,
											extent: extent 
										});
										
										printTask.execute(printParams).then(function(evt){
											//	保存至本地	       						                    	
											let a = document.createElement('a');
											a.href = evt.url;
											a.download = '截图.jpg';
											a.click();
											//window.open(evt.url);
											
										}, function (evt) {
											alert("截图失败!");
										});
										break;
									case "取消":
										clearGraphics();
										isEndDraw = false;
										break;
									default: 
										break;
								}
							}
						}
					});
				}
			});
			
			//	截屏范围拖动事件监听           	
			let isStartDrag = false, isAllDrag = false, dragHandle = {drag: {}}, isEnableDrag = true;
			let allDrag = {startPoint: [], endPoint: [], orignVertices: [[], []]};
			let dragVertices = [[], []];
			view.on("pointer-down", function(event){
				let screenPoint = {
					x: event.x,
					y: event.y
				};
				// 开始截屏/取消截屏
				if(isEndDraw){
					view.hitTest(screenPoint).then(function(response){
						if(response.results[0].graphic){
							let graphic = response.results[0].graphic;
							if(graphic.attributes.clipName){
								switch(graphic.attributes.clipName){
									case "确定":
										break;
									case "取消":
										break;
									case "clipRectangle":
										isStartDrag = isAllDrag = true;
										let sGraphic = tempRectangle[1];
										let nGraphic = tempRectangle[3];
										dragVertices = [
											[sGraphic.geometry.x, sGraphic.geometry.y],
											[nGraphic.geometry.x, nGraphic.geometry.y]
										];
										
										let point = view.toMap(screenPoint);
										allDrag.startPoint = [point.x, point.y];
										allDrag.orignVertices = [].concat(dragVertices);
										
										//  禁止地图拖动	       										
										dragHandle.drag = view.on('drag',function(e){e.stopPropagation()});
										break;
									default: 
										if(graphic.attributes.clipName.indexOf("_") > -1){
											//	  开始拖动顶点     										
											isStartDrag = true;
											let index = graphic.attributes.clipName.split("_")[1];
											let nIndex = parseInt(index) + 2;
											if(nIndex > 3){
												nIndex = nIndex - 3 - 1;
											}
											let nGraphic = tempRectangle[nIndex];
											dragVertices[0] = [nGraphic.geometry.x, nGraphic.geometry.y];
											
											//  禁止地图拖动	       										
											dragHandle.drag = view.on('drag',function(e){e.stopPropagation()});
										}
										break;
								}
							}
						}
					});
				}
			})
			
			//	监听鼠标移动事件           	
			view.on('pointer-move', function(evt){
				let screenPoint = {x: evt.x, y: evt.y};
				let point = view.toMap(screenPoint);
				if(isEndDraw){
					//  改变指针样式
					$(".esri-view-root").css("cursor", "default");
					
					view.hitTest(screenPoint).then(function(response){
						if(response.results[0].graphic){
							let graphic = response.results[0].graphic;
							if(graphic.attributes.clipName){
								switch(graphic.attributes.clipName){
									case "确定":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "pointer");
										break;
									case "取消":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "pointer");
										break;
									case "clipRectangle":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "move");
										break;
									case "extent_0":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "ne-resize");
										break;
									case "extent_1":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "se-resize");
										break;
									case "extent_2":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "sw-resize");
										break;
									case "extent_3":
										//  改变指针样式
										$(".esri-view-root").css("cursor", "se-resize");
										break;
									default: 
										break;
								}
							}
						}
					});
				}
				//	若开始拖动           		
				if(isStartDrag){
					if(isAllDrag){//整体拖动
						allDrag.endPoint = [point.x, point.y];
						
						//	 xy差值         				
						let gapX = allDrag.endPoint[0] - allDrag.startPoint[0];
						let gapY = allDrag.endPoint[1] - allDrag.startPoint[1];
						dragVertices = [
							[allDrag.orignVertices[0][0] + gapX, allDrag.orignVertices[0][1] + gapY],
							[allDrag.orignVertices[1][0] + gapX, allDrag.orignVertices[1][1] + gapY]
						];
						let evt = {
							type: "vertex-drag",
							vertices: dragVertices
						}
						endDraw(evt);
					}else{//顶点拖动
						dragVertices[1] = [point.x, point.y];
						let evt = {
							type: "vertex-drag",
							vertices: dragVertices
						}
						endDraw(evt);
					}
				}
			});
			
			// 监听鼠标移动事件           	
			view.on('pointer-up', function(evt){
			  let point = view.toMap({x: evt.x, y: evt.y});
			  if(isStartDrag){
				if(isAllDrag){//整体拖动
					allDrag.endPoint = [point.x, point.y];
					//	 xy差值         				
					let gapX = allDrag.endPoint[0] - allDrag.startPoint[0];
					let gapY = allDrag.endPoint[1] - allDrag.startPoint[1];
					dragVertices = [
						[allDrag.orignVertices[0][0] + gapX, allDrag.orignVertices[0][1] + gapY],
						[allDrag.orignVertices[1][0] + gapX, allDrag.orignVertices[1][1] + gapY]
					];
					let evt = {
						type: "vertex-drag",
						vertices: dragVertices
					}
					endDraw(evt);
					//  恢复地图拖动	   
					dragHandle.drag.remove();
					isStartDrag = isAllDrag = false;
					allDrag = {startPoint: [], endPoint: []};
				}else{
					dragVertices[1] = [point.x, point.y];
					let evt = {
						type: "vertex-drag",
						vertices: dragVertices
					}
					endDraw(evt);
					//  恢复地图拖动	   
					dragHandle.drag.remove();
					isStartDrag = false;
				}
				 
			  }
			});        
		});           
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <div id="screenshot" class="esri-widget-button esri-widget esri-interactive" title="截图">
      <a role="tab" data-toggle="tab" class="esri-icon-applications"></a>
  </div>
</body>
</html>

说明:该代码不太好 只实现了功能 在性能上和代码上还需优化!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1410566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

InnoDB索引

B树与B树 索引的数据结构就是B树&#xff0c;它的叶子节点存储数据(数据页)&#xff0c;非叶子节点存储索引(索引页)。 所以索引走树&#xff0c;全表扫走叶子节点的单向链表(mysql里优化成双向) 二级索引页(非主键) 多个目录项记录 目录项记录 每页记录的最小值 主键值 …

Linux系统下常用软件安装汇总,包括mysql,java,git,redis等

01.环境搭建 1.安装列表 MySQL 5.7.11 Java 1.8 Apache Maven 3.6 tomcat8.5 git Redis Nginx python docker 2.安装mysql 1.拷贝mysql安装文件到Linux的某个目录下 2.解压Linux安装包&#xff1a;tar -xvzf mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz 3.进入解压后…

[漏洞复现]Redis 沙盒逃逸漏洞(CVE-2022-0543)

一、漏洞情况分析 Redis 存在代码注入漏洞&#xff0c;攻击者可利用该漏洞远程执行代码。 二、漏洞复现 春秋云境.com 进入靶场 开始复现 三、漏洞处置建议 把靶场关了&#xff0c;跟漏洞说“白白吧

4.【SpringBoot3】文章管理接口开发

序言 在文章管理模块&#xff0c;有以下接口需要开发&#xff1a; 新增文章文章列表&#xff08;条件分页&#xff09;获取文章详情更新文章删除文章 数据库表字段和实体类属性&#xff1a; 1. 新增文章 需求分析 当用户点击左侧菜单中的“文章管理”后&#xff0c;页面主…

apk加固后,签名后没有V2签名的,targetsdk版本改为30后报字节没有对齐的

当我吧targetsdk版本改为30后,加固后重新签名发现,安装不上报错 adb: failed to install E:\XX\262_rel.apk: Failure [-124: Failed parse during installPackageLI: Targeting R (version 30 and above) requires the resources.arsc of installed APKs to be stored uncomp…

全桥变压器计算1

一共有两级&#xff0c;先DC升压&#xff0c;后H桥逆变为AC 因为两级都有损耗&#xff0c;所以一般用输入功率计算 电池升压到400V高压用的效率用表示&#xff0c;后面DC转AC的效率用表示&#xff0c;输入电压用Vin&#xff0c;输出功率Po2000W,输入功率为Pin 一般和96% 所…

叩开c++的大门

目录 1. 什么是c&#xff1f; 2. c的发展史 3. c和c语言的区别是什么呢&#xff1f; 4. 接下来让我们正式进入c的学习吧。 4.1 c的关键字 4.2 命名空间 4.2.1 命名空间的定义 4.2.2 命名空间的使用 4.3 c的输入输出 std命名空间的使用惯例std是C标准库的命名空间&…

深入《羊了个羊》:从0到1的消除游戏开发

一、游戏简介 《羊了个羊》是一款备受欢迎的消除类游戏。玩家需要通过交换相邻的方块&#xff0c;使三个或更多相同方块连成一线&#xff0c;从而将它们消除。消除方块可以获得分数&#xff0c;并在全球排行榜上与其他玩家竞争。 设置项目结构 首先&#xff0c;在文本编辑器中…

【数据结构与算法】之字符串系列-20240126

这里写目录标题 一、12. 整数转罗马数字二、43. 字符串相乘三、49. 字母异位词分组四、151. 反转字符串中的单词五、179. 最大数 一、12. 整数转罗马数字 中等 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D …

前端vue集成echarts图形报表样例

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f415;1.在项目终端下载echarts依赖包&#x1f3e8;2.在main.js中导入echarts资源包并使用&#x1f380;3.在.vue文件中直接使用echarts&#xff0c;下面是一个样例&a…

计算机找不到x3daudio1_7.dll无法继续执行的5种解决方法

当我们在运行一款游戏时&#xff0c;遇到了“游戏找不到x3daudio1_7.dll”这样的错误提示&#xff0c;并因此无法继续执行游戏进程&#xff0c;这种情况具体是什么问题呢&#xff1f;我们可以深入解析一下。通常情况下&#xff0c;这种报错信息意味着系统缺失了一个关键的动态链…

144基于matlab的平面桁架结构的总体刚度矩阵计算

基于matlab的平面桁架结构的总体刚度矩阵计算&#xff0c;最后以图形形式显示出桁架结构&#xff0c;程序已调通&#xff0c;可直接运行。 144matlab 平面桁架 有限元分析 总体刚度 (xiaohongshu.com)

华为鸿蒙扩圈何时才会停息~

自从2023年华为秋季发布会上宣布鸿蒙Next不在兼容Android后&#xff0c;鸿蒙才开始扩圈行动&#xff0c;直到2024年1月18日鸿蒙千帆启航的仪式上宣布已有200鸿蒙原生态应用正在加速开发中&#xff0c;并且宣布启动了第二阶段的扩圈行动。 就1月25日就有多家银行和淘宝等支付平台…

Grafana loki配置, 无脑版

使用docker部署Grafana loki 1.创建 docker-compose.yml 文件 touch docker-compose.yml写入以下内容 vim touch docker-compose.yml version: "3"networks:loki:services:loki:image: grafana/loki:latestrestart: unless-stoppedports:- "3100:3100"vo…

1.24 C++ day1

思维导图 试编程 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数&#xff0c;要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {string s;cout << "please enter a str…

设置模式之责任链模式

目录 1.概述 2.结构 3.实现 4.总结 1.概述 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为性设计模式&#xff1b;它为请求创建了一个接收者对象的链&#xff0c;允许你将请求沿着处理者链进行发送。 收到请求后&#xff0c; 每个处理者均…

list的介绍及其模拟实现

今天我们了解list&#xff0c;list在python中是列表的意思 &#xff0c;但是在C中它是一个带头双向循环链表&#xff1a; list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xf…

1.25学习总结

今天学习了二叉树&#xff0c;了解了二叉树的创建和遍历的过程 今天所了解的遍历过程主要分为三种&#xff0c;前序中序和后序&#xff0c;都是DFS的想法 前序遍历&#xff1a;先输出在遍历左节点和右节点&#xff08;输出->左->右&#xff09; 中序遍历&#xff1a;先…

2024传薪文化盛大启航 年度论坛暨新春年会圆满举办

2024年1月20日下午, 由创人文/传薪文化理事会与长三角美好生活创新联盟主办,由传薪文化、九鲲文化承办的“文脉传万象薪”传薪&美创联2024甲辰年度论坛暨新春年会,在上海成功举办。来自学界、文化、经济和艺术等领域的社会精英人士170余人齐聚一堂,从历史和传承中汲取营养,…

elementplus 中 DatePicker 日期选择器样式修改无效

问题 遇到一个需求需要修改 DatePicker 日期选择器的样式&#xff0c;在添加了 scoped 属性的 style 标签&#xff0c;并且使用了 deep 样式穿透的情况下并不能修改其样式。 原因 DatePicker 日期选择器弹出面板默认挂载在 body 上&#xff0c;所以在组件中添加了 scoped 属…