arcgis实现截图/截屏功能

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>

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

289. 生命游戏

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

嵌入式工程师有什么推荐学习路径?

嵌入式工程师有什么推荐学习路径&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff…

阿赵UE学习笔记——12、植物系统

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的用法。这次需要使用植物系统在地形上添加一些草和石头的装饰。 一、素材准备 之前介绍过&#xff0c;可以在Quixel上面获取免费的资源&#xff0c;所以我这里就下载了一些资源&#xff0c;有草和石头的…

MySQL(下)

四、事务 一、概念 对数据库的一次执行中有多条sql语句执行。这多条sql在一次执行中&#xff0c;要么都成功执行&#xff0c;要么都不执行。保证了数据完整性。MySQL中只有innodb引擎支持事务。 二、特性 事务是必须满足 4 个条件&#xff08;ACID&#xff09;&#x…

【mongoDB】集合的创建和删除

目录 1.集合的创建 2. 查看所有集合 3.删除集合 1.集合的创建 格式&#xff1a; db.createCollection ( name ) 例如创建一个名为 bbb 的集合 还可以通过传递一个选项对象来指定集合的属性&#xff0c;例如最大文档的大小&#xff0c;索引选项等 例如 这样创建了一个名为 cc…

【业务功能篇133】 Mysql连接串优化性能问题

rewriteBatchedStatementstrue开启了MySQL驱动程序的批量处理功能。 spring.datasource.urljdbc:mysql://localhost:3306/mydatabase?rewriteBatchedStatementstrue 在MyBatis Plus框架中&#xff0c;批量插入是一种高效的数据库操作方式。通过开启rewriteBatchedStatementstr…

在优衣库新衣年货里,看见幸福感的“共振”

一场寒潮自北向南掠过&#xff0c;很多地区迎来瑞雪兆丰年的美好意象&#xff0c;年味渐浓&#xff0c;农历新年进入倒计时状态。带着对新年团聚的期许&#xff0c;置办年货&#xff0c;开始成为老百姓在这个时节的大事。 经历颇具魔幻色彩的2023年&#xff0c;“龙年”对中国…

x-cmd pkg | sqlite3 - 轻量级的嵌入式关系型数据库

目录 简介首次用户 技术特点竞品和相关产品sqlite 与 x-cmd进一步阅读 简介 sqlite3 是一个轻量级的文件数据库&#xff0c;体积非常小&#xff0c;提供简单优雅而功能强大的 sql 化的数据查询。 通常情况下&#xff0c;sqlite 指的是 SQLite 2.x 版本&#xff0c;而 sqlite3 …

Aleo测试网回顾-测试网期间共释放了多少积分

上一篇我们整理了Aleo的详细项目介绍&#xff0c;Aleo项目详细介绍-一个兼顾隐私和可编程性的隐私公链-CSDN博客 接下来&#xff0c;让我们盘点下测试网期间的积分释放情况&#xff0c;测试网期间的奖励积分也将是Aleo主网上线后的抛压来源。测试网期间共计释放了4000万的积分…

MATLAB标记点

% clear % clc % close all % % 生成随机时程信号 % fs100; % signalLength fs*60*2; % time 1/fs:1/fs:signalLength/fs; % randomSignal 2*sin(2*pi*0.5*time)3*cos(2*pi*1*time)randn(1, signalLength); function [frequencyPP]funct_peak(signal,Hz) % 生成随机时…

跨境防诈指南 | 了解美国电商持续遭遇的“超额支付”欺诈

目录 常见的“超额支付”欺诈类型 假支票诈骗 虚假信用卡欺诈 基于交易的洗钱诈骗 防止“超额支付”欺诈 增强交易安全保障 加强异常交易识别 借助反欺诈技术识别 加强团队欺诈培训 美国商业委员会的统计报告显示&#xff0c;2023年年1至6月&#xff0c;联邦贸易委员会&#xf…

kafka(三)生产问题

一、线上机器规划 二、线上问题优化 1、消息丢失的情况 消息发送端&#xff1a; a&#xff1a;acks0&#xff1a; 表示producer不需要等待broker确认收到消息的回复就可以继续发送消息&#xff1b;性能高&#xff0c;但很容易丢失消息&#xff1b; b&#xff1a;acks1&#x…

《游戏-01_3D-开发》之—人物动画控制器

创建变量&#xff0c; 创建线&#xff0c; 连接&#xff0c; 选中线会变为蓝色&#xff0c;新增变量&#xff0c; 设置线&#xff0c; 双击子层进入子层&#xff0c; 创建变量&#xff0c; 双击SkillPanel 拖拽好之后返回上一层&#xff0c; 依次连接&#xff0c; 设置线&#…

《WebKit 技术内幕》学习之十四(1):调式机制

第14章 调试机制 支持调试HTML、CSS和JavaScript代码是浏览器或者渲染引擎需要提供的一项非常重要的功能&#xff0c;这里包括两种调试类型&#xff1a;其一是功能&#xff0c;其二是性能。功能调试能够帮助HTML开发者使用单步调试等技术来查找代码中的问题&#xff0c;性能调…

03. 静态路由

文章目录 一. 静态路由概述1.1. 概述1.2. 路由信息获取方式1.3. 路由表的参数1.4. 路由协议的优先级1.5. 最优路由条目优先1.6. 最长前缀匹配原则 二. 实验实操2.1. 实验1&#xff1a;静态路由2.1.1. 实验目的2.1.2. 实验拓扑图2.1.3. 实验步骤&#xff08;1&#xff09;配置网…

centos系统安装Ward服务器监控工具

简介 Ward是一个简约美观多系统支持的服务器监控面板 安装 1.首先安装jdk yum install java-1.8.0-openjdk-devel.x86_64 2.下载jar wget 3.启动 java -jar ward-1.8.8.jar 体验 浏览器输入 http://192.168.168.110:4000/ 设置服务名设置为:myserver 端口号:5000 点击…

写一份简单的产品说明书:格式和排版建议

现在的市场竞争那么激烈&#xff0c;拥有一份简洁明了的产品说明书可以说是很重要的。产品说明书不仅向用户提供了对产品的详细了解&#xff0c;还能够树立品牌形象&#xff0c;提升用户体验。 | 一、写一份简单的产品说明书—一些建议 1.创意封面设计 一个吸引人的封面设计能…

wpf控件Expander集合下的像素滚动

项目场景&#xff1a;Expander集合滚动 如下图&#xff0c;有一个Expander集合&#xff0c;且设置 ScrollViewer.VerticalScrollBarVisibility "Auto" 每个Expaner下包含有若干元素&#xff0c;当打开Expader(即IsExpanded "true"&#xff09;时&#…

利用Python实现科学式占卜

一直以来,中式占卜都是基于算命先生手工实现,程序繁琐(往往需要沐浴、计算天时、静心等等流程)。准备工作复杂(通常需要铜钱等道具),计算方法复杂,需要纯手工计算二进制并转换为最终的卦象,为了解决这个问题,笔者基于python实现了一套科学算命工具,用于快速进行占卜…