feat: 完善地图组件
This commit is contained in:
parent
b2df3e3a7c
commit
6f65746373
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,6 +9,6 @@ vueuse
|
|||||||
/temp
|
/temp
|
||||||
# packages/**/es
|
# packages/**/es
|
||||||
# packages/**/lib
|
# packages/**/lib
|
||||||
/es
|
# /es
|
||||||
/lib
|
# /lib
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
|
@ -1,60 +1,9 @@
|
|||||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||||
import type { CSSProperties } from 'react';
|
|
||||||
import Map, { MapRef } from 'react-map-gl';
|
import Map, { MapRef } from 'react-map-gl';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
import { MapProps } from './interface';
|
||||||
export const mapboxAccessToken =
|
import { merge } from './utils';
|
||||||
'pk.eyJ1IjoiZGluZ2xpMTIzIiwiYSI6ImNra204ODhjczBobTgyeHJ6MmJpZHMxNWgifQ.NbKrXh_hb2gvjr5CEMDnyQ';
|
import { MAP_CENTER, defaultMapConfig } from './constants';
|
||||||
export const MAP_CENTER = {
|
|
||||||
longitude: 120.2667694313269,
|
|
||||||
latitude: 30.180942826533766,
|
|
||||||
}; //地图中心
|
|
||||||
const MapUrl = 'http://10.0.0.120:30003/map';
|
|
||||||
export const MapConfig = {
|
|
||||||
mapboxAccessToken,
|
|
||||||
maxZoom: 18,
|
|
||||||
minZoom: 4,
|
|
||||||
dragRotate: false,
|
|
||||||
mapStyle: {
|
|
||||||
version: 8,
|
|
||||||
name: 'Mapbox Streets',
|
|
||||||
// sprite: `${location.origin}/mapbox/sprite`, // 地图图标
|
|
||||||
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', // 字体
|
|
||||||
sources: {
|
|
||||||
//数据源
|
|
||||||
'osm-tiles': {
|
|
||||||
type: 'raster', //栅格切片。vector:矢量切片
|
|
||||||
// Z-瓦片层级,一般支持0-18级,越大代表越清晰;
|
|
||||||
// X-瓦片列号,从西向东(0->360),依次0,1,2,……;
|
|
||||||
// Y-瓦片行号,从北向南(有些也可能是从南向北),依次0,1,2,……;
|
|
||||||
tiles: [`${MapUrl}/api/tilesets/mapfile/{z}/{x}/{y}.png`], //在线地址,先写死120
|
|
||||||
tileSize: 256, //切片的最小展示尺寸(可选,单位:像素,默认值为 512,即 1024/2
|
|
||||||
},
|
|
||||||
},
|
|
||||||
layers: [
|
|
||||||
// 图层。图层指定了如何渲染数据源提供的数据
|
|
||||||
{
|
|
||||||
id: 'zhstLayer', //唯一id
|
|
||||||
type: 'raster', //类型 栅格。circle,symbol,line...
|
|
||||||
source: 'osm-tiles',
|
|
||||||
// 'source-layer': 'osmtiles',//数据源必须是type:vector
|
|
||||||
minZoom: 4, //最小层级
|
|
||||||
maxZoom: 17, //最大层级
|
|
||||||
renderingMode: '2d',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
interface MapProps {
|
|
||||||
onLoad?: (e: mapboxgl.MapboxEvent<undefined>) => void;
|
|
||||||
onDrawCreate?: () => void;
|
|
||||||
mapRef?: React.MutableRefObject<MapRef | undefined>;
|
|
||||||
style?: CSSProperties;
|
|
||||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
|
||||||
defaultMode?: string;
|
|
||||||
setIsReady?: (ready: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MapBox: React.FC<MapProps> = (props) => {
|
const MapBox: React.FC<MapProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
@ -62,13 +11,10 @@ const MapBox: React.FC<MapProps> = (props) => {
|
|||||||
children,
|
children,
|
||||||
mapRef,
|
mapRef,
|
||||||
onLoad,
|
onLoad,
|
||||||
defaultMode,
|
mapCenter = MAP_CENTER,
|
||||||
onDrawCreate,
|
mapConfig = {},
|
||||||
setIsReady,
|
|
||||||
...others
|
...others
|
||||||
} = props || {};
|
} = props || {};
|
||||||
let mapCneter = MAP_CENTER;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
<Map
|
<Map
|
||||||
@ -78,12 +24,11 @@ const MapBox: React.FC<MapProps> = (props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onLoad={(e) => {
|
onLoad={(e) => {
|
||||||
setIsReady && setIsReady(true);
|
|
||||||
onLoad && onLoad(e);
|
onLoad && onLoad(e);
|
||||||
}}
|
}}
|
||||||
style={{ width: '100%', height: 600, ...style }}
|
style={{ width: '100%', height: 600, ...style }}
|
||||||
{...MapConfig}
|
{...merge(defaultMapConfig, mapConfig)}
|
||||||
initialViewState={{ ...mapCneter, zoom: 10 }}
|
initialViewState={{ ...mapCenter, zoom: 10 }}
|
||||||
{...others}
|
{...others}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
42
packages/map/src/constants.ts
Normal file
42
packages/map/src/constants.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
export const mapboxAccessToken =
|
||||||
|
'pk.eyJ1IjoiZGluZ2xpMTIzIiwiYSI6ImNra204ODhjczBobTgyeHJ6MmJpZHMxNWgifQ.NbKrXh_hb2gvjr5CEMDnyQ';
|
||||||
|
export const MAP_CENTER = {
|
||||||
|
longitude: 120.2667694313269,
|
||||||
|
latitude: 30.180942826533766,
|
||||||
|
}; //地图中心
|
||||||
|
const MapUrl = 'http://10.0.0.120:30003/map';
|
||||||
|
export const defaultMapConfig = {
|
||||||
|
mapboxAccessToken,
|
||||||
|
maxZoom: 18,
|
||||||
|
minZoom: 4,
|
||||||
|
dragRotate: false,
|
||||||
|
mapStyle: {
|
||||||
|
version: 8,
|
||||||
|
name: 'Mapbox Streets',
|
||||||
|
// sprite: `${location.origin}/mapbox/sprite`, // 地图图标
|
||||||
|
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf', // 字体
|
||||||
|
sources: {
|
||||||
|
//数据源
|
||||||
|
'osm-tiles': {
|
||||||
|
type: 'raster', //栅格切片。vector:矢量切片
|
||||||
|
// Z-瓦片层级,一般支持0-18级,越大代表越清晰;
|
||||||
|
// X-瓦片列号,从西向东(0->360),依次0,1,2,……;
|
||||||
|
// Y-瓦片行号,从北向南(有些也可能是从南向北),依次0,1,2,……;
|
||||||
|
tiles: [`${MapUrl}/api/tilesets/mapfile/{z}/{x}/{y}.png`], //在线地址,先写死120
|
||||||
|
tileSize: 256, //切片的最小展示尺寸(可选,单位:像素,默认值为 512,即 1024/2
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layers: [
|
||||||
|
// 图层。图层指定了如何渲染数据源提供的数据
|
||||||
|
{
|
||||||
|
id: 'zhstLayer', //唯一id
|
||||||
|
type: 'raster', //类型 栅格。circle,symbol,line...
|
||||||
|
source: 'osm-tiles',
|
||||||
|
// 'source-layer': 'osmtiles',//数据源必须是type:vector
|
||||||
|
minZoom: 4, //最小层级
|
||||||
|
maxZoom: 17, //最大层级
|
||||||
|
renderingMode: '2d',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
@ -1,11 +1,23 @@
|
|||||||
import React from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { MapBox } from '@zhst/map';
|
import { MapBox } from '@zhst/map';
|
||||||
|
|
||||||
const demo = () => {
|
const demo = () => {
|
||||||
|
const mapRef = useRef(null);
|
||||||
|
const handleMapLoad = (e: mapboxgl.MapboxEvent<undefined>) => {
|
||||||
|
const map = e.target;
|
||||||
|
if (!map) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map.flyTo({
|
||||||
|
center: [120,30],
|
||||||
|
zoom: map?.getMaxZoom(),
|
||||||
|
});
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MapBox/>
|
<MapBox onLoad={handleMapLoad}
|
||||||
|
mapRef={mapRef}
|
||||||
|
style={{ width: '100%', height: 300 }}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,4 +8,13 @@ title: 快速上手
|
|||||||
|
|
||||||
<embed src="../README.md" ></embed>
|
<embed src="../README.md" ></embed>
|
||||||
<code src="./demo/basic.tsx">基本用法</code>
|
<code src="./demo/basic.tsx">基本用法</code>
|
||||||
|
## API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| mapRef | 标题 | React.MutableRefObject<MapRef或undefined> | '' | - |
|
||||||
|
| style | 地图样式 | cssProperties | {} | - |
|
||||||
|
| children | 内部元素 | JSX.Element或JSX.Element[]或Array<JSX.Element或undefined> | {} | - |
|
||||||
|
| mapConfig | 地图配置 | MapConfigProps | defaultMapConfig | - |
|
||||||
|
| onLoad | 地图加载事件 | function | ()=>{} | - |
|
||||||
|
| onDrawCreate | 地图绘制事件 | string | '' | - |
|
||||||
|
18
packages/map/src/interface.ts
Normal file
18
packages/map/src/interface.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { CSSProperties } from "react";
|
||||||
|
import { MapRef, MapStyle } from "react-map-gl";
|
||||||
|
|
||||||
|
export interface MapProps {
|
||||||
|
onLoad?: (e: mapboxgl.MapboxEvent<undefined>) => void;
|
||||||
|
mapRef?: React.MutableRefObject<MapRef | undefined>;
|
||||||
|
style?: CSSProperties;
|
||||||
|
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||||
|
mapConfig?: MapConfigProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MapConfigProps {
|
||||||
|
mapboxAccessToken?: string; //token
|
||||||
|
minZoom?: number; //最小层级
|
||||||
|
maxZoom?: number; //最大层级
|
||||||
|
dragRotate?: boolean; //是否支持拖拽旋转
|
||||||
|
mapStyle?: MapStyle; //地图样式
|
||||||
|
}
|
35
packages/map/src/utils.ts
Normal file
35
packages/map/src/utils.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const getRawType = (val) => {
|
||||||
|
return Object.prototype.toString.call(val).slice(8, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPlainObjectOrArray = (val) => {
|
||||||
|
return isPlainObject(val) || Array.isArray(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPlainObject = (val) => {
|
||||||
|
return getRawType(val) === 'Object'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const merge = (object, ...sources) => {
|
||||||
|
for(const source of sources) {
|
||||||
|
for(const key in source) {
|
||||||
|
if(source[key] === undefined && key in object) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(isPlainObjectOrArray(source[key])) {
|
||||||
|
if(getRawType(object[key] === getRawType(source[key]))) {
|
||||||
|
if(isPlainObject(object[key])) {
|
||||||
|
merge(object[key], source[key])
|
||||||
|
} else {
|
||||||
|
object[key] = object[key].concat(source[key])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
object[key] = source[key]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
object[key] = source[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
559
pnpm-lock.yaml
559
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user