arcgis实现截图/截屏功能

arcgis实现截图/截屏功能

文章目录


前言

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


效果展示


相关代码

html 复制代码
<!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>

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

相关推荐
新中地GIS开发老师1 小时前
Cesium 军事标绘入门:用 Cesium-Plot-JS 快速实现标绘功能
前端·javascript·arcgis·cesium·gis开发·地理信息科学
清欢ysy15 小时前
Cannot find module ‘@next/bundle-analyzer‘
开发语言·javascript·arcgis
jerryinwuhan1 天前
arcgis如何将一部分shp地图截取下来并处理成networkx格式
arcgis
细节控菜鸡4 天前
【2025最新】ArcGIS for JS 实现地图卷帘效果
开发语言·javascript·arcgis
细节控菜鸡5 天前
【2025最新】ArcGIS for JS 实现地图卷帘效果,动态修改参数(进阶版)
开发语言·javascript·arcgis
GIS阵地6 天前
CSV转换为QGIS的简单分类符号
arcgis·二次开发·qgis·地理信息系统·pyqgis
角砾岩队长7 天前
基于ArcGIS实现Shapefile转KML并保留标注
arcgis
细节控菜鸡7 天前
【2025最新】ArcGIS for JS二维底图与三维地图的切换
javascript·arcgis
zenithdev17 天前
开源库入门教程 Cesium:3D地球和地图库
其他·3d·arcgis
徐赛俊9 天前
QGIS + ArcGIS Pro 下载常见卫星影像及 ESRI Wayback 历史影像
arcgis