当前位置: 首页 > 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.xdnf.cn/news/1309933.html

相关文章:

  • Matplotlib直线绘制:从基础到三维空间的高级可视化
  • 数组名本质与指针运算揭秘
  • List容器:特性与操作使用指南
  • 零基础学习人工智能的完整路线规划
  • 民法学学习笔记(个人向) Part.5
  • 学习游戏制作记录(制作系统与物品掉落系统)8.16
  • MySQL查询性能慢时索引失效的排查与优化实践
  • Redis缓存
  • 【OpenGL】LearnOpenGL学习笔记09 - 材质、光照贴图
  • 登录与登录校验:Web安全核心解析
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑7B大语言模型_20250816
  • 如何在FastAPI中玩转APScheduler,实现动态定时任务的魔法?
  • 【wmi异常】关于taskkill命令提示“错误:找不到” 以及无法正常获取设备机器码的处理办法
  • pytorch例子计算两张图相似度
  • PHP反序列化的CTF题目环境和做题复现第2集_POP链构造
  • 利用Qwen大模型进行c++11并发库的学习,与时俱进!!!!
  • AI安全增强核心技术:提示词防火墙、置信度过滤与知识蒸馏防御
  • 第6问 数据分析领域主要的岗位有哪些?
  • Rust 入门 KV存储HashMap (十七)
  • pdf合并代码
  • 【C++】异常详解(万字解读)
  • FPGA串口通信实现方案
  • Qt QDateTime时间部分显示为全0,QTime赋值后显示无效问题【已解决】
  • 【C++】C++11
  • Maven私服配置模版
  • 深入详解PCB布局布线技巧-去耦电容的摆放位置
  • IOMMU的2级地址翻译机制及多级(2~5)页表查找
  • Python 项目高频设计模式实战指南:从理念到落地的全景剖析
  • 电路方案分析(二十一)笔记本电脑散热风扇参考设计
  • 【运维心得】三步更换HP笔记本电脑外壳