当前位置: 首页 > 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.dtcms.com/a/333890.html

相关文章:

  • SpringBoot 整合 Langchain4j:系统提示词与用户提示词实战详解
  • uniapp:微信小程序使用Canvas 和Canvas 2D绘制图形
  • 【Java笔记】synchronized
  • GitHub宕机时的应急协作方案
  • 【Java学习】锁、线程死锁、线程安全2
  • Go语言实战案例:连接MySQL数据库
  • webrtc弱网-VideoSendStreamImpl类源码分析与算法原理
  • debian 13 显示中文字体 不再显示菱形块 终端显示中文
  • OpenCompass傻瓜式入门教程
  • 命令模式C++
  • Point-LIO技术文档中文翻译解析
  • 【计算机组成原理】第四章:指令系统
  • 使用vscode插件(c cpp cmake project creator)自动生成C++程序模板
  • LeetCode 283.移动零
  • C语言:指针(5)
  • break的使用大全
  • 基于STM32单片机的智能粮仓温湿度检测蓝牙手机APP设计
  • YAML:锚点深度解析,告别重复,拥抱优雅的配置艺术
  • 初识CNN02——认识CNN2
  • 浏览器面试题及详细答案 88道(45-55)
  • MyBatis 与 MyBatis-Plus 的区别
  • 20day-人工智能-机器学习-线性回归
  • 数据处理与统计分析 —— numpy入门
  • @mcp.tool如何从函数定义映射到llm系统输入
  • Kotlin作用域函数全解:run/with/apply/let/also与this/it的魔法对决
  • LORA模块的通讯速率(915Mhz)以及通道数量规划
  • 图片滤镜处理(filters)
  • 【机器学习深度学习】生成式评测
  • 数据处理分析环境搭建+Numpy使用教程
  • Design Compiler:使用IC Compiler II Link