专栏首页ArcGIS JS API开发ArcGIS JS API 4.15实现地图加载图片(优化版)

ArcGIS JS API 4.15实现地图加载图片(优化版)

主要介绍如何用ArcGIS JS API 4.15实现在二维地图中添加图片的操作。上一篇文章已经介绍了如何添加图片的四种方法,但是添加到地图上的图片在拖动时有些卡顿,所以本文又提出了另一种优化的方法。

写在前面

之前写了一篇关于在ArcGIS地图上添加图片的文章,关注度还可以,在项目中也用文章中提到的技术路线实现了地图叠加图片的需求。但是最近客户又有了新需求,因为我们在之前的文章中通过扩展图层来实现图片添加后,如果图片中某一处的信息比较丰富,在地图缩放的一瞬间如果我们拖动地图的话,那部分的图片会有卡顿。其实这情况不算严重,因为仅仅卡顿那么一秒钟左右而已,但是客户抓着这个点就要较劲,那没办法,来一波优化吧。

之前文章的地址如下:《ArcGIS JS API 4.14实现地图加载图片》。

最终的效果如下:

具体操作

1、因为之前的技术路线是通过扩展BaseDynamicLayer这个类来实现的,所以底层还是使用canvas绘制技术,将图片绘制到了我们的地图上。那这样一来,在图片上信息比较丰富的地方绘制的时候就比较慢,肯定会有一丢丢的卡顿,尽管后期使用双缓冲技术也没有得到优化,所以这篇文章我们采用另一种方式来实现地图叠加图片。

2、这篇文章直接使用img标签来做,原理很简单,我们直接在地图渲染的canvas标签处另外添加一个img标签,然后通过监听地图的视图区域变化来动态改变图片大小和位置即可。

3、首先,我们实例化一张二维地图,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>Intro to MapView - Create a 2D map - 4.15</title>
        <style>
            html,
            body,
            #viewDiv {
                padding: 0;
                margin: 0;
                height: 100%;
                width: 100%;
            }
        </style>
        <link rel="stylesheet" href="http://localhost/4.15/esri/themes/light/main.css" />
        <script src="http://localhost/4.15/init.js"></script>
        <script>
            require(['esri/Map', 'esri/views/MapView', 'esri/core/watchUtils'], function (Map, MapView, watchUtils) {
                var map = new Map({
                    basemap: 'osm',
                });
                var view = new MapView({
                    container: 'viewDiv',
                    map: map,
                    zoom: 7,
                    center: [104.071883, 30.664022], // longitude, latitude
                });
            });
        </script>
    </head>
    <body>
        <div id="viewDiv"></div>
    </body>
</html>

4、然后我们在地图初始化完成之后获取地图渲染的标签,在它同级的地方添加一个img标签,并指定一些属性,如下:

var resultDom;
view.when(function () {
    //添加图片
    var selectDom = document.getElementsByClassName(
        'esri-view-surface esri-view-surface--inset-outline esri-view-surface--touch-none',
    );
    console.log(extent);
    resultDom = document.createElement('img');
    resultDom.src = './testquickviewphoto.png';
    resultDom.className = 'mystyle';
    resultDom.id = 'mystyle';
    selectDom[0].appendChild(resultDom);
});

5、这样一来,我们的图片就已经添加到了地图上,需要我们为这个img标签指定样式才可以看到我们添加后的图片,所以接下来我们直接监听地图的视图变化,在这里面为其指定样式和相应的位置:

let extent = {    //图片的范围
    xmin: 10138549.59667821,
    ymin: 3449716.2722409572,
    xmax: 10249869.087471481,
    ymax: 3578363.913808475,
};
var absd = view.zoom;
watchUtils.when(view, 'extent', function () {
    if (view.extent && document.getElementById('mystyle')) {
        var lefttop = {
            x: extent.xmin,
            y: extent.ymax,
            spatialReference: {
                wkid: 102100,
            },
        };
        var screen_lefttop = view.toScreen(lefttop);
        document.getElementById('mystyle').style.top = screen_lefttop.y + 'px';
        document.getElementById('mystyle').style.left = screen_lefttop.x + 'px';
        //zoom未改变的情况下不重新计算image长和宽
        if (absd != view.zoom) {
            var rightbottom = {
                x: extent.xmax,
                y: extent.ymin,
                spatialReference: {
                    wkid: 102100,
                },
            };
            var screen_rightbottom = view.toScreen(rightbottom);
            document.getElementById('mystyle').style.width =
                screen_rightbottom.x - screen_lefttop.x + 'px';
            document.getElementById('mystyle').style.height =
                screen_rightbottom.y - screen_lefttop.y + 'px';
        }
    }
});

6、完成以上操作后,我们就成功的实现了地图加载图片的过程,这样一来,我们添加上去的图片在地图进行缩放的时候,并不会有卡顿的现象了。

附:

全部代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>Intro to MapView - Create a 2D map - 4.15</title>
        <style>
            html,
            body,
            #viewDiv {
                padding: 0;
                margin: 0;
                height: 100%;
                width: 100%;
            }
            .mystyle {
                position: absolute;
                top: 937px;
                left: 0px;
                width: 1920px;
                height: 937px;
            }
        </style>
        <link rel="stylesheet" href="http://localhost/4.15/esri/themes/light/main.css" />
        <script src="http://localhost/4.15/init.js"></script>
        <script>
            require(['esri/Map', 'esri/views/MapView', 'esri/core/watchUtils'], function (Map, MapView, watchUtils) {
                var map = new Map({
                    basemap: 'osm',
                });
                var view = new MapView({
                    container: 'viewDiv',
                    map: map,
                    zoom: 7,
                    center: [104.071883, 30.664022], // longitude, latitude
                });
                let extent = {
                    xmin: 10138549.59667821,
                    ymin: 3449716.2722409572,
                    xmax: 10249869.087471481,
                    ymax: 3578363.913808475,
                };
                var resultDom;
                view.when(function () {
                    //添加图片
                    var selectDom = document.getElementsByClassName(
                        'esri-view-surface esri-view-surface--inset-outline esri-view-surface--touch-none',
                    );
                    console.log(extent);
                    resultDom = document.createElement('img');
                    resultDom.src = './testquickviewphoto.png';
                    resultDom.className = 'mystyle';
                    resultDom.id = 'mystyle';
                    selectDom[0].appendChild(resultDom);
                });
                var absd = view.zoom;
                watchUtils.when(view, 'extent', function () {
                    if (view.extent && document.getElementById('mystyle')) {
                        var lefttop = {
                            x: extent.xmin,
                            y: extent.ymax,
                            spatialReference: {
                                wkid: 102100,
                            },
                        };
                        var screen_lefttop = view.toScreen(lefttop);
                        document.getElementById('mystyle').style.top = screen_lefttop.y + 'px';
                        document.getElementById('mystyle').style.left = screen_lefttop.x + 'px';
                        //zoom未改变的情况下不重新计算image长和宽
                        if (absd != view.zoom) {
                            var rightbottom = {
                                x: extent.xmax,
                                y: extent.ymin,
                                spatialReference: {
                                    wkid: 102100,
                                },
                            };
                            var screen_rightbottom = view.toScreen(rightbottom);
                            document.getElementById('mystyle').style.width =
                                screen_rightbottom.x - screen_lefttop.x + 'px';
                            document.getElementById('mystyle').style.height =
                                screen_rightbottom.y - screen_lefttop.y + 'px';
                        }
                    }
                });
                setTimeout(reloadPhoto, 500);
                function reloadPhoto() {
                    //console.log(extent.xmax)
                    //左下角
                    var leftbottom = {
                        x: extent.xmin,
                        y: extent.ymin,
                        spatialReference: {
                            wkid: 102100,
                        },
                    };
                    var screen_leftbottom = view.toScreen(leftbottom);
                    //右上角
                    var righttop = {
                        x: extent.xmax,
                        y: extent.ymax,
                        spatialReference: {
                            wkid: 102100,
                        },
                    };
                    var screen_righttop = view.toScreen(righttop);
                    document.getElementById('mystyle').style.top = screen_righttop.y + 'px';
                    document.getElementById('mystyle').style.left = screen_leftbottom.x + 'px';
                    document.getElementById('mystyle').style.width =
                        Math.abs(screen_righttop.x - screen_leftbottom.x) + 'px';
                    document.getElementById('mystyle').style.height =
                        Math.abs(screen_righttop.y - screen_leftbottom.y) + 'px';
                }
            });
        </script>
    </head>
    <body>
        <div id="viewDiv"></div>
    </body>
</html>
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:http://www.xbeichenbei.com/复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • ArcGIS JS API 4.14实现地图加载图片

    主要介绍如何用ArcGIS JS API 4.14实现在二维地图中添加图片的操作。

    X北辰北
  • ArcGIS JS API 4.15实现萤火虫效果

    看到网上的萤火虫效果后,也想在前端通过ArcGIS JS API来实现一下,所以感兴趣的话就跟我一起来看看吧。

    X北辰北
  • 【番外】Electron和ArcGIS API for JavaScript的开发

    最近学了一些Electron.js开发桌面应用的知识,然后作为一名专业的GISer,脑海里马上想到的是,它能不能和我们的ArcGIS JS API整合呢,意思就...

    X北辰北
  • ArcGIS JS API 4.15渲染后台接口返回的数据,并进行点选查询

    本文主要介绍下如何使用ArcGIS JS API对后台接口返回的数据进行渲染,文章中的后台返回数据使用单独的配置文件来处理,详情请看文章内容。

    X北辰北
  • ArcGIS API For Javascript 4.15 绘制地图:三维地图绘制 SceneView 和 ElevationLayer

    魏晓蕾
  • ArcGIS API For Javascript 4.15 绘制地图:查询某个地点和在一定范围内根据条件查询

    魏晓蕾
  • ArcGIS JS API 4.16实现三维场景中在天地图底图上加载2000坐标系的倾斜摄影数据

    本文主要介绍下如何在国家天地图的底图上面使用ArcGIS JS API 4.16加载2000坐标系的倾斜摄影数据。

    X北辰北
  • ArcGIS API For Javascript 4.15 绘制地图:结合 Echarts 绘制地形剖面图

    魏晓蕾
  • ArcGIS API For Javascript 4.15 绘制地图:在地图上测距离、测面积和在不同图层上搜索

    魏晓蕾
  • ArcGIS API For Javascript 4.15 绘制地图:在地图上绘制点和面

    魏晓蕾
  • ArcGIS JS API 加载 TMS 地图瓦片

    TMS(Tile Map Service) 是 OSGeo (开源地理基金会) 提出的一种地图瓦片服务。额外补充一句,WMTS、WMS、WFS这些是 OGC(开...

    前端小tips
  • ArcGIS API for JavaScript 4.18基于ES Modules的新开发方式@arcgis/core

    ArcGIS API for JavaScript 4.18中新增加了一种基于ES Modules的新开发方式@arcgis/core,这篇文章就来介绍一下如何...

    X北辰北
  • ArcGIS API for JavaScript开发入门必读

    ArcGIS API for JavaScript开发必读的一篇入门文档,文章中对ArcGIS API for JavaScript做了简单的介绍,包括学习路线...

    X北辰北

扫码关注腾讯云开发者

领取腾讯云代金券