vue 高德地图Loca.GeoJSONSource、Loca.PolygonLayer绘制3D楼房、AMap.LabelMarker文字标注、Loca.ScatterLayer绘制水波扩散效果

这篇具有很好参考价值的文章主要介绍了vue 高德地图Loca.GeoJSONSource、Loca.PolygonLayer绘制3D楼房、AMap.LabelMarker文字标注、Loca.ScatterLayer绘制水波扩散效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

创建地图

假设已经正确引入了高德地图,这里使用2.0版本,注意了,1.4.x版本的使用和2.x版本的使用方式不一样。有很多地方不兼容哦。

话说3D效果这一块,高德是真比不上百度地图哦,要不是项目一直用的高德地图,怕影响数据,就真想换百度地图了。百度地图有很多地方,地级市县都有3D效果了,但是高德没有。高德只有省会城市有3D楼

引入高德地图还需要加上Loca版本,plugin插件里面也要包含Map3D插件。可以参考这里 [vue 使用amap-jsapi-loader加载高德地图]
然后我们创建地图。注意这次我们是要绘制3D楼房,所以初始化地图时必须指定 viewMode: ‘3D’

这里还加个小小的效果,旋转地图动画

友情提醒:水波效果图,高德地图里面叫呼吸图,不知道是哪位大佬起的名字。话说叫水波纹不是更形象吗?叫呼吸图,真的想不出来是者效果。

<template>
    <div>
        <el-switch v-model="isRotate" active-color="#FC982A" @change="rotateChange"/>
        <div class="amap" id="amap"></div>
    </div>
</template>
<script>
import reqMapList from '../../../api'
import transparentImg from '../../assets/transparent.svg'
import {mapState} from 'vuex'
import texture from "../../assets/images/breath_red.png";
    export default{
        data(){
            return{
                 center:[116.438202,40.138265],
                 isRotate: false,//是否旋转
                 }
        },
        computed:{
            ...mapState(['lngLatArr'])
        },
          mounted() {
            if(window.AMap && window.Loca){
              this.loadMap()
              return
            }
            this.awaitAmapLoading()
          },
          methods: {
          //定时加递归,确保有AMap和Local实例后再加载地图
            awaitAmapLoading(){
              let interval=setInterval(()=>{
                if(window.AMap&& window.Loca){
                  clearTimeout(interval)
                  this.loadMap()
                }
              },500)
            },
            async loadMap() { // 加载地图 需要在挂载后
              let {center} = this
              let map = new AMap.Map('amap', {
                center,
                zooms: [2, 20],
                zoom: 16,
                viewMode: '3D',
                pitch: 50,
                rotation: 35,
              })
              let loca = new Loca.Container({
                map,
              })
              map.setRotation(395,false,4000)
              this.map = map           
              let {mapAllList} = await reqMapList ()
              this.add3DBuild(loca) //绘制3d楼函数
              this.drawRipple(loca, mapAllList) //绘制水波
              this.addLabelMarker(mapAllList)//绘制文字标注
            },
            //旋转切换
            rotateChange(value) {
              let {map} = this
              if (!value) {
                clearInterval(this.mapInterval)
                let rotate = map.getRotation()
                let remainderRotate = (rotate - 35) % 360
                let backRotate = rotate - remainderRotate
                map.setRotation(backRotate,false,8000*remainderRotate/360)
                return
              }
              let n=0
              map.setRotation(map.getRotation()+395,false,8000)
              let currentRotation=map.getRotation()+395
              this.mapInterval=setInterval(()=>{
                n++
                map.setRotation(currentRotation+395*n,false,8000)
              },8000)       
            },
            addLabelMarker(mapAllList){
              let icon = {
                // 图标类型,现阶段只支持 image 类型
                type: 'image',
                // 图片 url
                image: transparentImg,
                // 图片尺寸
                size: [30, 30],
                // 图片相对 position 的锚点,默认为 bottom-center
                anchor: 'center',
              }
              let text = {
                // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
                direction: 'right',
                // 在 direction 基础上的偏移量
                // 文字样式
                style: {
                  // 字体大小
                  fontSize: 12,
                  // 字体颜色
                  fillColor: '#248BFE',
                }
              }
              this.addLabelMarker(mapAllList,icon,text)
            },
        //添加3d建筑物
            add3DBuild(loca){
                let {lngLatArr}=this
                let features=lngLatArr.reduce((result,current)=>{
                    result.push({
                        "type": "Feature",
                        "geometry": {
                            "type": "Polygon",
                            "coordinates": [
                                current
                            ]
                        }
                    })
                    return result
                },[])
                loca.pointLight = {
                    color: 'rgb(100,100,100)',
                    position: [112.053413,27.778557, 200],
                    intensity: 3,
                    // 距离表示从光源到光照强度为 0 的位置,0 就是光不会消失。
                    distance: 50000,
                }
                let geo = new Loca.GeoJSONSource({
                    data:{
                        "type": "FeatureCollection",
                        features
                    }
                })
                let pl = new Loca.PolygonLayer({
                    zIndex: 120,
                    opacity:1,
                    shininess: 10,
                    hasSide: true,
                })
                pl.setSource(geo)
                pl.setStyle({
                    topColor:'#dddddd',
                    sideColor: '#cccccc',
                    height:300,
                    altitude: 1,
                })
                loca.add(pl)
            },
            //绘制波纹
            drawRipple(loca,mapAllList){
                let geoFeatures=mapAllList.reduce((result,current)=>{
                    let {lon,lat,address}=current
                    if(lon && lat){
                        result.push({
                            "type": "Feature",
                            "geometry": {
                                "type": "Point",
                                "coordinates": [lon, lat]
                            },
                            "properties": {
                                "name": address,
                            }
                        })
                    }
                    return result
                },[])
                let geoLevelF = new Loca.GeoJSONSource({
                    data: {
                        "type": "FeatureCollection",
                        "features":geoFeatures
                    },
                })
                let breathRed = new Loca.ScatterLayer({
                    loca,
                    zIndex: 9130,
                    opacity: 1,
                    visible: true,
                    zooms: [2, 22],
                })
                breathRed.setSource(geoLevelF)
                breathRed.setStyle({
                    unit: 'meter',
                    size: [100, 100],
                    borderWidth: 0,
                    texture,//动画图片,后面会做说明
                    duration: 500,
                    animate: true,
                })
                // 启动渲染动画
                loca.animate.start()
            },
            //添加文字标注
            addLabelMarker(mapAllList,icon,text){
                let labelsMarkerArr=mapAllList.reduce((result,current)=>{
                    let {name,lon,lat}=current
                    if(lon && lat){
                        let labelMarker = new AMap.LabelMarker({
                            name: name, // 此属性非绘制文字内容,仅最为标识使用
                            position: [lon, lat],
                            zIndex: 16,
                            // 将第一步创建的 icon 对象传给 icon 属性
                            icon,
                            // 将第二步创建的 text 对象传给 text 属性
                            text:{
                                ...text,
                                content:name
                            },
                        })
                        labelMarker.on('click', function(e){
                           console.log(e)
                        })
                        result.push(labelMarker)
                    }
                    return result
                },[])

                let labelsLayer = new AMap.LabelsLayer({
                    zooms: [3, 20],
                    zIndex: 1000000,
                    // 该层内标注是否避让
                    collision: true,
                    // 设置 allowCollision:true,可以让标注避让用户的标注
                    allowCollision: true,
                })
                // 批量添加 labelMarker
                labelsLayer.add(labelsMarkerArr)
                this.map.add(labelsLayer)
            }
          },
          beforeDestroy() {
            clearInterval(this.interval)
            clearInterval(this.mapInterval)
            this.map=null
          }
    }
</script>

这里说下lngLatArr的数据结构,这是楼房的经纬度,由于是自定义画的,因此需要自己去获取。

获取有一点规则,首先要顺时针获取四个点,然后需要画闭环的楼房,所以第五个点和第一个点是同一个坐标。

lngLatArr是一个三维数组。说道这里真忍不住吐槽下高德地图的文档,反正我没找到有关于数据结构的说明,做的时候全靠猜,靠试。

如果自己项目里没有配置有逝去经纬度的页面,可以搜索高德地图拾取经纬度,去高德地图相关页面获取,页面地址 https://lbs.amap.com/tools/picker

示例结构如下:

 blLngLatArr:Object.freeze([
        [
            [116.42095,40.138003],
            [116.445755,40.14148],
            [116.422666,40.131703],
            [116.441549,40.126584],
            [116.42095,40.138003],
        ],
        [
            [116.463093,40.144236],
            [116.476139,40.144761],
            [116.465668,40.140234],
            [116.476396,40.140168],
            [116.463093,40.144236],
        ],   
    ]),

绘制水波纹最后一定要启动动画,即loca.animate.start(),奇怪的是,不加这行也有动画,只不过,这动画怪怪的,运行两下就不动了。

texture 是动画图片,这里绘制的水波纹图效果,实际上是不断变化图片的位置形成的。我这里直接用了官方的示例图片,如下!

breath_red.png

优化

虽然这样是可以了,但是你会发现,切换页面以后,再切换回来,3D图没有了,水波图也没有了!!
这已经是一个很严重的bug了,但是官方问答貌似没有很明确的说明。

原因是:loca实例只能创建一个,虽然这里创建loca实例时只是使用了局部变量,但是高德地图生成了全局的loca实例。当我们切换页面再切回来时,又去创建一个实例,这时就有两个了,然后就是看到的效果,图出不来。

最终的解决方案是,当前页面离开时,销毁loca实例。销毁不是直接置为Null就可以,而是要调loca的destroy方法。

然后说下水波纹图,同样是,需要移除水波纹图层,不然会报错:cannot read property ‘getZoom’ of null。

最终解决方案如下:
先将loca和breathRed挂载到this上,然后销毁他们文章来源地址https://www.toymoban.com/news/detail-857837.html

 beforeDestroy(){
    this.loca.remove(this.breathRed)
    this.loca.destroy()
 }

到了这里,关于vue 高德地图Loca.GeoJSONSource、Loca.PolygonLayer绘制3D楼房、AMap.LabelMarker文字标注、Loca.ScatterLayer绘制水波扩散效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 高德地图自定义绘制园区区域,区域描边,并添加自定义内容maker标注

    高德地图自定义绘制园区区域,区域描边,并添加自定义内容maker标注

    绘制自定义区域第一步需要获取指定区域的边界坐标点list,可以在高德地图官网的工具中获取 高德选点工具,拿到区域边界点list后就是绘制,区域绘制有几种方式,具体可查看高德的API,大体可用Wall和Prism两种方式,区别是wall没有区域填充颜色,Prism可以填充,所以我选择

    2024年02月12日
    浏览(29)
  • Axure中利用JSBOX制作3D高德地图组件

    Axure中利用JSBOX制作3D高德地图组件

    JSBOX 是一个面向 Axure 提供便捷开发方式的组件,我们将用它来制作可以显示三维白模的高德地图组件,下面是制作步骤,可以先 点击此处预览效果 将JSBOX标准版组件拖进Axure,可以见到JSBOX的载体就是一个空白的中继器: 注:不想了解代码的童鞋请到文末直接下载完成后的

    2024年02月05日
    浏览(7)
  • 【微信小程序】微信小程序集成高德卫星地图完成多边形绘制与截图保存

    【微信小程序】微信小程序集成高德卫星地图完成多边形绘制与截图保存

    目录 功能需求 使用的技术点 注意点 实现步骤 代码 微信小程序-地图所在的wxml 微信小程序-地图所在的js 微信小程序-展示截图结果的wxml 微信小程序-展示截图结果的js H5-地图所在的html 完成效果  参考文档 感谢阅读,欢迎讨论 打开页面展示卫星地图,用户自行在地图上绘制

    2024年02月06日
    浏览(392)
  • 高德地图系列(三):vue项目利用高德地图实现地址搜索功能

    高德地图系列(三):vue项目利用高德地图实现地址搜索功能

    目录 第一章 效果图 第二章 源代码 高德地图为我们提供了搜索联想,以及搜索结果标记,该案例已将基础功能打通,后续我们肯定还会对功能有所修改,想实现自己想要的效果,基本上看高德地图文档对着改就好了(跟我们用别的工具一样做即可)  代码描述如下:  注意事

    2024年02月03日
    浏览(7)
  • Vue 引入高德地图:实现地图展示与交互

    本文将介绍如何在Vue项目中引入高德地图,以及如何实现地图的展示和交互功能。我们将从安装依赖开始,然后配置高德地图的密钥和相关插件,最后演示如何在Vue组件中使用地图组件和实现基本的交互功能。通过本文的指导,您将能够轻松地在Vue项目中集成高德地图,实现

    2024年02月08日
    浏览(11)
  • vue引入高德地图

    1.首先index.html引入   2.引入并插入坐标点

    2024年02月13日
    浏览(7)
  • 【Vue】集成高德地图

    【Vue】集成高德地图

    注册成为高德开发者 获取申请的安全密钥、申请好的Web端开发者Key 创建Vue 工程 创建地图组件 引入地图组件 首先创建一个vue工程 安装 创建地图组件 将代码中的xx 替换成你的安全密钥和Web端开发者Key 引入地图组件 测试预览

    2024年02月11日
    浏览(13)
  • 在vue中引入高德地图

    在vue中引入高德地图

    既然要用到高德地图首先要申请成为高德地图开发者,并申请使用高德地图的key 这两点在这篇文章就不过多赘述,有需要的小伙伴可以查查资料,或者去高德地图api官网都有很详细的介绍。高德地图官网 简单提一下申请秘钥流程(web端) 控制台–应用管理–我的应用 好啦!

    2024年02月04日
    浏览(13)
  • vue项目中使用高德地图

    vue项目中使用高德地图

    最近做的项目中有个地图选择的功能,如下图所示: 所以在此记录下使用方法,望各位大神指导 我的应用 | 高德控制台 第一步: 去高德官网去创建一个属于自己的地图应用 (得到key和秘钥) 我的应用 | 高德控制台  这是添加的方式: 准备-入门-教程-地图 JS API | 高德地图

    2024年02月07日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包