umi3.x使用百度地图

本文介绍了如何在基于Umi的React应用中添加地图定位功能。首先,通过创建自定义插件在HTML中引入BaiduMapsAPI,然后在UMI配置文件中注册该插件。接着,手动添加ejs模板引擎并在其中插入地图脚本。最后,展示了如何在Map组件中初始化地图,进行定位和添加覆盖物的操作。
摘要由CSDN通过智能技术生成

前言

在写react中需要使用地图的一个定位功能,vue是有这个入口文件的,在umi里面默认没有这个入口文件,所以需要通过自己创建ejs文件,插件结合的方式进行实现

一、用插件把链接添加到页面上

1.在在src/page下 ,新建文件 plugins/mapPlugin.js

export default (api, opts) => {
  // 在HTML尾部添加脚本
  api.addHTMLScripts(() => {
    return [
      {
        // 百度地图
        src: '//api.map.baidu.com/api?v=3.0&ak=AK码',
      },
    ];
  });
};

2.在umirc.ts中导入本地新建的插件文件mapPlugin.js

/**
umi 的路由文件
*/
import { defineConfig } from 'umi';

export default defineConfig({
 nodeModulesTransform: {
   type: 'none',
 },
 routes: [],
 fastRefresh: {},
 plugins:['./src/pages/plugins/mapPlugin.js']
});

二、手动添加ejs模板引擎

<!Doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="apple-mobile-web-app-capable" content="yes"/>
  <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
  <meta name="format-detection" content="telephone=no"/>
  <meta name="format-detection" content="email=no"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
  <title> </title>
  <script src="//api.map.baidu.com/api?v=3.0&ak=AK码"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
// Map组件
import { Navbar, Popup } from 'tdesign-mobile-react';
// import { ChevronLeftIcon } from 'tdesign-icons-react';
import { getMap } from '@/utils/api/home.js'
import { useEffect, useState } from 'react';
import './index.less'
import { useLocation } from 'umi';

export default function MapPage() {
    const location = useLocation()
    let [isShow, setIsShow] = useState(false)
    const [visible, setVisible] = useState(false)
    const handleVisibleChange = (visible: any) => {
        setVisible(visible);
    }
    useEffect(() => {
        initMap()
    }, [])
    const initMap = () => {
        // 获取当前定位城市
        // JSON.parse(sessionStorage.getItem('hkzf_city')||'')  |||window.sessionStorage.getItem('currentCity')
        const { label, value } = JSON.parse(JSON.stringify({ label: "北京", value: "AREA|88cff55c-aaa4-e2e0", pinyin: "beijing", short: "bj" }))
        // 初始化地图实例
        var map = new BMap.Map("container");
        // 创建地址解析器实例
        var myGeo = new BMap.Geocoder();
        // 将地址解析结果显示在地图上,并调整地图视野
        myGeo.getPoint(label, async (point: any) => {
            if (point) {
                //缩放
                map.centerAndZoom(point, 11);
                //添加标记
                map.addOverlay(new BMap.Marker(point))

                //添加控件
                map.addControl(new BMap.ScaleControl())
                // map.addControl(new BMap.ZoomControl())
                renderOverLays(value, 11, map, point)
            } else {
                alert('您选择的地址没有解析到结果!');
            }
        }, label)
        map.addEventListener('movestart', () => {
            if (isShow) {
                setIsShow(false)
            }
        })
    }
    // 创建区, 镇覆盖物
    const createCircle = (item: any, zoom: any, map: any, point: any) => {
        const { coord: { longitude, latitude }, label: areaName, count, value } = item
        const areaPoint = new BMap.Point(longitude, latitude)

        //添加文本覆盖物
        const opts = {
            position: areaPoint,
            offset: new BMap.Size(30, -30)
        }
        //注意:设置setContent以后,第一个参数中设置的文本内容就失效了,因此直接清空即可
        const label = new BMap.Label('', opts)

        //设置房源覆盖物内容
        label.setContent(`
              <div class="contest-box"  key=${value}>
                  <p class="text-bxo">${areaName}</p>
                  <p  class="text-bxo">${count}套</p>
              </div>
            `)

        //设置样式
        const labelStyle = {
            cursor: 'pointer',
            border: '2px solid white',
            whiteSpace: 'nowrap',
            fontSize: '12px',
            textAlign: 'center',
            borderRadius: '50%',
            width: '65px',
            height: '65px',
            background: 'rgba(38, 191, 110, 0.9)'

        }
        label.setStyle(labelStyle)

        zoom += 2
        if (zoom >= 15) {
            zoom = 15
        }
        // 添加单击事件
        label.addEventListener('click', () => {
            // 调用 renderOverlays 方法,获取该区域下的房源数据
            renderOverLays(item.value, zoom, map, point)

            // 放大地图,以当前点击的覆盖物为中心放大地图
            map.centerAndZoom(areaPoint, zoom)

            // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                map.clearOverlays()
            }, 0)
        })
        map.addOverlay(label)
    }
    // 熏染覆盖物 接收id参数获取区域房源数据 或覆盖类型以及下级地图的缩放级别
    const renderOverLays = async (id: any, zoom: any, map: any, point: any) => {
        let data = await getMap()
        let result = data.body
        console.log(zoom);
        result.forEach((item: any) => {
            // 创建覆盖物
            createOverlays(item, zoom, map, point)
        })
    }
    const createReact = (item: any, zoom: any, map: any, point: any) => {
        const { coord: { longitude, latitude }, label: areaName, count, value } = item
        const areaPoint = new BMap.Point(longitude, latitude)
        //添加文本覆盖物
        const opts = {
            position: areaPoint,
            offset: new BMap.Size(30, -30)
        }
        //注意:设置setContent以后,第一个参数中设置的文本内容就失效了,因此直接清空即可
        const label = new BMap.Label('', opts)

        //设置房源覆盖物内容
        label.setContent(`  
              <div>
                <p>
                    ${areaName} ${count}套
                  </p>

              </div>
            `)

        //设置样式
        const labelStyle = {
            border: 'none',
            cursor: 'pointer',
            whiteSpace: 'nowrap',
            fontSize: '12px',
            textAlign: 'center',
            height: '20px',
            background: 'rgba(38, 191, 110, 0.9)'

        }
        label.setStyle(labelStyle)

        zoom++
        // 添加单击事件
        label.addEventListener('click', () => {
            // 调用 renderOverlays 方法,获取该区域下的房源数据
            renderOverLays(item.value, zoom, map, point)

            // 放大地图,以当前点击的覆盖物为中心放大地图
            map.centerAndZoom(areaPoint, zoom)

            // 解决清除覆盖物时,百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                map.clearOverlays()
            }, 0)
        })
        map.addOverlay(label)
    }

    // 创建覆盖物 根据传入的数据调用对应的方法 创建覆盖物 
    const createOverlays = (item: any, zoom: any, map: any, point: any) => {
        switch (zoom) {
            case 11:
                createCircle(item, zoom, map, point)
                break;
            case 13:
                createCircle(item, zoom, map, point)
                break;
            case 15:
                createReact(item, zoom, map, point)
                break;

            default:
                break;
        }
    }

    return (
        <div className="map">
            <Navbar leftIcon style={{ zIndex: 2 }}>
                地图找房
            </Navbar>
            <div id="container" style={{ height: 799 }}>
                <Popup visible={visible} onVisibleChange={handleVisibleChange} placement="bottom">
                    <div className="vertical"></div>
                </Popup>
            </div>
        </div>
    )
}

效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值