专题一讲了如何将天地图加载进Vue项目,专题二将来讲在天地图上添加自定义图片,点击可以弹框并显示对应数据。
把数据库里的小区根据自带的经纬度在地图上显示出来,每个小区有不同的状态,根据经纬度和小区的状态显示不同的图片,点击图片可以弹窗,在窗口里显示小区的详情。
先看下效果图,然后从加载地图、落点、带弹窗一步一步讲
①将天地图加载出来,代码如下:
将天地图加载出来比较简单,加载地图初始化参数,绑定地图注记。注:令牌编码需要注册申请
<template> <div class="contant" id="map" style="z-index:1"> </div> </template> <script> export default { name: "testJwds.vue", data() { return { map:{}, } }, methods:{ init(){ GeoGlobe.customToken = "令牌编码"; //地图初始化参数 let map = new GeoGlobe.Map({ container: 'map', //绑定容器 showLogo:false, mapCRS: '4490', //定义坐标系 zoom: 13, //当前缩放级别 center: [118.778,32.043], //定位中心点 pitchWithRotate: false,//禁止45度倾斜 dragRotate: false, maxZoom: 17, //最大缩放级别 minZoom: 11, //最小缩放级别 areaId:'',//区ID streetId:'',//街道ID }); map.on( "load", function () { var dt_layer = new GeoGlobe.NJLayer("esri_vec_dt_controlcabin"); map.loadSprite(dt_layer.sprite); map.style.setGlyphs(dt_layer.glyphs); map.addLayer(dt_layer); // 加载南京大屏版矢量注记 var zj_layer = new GeoGlobe.NJLayer("esri_vec_zj_controlcabin"); map.loadSprite(zj_layer.sprite); map.style.setGlyphs(zj_layer.glyphs); map.addLayer(zj_layer); }.bind(this) ) this.map = map; }, }, mounted(){ this.init() } } </script> <style scoped> </style>
效果图如下:
②在地图上根据经纬度,和状态进行落点,不同状态展示不同图片
代码如下:
<template> <div class="contant" id="map" style="z-index:1"> </div> </template> <script> export default { name: "testJwds.vue", data() { return { map:{}, geoJsons:{ "data": { "features": [ { "geometry": {"coordinates": ["118.794580", "32.037248"], "type": "Point"}, "properties": { "icon": "demoImg4", "xmmc": "测试1", "zzlds": "2", "zznd": "2021", }, "type": "Feature" }, { "geometry": {"coordinates": ["118.745607","32.060402"], "type": "Point"}, "properties": { "icon": "demoImg2", "xmmc": "测试2", }, "type": "Feature" } ], "type": "FeatureCollection" }, "type": "geojson" }, } }, methods:{ init(){ GeoGlobe.customToken = "令牌编码"; //地图初始化参数 let map = new GeoGlobe.Map({ container: 'map', //绑定容器 showLogo:false, mapCRS: '4490', //定义坐标系 zoom: 11, //当前缩放级别 center: [118.778,32.043], //定位中心点 pitchWithRotate: false,//禁止45度倾斜 dragRotate: false, maxZoom: 17, //最大缩放级别 minZoom: 11, //最小缩放级别 areaId:'',//区ID streetId:'',//街道ID }); map.on( "load", function () { var dt_layer = new GeoGlobe.NJLayer("esri_vec_dt_controlcabin"); map.loadSprite(dt_layer.sprite); map.style.setGlyphs(dt_layer.glyphs); map.addLayer(dt_layer); // 加载南京大屏版矢量注记 var zj_layer = new GeoGlobe.NJLayer("esri_vec_zj_controlcabin"); map.loadSprite(zj_layer.sprite); map.style.setGlyphs(zj_layer.glyphs); map.addLayer(zj_layer); //落点 this.addImgs() }.bind(this) ) this.map = map; }, addImgs(){ let map = this.map var url1 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10.png'; //申明图片路径 map.loadImage(url1, function(error, image) { console.log(image) //添加图片 命名为demoImg,即这张图片的id为demoImg map.addImage("demoImg1", image); }); var url2 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝.png'; map.loadImage(url2, function(error, image) { map.addImage("demoImg2", image); }); var url3 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝2.png'; map.loadImage(url3, function(error, image) { map.addImage("demoImg3", image); }); var url4 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝3.png'; map.loadImage(url4, function(error, image) { map.addImage("demoImg4", image); }); //通过点方法组装点geojson串 var pointGeoJSON = this.geoJsons //添加点数据源 map.addSource('point-source', pointGeoJSON); //添加点图层 map.addLayer({ "id": "point-layer", //图层ID "type": "symbol", //图层类型 "source": 'point-source', //数据源 "layout": { "icon-image": ['get','icon'], //获取properties icon 图片 "icon-size": 0.5, //图片大小 } }); }, }, mounted(){ this.init() } } </script> <style scoped> </style>
相比第一步,在第二步中多个一个geoJsons对象和一个addImgs方法。
geoJsons对象在实际开发中是从后台查出来的我在这为了方便演示将他直接在页面上列了出来,我把这个对象单拉出来看下
features是一个数组,多个点数据都在这个数组里面;数组里有一个geometry对象,其中coordinates是落点所需要的经纬度,properties对象则是要展示的数据。
在properties中有一个icon属性,这里面的值就是图片的ID,在features数组中有两条状态不同的数据,不同的状态需要显示不同的图片,后台判断状态并将不同图片的ID赋值给icon(上文标绿部分,demoImg4,demoImg2);在addImgs方法中会用map.loadImage 将图片加载,用map.addImage将图片添加到天地图的map中(包含两个参数,参数一对应properties.icon中的图片ID),用map.addSource添加点数据源,用map.addLayer添加图层,注意在添加图层中有一个"icon-image": ['get','icon'] 这个属性负责读取properties中icon的ID值并显示
geoJsons:{ "data": { "features": [ { "geometry": { "coordinates": ["118.794580", "32.037248"], //经纬度 "type": "Point" }, "properties": { //展示的数据 "icon": "demoImg4",//展示图片的ID① "xmmc": "测试1", "zzlds": "2", "zznd": "2021", }, "type": "Feature" }, { "geometry": { "coordinates": ["118.745607","32.060402"], "type": "Point" }, "properties": { "icon": "demoImg2",//展示图片的ID② "xmmc": "测试2", }, "type": "Feature" } ], "type": "FeatureCollection" }, "type": "geojson" }
效果图如下:
③在有落点的基础上点击落点,落点居中并展示弹窗
首先上代码:
<template> <div class="contant" id="map" style="z-index:1"> </div> </template> <script> export default { name: "testJwds.vue", data() { return { map:{}, geoJsons:{ "data": { "features": [ { "geometry": { "coordinates": ["118.794580", "32.037248"], "type": "Point" }, "properties": { "icon": "demoImg4", "xmmc": "测试1", "zzlds": "2", "zznd": "2021", }, "type": "Feature" }, { "geometry": { "coordinates": ["118.745607","32.060402"], "type": "Point" }, "properties": { "icon": "demoImg2", "xmmc": "测试2", }, "type": "Feature" } ], "type": "FeatureCollection" }, "type": "geojson" }, } }, methods:{ init(){ GeoGlobe.customToken = "令牌编码"; //地图初始化参数 let map = new GeoGlobe.Map({ container: 'map', //绑定容器 showLogo:false, mapCRS: '4490', //定义坐标系 zoom: 11, //当前缩放级别 center: [118.778,32.043], //定位中心点 pitchWithRotate: false,//禁止45度倾斜 dragRotate: false, maxZoom: 17, //最大缩放级别 minZoom: 11, //最小缩放级别 areaId:'',//区ID streetId:'',//街道ID }); map.on( "load", function () { var dt_layer = new GeoGlobe.NJLayer("esri_vec_dt_controlcabin"); map.loadSprite(dt_layer.sprite); map.style.setGlyphs(dt_layer.glyphs); map.addLayer(dt_layer); // 加载南京大屏版矢量注记 var zj_layer = new GeoGlobe.NJLayer("esri_vec_zj_controlcabin"); map.loadSprite(zj_layer.sprite); map.style.setGlyphs(zj_layer.glyphs); map.addLayer(zj_layer); this.addImgs() }.bind(this) ) this.map = map; }, addImgs(){ let map = this.map var url1 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10.png'; //申明图片路径 map.loadImage(url1, function(error, image) { console.log(image) //添加图片 命名为demoImg,即这张图片的id为demoImg map.addImage("demoImg1", image); }); var url2 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝.png'; map.loadImage(url2, function(error, image) { map.addImage("demoImg2", image); }); var url3 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝2.png'; map.loadImage(url3, function(error, image) { map.addImage("demoImg3", image); }); var url4 = '/msgcdp/static/GeoGlobeAPI_53/img/图层10拷贝3.png'; map.loadImage(url4, function(error, image) { map.addImage("demoImg4", image); }); //通过点方法组装点geojson串 var pointGeoJSON = this.geoJsons //添加点数据源 map.addSource('point-source', pointGeoJSON); //添加点图层 map.addLayer({ "id": "point-layer", //图层ID "type": "symbol", //图层类型 "source": 'point-source', //数据源 "layout": { "icon-image": ['get','icon'], //获取properties icon 图片 "icon-size": 0.5, //图片大小 } }); this.popups() }, popups(){ let map = this.map //弹出信息框 var popup = new GeoGlobe.Popup({ closeButton: true, //显示关闭按钮 closeOnClick: true //点击地图其他地方也可以关闭弹窗 }); //点击弹出框 map.on('click', function (e) { var bbox = [//设置容差,使点变成一个范围,方便操作获取到对应的信息 [e.point.x - 10, e.point.y - 10], [e.point.x + 10, e.point.y + 10] ]; var features = map.queryRenderedFeatures(bbox, { layers:["point-layer"] }); if(features.length>0){ var coordinates = features[0].geometry.coordinates.slice(); this.jd = coordinates[0] this.wd = coordinates[1] //设置中心点 map.setCenter(new GeoGlobe.LngLat(this.jd, this.wd),11); popup.setLngLat(coordinates) .setHTML('<div class="wrap" >' + ' <label class="st" >' + ' <span class="st_title" onclick="sss(this)" >项目信息</span>' + ' <input type="radio" name="tab" checked>' + ' <div>' + '<p align="left" ><span class="st_title_spot" ></span><strong>项目名称</strong>' + '<span class="st_title_spot2" >'+features[0].properties.xmmc+'</span>' + '</p>' + '</div>' + ' </label>' + ' <label class="st" >' + ' <span class="st_title" onclick="sss(this)" >项目流程信息</span>' + ' <input type="radio" name="tab">' + ' <div>' + '</div>' + ' </label>' + '</div>') .addTo(map); } }) }, }, mounted(){ this.init() } } </script> <style scoped> </style>
在第三步中,比第二步又多了一个方法popups,在popups中通过new GeoGlobe.Popup会创建弹窗,弹窗中有两个属性
closeButton: true, //弹框中显示关闭按钮
closeOnClick: true //点击地图其他地方也可以关闭弹窗
点击出弹窗的主要方法是 map.on('click', function (e) {}),点击落点图标会进入这个方法,在这个方法中通过var features = map.queryRenderedFeatures(bbox, { layers:["point-layer"] }); 其中point-layer是图层ID,获取当前
点击的图层ID的数据也就是 上文geoJsons中的properties中的数据;
map.setCenter(new GeoGlobe.LngLat(this.jd, this.wd),11); 是根据经纬度将所点击的落点图标设为地图中心点,并设置显示级别。
popup.setLngLat(coordinates) .setHTML()是就是所显示的弹窗中的内容。这个最好先在页面上画出来再移到setHtml()中,不然在setHtml调样式比较麻烦。
以上就专题二落点展示图片并弹窗的所有代码,效果图如下: 专题三将展示如何在地图上落多个面,点击并弹窗。