ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

高德3D动态地图—旋转视角

2021-06-15 15:59:42  阅读:391  来源: 互联网

标签:obj 示例 动态地图 transform var webkit translate 高德 3D


做这个动态效果之前,大家可以了解下高地的官方示例(https://lbs.amap.com/demo/loca-v2/demos/cat-view-control/view-control)高德提供了镜头旋转的官方示例,但是镜头旋转没有说明,而且存在bug,调整speed速度后整个场景就乱了,因为我能力有限而且比较懒,所以我开始自己写动画。

地图使用2.0的版本(http://webapi.amap.com/maps?v=2.0),之前使用1.4.3的版本在旋转是存在周边空白,又没找到刷新的方法,所以使用当前最新的2.0版本。将整个动画划分为四步:

第一步,加载,2.0版本首次加载时如果不预留加载时间,地图标记点不会显示。判断是否首次加载,首次加载不旋转,非首次旋转

第二步,调整视角到2D视角

第三步,2D视角进行旋转一定时间

第四步,重新旋转回到3D视角

这四步需要处理的几个问题:

1、通过requestAnimationFrame方法循环处理每一帧的动画。

2、控制FPS(每秒帧数),防止帧数太高,电脑发热

3、处理旋转一周后,高德反转导致的回放

下面是示例代码,有兴趣自己看吧(把key替换成自己的

<script src="http://webapi.amap.com/maps?v=2.0&key=改成自己的&plugin=Map3D,AMap.DistrictLayer,AMap.DistrictSearch,AMap.Scale,AMap.ToolBar"></script>
<script src="http://webapi.amap.com/loca?v=2.0.4&key=改成自己的"></script>

<html>
<head>
    <title>牟云飞示例</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta id="viewport" name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0"/>

    <link type="text/css" rel="styleSheet"  href="css/fatterStyle3D.css" />
    <style>

        .infowindow_custom_geo{


        }
        .infowindow_custom_geoContent{
            display: flex;
            flex-direction:column;
            justify-content: center;/*实现水平居中*/
        }
        .infowindow_custom_geoContent_fontcolor{
            color:RGB(21,253,255);
            height: 30px;
        }

        /*从左到右进入*/
        .fadeInLeft {
            animation: fadeInLeft 0.8s ;
            -webkit-animation: fadeInLeft 0.8s ;
        }
        @keyframes fadeInLeft
        {
            from {
                opacity: 0;
                -webkit-transform: translate(-1000px,0);
                transform: translate(-1000px,0);
            }
            to {
                opacity:1;
                -webkit-transform: translate(10px,0);
                transform: translate(10px,0);
            }
        }

        @-webkit-keyframes fadeInLeft
        {
            from {
                opacity:0;
                -webkit-transform: translate(-1000px,0);
                transform: translate(-1000px,0);
            }
            to {
                opacity:1;
                -webkit-transform: translate(10px,0);
                transform: translate(10px,0);
            }
        }

        /*从右到左进入*/
        .fadeInRight {
            animation: fadeInRight 0.8s ;
            -webkit-animation: fadeInRight 0.8s ;
        }
        @keyframes fadeInRight
        {
            from {
                opacity: 0;
                -webkit-transform: translate(1000px,0);
                transform: translate(1000px,0);
            }
            to {
                opacity:1;
                -webkit-transform: translate(10px,0);
                transform: translate(10px,0);
            }
        }

        @-webkit-keyframes fadeInRight
        {
            from {
                opacity:0;
                -webkit-transform: translate(1000px,0);
                transform: translate(1000px,0);
            }
            to {
                opacity:1;
                -webkit-transform: translate(10px,0);
                transform: translate(10px,0);
            }
        }



    </style>
</head>
<body>
<div id="topDiv" >
    <div id="containerMap"></div>
</div>
<script src="http://webapi.amap.com/maps?v=2.0&key=改成自己的&plugin=Map3D,AMap.DistrictLayer,AMap.DistrictSearch,AMap.Scale,AMap.ToolBar"></script>
<script src="http://webapi.amap.com/loca?v=2.0.4&key=改成自己的"></script>


<script type="text/javascript">

    var myMap_zhdp;
    var box_zhdp, network_zhdp, baiduMap_zhdp;
    var node_colors = ['#259B24','#2DC1B4','#FF9800','#005E7D','#BF2DC1','#FF0000','#6184F0'];
    var layer = null;//撒点
    var markers = [];
    var mapDataArr = [];


    var initData = {
        "parameters": {
            "mapData": {
                "greenhouse": [
                    {
                        "latitude": "36.793139",
                        "longitude": "118.682124",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    },
                    {
                        "latitude": "36.90723878",
                        "longitude": "118.86398011",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "scenicspot": [
                    {
                        "latitude": "37.070134",
                        "longitude": "118.696025",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "livestockCultivation": [
                    {
                        "latitude": "36.972933",
                        "longitude": "118.89215",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "seafoodCultivation": [
                    {
                        "latitude": "37.186281",
                        "longitude": "118.751003",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "heating": [
                    {
                        "latitude": "36.801139",
                        "longitude": "118.830124",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "fruitProcessing": [
                    {
                        "latitude": "36.861139",
                        "longitude": "118.680124",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ],
                "zhxxInfo": [
                    {
                        "latitude": "36.791139",
                        "longitude": "118.680124",
                        "info": {
                            "name": "牟云飞示例1",
                        }
                    }
                ]
            }
        },
        "dataWraps": { },
        "errorMessage": "",
        "message": "",
        "exportFileName": null,
        "currentDataWrap": "dataWrap",
        "exportColumns": null,
        "metaData": null
    }




    var obj =initData.parameters.mapData;

    function initMap(obj){
        console.log("obj:",obj);
        myMap_zhdp = new AMap.Map("containerMap", {
            viewMode: '3D',
            mapStyle: 'amap://styles/90287222547b179fcbda2e63865f2f5c',
            showBuildingBlock: true,
            //center: [118.848014,36.885728],
            center: [118.848014,37.085728],
            pitch: 80,
            zoom: 11,
//            layers: [
//                // 卫星
//                new AMap.TileLayer.Satellite(),
//                // 路网
//                new AMap.TileLayer.RoadNet()
//            ]
        });
        //为地图注册click事件获取鼠标点击出的经纬度坐标
        myMap_zhdp.on('click', function(e) {
            console.log(e.lnglat.getLng() + ',' + e.lnglat.getLat());
        });

        //创建区域
        createArea();
        //散点
        layer = new AMap.LabelsLayer({
            zooms: [3, 20],
            zIndex: 1000,
            // 开启标注避让,默认为开启,v1.4.15 新增属性
            collision: false,
            // 开启标注淡入动画,默认为开启,v1.4.15 新增属性
            animation: true,
        });
        addnodes(obj.greenhouse,0);
        addnodes(obj.scenicspot,1);
        addnodes(obj.livestockCultivation,2);
        addnodes(obj.seafoodCultivation,3);
        addnodes(obj.heating,4);
        addnodes(obj.fruitProcessing,5);
        var zhxxInfo = obj.zhxxInfo;
        addnodes(zhxxInfo,6);

        myMap_zhdp.add(layer);



        myMap_zhdp.on('complete', function () {
            //地图加载完成后

            render();
        });
    }

    //添加地图节点
    function addnodes(obj,index) {
        if(obj==null) return;
        for(var i=0;i<obj.length;i++){
            var curData = {
                name: obj[i].info.name,
                position: [obj[i].longitude, obj[i].latitude],
                zooms: [3, 20],
                opacity: 1,
                zIndex: 10,
                icon: {
                    type: 'image',
                    image: '../images/mapImages/poi-marker.png',
                    clipOrigin: [14, 92],
                    clipSize: [50, 68],
                    size: [25, 34],
                    anchor: 'bottom-center',
                    angel: 0,
                    retina: true
                },
                text: {
                    content: obj[i].info.name,
                    direction: 'left',
                    offset: [0, -5],
                    style: {
                        fontSize: 15,
                        fontWeight: 'normal',
                        fillColor: node_colors[index],
                        strokeColor: '#fff',
                        strokeWidth: 2,
                    }
                }
            };
            //console.log("-----------obj:",obj);

            var labelMarker = new AMap.LabelMarker(curData);
            markers.push(labelMarker);
            mapDataArr.push(obj[i]);
            //console.log("-----------labelMarker:",labelMarker);
            layer.add(labelMarker);
        }
    }

    //划分区域
    var district = null;
    var polygons=[];
    function createArea() {
        if(!district){
            //实例化DistrictSearch
            var opts = {
                subdistrict: 0,   //获取边界不需要返回下级行政区
                extensions: 'all',  //返回行政区边界坐标组等具体信息
                level: 'district'  //查询行政级别为 市
            };
            district = new AMap.DistrictSearch(opts);
        }
        //行政区查询
        district.search("寿光市", function(status, result) {
            myMap_zhdp.remove(polygons)//清除上次结果
            polygons = [];
            var bounds = result.districtList[0].boundaries;
            if (bounds) {
                for (var i = 0, l = bounds.length; i < l; i++) {
                    //生成行政区划polygon
                    var polygon = new AMap.Polygon({
                        strokeWeight: 1,
                        path: bounds[i],
                        fillOpacity: 0.2,
                        fillColor: '#80d8ff',
                        strokeColor: '#0091ea'
                    });
                    polygons.push(polygon);
                }
            }
            myMap_zhdp.add(polygons);
        });
    }




    /**
     * -----------------------------
     * 动画事件,时钟
     * -----------------------------
     */
    class fatterClock {
        constructor( autoStart ) {
            this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
            this.startTime = 0;
            this.oldTime = 0;
            this.elapsedTime = 0;
            this.running = false;
        }
        start() {
            this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
            this.oldTime = this.startTime;
            this.elapsedTime = 0;
            this.running = true;
        }
        stop() {
            this.getElapsedTime();
            this.running = false;
            this.autoStart = false;
        }
        getElapsedTime() {
            this.getDelta();
            return this.elapsedTime;
        }
        getDelta() {
            let diff = 0;
            if ( this.autoStart && ! this.running ) {
                this.start();
                return 0;
            }
            if ( this.running ) {
                const newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
                diff = ( newTime - this.oldTime ) / 1000;
                this.oldTime = newTime;
                this.elapsedTime += diff;
            }
            return diff;
        }
    }

    /**
     * -----------------------------
     * 动画事件
     * -----------------------------
     */
    var mapStep = 0;
    var waitTime = 90;
    var curWaitTime = 0;
    var isFirst = true ;//判断是否第一次加载,第一次加载进入等待期,防止一开始不加载图层
    var mapRotationInitControl = false;//判断是否开启回正旋转角度模式,如果超过360度,高德不会继续顺时针旋转,高德会逆时针旋转到0
    function mapAnimate(map,callbackParam,beginPoi,endPoi){

        //动画前关闭展示框
        //hideInfoWindow();


        var _curPitch = map.getPitch();
        var _curZoom = map.getZoom();
        var _curRotation = map.getRotation();

        var _pitchSpeed = 0.5;
        var _zoomSpeed = 0.02;
        var _rotationSpeed = 0.1;

        //进入等待期,防止一开始不加载图层
        if(mapStep == 0 ){
            /* if(curWaitTime<=waitTime){
             curWaitTime = curWaitTime + 1;
             }else{
             mapStep = 1;
             curWaitTime = 0;
             isFirst = false;
             }
             if(isFirst == false){
             map.setRotation((_curRotation + _rotationSpeed)%360);
             } */


            curWaitTime = curWaitTime + 1;


            //如果超过360度,高德不会继续顺时针旋转,高德会逆时针旋转到0
            if(isFirst == false&&(_curRotation + _rotationSpeed)<360 && mapRotationInitControl==false){
                map.setRotation((_curRotation + _rotationSpeed)%360);
            }else if(isFirst == false){
                map.setRotation((_curRotation - _rotationSpeed*6)%360);
                mapRotationInitControl = true;//开启旋转角度回正控制
            }
            //开启角度回正模式后,判断是否已经回正旋转角度
            if(mapRotationInitControl==true&&_curRotation<10){
                mapRotationInitControl = false;
            }

            if(curWaitTime>waitTime&&mapRotationInitControl==false){
                mapStep = 1;
                curWaitTime = 0;
                isFirst = false;
            }
        }

        //第一阶段,回2d地图
        if(mapStep==1){
            //回正地图
            let _flag = 3;
            if(_curPitch>1){
                map.setPitch(_curPitch - _pitchSpeed);
                _flag = _flag - 1;
            }
            //缩小尺寸
            if(_curZoom>10){
                map.setZoom(_curZoom - _zoomSpeed);
                _flag = _flag - 1;
            }
            //if(_curRotation<20){
            //map.setRotation((_curRotation + _rotationSpeed)%360);
            //_flag = _flag - 1;
            //}
            map.setCenter([118.848014,36.985728]);
            if(_flag == 3){
                //进入下一阶段
                mapStep = 2;
            }
        }

        //进入等待期
        if(mapStep == 2 ){

            curWaitTime = curWaitTime + 1;


            //如果超过360度,高德不会继续顺时针旋转,高德会逆时针旋转到0
            if(isFirst == false&&(_curRotation + _rotationSpeed)<360 && mapRotationInitControl==false){
                map.setRotation((_curRotation + _rotationSpeed)%360);
            }else{
                map.setRotation((_curRotation - _rotationSpeed*6)%360);
                mapRotationInitControl = true;//开启旋转角度回正控制
            }
            //开启角度回正模式后,判断是否已经回正旋转角度
            if(mapRotationInitControl==true&&_curRotation<10){
                mapRotationInitControl = false;
            }

            if(curWaitTime>waitTime&&mapRotationInitControl==false){
                mapStep = 3;
                curWaitTime = 0;
            }

        }


        //回到3D地图
        if(mapStep == 3 ){

            let _flag = 3;
            if(_curPitch<=75){
                map.setPitch(parseFloat(_curPitch + _pitchSpeed));
                _flag = _flag - 1;
            }
            //缩小尺寸
            if(_curZoom<=11.5){
                map.setZoom(parseFloat(_curZoom + _zoomSpeed*3));
                _flag = _flag - 1;
            }

            //如果超过360度,高德不会继续顺时针旋转,高德会逆时针旋转到0
            if(isFirst == false&&(_curRotation + _rotationSpeed*10)<360 && mapRotationInitControl==false){
                map.setRotation((_curRotation + _rotationSpeed*10)%360);
            }else{
                map.setRotation((_curRotation - _rotationSpeed*20)%360);
                mapRotationInitControl = true;//开启旋转角度回正控制
            }
            //开启角度回正模式后,判断是否已经回正旋转角度
            if(mapRotationInitControl==true&&_curRotation<10){
                mapRotationInitControl = false;
            }

            if(_flag == 3&&mapRotationInitControl==false){
                mapStep = 0;
            }


        }

    }


    //渲染
    var timeInteval = 200; //20为1秒,浏览器不同,事件不一定,用于地图
    var curTimeInteval = 20;//,用于地图
    var curGeoPoint = 0;//,用于地图

    var clock = new fatterClock();
    var timeS = 0;//控制间隔时间
    var FPS = 60;
    var renderT = 1 / FPS; //单位秒  间隔多长时间渲染渲染一次
    function render(){
        let T = clock.getDelta()
        timeS = timeS + T;
        if (timeS > renderT) {

            //整个场景动起来
            if(null!=myMap_zhdp&&null!=mapDataArr&&0!=mapDataArr.length){
                if(curTimeInteval>=timeInteval){
                    curTimeInteval = 0;//重置
                    curGeoPoint++;
                    if(curGeoPoint>=mapDataArr.length){
                        curGeoPoint = 0;
                    }
                }
                //getPosition( )
                var _temp = mapDataArr[curGeoPoint];
                //console.log("++++++_temp:",_temp);
                //场景动画
                mapAnimate(
                        myMap_zhdp,
                        {
                            'curId': _temp.info.code,
                            'curCustomObj_center': new AMap.LngLat( _temp.longitude,_temp.latitude),
                            'customObj_height': -_temp.info.greenHouseCount
                        },null,new AMap.LngLat( _temp.longitude,_temp.latitude)
                );

            }
            curTimeInteval++;

            //控制渲染的帧数
            timeS = 0;
        }

        //动画
        requestAnimationFrame(render);

    }


    initMap(obj);

</script>
</body>
</html>

 

标签:obj,示例,动态地图,transform,var,webkit,translate,高德,3D
来源: https://blog.csdn.net/myfmyfmyfmyf/article/details/117924319

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有