美文网首页让前端飞前端开发Vue.js开发技巧
基于nuxt和iview搭建OM后台管理系统实践(5)-高德地图

基于nuxt和iview搭建OM后台管理系统实践(5)-高德地图

作者: 小呆爱学习 | 来源:发表于2018-07-10 00:37 被阅读1次
    封面图,基于创客贴在线制作

    目录结构

    这是《基于nuxt和iview搭建OM后台管理系统实践》这一个系列文章的目录,大致思路如下:

    前言

    上几篇记录了几个功能比较简单的组件,本篇的高德地图封装遇到了蛮多坑,在此记录一下,避免后面再踩坑。

    说到地图组件,其实是其他项目组需要地图数据展示,然后我被借调到其他项目组,最终翻阅高德地图众多api后终于完成了。

    直接看东西

    高德地图组件展示

    本地数据原因,没有完整的展示地图组件功能,待去公司再截取动态图

    核心代码

    // 文件componets/amap-weather.vue
    
    <template>
        <div>
            <Form :model="searchForm" :label-width="190" inline>
                <FormItem label="地区">
                    <Select v-model="searchForm.crop" style="width:300px" @on-change="changeImage">
                        <Option v-for="item in crops" :value="item.title" :key="item.id">{{item.title}}</Option>
                    </Select>
                </FormItem>
            </Form>
            <div :id="id" :style="{'width':width,'height':height}"></div>
        </div>
    </template>
    
    
    <script>
        // import VeAmap from 'v-charts/lib/amap';
        import axios from "../plugins/axios";
    
        export default {
            name: "VAmap",
            data() {
                return {
                    weaherData: [],
                    weatherVoList: [],
                    arr: [],
                    polygons: [],
                    searchForm: {
                        crop: ''
                    },
                    crops: [],
                    latID: 124.298158,
                    lngID: 43.223817
                };
            },
            props: {
                id: {
                    default: "container"
                },
                width: {
                    default: "100%"
                },
                zoom: {
                    default: 15
                },
                height: {
                    default: "800px"
                },
                getlandRequestURL: {
                    default: ""
                },
                getgeoJsonURL: {
                    default: ""
                },
                getWeatherJsonURL: {
                    default: ""
                },
                getAreaData: {
                    default: ""
                }
            },
            head() {
                return {
                    script: [
                        {
                            src: "http://webapi.amap.com/maps?v=1.4.5&key=key自行去高德地图开发者中心申请&&plugin=AMap.ToolBar"
                        }
                    ]
                };
            },
            created: function () {
            },
            mounted() {
                var _this = this;
                if (process.browser) {
                    _this.initMap();
                    _this.getData();
                }
            },
            methods: {
                getData() {
                    var _this = this
                    axios.get(_this.getAreaData).then(res => {
                        this.crops = res.data.area
                    }).catch(error => {
                        console.log(error);
                    });
                },
                changeImage(e) {
                    var _this = this;
                    this.polygons = [];
                    axios.get(_this.getAreaData).then(res => {
                        var changeData = res.data.area
                        changeData.forEach(el => {
                            if (el.title == e) {
                                this.latID = el.point.lat;
                                this.lngID = el.point.lng
                                var _this = this;
                                this.initMap()
                            }
    
                        })
                    }).catch(error => {
                        console.log(error);
                    });
    
                },
                initMap() {
                    //地图初始化
                    var _this = this;
                    var googleLayer = new AMap.TileLayer({
                        getTileUrl: "http://mt{1,2,3,0}.google.cn/vt/lyrs=s&hl=zh-CN&gl=cn&x=[x]&y=[y]&z=[z]&s=Galile"
                    }); //定义谷歌卫星切片图层
                    var roadNetLayer = new AMap.TileLayer.RoadNet(); //定义一个路网图层
    
                    var map = new AMap.Map(this.id, {
                        resizeEnable: true,
                        center: [_this.latID, _this.lngID],
                        zoom: _this.zoom,
                        layers: [googleLayer, roadNetLayer] //设置图层
                    });
                    var toolBar = new AMap.ToolBar({
                        visible: true
                    });
                    map.addControl(toolBar);
                    // debugger;
                    // 初始化
                    var bounds = map.getBounds();
                    var northeast = bounds.Kb.lng + ',' + bounds.Kb.lat;
                    var northwest = bounds.Nb.lng + "," + bounds.Kb.lat;
                    var southwest = bounds.Nb.lng + ',' + bounds.Nb.lat;
                    var southeast = bounds.Kb.lng + ',' + bounds.Nb.lat;
    
                    var area = northeast + ";" + northwest + ";" + southwest + ";" + southeast + ";" + northeast
    
                    _this.loadLandData(area, map); //加载可视范围内的地块
    
                    map.on("moveend", function (e) {
                        //监听页面变化
                        //获取可视区域的经纬度
                        var getBounds = map.getBounds()
    
                        var bounds = map.getBounds();
                        var northeast = bounds.Kb.lng + ',' + bounds.Kb.lat;
                        var northwest = bounds.Nb.lng + "," + bounds.Kb.lat;
                        var southwest = bounds.Nb.lng + ',' + bounds.Nb.lat;
                        var southeast = bounds.Kb.lng + ',' + bounds.Nb.lat;
    
                        var area = northeast + ";" + northwest + ";" + southwest + ";" + southeast + ";" + northeast
    
                        _this.loadLandData(area, map); //加载可视范围内的地块
                    });
                },
    
                loadLandData(area, map) {
                    //根据当前区域经纬度获取地图区域的地块
                    let _this = this;
                    axios
                    // .get(_this.getlandRequestURL+"?area[]="+area)
                        .get(_this.getlandRequestURL + "?area[]=" + area)
                        .then(res => {
                            let list = res.data.data;
                            list.forEach(els => {
                                let obj = [];
                                let points = els.geometry.coordinates[0].points; //重新组装接口来的数据
                                points.forEach(el => {
                                    obj.push(el.coordinates);
                                });
                                _this.polygonShow(els.id, map, obj); //遍历经纬度并渲染到地图上
                            });
                        })
                        .catch(error => {
                            console.log(error);
                        });
                },
    
                polygonShow(id, map, obj) {
                    //渲染多边形和网格 判断地块是否是重新加载的
    
                    if (!this.polygons.find(p => p.toString() === id.toString())) {
                        //渲染多边形和网格
                        let polygonOpt = {
                            path: obj, //设置多边形边界路径
                            strokeColor: "#FF33FF", //线颜色
                            strokeOpacity: 0.2, //线透明度
                            strokeWeight: 3, //线宽
                            fillColor: "red", //填充色
                            fillOpacity: 0.4, //填充透明度
                            id: id,
                            points: obj
                        };
                        let polygon = new AMap.Polygon(polygonOpt);
                        polygon.setMap(map);
                        this.polygons.push(id);
                        this.polygonClick(map, polygon);
                    }
    
                },
                polygonClick(map, polygon) {
                    //点击地块获得格点数据
                    var _this = this;
                    polygon.on("click", function (e) {
                        let list = e.target.Ch.points;
                        let areas = "";
                        list.forEach(el => {
                            areas += el + ";";
                        });
                        _this.gridPolygonData(map, _this.removeLastCode(areas)); //加载geoJson
                    });
                },
                gridPolygonData(map, areas) {
                    //加载网格的数据并添加上点击事件
                    var _this = this;
                    axios
                        .get(_this.getWeatherJsonURL + "?point[]=" + areas)
                        .then(res => {
                            _this.weaherData = res.data.data;//获取所有天气信息
                            let list = res.data.data;
                       
                            let obj = [];
                            list.forEach(els => {
                                let points = els.gridPolygon.points; //重新组装接口来的数据
                                points.forEach(el => {
                                    obj.push(el.coordinates);
                                });
    
                                _this.gridPolygonShow(els.id, map, obj); //遍历经纬度并渲染到地图上
                            });
                        })
                        .catch(error => {
                            console.log(error);
                        });
                },
                // 地图上加载天气轨迹
                gridPolygonShow(id, map, obj) {
                    var polygon = new AMap.Polygon({
                        path: obj, //设置多边形边界路径
                        strokeColor: "#FF33FF", //线颜色
                        strokeOpacity: 0.2, //线透明度
                        strokeWeight: 3, //线宽
                        fillColor: "#ccc", //填充色
                        fillOpacity: 0.2, //填充透明度
                        id: id,
                        points: obj
                    });
    
                    polygon.setMap(map);//绘制地图
                    map.setZoomAndCenter(this.zoom, obj[0]); //重新设置地图中心点
                    this.gridPolygonClick(polygon);
    
                },
                // 点击地块触发的事件
                gridPolygonClick(polygon) {
                    var _this = this;
                    polygon.on("click", function (e) {
                        _this.loadWeatherData(e.target.Ch.id); //通过id得到当前的数据
    
                    });                
                },
    
                loadWeatherData(id) {
                    // 点击格点获取天气数据
                    // alert(id);
    
                    var _this = this;
                    let weatherVoList = [];
                    let weaherData2 =[];
    
                    weaherData2.push(_this.weaherData[0]);
    
                   weaherData2.forEach(els => {
                        if (els.id == id) {
    
                          weatherVoList=els.weatherForecastVoList;
    
                        }   
                    });
    
                    _this.$emit('loadWeather',weatherVoList);//把得到的天气数据暴露给父组件引用
                    // _this.dataEmpty = false;
                },
    
    
                removeLastCode(str) {
                    //去掉字符串最后一位
                    if (str == null || str == "" || str.length < 1) {
                        return str;
                    }
                    return str.substring(0, str.length - 1);
                }
            }
        };
    </script>
    
    <style scoped>
        .v-charts-data-empty {
            position: absolute;
            top: 0;
            left: 40%;
            font-size: 16px;
            top: 10%;
        }
    </style>
    
    
    

    使用方法:按照vue标准引用局部组件的方式引入即可,分别传入getlandRequestURL,getgeoJsonURL,getWeatherJsonURL,getAreaData地址。

    <template>
      <div class="body">
        <amap-weather
          getlandRequestURL="/data/getLand.json"
          getgeoJsonURL="/data/getLand.json"
          getWeatherJsonURL="/data/getweatherforgeo.json"
          getAreaData="/data/area.json"
        ></amap-weather>
      </div>
    </template>
    
    <script>
    import amapWeather from '../../components/amap-weather';
    export default {
      layout:'nav',
      components: {
        amapWeather
      },
      head() {
        return {
          title: "高德地图插件"
        };
      },
    }
    </script>
    
    <style>
    
    </style>
    
    

    总结

    • 在封装高德地图组件过程中遇到最大的一个坑:nuxt路由跳转到地图页面报错,最终的解决方案是在left-nav.vue跳转方法里做判断,如果路由路径为map就刷新页面,同时利用:active-name="menuName"属性展开左侧菜单;
    路由跳转报错展示
    • 另外一个坑就是服务端渲染带来的问题,最终在mounted生命周期函数中根据process做判断是浏览器端还是服务端并做相应的处理,如代码所示
    mounted() {
        var _this = this;
        if (process.browser) {
            _this.initMap();
            _this.getData();
        }
    }
    
    • 展示的气象数据需要用到echart图表展示,这一块时间限制并没有做很好的封装,导致代码太乱,后续有时间会做优化;
    乱得一批的代码
    • 另外对于组件命名也不规范,官方推荐用amap-weather.vue这种,在做这一块的总结的时候可以看到上面的代码改过来了;
    组件命名规范

    系列文章链接

    以下为本系列的文章合集,在此列出便于查阅:

    相关文章

      网友评论

        本文标题:基于nuxt和iview搭建OM后台管理系统实践(5)-高德地图

        本文链接:https://www.haomeiwen.com/subject/xkmxpftx.html