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

基于uni-app+vue3实现的微信小程序地图范围限制与单点标记功能实现指南

一、功能概述

本文将分步骤讲解如何使用uni-app框架在微信小程序中实现以下功能:

  1. 显示基础地图

  2. 绘制特定区域范围(以郑州市为例)

  3. 实现点击地图添加标记点

  4. 限制标记点只能在指定区域内添加

  5. 显示选中位置的坐标信息

    二、分步骤实现

    步骤1:搭建基础地图

    1.1 添加map组件

    在页面template中添加map组件:

    <template><view class="container"><mapid="map"style="width: 100%; height: 80vh":latitude="center.latitude":longitude="center.longitude":show-location="true":enable-zoom="true":enable-scroll="true"@tap="handleMapTap"></map></view>
    </template>

    1.2 设置地图中心点

    在script部分设置地图初始中心点(xxx位置):

    <script setup>
    import { ref } from 'vue'const center = ref({latitude: 34.747,   // 纬度longitude: 113.625  // 经度
    })
    </script>

    步骤2:绘制郑州市范围

    2.1 定义郑州市边界坐标

    const zhengzhouPolygon = [{latitude: 34.936, longitude: 112.842}, // 西北角{latitude: 34.936, longitude: 114.023}, // 东北角{latitude: 34.524, longitude: 114.023}, // 东南角{latitude: 34.524, longitude: 112.842}, // 西南角{latitude: 34.936, longitude: 112.842}  // 闭合多边形
    ]

    2.2 添加polygons属性到map组件 绘制限制范围

    const polygons = ref([{points: zhengzhouPolygon,strokeWidth: 2,strokeColor: "#1E90FF",fillColor: "#1E90FF22"
    }])

    更新map组件:

    <map...:polygons="polygons"
    ></map>

    步骤3:实现点击添加标记功能

    3.1 初始化markers和选中点

    const markers = ref([])
    const selectedPoint = ref(null)
    const isInZhengzhou = ref(false)

    3.2 实现点击事件处理

    const handleMapTap = (e) => {const { latitude, longitude } = e.detailselectedPoint.value = { latitude, longitude }// 判断是否在郑州范围内isInZhengzhou.value = isPointInPolygon({latitude, longitude}, zhengzhouPolygon)if (isInZhengzhou.value) {// 在范围内,添加标记markers.value = [{id: 1,latitude,longitude,iconPath: '/static/location.png', // 替换为你的标记图标路径width: 30,height: 30,title: "选择的位置"}]} else {// 不在范围内,清除标记并提示markers.value = []uni.showToast({title: "请选择郑州市范围内的位置",icon: "none",duration: 2000})}
    }

    步骤4:实现点在多边形内判断(射线法)

    function isPointInPolygon(point, polygon) {const x = point.longitude, y = point.latitudelet inside = falsefor (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {const xi = polygon[i].longitude, yi = polygon[i].latitudeconst xj = polygon[j].longitude, yj = polygon[j].latitudeconst intersect = ((yi > y) !== (yj > y)) &&(x < (xj - xi) * (y - yi) / (yj - yi) + xi)if (intersect) inside = !inside}return inside
    }

    步骤5:添加信息显示区域

    <view class="info-box" v-if="selectedPoint"><text>已选位置:</text><text>纬度: {{selectedPoint.latitude.toFixed(6)}}</text><text>经度: {{selectedPoint.longitude.toFixed(6)}}</text><text v-if="!isInZhengzhou" class="error">当前位置不在郑州范围内!</text>
    </view>

    添加样式:

    <style scoped>
    .container {padding: 20rpx;
    }.info-box {margin-top: 20rpx;padding: 20rpx;background-color: #f5f5f5;border-radius: 10rpx;
    }.info-box text {display: block;margin: 10rpx 0;font-size: 28rpx;
    }.error {color: #ff0000;font-weight: bold;
    }
    </style>

    三、完整代码

    <template><view class="container"><mapid="map"style="width: 100%; height: 80vh":latitude="center.latitude":longitude="center.longitude":polygons="polygons":markers="markers"@tap="handleMapTap":show-location="true":enable-zoom="true":enable-scroll="true"></map><view class="info-box" v-if="selectedPoint"><text>已选位置:</text><text>纬度: {{selectedPoint.latitude.toFixed(6)}}</text><text>经度: {{selectedPoint.longitude.toFixed(6)}}</text><text v-if="!isInZhengzhou" class="error">当前位置不在郑州范围内!</text></view></view>
    </template><script setup>
    import { ref } from 'vue'// 郑州市边界坐标
    const zhengzhouPolygon = [{latitude: 34.936, longitude: 112.842},{latitude: 34.936, longitude: 114.023},{latitude: 34.524, longitude: 114.023},{latitude: 34.524, longitude: 112.842},{latitude: 34.936, longitude: 112.842}
    ]// 地图中心点(郑州二七塔)
    const center = ref({latitude: 34.747,longitude: 113.625
    })// 多边形配置
    const polygons = ref([{points: zhengzhouPolygon,strokeWidth: 2,strokeColor: "#1E90FF",fillColor: "#1E90FF22"
    }])// 标记点
    const markers = ref([])
    const selectedPoint = ref(null)
    const isInZhengzhou = ref(false)// 判断点是否在多边形内
    function isPointInPolygon(point, polygon) {const x = point.longitude, y = point.latitudelet inside = falsefor (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {const xi = polygon[i].longitude, yi = polygon[i].latitudeconst xj = polygon[j].longitude, yj = polygon[j].latitudeconst intersect = ((yi > y) !== (yj > y)) &&(x < (xj - xi) * (y - yi) / (yj - yi) + xi)if (intersect) inside = !inside}return inside
    }// 处理地图点击
    const handleMapTap = (e) => {const { latitude, longitude } = e.detailselectedPoint.value = { latitude, longitude }isInZhengzhou.value = isPointInPolygon({latitude, longitude}, zhengzhouPolygon)if (isInZhengzhou.value) {markers.value = [{id: 1,latitude,longitude,iconPath: '/static/location.png',width: 30,height: 30,title: "选择的位置"}]} else {markers.value = []uni.showToast({title: "请选择郑州市范围内的位置",icon: "none",duration: 2000})}
    }
    </script><style scoped>
    .container {padding: 20rpx;
    }.info-box {margin-top: 20rpx;padding: 20rpx;background-color: #f5f5f5;border-radius: 10rpx;
    }.info-box text {display: block;margin: 10rpx 0;font-size: 28rpx;
    }.error {color: #ff0000;font-weight: bold;
    }
    </style>

    通过以上步骤,我们完整实现了一个限制区域范围的单点标记功能。开发者可以根据实际需求调整区域范围或扩展更多功能。。。ps:markers中的iconpath 如果不传 会展示系统默认的标记点,如果要根据经纬度获取地名则需要申请对接地图的接口才能实现

    四、实现效果

http://www.lryc.cn/news/623009.html

相关文章:

  • Altium Designer 22使用笔记(7)---网表导入,叠层设置
  • 【电路笔记 通信】AXI4-Lite协议 论文阅读 简化的高级可扩展接口(AdvancedeXtensibleInterface4Lite)
  • 【计算机网络架构】混合型架构简介
  • 车载诊断架构 --- 怎么解决对已量产ECU增加具体DTC的快照信息?
  • 超越Transformer:大模型架构创新的深度探索
  • 【自动化运维神器Ansible】Ansible逻辑运算符详解:构建复杂条件判断的核心工具
  • 11、软件需求工程
  • 【系统分析师】软件需求工程——第11章学习笔记(下)
  • 架构调整决策
  • 软件需求管理过程详解
  • M-LAG双活网关
  • linux I2C核心、总线与设备驱动
  • 特洛伊木马和后门程序的定义、联系、区别与应用场景
  • UE5多人MOBA+GAS 45、制作冲刺技能
  • 深入详解PCB布局布线技巧-去耦电容的摆放位置
  • 【AndroidStudio修改中文设置】
  • 玉米及淀粉深加工产业展|2026中国(济南)国际玉米及淀粉深加工产业展览会
  • UE5多人MOBA+GAS 46、制作龙卷风技能
  • 机器学习——PCA算法
  • 心路历程-学Linux的开端
  • 【php反序列化介绍与常见触发方法】
  • Linux 多线程:线程回收策略 线程间通信(互斥锁详解)
  • MyBatis 的 SQL 拦截器:原理、实现与实践
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑7B大语言模型_20250816
  • Wi-Fi 7 将如何重塑互联工作场所
  • Python脚本开发-统计Rte中未连接的Port
  • Python---异常链(Exception Chaining)
  • 完整设计 之 定稿 之:后现代元宇宙九宫格(重命名)-腾讯元宝答问
  • 线性代数之两个宇宙文明关于距离的对话
  • 分享一个大数据的源码实现 基于Hadoop的二手车市场数据分析与可视化 基于Spark的懂车帝二手车交易数据可视化分析系统