Vue项目嵌入天地图专题二:在天地图上添加自定义图片,点击图片居中可以弹框并显示对应数据

专题一讲了如何将天地图加载进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调样式比较麻烦。

以上就专题二落点展示图片并弹窗的所有代码,效果图如下:  专题三将展示如何在地图上落多个面,点击并弹窗。

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要在地图添加弹框,你可以使用Vue.js和一些流行的地图API(如Google Maps API或Mapbox)来实现。下面是一个简单的示例: 首先,在Vue组件中,你需要引入地图API并创建地图对象: ```javascript import {mapState} from 'vuex'; import * as mapboxgl from 'mapbox-gl'; export default { data() { return { map: null, popup: null } }, mounted() { mapboxgl.accessToken = 'YOUR_ACCESS_TOKEN'; this.map = new mapboxgl.Map({ container: this.$refs.mapContainer, style: 'mapbox://styles/mapbox/streets-v11', center: [-96, 37.8], zoom: 3 }); }, computed: { ...mapState(['markers']) } } ``` 在上面的代码中,我们创建了一个Mapbox地图,并将其挂载到Vue组件的DOM元素中。我们还定义了一个`popup`变量,用于存储弹出窗口对象。 接下来,我们可以在地图添加标记,并在用户点击标记时显示弹出窗口: ```javascript mounted() { // ... this.markers.forEach(marker => { const el = document.createElement('div'); el.className = 'marker'; el.style.backgroundImage = `url(${marker.icon})`; const popup = new mapboxgl.Popup({ offset: 25 }) .setHTML(`<h3>${marker.title}</h3><p>${marker.description}</p>`); new mapboxgl.Marker(el) .setLngLat(marker.coordinates) .setPopup(popup) .addTo(this.map); }); }, ``` 在上面的代码中,我们遍历了一个名为`markers`的状态对象,并为每个标记创建一个HTML元素和一个弹出窗口。我们在地图上使用`mapboxgl.Marker`对象将标记添加地图中,并将弹出窗口与标记关联。当用户点击标记时,弹出窗口将显示。 最后,我们需要在Vue组件的模板中添加一个地图容器元素: ```html <template> <div class="map-container" ref="mapContainer"></div> </template> ``` 通过这些步骤,你就可以在Vue.js应用程序中向地图添加弹出窗口了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值