当前位置: 首页 > article >正文

uniapp 地图添加,删除,编辑标记,在地图中根据屏幕范围中呈现标记

前言

小程序实现新功能,在地图中选取位置添加标记,并在地图中呈现添加的标记,(呈现的是根据当前屏幕范围内的标记),并对标记进行分享,删除,编辑,导航,并从分享标记点位置打开页面的时候在呈现该标记的信息详情,

部分代码解释

scale:地图缩放级别
markers:标记点	
callouttap:标记点点击事件
markertap:markers内容的点击事件,就是自定义内容的点击事件
regionchange:推拽事件
regionchange - begin :拖拽开始事件
regionchange - end:拖拽结束事件
this.mapContext = uni.createMapContext("map", this); // 创建地图上下文
that.mapContext.getCenterLocation: 获取中心点位置
that.mapContext.getRegion : 获取后获取对角坐标
that.mapContext.getScale : 获取缩放级别

更多更详细地图上下文接口点击这里(uniapp官网,进去就是地图上下文相关)

uni.chooseLocation 和 uni.getLocation 使用的时候需要先声明
在这里插入图片描述

部分功能图片预览

声明:图片中内容为随机添加,内容也是胡乱写的

在这里插入图片描述

在这里插入图片描述

拖动地图,位置也会及时更新,选取添加的标记点位置
在这里插入图片描述

地图首页

添加修改标记页面和搜索页面就没必要放上来了,都是一些基础的样式和添加逻辑,根据个人情况写就行了,主要就是添加标记,(添加页面传递参数就是进度和纬度,有重要这两个数据就可以了),bijiaoInfos,就是分享和搜索页面传递过来的,根据id请求详情,拿到经纬度,把这个坐标定为中心点,再让地图重新加载,然后在自动弹出这个id的详情弹窗,就是示例的第二张图,通过搜索和分享进来看到的就是这个页面。

还有 - 记得点赞!!

<template>
    <view>
        <view class="search-box">
            <view class="search" @click="searchFocus">
                <text class="iconfont icon-sousuo-copy-copy"></text>
                <text>请输入搜索内容</text>
                <!-- <input type="text" v-model="search" @focus="searchFocus" placeholder="请输入搜索内容"> -->
            </view>
        </view>
        <view class="titleNum">
            当前区域标记数量为: {{ titleNum }}
        </view>
        <map id="map" class="map" style="width: 100%; height: 100vh;" :scale="scale" :latitude="latitude"
            :longitude="longitude" :markers="covers" @callouttap='mapAction' @markertap="mapAction"
            @regionchange="regionchange">
        </map>
        <uni-popup ref="popup" background-color="#fff">
            <view class="popup-content">
                <text @click="closePopup" class="iconfont icon-x"></text>
                <view class="popup-content-top">
                    <view>{{ bijiaoInfo.title }}</view>
                    <view>{{ bijiaoInfo.address }}</view>
                </view>
                <view class="popup-content-content">
                    <view class="popup-content-title">备注</view>
                    <view class="popup-content-text">{{ bijiaoInfo.bz }}</view>
                </view>
                <view class="popup-content-content">
                    <view class="popup-content-title">创建人</view>
                    <view class="popup-content-text">{{ bijiaoInfo.username }} - {{ bijiaoInfo.addtime }}</view>
                </view>
                <view class="popup-img">
                    <image @click="previewImage(index)" v-for="item, index in bijiaoInfo.picurls_path" :key="index"
                        :src="item" mode="scaleToFill" />
                </view>
                <view class="popup-bom">
                    <view class="popup-bom-left">
                        <view class="popup-bom-left-item del" @click="delBiaoJi">
                            <text class="iconfont icon-shanchu"></text>
                            <text>删除</text>
                        </view>
                        <button open-type="share" class="popup-bom-left-item">
                            <text class="iconfont icon-fenxiang"></text>
                            <text>分享</text>
                        </button>
                        <view class="popup-bom-left-item" @click="biaoJiSave">
                            <text class="iconfont icon-beizhu"></text>
                            <text>编辑</text>
                        </view>
                    </view>
                    <view @click="goNavigation" class="popup-bom-right">导航</view>
                </view>

            </view>
        </uni-popup>
        <uni-popup ref="alertDialog" type="dialog">
            <uni-popup-dialog type="error" cancelText="取消" confirmText="确定" title="提示"
                :content="'您确定要删除' + bijiaoInfo.title + '标记点吗?'" @confirm="dialogConfirm"></uni-popup-dialog>
        </uni-popup>
        <view @click="goMyLocation" class="iconfont icon-wodeweizhi"></view>
        <view class="gongNeng">
            <view class="gongNeng-item" @click="quanLanAction">
                <view class="iconfont icon-quanlan"></view>
                <view>全览</view>
            </view>
            <view class="gongNeng-item huadian" @click="biaoJiAction">
                <view class="iconfont icon-weizhi"></view>
                <view>画点</view>
            </view>
        </view>
    </view>
</template>

<script>

export default {
    data() {
        return {
            titleNum: 0,
            currentLocation: {},
            scale: 14,// 地图缩放级别
            id: null, // 
            title: 'map',
            // 地图中心点 为空 默认北京   
            latitude: null,
            longitude: null,
            covers: [],
            myLatitude: null,
            myLongitude: null,
            search: '',//搜索内容
            searchList: [],
            mapContext: '',//地图对象
            zuobiao: {},//拖拽坐标
            my_zuobiao: {},//我的坐标
            isMarking: false, // 标记模式开关
            centerMarker: null, // 中心点标记
            type: 'bottom',
            bijiaoInfo: {},
            currentPage: 1,
            totle_page: 0,
        }
    },
    onLoad(options) {
        console.log("options", JSON.parse(JSON.stringify(options)));
        if (options.id) {
            this.id = options.id;
            this.bijiaoInfos();
        }
        // this.biaojiIndex();
        uni.$on('callreload', () => {
            this.biaojiIndex();
        });
        this.getLocation();
        this.mapContext = uni.createMapContext("map", this); // 创建地图上下文
        this.getInitialFocusCoordinates(); // 获取首次屏幕对焦经纬度
    },
    onShow() {
        uni.getStorage({
            key: 'currentLocation',
            success: (res) => {
                this.currentLocation = res.data
            }
        })
        // latitude: 34.745982,郑州中心点
        // longitude: 113.658233, 
    },
    // 下拉刷新
    // onPullDownRefresh() {
    //     this.getInitialFocusCoordinates(); // 获取首次屏幕对焦经纬度
    //     uni.showToast({
    //         title: '刷新成功',
    //         icon: 'success',
    //         duration: 1000
    //     })
    //     uni.stopPullDownRefresh(); // 停止刷新	
    // },
    methods: {
        searchFocus() {
            uni.navigateTo({
                url: '/biaoji/searchBiaoJi'
            })
        },
        getLocation() {
            uni.getLocation({
                type: 'wgs84', // 获取经纬度坐标
                accuracy: 'high', // 请求高精度位置
                success: (res) => {
                    console.log("获取经纬度坐标", JSON.parse(JSON.stringify(res)));
                    // that.latitude =  parseFloat(res.latitude.toFixed(5));
                    // that.longitude =  parseFloat(res.longitude.toFixed(5));
                    this.latitude = parseFloat(res.latitude.toFixed(5));
                    this.longitude = parseFloat(res.longitude.toFixed(5));
                    this.myLatitude = parseFloat(res.latitude.toFixed(5));;
                    this.myLongitude = parseFloat(res.longitude.toFixed(5));;
                    this.covers = [{
                        id: 1,
                        latitude: res.latitude,
                        longitude: res.longitude,
                        iconPath: '../static/imgs/map/我的位置.png',
                        width: 25,
                        height: 25,
                        name: '我的位置',
                    }]
                },
                fail: (err) => {
                    console.error('获取位置信息失败', err);
                }
            });
        },
        // 分享过来传来的id 显示标记点详情
        async bijiaoInfos() {
            const res = await this.$axios("biaoji/biaojiInfo", {
                id: this.id,
            });
            console.log("标记地点详情", JSON.parse(JSON.stringify(res.data)));
            if (res.data.code == 0) {
                this.bijiaoInfo = res.data.result;
                const latitude = parseFloat(res.data.result.latitude)
                const longitude = parseFloat(res.data.result.longitude)
                this.mapContext.moveToLocation({
                    latitude: latitude.toFixed(5),
                    longitude: longitude.toFixed(5),
                    success: () => {
                        // 添加平滑过渡效果
                        const timer = setTimeout(() => {
                            // 在移动后更新缩放级别
                            this.latitude = latitude.toFixed(5),
                            this.longitude = longitude.toFixed(5),
                            this.scale = 14; // 设置为更适合查看的缩放级别
                            clearTimeout(timer);
                            this.$refs.popup.open(this.type);
                        }, 300); // 确保地图移动有足够的时间
                    },
                    fail: () => {
                        uni.showToast({
                            title: '移动到我的位置失败',
                            icon: 'none',
                            duration: 2000
                        });
                    }
                });

            }
        },
        // 回到我的位置
        goMyLocation() {
            // 检查用户位置是否可用
            if (this.myLatitude === null || this.myLongitude === null) {
                uni.showToast({
                    title: '无法获取当前位置,请确保已授权定位服务',
                    icon: 'none',
                    duration: 2000
                });
                return;
            }
            // 使用 moveToLocation 平滑移动到用户的位置
            this.mapContext.moveToLocation({
                latitude: this.myLatitude,
                longitude: this.myLongitude,
                success: () => {
                    // 添加平滑过渡效果
                    const timer = setTimeout(() => {
                        // 在移动后更新缩放级别
                        this.latitude = this.myLatitude;
                        this.longitude = this.myLongitude;
                        this.scale = 16; // 缩放级别
                        clearTimeout(timer);
                    }, 300); // 确保地图移动有足够的时间
                },
                fail: () => {
                    uni.showToast({
                        title: '移动到我的位置失败',
                        icon: 'none',
                        duration: 2000
                    });
                }
            });
        },
        // 全览
        quanLanAction() {
            if (this.myLatitude === null || this.myLongitude === null) {
                uni.showToast({
                    title: '无法获取当前位置,请确保已授权定位服务',
                    icon: 'none',
                    duration: 2000
                });
                return;
            }
            // 使用 moveToLocation 平滑移动到用户的位置
            this.mapContext.moveToLocation({
                latitude: this.myLatitude,
                longitude: this.myLongitude,
                success: () => {
                    // 添加平滑过渡效果
                    const timer = setTimeout(() => {
                        // 在移动后更新缩放级别
                        this.latitude = this.myLatitude;
                        this.longitude = this.myLongitude;
                        this.scale = 11; // 缩放级别
                        clearTimeout(timer);
                    }, 300); // 确保地图移动有足够的时间
                },
                fail: () => {
                    uni.showToast({
                        title: '全览失败',
                        icon: 'none',
                        duration: 2000
                    });
                }
            });
        },
        async GetMapData() {
            const res = await this.$axios("work/getMap", {
                lat: this.location.latitude,
                lon: this.location.longitude
            });
            console.log("当前位置的名称", JSON.parse(JSON.stringify(res)));
            if (res.data.code == 0) {
                this.location_data = res.data.result;
            } else {
                uni.showToast({
                    title: res.data.msg,
                    icon: 'none',
                    duration: 1000
                })
            }
        },
        // 获取首次屏幕对焦经纬度
        getInitialFocusCoordinates() {
            this.mapContext.getRegion({
                success: (res) => {
                    console.log("获取首次屏幕对焦经纬度", JSON.parse(JSON.stringify(res)));
                    const northeast = res.northeast; // 东北角
                    const southwest = res.southwest; // 西南角
                    const zuobiao = {
                        northeast: northeast,
                        southwest: southwest
                    };
                    this.zuobiao = [zuobiao.northeast, zuobiao.southwest];
                    this.biaojiIndex();
                },
                fail: (err) => {
                    console.error('获取对焦经纬度失败:', err);
                }
            });

        },
        // 标记地点数据
        async biaojiIndex() {
            const res = await this.$axios("biaoji/biaojiIndex", {
                title: '',
                zuobiao: this.zuobiao,
                scale: this.scale,
                page: '',//页码
                limit: '',//每页数量
            })
            console.log("标记地点数据", JSON.parse(JSON.stringify(res.data)));
            if (res.data.code == 0) {
                this.titleNum = res.data.totle_num;
                this.covers = res.data.lists.map(item => {
                    return {
                        id: item.id,
                        latitude: parseFloat(item.latitude),
                        longitude: parseFloat(item.longitude),
                        // iconPath: '/static/images/map.png',
                        width: 22,
                        height: 22,
                        callout: {
                            content: item.title,
                            display: 'ALWAYS',
                            color: '#ffffff',
                            fontSize: 12,
                            borderRadius: 4,
                            bgColor: '#000',
                            padding: '5',
                        }
                    }
                });
            } else {
                uni.showToast({
                    title: res.data.msg,
                    icon: 'none',
                    duration: 1000
                })
            }
        },
        // 地图标记点点击事件
        async mapAction(e) {
            console.log("markers 内容的点击事件", JSON.parse(JSON.stringify(e)));
            this.$refs.popup.open(this.type);
            const res = await this.$axios("biaoji/biaojiInfo", {
                id: e.detail.markerId
            });
            console.log("标记地点详情", JSON.parse(JSON.stringify(res.data)));
            if (res.data.code == 0) {
                this.bijiaoInfo = res.data.result;
            }
        },
        //监听地图拖拽
        regionchange(data) {
            // console.log("拖拽", JSON.parse(JSON.stringify(data)));
            const that = this;
            if (data.type == "end") {
                // 获取拖拽后的中心点
                that.mapContext.getCenterLocation({
                    success: function (res) {
                        that.latitude = parseFloat(res.latitude.toFixed(5));
                        that.longitude = parseFloat(res.longitude.toFixed(5));
                        // 获取后获取对角坐标
                        that.mapContext.getRegion({
                            success: (res) => {
                                const zuobiao = {
                                    northeast: res.northeast,
                                    southwest: res.southwest
                                };
                                that.zuobiao = [zuobiao.northeast, zuobiao.southwest];
                                // 获取缩放级别
                                that.mapContext.getScale({
                                    success: (res) => {
                                        if (res.scale !== that.scale) {
                                            that.scale = res.scale; // 更新缩放级别
                                        }
                                    }
                                })
                                that.biaojiIndex();
                            }
                        })
                    }
                });

            }
        },
        // 添加标记点
        biaoJiAction() {
            uni.getSetting({
                success: (res) => {
                    if (res.authSetting['scope.userLocation']) { /* 用户授权成功时走这里 */
                        this.handerChooseLocation()
                    } else if (res.authSetting['scope.userLocation'] === undefined) { /* 用户未授权时走这里 */
                        console.log('没有授权')
                        this.handleOpenSetting()
                    } else { /* 用户拒绝了授权后走这里 */
                        console.log('拒绝了授权 false')
                        this.handleOpenSetting()
                    }
                },
            })
        },
        handerChooseLocation() {
            uni.chooseLocation({
                latitude: this.latitude,
                longitude: this.longitude,
                success: (res) => {
                    // console.log('wx.chooseLocation res=', res)
                    uni.setStorageSync('currentLocation', res)
                    uni.navigateTo({
                        url: '/biaoji/biaojiInfo?status=1&res=' + JSON.stringify(res)
                    })
                },
                fail: function (err) {
                    console.log('取消按钮', err)
                }
            })
        },
        handleOpenSetting() {
            wx.openSetting({
                success: (res) => {
                    console.log('定位 openSetting', res)
                    if (res.authSetting["scope.userLocation"]) {
                        this.handerChooseLocation()
                    }
                }
            })
        },
        // 关闭弹窗
        closePopup() {
            this.$refs.popup.close();
            if (this.id != null) {
                this.getInitialFocusCoordinates(); // 获取首次屏幕对焦经纬度
                this.id = null;
            }
        },
        // 右上角分享
        onShareAppMessage() {
            return {
                title: this.bijiaoInfo.title,
                path: '/biaoji/biaoji?id=' + this.bijiaoInfo.id, //自定义路径
                // imageUrl: '分享图片链接',
            };
        },
        // 右上角分享到朋友圈
        onShareTimeline() {
            return {
                title: this.bijiaoInfo.title,
                path: '/biaoji/biaoji', //自定义路径
                // imageUrl: this.shareImg //自定义展示图片
            };
        },
        // 导航
        goNavigation() {
            // 导航跳转
            uni.openLocation({
                latitude: parseFloat(this.bijiaoInfo.latitude),
                longitude: parseFloat(this.bijiaoInfo.longitude),
                name: this.bijiaoInfo.title,
                address: this.bijiaoInfo.address,
                success: function (res) {
                    console.log('打开系统位置地图成功')
                },
                fail: function (error) {
                    console.log(error)
                }
            })
        },
        // 图片预览
        previewImage(index) {
            uni.previewImage({
                urls: this.bijiaoInfo.big_picurls,
                current: index, // 当前显示图片的索引
                loop: true // 是否开启图片轮播
            });
        },
        // 删除标记点
        async delBiaoJi() {
            this.$refs.alertDialog.open()
        },
        // 删除标记点
        async dialogConfirm() {
            const res = await this.$axios("biaoji/biaojiDel", {
                id: this.bijiaoInfo.id
            })
            console.log("删除标记点", JSON.parse(JSON.stringify(res)));
            if (res.data.code == 0) {
                this.$refs.popup.close()
                uni.showToast({
                    title: '删除成功',
                    icon: 'success',
                    duration: 1000
                })
                this.getLocation();
                this.biaojiIndex();
                this.getInitialFocusCoordinates(); // 获取首次屏幕对焦经纬度
            } else {
                uni.showToast({
                    title: res.data.msg,
                    icon: 'none',
                    duration: 1000
                })
            }

        },
        // 修改标记点
        biaoJiSave() {
            this.$refs.popup.close()
            uni.navigateTo({
                url: '/biaoji/biaojiInfo?status=2&id=' + this.bijiaoInfo.id
            })
        },
    }

}
</script>

<style lang="scss" scoped>
.search-box {
    background-color: white;
    padding: 0.5rem 0;

    .search {
        width: 90%;
        margin: auto;
        display: flex;
        align-items: center;
        font-size: 14px;
        background-color: #f7f7f7;
        padding: 0.4rem;

        border-radius: 30px;

        .icon-sousuo-copy-copy {
            font-size: 14px;
            margin-right: 10px;
            margin-left: .5rem;
        }

        text {
            color: DarkGray;
        }
    }

}

.icon-wodeweizhi {
    position: fixed;
    left: 2%;
    bottom: 5%;
    background-color: white;
    padding: 0.5rem;
    z-index: 3;
    border-radius: 10px;
}

.gongNeng {
    position: fixed;
    right: 2%;
    bottom: 5%;
    border-radius: 10px;
    background-color: white;
    padding: 0.5rem;
    z-index: 3;

    .gongNeng-item {
        font-size: 12px;
        text-align: center;
    }

    .huadian {
        margin-top: 0.5rem;

        .iconfont {
            margin-bottom: 0.3rem;
        }
    }
}

.popup-content {
    position: relative;
    padding: 1rem 0;

    // font-size: 1px;
    .icon-x {
        position: absolute;
        top: 1rem;
        right: 1rem;
        font-size: 20px;
    }

    .popup-content-top {
        margin: 0 1rem;
        border-bottom: 1px solid #f7f7f7;
        padding-bottom: 0.5rem;

        view:nth-of-type(1) {
            font-size: 14px;
            margin-top: 0.3rem;
            font-weight: bold;
        }

        view:nth-of-type(2) {
            font-size: 10px;
            margin-top: 0.3rem;
            color: #666666;
        }
    }

    .popup-content-content {
        margin: 0 1rem;
        border-bottom: 1px solid #f7f7f7;
        padding-bottom: 0.5rem;

        .popup-content-text {
            margin-top: 0.3rem;
            font-size: 12px;
        }
    }

    .popup-content-title {
        font-weight: bold;
        font-size: 12px;
        margin-top: 0.3rem;
    }

    .popup-img {
        margin: 0.5rem 1rem;

        image {
            margin-right: 0.3rem;
            width: 80px;
            height: 80px;
        }
    }

    .popup-bom {
        margin: 0 1rem;
        margin-top: 3rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-top: 1px solid #f7f7f7;

        .popup-bom-left {
            display: flex;
            align-items: center;
            font-size: 12px;

            .popup-bom-left-item {
                .iconfont {
                    margin-right: 0.2rem;
                }
            }

            .del {
                color: #f56c6c;
            }

            button {
                font-size: 12px;
                background-color: white;
                // height: 60px;
            }

            button::after {
                border: none;
            }
        }

        .popup-bom-right {
            color: white;
            background-color: #377fff;
            border-radius: 30px;
            padding: 0.3rem 0.8rem;
            font-size: 14px;
            text-align: center;
        }

    }
}

.searchDialog {
    background-color: white;
    height: 50vh;
}

.titleNum {
    position: fixed;
    left: 0.2rem;
    top: 3.5rem;
    background-color: white;
    padding: 0.3rem;
    z-index: 5;
    font-size: 14px;
    border-radius: 5px;
}
</style>

http://www.kler.cn/a/522343.html

相关文章:

  • 哈工大:LLM高质量嵌入模型KaLM-Embedding
  • Fullcalendar @fullcalendar/react 样式错乱丢失问题和导致页面卡顿崩溃问题
  • 《Java核心技术 卷II》日期和时间API的时间线
  • Next.js 14 TS 中使用jwt 和 App Router 进行管理
  • 【MySQL — 数据库增删改查操作】深入解析MySQL的 Update 和 Delete 操作
  • 2025多目标优化创新路径汇总
  • 深度学习|表示学习|卷积神经网络|详细推导每一层的维度变化|14
  • 项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(九)(完结篇)
  • Golang Ticker Reset异常的坑
  • 第一届“启航杯”网络安全挑战赛WP
  • xss总结标签
  • 滑动窗口详解:解决无重复字符的最长子串问题
  • EtherCAT主站IGH-- 17 -- IGH之fsm_master.h/c文件解析
  • 分布式系统相关面试题收集
  • C语言中宏(Macro)的高级用法:中英双语
  • 人工智能在计算机视觉中的应用与创新发展研究
  • Day27-【13003】短文,什么是栈?栈为何用在递归调用中?顺序栈和链式栈是什么?
  • scikit-learn基本功能和示例代码
  • postgresql 9.4.1 普通表,子表,父表的创建与测试
  • 系统设计的
  • JavaScript系列(46)-- WebGL图形编程详解
  • 专为课堂打造:宏碁推出三款全新耐用型 Chromebook
  • 【实用技能】如何借助Excel处理控件Aspose.Cells,使用 C# 锁定 Excel 中的单元格
  • 获取加工视图下所有元素
  • java后端之事务管理
  • 【C++探索之路】STL---string