mirror of https://gitee.com/antv-l7/antv-l7
improvement: update l7-react
This commit is contained in:
parent
8900aec8fc
commit
cfdb0bae8a
|
@ -1,8 +1,14 @@
|
|||
import { ILngLat, IMapService, IPoint, IPopup, TYPES } from '@antv/l7-core';
|
||||
import { bindAll, DOM } from '@antv/l7-utils';
|
||||
import {
|
||||
anchorTranslate,
|
||||
anchorType,
|
||||
applyAnchorClass,
|
||||
bindAll,
|
||||
DOM,
|
||||
} from '@antv/l7-utils';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { Container } from 'inversify';
|
||||
import { anchorTranslate, anchorType, applyAnchorClass } from './utils/anchor';
|
||||
|
||||
// marker 支持 dragger 未完成
|
||||
|
||||
export interface IMarkerOption {
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
import { ILngLat, IMapService, IPoint, IPopup, TYPES } from '@antv/l7-core';
|
||||
import { bindAll, DOM } from '@antv/l7-utils';
|
||||
import {
|
||||
ILngLat,
|
||||
IMapService,
|
||||
IPoint,
|
||||
IPopup,
|
||||
IPopupOption,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import {
|
||||
anchorTranslate,
|
||||
anchorType,
|
||||
applyAnchorClass,
|
||||
bindAll,
|
||||
DOM,
|
||||
} from '@antv/l7-utils';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { Container } from 'inversify';
|
||||
import { anchorTranslate, anchorType, applyAnchorClass } from './utils/anchor';
|
||||
|
||||
/** colse event */
|
||||
|
||||
export interface IPopupOption {
|
||||
closeButton: boolean;
|
||||
closeOnClick: boolean;
|
||||
maxWidth: string;
|
||||
anchor: anchorType;
|
||||
className: string;
|
||||
offsets: number[];
|
||||
}
|
||||
export default class Popup extends EventEmitter implements IPopup {
|
||||
private popupOption: IPopupOption;
|
||||
private mapsService: IMapService<unknown>;
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
import { anchorType } from '@antv/l7-utils';
|
||||
import { Container } from 'inversify';
|
||||
import { ILngLat, IMapService } from '../map/IMapService';
|
||||
|
||||
export interface IPopupOption {
|
||||
closeButton: boolean;
|
||||
closeOnClick: boolean;
|
||||
maxWidth: string;
|
||||
anchor: anchorType;
|
||||
className: string;
|
||||
offsets: number[];
|
||||
}
|
||||
export interface IPopup {
|
||||
addTo(scene: Container): this;
|
||||
remove(): void;
|
||||
|
|
|
@ -18,7 +18,7 @@ import { gl } from '../renderer/gl';
|
|||
import { IFramebuffer } from '../renderer/IFramebuffer';
|
||||
import { IPickingService } from './IPickingService';
|
||||
|
||||
const PICKSCALE = 10.0;
|
||||
const PICKSCALE = 1.0;
|
||||
@injectable()
|
||||
export default class PickingService implements IPickingService {
|
||||
@inject(TYPES.IRendererService)
|
||||
|
@ -155,9 +155,9 @@ export default class PickingService implements IPickingService {
|
|||
}
|
||||
let pickedColors: Uint8Array | undefined;
|
||||
pickedColors = readPixels({
|
||||
x: Math.round(xInDevicePixel / PICKSCALE),
|
||||
x: Math.floor(xInDevicePixel / PICKSCALE),
|
||||
// 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴
|
||||
y: Math.round((height - (y + 1) * window.devicePixelRatio) / PICKSCALE),
|
||||
y: Math.floor((height - (y + 1) * window.devicePixelRatio) / PICKSCALE),
|
||||
width: 1,
|
||||
height: 1,
|
||||
data: new Uint8Array(1 * 1 * 4),
|
||||
|
|
|
@ -108,14 +108,14 @@ float project_pixel(float pixel) {
|
|||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||
}
|
||||
return pixel;
|
||||
return pixel * -1.;
|
||||
}
|
||||
vec2 project_pixel(vec2 pixel) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||
}
|
||||
return pixel;
|
||||
return pixel * -1.;
|
||||
}
|
||||
|
||||
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
|
||||
|
|
|
@ -24,7 +24,7 @@ void main() {
|
|||
// radius(16-bit)
|
||||
v_radius = a_Size;
|
||||
|
||||
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width)) * -1.;
|
||||
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width));
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
|
|
|
@ -59,6 +59,25 @@ export default function BaseLayer(type: string, props: ILayerProps) {
|
|||
mapScene.render();
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited) {
|
||||
layer.updateLayerConfig(options);
|
||||
}
|
||||
}, [options?.maxZoom, options?.maxZoom, options?.visible, options?.autoFit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited && options && options.zIndex) {
|
||||
layer.setIndex(options.zIndex);
|
||||
}
|
||||
}, [options?.zIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited && options && options.blend) {
|
||||
layer.setBlend(options.blend);
|
||||
}
|
||||
}, [options?.blend]);
|
||||
|
||||
return (
|
||||
<LayerContext.Provider value={layer}>
|
||||
<Source layer={layer} source={source} />
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { IActiveOption, IScale, IScaleOptions, ISourceCFG } from '@antv/l7';
|
||||
import {
|
||||
BlendType,
|
||||
IActiveOption,
|
||||
IScale,
|
||||
IScaleOptions,
|
||||
ISourceCFG,
|
||||
} from '@antv/l7';
|
||||
import Active from './Active';
|
||||
import Color from './Color';
|
||||
import Filter from './Filter';
|
||||
|
@ -13,8 +19,9 @@ type CallBack = (...args: any[]) => any;
|
|||
export interface IAttributeOptions {
|
||||
field: string;
|
||||
value: string | number;
|
||||
values: string[] | number[] | string | number;
|
||||
values: string[] | number[] | string | number | CallBack;
|
||||
scale?: string;
|
||||
blend: keyof typeof BlendType;
|
||||
}
|
||||
|
||||
export interface IScaleAttributeOptions {
|
||||
|
@ -22,7 +29,16 @@ export interface IScaleAttributeOptions {
|
|||
value: IScale;
|
||||
values: IScaleOptions | IScale;
|
||||
}
|
||||
|
||||
export interface ILayerOption {
|
||||
name?: string;
|
||||
visible: boolean;
|
||||
zIndex: number;
|
||||
minZoom: number;
|
||||
maxZoom: number;
|
||||
autoFit: boolean;
|
||||
blend: keyof typeof BlendType;
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface IScaleOption {
|
||||
[key: string]: IScaleAttributeOptions;
|
||||
}
|
||||
|
@ -39,9 +55,7 @@ export interface IActiveOptions {
|
|||
option: IActiveOption | boolean;
|
||||
}
|
||||
export interface ILayerProps {
|
||||
options?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
options?: Partial<ILayerOption>;
|
||||
source: ISourceOptions;
|
||||
color: Partial<IAttributeOptions>;
|
||||
shape: Partial<IAttributeOptions>;
|
||||
|
|
|
@ -13,6 +13,9 @@ export const LayerEvent = React.memo((props: ILayerProps) => {
|
|||
|
||||
useEffect(() => {
|
||||
layer.on(type, handler);
|
||||
return () => {
|
||||
layer.off('type', handler);
|
||||
};
|
||||
}, [type]);
|
||||
return null;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import { IActiveOption, IImage, ILayer, Scene } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILoadImageProps {
|
||||
name: string;
|
||||
url: IImage;
|
||||
}
|
||||
export default React.memo(function LoadImage(props: ILoadImageProps) {
|
||||
const { name, url } = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
useEffect(() => {
|
||||
mapScene.addImage(name, url);
|
||||
}, [name, url]);
|
||||
return null;
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import { IMapConfig, Scene } from '@antv/l7';
|
||||
import { IMapConfig, Scene, Zoom } from '@antv/l7';
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import Mapbox from '@antv/l7-maps/lib/mapbox';
|
||||
|
@ -14,6 +14,8 @@ const MapboxScene = React.memo((props: IMapSceneConig) => {
|
|||
const { style, className, map } = props;
|
||||
const container = createRef();
|
||||
const [scene, setScene] = useState();
|
||||
|
||||
// 地图初始
|
||||
useEffect(() => {
|
||||
const sceneInstance = new Scene({
|
||||
id: container.current as HTMLDivElement,
|
||||
|
@ -26,6 +28,8 @@ const MapboxScene = React.memo((props: IMapSceneConig) => {
|
|||
sceneInstance.destroy();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 更新地图样式
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
|
@ -33,6 +37,32 @@ const MapboxScene = React.memo((props: IMapSceneConig) => {
|
|||
scene.setMapStyle(map.style);
|
||||
}, [map.style]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
scene.setZoom(map.zoom);
|
||||
}, [map.zoom, map.center, map.pitch, map.rotation]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
scene.setCenter(map.center);
|
||||
}, [map.center]);
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
scene.setPitch(map.pitch);
|
||||
}, [map.pitch]);
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
scene.setRotation(map.rotation);
|
||||
}, [map.rotation]);
|
||||
|
||||
return (
|
||||
<SceneContext.Provider value={scene}>
|
||||
{createElement(
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import {
|
||||
IActiveOption,
|
||||
IImage,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopupOption,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface IPopupProps {
|
||||
option: IPopupOption;
|
||||
lnglat: ILngLat;
|
||||
text: string;
|
||||
html: string;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
}
|
||||
export default React.memo(function LoadImage(props: IPopupProps) {
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
const { lnglat, html, text, children } = props;
|
||||
const [popup, setPopup] = React.useState();
|
||||
const el = document.createElement('div');
|
||||
useEffect(() => {
|
||||
const p = new Popup(props.option);
|
||||
if (lnglat) {
|
||||
p.setLnglat(lnglat);
|
||||
}
|
||||
if (html) {
|
||||
p.setHTML(html);
|
||||
}
|
||||
if (text) {
|
||||
p.setText(text);
|
||||
}
|
||||
if (children) {
|
||||
p.setDOMContent(el);
|
||||
}
|
||||
setPopup(p);
|
||||
}, []);
|
||||
return createPortal(children, el);
|
||||
});
|
|
@ -12,7 +12,7 @@ interface IMapSceneConig {
|
|||
map: IMapWrapper;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
}
|
||||
const MapScene = React.memo((props: IMapSceneConig) => {
|
||||
export default React.memo((props: IMapSceneConig) => {
|
||||
const { style, className, map, options } = props;
|
||||
const container = createRef();
|
||||
const [scene, setScene] = useState();
|
||||
|
@ -36,6 +36,8 @@ const MapScene = React.memo((props: IMapSceneConig) => {
|
|||
sceneInstance.destroy();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 更新地图
|
||||
useEffect(() => {
|
||||
if (!scene) {
|
||||
return;
|
||||
|
@ -57,5 +59,3 @@ const MapScene = React.memo((props: IMapSceneConig) => {
|
|||
</SceneContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
export { MapScene };
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { ILayer, Scene } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
type: string;
|
||||
handler: (...args: any[]) => void;
|
||||
}
|
||||
export const SceneEvent = React.memo((props: ILayerProps) => {
|
||||
const { type, handler } = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
|
||||
useEffect(() => {
|
||||
mapScene.on(type, handler);
|
||||
return () => {
|
||||
mapScene.off('type', handler);
|
||||
};
|
||||
}, [type]);
|
||||
return null;
|
||||
});
|
|
@ -1,11 +1,10 @@
|
|||
export * from './component/SceneContext';
|
||||
export { default as Scene } from './component/Scene';
|
||||
export { default as AMapScene } from './component/AMapScene';
|
||||
export { default as MapboxScene } from './component/MapboxScene';
|
||||
export { default as Scene } from './component/Scene';
|
||||
export * from './component/Layer';
|
||||
export { default as Control } from './component/Control';
|
||||
export { default as CustomControl } from './component/CustomControl';
|
||||
export { MapScene } from './component/Scene';
|
||||
export { PolygonLayer, LineLayer, PointLayer } from './component/Layer';
|
||||
export { LayerEvent } from './component/LayerEvent';
|
||||
export { useSceneValue, SceneContext } from './component/SceneContext';
|
||||
|
|
|
@ -5,5 +5,6 @@ export * from './geo';
|
|||
export * from './lru_cache';
|
||||
export * from './event';
|
||||
export * from './color';
|
||||
export * from './anchor';
|
||||
import * as Satistics from './statistics';
|
||||
export { DOM, Satistics };
|
||||
|
|
|
@ -46,10 +46,14 @@ export default class PointImage extends React.Component {
|
|||
y: 'latitude',
|
||||
},
|
||||
})
|
||||
.shape('triangle')
|
||||
// .shape('name', ['00', '01', '02'])
|
||||
.shape('name', 'text')
|
||||
.color('red')
|
||||
.active(true)
|
||||
.active(false)
|
||||
.size(20);
|
||||
// imageLayer.on('click', (e) => {
|
||||
// console.log(e);
|
||||
// });
|
||||
scene.addLayer(imageLayer);
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ export default class DashLineDemo extends React.Component {
|
|||
.source(await response.json())
|
||||
.size(1)
|
||||
.shape('line')
|
||||
.active({ color: 'red' })
|
||||
.color(
|
||||
'ELEV',
|
||||
[
|
||||
|
@ -44,7 +45,7 @@ export default class DashLineDemo extends React.Component {
|
|||
)
|
||||
.style({
|
||||
// lineType: 'dash',
|
||||
opacity: 0.5,
|
||||
opacity: 1.0,
|
||||
});
|
||||
|
||||
scene.addLayer(lineLayer);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { LineLayer, MapScene } from '@antv/l7-react';
|
||||
import { LineLayer, Scene } from '@antv/l7-react';
|
||||
import * as React from 'react';
|
||||
|
||||
export default React.memo(function Map() {
|
||||
|
@ -23,7 +23,7 @@ export default React.memo(function Map() {
|
|||
}, []);
|
||||
return (
|
||||
<>
|
||||
<MapScene
|
||||
<Scene
|
||||
map={amap}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
|
@ -40,20 +40,20 @@ export default React.memo(function Map() {
|
|||
data,
|
||||
}}
|
||||
size={{
|
||||
value: 1,
|
||||
values: 1,
|
||||
}}
|
||||
color={{
|
||||
value: '#fff',
|
||||
values: '#fff',
|
||||
}}
|
||||
shape={{
|
||||
value: 'line',
|
||||
values: 'line',
|
||||
}}
|
||||
style={{
|
||||
opacity: 1,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</MapScene>
|
||||
</Scene>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue