arcgis 叠加图片 watch
<html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <title>ArcGIS 4x - Add Image to Map</title> <link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/light/main.css" /> <script src="https://js.arcgis.com/4.19/"></script> </head> <body> <div id="viewDiv"></div> <div id="instructions" style="font-family:Arial;">This pen is a sandbox for testing methods of adding images to the map view in 4x, without the use of a map service. <ul> <li> Option 1: <a style="font-weight:bold;">WebTileLayer</a> </li> <li> Option 2: <a style="font-weight:bold;">PictureFillSymbol</a> </li> <li> Option 3: <a style="font-weight:bold;">PictureMarkerSymbol</a> </li> <li> Option 4: <a style="font-weight:bold;">Sublayer</a> </li> </ul> </div> </body> </html>
require(["esri/layers/WebTileLayer", "esri/layers/MapImageLayer", "esri/Map", "esri/layers/WMSLayer", "esri/layers/GraphicsLayer", "esri/symbols/PictureFillSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/Color", "esri/views/MapView", "esri/Graphic", "esri/geometry/Extent", "esri/geometry/Polygon", "esri/geometry/Point", "esri/layers/TileLayer", "esri/layers/WebTileLayer", "esri/core/watchUtils", "esri/request", "esri/widgets/CoordinateConversion"], function( WebTileLayer, MapImageLayer, Map, WMSLayer, GraphicsLayer, PictureFillSymbol, SimpleLineSymbol, SimpleFillSymbol, Color, MapView, Graphic, Extent, Polygon, Point, TileLayer, WebTileLayer, watchUtils, esriRequest, CoordinateConversion ) { const imageUrl = "https://prd-wret.s3.us-west-2.amazonaws.com/assets/palladium/production/s3fs-public/styles/atom_page_medium/public/thumbnails/image/md_state_house.jpg"; //OPTION 1 const layerTile = new WebTileLayer({ urlTemplate: imageUrl }); //OPTION 2 const rings = [[-76.492400, 38.9800], [-76.4896, 38.9800], [-76.4896, 38.9774], [-76.492400, 38.9774],[-76.492400, 38.9810]]; const polygon = new Polygon({ rings: rings, spatialReference: { wkid: 4326 } }); const symbolFill = { type: "picture-fill", url: imageUrl, width: 1200, height: 1500 }; const graphicPolygon = new Graphic({ geometry: polygon, symbol: symbolFill }); const layerPolygon = new GraphicsLayer({ graphics: [graphicPolygon] }); //OPTION 3 const point = new Point ({ x: -76.490695, y: 38.9788 }); const markerExtent = { xmin: -76.492706, xmax: -76.488920, ymin: 38.978750, ymax: 38.980800 } const symbolMarker = { type: "picture-marker", url: imageUrl, width: 200, height: 200 }; const graphicPoint = new Graphic({ geometry: point, symbol: symbolMarker }); const layerPoint = new GraphicsLayer({ graphics: [graphicPoint] }); //OPTION 4 const CustomTileLayer = WebTileLayer.createSubclass({ properties: { urlTemplate: null, }, getTileUrl: function(level, row, col) { return imageUrl; // return urlTemplate // .replace("{z}", level) // .replace("{x}", col) // .replace("{y}", row); }, // Override this method to process the data returned from the server. fetchTile: function(level, row, col, options) { // call getTileUrl() method to construct the URL to tiles // for a given level, row and col provided by the LayerView const url = this.getTileUrl(level, row, col); // request for tiles based on the generated url // the signal option ensures that obsolete requests are aborted return esriRequest(url, { responseType: "image", signal: options && options.signal }).then( function(response) { const image = response.data; const width = this.tileInfo.size[0]; const height = this.tileInfo.size[0]; // create a canvas with 2D rendering context const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = width; canvas.height = height; if (this.tint) { context.fillStyle = this.tint.toCss(); context.fillRect(0, 0, width, height); context.globalCompositeOperation = "difference"; } context.drawImage(image, 0, 0, width, height); return canvas; }.bind(this) ); } }); const layerSub = new CustomTileLayer({ urlTemplate: imageUrl }); //-------------------------------- const option1 = layerTile; const option2 = layerPolygon; const option3 = layerPoint; const option4 = layerSub; //Change targetLayer to try different options const targetLayer = option3; //--------------------------------- const map = new Map({ basemap: "dark-gray", layers: [targetLayer] }); const center = [-76.4907, 38.9789]; const view = new MapView({ container: "viewDiv", map: map, zoom: 16, center: center }); if (targetLayer === option1) { watchUtils.on(targetLayer, "destroy", "call", () => {console.warn('targetLayer refresh!');}); targetLayer.destroyer = function fakeDestroyer() { // return targetLayer.url; } targetLayer.destroy = function fakeDestroy() { //test destroy override } console.warn(targetLayer.destroyer); console.warn(targetLayer.destroy); } if (targetLayer === option3) { view.watch("animation", (response) => { if(response && response.state === "running"){ targetLayer.visible = false; } }); view.watch("stationary", (newValue, oldValue) => { if (newValue == true) { adjustMarker(); } }); } function adjustMarker() { const topRightScreenPt = view.toScreen({ x: markerExtent.xmax, y: markerExtent.ymax, spatialReference:{ wkid: 4326 } }); const bottomLeftScreenPt = view.toScreen({ x: markerExtent.xmin, y: markerExtent.ymin, spatialReference:{ wkid: 4326 } }); const newWidth = Math.abs(topRightScreenPt.x - bottomLeftScreenPt.x); const newHeight = Math.abs(bottomLeftScreenPt.y - topRightScreenPt.y); targetLayer.graphics.items[0].symbol = { type: "picture-marker", url: imageUrl, width: newWidth > 0 ? newWidth + "pt" : 1, height: newHeight > 0 ? newHeight + "pt" : 1 }; targetLayer.visible = true; } var ccWidget = new CoordinateConversion({ view: view }); view.ui.add(ccWidget, "bottom-left"); });