@pansy/react-mapbox-gl
Version:
🌍 基于 Mapbox GL 封装的 React 组件库
83 lines (72 loc) • 2.08 kB
text/typescript
import { assert } from '../../utils/assert';
import { isStyleLoaded } from '../../utils/isStyleLoaded';
import { deepEqual } from '../../utils/deepEqual';
import type {
Map as MapInstance,
SourceSpecification,
Source as MapboxSource,
GeoJSONSource,
ImageSource,
} from 'mapbox-gl';
import type { Source, SourceProps } from './types';
export function createSource<SourceT extends Source>(
map: MapInstance,
id: string,
props: SourceProps<SourceT>,
) {
if (isStyleLoaded(map)) {
const options = { ...props };
delete options.id;
delete options.children;
map.addSource(id, options as SourceSpecification);
return map.getSource(id);
}
}
export function updateSource<SourceT extends Source>(
source: MapboxSource,
props: SourceProps<SourceT>,
prevProps: SourceProps<SourceT>,
) {
assert(props.id === prevProps.id, 'source id changed');
assert(props.type === prevProps.type, 'source type changed');
let changedKey = '';
let changedKeyCount = 0;
for (const key in props) {
if (
key !== 'children' &&
key !== 'id' &&
// @ts-ignore
!deepEqual(prevProps[key], props[key])
) {
changedKey = key;
changedKeyCount++;
}
}
if (!changedKeyCount) {
return;
}
const type = props.type;
if (type === 'geojson') {
(source as GeoJSONSource).setData((props as any).data);
} else if (type === 'image') {
(source as ImageSource).updateImage({
url: (props as unknown as any).url,
coordinates: (props as unknown as any).coordinates,
});
} else if ('setCoordinates' in source && changedKeyCount === 1 && changedKey === 'coordinates') {
source.setCoordinates((props as any).coordinates!);
} else if ('setUrl' in source) {
switch (changedKey) {
case 'url':
source.setUrl((props as any).url!);
break;
case 'tiles':
source.setTiles((props as any).tiles!);
break;
default:
}
} else {
// eslint-disable-next-line
console.warn(`Unable to update <Source> prop: ${changedKey}`);
}
}