【uniapp+mapbox】

1.在uni-app项目的根目录下使用npm下载mapbox-gl 我用的是2.15.0 版本

npm install --save mapbox-gl

2.创建一个页面 代码如下

<template>
  <view class="map-wrap">
    <!-- #ifdef APP-PLUS || H5 -->
    <view
      id="mapbox"
      :operation="mapConfig"
      :change:operation="mapbox.handleConfigChange"
    ></view>
    <!-- 显示点击的完整信息(经纬度+名称) -->
    <view class="click-info" v-if="clickData">
      位置:{{ clickData.name }}<br />
      经纬度:{{ clickData.lng.toFixed(6) }}, {{ clickData.lat.toFixed(6) }}
    </view>
    <!-- #endif -->
  </view>
</template>

<!-- 主页面脚本:接收完整数据(经纬度+名称) -->
<script>
export default {
  data() {
    return {
      clickData: null, // 存储 { lng, lat, name }
      mapConfig: {
        center: [118.810251, 32.062151], // 初始:南京
        zoom: 9,
        title: "南京地图",
      },
    };
  },
  methods: {
    // 接收renderjs传递的完整数据
    handleMapClick(clickData) {
      console.log("主页面接收完整数据:", clickData);
      this.clickData = clickData[0];
    },
  },
};
</script>

<!-- renderjs脚本:实现标点+逆地理编码+数据传递 -->
<script module="mapbox" lang="renderjs">
// 1. 引入Mapbox核心库和Marker类(Marker已包含在mapboxgl中)
const mapboxgl = require('!mapbox-gl/dist/mapbox-gl.js');
import 'mapbox-gl/dist/mapbox-gl.css';

export default {
  data() {
    return {
      map: null,
      lastMarker: null // 存储上一个标点,用于点击新位置时清除旧标点
    };
  },
  mounted() {
    // this.createdMap(this.operation);
  },
  methods: {
        handleConfigChange(newConfig, oldConfig) {
      console.log('主页面数据更新:', newConfig);
      console.log('旧数据:', oldConfig);

      // 根据新配置更新地图
      this.$nextTick(()=>{
        this.createdMap(newConfig)
      })
    },
    createdMap(config) {
        console.log('config',config);
      mapboxgl.accessToken = '你申请的token';
      this.map = new mapboxgl.Map({
        container: 'mapbox',
        center: [118.810251, 32.062151],
        style: "mapbox://styles/mapbox/streets-v11",
        zoom: 9
      });

      // 2. 地图点击事件:标点+逆地理编码
      this.map.on('click', async (e) => {
        const lng = e.lngLat.lng;
        const lat = e.lngLat.lat;
        console.log('renderjs获取点击经纬度:', lng, lat);

        // 3. 先清除上一个标点(避免地图上标点过多)
        if (this.lastMarker) {
          this.lastMarker.remove();
        }

        // 4. 调用逆地理编码API,获取地点名称(异步操作)
        const placeName = await this.getPlaceNameByLngLat(lng, lat);

        // 5. 在点击位置创建标点
        const marker = new mapboxgl.Marker({
          color: '#ff4444', // 标点颜色
          size: 'large',    // 标点大小
          draggable: false  // 是否可拖动(false=固定)
        })
          .setLngLat([lng, lat]) // 设置标点位置
          .addTo(this.map);      // 添加到地图

        // 6. 存储当前标点,用于下次清除
        this.lastMarker = marker;

        // 7. 传递完整数据给主页面(经纬度+名称)
        this.$ownerInstance.callMethod('handleMapClick', [{
          lng: lng,
          lat: lat,
          name: placeName // 地点名称(如“南京市玄武区XX路”)
        }]);
      });

      this.map.on("load", () => {
        console.log('地图加载完成,可点击标点并获取名称');
      });
    },

    /**
     * 逆地理编码:通过经纬度获取地点名称
     * @param {number} lng - 经度
     * @param {number} lat - 纬度
     * @returns {string} 地点名称(如“北京市朝阳区”)
     */
    async getPlaceNameByLngLat(lng, lat) {
      try {
        // Mapbox逆地理编码API地址(文档:https://docs.mapbox.com/api/search/geocoding/#reverse-geocoding)
        const apiUrl = `https://api.mapbox.com/geocoding/v5/mapbox.places/${lng},${lat}.json?access_token=${mapboxgl.accessToken}&limit=1`;

        // 发送请求(renderjs中可直接用fetch,需配置跨域)
        const response = await fetch(apiUrl);
        const data = await response.json();
        console.log('data',data);

        // 解析返回数据:取第一个结果的place_name(完整地点名称)
        if (data.features && data.features.length > 0) {
          return data.features[0].place_name;
        }
        return '未知地点'; // 无结果时返回默认值

      } catch (error) {
        console.error('逆地理编码失败:', error);
        return '获取名称失败'; // 出错时返回提示
      }
    }
  }
};
</script>

<style lang="scss">
.map-wrap {
  position: relative;
  width: 300px;
  height: 300px;
}

#mapbox {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* 显示点击信息的样式 */
.click-info {
  position: absolute;
  bottom: 10px;
  left: 10px;
  padding: 8px 12px;
  background: white;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 12px;
  z-index: 10;
  line-height: 1.5;
}

/* 原有样式保留 */
#mapbox /deep/ .mapboxgl-ctrl-geocoder {
  min-width: 140px;
}
#mapbox /deep/ .mapboxgl-ctrl-geocoder input[type="text"] {
  height: 30px;
}
#mapbox /deep/ .mapboxgl-ctrl-geocoder .geocoder-icon-search {
  top: 5px;
}
#mapbox /deep/ .mapboxgl-ctrl-geocoder .geocoder-pin-right * {
  top: 5px;
}
.control-box {
  padding: 10rpx 30rpx;
  background-color: #00aaff;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 999px;
}
</style>

3.实现上面两步之后会有这个报错 需要配置一下
在这里插入图片描述
在这里插入图片描述
根目录下创建.browserslistr 文件

> 0.25%
not ie 11
not op_mini all
not dead

在修改vue.config.js

module.exports = {
  transpileDependencies: [], // 不转译任何node_modules依赖
  chainWebpack: (config) => {
    // 1. 排除Mapbox被babel-loader处理
    config.module.rule('js').exclude.add(/node_modules\/mapbox-gl\//);
    // 2. 按官网要求:用!前缀排除loader(UniApp中在require时加)
  }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值