From 107b6a38e05dbe7e36de14ae79e81ef1e6fbee42 Mon Sep 17 00:00:00 2001 From: YiQianYao <42212176+2912401452@users.noreply.github.com> Date: Thu, 7 Jul 2022 14:29:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E3=80=81=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E7=82=B9=E5=9B=BE=E5=B1=82=E7=AD=89=E9=9D=A2=E7=A7=AF?= =?UTF-8?q?=E7=82=B9=E6=A8=A1=E5=BC=8F=20(#1222)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 去处事件节流 * feat: 修复、优化等面积点存在的问题和可视化表现 * style: lint style * style: lint style --- packages/core/src/services/map/IMapService.ts | 2 + packages/layers/src/point/models/fill.ts | 82 ++++++++++++------- .../layers/src/point/shaders/fill_vert.glsl | 29 +++++-- packages/maps/src/earth/index.ts | 2 +- packages/maps/src/earth/map.ts | 6 +- packages/maps/src/map/map.ts | 5 ++ stories/Map/components/bugfix.tsx | 61 +++++++------- 7 files changed, 116 insertions(+), 71 deletions(-) diff --git a/packages/core/src/services/map/IMapService.ts b/packages/core/src/services/map/IMapService.ts index c23e136ce4..1b4ce889a6 100644 --- a/packages/core/src/services/map/IMapService.ts +++ b/packages/core/src/services/map/IMapService.ts @@ -91,6 +91,7 @@ export interface IMapService { setMapStatus(option: Partial): void; // coordinates methods + meterToCoord(center: number[], lnglat: number[]): number; pixelToLngLat(pixel: Point): ILngLat; lngLatToPixel(lnglat: Point): IPoint; containerToLngLat(pixel: Point): ILngLat; @@ -170,6 +171,7 @@ export interface IEarthService { setMapStatus(option: Partial): void; // coordinates methods + meterToCoord(center: number[], lnglat: number[]): number; pixelToLngLat(pixel: Point): ILngLat; lngLatToPixel(lnglat: Point): IPoint; containerToLngLat(pixel: Point): ILngLat; diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index c239a34162..098de574ad 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -9,7 +9,7 @@ import { IModel, IModelUniform, } from '@antv/l7-core'; -import { getCullFace, getMask } from '@antv/l7-utils'; +import { $window, getCullFace, getMask } from '@antv/l7-utils'; import { isNumber } from 'lodash'; import BaseModel from '../../core/BaseModel'; import { IPointLayerStyleOptions } from '../../core/interface'; @@ -26,8 +26,11 @@ import pointFillVert from '../shaders/fill_vert.glsl'; import { Version } from '@antv/l7-maps'; import { mat4, vec3 } from 'gl-matrix'; export default class FillModel extends BaseModel { - public meter2coord: number = 1; + private meter2coord: number = 1; + private meteryScale: number = 1; // 兼容 mapbox private isMeter: boolean = false; + + private unit: string = 'l7size'; public getUninforms(): IModelUniform { const { opacity = 1, @@ -38,7 +41,9 @@ export default class FillModel extends BaseModel { blend, blur = 0, raisingHeight = 0, + unit = 'l7size', } = this.layer.getLayerConfig() as IPointLayerStyleOptions; + this.updateUnit(unit); if ( this.dataTextureTest && @@ -89,6 +94,8 @@ export default class FillModel extends BaseModel { return { u_raisingHeight: Number(raisingHeight), + u_meter2coord: this.meter2coord, + u_meteryScale: this.meteryScale, u_isMeter: Number(this.isMeter), u_blur: blur, @@ -129,18 +136,7 @@ export default class FillModel extends BaseModel { } public initModels(): IModel[] { - const { - unit = 'l7size', - } = this.layer.getLayerConfig() as IPointLayerStyleOptions; - const { version } = this.mapService; - if ( - unit === 'meter' && - version !== Version.L7MAP && - version !== Version.GLOBEL - ) { - this.isMeter = true; - this.calMeter2Coord(); - } + this.updateUnit('l7size'); return this.buildModels(); } @@ -154,28 +150,36 @@ export default class FillModel extends BaseModel { const center = [(minLng + maxLng) / 2, (minLat + maxLat) / 2]; const { version } = this.mapService; - if (version === Version.MAPBOX && window.mapboxgl.MercatorCoordinate) { - const coord = window.mapboxgl.MercatorCoordinate.fromLngLat( + const mapboxContext = $window?.mapboxgl; + if (version === Version.MAPBOX && mapboxContext?.MercatorCoordinate) { + // 参考: + // https://docs.mapbox.com/mapbox-gl-js/api/geography/#mercatorcoordinate#meterinmercatorcoordinateunits + const coord = mapboxContext.MercatorCoordinate.fromLngLat( { lng: center[0], lat: center[1] }, 0, ); - const offsetInMeters = 1; - const offsetInMercatorCoordinateUnits = - offsetInMeters * coord.meterInMercatorCoordinateUnits(); - const westCoord = new window.mapboxgl.MercatorCoordinate( + const offsetInMercatorCoordinateUnits = coord.meterInMercatorCoordinateUnits(); + const westCoord = new mapboxContext.MercatorCoordinate( coord.x - offsetInMercatorCoordinateUnits, coord.y, coord.z, ); const westLnglat = westCoord.toLngLat(); + const southCoord = new mapboxContext.MercatorCoordinate( + coord.x, + coord.y - offsetInMercatorCoordinateUnits, + coord.z, + ); + const southLnglat = southCoord.toLngLat(); + this.meter2coord = center[0] - westLnglat.lng; + + this.meteryScale = (southLnglat.lat - center[1]) / this.meter2coord; return; } - // @ts-ignore const m1 = this.mapService.meterToCoord(center, [minLng, minLat]); - // @ts-ignore const m2 = this.mapService.meterToCoord(center, [ maxLng === minLng ? maxLng + 0.1 : maxLng, maxLat === minLat ? minLat + 0.1 : maxLat, @@ -213,10 +217,6 @@ export default class FillModel extends BaseModel { depth: { enable: isGlobel }, blend: this.getBlend(), stencil: getMask(mask, maskInside), - cull: { - enable: true, - face: getCullFace(this.mapService.version), - }, }), ]; } @@ -350,10 +350,7 @@ export default class FillModel extends BaseModel { attributeIdx: number, ) => { const { size = 5 } = feature; - // console.log('featureIdx', featureIdx, feature) - return Array.isArray(size) - ? [size[0] * this.meter2coord] - : [(size as number) * this.meter2coord]; + return Array.isArray(size) ? [size[0]] : [size as number]; }, }, }); @@ -385,4 +382,29 @@ export default class FillModel extends BaseModel { }, }); } + + /** + * 判断是否更新点图层的计量单位 + * @param unit + */ + private updateUnit(unit: string) { + const { version } = this.mapService; + if (this.unit !== unit) { + // l7size => meter + if ( + this.unit !== 'meter' && + unit === 'meter' && + version !== Version.L7MAP && + version !== Version.GLOBEL + ) { + this.isMeter = true; + this.calMeter2Coord(); + // meter => l7size + } else if (this.unit === 'meter' && unit !== 'meter') { + this.isMeter = false; + this.meter2coord = 1; + } + this.unit = unit; + } + } } diff --git a/packages/layers/src/point/shaders/fill_vert.glsl b/packages/layers/src/point/shaders/fill_vert.glsl index de09e1c2a3..a001c25eea 100644 --- a/packages/layers/src/point/shaders/fill_vert.glsl +++ b/packages/layers/src/point/shaders/fill_vert.glsl @@ -9,6 +9,8 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样 uniform float u_globel; uniform mat4 u_ModelMatrix; uniform mat4 u_Mvp; +uniform float u_meter2coord; +uniform float u_meteryScale; uniform float u_isMeter; varying vec4 v_data; @@ -36,7 +38,12 @@ uniform float u_raisingHeight: 0.0; void main() { vec3 extrude = a_Extrude; float shape_type = a_Shape; - float newSize = setPickingSize(a_Size); + /* + * setPickingSize 设置拾取大小 + * u_meter2coord 在等面积大小的时候设置单位 + */ + float newSize = setPickingSize(a_Size) * u_meter2coord; + // float newSize = setPickingSize(a_Size) * 0.00001038445708445579; // cal style mapping - 数据纹理映射部分的计算 styleMappingMat = mat4( @@ -126,7 +133,7 @@ void main() { // TODO: billboard // anti-alias // float antialiased_blur = -max(u_blur, antialiasblur); - float antialiasblur = -max(2.0 / u_DevicePixelRatio / a_Size, u_blur); + float antialiasblur = -max(2.0 / u_DevicePixelRatio / newSize, u_blur); vec2 offset = (extrude.xy * (newSize + u_stroke_width) + textrueOffsets); vec3 aPosition = a_Position; @@ -135,14 +142,18 @@ void main() { offset = project_pixel(offset); } else { // 以米为实际单位 - antialiasblur *= pow(19.0 - u_Zoom, 2.0); - antialiasblur = max(antialiasblur, -0.01); - // offset *= 0.5; - + if(newSize * pow(2.0, u_Zoom) < 48.0) { + antialiasblur = max(antialiasblur, -0.05); + } else if(newSize * pow(2.0, u_Zoom) < 128.0) { + antialiasblur = max(antialiasblur, -0.6/pow(u_Zoom, 2.0)); + } else { + antialiasblur = max(antialiasblur, -0.8/pow(u_Zoom, 2.0)); + } + if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - aPosition.xy += offset; - offset.x = 0.0; - offset.y = 0.0; + aPosition.x += offset.x / u_meteryScale; + aPosition.y += offset.y; + offset = vec2(0.0); } } diff --git a/packages/maps/src/earth/index.ts b/packages/maps/src/earth/index.ts index 5fa4227acd..6ca53d102b 100644 --- a/packages/maps/src/earth/index.ts +++ b/packages/maps/src/earth/index.ts @@ -1,7 +1,7 @@ import { Map } from '@antv/l7-map'; import BaseMapWrapper from '../BaseMapWrapper'; import MapService from './map'; -export default class MapboxWrapper extends BaseMapWrapper { +export default class EarthWrapper extends BaseMapWrapper { protected getServiceConstructor() { return MapService; } diff --git a/packages/maps/src/earth/map.ts b/packages/maps/src/earth/map.ts index 002ffc82ea..745e4995f8 100644 --- a/packages/maps/src/earth/map.ts +++ b/packages/maps/src/earth/map.ts @@ -36,7 +36,7 @@ import { MapTheme } from './theme'; const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; /** - * AMapService + * EarthService */ @injectable() export default class L7EarthService implements IEarthService { @@ -231,6 +231,10 @@ export default class L7EarthService implements IEarthService { return this.map.unproject(pixel); } + public meterToCoord(center: [number, number], outer: [number, number]) { + return 1.0; + } + public lngLatToPixel(lnglat: [number, number]): IPoint { return this.map.project(lnglat); } diff --git a/packages/maps/src/map/map.ts b/packages/maps/src/map/map.ts index 295c022484..5f06404f0d 100644 --- a/packages/maps/src/map/map.ts +++ b/packages/maps/src/map/map.ts @@ -223,6 +223,11 @@ export default class L7MapService implements IMapService { public setMapStyle(style: any): void { this.map.setStyle(this.getMapStyle(style)); } + + public meterToCoord(center: [number, number], outer: [number, number]) { + return 1.0; + } + // TODO: 计算像素坐标 public pixelToLngLat(pixel: [number, number]): ILngLat { return this.map.unproject(pixel); diff --git a/stories/Map/components/bugfix.tsx b/stories/Map/components/bugfix.tsx index e39392beaf..604fe7a78d 100644 --- a/stories/Map/components/bugfix.tsx +++ b/stories/Map/components/bugfix.tsx @@ -24,45 +24,46 @@ export default class Amap2demo extends React.Component { public async componentDidMount() { const scene = new Scene({ id: 'map', - map: new GaodeMap({ - pitch: 0, - style: 'blank', - // center: [115, 30], - + map: new Mapbox({ + // style: 'blank', center: [120, 30], - - zoom: 0, - // layers: [new window.AMap.TileLayer.Satellite()] + zoom: 15, }), }); this.scene = scene; scene.on('loaded', () => { - const layer = new HeatmapLayer({}) - .source([{ lng: 120, lat: 30, mag: 1 }], { - parser: { type: 'json', x: 'lng', y: 'lat' }, - }) - .shape('heatmap') - .size('mag', [0, 1.0]) // weight映射通道 - .style({ - intensity: 2, - radius: 20, - opacity: 1.0, - rampColors: { - colors: [ - '#FF4818', - '#F7B74A', - '#FFF598', - '#F27DEB', - '#8C1EB2', - '#421EB2', - ].reverse(), - positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], + const layer = new PointLayer() + .source( + [ + { + lng: 120, + lat: 30, + }, + ], + { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, }, + ) + .shape('circle') + .color('#f00') + .size(150) + .style({ + unit: 'meter', }); - - this.scene.addLayer(layer); + // setTimeout(() => { + // layer.style({ + // opacity: 0.5, + // unit: '' + // }) + // scene.render() + // }, 2000) + scene.addLayer(layer); }); }