fix: circle meter size && remove unuse code file (#1550)

This commit is contained in:
@thinkinggis 2022-12-21 17:15:05 +08:00 committed by GitHub
parent ef317bfb26
commit c188238b70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 177 additions and 1599 deletions

View File

@ -9,7 +9,7 @@ import {
// @ts-ignore
} from '@antv/l7';
// @ts-ignore
import { GaodeMap } from '@antv/l7-maps';
import { Map,GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';
export default () => {
@ -70,7 +70,7 @@ export default () => {
const source = new Source(geoData);
const layer = new LineLayer({ blend: 'normal' })
.source(source)
.size(1)
.size(10)
.shape('line')
.color('#f00')
.style({});

View File

@ -9,7 +9,7 @@ import {
// @ts-ignore
} from '@antv/l7';
// @ts-ignore
import { GaodeMap } from '@antv/l7-maps';
import { GaodeMap,Map } from '@antv/l7-maps';
import React, { useEffect } from 'react';
export default () => {
@ -54,8 +54,8 @@ export default () => {
type: 'MultiLineString',
coordinates: [
[
[120, 30],
[120, 40],
[116.43,39.97],
[108.39,22.91],
],
],
},
@ -64,11 +64,12 @@ export default () => {
};
const source = new Source(geoData);
// scene.on('zoom', e => console.log(e))
const layer = new LineLayer({ blend: 'normal' })
.source(source)
.size(1)
.size(2)
.shape('arc')
.color('#f00')
.style({
@ -77,15 +78,15 @@ export default () => {
thetaOffset: 0.5,
});
source.on('update', () => {
const midPoints = lineAtOffset(source, {
offset: 0.1,
shape: 'arc',
thetaOffset: 0.5,
mapVersion: scene.getMapService().version,
});
const point = new PointLayer({ blend: 'normal', zIndex: 1 })
.source(midPoints, {
.source([{
lng:116.43,
lat:39.97
},{
lng:108.39,
lat:22.91
}], {
parser: {
type: 'json',
x: 'lng',
@ -94,21 +95,15 @@ export default () => {
})
.shape('circle')
.size(10)
.color('#ff0');
scene.addLayer(point);
});
(async () => {
// const midPoints = await lineAtOffsetAsyc(source, 0.1, 'arc', 'offset');
const midPoints = await lineAtOffsetAsyc(source, {
offset: 0.3,
shape: 'arc',
thetaOffset: 0.5,
mapVersion: scene.getMapService().version,
featureId: 1,
});
const point = new PointLayer({ blend: 'normal', zIndex: 1 })
.source(midPoints, {
.color('blue');
const point2 = new PointLayer({ blend: 'normal', zIndex: 1 })
.source([{
lng:116.43,
lat:39.97
},{
lng:108.39,
lat:22.91
}], {
parser: {
type: 'json',
x: 'lng',
@ -116,13 +111,15 @@ export default () => {
},
})
.shape('circle')
.size(5)
.color('#0f0')
.size(100000)
.color('blue')
.style({
opacity: 0.8,
});
opacity:0.5,
unit:'meter'
})
scene.addLayer(point);
})();
scene.addLayer(point2);
scene.on('loaded', () => {
scene.addLayer(layer);

View File

@ -0,0 +1,2 @@
### point - circle 等面积
<code src="./demos/circlemeter.tsx"></code>

View File

@ -0,0 +1,65 @@
import { Scene, PointLayer,PolygonLayer } from "@antv/l7";
import { GaodeMap } from "@antv/l7-maps";
import React, { useEffect } from 'react';
import * as turf from '@turf/turf'
export default () => {
useEffect( () => {
const scene = new Scene({
id: "map",
map: new GaodeMap({
style: "light",
center: [120.099658370018, 30.263445807542666],
zoom: 10
})
});
scene.on("loaded", () => {
const size = 1000;
const circle = turf.circle([120.099658370018, 30.263445807542666],size/1000,{
steps: 60, units: 'kilometers'
});
const player = new PolygonLayer().source(turf.featureCollection([circle]))
.shape('fill')
.color('blue')
.style({
opacity:0.5
})
const pointLayer = new PointLayer({
autoFit: false
})
.source({
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {},
geometry: {
type: "Point",
coordinates: [120.099658370018, 30.263445807542666]
}
}
]
})
.shape("circle")
.size(size)
.color("#ff0000")
.active(true)
.style({
opacity: 0.3,
strokeWidth: 1,
unit:'meter'
});
scene.addLayer(player);
scene.addLayer(pointLayer);
});
}, []);
return (
<div
id="map"
style={{
height: '500px',
position: 'relative',
}}
/>
);
};

View File

@ -32,9 +32,12 @@ export default () => {
},
},
)
.size(25)
.size(100)
.color('#f00')
.shape('radar')
.style({
unit:'pixel'
})
.animate(true)
.active(true);

View File

@ -32,6 +32,9 @@ export default () => {
y: 'lat',
},
})
.style({
unit:'meter'
})
.shape('marker')
.size(36)

View File

@ -147,38 +147,38 @@ float project_pixel_allmap(float pixel) {
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return pixel * pow(2.0, u_Zoom);
}
return pixel;
return pixel * u_FocalDistance ;
}
// 适配纹理贴图的等像素大小
float project_pixel_texture(float pixel) {
// mapbox zoom > 12
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
return pixel * pow(0.5, u_Zoom);
return pixel * pow(0.5, u_Zoom) * u_FocalDistance ;
}
// amap2 zoom > 12
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom))* u_FocalDistance ;
}
// amap zoom > 12
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
return pixel * pow(0.5, u_Zoom);
return pixel * pow(0.5, u_Zoom)* u_FocalDistance ;
}
// amap zoom < 12
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
return pixel * pow(2.0, (20.0 - u_Zoom));
return pixel * pow(2.0, (20.0 - u_Zoom))* u_FocalDistance ;
}
return pixel * 2.0;
return pixel * 2.0 * u_FocalDistance;;
}
// 在不论什么底图下需要统一处理的时候使用
float project_float_pixel(float pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// mapbox P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ;
}
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// amap P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
@ -186,43 +186,43 @@ float project_float_pixel(float pixel) {
}
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
// amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减3
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom))* u_FocalDistance ;
}
return pixel;
return pixel * u_FocalDistance;
}
float project_pixel(float pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// amap P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ;
}
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
// amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减3
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ;
}
return pixel;
return pixel * u_FocalDistance;
}
vec2 project_pixel(vec2 pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ;
}
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 * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ;
}
return pixel * -1.;
return pixel * -1. * u_FocalDistance;
}
vec3 project_pixel(vec3 pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ;
}
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 * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ;
}
return pixel * -1.;
return pixel * -1. * u_FocalDistance;
}
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {

View File

@ -83,7 +83,10 @@ export interface ILineLayerStyleOptions extends IBaseLayerStyleOptions {
enablePicking?: boolean;
workerEnabled?: boolean;
}
export enum SizeUnitType {
pixel = 0,
meter = 1,
}
export interface IPointLayerStyleOptions extends IBaseLayerStyleOptions {
tileOrigin?: number[];
coord?: string;
@ -118,7 +121,7 @@ export interface IPointLayerStyleOptions extends IBaseLayerStyleOptions {
offsets?: styleOffset;
unit?: string;
unit?: SizeUnitType;
rotation?: number; // angle
speed?: number;
@ -191,11 +194,6 @@ export interface IImageLayerStyleOptions extends IBaseLayerStyleOptions {
rampColors?: IColorRamp;
rampColorsData?: ImageData | IImagedata;
colorTexture?: ITexture2D;
pixelConstant?: number;
pixelConstantR?: number;
pixelConstantG?: number;
pixelConstantB?: number;
pixelConstantRGB?: number;
}
export interface ICityBuildLayerStyleOptions {

View File

@ -6,7 +6,6 @@ import LineHalfModel from './half';
import LineModel from './line';
import LinearLine from './linearline';
import SimpleLineModel from './simpleLine';
import TileLineModel from './tile';
import LineWallModel from './wall';
export type LineModelType =
@ -18,7 +17,6 @@ export type LineModelType =
| 'line'
| 'halfLine'
| 'linearline'
| 'tileLine'
| 'earthArc3d';
const LineModels: { [key in LineModelType]: any } = {
@ -30,7 +28,6 @@ const LineModels: { [key in LineModelType]: any } = {
halfLine: LineHalfModel,
simple: SimpleLineModel,
linearline: LinearLine,
tileLine: TileLineModel,
earthArc3d: EarthArc3DModel,
};

View File

@ -1,137 +0,0 @@
import {
AttributeType,
gl,
IEncodeFeature,
IModel,
IModelUniform,
} from '@antv/l7-core';
import { getMask, rgb2arr } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions } from '../../core/interface';
import { LineTriangulation } from '../../core/triangulation';
import line_tile_frag from '../../shader/minify_picking_frag.glsl';
import line_tile_vert from '../shaders/tile/line_tile_vert.glsl';
import line_tile_map_frag from '../../shader/minify_frag.glsl';
import line_tile_map_vert from '../shaders/tile/line_tile_map_vert.glsl'
export default class LineModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity = 1,
usage,
color = '#fff',
size = 1
// coord = 'lnglat',
// tileOrigin,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return {
// u_tileOrigin: tileOrigin || [0, 0],
// u_coord: coord === 'lnglat' ? 1.0 : 0.0,
u_opacity: Number(opacity),
u_color: usage === 'basemap' ? rgb2arr(color): [0, 0, 0, 0],
u_size: usage === 'basemap' ? size: 1
};
}
public async initModels(): Promise<IModel[]> {
return await this.buildModels();
}
public async buildModels(): Promise<IModel[]> {
const {
mask = false,
maskInside = true,
depth = false,
usage
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
this.layer.triangulation = LineTriangulation;
const model = await this.layer
.buildLayerModel({
moduleName: 'lineTile_' + usage,
vertexShader: usage === 'basemap' ? line_tile_map_vert : line_tile_vert,
fragmentShader: usage === 'basemap' ? line_tile_map_frag : line_tile_frag,
triangulation: LineTriangulation,
blend: this.getBlend(),
depth: { enable: depth },
stencil: getMask(mask, maskInside),
pick: usage !== 'basemap'
})
return [model]
}
protected registerBuiltinAttributes() {
const { usage } = this.layer.getLayerConfig();
if(usage !== 'basemap') {
this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
) => {
const { size = 1 } = feature;
return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0];
},
},
});
}
this.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'miter',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Miter',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
) => {
return [vertex[4]];
},
},
});
}
}

View File

@ -1,25 +0,0 @@
attribute float a_Miter;
attribute vec4 a_Color;
attribute vec3 a_Normal;
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_size;
#pragma include "projection"
void main() {
vec3 size = a_Miter * u_size * reverse_offset_normal(a_Normal);
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Position.xy, 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, 0.0, 1.0));
}
}

View File

@ -1,52 +0,0 @@
attribute float a_Miter;
attribute vec4 a_Color;
attribute vec2 a_Size;
attribute vec3 a_Normal;
attribute vec3 a_Position;
// uniform vec2 u_tileOrigin;
// uniform float u_coord;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
#pragma include "projection"
#pragma include "picking"
varying vec4 v_color;
void main() {
v_color = a_Color;
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
// if(u_coord > 0.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, 0.0, 1.0));
}
// } else { // 使用偏移坐标
// vec2 pointPos = a_Position.xy;
// vec4 tileWorld = vec4(project_mvt_offset_position(vec4(u_tileOrigin, 0.0, 1.0)).xyz, 1.0); // 瓦片起始点的世界坐标
// vec2 pointOffset = pointPos * pow(2.0, u_Zoom); // 瓦片内的点的偏移坐标
// tileWorld.xy += pointOffset;
// tileWorld.xy += offset;
// if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// // Needs to be divided with project_uCommonUnitsPerMeter
// tileWorld.w *= u_PixelsPerMeter.z;
// }
// gl_Position = u_ViewProjectionMatrix * tileWorld + u_ViewportCenterProjection;
// }
setPickingColor(a_PickingColor);
}

View File

@ -1,15 +0,0 @@
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
#pragma include "projection"
void main() {
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * (vec4(project_pos.xy, 0.0, 1.0));
} else {
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0));
}
}

View File

@ -1,21 +0,0 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
#pragma include "projection"
varying vec4 v_color;
void main() {
v_color = a_Color;
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * (vec4(project_pos.xy, 0.0, 1.0));
} else {
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0));
}
}

View File

@ -9,7 +9,7 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import { $window, getMask, PointFillTriangulation } from '@antv/l7-utils';
import { getMask, PointFillTriangulation } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
@ -18,15 +18,11 @@ import waveFillFrag from '../shaders/animate/wave_frag.glsl';
// static pointLayer shader - not support animate
import pointFillFrag from '../shaders/fill_frag.glsl';
import pointFillVert from '../shaders/fill_vert.glsl';
import { SizeUnitType } from '../../core/interface'
import { Version } from '@antv/l7-maps';
export default class FillModel extends BaseModel {
private meter2coord: number = 1;
private meterYScale: number = 1; // 兼容 mapbox
private isMeter: boolean = false;
private unit: string = 'l7size';
public getUninforms(): IModelUniform {
const {
opacity = 1,
@ -38,9 +34,8 @@ export default class FillModel extends BaseModel {
blur = 0,
raisingHeight = 0,
heightfixed = false,
unit = 'l7size',
unit = 'pixel',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.updateUnit(unit);
if (
this.dataTextureTest &&
this.dataTextureNeedUpdate({
@ -89,12 +84,7 @@ export default class FillModel extends BaseModel {
return {
u_raisingHeight: Number(raisingHeight),
u_heightfixed: Number(heightfixed),
u_meter2coord: this.meter2coord,
u_meteryScale: this.meterYScale,
u_isMeter: Number(this.isMeter),
u_blur: blur,
u_additive: blend === 'additive' ? 1.0 : 0.0,
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
u_cellTypeLayout: this.getCellTypeLayout(),
@ -103,6 +93,7 @@ export default class FillModel extends BaseModel {
u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0,
u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 1.0,
u_stroke_color: this.getStrokeColor(stroke),
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
u_offsets: this.isOffsetStatic(offsets)
? (offsets as [number, number])
: [0, 0],
@ -131,60 +122,9 @@ export default class FillModel extends BaseModel {
}
public async initModels(): Promise<IModel[]> {
this.updateUnit('l7size');
return await this.buildModels();
}
/**
* unit meter
* @returns
*/
public calMeter2Coord() {
const [minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent;
const center = [(minLng + maxLng) / 2, (minLat + maxLat) / 2];
const { version } = this.mapService;
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 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;
}
const m1 = this.mapService.meterToCoord(center, [minLng, minLat]);
const m2 = this.mapService.meterToCoord(center, [
maxLng === minLng ? maxLng + 0.1 : maxLng,
maxLat === minLat ? minLat + 0.1 : maxLat,
]);
this.meter2coord = (m1 + m2) / 2;
if (!this.meter2coord) {
// Tip: 兼容单个数据导致的 m1、m2 为 NaN
this.meter2coord = 7.70681090738883;
}
}
public async buildModels():Promise<IModel[]> {
const {
mask = false,
@ -335,28 +275,5 @@ 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.DEFUALT &&
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;
}
}
}

View File

@ -8,7 +8,6 @@ import {
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { Version } from '@antv/l7-maps';
import { getCullFace, getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
@ -17,6 +16,7 @@ import { PointFillTriangulation } from '../../core/triangulation';
// static pointLayer shader - not support animate
import pointFillFrag from '../shaders/image/fillImage_frag.glsl';
import pointFillVert from '../shaders/image/fillImage_vert.glsl';
import { SizeUnitType } from '../../core/interface'
export default class FillImageModel extends BaseModel {
private meter2coord: number = 1;
@ -30,6 +30,7 @@ export default class FillImageModel extends BaseModel {
rotation,
raisingHeight = 0.0,
heightfixed = false,
unit = 'pixel',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
if (this.rendererService.getDirty()) {
@ -98,7 +99,7 @@ export default class FillImageModel extends BaseModel {
return {
u_raisingHeight: Number(raisingHeight),
u_heightfixed: Number(heightfixed),
u_isMeter: Number(this.isMeter),
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
u_RotateMatrix: new Float32Array([
Math.cos(this.radian),
Math.sin(this.radian),
@ -134,63 +135,10 @@ export default class FillImageModel extends BaseModel {
public async initModels():Promise<IModel[]> {
this.iconService.on('imageUpdate', this.updateTexture);
this.updateTexture();
const {
unit = 'l7size',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const { version } = this.mapService;
if (
unit === 'meter' &&
version !== Version.DEFUALT &&
version !== Version.GLOBEL
) {
this.isMeter = true;
this.calMeter2Coord();
}
return await this.buildModels();
}
/**
* unit meter
* @returns
*/
public calMeter2Coord() {
const [minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent;
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(
{ lng: center[0], lat: center[1] },
0,
);
const offsetInMeters = 1;
const offsetInMercatorCoordinateUnits =
offsetInMeters * coord.meterInMercatorCoordinateUnits();
const westCoord = new window.mapboxgl.MercatorCoordinate(
coord.x - offsetInMercatorCoordinateUnits,
coord.y,
coord.z,
);
const westLnglat = westCoord.toLngLat();
this.meter2coord = center[0] - westLnglat.lng;
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,
]);
this.meter2coord = (m1 + m2) / 2;
if (!this.meter2coord) {
// Tip: 兼容单个数据导致的 m1、m2 为 NaN
this.meter2coord = 7.70681090738883;
}
}
public async buildModels():Promise<IModel[]> {
const {
@ -313,8 +261,8 @@ export default class FillImageModel extends BaseModel {
) => {
const { size = 5 } = feature;
return Array.isArray(size)
? [size[0] * this.meter2coord]
: [(size as number) * this.meter2coord];
? [size[0]]
: [(size as number)];
},
},
});

View File

@ -9,8 +9,6 @@ import NormalModel from './normal';
import Radar from './radar';
import SimplePoint from './simplePoint';
import TextModel from './text';
import TileTextModel from './tileText';
import TileFillModel from './tile';
export type PointType =
| 'fillImage'
@ -21,8 +19,6 @@ export type PointType =
| 'simplePoint'
| 'extrude'
| 'text'
| 'tile'
| 'tileText'
| 'earthFill'
| 'earthExtrude';
@ -35,8 +31,6 @@ const PointModels: { [key in PointType]: any } = {
simplePoint: SimplePoint,
extrude: ExtrudeModel,
text: TextModel,
tile: TileFillModel,
tileText: TileTextModel,
earthFill: EarthFillModel,
earthExtrude: EarthExtrudeModel,
};

View File

@ -17,21 +17,19 @@ import { PointFillTriangulation } from '../../core/triangulation';
import pointFillFrag from '../shaders/radar/radar_frag.glsl';
import pointFillVert from '../shaders/radar/radar_vert.glsl';
import { Version } from '@antv/l7-maps';
import { SizeUnitType } from '../../core/interface'
export default class RadarModel extends BaseModel {
public meter2coord: number = 1;
private isMeter: boolean = false;
public getUninforms(): IModelUniform {
const {
opacity = 1,
blend,
speed = 1,
unit = 'pixel'
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
return {
u_isMeter: Number(this.isMeter),
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
u_speed: speed,
u_additive: blend === 'additive' ? 1.0 : 0.0,
u_opacity: isNumber(opacity) ? opacity : 1.0,
@ -60,63 +58,10 @@ export default class RadarModel extends BaseModel {
}
public async initModels():Promise<IModel[]> {
const {
unit = 'l7size',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const { version } = this.mapService;
if (
unit === 'meter' &&
version !== Version.DEFUALT &&
version !== Version.GLOBEL
) {
this.isMeter = true;
this.calMeter2Coord();
}
return await this.buildModels();
}
/**
* unit meter
* @returns
*/
public calMeter2Coord() {
const [minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent;
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(
{ lng: center[0], lat: center[1] },
0,
);
const offsetInMeters = 1;
const offsetInMercatorCoordinateUnits =
offsetInMeters * coord.meterInMercatorCoordinateUnits();
const westCoord = new window.mapboxgl.MercatorCoordinate(
coord.x - offsetInMercatorCoordinateUnits,
coord.y,
coord.z,
);
const westLnglat = westCoord.toLngLat();
this.meter2coord = center[0] - westLnglat.lng;
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,
]);
this.meter2coord = (m1 + m2) / 2;
if (!this.meter2coord) {
// Tip: 兼容单个数据导致的 m1、m2 为 NaN
this.meter2coord = 7.70681090738883;
}
}
public async buildModels():Promise<IModel[]> {
const {
@ -194,8 +139,8 @@ export default class RadarModel extends BaseModel {
) => {
const { size = 5 } = feature;
return Array.isArray(size)
? [size[0] * this.meter2coord]
: [(size as number) * this.meter2coord];
? [size[0]]
: [(size as number)];
},
},
});

View File

@ -1,171 +0,0 @@
import {
AttributeType,
gl,
IAttribute,
IElements,
IEncodeFeature,
ILayerConfig,
IModel,
IModelUniform,
} from '@antv/l7-core';
import { getCullFace } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import { PointFillTriangulation } from '../../core/triangulation';
import point_tile_frag from '../shaders/tile/fill_tile_frag.glsl';
import point_tile_vert from '../shaders/tile/fill_tile_vert.glsl';
export default class FillModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity = 1,
strokeOpacity = 1,
strokeWidth = 0,
stroke = 'rgba(0,0,0,0)',
blend,
// coord = 'lnglat',
// tileOrigin,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
return {
// u_tileOrigin: tileOrigin || [0, 0],
// u_coord: coord === 'lnglat' ? 1.0 : 0.0,
u_additive: blend === 'additive' ? 1.0 : 0.0,
u_opacity: Number(opacity),
u_stroke_opacity: Number(strokeOpacity),
u_stroke_width: Number(strokeWidth),
u_stroke_color: this.getStrokeColor(stroke),
};
}
public getAttribute(): {
attributes: {
[attributeName: string]: IAttribute;
};
elements: IElements;
} {
return this.styleAttributeService.createAttributesAndIndices(
this.layer.getEncodedData(),
PointFillTriangulation,
);
}
public async initModels():Promise<IModel[]> {
return await this.buildModels();
}
public async buildModels():Promise<IModel[]> {
const {
workerEnabled = false,
usage
} = this.layer.getLayerConfig() as Partial<
ILayerConfig & IPointLayerStyleOptions
>;
this.layer.triangulation = PointFillTriangulation;
const model = await this.layer
.buildLayerModel({
moduleName: 'pointTile_' + usage,
vertexShader: point_tile_vert,
fragmentShader: point_tile_frag,
triangulation: PointFillTriangulation,
depth: { enable: false },
cull: {
enable: true,
face: getCullFace(this.mapService.version),
},
blend: this.getBlend(),
workerEnabled,
workerOptions: {
modelType: 'pointTile',
},
pick: usage !== 'basemap'
})
return [model]
}
public clearModels() {
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
name: 'extrude',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Extrude',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const extrude = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0];
const extrudeIndex = (attributeIdx % 4) * 3;
return [
extrude[extrudeIndex],
extrude[extrudeIndex + 1],
extrude[extrudeIndex + 2],
];
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
) => {
const { size = 5 } = feature;
return Array.isArray(size)
? [size[0]]
: [(size as number)];
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'shape',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Shape',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
) => {
const { shape = 2 } = feature;
const shape2d = this.layer.getLayerConfig().shape2d as string[];
const shapeIndex = shape2d.indexOf(shape as string);
return [shapeIndex];
},
},
});
}
}

View File

@ -1,412 +0,0 @@
import {
AttributeType,
gl,
IEncodeFeature,
IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import {
calculateCentroid,
padBounds,
rgb2arr
} from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import CollisionIndex from '../../utils/collision-index';
import {
getGlyphQuads,
IGlyphQuad,
shapeText,
} from '../../utils/symbol-layout';
import text_frag from '../shaders/tile/text_frag.glsl';
import text_vert from '../shaders/tile/text_vert.glsl';
import text_map_frag from '../shaders/tile/text_map_frag.glsl';
import text_map_vert from '../shaders/tile/text_map_vert.glsl';
export function TextTriangulation(feature: IEncodeFeature) {
// @ts-ignore
const that = this as TextModel;
const id = feature.id as number;
const vertices: number[] = [];
const indices: number[] = [];
if (!that.glyphInfoMap || !that.glyphInfoMap[id]) {
return {
vertices: [], // [ x, y, z, tex.x,tex.y, offset.x. offset.y]
indices: [],
size: 7,
};
}
const centroid = that.glyphInfoMap[id].centroid as number[]; // 计算中心点
const coord =
centroid.length === 2 ? [centroid[0], centroid[1], 0] : centroid;
that.glyphInfoMap[id].glyphQuads.forEach(
(quad: IGlyphQuad, index: number) => {
vertices.push(
...coord,
quad.tex.x,
quad.tex.y + quad.tex.height,
quad.tl.x,
quad.tl.y,
...coord,
quad.tex.x + quad.tex.width,
quad.tex.y + quad.tex.height,
quad.tr.x,
quad.tr.y,
...coord,
quad.tex.x + quad.tex.width,
quad.tex.y,
quad.br.x,
quad.br.y,
...coord,
quad.tex.x,
quad.tex.y,
quad.bl.x,
quad.bl.y,
);
indices.push(
0 + index * 4,
1 + index * 4,
2 + index * 4,
2 + index * 4,
3 + index * 4,
0 + index * 4,
);
},
);
return {
vertices, // [ x, y, z, tex.x,tex.y, offset.x. offset.y]
indices,
size: 7,
};
}
export default class TextModel extends BaseModel {
public glyphInfo: IEncodeFeature[];
public glyphInfoMap: {
[key: string]: {
shaping: any;
glyphQuads: IGlyphQuad[];
centroid: number[];
};
} = {};
private texture: ITexture2D;
private currentZoom: number = -1;
private extent: [[number, number], [number, number]];
private textureHeight: number = 0;
private textCount: number = 0;
private preTextStyle: Partial<IPointLayerStyleOptions> = {};
public getUninforms(): IModelUniform {
const {
opacity = 1.0,
stroke = '#fff',
strokeWidth = 0,
textAnchor = 'center',
textAllowOverlap = false,
halo = 0.5,
gamma = 2.0,
usage,
color = '#fff',
size = 1
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const { canvas, mapping } = this.fontService;
if (Object.keys(mapping).length !== this.textCount) {
this.updateTexture();
this.textCount = Object.keys(mapping).length;
}
this.preTextStyle = {
textAnchor,
textAllowOverlap,
};
return {
u_opacity: isNumber(opacity) ? opacity : 1.0,
u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 1.0,
u_stroke_color: this.getStrokeColor(stroke),
u_sdf_map: this.texture,
u_halo_blur: halo,
u_gamma_scale: gamma,
u_sdf_map_size: [canvas.width, canvas.height],
u_color: usage === 'basemap' ? rgb2arr(color): [0, 0, 0, 0],
u_size: usage === 'basemap' ? size : 1
};
}
public async initModels():Promise<IModel[]> {
this.extent = this.textExtent();
const {
textAnchor = 'center',
textAllowOverlap = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.preTextStyle = {
textAnchor,
textAllowOverlap,
};
return await this.buildModels();
}
public async buildModels ():Promise<IModel[]> {
this.mapping();
const { usage } = this.layer.getLayerConfig();
const model = await this.layer
.buildLayerModel({
moduleName: 'pointTileText_' + usage,
vertexShader: usage === 'basemap' ? text_map_vert : text_vert,
fragmentShader: usage === 'basemap' ? text_map_frag : text_frag,
triangulation: TextTriangulation.bind(this),
depth: { enable: false },
blend: this.getBlend(),
pick: usage !== 'basemap'
})
return [model]
}
public clearModels() {
this.texture?.destroy();
}
protected registerBuiltinAttributes() {
const { usage } = this.layer.getLayerConfig();
this.styleAttributeService.registerStyleAttribute({
name: 'textOffsets',
type: AttributeType.Attribute,
descriptor: {
name: 'a_textOffsets',
buffer: {
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
) => {
return [vertex[5], vertex[6]];
},
},
});
if(usage !== 'basemap') {
this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
) => {
const { size = 12 } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
}
this.styleAttributeService.registerStyleAttribute({
name: 'textUv',
type: AttributeType.Attribute,
descriptor: {
name: 'a_tex',
buffer: {
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
) => {
return [vertex[3], vertex[4]];
},
},
});
}
private mapping = () => {
this.initGlyph();
this.updateTexture();
this.filterGlyphs();
this.reBuildModel();
};
private textExtent(): [[number, number], [number, number]] {
const bounds = this.mapService.getBounds();
return padBounds(bounds, 0.5);
}
/**
*
*/
private initTextFont() {
const {
fontWeight = '400',
fontFamily = 'sans-serif',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const data = this.layer.getEncodedData();
const characterSet: string[] = [];
data.forEach((item: IEncodeFeature) => {
let { shape = '' } = item;
shape = shape.toString();
for (const char of shape) {
// 去重
if (characterSet.indexOf(char) === -1) {
characterSet.push(char);
}
}
});
this.fontService.setFontOptions({
characterSet,
fontWeight,
fontFamily,
iconfont: false,
});
}
/**
*
*/
private generateGlyphLayout() {
const { mapping } = this.fontService;
const {
spacing = 2,
textAnchor = 'center',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const data = this.layer.getEncodedData();
this.glyphInfo = data.map((feature: IEncodeFeature) => {
const { shape = '', id, size = 1, textOffset = [0, 0] } = feature;
const shaping = shapeText(
shape.toString(),
mapping,
// @ts-ignore
size,
textAnchor,
'left',
spacing,
textOffset,
false,
);
const glyphQuads = getGlyphQuads(shaping, textOffset, false);
feature.shaping = shaping;
feature.glyphQuads = glyphQuads;
feature.centroid = calculateCentroid(feature.coordinates);
// 此时地图高德2.0 originCentroid == centroid
feature.originCentroid =
feature.version === 'GAODE2.x'
? calculateCentroid(feature.originCoordinates)
: (feature.originCentroid = feature.centroid);
this.glyphInfoMap[id as number] = {
shaping,
glyphQuads,
centroid: calculateCentroid(feature.coordinates),
};
return feature;
});
}
/**
* depend on originCentorid
*/
private filterGlyphs() {
const {
padding = [4, 4],
textAllowOverlap = false,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
if (textAllowOverlap) {
// 如果允许文本覆盖
return;
}
this.glyphInfoMap = {};
this.currentZoom = this.mapService.getZoom();
this.extent = this.textExtent();
const { width, height } = this.rendererService.getViewportSize();
const collisionIndex = new CollisionIndex(width, height);
const filterData = this.glyphInfo.filter((feature: IEncodeFeature) => {
const { shaping, id = 0 } = feature;
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);
const { box } = collisionIndex.placeCollisionBox({
x1: shaping.left * fontScale - padding[0],
x2: shaping.right * fontScale + padding[0],
y1: shaping.top * fontScale - padding[1],
y2: shaping.bottom * fontScale + padding[1],
anchorPointX: pixels.x,
anchorPointY: pixels.y,
});
if (box && box.length) {
collisionIndex.insertCollisionBox(box, id);
return true;
} else {
return false;
}
});
filterData.forEach((item) => {
// @ts-ignore
this.glyphInfoMap[item.id as number] = item;
});
}
/**
*
*/
private initGlyph() {
// 1.生成文字纹理
this.initTextFont();
// 2.生成文字布局
this.generateGlyphLayout();
}
/**
*
*/
private updateTexture() {
const { createTexture2D } = this.rendererService;
const { canvas } = this.fontService;
this.textureHeight = canvas.height;
if (this.texture) {
this.texture.destroy();
}
this.texture = createTexture2D({
data: canvas,
mag: gl.LINEAR,
min: gl.LINEAR,
width: canvas.width,
height: canvas.height,
});
}
private async reBuildModel() {
const { usage } = this.layer.getLayerConfig();
this.filterGlyphs();
const model = await this.layer
.buildLayerModel({
moduleName: 'pointTileText_' + usage,
vertexShader: usage === 'basemap' ? text_map_vert : text_vert,
fragmentShader: usage === 'basemap' ? text_map_frag : text_frag,
triangulation: TextTriangulation.bind(this),
depth: { enable: false },
blend: this.getBlend(),
pick: usage !== 'basemap'
})
return [model]
}
}

View File

@ -8,9 +8,7 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_meter2coord;
uniform float u_meteryScale;
uniform float u_isMeter;
uniform int u_Size_Unit;
varying vec4 v_data;
varying vec4 v_color;
@ -42,7 +40,7 @@ void main() {
* setPickingSize 设置拾取大小
* u_meter2coord 在等面积大小的时候设置单位
*/
float newSize = setPickingSize(a_Size) * u_meter2coord;
float newSize = setPickingSize(a_Size);
// float newSize = setPickingSize(a_Size) * 0.00001038445708445579;
// cal style mapping - 数据纹理映射部分的计算
@ -126,9 +124,11 @@ void main() {
// unpack color(vec2)
v_color = a_Color;
if(u_Size_Unit == 1) {
newSize = newSize * u_PixelsPerMeter.z;
}
// radius(16-bit)
v_radius = newSize;
v_radius = newSize;
// anti-alias
// float antialiased_blur = -max(u_blur, antialiasblur);
@ -136,26 +136,9 @@ void main() {
vec2 offset = (extrude.xy * (newSize + u_stroke_width) + textrueOffsets);
vec3 aPosition = a_Position;
if(u_isMeter < 1.0) {
// 不以米为实际单位
offset = project_pixel(offset);
} else {
// 以米为实际单位
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.x += offset.x / u_meteryScale;
aPosition.y += offset.y;
offset = vec2(0.0);
}
}
offset = project_pixel(offset);
// TODP: /abs(extrude.x) 是为了兼容地球模式
v_data = vec4(extrude.x/abs(extrude.x), extrude.y/abs(extrude.y), antialiasblur,shape_type);
@ -177,7 +160,7 @@ void main() {
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * vec4(project_pos.xy + offset, raisingHeight, 1.0);
gl_Position = u_Mvp * vec4(project_pos.xy + offset, raisingHeight, 1.0);
} else {
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, raisingHeight, 1.0));
}

View File

@ -10,7 +10,7 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform mat2 u_RotateMatrix;
uniform float u_isMeter;
uniform int u_Size_Unit;
varying vec2 v_uv; // 本身的 uv 坐标
varying vec2 v_Iconuv; // icon 贴图的 uv 坐标
@ -76,22 +76,16 @@ void main() {
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);
float newSize = a_Size;
if(u_Size_Unit == 1) {
newSize = newSize * u_PixelsPerMeter.z;
}
// vec2 offset = (u_RotateMatrix * extrude.xy * (a_Size) + textrueOffsets);
vec2 offset = (rotation_matrix * u_RotateMatrix * extrude.xy * (a_Size) + textrueOffsets);
vec2 offset = (rotation_matrix * u_RotateMatrix * extrude.xy * (newSize) + textrueOffsets);
vec3 aPosition = a_Position;
if(u_isMeter < 1.0) {
// 不以米为实际单位
offset = project_pixel(offset);
} else {
// 以米为实际单位
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
aPosition.xy += offset;
offset.x = 0.0;
offset.y = 0.0;
}
}
offset = project_pixel(offset);
vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0));
float raisingHeight = u_raisingHeight;
@ -105,7 +99,7 @@ void main() {
}
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * vec4(project_pos.xy + offset, raisingHeight, 1.0);
gl_Position = u_Mvp *vec4(project_pos.xy + offset, raisingHeight, 1.0);
} else {
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, raisingHeight, 1.0));
}

View File

@ -7,7 +7,7 @@ uniform float u_time;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_isMeter;
uniform int u_Size_Unit;
varying vec4 v_data;
varying vec4 v_color;
@ -31,37 +31,30 @@ void main() {
// unpack color(vec2)
v_color = a_Color;
// radius(16-bit)
v_radius = newSize;
// anti-alias
float blur = 0.0;
float antialiasblur = -max(2.0 / u_DevicePixelRatio / a_Size, blur);
if(u_Size_Unit == 1) {
newSize = newSize * u_PixelsPerMeter.z;
}
// radius(16-bit)
v_radius = newSize;
vec2 offset = (extrude.xy * (newSize));
vec3 aPosition = a_Position;
if(u_isMeter < 1.0) {
// 不以米为实际单位
offset = project_pixel(offset);
} else {
// 以米为实际单位
antialiasblur *= pow(19.0 - u_Zoom, 2.0);
antialiasblur = max(antialiasblur, -0.01);
// offset *= 0.5;
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
aPosition.xy += offset;
offset.x = 0.0;
offset.y = 0.0;
}
}
offset = project_pixel(offset);
v_data = vec4(extrude.x, extrude.y, antialiasblur, -1.0);
vec4 project_pos = project_position(vec4(aPosition.xy, 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);
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));
}

View File

@ -118,7 +118,7 @@ void main() {
vec4 projected_position;
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
projected_position = u_Mvp * (vec4(a_Position.xyz + vec3(0.0, 0.0, raiseHeight), 1.0));
projected_position = u_Mvp *(vec4(a_Position.xyz + vec3(0.0, 0.0, raiseHeight), 1.0));
} else { // else
projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz + vec3(0.0, 0.0, raiseHeight), 1.0));
}

View File

@ -1,76 +0,0 @@
uniform float u_additive;
uniform float u_opacity : 1;
uniform float u_stroke_opacity : 1;
uniform float u_stroke_width : 2;
uniform vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0];
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
#pragma include "sdf_2d"
#pragma include "picking"
void main() {
int shape = int(floor(v_data.w + 0.5));
lowp float antialiasblur = v_data.z;
float r = v_radius / (v_radius + u_stroke_width);
float outer_df;
float inner_df;
// 'circle', 'triangle', 'square', 'pentagon', 'hexagon', 'octogon', 'hexagram', 'rhombus', 'vesica'
if (shape == 0) {
outer_df = sdCircle(v_data.xy, 1.0);
inner_df = sdCircle(v_data.xy, r);
} else if (shape == 1) {
outer_df = sdEquilateralTriangle(1.1 * v_data.xy);
inner_df = sdEquilateralTriangle(1.1 / r * v_data.xy);
} else if (shape == 2) {
outer_df = sdBox(v_data.xy, vec2(1.));
inner_df = sdBox(v_data.xy, vec2(r));
} else if (shape == 3) {
outer_df = sdPentagon(v_data.xy, 0.8);
inner_df = sdPentagon(v_data.xy, r * 0.8);
} else if (shape == 4) {
outer_df = sdHexagon(v_data.xy, 0.8);
inner_df = sdHexagon(v_data.xy, r * 0.8);
} else if (shape == 5) {
outer_df = sdOctogon(v_data.xy, 1.0);
inner_df = sdOctogon(v_data.xy, r);
} else if (shape == 6) {
outer_df = sdHexagram(v_data.xy, 0.52);
inner_df = sdHexagram(v_data.xy, r * 0.52);
} else if (shape == 7) {
outer_df = sdRhombus(v_data.xy, vec2(1.0));
inner_df = sdRhombus(v_data.xy, vec2(r));
} else if (shape == 8) {
outer_df = sdVesica(v_data.xy, 1.1, 0.8);
inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8);
}
float opacity_t = smoothstep(0.0, antialiasblur, outer_df);
float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
antialiasblur,
0.0,
inner_df
);
if(u_stroke_width < 0.01) {
gl_FragColor = vec4(v_color.rgb, v_color.a * u_opacity);
} else {
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), u_stroke_color * u_stroke_opacity, color_t);
}
if(u_additive > 0.0) {
gl_FragColor *= opacity_t;
gl_FragColor = filterColorAlpha(gl_FragColor, gl_FragColor.a);
} else {
gl_FragColor.a *= opacity_t;
gl_FragColor = filterColor(gl_FragColor);
}
}

View File

@ -1,78 +0,0 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec3 a_Extrude;
attribute float a_Size;
attribute float a_Shape;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
// uniform vec2 u_tileOrigin;
// uniform float u_coord;
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
uniform float u_opacity : 1;
uniform float u_stroke_opacity : 1;
uniform float u_stroke_width : 2;
uniform vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0];
#pragma include "projection"
#pragma include "picking"
void main() {
vec3 extrude = a_Extrude;
float shape_type = a_Shape;
float newSize = setPickingSize(a_Size);
// cal style mapping
v_color = a_Color;
v_radius = newSize;
// anti-alias
// float antialiased_blur = -max(u_blur, antialiasblur);
float antialiasblur = -max(2.0 / u_DevicePixelRatio / a_Size, 0.0);
vec2 offset = (extrude.xy * (newSize + u_stroke_width));
offset = project_pixel(offset);
v_data = vec4(extrude.x, extrude.y, antialiasblur,shape_type);
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom);
}
// if(u_coord > 0.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, 0.0, 1.0));
}
// } else {
// vec2 pointPos = a_Position.xy;
// vec4 world = vec4(project_mvt_offset_position(vec4(u_tileOrigin, 0.0, 1.0)).xyz, 1.0); // 瓦片起始点的世界坐标
// vec2 pointOffset = pointPos * pow(2.0, u_Zoom); // 瓦片内的点的偏移坐标
// world.xy += offset;
// world.xy += pointOffset;
// if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// // Needs to be divided with project_uCommonUnitsPerMeter
// world.w *= u_PixelsPerMeter.z;
// }
// gl_Position = u_ViewProjectionMatrix * world + u_ViewportCenterProjection;
// }
setPickingColor(a_PickingColor);
}

View File

@ -1,33 +0,0 @@
#define SDF_PX 8.0
#define EDGE_GAMMA 0.105
#define FONT_SIZE 48.0
uniform sampler2D u_sdf_map;
uniform float u_gamma_scale : 0.5;
// uniform float u_font_size : 24.0;
uniform float u_opacity : 1.0;
uniform vec4 u_stroke_color : [0, 0, 0, 1];
uniform float u_stroke_width : 2.0;
uniform float u_halo_blur : 0.5;
uniform float u_DevicePixelRatio;
varying vec4 v_color;
varying vec2 v_uv;
varying float v_gamma_scale;
varying float v_fontScale;
#pragma include "picking"
void main() {
// get sdf from atlas
float dist = texture2D(u_sdf_map, v_uv).a;
lowp float buff = (6.0 - u_stroke_width / v_fontScale) / SDF_PX;
highp float gamma = (u_halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (v_fontScale * u_gamma_scale) / 1.0;
highp float gamma_scaled = gamma * v_gamma_scale;
highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), vec4(u_stroke_color.rgb, u_stroke_color.a * u_opacity), smoothstep(0., 0.5, 1. - dist));
gl_FragColor.a= gl_FragColor.a * alpha;
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -1,31 +0,0 @@
#define SDF_PX 8.0
#define EDGE_GAMMA 0.105
#define FONT_SIZE 48.0
uniform sampler2D u_sdf_map;
uniform float u_gamma_scale : 0.5;
uniform float u_opacity : 1.0;
uniform vec4 u_stroke_color : [0, 0, 0, 1];
uniform float u_stroke_width : 2.0;
uniform float u_halo_blur : 0.5;
uniform float u_DevicePixelRatio;
varying vec2 v_uv;
varying float v_gamma_scale;
varying float v_fontScale;
uniform vec4 u_color;
void main() {
// get sdf from atlas
float dist = texture2D(u_sdf_map, v_uv).a;
lowp float buff = (6.0 - u_stroke_width / v_fontScale) / SDF_PX;
highp float gamma = (u_halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (v_fontScale * u_gamma_scale) / 1.0;
highp float gamma_scaled = gamma * v_gamma_scale;
highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
gl_FragColor = mix(vec4(u_color.rgb, u_color.a * u_opacity), vec4(u_stroke_color.rgb, u_stroke_color.a * u_opacity), smoothstep(0., 0.5, 1. - dist));
gl_FragColor.a= gl_FragColor.a * alpha;
}

View File

@ -1,38 +0,0 @@
#define FONT_SIZE 24.0
attribute vec3 a_Position;
attribute vec2 a_tex;
attribute vec2 a_textOffsets;
uniform vec2 u_sdf_map_size;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_size;
varying vec2 v_uv;
varying float v_gamma_scale;
varying float v_fontScale;
#pragma include "projection"
void main() {
v_uv = a_tex / u_sdf_map_size;
// 文本缩放比例
float fontScale = u_size / FONT_SIZE;
v_fontScale = fontScale;
vec4 project_pos = project_position(vec4(a_Position, 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 + a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0);
v_gamma_scale = gl_Position.w;
}

View File

@ -1,48 +0,0 @@
#define SDF_PX 8.0
#define EDGE_GAMMA 0.105
#define FONT_SIZE 24.0
attribute vec3 a_Position;
attribute vec2 a_tex;
attribute vec2 a_textOffsets;
attribute vec4 a_Color;
attribute float a_Size;
uniform vec2 u_sdf_map_size;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
varying vec2 v_uv;
varying float v_gamma_scale;
varying vec4 v_color;
varying float v_fontScale;
uniform float u_opacity : 1;
uniform float u_stroke_width : 2;
uniform vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0];
#pragma include "projection"
#pragma include "picking"
void main() {
v_color = a_Color;
v_uv = a_tex / u_sdf_map_size;
// 文本缩放比例
float fontScale = a_Size / FONT_SIZE;
v_fontScale = fontScale;
vec4 project_pos = project_position(vec4(a_Position, 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 + a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0);
v_gamma_scale = gl_Position.w;
setPickingColor(a_PickingColor);
}

View File

@ -33,8 +33,6 @@ export default class PolygonLayer extends BaseLayer<IPolygonLayerStyleOptions> {
return 'ocean';
} else if (shape === 'line') {
return 'line';
} else if (shape === 'tile') {
return 'tile';
} else {
return this.getPointModelType();
}

View File

@ -7,7 +7,6 @@ import TextModel from '../../point/models/text';
import ExtrudeModel from './extrude';
import FillModel from './fill';
import Ocean from './ocean';
import TilePolygonModel from './tile';
import Water from './water';
export type PolygonModelType =
@ -21,7 +20,6 @@ export type PolygonModelType =
| 'text'
| 'water'
| 'ocean'
| 'tile';
const PolygonModels: { [key in PolygonModelType]: any } = {
fill: FillModel,
line: LineModel,
@ -34,7 +32,5 @@ const PolygonModels: { [key in PolygonModelType]: any } = {
water: Water,
ocean: Ocean,
// point_fill: PointModels.fill,
tile: TilePolygonModel,
};
export default PolygonModels;

View File

@ -1,60 +0,0 @@
import { IModel } from '@antv/l7-core';
import { getMask, rgb2arr } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IPolygonLayerStyleOptions } from '../../core/interface';
import { polygonTriangulation } from '../../core/triangulation';
import polygon_tile_frag from '../../shader/minify_picking_frag.glsl';
import polygon_tile_vert from '../shaders/tile/polygon_tile_vert.glsl';
import polygon_tile_map_frag from '../../shader/minify_frag.glsl';
import polygon_tile_map_vert from '../shaders/tile/polygon_tile_map_vert.glsl';
export default class FillModel extends BaseModel {
public getUninforms() {
const {
opacity = 1,
// tileOrigin,
// coord = 'lnglat',
usage,
color = '#fff'
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
return {
// u_tileOrigin: tileOrigin || [0, 0],
// u_coord: coord === 'lnglat' ? 1.0 : 0.0,
u_opacity: opacity,
u_color: usage === 'basemap' ? rgb2arr(color): [0, 0, 0, 0]
};
}
public async initModels(): Promise<IModel[]> {
return await this.buildModels();
}
public async buildModels():Promise<IModel[]> {
const {
mask = false,
maskInside = true,
usage
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
this.layer.triangulation = polygonTriangulation;
const model = await this.layer
.buildLayerModel({
moduleName: 'polygonTile_' + usage,
vertexShader: usage === 'basemap' ? polygon_tile_map_vert : polygon_tile_vert,
fragmentShader: usage === 'basemap' ? polygon_tile_map_frag : polygon_tile_frag,
triangulation: polygonTriangulation,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
pick: usage !== 'basemap'
})
return [model]
}
public clearModels() {
}
protected registerBuiltinAttributes() {
//
}
}

View File

@ -1,16 +0,0 @@
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
#pragma include "projection"
void main() {
vec4 project_pos = project_position(vec4(a_Position, 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));
}
}

View File

@ -1,42 +0,0 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
// uniform vec2 u_tileOrigin;
// uniform float u_coord;
varying vec4 v_color;
#pragma include "projection"
#pragma include "picking"
void main() {
v_color = a_Color;
vec4 project_pos = project_position(vec4(a_Position, 1.0));
// if(u_coord > 0.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));
}
// } else {
// vec4 world = vec4(project_mvt_offset_position(vec4(u_tileOrigin, 0.0, 1.0)).xyz, 1.0); // 瓦片起始点的世界坐标
// vec2 pointOffset = a_Position.xy * pow(2.0, u_Zoom); // 瓦片内的点的偏移坐标
// world.xy += pointOffset;
// if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// // Needs to be divided with project_uCommonUnitsPerMeter
// world.w *= u_PixelsPerMeter.z;
// }
// gl_Position = u_ViewProjectionMatrix * world + u_ViewportCenterProjection;
// }
setPickingColor(a_PickingColor);
}

View File

@ -121,7 +121,7 @@ export default class Viewport implements IViewport {
}
public getFocalDistance() {
return 1;
return 1.2;
}
/**

View File

@ -36,15 +36,15 @@ layer.style({
| offsets | `[number, number]` | 点偏移 | `[0, 0]` |
| raisingHeight | `number` | 抬升高度 | `0` |
| heightfixed | `boolean` | 抬升高度是否随 `zoom` 变化 | `false` |
| unit | `string` | 点大小单位 | `l7size` |
| unit | `string` | 点大小单位 | `pixel` |
#### unit
- l7size 默认值
- pixel 默认值
- meter 单位为米
```js
type IUnit = 'l7size' | 'meter';
type IUnit = 'pixel' | 'meter';
```
点图层支持等面积点,点大小的单位是米,同样通过 size 方法设置大小