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

一、功能概述

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

  1. 显示基础地图

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

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

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

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

    二、分步骤实现

    步骤1:搭建基础地图

    1.1 添加map组件

    在页面template中添加map组件:

    1.2 设置地图中心点

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

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

    步骤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组件:

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

    3.1 初始化markers和选中点

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

    3.2 实现点击事件处理

    const handleMapTap = (e) => {
    const { latitude, longitude } = e.detail
    selectedPoint.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.latitude
    let inside = false
    for (let i = 0, j = polygon.length - 1; i  y) !== (yj > y)) &&
    (x < (xj - xi) * (y - yi) / (yj - yi) + xi)
    if (intersect) inside = !inside
    }
    return inside
    }

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

    已选位置:
    纬度: {{selectedPoint.latitude.toFixed(6)}}
    经度: {{selectedPoint.longitude.toFixed(6)}}
    当前位置不在郑州范围内!

    添加样式:

    .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;
    }

    三、完整代码

    已选位置:
    纬度: {{selectedPoint.latitude.toFixed(6)}}
    经度: {{selectedPoint.longitude.toFixed(6)}}
    当前位置不在郑州范围内!
    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.latitude
    let inside = false
    for (let i = 0, j = polygon.length - 1; i  y) !== (yj > y)) &&
    (x  {
    const { latitude, longitude } = e.detail
    selectedPoint.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
    })
    }
    }
    .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;
    }

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

    四、实现效果

posted @ 2025-08-22 08:56  yjbjingcha  阅读(37)  评论(0)    收藏  举报