mirror of https://gitee.com/antv-l7/antv-l7
fix: circle meter size && remove unuse code file (#1550)
This commit is contained in:
parent
ef317bfb26
commit
c188238b70
|
@ -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({});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### point - circle 等面积
|
||||
<code src="./demos/circlemeter.tsx"></code>
|
|
@ -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',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -32,9 +32,12 @@ export default () => {
|
|||
},
|
||||
},
|
||||
)
|
||||
.size(25)
|
||||
.size(100)
|
||||
.color('#f00')
|
||||
.shape('radar')
|
||||
.style({
|
||||
unit:'pixel'
|
||||
})
|
||||
.animate(true)
|
||||
.active(true);
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ export default () => {
|
|||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.style({
|
||||
unit:'meter'
|
||||
})
|
||||
.shape('marker')
|
||||
.size(36)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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]];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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)];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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];
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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]
|
||||
}
|
||||
}
|
|
@ -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,8 +124,10 @@ 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;
|
||||
|
||||
// anti-alias
|
||||
|
@ -136,25 +136,8 @@ 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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
//
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ export default class Viewport implements IViewport {
|
|||
}
|
||||
|
||||
public getFocalDistance() {
|
||||
return 1;
|
||||
return 1.2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 方法设置大小
|
||||
|
|
Loading…
Reference in New Issue