arcgis js地图叠加图片(影像)

之前做地图叠加影像时,出现地图旋转后图片位置不对或图片变形,第一次图片加载不出来的问题,特此记录

上代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>地图叠加图片之BaseDynamicLayer</title>
    <link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/dark-blue/main.css" />
    <script src="https://js.arcgis.com/4.19/"></script>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        button {
            position: fixed;
            top: 10px;
            right: 10px;
        }
    </style>
</head>

<body>
    <div id="viewDiv"></div>
    <button onclick="addImageToMap()">显示/隐藏图片</button>
    <script>
        let baseMap, mapView, customDynamicLayer, GeoExtent, GeoPoint, DynamicLayer, WebMercatorUtils;
        const extent = {
            "xmin": 73.42961975,
            "ymin": 20.2,
            "xmax": 135.10961975,
            "ymax": 53.56
        }
        require([
            "esri/Map",
            "esri/views/MapView",
            "esri/geometry/Extent",
            "esri/geometry/Point",
            "esri/geometry/support/webMercatorUtils",
            "esri/layers/BaseDynamicLayer"
        ], function (Map, MapView, Extent, Point, webMercatorUtils, BaseDynamicLayer) {
            GeoExtent = Extent;
            GeoPoint = Point;
            DynamicLayer = BaseDynamicLayer;
            WebMercatorUtils = webMercatorUtils;
            var map = new Map({
                basemap: 'osm',
            });
            baseMap = map

            var view = new MapView({
                container: "viewDiv",
                map: map,
                center: [107.246152, 34.414465],
                zoom: 7
            });
            mapView = view
            view.when(() => crateDynamicLayer())
        });

        function addImageToMap() {
            //初次叠加创建图层,后续控制该图层的显示隐藏
            const curLayer = baseMap.findLayerById(`baes_dynamic_layer`);
            // mapView.goTo({
            //     center: [extent.xmin + (extent.xmax - extent.xmin) / 2, extent.ymin + (extent.ymax - extent.ymin) / 2],
            //     zoom: 10
            // })
            mapView.extent = extent;
            if (curLayer) {
                curLayer.visible = !curLayer.visible;
                return
            }
            let ImageOverlayLayer = new customDynamicLayer({
                id: 'baes_dynamic_layer',
                picUrl: `./image/quickview.png`,
                extent: extent,
                view: mapView
            });
            ImageOverlayLayer.refreshInterval = 0;//不自动刷新
            baseMap.add(ImageOverlayLayer);
        }

        function crateDynamicLayer() {
            customDynamicLayer = DynamicLayer.createSubclass({
                properties: {
                    picUrl: null,
                    extent: null,
                    image: null,
                    canvas: null,
                    view: mapView
                },
                getImageUrl: async function (extent, width, height) {
                    //转换图片范围的坐标系,如果坐标系相同,则无需转换
                    console.log(this.extent);
                    let wgsExtent = WebMercatorUtils.geographicToWebMercator(new GeoExtent({
                        xmin: this.extent.xmin,
                        ymin: this.extent.ymin,
                        xmax: this.extent.xmax,
                        ymax: this.extent.ymax
                    }));
                    let upperLeftMerc = new GeoPoint({
                        x: wgsExtent.xmin,
                        y: wgsExtent.ymax,
                        spatialReference: this.view.spatialReference
                    });
                    let lowerRightMerc = new GeoPoint({
                        x: wgsExtent.xmax,
                        y: wgsExtent.ymin,
                        spatialReference: this.view.spatialReference
                    });
                    let newULX = (upperLeftMerc.x - extent.xmin) / (extent.xmax - extent.xmin) * width;
                    let newULY = height - (upperLeftMerc.y - extent.ymin) / (extent.ymax - extent.ymin) * height;

                    let newLRX = (lowerRightMerc.x - extent.xmin) / (extent.xmax - extent.xmin) * width;
                    let newLRY = height - (lowerRightMerc.y - extent.ymin) / (extent.ymax - extent.ymin) * height;

                    let imageWidth = Math.abs(newLRX - newULX);
                    let imageHeight = Math.abs(newULY - newLRY);

                    if (!this.image) {
                        this.image = new Image();
                        this.image.setAttribute("crossOrigin", 'Anonymous');
                    }
                    if (!this.canvas) {
                        this.canvas = document.createElement('canvas');
                    }
                    this.canvas.width = width;
                    this.canvas.height = height;
                    //第一次图片未加载完成就导出canvas,所以第一次不显示,这里改为异步导出canvas
                    const loadimg = img => {
                        return new Promise((rel, rej) => {
                            img.onload = () => {
                                this.canvas.getContext('2d').drawImage(img, newULX, newULY, imageWidth, imageHeight);
                                rel(this.canvas.toDataURL('image/png'))
                            }
                            img.src = this.picUrl;
                        })
                    }
                    return await loadimg(this.image)
                }
            })
        }
    </script>
</body>

</html>

github地址:https://github.com/YUN73R/Arcgis-BaseDynamicLayer

实现地图旋转图片不变形,不位移

预览地址:https://yun73r.github.io/Arcgis-BaseDynamicLayer/

第一次加载请耐心等待图片加载完成

运行

  npm i
  npm run dev

浏览:http://localhost:3456

或者本机装了liver-server、serve等工具,直接项目下运行即可

主要解决了图片位置和大小的算法,地图旋转后图片位置不对和图片变形的问题。

更新

第一次图片未加载完成就导出canvas,所以第一次不显示,改为异步导出canvas

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值