From 0fdb6d1b0dd16f9dcb1c7c6f547017af8c5b46a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=8A=E9=92=B1=E8=80=80?= Date: Thu, 22 Apr 2021 15:08:41 +0800 Subject: [PATCH] feat(many): gaode1.x -> gaode2.0 not finished --- .../coordinate/CoordinateSystemService.ts | 5 + .../coordinate/ICoordinateSystemService.ts | 3 + packages/core/src/services/map/IMapService.ts | 11 + .../core/src/services/scene/SceneService.ts | 28 +- packages/core/src/shaders/projection.glsl | 39 +- packages/layers/src/core/triangulation.ts | 50 +- .../src/line/shaders/line_arc_vert.glsl | 9 +- .../layers/src/line/shaders/line_vert.glsl | 11 +- .../layers/src/plugins/DataMappingPlugin.ts | 37 +- .../layers/src/plugins/DataSourcePlugin.ts | 9 +- .../layers/src/plugins/ShaderUniformPlugin.ts | 25 +- packages/layers/src/point/index.ts | 1 - packages/layers/src/point/models/fill.ts | 2 +- packages/layers/src/point/models/text.ts | 24 +- .../src/point/shaders/extrude_vert.glsl | 9 +- .../layers/src/point/shaders/fill_vert.glsl | 26 +- .../layers/src/point/shaders/image_vert.glsl | 10 +- .../layers/src/point/shaders/normal_vert.glsl | 18 +- .../layers/src/point/shaders/text_vert.glsl | 27 +- .../polygon/shaders/polygon_extrude_vert.glsl | 10 +- .../src/polygon/shaders/polygon_vert.glsl | 9 +- packages/layers/src/utils/extrude_polyline.ts | 349 ++++++++++ packages/maps/src/amap/map.ts | 5 +- packages/maps/src/amap2/Viewport.ts | 124 ++++ packages/maps/src/amap2/index.ts | 11 + packages/maps/src/amap2/logo.css | 3 + packages/maps/src/amap2/map.ts | 625 ++++++++++++++++++ packages/maps/src/amap2/theme.ts | 8 + packages/maps/src/index.ts | 3 +- packages/maps/src/map/map.ts | 3 +- packages/maps/src/mapbox/map.ts | 3 +- packages/maps/src/version.ts | 9 + packages/maps/typings/index.d.ts | 7 + packages/source/src/source.ts | 4 +- stories/Map/components/amap2demo.tsx | 88 +++ stories/Map/components/amap2demo_arcLine.tsx | 74 +++ stories/Map/components/amap2demo_extrude.tsx | 84 +++ stories/Map/components/amap2demo_image.tsx | 80 +++ stories/Map/components/amap2demo_polygon.tsx | 140 ++++ .../components/amap2demo_polygon_extrude.tsx | 132 ++++ stories/Map/components/amap2demo_text.tsx | 80 +++ stories/Map/components/amapdemo_extrude.tsx | 84 +++ stories/Map/components/mapCenter.tsx | 40 +- stories/Map/map.stories.tsx | 20 +- 44 files changed, 2253 insertions(+), 86 deletions(-) create mode 100644 packages/maps/src/amap2/Viewport.ts create mode 100644 packages/maps/src/amap2/index.ts create mode 100644 packages/maps/src/amap2/logo.css create mode 100644 packages/maps/src/amap2/map.ts create mode 100644 packages/maps/src/amap2/theme.ts create mode 100644 packages/maps/src/version.ts create mode 100644 stories/Map/components/amap2demo.tsx create mode 100644 stories/Map/components/amap2demo_arcLine.tsx create mode 100644 stories/Map/components/amap2demo_extrude.tsx create mode 100644 stories/Map/components/amap2demo_image.tsx create mode 100644 stories/Map/components/amap2demo_polygon.tsx create mode 100644 stories/Map/components/amap2demo_polygon_extrude.tsx create mode 100644 stories/Map/components/amap2demo_text.tsx create mode 100644 stories/Map/components/amapdemo_extrude.tsx diff --git a/packages/core/src/services/coordinate/CoordinateSystemService.ts b/packages/core/src/services/coordinate/CoordinateSystemService.ts index 8bf04809dc..cbd2f400b5 100644 --- a/packages/core/src/services/coordinate/CoordinateSystemService.ts +++ b/packages/core/src/services/coordinate/CoordinateSystemService.ts @@ -3,6 +3,7 @@ import { inject, injectable } from 'inversify'; import { TYPES } from '../../types'; import { getDistanceScales } from '../../utils/project'; import { ICameraService } from '../camera/ICameraService'; +// import { IMapService } from '../map/IMapService' import { CoordinateSystem, ICoordinateSystemService, @@ -17,6 +18,10 @@ export default class CoordinateSystemService @inject(TYPES.ICameraService) private readonly cameraService: ICameraService; + // map.getCenter + // @inject(TYPES.IMapService) + // private readonly mapService: IMapService + /** * 1. Web 墨卡托坐标系 * 2. 偏移经纬度,用于解决高精度抖动问题 diff --git a/packages/core/src/services/coordinate/ICoordinateSystemService.ts b/packages/core/src/services/coordinate/ICoordinateSystemService.ts index 8bbc211970..ca3e0f2d6f 100644 --- a/packages/core/src/services/coordinate/ICoordinateSystemService.ts +++ b/packages/core/src/services/coordinate/ICoordinateSystemService.ts @@ -17,6 +17,7 @@ export enum CoordinateSystem { P20 = 5.0, P20_OFFSET = 6.0, METER_OFFSET = 7.0, + P20_2 = 8.0, } // 后续传入 Shader 的变量 @@ -27,6 +28,8 @@ export const CoordinateUniform = { PixelsPerDegree: 'u_PixelsPerDegree', PixelsPerDegree2: 'u_PixelsPerDegree2', PixelsPerMeter: 'u_PixelsPerMeter', + + Mvp: 'u_Mvp', }; export interface ICoordinateSystemService { diff --git a/packages/core/src/services/map/IMapService.ts b/packages/core/src/services/map/IMapService.ts index 6207cbb9e9..fe307857ac 100644 --- a/packages/core/src/services/map/IMapService.ts +++ b/packages/core/src/services/map/IMapService.ts @@ -30,8 +30,10 @@ export interface IMapWrapper { } export interface IMapService { + version: string; map: RawMap; init(): void; + initViewPort?(): void; destroy(): void; onCameraChanged(callback: (viewport: IViewport) => void): void; // init map @@ -85,6 +87,12 @@ export interface IMapService { scale: [number, number, number], origin: IMercator, ): number[]; + lngLatToCoord?(lnglat: [number, number]): [number, number]; + lngLatToCoords?( + lnglatArray: number[][][] | number[][], + ): number[][][] | number[][] | number[][][] | number[][]; + // lngLatToCoords?(lnglatArray: any): any; + getCustomCoordCenter?(): [number, number]; exportMap(type: 'jpg' | 'png'): string; } @@ -178,6 +186,9 @@ export interface IMapCamera { center: [number, number]; // 相机高度 cameraHeight: number; + cameraPosition?: [number, number, number]; + up?: [number, number, number]; + lookAt?: [number, number, number]; // 偏移原点,例如 P20 坐标系下 offsetOrigin: [number, number]; } diff --git a/packages/core/src/services/scene/SceneService.ts b/packages/core/src/services/scene/SceneService.ts index eb94c3fdae..75c0fcc246 100644 --- a/packages/core/src/services/scene/SceneService.ts +++ b/packages/core/src/services/scene/SceneService.ts @@ -139,15 +139,32 @@ export default class Scene extends EventEmitter implements ISceneService { */ this.hooks.init.tapPromise('initMap', async () => { // 等待首次相机同步 - await new Promise((resolve) => { + await new Promise((resolve) => { this.map.onCameraChanged((viewport: IViewport) => { this.cameraService.init(); this.cameraService.update(viewport); - resolve(); + if (this.map.version !== 'GAODE2.x') { + // not amap2 + resolve(); + } }); - this.map.init(); + + if (this.map.version !== 'GAODE2.x') { + // not amap2 + this.map.init(); + } else { + // amap2 + resolve(); + } }); + + if (this.map.version === 'GAODE2.x' && this.map.initViewPort) { + // amap2 + await this.map.init(); + this.map.initViewPort(); + } // this.controlService.addControls(); + // 重新绑定非首次相机更新事件 this.map.onCameraChanged(this.handleMapCameraChanged); this.map.addMarkerContainer(); @@ -208,7 +225,6 @@ export default class Scene extends EventEmitter implements ISceneService { // 执行异步并行初始化任务 // @ts-ignore this.initPromise = this.hooks.init.promise(); - this.render(); } @@ -222,11 +238,11 @@ export default class Scene extends EventEmitter implements ISceneService { if (this.rendering || this.destroyed) { return; } - this.rendering = true; // 首次初始化,或者地图的容器被强制销毁的需要重新初始化 if (!this.inited) { // 还未初始化完成需要等待 + await this.initPromise; if (this.destroyed) { this.destroy(); @@ -243,9 +259,7 @@ export default class Scene extends EventEmitter implements ISceneService { // 尝试初始化未初始化的图层 this.layerService.renderLayers(); // 组件需要等待layer 初始化完成之后添加 - this.logger.debug(`scene ${this.id} render`); - this.rendering = false; } diff --git a/packages/core/src/shaders/projection.glsl b/packages/core/src/shaders/projection.glsl index 0ecd325e51..c5eadf8143 100644 --- a/packages/core/src/shaders/projection.glsl +++ b/packages/core/src/shaders/projection.glsl @@ -10,6 +10,8 @@ #define COORDINATE_SYSTEM_P20_OFFSET 6.0 #define COORDINATE_SYSTEM_METER_OFFSET 7.0 +#define COORDINATE_SYSTEM_P20_2 8.0 + uniform mat4 u_ViewMatrix; uniform mat4 u_ProjectionMatrix; uniform mat4 u_ViewProjectionMatrix; @@ -28,6 +30,8 @@ uniform float u_DevicePixelRatio; uniform float u_FocalDistance; uniform vec3 u_CameraPosition; +// uniform mat4 u_Mvp; + // web mercator coords -> world coords vec2 project_mercator(vec2 lnglat) { float x = lnglat.x; @@ -38,7 +42,13 @@ vec2 project_mercator(vec2 lnglat) { } float project_scale(float meters) { - return meters * u_PixelsPerMeter.z; + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { + // 因为高德2.0和1.x的相机控制方向相反,而u_PixelsPerMeter的计算与此相关(计算结果也相反) + // 可通过 shaderUniformPlugin -> CoordinateSystemService -> project 的顺序查看区别 + return meters * u_PixelsPerMeter.z * -1.0; + } else { + return meters * u_PixelsPerMeter.z; + } } @@ -69,6 +79,10 @@ vec3 reverse_offset_normal(vec3 vector) { if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 ||u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET ) { return vector * vec3(1.0, -1.0, 1.0); } + + if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.0 + return vector * vec3(1.0, -1.0, 1.0); + } return vector; } @@ -97,6 +111,17 @@ vec4 project_position(vec4 position) { position.w ); } + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { + // return vec4( + // (position.xy * WORLD_SCALE * u_ZoomScale) * vec2(1., -1.), + // project_scale(position.z), + // position.w); + return vec4( + position.xy, + project_scale(position.z), + position.w); + } return position; // TODO: 瓦片坐标系 & 常规世界坐标系 @@ -111,6 +136,10 @@ float project_pixel(float pixel) { // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 return pixel * pow(2.0, (19.0 - u_Zoom)); } + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { + // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 + return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)); + } return pixel; } vec2 project_pixel(vec2 pixel) { @@ -118,6 +147,10 @@ vec2 project_pixel(vec2 pixel) { // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 return pixel * pow(2.0, (19.0 - u_Zoom)); } + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { + // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 + return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)); + } return pixel * -1.; } @@ -127,6 +160,7 @@ vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatr // Needs to be divided with project_uCommonUnitsPerMeter position.w *= u_PixelsPerMeter.z; } + return viewProjectionMatrix * position + center; } @@ -153,5 +187,4 @@ vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjec bool isEqual( float a, float b) { return a< b + 0.001 && a > b - 0.001; -} - +} \ No newline at end of file diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts index c95eebf878..dfd266c3eb 100644 --- a/packages/layers/src/core/triangulation.ts +++ b/packages/layers/src/core/triangulation.ts @@ -69,19 +69,48 @@ export function PointImageTriangulation(feature: IEncodeFeature) { * @param feature 映射feature */ export function LineTriangulation(feature: IEncodeFeature) { - const { coordinates } = feature; - let path = coordinates as number[][][] | number[][]; - if (!Array.isArray(path[0][0])) { - path = [coordinates] as number[][][]; - } + const { coordinates, originCoordinates, version } = feature; + // let path = coordinates as number[][][] | number[][]; + // if (!Array.isArray(path[0][0])) { + // path = [coordinates] as number[][][]; + // } + const line = new ExtrudePolyline({ dash: true, - join: 'bevel', // - }); - path.forEach((item: any) => { - // 处理带洞的多边形 - line.extrude(item as number[][]); + join: 'bevel', }); + + if (version === 'GAODE2.x') { + // 处理高德2.0几何体构建 + let path1 = coordinates as number[][][] | number[][]; + if (!Array.isArray(path1[0][0])) { + path1 = [coordinates] as number[][][]; + } + let path2 = originCoordinates as number[][][] | number[][]; + if (!Array.isArray(path2[0][0])) { + path2 = [originCoordinates] as number[][][]; + } + + path1.forEach((item: any) => { + // 处理带洞的多边形 + line.extrude1(item as number[][]); + }); + + path2.forEach((item: any) => { + // 处理带洞的多边形 + line.extrude2(item as number[][]); + }); + } else { + // 处理非高德2.0的几何体构建 + let path = coordinates as number[][][] | number[][]; + if (!Array.isArray(path[0][0])) { + path = [coordinates] as number[][][]; + } + path.forEach((item: any) => { + line.extrude(item as number[][]); + }); + } + const linebuffer = line.complex; return { vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ] @@ -207,6 +236,7 @@ export function LineArcTriangulation(feature: IEncodeFeature) { ); } } + // console.log('positions', positions) return { vertices: positions, indices: indexArray, diff --git a/packages/layers/src/line/shaders/line_arc_vert.glsl b/packages/layers/src/line/shaders/line_arc_vert.glsl index 5fcbcfd42a..013c210346 100644 --- a/packages/layers/src/line/shaders/line_arc_vert.glsl +++ b/packages/layers/src/line/shaders/line_arc_vert.glsl @@ -6,6 +6,7 @@ attribute vec3 a_Position; attribute vec4 a_Instance; attribute float a_Size; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; uniform float segmentNumber; uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; varying vec4 v_color; @@ -78,8 +79,14 @@ void main() { vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio), 0.0, 1.0)); vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio), 0.0, 1.0)); v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y); + vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y)); - gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0)); + // gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0)); + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0)); + } else { + gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0)); + } setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/line_vert.glsl b/packages/layers/src/line/shaders/line_vert.glsl index 7b0495a44d..848948b3a0 100644 --- a/packages/layers/src/line/shaders/line_vert.glsl +++ b/packages/layers/src/line/shaders/line_vert.glsl @@ -13,6 +13,7 @@ attribute float a_Total_Distance; attribute float a_Distance; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; uniform float u_line_type: 0.0; uniform vec4 u_dash_array: [10.0, 5.,0, 0]; uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; @@ -42,7 +43,15 @@ void main() { vec2 offset = project_pixel(size.xy); v_side = a_Miter * a_Size.x; vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0)); - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0)); + + // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0)); + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + // gl_Position = u_Mvp * (vec4(project_pos.xy + offset, a_Size.y, 1.0)); + gl_Position = u_Mvp * (vec4(project_pos.xy + offset, a_Size.y, 1.0)); + } else { + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0)); + } setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/plugins/DataMappingPlugin.ts b/packages/layers/src/plugins/DataMappingPlugin.ts index cdc8082b4e..86ab15bc87 100644 --- a/packages/layers/src/plugins/DataMappingPlugin.ts +++ b/packages/layers/src/plugins/DataMappingPlugin.ts @@ -3,7 +3,9 @@ import { IGlobalConfigService, ILayer, ILayerPlugin, + ILngLat, ILogService, + IMapService, IParseDataItem, IStyleAttribute, IStyleAttributeService, @@ -11,6 +13,7 @@ import { } from '@antv/l7-core'; import { rgb2arr } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; +import { cloneDeep } from 'lodash'; @injectable() export default class DataMappingPlugin implements ILayerPlugin { @@ -20,6 +23,9 @@ export default class DataMappingPlugin implements ILayerPlugin { @inject(TYPES.ILogService) private readonly logger: ILogService; + @inject(TYPES.IMapService) + private readonly mapService: IMapService; + public apply( layer: ILayer, { @@ -99,7 +105,7 @@ export default class DataMappingPlugin implements ILayerPlugin { data: IParseDataItem[], predata?: IEncodeFeature[], ): IEncodeFeature[] { - return data.map((record: IParseDataItem, i) => { + const mappedData = data.map((record: IParseDataItem, i) => { const preRecord = predata ? predata[i] : {}; const encodeRecord: IEncodeFeature = { id: record._id, @@ -124,6 +130,35 @@ export default class DataMappingPlugin implements ILayerPlugin { }); return encodeRecord; }) as IEncodeFeature[]; + + // console.log('mappedData', mappedData) + // 根据地图的类型判断是否需要对点位数据进行处理 + if (this.mapService.version === 'GAODE2.x') { + // 若是高德2.0则需要对坐标进行相对偏移 + + if (typeof mappedData[0].coordinates[0] === 'number') { + // 单个的点数据 + // @ts-ignore + mappedData.map((d) => { + d.version = 'GAODE2.x'; + // @ts-ignore + d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据) + // @ts-ignore + d.coordinates = this.mapService.lngLatToCoord(d.coordinates); + }); + } else { + // 连续的线、面数据 + // @ts-ignore + mappedData.map((d) => { + d.version = 'GAODE2.x'; + // @ts-ignore + d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据) + // @ts-ignore + d.coordinates = this.mapService.lngLatToCoords(d.coordinates); + }); + } + } + return mappedData; } private applyAttributeMapping( diff --git a/packages/layers/src/plugins/DataSourcePlugin.ts b/packages/layers/src/plugins/DataSourcePlugin.ts index 44eb96d0a3..b0675ac5ea 100644 --- a/packages/layers/src/plugins/DataSourcePlugin.ts +++ b/packages/layers/src/plugins/DataSourcePlugin.ts @@ -1,6 +1,13 @@ -import { ILayer, ILayerPlugin, IMapService, TYPES } from '@antv/l7-core'; +import { + ILayer, + ILayerPlugin, + ILngLat, + IMapService, + TYPES, +} from '@antv/l7-core'; import Source from '@antv/l7-source'; import { injectable } from 'inversify'; +import { cloneDeep } from 'lodash'; @injectable() export default class DataSourcePlugin implements ILayerPlugin { diff --git a/packages/layers/src/plugins/ShaderUniformPlugin.ts b/packages/layers/src/plugins/ShaderUniformPlugin.ts index c0a7ca9c6c..c8f565b4fe 100644 --- a/packages/layers/src/plugins/ShaderUniformPlugin.ts +++ b/packages/layers/src/plugins/ShaderUniformPlugin.ts @@ -5,6 +5,7 @@ import { ICoordinateSystemService, ILayer, ILayerPlugin, + IMapService, IRendererService, TYPES, } from '@antv/l7-core'; @@ -29,13 +30,28 @@ export default class ShaderUniformPlugin implements ILayerPlugin { @inject(TYPES.IRendererService) private readonly rendererService: IRendererService; + @inject(TYPES.IMapService) + private readonly mapService: IMapService; + public apply(layer: ILayer) { + const version = this.mapService.version; + + let mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // default matrix (for gaode2.x) + // let sceneCenterMKT = [0, 0] layer.hooks.beforeRender.tap('ShaderUniformPlugin', () => { // 重新计算坐标系参数 this.coordinateSystemService.refresh(); + if (version === 'GAODE2.x') { + // @ts-ignore + mvp = this.mapService.map.customCoords.getMVPMatrix(); + // mvp = amapCustomCoords.getMVPMatrix() + // @ts-ignore + // sceneCenterMKT = this.mapService.getCustomCoordCenter() + } + const { width, height } = this.rendererService.getViewportSize(); - layer.models.forEach((model) => + layer.models.forEach((model) => { model.addUniforms({ // 相机参数,包含 VP 矩阵、缩放等级 [CameraUniform.ProjectionMatrix]: this.cameraService.getProjectionMatrix(), @@ -52,13 +68,16 @@ export default class ShaderUniformPlugin implements ILayerPlugin { [CoordinateUniform.PixelsPerDegree]: this.coordinateSystemService.getPixelsPerDegree(), [CoordinateUniform.PixelsPerDegree2]: this.coordinateSystemService.getPixelsPerDegree2(), [CoordinateUniform.PixelsPerMeter]: this.coordinateSystemService.getPixelsPerMeter(), + // 坐标系是高德2.0的时候单独计算 + [CoordinateUniform.Mvp]: mvp, + // u_SceneCenterMKT: sceneCenterMKT, // 其他参数,例如视口大小、DPR 等 u_ViewportSize: [width, height], u_DevicePixelRatio: window.devicePixelRatio, u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0, - }), - ); + }); + }); // TODO:脏检查,决定是否需要渲染 }); diff --git a/packages/layers/src/point/index.ts b/packages/layers/src/point/index.ts index 32226817c5..fb9655337a 100644 --- a/packages/layers/src/point/index.ts +++ b/packages/layers/src/point/index.ts @@ -11,7 +11,6 @@ export default class PointLayer extends BaseLayer { public buildModels() { const modelType = this.getModelType(); this.layerModel = new PointModels[modelType](this); - this.models = this.layerModel.initModels(); } public rebuildModels() { diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index cd47da65f7..3fa71d2493 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -67,7 +67,7 @@ export default class FillModel extends BaseModel { vertexShader: pointFillVert, fragmentShader: pointFillFrag, triangulation: PointFillTriangulation, - depth: { enable: true }, + depth: { enable: false }, blend: this.getBlend(), }), ]; diff --git a/packages/layers/src/point/models/text.ts b/packages/layers/src/point/models/text.ts index 689d0c4f69..07424931a3 100644 --- a/packages/layers/src/point/models/text.ts +++ b/packages/layers/src/point/models/text.ts @@ -330,8 +330,7 @@ export default class TextModel extends BaseModel { } = this.layer.getLayerConfig() as IPointTextLayerStyleOptions; const data = this.layer.getEncodedData(); this.glyphInfo = data.map((feature: IEncodeFeature) => { - const { shape = '', coordinates, id, size = 1 } = feature; - + const { shape = '', id, size = 1 } = feature; const shaping = shapeText( shape.toString(), mapping, @@ -345,17 +344,28 @@ export default class TextModel extends BaseModel { const glyphQuads = getGlyphQuads(shaping, textOffset, false); feature.shaping = shaping; feature.glyphQuads = glyphQuads; - feature.centroid = calculteCentroid(coordinates); + // feature.centroid = calculteCentroid(coordinates); + + feature.centroid = calculteCentroid(feature.coordinates); + // if (feature.version === 'GAODE2.x') { + // // 此时地图为高德2.0 + // feature.originCentroid = calculteCentroid(feature.originCoordinates); + // } else { + // // 此时地图不是高德2.0 originCentroid == centroid + // feature.originCentroid = feature.centroid; + // } + feature.originCentroid = feature.version === 'GAODE2.x'?calculteCentroid(feature.originCoordinates):feature.originCentroid = feature.centroid; + this.glyphInfoMap[id as number] = { shaping, glyphQuads, - centroid: calculteCentroid(coordinates), + centroid: calculteCentroid(feature.coordinates), }; return feature; }); } /** - * 文字避让 + * 文字避让 depend on originCentorid */ private filterGlyphs() { const { @@ -374,7 +384,9 @@ export default class TextModel extends BaseModel { const collisionIndex = new CollisionIndex(width, height); const filterData = this.glyphInfo.filter((feature: IEncodeFeature) => { const { shaping, id = 0 } = feature; - const centroid = feature.centroid as [number, number]; + // const centroid = feature.centroid as [number, number]; + // const centroid = feature.originCentroid as [number, number]; + const centroid = (feature.version === 'GAODE2.x'?feature.originCentroid:feature.centroid) as [number, number]; const size = feature.size as number; const fontScale: number = size / 24; const pixels = this.mapService.lngLatToContainer(centroid); diff --git a/packages/layers/src/point/shaders/extrude_vert.glsl b/packages/layers/src/point/shaders/extrude_vert.glsl index ecf797db05..c15eb4d37c 100644 --- a/packages/layers/src/point/shaders/extrude_vert.glsl +++ b/packages/layers/src/point/shaders/extrude_vert.glsl @@ -11,6 +11,7 @@ attribute vec3 a_Size; attribute vec3 a_Normal; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; uniform vec2 u_offsets; varying vec4 v_color; @@ -30,6 +31,12 @@ void main() { float lightWeight = calc_lighting(pos); v_color =vec4(a_Color.rgb * lightWeight, a_Color.w); - gl_Position = project_common_position_to_clipspace(pos); + // gl_Position = project_common_position_to_clipspace(pos); + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * pos; + } else { + gl_Position = project_common_position_to_clipspace(pos); + } setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/fill_vert.glsl b/packages/layers/src/point/shaders/fill_vert.glsl index 4ecb2c2d4c..ff6ff6ed89 100644 --- a/packages/layers/src/point/shaders/fill_vert.glsl +++ b/packages/layers/src/point/shaders/fill_vert.glsl @@ -4,6 +4,7 @@ attribute vec2 a_Extrude; attribute float a_Size; attribute float a_Shape; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; uniform float u_stroke_width : 2; uniform vec2 u_offsets; @@ -16,24 +17,16 @@ varying float v_radius; #pragma include "picking" void main() { + vec2 extrude = a_Extrude; + float shape_type = a_Shape; + float newSize = setPickingSize(a_Size); + // unpack color(vec2) v_color = a_Color; - vec2 extrude = a_Extrude; - - float shape_type = a_Shape; - - float newSize = setPickingSize(a_Size); // radius(16-bit) v_radius = newSize; - vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets); - vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); - - - - - // TODO: billboard // anti-alias float antialiasblur = 1.0 / u_DevicePixelRatio / (newSize + u_stroke_width); @@ -41,8 +34,15 @@ void main() { // construct point coords v_data = vec4(extrude, antialiasblur,shape_type); - setPickingColor(a_PickingColor); + vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets); + 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, project_pixel(setPickingOrder(0.0)), 1.0)); + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * vec4(project_pos.xy + offset, 0.0, 1.0); + } else { gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0)); + } + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/image_vert.glsl b/packages/layers/src/point/shaders/image_vert.glsl index dd55e41724..e4a9b04559 100644 --- a/packages/layers/src/point/shaders/image_vert.glsl +++ b/packages/layers/src/point/shaders/image_vert.glsl @@ -6,6 +6,7 @@ attribute float a_Size; varying vec4 v_color; varying vec2 v_uv; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; uniform float u_stroke_width : 1; uniform vec2 u_offsets; varying float v_size; @@ -19,7 +20,14 @@ void main() { vec4 project_pos = project_position(vec4(a_Position, 1.0)); v_size = a_Size; vec2 offset = project_pixel(u_offsets); - gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0)); + + // gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0)); + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0); + } else { + gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0)); + } gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio; setPickingColor(a_PickingColor); diff --git a/packages/layers/src/point/shaders/normal_vert.glsl b/packages/layers/src/point/shaders/normal_vert.glsl index a721eaa72e..000895e6d1 100644 --- a/packages/layers/src/point/shaders/normal_vert.glsl +++ b/packages/layers/src/point/shaders/normal_vert.glsl @@ -1,6 +1,7 @@ attribute vec3 a_Position; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; attribute float a_Size; attribute vec4 a_Color; varying vec4 v_color; @@ -11,9 +12,18 @@ uniform vec2 u_offsets; #pragma include "picking" void main() { v_color = a_Color; - vec2 offset = project_pixel(u_offsets); - vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.); - gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w)); + // vec2 offset = project_pixel(u_offsets); + // vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.); + // gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w));\ + // + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * vec4(a_Position, 1.0); + } else { // else + vec2 offset = project_pixel(u_offsets); + vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.); + gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w)); + } + gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio; - setPickingColor(a_PickingColor); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/text_vert.glsl b/packages/layers/src/point/shaders/text_vert.glsl index 4c279f8bd6..40d00e68a9 100644 --- a/packages/layers/src/point/shaders/text_vert.glsl +++ b/packages/layers/src/point/shaders/text_vert.glsl @@ -10,6 +10,7 @@ attribute float a_Rotate; uniform vec2 u_sdf_map_size; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; varying vec2 v_uv; varying float v_gamma_scale; @@ -25,15 +26,25 @@ void main() { // 文本缩放比例 float fontScale = a_Size / FONT_SIZE; - v_fontScale = fontScale; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + v_fontScale = fontScale; - vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); - highp float angle_sin = sin(a_Rotate); - highp float angle_cos = cos(a_Rotate); - mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); - gl_Position = vec4(projected_position.xy / projected_position.w - + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0); + vec4 project_pos = project_position(vec4(a_Position, 1.0)); + // vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + + highp float angle_sin = sin(a_Rotate); + highp float angle_cos = cos(a_Rotate); + mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); + + // gl_Position = vec4(projected_position.xy / projected_position.w + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0); + + vec4 projected_position; + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + projected_position = u_Mvp * (vec4(a_Position.xyz, 1.0)); + } else { // else + projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + } + + gl_Position = vec4(projected_position.xy / projected_position.w + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0); v_gamma_scale = gl_Position.w; setPickingColor(a_PickingColor); diff --git a/packages/layers/src/polygon/shaders/polygon_extrude_vert.glsl b/packages/layers/src/polygon/shaders/polygon_extrude_vert.glsl index f0f0245ed3..715a5c8cf8 100644 --- a/packages/layers/src/polygon/shaders/polygon_extrude_vert.glsl +++ b/packages/layers/src/polygon/shaders/polygon_extrude_vert.glsl @@ -9,6 +9,7 @@ attribute vec3 a_Position; attribute vec3 a_Normal; attribute float a_Size; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; varying vec4 v_Color; @@ -20,7 +21,14 @@ void main() { vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0); vec4 project_pos = project_position(pos); - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + // gl_Position = u_Mvp * (vec4(project_pos.xyz * vec3(1.0, 1.0, -1.0), 1.0)); + gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0)); + } else { + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + } float lightWeight = calc_lighting(pos); // v_Color = a_Color; diff --git a/packages/layers/src/polygon/shaders/polygon_vert.glsl b/packages/layers/src/polygon/shaders/polygon_vert.glsl index 8f83442e9c..1ac57b0e7d 100644 --- a/packages/layers/src/polygon/shaders/polygon_vert.glsl +++ b/packages/layers/src/polygon/shaders/polygon_vert.glsl @@ -3,6 +3,7 @@ attribute vec3 a_Position; attribute vec3 a_Normal; attribute float a_Size; uniform mat4 u_ModelMatrix; +uniform mat4 u_Mvp; varying vec4 v_Color; @@ -12,7 +13,13 @@ varying vec4 v_Color; void main() { v_Color = a_Color; vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + + if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x + gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0)); + } else { + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + } setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/utils/extrude_polyline.ts b/packages/layers/src/utils/extrude_polyline.ts index be92556998..83febd3bc1 100644 --- a/packages/layers/src/utils/extrude_polyline.ts +++ b/packages/layers/src/utils/extrude_polyline.ts @@ -115,6 +115,62 @@ export default class ExtrudePolyline { complex.startIndex = complex.positions.length / 6; return complex; } + public extrude1(points: number[][]) { + const complex = this.complex; + if (points.length <= 1) { + return complex; + } + this.lastFlip = -1; + this.started = false; + this.normal = null; + this.totalDistance = 0; + // 去除数组里重复的点 + // points = getArrayUnique(points); + const total = points.length; + let count = complex.startIndex; + for (let i = 1; i < total; i++) { + const last = points[i - 1] as vec2; + const cur = points[i] as vec2; + const next = i < points.length - 1 ? points[i + 1] : null; + const amt = this.segment1(complex, count, last, cur, next as vec2); + count += amt; + } + if (this.dash) { + for (let i = 0; i < complex.positions.length / 6; i++) { + complex.positions[i * 6 + 5] = this.totalDistance; + } + } + complex.startIndex = complex.positions.length / 6; + return complex; + } + public extrude2(points: number[][]) { + const complex = this.complex; + if (points.length <= 1) { + return complex; + } + this.lastFlip = -1; + this.started = false; + this.normal = null; + this.totalDistance = 0; + // 去除数组里重复的点 + // points = getArrayUnique(points); + const total = points.length; + let count = complex.startIndex; + for (let i = 1; i < total; i++) { + const last = points[i - 1] as vec2; + const cur = points[i] as vec2; + const next = i < points.length - 1 ? points[i + 1] : null; + const amt = this.segment2(complex, count, last, cur, next as vec2); + count += amt; + } + if (this.dash) { + for (let i = 0; i < complex.positions.length / 6; i++) { + complex.positions[i * 6 + 5] = this.totalDistance; + } + } + complex.startIndex = complex.positions.length / 6; + return complex; + } private segment( complex: any, index: number, @@ -329,6 +385,285 @@ export default class ExtrudePolyline { } return count; } + private segment1( + complex: any, + index: number, + last: vec2, + cur: vec2, + next: vec2, + ) { + let count = 0; + const indices = complex.indices; + const positions = complex.positions; + const capSquare = this.cap === 'square'; + const joinBevel = this.join === 'bevel'; + const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number]; + const flatLast = aProjectFlat([last[0], last[1]]) as [number, number]; + direction(lineA, flatCur, flatLast); + let segmentDistance = 0; + if (this.dash) { + segmentDistance = this.lineSegmentDistance(flatCur, flatLast); + this.totalDistance += segmentDistance; + } + + if (!this.normal) { + this.normal = vec2.create(); + computeNormal(this.normal, lineA); + } + if (!this.started) { + this.started = true; + + // if the end cap is type square, we can just push the verts out a bit + if (capSquare) { + // vec2.scaleAndAdd(capEnd, last, lineA, -this.thickness); + const out1 = vec2.create(); + const out2 = vec2.create(); + vec2.add(out1, this.normal, lineA); + vec2.add(out2, this.normal, lineA); + + positions.push( + last[0], + last[1], + 0, + this.totalDistance - segmentDistance, + -this.thickness, + 0, + ); + positions.push( + last[0], + last[1], + 0, + this.totalDistance - segmentDistance, + this.thickness, + 0, + ); + } else { + this.extrusionsPosition( + positions, + last, + this.thickness, + this.totalDistance - segmentDistance, + ); + } + } + + indices.push(index + 0, index + 1, index + 2); + + if (!next) { + computeNormal(this.normal, lineA); + if (capSquare) { + const out1 = vec2.create(); + const out2 = vec2.create(); + vec2.sub(out2, lineA, this.normal); + vec2.add(out1, lineA, this.normal); + + positions.push( + cur[0], + cur[1], + 0, + this.totalDistance, + this.thickness, + 0, + ); + positions.push( + cur[0], + cur[1], + 0, + this.totalDistance, + this.thickness, + 0, + ); + } else { + this.extrusionsPosition( + positions, + cur, + this.thickness, + this.totalDistance, + ); + } + indices.push( + ...(this.lastFlip === 1 + ? [index, index + 2, index + 3] + : [index + 2, index + 1, index + 3]), + ); + count += 2; + } else { + const flatNext = aProjectFlat([next[0], next[1]]) as [number, number]; + if (isPointEqual(flatCur, flatNext)) { + vec2.add( + flatNext, + flatCur, + vec2.normalize(flatNext, vec2.subtract(flatNext, flatCur, flatLast)), + ); + } + direction(lineB, flatNext, flatCur); + + const [miterLen, miter] = computeMiter( + tangent, + vec2.create(), + lineA, + lineB, + this.thickness, + ); + let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1; + let bevel = joinBevel; + if (!bevel && this.join === 'miter') { + const limit = miterLen; + if (limit > this.miterLimit) { + bevel = true; + } + } + if (bevel) { + positions.push( + cur[0], + cur[1], + 0, + this.totalDistance, + -this.thickness * flip, + 0, + ); + positions.push( + cur[0], + cur[1], + 0, + this.totalDistance, + this.thickness * flip, + 0, + ); + indices.push( + ...(this.lastFlip !== -flip + ? [index, index + 2, index + 3] + : [index + 2, index + 1, index + 3]), + ); + indices.push(index + 2, index + 3, index + 4); + + computeNormal(tmp, lineB); + vec2.copy(this.normal, tmp); // store normal for next round + + positions.push( + cur[0], + cur[1], + 0, + this.totalDistance, + -this.thickness * flip, + 0, + ); + count += 3; + } else { + this.extrusionsPosition(positions, cur, miterLen, this.totalDistance); + indices.push( + ...(this.lastFlip === 1 + ? [index, index + 2, index + 3] + : [index + 2, index + 1, index + 3]), + ); + flip = -1; + vec2.copy(this.normal, miter); + count += 2; + } + this.lastFlip = flip; + } + return count; + } + private segment2( + complex: any, + index: number, + last: vec2, + cur: vec2, + next: vec2, + ) { + let count = 0; + const normals = complex.normals; + const capSquare = this.cap === 'square'; + const joinBevel = this.join === 'bevel'; + const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number]; + const flatLast = aProjectFlat([last[0], last[1]]) as [number, number]; + direction(lineA, flatCur, flatLast); + let segmentDistance = 0; + if (this.dash) { + segmentDistance = this.lineSegmentDistance(flatCur, flatLast); + this.totalDistance += segmentDistance; + } + + if (!this.normal) { + this.normal = vec2.create(); + computeNormal(this.normal, lineA); + } + if (!this.started) { + this.started = true; + + if (capSquare) { + const out1 = vec2.create(); + const out2 = vec2.create(); + vec2.add(out1, this.normal, lineA); + vec2.add(out2, this.normal, lineA); + normals.push(out2[0], out2[1], 0); + normals.push(out1[0], out1[1], 0); + } else { + this.extrusionsNormal(normals, this.normal); + } + } + + if (!next) { + computeNormal(this.normal, lineA); + if (capSquare) { + const out1 = vec2.create(); + const out2 = vec2.create(); + vec2.sub(out2, lineA, this.normal); + vec2.add(out1, lineA, this.normal); + normals.push(out2[0], out2[1], 0); + normals.push(out1[0], out1[1], 0); + } else { + this.extrusionsNormal(normals, this.normal); + } + + count += 2; + } else { + const flatNext = aProjectFlat([next[0], next[1]]) as [number, number]; + if (isPointEqual(flatCur, flatNext)) { + vec2.add( + flatNext, + flatCur, + vec2.normalize(flatNext, vec2.subtract(flatNext, flatCur, flatLast)), + ); + } + direction(lineB, flatNext, flatCur); + + const [miterLen, miter] = computeMiter( + tangent, + vec2.create(), + lineA, + lineB, + this.thickness, + ); + + let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1; + let bevel = joinBevel; + if (!bevel && this.join === 'miter') { + const limit = miterLen; + if (limit > this.miterLimit) { + bevel = true; + } + } + + if (bevel) { + normals.push(this.normal[0], this.normal[1], 0); + normals.push(miter[0], miter[1], 0); + + computeNormal(tmp, lineB); + vec2.copy(this.normal, tmp); // store normal for next round + normals.push(this.normal[0], this.normal[1], 0); + + count += 3; + } else { + this.extrusionsNormal(normals, miter); + flip = -1; + vec2.copy(this.normal, miter); + count += 2; + } + this.lastFlip = flip; + } + return count; + } private extrusions( positions: number[], @@ -343,6 +678,20 @@ export default class ExtrudePolyline { positions.push(point[0], point[1], 0, distanceRadio, -thickness, 0); positions.push(point[0], point[1], 0, distanceRadio, thickness, 0); } + private extrusionsPosition( + positions: number[], + point: vec2, // 顶点 + thickness: number, // 高度 + distanceRadio: number, + ) { + positions.push(point[0], point[1], 0, distanceRadio, -thickness, 0); + positions.push(point[0], point[1], 0, distanceRadio, thickness, 0); + } + private extrusionsNormal(normals: number[], normal: vec2) { + // 法向量 + normals.push(normal[0], normal[1], 0); + normals.push(normal[0], normal[1], 0); + } private lineSegmentDistance(b1: vec2, a1: vec2) { const dx = a1[0] - b1[0]; const dy = a1[1] - b1[1]; diff --git a/packages/maps/src/amap/map.ts b/packages/maps/src/amap/map.ts index 76acb99243..3055c07131 100644 --- a/packages/maps/src/amap/map.ts +++ b/packages/maps/src/amap/map.ts @@ -25,6 +25,7 @@ import { mat4, vec2, vec3 } from 'gl-matrix'; import { inject, injectable } from 'inversify'; import { IAMapEvent, IAMapInstance } from '../../typings/index'; import { toPaddingOptions } from '../utils'; +import { Version } from '../version'; import './logo.css'; import { MapTheme } from './theme'; import Viewport from './Viewport'; @@ -54,6 +55,7 @@ const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; // 暂时关闭 fix 统一不同坐标 @injectable() export default class AMapService implements IMapService { + public version: string = Version['GAODE1.x']; /** * 原始地图实例 */ @@ -328,7 +330,7 @@ export default class AMapService } = this.config; // 高德地图创建独立的container; // tslint:disable-next-line:typedef - await new Promise((resolve) => { + await new Promise((resolve) => { const resolveMap = () => { if (mapInstance) { this.map = mapInstance as AMap.Map & IAMapInstance; @@ -458,7 +460,6 @@ export default class AMapService offsetOrigin: [position.x, position.y], }); const { offsetZoom = LNGLAT_OFFSET_ZOOM_THRESHOLD } = this.config; - // set coordinate system if (this.viewport.getZoom() > offsetZoom) { this.coordinateSystemService.setCoordinateSystem( diff --git a/packages/maps/src/amap2/Viewport.ts b/packages/maps/src/amap2/Viewport.ts new file mode 100644 index 0000000000..63fc246759 --- /dev/null +++ b/packages/maps/src/amap2/Viewport.ts @@ -0,0 +1,124 @@ +import { IMapCamera, IViewport } from '@antv/l7-core'; +import { mat4, vec3 } from 'gl-matrix'; + +export default class Viewport implements IViewport { + private projectionMatrix: mat4 = mat4.create(); + private viewMatrix: mat4 = mat4.create(); + private viewProjectionMatrix: mat4 = mat4.create(); + private ViewProjectionMatrixUncentered: mat4 = mat4.create(); + private viewUncenteredMatrix: mat4 = mat4.create(); + private zoom: number; + private center: number[]; + + public syncWithMapCamera(mapCamera: Partial) { + const { + zoom = 1, + center = [0, 0], + offsetOrigin = [0, 0], + cameraPosition = [0, 0, 0], + up = [0, 1, 0], + lookAt = [0, 0, 0], + aspect = 1, + near = 0.1, + far = 1000, + fov = 0, + } = mapCamera; + this.zoom = zoom; + this.center = center; + + // 计算透视投影矩阵 projectionMatrix + mat4.perspective(this.projectionMatrix, fov, aspect, near, far); + + // 计算相机矩阵 viewMatrix + const eyePoint = vec3.fromValues(...cameraPosition); + const lookAtPoint = vec3.fromValues(...lookAt); + const upDirect = vec3.fromValues(...up); + mat4.lookAt(this.viewMatrix, eyePoint, lookAtPoint, upDirect); + + this.viewUncenteredMatrix = mat4.clone(this.viewMatrix); + + // 移动相机位置 + mat4.translate( + this.viewMatrix, + this.viewMatrix, + vec3.fromValues(-offsetOrigin[0], offsetOrigin[1], 0), + ); + + mat4.multiply( + this.viewProjectionMatrix, + this.projectionMatrix, + this.viewMatrix, + ); + mat4.multiply( + this.ViewProjectionMatrixUncentered, + this.projectionMatrix, + this.viewMatrix, + ); + } + + public getZoom(): number { + return this.zoom; + } + + public getZoomScale(): number { + // 512 尺寸下的缩放:2 ^ 19 + return 524288; + } + + public getCenter(): [number, number] { + const [lng, lat] = this.center; + return [lng, lat]; + } + + public getProjectionMatrix(): number[] { + // @ts-ignore + return this.projectionMatrix; + } + + public getViewMatrix(): number[] { + // @ts-ignore + return this.viewMatrix; + } + + public getViewMatrixUncentered(): number[] { + // @ts-ignore + return this.viewUncenteredMatrix; + } + public getViewProjectionMatrix(): number[] { + // @ts-ignore + return this.viewProjectionMatrix; + } + + public getViewProjectionMatrixUncentered(): number[] { + // @ts-ignore + return this.ViewProjectionMatrixUncentered; + } + + public getFocalDistance() { + return 1; + } + + /** + * P20 坐标系,固定 scale + */ + public projectFlat( + lngLat: [number, number], + scale?: number | undefined, + ): [number, number] { + const maxs = 85.0511287798; + const lat = Math.max(Math.min(maxs, lngLat[1]), -maxs); + // tslint:disable-next-line:no-bitwise + const zoomScale = 256 << 20; + let d = Math.PI / 180; + let x = lngLat[0] * d; + let y = lat * d; + y = Math.log(Math.tan(Math.PI / 4 + y / 2)); + const a = 0.5 / Math.PI; + const b = 0.5; + const c = -0.5 / Math.PI; + d = 0.5; + x = zoomScale * (a * x + b) - 215440491; + y = -(zoomScale * (c * y + d) - 106744817); + return [x, y]; + } +} diff --git a/packages/maps/src/amap2/index.ts b/packages/maps/src/amap2/index.ts new file mode 100644 index 0000000000..1661938a64 --- /dev/null +++ b/packages/maps/src/amap2/index.ts @@ -0,0 +1,11 @@ +import { IAMapInstance } from '../../typings/index'; +import BaseMapWrapper from '../BaseMapWrapper'; +import AMapService from './map'; + +export default class AMapWrapper2 extends BaseMapWrapper< + AMap.Map & IAMapInstance +> { + protected getServiceConstructor() { + return AMapService; + } +} diff --git a/packages/maps/src/amap2/logo.css b/packages/maps/src/amap2/logo.css new file mode 100644 index 0000000000..5dbe1028c9 --- /dev/null +++ b/packages/maps/src/amap2/logo.css @@ -0,0 +1,3 @@ +.amap-logo{ + display: none !important; +} diff --git a/packages/maps/src/amap2/map.ts b/packages/maps/src/amap2/map.ts new file mode 100644 index 0000000000..83b1822463 --- /dev/null +++ b/packages/maps/src/amap2/map.ts @@ -0,0 +1,625 @@ +/** + * AMapService + */ +import AMapLoader from '@amap/amap-jsapi-loader'; +import { + Bounds, + CoordinateSystem, + ICameraOptions, + ICoordinateSystemService, + IGlobalConfigService, + ILngLat, + ILogService, + IMapConfig, + IMapService, + IMercator, + IPoint, + IStatusOptions, + IViewport, + MapServiceEvent, + MapStyle, + Point, + TYPES, +} from '@antv/l7-core'; +import { DOM } from '@antv/l7-utils'; +import { mat4, vec2, vec3 } from 'gl-matrix'; +import { inject, injectable } from 'inversify'; +import { IAMapEvent, IAMapInstance } from '../../typings/index'; +import { toPaddingOptions } from '../utils'; +import { Version } from '../version'; +import './logo.css'; +import { MapTheme } from './theme'; +import Viewport from './Viewport'; + +let mapdivCount = 0; +// @ts-ignore +window.forceWebGL = true; + +// const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200'; +const AMAP_API_KEY: string = 'ff533602d57df6f8ab3b0fea226ae52f'; +// const AMAP_VERSION: string = '1.4.15'; +const AMAP_VERSION: string = '2.0'; +/** + * 确保多个场景只引入一个高德地图脚本 + */ +const AMAP_SCRIPT_ID: string = 'amap-script'; +/** + * 高德地图脚本是否加载完毕 + */ +let amapLoaded = false; +/** + * 高德地图脚本加载成功等待队列,成功之后依次触发 + */ +let pendingResolveQueue: Array<() => void> = []; + +/** + * AMapService + */ +@injectable() +export default class AMapService + implements IMapService { + public version: string = Version['GAODE2.x']; + /** + * 原始地图实例 + */ + public map: AMap.Map & IAMapInstance; + + /** + * 用于 customCooords 数据的计算 + */ + public sceneCenter!: [number, number]; // 一般使用用户数据的第一个 + public sceneCenterMKT!: [number, number]; // 莫卡托 + + @inject(TYPES.IGlobalConfigService) + private readonly configService: IGlobalConfigService; + + @inject(TYPES.ILogService) + private readonly logger: ILogService; + + @inject(TYPES.MapConfig) + private readonly config: Partial; + + @inject(TYPES.ICoordinateSystemService) + private readonly coordinateSystemService: ICoordinateSystemService; + + @inject(TYPES.IEventEmitter) + private eventEmitter: any; + + private markerContainer: HTMLElement; + private $mapContainer: HTMLElement | null; + + private viewport: Viewport; + + private cameraChangedCallback: (viewport: IViewport) => void; + + /** + * 设置数据的绘制中心 高德2.0 + */ + public setCustomCoordCenter(center: [number, number]) { + this.sceneCenter = center; + // @ts-ignore + this.sceneCenterMKT = this.map.getProjection().project(...this.sceneCenter); + } + + public getCustomCoordCenter(): [number, number] { + return this.sceneCenterMKT; + } + /** + * 根据数据的绘制中心转换经纬度数据 高德2.0 + */ + public lngLatToCoord(lnglat: [number, number]) { + // @ts-ignore + const proj = this.map.getProjection(); + const project = proj.project; + // console.log('proj', proj.project) + // 单点 + if (!this.sceneCenter) { + // @ts-ignore + this.map.customCoords.setCenter(lnglat); + this.setCustomCoordCenter(lnglat); + } + return this._sub(project(lnglat[0], lnglat[1]), this.sceneCenterMKT); + } + + /** + * 转化线、面类型的点位数据 + */ + // public lngLatToCoords(lnglatArray: Array> | Array<[number, number]>): Array>|Array<[number, number]> { + public lngLatToCoords( + lnglatArray: number[][][] | number[][], + ): number[][][] | number[][] { + // @ts-ignore + return lnglatArray.map((lnglats) => { + if (typeof lnglats[0] === 'number') { + return this.lngLatToCoord(lnglats); + } else { + // @ts-ignore + return lnglats.map((lnglat) => { + return this.lngLatToCoord(lnglat); + }); + } + }); + } + + public addMarkerContainer(): void { + const mapContainer = this.map.getContainer(); + if (mapContainer !== null) { + const amap = mapContainer.getElementsByClassName( + 'amap-maps', + )[0] as HTMLElement; + this.markerContainer = DOM.create('div', 'l7-marker-container', amap); + } + } + public getMarkerContainer(): HTMLElement { + return this.markerContainer; + } + + // map event + public on(type: string, handler: (...args: any[]) => void): void { + if (MapServiceEvent.indexOf(type) !== -1) { + this.eventEmitter.on(type, handler); + } else { + this.map.on(type, handler); + } + } + public off(type: string, handler: (...args: any[]) => void): void { + if (MapServiceEvent.indexOf(type) !== -1) { + this.eventEmitter.off(type, handler); + } else { + this.map.off(type, handler); + } + } + + public getContainer(): HTMLElement | null { + return this.map.getContainer(); + } + + public getMapCanvasContainer(): HTMLElement { + return this.map + .getContainer() + ?.getElementsByClassName('amap-maps')[0] as HTMLElement; + } + + public getSize(): [number, number] { + const size = this.map.getSize(); + return [size.getWidth(), size.getHeight()]; + } + + public getType() { + return 'amap'; + } + public getZoom(): number { + // 统一返回 Mapbox 缩放等级 + return this.map.getZoom() - 1; + } + + public setZoom(zoom: number): void { + return this.map.setZoom(zoom); + } + + public getCenter(options?: ICameraOptions): ILngLat { + if (options?.padding) { + const originCenter = this.getCenter(); + const [w, h] = this.getSize(); + const padding = toPaddingOptions(options.padding); + const px = this.lngLatToPixel([originCenter.lng, originCenter.lat]); + const offsetPx = [ + (padding.right - padding.left) / 2, + (padding.bottom - padding.top) / 2, + ]; + + const newCenter = this.pixelToLngLat([ + px.x - offsetPx[0], + px.y - offsetPx[1], + ]); + return newCenter; + } + const center = this.map.getCenter(); + return { + lng: center.getLng(), + lat: center.getLat(), + }; + } + public setCenter(lnglat: [number, number], options?: ICameraOptions): void { + if (options?.padding) { + const padding = toPaddingOptions(options.padding); + const px = this.lngLatToPixel(lnglat); + const offsetPx = [ + (padding.right - padding.left) / 2, + (padding.bottom - padding.top) / 2, + ]; + const newCenter = this.pixelToLngLat([ + px.x + offsetPx[0], + px.y + offsetPx[1], + ]); + this.map.setCenter([newCenter.lng, newCenter.lat]); + } else { + this.map.setCenter(lnglat); + } + } + public getPitch(): number { + return this.map.getPitch(); + } + + public getRotation(): number { + // 统一返回逆时针旋转角度 + return 360 - this.map.getRotation(); + } + + public getBounds(): Bounds { + // @ts-ignore + // const amapBound = this.map.getBounds().toBounds(); + // const NE = amapBound.getNorthEast(); + // const SW = amapBound.getSouthWest(); + const bounds = this.map.getBounds(); + // console.log('bounds', bounds) + + // @ts-ignore + const NE = bounds.getNorthEast(); + // @ts-ignore + const SW = bounds.getSouthWest(); + const center = this.getCenter(); + const maxlng = + center.lng > NE.getLng() || center.lng < SW.getLng() + ? 180 - NE.getLng() + : NE.getLng(); + const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng(); + // 兼容 Mapbox,统一返回西南、东北 + return [ + [minlng, SW.getLat()], + [maxlng, NE.getLat()], + ]; + } + + public getMinZoom(): number { + const zooms = this.map.get('zooms') as [number, number]; + return zooms[0] - 1; + } + public getMaxZoom(): number { + const zooms = this.map.get('zooms') as [number, number]; + return zooms[1] - 1; + } + public setRotation(rotation: number): void { + return this.map.setRotation(rotation); + } + + public setPitch(pitch: number) { + return this.map.setPitch(pitch); + } + public zoomIn(): void { + this.map.zoomIn(); + } + + public zoomOut(): void { + this.map.zoomOut(); + } + + public panTo(p: [number, number]): void { + this.map.panTo(p); + } + public panBy(pixel: [number, number]): void { + this.map.panTo(pixel); + } + public fitBounds(extent: Bounds): void { + this.map.setBounds( + new AMap.Bounds([extent[0][0], extent[0][1], extent[1][0], extent[1][1]]), + ); + } + public setZoomAndCenter(zoom: number, center: [number, number]): void { + this.map.setZoomAndCenter(zoom, center); + } + public setMapStyle(style: string): void { + this.map.setMapStyle(this.getMapStyle(style)); + } + + public setMapStatus(option: Partial): void { + this.map.setStatus(option); + } + public pixelToLngLat(pixel: [number, number]): ILngLat { + const lngLat = this.map.pixelToLngLat(new AMap.Pixel(pixel[0], pixel[1])); + return { lng: lngLat.getLng(), lat: lngLat.getLat() }; + } + public lngLatToPixel(lnglat: [number, number]): IPoint { + const p = this.map.lnglatToPixel(new AMap.LngLat(lnglat[0], lnglat[1])); + return { + x: p.getX(), + y: p.getY(), + }; + } + public containerToLngLat(pixel: [number, number]): ILngLat { + const ll = new AMap.Pixel(pixel[0], pixel[1]); + const lngLat = this.map.containerToLngLat(ll); + return { + lng: lngLat?.getLng(), + lat: lngLat?.getLat(), + }; + } + public lngLatToContainer(lnglat: [number, number]): IPoint { + const ll = new AMap.LngLat(lnglat[0], lnglat[1]); + const pixel = this.map.lngLatToContainer(ll); + return { + x: pixel.getX(), + y: pixel.getY(), + }; + } + + public lngLatToMercator( + lnglat: [number, number], + altitude: number, + ): IMercator { + return { + x: 0, + y: 0, + z: 0, + }; + } + + public getModelMatrix( + lnglat: [number, number], + altitude: number, + rotate: [number, number, number], + scale: [number, number, number] = [1, 1, 1], + origin: IMercator = { x: 0, y: 0, z: 0 }, + ): number[] { + const flat = this.viewport.projectFlat(lnglat); + // @ts-ignore + const modelMatrix = mat4.create(); + + mat4.translate( + modelMatrix, + modelMatrix, + vec3.fromValues(flat[0], flat[1], altitude), + ); + mat4.scale( + modelMatrix, + modelMatrix, + vec3.fromValues(scale[0], scale[1], scale[2]), + ); + + mat4.rotateX(modelMatrix, modelMatrix, rotate[0]); + mat4.rotateY(modelMatrix, modelMatrix, rotate[1]); + mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]); + + return (modelMatrix as unknown) as number[]; + } + public async init(): Promise { + const { + id, + style = 'light', + minZoom = 0, + maxZoom = 18, + token = AMAP_API_KEY, + mapInstance, + plugin = [], + ...rest + } = this.config; + // 高德地图创建独立的container; + + // tslint:disable-next-line:typedef + await new Promise((resolve) => { + const resolveMap = () => { + if (mapInstance) { + this.map = mapInstance as AMap.Map & IAMapInstance; + this.$mapContainer = this.map.getContainer(); + + setTimeout(() => { + this.map.on('viewchange', this.handleViewChanged); + resolve(); + }, 30); + } else { + this.$mapContainer = this.creatAmapContainer( + id as string | HTMLDivElement, + ); + + const map = new AMap.Map(this.$mapContainer, { + mapStyle: this.getMapStyle(style as string), + zooms: [minZoom, maxZoom], + viewMode: '3D', + ...rest, + }); + // @ts-ignore + this.map = map; + + // 在使用 map.customCoords 的时候必须使用 + const mapInitCenter = map.getCenter(); + // @ts-ignore + map.customCoords.setCenter([mapInitCenter.lng, mapInitCenter.lat]); + + // @ts-ignore + this.setCustomCoordCenter([mapInitCenter.lng, mapInitCenter.lat]); + // 监听地图相机事件 + map.on('viewchange', this.handleViewChanged); + + setTimeout(() => { + resolve(); + }, 10); + } + }; + this.viewport = new Viewport(); + if (!amapLoaded && !mapInstance) { + if (token === AMAP_API_KEY) { + this.logger.warn(this.configService.getSceneWarninfo('MapToken')); + } + amapLoaded = true; + plugin.push('Map3D'); + AMapLoader.load({ + key: token, // 申请好的Web端开发者Key,首次调用 load 时必填 + version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 + plugins: plugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等 + }) + .then((AMap) => { + resolveMap(); + if (pendingResolveQueue.length) { + pendingResolveQueue.forEach((r) => r()); + pendingResolveQueue = []; + } + }) + .catch((e) => { + throw new Error(e); + }); + } else { + if ((amapLoaded && window.AMap) || mapInstance) { + resolveMap(); + } else { + pendingResolveQueue.push(resolveMap); + } + } + }); + } + + public exportMap(type: 'jpg' | 'png'): string { + const renderCanvas = this.getContainer()?.getElementsByClassName( + 'amap-layer', + )[0] as HTMLCanvasElement; + const layersPng = + type === 'jpg' + ? (renderCanvas?.toDataURL('image/jpeg') as string) + : (renderCanvas?.toDataURL('image/png') as string); + return layersPng; + } + + public emit(name: string, ...args: any[]) { + this.eventEmitter.emit(name, ...args); + } + + public once(name: string, ...args: any[]) { + this.eventEmitter.once(name, ...args); + } + + public destroy() { + this.map.destroy(); + // @ts-ignore + delete window.initAMap; + const $jsapi = document.getElementById(AMAP_SCRIPT_ID); + if ($jsapi) { + document.head.removeChild($jsapi); + } + } + + public getMapContainer() { + return this.$mapContainer; + } + + public onCameraChanged(callback: (viewport: IViewport) => void): void { + this.cameraChangedCallback = callback; + } + + public initViewPort() { + // @ts-ignore + const { + // @ts-ignore + fov, + // @ts-ignore + near, + // @ts-ignore + far, + // @ts-ignore + aspect, + // @ts-ignore + position, + // @ts-ignore + lookAt, + // @ts-ignore + up, + // @ts-ignore + } = this.map.customCoords.getCameraParams(); + const center = this.map.getCenter(); + const zoom = this.map.getZoom(); + + if (this.cameraChangedCallback) { + this.viewport.syncWithMapCamera({ + aspect, + far, + fov, + cameraPosition: position, + lookAt, + near, + up, + // AMap 定义的缩放等级 与 Mapbox 相差 1 + zoom: zoom - 1, // 与amap1.x对比相差一个级别 + center: [center.getLat(), center.getLng()], + offsetOrigin: [position[0], position[1]], + }); + + // set coordinate system + this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_2); + this.cameraChangedCallback(this.viewport); + } + } + + private _sub(a: number[] | vec3 | vec2, b: number[]): [number, number] { + const r: [number, number] = [0, 0]; + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; + return r; + } + + /** + * + * @param e + */ + private handleViewChanged = (e: any): void => { + // @ts-ignore + const { + // @ts-ignore + fov, + // @ts-ignore + near, + // @ts-ignore + far, + // @ts-ignore + aspect, + // @ts-ignore + position, + // @ts-ignore + lookAt, + // @ts-ignore + up, + // @ts-ignore + } = this.map.customCoords.getCameraParams(); + const { zoom } = e; + // console.log('zoom', zoom, this.map.getZoom()) + const center = this.map.getCenter(); + if (this.cameraChangedCallback) { + // resync viewport + this.viewport.syncWithMapCamera({ + aspect, + far, + fov, + cameraPosition: position, + lookAt, + up, + near, + // AMap 定义的缩放等级 与 Mapbox 相差 1 + zoom: zoom - 1, // 与amap1.x对比相差一个级别 + center: [center.getLat(), center.getLng()], + offsetOrigin: [position[0], position[1]], + }); + + // set coordinate system + this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_2); + this.cameraChangedCallback(this.viewport); + } + }; + + private getMapStyle(name: string): string { + return MapTheme[name] ? MapTheme[name] : name; + } + + private creatAmapContainer(id: string | HTMLDivElement) { + let $wrapper = id as HTMLDivElement; + if (typeof id === 'string') { + $wrapper = document.getElementById(id) as HTMLDivElement; + } + const $amapdiv = document.createElement('div'); + $amapdiv.style.cssText += ` + position: absolute; + top: 0; + height: 100%; + width: 100%; + `; + $amapdiv.id = 'l7_amap_div' + mapdivCount++; + $wrapper.appendChild($amapdiv); + return $amapdiv; + } +} diff --git a/packages/maps/src/amap2/theme.ts b/packages/maps/src/amap2/theme.ts new file mode 100644 index 0000000000..d7654ddafc --- /dev/null +++ b/packages/maps/src/amap2/theme.ts @@ -0,0 +1,8 @@ +export const MapTheme: { + [key: string]: any; +} = { + dark: 'amap://styles/2a09079c3daac9420ee53b67307a8006?isPublic=true', + light: 'amap://styles/1fd9f8ef9751298f11f5c56968312c70?isPublic=true', + normal: 'amap://styles/normal', + blank: 'amap://styles/07c17002b38775b32a7a76c66cf90e99?isPublic=true', +}; diff --git a/packages/maps/src/index.ts b/packages/maps/src/index.ts index 7e363b9af7..c3e1da15fc 100644 --- a/packages/maps/src/index.ts +++ b/packages/maps/src/index.ts @@ -1,5 +1,6 @@ import GaodeMap from './amap/'; +import GaodeMap2 from './amap2/'; import Map from './map/'; import Mapbox from './mapbox/'; -export { GaodeMap, Mapbox, Map }; +export { GaodeMap, GaodeMap2, Mapbox, Map }; diff --git a/packages/maps/src/map/map.ts b/packages/maps/src/map/map.ts index 32bb5b95d2..e8160a556c 100644 --- a/packages/maps/src/map/map.ts +++ b/packages/maps/src/map/map.ts @@ -22,7 +22,7 @@ import { Map } from '@antv/l7-map'; import { DOM } from '@antv/l7-utils'; import { mat4, vec2, vec3 } from 'gl-matrix'; import { inject, injectable } from 'inversify'; - +import { Version } from '../version'; import Viewport from './Viewport'; const EventMap: { [key: string]: any; @@ -40,6 +40,7 @@ const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; */ @injectable() export default class L7MapService implements IMapService { + public version: string = Version.L7MAP; public map: Map; @inject(TYPES.MapConfig) diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 46a545c35c..01d96e39c2 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -22,10 +22,10 @@ import { DOM } from '@antv/l7-utils'; import { mat4, vec2, vec3 } from 'gl-matrix'; import { inject, injectable } from 'inversify'; import mapboxgl, { IControl, Map } from 'mapbox-gl'; - // tslint:disable-next-line:no-submodule-imports import 'mapbox-gl/dist/mapbox-gl.css'; import { IMapboxInstance } from '../../typings/index'; +import { Version } from '../version'; import Viewport from './Viewport'; window.mapboxgl = mapboxgl; const EventMap: { @@ -47,6 +47,7 @@ const MAPBOX_API_KEY = @injectable() export default class MapboxService implements IMapService { + public version: string = Version.MAPBOX; public map: Map & IMapboxInstance; @inject(TYPES.MapConfig) diff --git a/packages/maps/src/version.ts b/packages/maps/src/version.ts new file mode 100644 index 0000000000..66006cf1a3 --- /dev/null +++ b/packages/maps/src/version.ts @@ -0,0 +1,9 @@ +/** + * 当前 L7 内部存在的地图版本 + */ +export enum Version { + 'GAODE1.x' = 'GAODE1.x', + 'GAODE2.x' = 'GAODE2.x', + 'MAPBOX' = 'MAPBOX', + 'L7MAP' = 'L7MAP', +} diff --git a/packages/maps/typings/index.d.ts b/packages/maps/typings/index.d.ts index ac3796c393..a74363a13e 100644 --- a/packages/maps/typings/index.d.ts +++ b/packages/maps/typings/index.d.ts @@ -17,8 +17,15 @@ interface IAMapEvent { }; } +interface CustomCoords { + getCameraParams(): void; + getCenter(): void; + getMVPMatrix(): void; + [other:string]:any +} interface IAMapInstance { get(key: string): unknown; + customCoords?: CustomCoords; } interface IMapboxInstance { diff --git a/packages/source/src/source.ts b/packages/source/src/source.ts index ab2bc5cd06..c647cf18ec 100644 --- a/packages/source/src/source.ts +++ b/packages/source/src/source.ts @@ -28,6 +28,7 @@ import { getParser, getTransform } from './'; import { cluster } from './transform/cluster'; import { statMap } from './utils/statistics'; import { getColumn } from './utils/util'; + function mergeCustomizer(objValue: any, srcValue: any) { if (Array.isArray(srcValue)) { return srcValue; @@ -54,6 +55,7 @@ export default class Source extends EventEmitter { zoom: -99, method: 'count', }; + private readonly mapService: IMapService; // 原始数据 private originData: any; @@ -66,7 +68,6 @@ export default class Source extends EventEmitter { super(); // this.rawData = cloneDeep(data); this.originData = data; - this.initCfg(cfg); this.hooks.init.tap('parser', () => { @@ -204,6 +205,7 @@ export default class Source extends EventEmitter { const trans = this.transforms; trans.forEach((tran: ITransform) => { const { type } = tran; + const data = getTransform(type)(this.data, tran); Object.assign(this.data, data); }); diff --git a/stories/Map/components/amap2demo.tsx b/stories/Map/components/amap2demo.tsx new file mode 100644 index 0000000000..656583d601 --- /dev/null +++ b/stories/Map/components/amap2demo.tsx @@ -0,0 +1,88 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +export default class Amap2demo extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + center: [121.107846, 30.267069], + pitch: 0, + style: 'normal', + zoom: 13, + animateEnable: false, + }), + }); + let originData = [ + { + lng: 121.107846, + lat: 30.267069, + }, + { + lng: 121.1, + lat: 30.267069, + }, + { + lng: 120.107846, + lat: 30.267069, + }, + { + lng: 38.54, + lat: 77.02, + }, + ]; + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + + const layer = new PointLayer() + .source(originData, { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('circle') + // .shape('normal') + .color('rgba(255, 0, 0, 0.9)') + .size(10) + .style({ + stroke: '#fff', + storkeWidth: 2, + }) + .active(true); + scene.addLayer(layer); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/amap2demo_arcLine.tsx b/stories/Map/components/amap2demo_arcLine.tsx new file mode 100644 index 0000000000..412464cbde --- /dev/null +++ b/stories/Map/components/amap2demo_arcLine.tsx @@ -0,0 +1,74 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, LineLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +export default class Amap2demo_arcLine extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + pitch: 0, + center: [107.77791556935472, 35.443286920228644], + zoom: 2.9142882493605033, + }), + }); + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + + fetch( + 'https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', + ) + .then((res) => res.text()) + .then((data) => { + const layer = new LineLayer({}) + .source(data, { + parser: { + type: 'csv', + x: 'lng1', + y: 'lat1', + x1: 'lng2', + y1: 'lat2', + }, + }) + .size(1) + .shape('arc') + .color('#8C1EB2') + .style({ + opacity: 0.8, + blur: 0.99, + }); + scene.addLayer(layer); + }); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/amap2demo_extrude.tsx b/stories/Map/components/amap2demo_extrude.tsx new file mode 100644 index 0000000000..5e81f39a66 --- /dev/null +++ b/stories/Map/components/amap2demo_extrude.tsx @@ -0,0 +1,84 @@ +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class Amapdemo_extrude extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + center: [121.107846, 30.267069], + pitch: 35.210526315789465, + style: 'normal', + zoom: 8, + animateEnable: false, + }), + }); + + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + fetch( + 'https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json', + ) + .then((res) => res.json()) + .then((data) => { + const pointLayer = new PointLayer({}) + .source(data.list, { + parser: { + type: 'json', + x: 'j', + y: 'w', + }, + }) + .shape('cylinder') + .size('t', function(level) { + return [1, 2, level * 2 + 20]; + }) + .active(true) + .color('t', [ + '#094D4A', + '#146968', + '#1D7F7E', + '#289899', + '#34B6B7', + '#4AC5AF', + '#5FD3A6', + '#7BE39E', + '#A1EDB8', + '#CEF8D6', + ]) + .style({ + opacity: 1.0, + }); + scene.addLayer(pointLayer); + }); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/amap2demo_image.tsx b/stories/Map/components/amap2demo_image.tsx new file mode 100644 index 0000000000..f89d4402d4 --- /dev/null +++ b/stories/Map/components/amap2demo_image.tsx @@ -0,0 +1,80 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +export default class Amap2demo_image extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + pitch: 0, + style: 'light', + center: [121.434765, 31.256735], + zoom: 14.83, + }), + }); + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ) + .then((res) => res.json()) + .then((data) => { + scene.addImage( + '00', + 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', + ); + scene.addImage( + '01', + 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', + ); + scene.addImage( + '02', + 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', + ); + const imageLayer = new PointLayer() + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', ['00', '01', '02']) + .size(20); + scene.addLayer(imageLayer); + }); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/amap2demo_polygon.tsx b/stories/Map/components/amap2demo_polygon.tsx new file mode 100644 index 0000000000..b58648acd8 --- /dev/null +++ b/stories/Map/components/amap2demo_polygon.tsx @@ -0,0 +1,140 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { DrawPolygon } from '@antv/l7-draw'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +function convertRGB2Hex(rgb: number[]) { + return ( + '#' + rgb.map((r) => ('0' + Math.floor(r).toString(16)).slice(-2)).join('') + ); +} + +export default class Amap2demo_polygon extends React.Component { + private gui: dat.GUI; + private $stats: Node; + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const response = await fetch( + // 'https://gw.alipayobjects.com/os/basement_prod/f79485d8-d86f-4bb3-856d-537b586be06e.json', + 'https://gw.alipayobjects.com/os/basement_prod/619a6f16-ecb0-4fca-9f9a-b06b67f6f02b.json', + ); + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + pitch: 0, + // style: 'dark', + center: [-44.40673828125, -18.375379094031825], + zoom: 13, + }), + }); + this.scene = scene; + const data = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [110.5224609375, 32.731840896865684], + [113.0712890625, 32.731840896865684], + [113.0712890625, 34.56085936708384], + [110.5224609375, 34.56085936708384], + [110.5224609375, 32.731840896865684], + ], + [ + [111.26953125, 33.52307880890422], + [111.26953125, 34.03445260967645], + [112.03857421875, 34.03445260967645], + [112.03857421875, 33.52307880890422], + [111.26953125, 33.52307880890422], + ], + ], + [ + [ + [115.04882812499999, 34.379712580462204], + [114.9609375, 33.46810795527896], + [115.8837890625, 33.50475906922609], + [115.86181640625001, 34.379712580462204], + [115.04882812499999, 34.379712580462204], + ], + ], + ], + }, + }, + { + type: 'Feature', + properties: {}, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [113.8623046875, 30.031055426540206], + [116.3232421875, 30.031055426540206], + [116.3232421875, 31.090574094954192], + [113.8623046875, 31.090574094954192], + [113.8623046875, 30.031055426540206], + ], + [ + [117.26806640625, 32.13840869677249], + [118.36669921875, 32.13840869677249], + [118.36669921875, 32.47269502206151], + [117.26806640625, 32.47269502206151], + [117.26806640625, 32.13840869677249], + ], + ], + }, + }, + ], + }; + + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .shape('fill') + .color('red') + .style({ + opacity: 1.0, + }); + scene.addLayer(layer); + + const layer2 = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .shape('line') + .color('#000') + .style({ + opacity: 1.0, + }); + scene.addLayer(layer2); + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/Map/components/amap2demo_polygon_extrude.tsx b/stories/Map/components/amap2demo_polygon_extrude.tsx new file mode 100644 index 0000000000..3ef4ea5230 --- /dev/null +++ b/stories/Map/components/amap2demo_polygon_extrude.tsx @@ -0,0 +1,132 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { DrawPolygon } from '@antv/l7-draw'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +function convertRGB2Hex(rgb: number[]) { + return ( + '#' + rgb.map((r) => ('0' + Math.floor(r).toString(16)).slice(-2)).join('') + ); +} + +export default class Amap2demo_polygon_extrude extends React.Component { + private gui: dat.GUI; + private $stats: Node; + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const response = await fetch( + // 'https://gw.alipayobjects.com/os/basement_prod/f79485d8-d86f-4bb3-856d-537b586be06e.json', + 'https://gw.alipayobjects.com/os/basement_prod/619a6f16-ecb0-4fca-9f9a-b06b67f6f02b.json', + ); + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + pitch: 0, + // style: 'dark', + center: [-44.40673828125, -18.375379094031825], + zoom: 13, + }), + }); + this.scene = scene; + const data = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [110.5224609375, 32.731840896865684], + [113.0712890625, 32.731840896865684], + [113.0712890625, 34.56085936708384], + [110.5224609375, 34.56085936708384], + [110.5224609375, 32.731840896865684], + ], + [ + [111.26953125, 33.52307880890422], + [111.26953125, 34.03445260967645], + [112.03857421875, 34.03445260967645], + [112.03857421875, 33.52307880890422], + [111.26953125, 33.52307880890422], + ], + ], + [ + [ + [115.04882812499999, 34.379712580462204], + [114.9609375, 33.46810795527896], + [115.8837890625, 33.50475906922609], + [115.86181640625001, 34.379712580462204], + [115.04882812499999, 34.379712580462204], + ], + ], + ], + }, + }, + { + type: 'Feature', + properties: {}, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [113.8623046875, 30.031055426540206], + [116.3232421875, 30.031055426540206], + [116.3232421875, 31.090574094954192], + [113.8623046875, 31.090574094954192], + [113.8623046875, 30.031055426540206], + ], + [ + [117.26806640625, 32.13840869677249], + [118.36669921875, 32.13840869677249], + [118.36669921875, 32.47269502206151], + [117.26806640625, 32.47269502206151], + [117.26806640625, 32.13840869677249], + ], + ], + }, + }, + ], + }; + + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(data) + // .shape('fill') + .shape('extrude') + .color('red') + .size(6000000) + .style({ + opacity: 1.0, + }) + .active(true); + scene.addLayer(layer); + } + + public render() { + return ( +
+ ); + } +} diff --git a/stories/Map/components/amap2demo_text.tsx b/stories/Map/components/amap2demo_text.tsx new file mode 100644 index 0000000000..ea0cafd48b --- /dev/null +++ b/stories/Map/components/amap2demo_text.tsx @@ -0,0 +1,80 @@ +import { vec2, vec3 } from 'gl-matrix'; +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +import { mat4 } from 'gl-matrix'; + +export default class Amap2demo_text extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap2({ + center: [120.19382669582967, 30.258134], + pitch: 0, + style: 'light', + zoom: 3, + }), + }); + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + + fetch( + 'https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json', + ) + .then((res) => res.json()) + .then((data) => { + const pointLayer = new PointLayer({}) + .source(data.list, { + parser: { + type: 'json', + x: 'j', + y: 'w', + }, + }) + .shape('m', 'text') + .size(12) + .color('w', ['#0e0030', '#0e0030', '#0e0030']) + .style({ + textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left + textOffset: [0, 0], // 文本相对锚点的偏移量 [水平, 垂直] + spacing: 2, // 字符间距 + padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近 + stroke: '#ffffff', // 描边颜色 + strokeWidth: 0.3, // 描边宽度 + strokeOpacity: 1.0, + // textAllowOverlap: true + }); + + scene.addLayer(pointLayer); + }); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/amapdemo_extrude.tsx b/stories/Map/components/amapdemo_extrude.tsx new file mode 100644 index 0000000000..c3e0fe27dc --- /dev/null +++ b/stories/Map/components/amapdemo_extrude.tsx @@ -0,0 +1,84 @@ +// @ts-ignore +import { ILngLat, PointLayer, PolygonLayer, Scene } from '@antv/l7'; +import { GaodeMap, GaodeMap2 } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class Amapdemo_extrude extends React.Component { + // @ts-ignore + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + center: [121.107846, 30.267069], + pitch: 35.210526315789465, + style: 'normal', + zoom: 8, + animateEnable: false, + }), + }); + + this.scene = scene; + + scene.on('loaded', () => { + console.log('event test'); + fetch( + 'https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json', + ) + .then((res) => res.json()) + .then((data) => { + const pointLayer = new PointLayer({}) + .source(data.list, { + parser: { + type: 'json', + x: 'j', + y: 'w', + }, + }) + .shape('cylinder') + .size('t', function(level) { + return [1, 2, level * 2 + 20]; + }) + .active(true) + .color('t', [ + '#094D4A', + '#146968', + '#1D7F7E', + '#289899', + '#34B6B7', + '#4AC5AF', + '#5FD3A6', + '#7BE39E', + '#A1EDB8', + '#CEF8D6', + ]) + .style({ + opacity: 1.0, + }); + scene.addLayer(pointLayer); + }); + }); + } + + public render() { + return ( + <> +
+ + ); + } +} diff --git a/stories/Map/components/mapCenter.tsx b/stories/Map/components/mapCenter.tsx index 1509dca603..0018b15100 100644 --- a/stories/Map/components/mapCenter.tsx +++ b/stories/Map/components/mapCenter.tsx @@ -18,7 +18,7 @@ export default class GaodeMapComponent extends React.Component { center: [121.107846, 30.267069], pitch: 0, style: 'normal', - zoom: 11, + zoom: 13, animateEnable: false, }), }); @@ -30,6 +30,18 @@ export default class GaodeMapComponent extends React.Component { lng: 121.107846, lat: 30.267069, }, + { + lng: 121.1, + lat: 30.267069, + }, + { + lng: 120.107846, + lat: 30.267069, + }, + { + lng: 38.54, + lat: 77.02, + }, ], { parser: { @@ -40,6 +52,7 @@ export default class GaodeMapComponent extends React.Component { }, ) .shape('circle') + // .shape('normal') .color('blue') .size(10) .style({ @@ -51,27 +64,25 @@ export default class GaodeMapComponent extends React.Component { this.scene = scene; scene.on('loaded', () => { - const padding = { - top: 50, - right: 0, - bottom: 200, - left: 800, - }; + // const padding = { + // top: 50, + // right: 0, + // bottom: 200, + // left: 800, + // }; // const px = scene.lngLatToPixel([center.lng, center.lat]); // const offsetPx = [ // (padding.right - padding.left) / 2, // (padding.bottom - padding.top) / 2, // ]; - scene.setCenter([121.107846, 30.267069], { padding }); + // scene.setCenter([121.107846, 30.267069], { padding }); // const newCenter = scene.pixelToLngLat([ // px.x + offsetPx[0], // px.y + offsetPx[1], // ]); // @ts-ignore // scene.setCenter(); - // get originCenter - // const originCenter = scene.getCenter(); // const originPx = scene.lngLatToPixel([ // originCenter.lng, @@ -85,7 +96,6 @@ export default class GaodeMapComponent extends React.Component { // originPx.x - offsetPx[0], // originPx.y - offsetPx[1], // ]); - // lngLatToContainer // 获取当前地图像素坐标 // console.log(originCenter, center, newCenter2); @@ -106,7 +116,7 @@ export default class GaodeMapComponent extends React.Component { bottom: 0, }} /> -
-
*/} + {/*
+ /> */} ); } diff --git a/stories/Map/map.stories.tsx b/stories/Map/map.stories.tsx index dca527ef51..5428a7850b 100644 --- a/stories/Map/map.stories.tsx +++ b/stories/Map/map.stories.tsx @@ -1,6 +1,24 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; import MapCenter from './components/mapCenter'; +import Amap2demo from './components/amap2demo' +import Amap2demo_extrude from './components/amap2demo_extrude' +import Amapdemo_extrude from './components/amapdemo_extrude' +import Amap2demo_text from './components/amap2demo_text' +import Amap2demo_image from './components/amap2demo_image' + +import Amap2demo_polygon from './components/amap2demo_polygon' +import Amap2demo_polygon_extrude from './components/amap2demo_polygon_extrude' +import Amap2demo_arcLine from "./components/amap2demo_arcLine" // @ts-ignore -storiesOf('地图方法', module).add('地图中心点', () => ); +storiesOf('地图方法', module) + .add('高德地图 point/demo', () => ) + .add('高德地图2.0 point/demo', () => ) + .add('高德地图 point/extrude', () => ) + .add('高德地图2.0 point/extrude', () => ) + .add('高德地图2.0 point/text', () => ) + .add('高德地图2.0 point/image', () => ) + .add('高德地图2.0 polygon', () => ) + .add('高德地图2.0 polygon_extrude', () => ) + .add('高德地图2.0 line_arc', () => )