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 PolygonDrawActiondrawAction = draw.create("polygon", {mode: "click"});// focus the view to activate keyboard shortcuts for drawing polygonsview.focus();// listen to vertex-add event on the actiondrawAction.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 Fontsize: 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 Fontsize: 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 graphicclearGraphics();// create a new rectanglelet polygon = createRectangle(vertices);// create a new graphic representing the polygon, add it to the viewtempRectangle.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 SimpleFillSymbolcolor: [0, 0, 0, 0.1],style: "solid",outline: { // autocasts as SimpleLineSymbolcolor: [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>
说明:该代码不太好 只实现了功能 在性能上和代码上还需优化!!!
相关文章:

arcgis实现截图/截屏功能
arcgis实现截图/截屏功能 文章目录 arcgis实现截图/截屏功能前言效果展示相关代码 前言 本篇将使用arcgis实现截图/截屏功能,类似于qq截图 效果展示 相关代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta nam…...

mysql备份
1.新建备份目录 mkdir -p /data/mysql_dump/#查找mysql配置位置 find / -name "my.cnf" find / -name "mysql.sock" find / -name "mysqldump"2.定时任务 #每天凌晨备份一次 echo "00 00 * * * root /data/mysql_bak.sh" >> /…...

CentOS7 安装PostgreSQL以及配置服务
文章目录 前言1. 安装步骤2. 连接PostgreSQL3. 配置服务配置文件所在路径设置监听地址修改数据库密码已经修改了密码,为什么没有生效?不需要密码就可以连接?设置访问权限4. 新的配置生效前言 PostgreSQL是一种功能强大的开源关系型数据库管理系统,被广泛用于各种应用程序和…...

React 表单、处理受控表单组件、非受控组件
React 表单处理 学习目标: 能够使用受控组件的方式获取文本框 使用 React 处理表单一般有两种方法 受控组件 (推荐)非受控组件 (了解) 1. 受控表单组件 什么是受控组件? input 框自己的状态被 React 组…...

Android开发--状态栏布局隐藏的方法
1.问题如下,安卓布局很不协调 2.先将ActionBar设置为NoActionBar 先打开styles.xml 3.使用工具类 package com.afison.newfault.utils;import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.graph…...

GaussDB如何创建和管理序列、定时任务
前言 GaussDB是华为自主创新研发的分布式关系型数据库,为企业提供功能全面、稳定可靠、扩展性强、性能优越的企业级数据库服务。在实际业务场景使用中,为了提高工作效率,数据库GaussDB提供定时任务的功能,本节为大家讲解GaussDB如…...

mybatis-plus:代码生成器
一、依赖 代码生成器需要添加一下依赖 <dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.7.1</version></dependency><!-- https://mvnre…...

几款提高开发效率的Idea 插件
1、ignore 开发代码过程中经常会有一些需要提交到代码仓库的文件,比如java文件生成的.class、.jar 等,如果将编译后的文件都提交到代码库那么代码库会很大,关键是没有必要。 这款插件就可以很方便的解决某类文件或者某个文件夹不需要提交到…...

Redisson 分布式锁可重入的原理
目录 1. 使用 Redis 实现分布式锁存在的问题 2. Redisson 的分布式锁解决不可重入问题的原理 1. 使用 Redis 实现分布式锁存在的问题 不可重入:同一个线程无法两次 / 多次获取锁举例 method1 执行需要获取锁method2 执行也需要(同一把)锁如…...

【Vue实用功能】Vue实现文档在线预览功能,在线预览PDF、Word等office文件
1、Office Web(微软的开发接口) 优点 没有 Office也可以直接查看Office 文件适用于移动端、PC无需下载文件就可以在浏览器中查看 <iframe src"文档地址" frameborder"0" /> const docUrl 外网可预览的地址 const url encodeURIComponent(docUrl…...

【一站解决您的问题】mac 利用命令升级nodejs、npm、安装Nodejs的多版本管理器n、nodejs下载地址
一:下载nodejs 官网地址,点击下载稳定版 https://nodejs.org/en 如果官网下载特别慢,可以点击这个地址下载 点击这里 https://nodejs.cn/download/current/ 安装完成后,就包含了nodejs 和 npm。此时您的版本就是下载安装的版本…...

【RabbitMQ】死信(延迟队列)的使用
目录 一、介绍 1、什么是死信队列(延迟队列) 2、应用场景 3、死信队列(延迟队列)的使用 4、死信消息来源 二、案例实践 1、案例一 2、案例二(消息接收确认 ) 3、总结 一、介绍 1、什么是死信队列(延迟队列) 死信,在官网中对应的单词…...

java 解析word模板(2024-01-25)
本文主要功能是解析word模板 这是一个word解析类,因为我做的系统用到了而且没有可用的帮助类,只能自己写。之前的实现方式是freemarker 模板解析。但是这次要求用poi不在使用freemarker。实现功能比较少,主要是满足开发需求即可,没…...

flutter-相关个人记录
1、flutter 安卓打包打包报错 flutter build apk -v --no-tree-shake-icons 2、获取华为指纹证书命令 keytool -list -v -keystore ***.jks 3、IOS项目中私有方法查找隐藏文件中 1、cd 项目目录地址 2、grep -r xerbla. "xerbla"为需要查找的关键字 3…...

互斥锁/读写锁(Linux)
一、互斥锁 临界资源概念: 不能同时访问的资源,比如写文件,只能由一个线程写,同时写会写乱。 比如外设打印机,打印的时候只能由一个程序使用。 外设基本上都是不能共享的资源。 生活中比如卫生间,同一…...

Jackson序列化Bean额外属性附加--@JsonAnyGetter、@JsonUnwrapped用户
1. 场景 有一项工作,需要将数据从一个服务S中读取出来(得到的是一个JSON),将数据解析转换以后构造成一个数组的类型A的对象,写入到一个服务T中。 A.class Data public class A {String f0 ;String f1 ; }在发现需要…...

排序算法——冒泡排序算法详解
冒泡排序算法详解 1.引言2.算法概览2.1输入处理2.2核心算法步骤2.3数据结构2.4复杂度分析 3.算法优化4.边界条件和异常处理5.实验和测试6.应用和扩展7.代码示例8.总结 1.引言 冒泡排序是一种简单而直观的比较排序算法,它通过多次遍历数组,比较相邻元素并…...

宋仕强论道之华强北的缺货潮(十六)
始于2019年缺货潮让华强北又生产一大批亿万富翁,缺货的原因主要是:首先,疫情封控导致大量白领在家远程办公,需要购买电脑、打印机等办公设备,同时孩子们也要在家上网课,进一步增加对电子智能终端产品的需求…...

登录注册页面
前提:基于element-ui环境 模态登录组件 分析Login.vue <template><div class"login"><span click"handleClose">X</span></div> </template><script> export default {name: "Login",m…...

视频美颜SDK详解:动态贴纸技术的前沿探索
当下,美颜SDK的动态贴纸技术作为视频美颜的独特亮点,吸引了越来越多开发者和用户的关注。 一、技术详解 动态贴纸技术是视频美颜SDK中的一项创新性功能,它通过在实时视频中添加各种动态效果,为用户提供更加生动有趣的拍摄体验。…...

vue3 实现上传图片裁剪
在线的例子以及代码,请点击访问链接...

flink1.18 广播流 The Broadcast State Pattern 官方案例scala版本
对应官网 https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/fault-tolerance/broadcast_state/ 测试数据 * 广播流 官方案例 scala版本* 广播状态* https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/fault-tolerance…...

vueRouter中scrollBehavior实现滚动固定位置
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。 注意: 这个功能只在 HTML5 h…...

解决WinForms跨线程操作控件的问题
解决WinForms跨线程操作控件的问题 介绍 在构建Windows窗体应用程序时,我们通常会遇到需要从非UI线程更新UI元素的场景。由于WinForms控件并不是线程安全的,直接这样做会抛出一个异常:“控件’control name’是从其他线程创建的,…...

从零开始:Git 上传与使用指南
Git 是一种非常强大的版本控制系统,它可以帮助您在多人协作开发项目中更好地管理代码版本,并确保每个团队成员都能及时地获取最新的代码更改。在使用 Git 进行版本控制之前,您需要先进行一些设置,以确保您的代码能够顺利地与远程仓…...

Docker compose部署Golang服务
Docker Compose 部署 在使用docker部署时,除了使用--link的方式来关联容器之外,还可以使用 docker compose 运行多个容器。 本文以项目:https://github.com/johncxf/go-api 为例。 定义 Dockerfile 我这里用于区分默认 Dockerfile 文件&a…...

Day36 435无重叠区间 763划分字母区间
435 无重叠区间 给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。 注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。 本题与上一题类似: 如果按照左…...

【Servlet】如何编写第一个Servlet程序
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【Servlet】 本专栏旨在分享学习Servlet的一点学习心得,欢迎大家在评论区交流讨论💌 Servlet是Java编写的服务器端…...

读懂比特币—bitcoin代码分析(五)
今天的代码分析主要是 bitcoin/src/init.cpp 文件中的三个函数:AppInitSanityChecks、AppInitLockDataDirectory、AppInitInterfaces,下面我们来说明这三个函数是用来干什么的,并逐行解读函数代码,先贴出源代码如下: …...

uniapp使用uQRCode插件生成二维码的简单使用
最近在找移动端绘制二维码的问题 ,直接上代码 下载 weapp-qrcode.js(可以通过npm install weapp-qrcode --save 下载,之后把它父子到untils目录下) npm install weapp-qrcode --save在组件页面使用 <canvas id"couponQrcode" canvas-id&qu…...