引言
此博客作为一份如何在 React 中使用 bing maps api 参考,其他地图 api 原理上也可参考此教程。
前期准备
首先需要在bing mpas dev center中,具体在 My accout 下 My keys 中创建 new key。
Application URL 作为可选项,若填写 url 相当于白名单。非此域名下的网站则无法通过此 key 获取对应的一些 api 操作。
创建后 key details 下面 key 默认隐藏点击 Show key 便可拿到所需要的 bing maps api 中的 key。
开发者文档:
加载 bing maps api script
该教程以 bing maps v8 组件为例子
首先需要在 React 中有两种方式引入第三方引入第三方 js 资源:
- 通常 React 项目中直接在 index.html 中通过 script 标签引入
<script
type="text/javascript"
src="http://www.bing.com/api/maps/mapcontrol?callback=GetMap&branch=experimental&key=[YOUR_BING_MAPS_KEY]"
async
defer></script>
- 由于某些情况该工程不包含 index.html 或者其他因素则需要 dom 操作。需要注意以下事项。
- bing map script 资源推荐全局引用,若在对应组件再加载 scipt 资源此时会极大影响体验。操作起来也会更为繁琐(需要留意是在地图资源加载完成后才进行初始化地图;由于是组件挂载 bing maps script 资源,每次组件卸载 scipt 资源也会被卸载,意味着每次组件加载时都需要获取一遍 script 资源)
- 推荐 dom 操作时,在 body 中插入 scipt 资源
以下是我的片段代码(自定义 hook)
/**
* useLoadMap hook
* @description 加载bing map script资源
* @returns {void}
*/
const useLoadMap = () => {
useEffect(() => {
if (!window.Microsoft) {
const script = document.createElement("script");
script.src = `https://www.bing.com/api/maps/mapcontrol?key=${BING_KEY}`;
script.async = true;
script.defer = true;
script.type = "text/javascript";
document.body.appendChild(script);
}
}, [window.Microsoft]);
};
export default useLoadMap;
引用
// ...app
// ...
useLoadMap();
// ...
初始化 bing map
简易获取当前用户位置并在地图图钉显示
import { BING_KEY, PIN } from "../utils";
const useMap = () => {
const mapRef = useRef(null);
/**
* Init map
*/
const getMap = () => {
// Initialize the map
const map = new window.Microsoft.Maps.Map("#myMap", {
credentials: BING_KEY,
enableCORS: false,
ShowNavigationBar: false,
});
mapRef.current = map;
// Load the spatial math module
window.Microsoft.Maps.loadModule("Microsoft.Maps.SpatialMath", function () {
// Request the user's location
navigator.geolocation.getCurrentPosition(function (position) {
var loc = new window.Microsoft.Maps.Location(
position.coords.latitude,
position.coords.longitude
);
// Create an accuracy circle
var path = window.Microsoft.Maps.SpatialMath.getRegularPolygon(
loc,
position.coords.accuracy,
36,
window.Microsoft.Maps.SpatialMath.Meters
);
var poly = new window.Microsoft.Maps.Polygon(path);
mapRef.current.entities.push(poly);
});
});
};
return [getMap, mapRef];
};
export default useMap;
在对应组件调用
// ...
const [getMap, mapRef] = useMap();
// ...
useLayoutEffect(() => {
// init map
if (window.Microsoft) {
// delay to wait for map loaded
setTimeout(() => getMap(), 100);
}
}, [window.Microsoft]);
// ...
模块
使用 loadModule 可加载不同模块
window.Microsoft.Maps.loadModule("Microsoft.Maps.SpatialMath", function () {
// todo
});
图钉
通过 Maps Pushpin 实例化图钉,在创建的 mapRef entities 中 push() 可对其进行增加 pop()移除
var pin = new window.Microsoft.Maps.Pushpin(
{
latitude: 47.58106995,
longitude: -122.34111023,
},
{
icon: PIN,
draggable: false,
}
);
mapRef.current.entities.push([location, pin]);
事件
在初始化的时候调用 Events addHandler 为其添加不同的事件
const getMap = () => {
window.Microsoft.Maps.Events.addHandler(map, "mouseup", function (e) {
// todo mouse up handler
});
};