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
|
// @ts-ignore
|
||||||
} from '@antv/l7';
|
} from '@antv/l7';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { GaodeMap } from '@antv/l7-maps';
|
import { Map,GaodeMap } from '@antv/l7-maps';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
@ -70,7 +70,7 @@ export default () => {
|
||||||
const source = new Source(geoData);
|
const source = new Source(geoData);
|
||||||
const layer = new LineLayer({ blend: 'normal' })
|
const layer = new LineLayer({ blend: 'normal' })
|
||||||
.source(source)
|
.source(source)
|
||||||
.size(1)
|
.size(10)
|
||||||
.shape('line')
|
.shape('line')
|
||||||
.color('#f00')
|
.color('#f00')
|
||||||
.style({});
|
.style({});
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} from '@antv/l7';
|
} from '@antv/l7';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { GaodeMap } from '@antv/l7-maps';
|
import { GaodeMap,Map } from '@antv/l7-maps';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
@ -54,8 +54,8 @@ export default () => {
|
||||||
type: 'MultiLineString',
|
type: 'MultiLineString',
|
||||||
coordinates: [
|
coordinates: [
|
||||||
[
|
[
|
||||||
[120, 30],
|
[116.43,39.97],
|
||||||
[120, 40],
|
[108.39,22.91],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -64,11 +64,12 @@ export default () => {
|
||||||
};
|
};
|
||||||
const source = new Source(geoData);
|
const source = new Source(geoData);
|
||||||
|
|
||||||
|
|
||||||
// scene.on('zoom', e => console.log(e))
|
// scene.on('zoom', e => console.log(e))
|
||||||
|
|
||||||
const layer = new LineLayer({ blend: 'normal' })
|
const layer = new LineLayer({ blend: 'normal' })
|
||||||
.source(source)
|
.source(source)
|
||||||
.size(1)
|
.size(2)
|
||||||
.shape('arc')
|
.shape('arc')
|
||||||
.color('#f00')
|
.color('#f00')
|
||||||
.style({
|
.style({
|
||||||
|
@ -77,15 +78,15 @@ export default () => {
|
||||||
thetaOffset: 0.5,
|
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 })
|
const point = new PointLayer({ blend: 'normal', zIndex: 1 })
|
||||||
.source(midPoints, {
|
.source([{
|
||||||
|
lng:116.43,
|
||||||
|
lat:39.97
|
||||||
|
},{
|
||||||
|
lng:108.39,
|
||||||
|
lat:22.91
|
||||||
|
}], {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
x: 'lng',
|
x: 'lng',
|
||||||
|
@ -94,21 +95,15 @@ export default () => {
|
||||||
})
|
})
|
||||||
.shape('circle')
|
.shape('circle')
|
||||||
.size(10)
|
.size(10)
|
||||||
.color('#ff0');
|
.color('blue');
|
||||||
scene.addLayer(point);
|
const point2 = new PointLayer({ blend: 'normal', zIndex: 1 })
|
||||||
});
|
.source([{
|
||||||
|
lng:116.43,
|
||||||
(async () => {
|
lat:39.97
|
||||||
// const midPoints = await lineAtOffsetAsyc(source, 0.1, 'arc', 'offset');
|
},{
|
||||||
const midPoints = await lineAtOffsetAsyc(source, {
|
lng:108.39,
|
||||||
offset: 0.3,
|
lat:22.91
|
||||||
shape: 'arc',
|
}], {
|
||||||
thetaOffset: 0.5,
|
|
||||||
mapVersion: scene.getMapService().version,
|
|
||||||
featureId: 1,
|
|
||||||
});
|
|
||||||
const point = new PointLayer({ blend: 'normal', zIndex: 1 })
|
|
||||||
.source(midPoints, {
|
|
||||||
parser: {
|
parser: {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
x: 'lng',
|
x: 'lng',
|
||||||
|
@ -116,13 +111,15 @@ export default () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.shape('circle')
|
.shape('circle')
|
||||||
.size(5)
|
.size(100000)
|
||||||
.color('#0f0')
|
.color('blue')
|
||||||
.style({
|
.style({
|
||||||
opacity: 0.8,
|
opacity:0.5,
|
||||||
});
|
unit:'meter'
|
||||||
|
})
|
||||||
scene.addLayer(point);
|
scene.addLayer(point);
|
||||||
})();
|
scene.addLayer(point2);
|
||||||
|
|
||||||
|
|
||||||
scene.on('loaded', () => {
|
scene.on('loaded', () => {
|
||||||
scene.addLayer(layer);
|
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')
|
.color('#f00')
|
||||||
.shape('radar')
|
.shape('radar')
|
||||||
|
.style({
|
||||||
|
unit:'pixel'
|
||||||
|
})
|
||||||
.animate(true)
|
.animate(true)
|
||||||
.active(true);
|
.active(true);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@ export default () => {
|
||||||
y: 'lat',
|
y: 'lat',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
.style({
|
||||||
|
unit:'meter'
|
||||||
|
})
|
||||||
.shape('marker')
|
.shape('marker')
|
||||||
.size(36)
|
.size(36)
|
||||||
|
|
||||||
|
|
|
@ -147,38 +147,38 @@ float project_pixel_allmap(float pixel) {
|
||||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
|
||||||
return pixel * pow(2.0, u_Zoom);
|
return pixel * pow(2.0, u_Zoom);
|
||||||
}
|
}
|
||||||
return pixel;
|
return pixel * u_FocalDistance ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 适配纹理贴图的等像素大小
|
// 适配纹理贴图的等像素大小
|
||||||
float project_pixel_texture(float pixel) {
|
float project_pixel_texture(float pixel) {
|
||||||
// mapbox zoom > 12
|
// mapbox zoom > 12
|
||||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
|
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
|
// amap2 zoom > 12
|
||||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
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
|
// amap zoom > 12
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
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
|
// amap zoom < 12
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
|
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) {
|
float project_float_pixel(float pixel) {
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
|
||||||
// mapbox P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// 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) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||||
// amap P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// amap P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||||
|
@ -186,43 +186,43 @@ float project_float_pixel(float pixel) {
|
||||||
}
|
}
|
||||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
// amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
// 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) {
|
float project_pixel(float pixel) {
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||||
// amap P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// 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) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
// amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
// 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) {
|
vec2 project_pixel(vec2 pixel) {
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// 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) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
// 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) {
|
vec3 project_pixel(vec3 pixel) {
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// 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) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
// 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) {
|
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
|
||||||
|
|
|
@ -83,7 +83,10 @@ export interface ILineLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
enablePicking?: boolean;
|
enablePicking?: boolean;
|
||||||
workerEnabled?: boolean;
|
workerEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
export enum SizeUnitType {
|
||||||
|
pixel = 0,
|
||||||
|
meter = 1,
|
||||||
|
}
|
||||||
export interface IPointLayerStyleOptions extends IBaseLayerStyleOptions {
|
export interface IPointLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
tileOrigin?: number[];
|
tileOrigin?: number[];
|
||||||
coord?: string;
|
coord?: string;
|
||||||
|
@ -118,7 +121,7 @@ export interface IPointLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
|
|
||||||
offsets?: styleOffset;
|
offsets?: styleOffset;
|
||||||
|
|
||||||
unit?: string;
|
unit?: SizeUnitType;
|
||||||
|
|
||||||
rotation?: number; // angle
|
rotation?: number; // angle
|
||||||
speed?: number;
|
speed?: number;
|
||||||
|
@ -191,11 +194,6 @@ export interface IImageLayerStyleOptions extends IBaseLayerStyleOptions {
|
||||||
rampColors?: IColorRamp;
|
rampColors?: IColorRamp;
|
||||||
rampColorsData?: ImageData | IImagedata;
|
rampColorsData?: ImageData | IImagedata;
|
||||||
colorTexture?: ITexture2D;
|
colorTexture?: ITexture2D;
|
||||||
pixelConstant?: number;
|
|
||||||
pixelConstantR?: number;
|
|
||||||
pixelConstantG?: number;
|
|
||||||
pixelConstantB?: number;
|
|
||||||
pixelConstantRGB?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICityBuildLayerStyleOptions {
|
export interface ICityBuildLayerStyleOptions {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import LineHalfModel from './half';
|
||||||
import LineModel from './line';
|
import LineModel from './line';
|
||||||
import LinearLine from './linearline';
|
import LinearLine from './linearline';
|
||||||
import SimpleLineModel from './simpleLine';
|
import SimpleLineModel from './simpleLine';
|
||||||
import TileLineModel from './tile';
|
|
||||||
import LineWallModel from './wall';
|
import LineWallModel from './wall';
|
||||||
|
|
||||||
export type LineModelType =
|
export type LineModelType =
|
||||||
|
@ -18,7 +17,6 @@ export type LineModelType =
|
||||||
| 'line'
|
| 'line'
|
||||||
| 'halfLine'
|
| 'halfLine'
|
||||||
| 'linearline'
|
| 'linearline'
|
||||||
| 'tileLine'
|
|
||||||
| 'earthArc3d';
|
| 'earthArc3d';
|
||||||
|
|
||||||
const LineModels: { [key in LineModelType]: any } = {
|
const LineModels: { [key in LineModelType]: any } = {
|
||||||
|
@ -30,7 +28,6 @@ const LineModels: { [key in LineModelType]: any } = {
|
||||||
halfLine: LineHalfModel,
|
halfLine: LineHalfModel,
|
||||||
simple: SimpleLineModel,
|
simple: SimpleLineModel,
|
||||||
linearline: LinearLine,
|
linearline: LinearLine,
|
||||||
tileLine: TileLineModel,
|
|
||||||
earthArc3d: EarthArc3DModel,
|
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,
|
IModel,
|
||||||
IModelUniform,
|
IModelUniform,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { $window, getMask, PointFillTriangulation } from '@antv/l7-utils';
|
import { getMask, PointFillTriangulation } from '@antv/l7-utils';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import BaseModel from '../../core/BaseModel';
|
import BaseModel from '../../core/BaseModel';
|
||||||
import { IPointLayerStyleOptions } from '../../core/interface';
|
import { IPointLayerStyleOptions } from '../../core/interface';
|
||||||
|
@ -18,15 +18,11 @@ import waveFillFrag from '../shaders/animate/wave_frag.glsl';
|
||||||
// static pointLayer shader - not support animate
|
// static pointLayer shader - not support animate
|
||||||
import pointFillFrag from '../shaders/fill_frag.glsl';
|
import pointFillFrag from '../shaders/fill_frag.glsl';
|
||||||
import pointFillVert from '../shaders/fill_vert.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 {
|
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 {
|
public getUninforms(): IModelUniform {
|
||||||
const {
|
const {
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
|
@ -38,9 +34,8 @@ export default class FillModel extends BaseModel {
|
||||||
blur = 0,
|
blur = 0,
|
||||||
raisingHeight = 0,
|
raisingHeight = 0,
|
||||||
heightfixed = false,
|
heightfixed = false,
|
||||||
unit = 'l7size',
|
unit = 'pixel',
|
||||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||||
this.updateUnit(unit);
|
|
||||||
if (
|
if (
|
||||||
this.dataTextureTest &&
|
this.dataTextureTest &&
|
||||||
this.dataTextureNeedUpdate({
|
this.dataTextureNeedUpdate({
|
||||||
|
@ -89,12 +84,7 @@ export default class FillModel extends BaseModel {
|
||||||
return {
|
return {
|
||||||
u_raisingHeight: Number(raisingHeight),
|
u_raisingHeight: Number(raisingHeight),
|
||||||
u_heightfixed: Number(heightfixed),
|
u_heightfixed: Number(heightfixed),
|
||||||
|
|
||||||
u_meter2coord: this.meter2coord,
|
|
||||||
u_meteryScale: this.meterYScale,
|
|
||||||
u_isMeter: Number(this.isMeter),
|
|
||||||
u_blur: blur,
|
u_blur: blur,
|
||||||
|
|
||||||
u_additive: blend === 'additive' ? 1.0 : 0.0,
|
u_additive: blend === 'additive' ? 1.0 : 0.0,
|
||||||
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
|
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
|
||||||
u_cellTypeLayout: this.getCellTypeLayout(),
|
u_cellTypeLayout: this.getCellTypeLayout(),
|
||||||
|
@ -103,6 +93,7 @@ export default class FillModel extends BaseModel {
|
||||||
u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0,
|
u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0,
|
||||||
u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 1.0,
|
u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 1.0,
|
||||||
u_stroke_color: this.getStrokeColor(stroke),
|
u_stroke_color: this.getStrokeColor(stroke),
|
||||||
|
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
|
||||||
u_offsets: this.isOffsetStatic(offsets)
|
u_offsets: this.isOffsetStatic(offsets)
|
||||||
? (offsets as [number, number])
|
? (offsets as [number, number])
|
||||||
: [0, 0],
|
: [0, 0],
|
||||||
|
@ -131,60 +122,9 @@ export default class FillModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async initModels(): Promise<IModel[]> {
|
public async initModels(): Promise<IModel[]> {
|
||||||
this.updateUnit('l7size');
|
|
||||||
return await this.buildModels();
|
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[]> {
|
public async buildModels():Promise<IModel[]> {
|
||||||
const {
|
const {
|
||||||
mask = false,
|
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,
|
IModelUniform,
|
||||||
ITexture2D,
|
ITexture2D,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { Version } from '@antv/l7-maps';
|
|
||||||
import { getCullFace, getMask } from '@antv/l7-utils';
|
import { getCullFace, getMask } from '@antv/l7-utils';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import BaseModel from '../../core/BaseModel';
|
import BaseModel from '../../core/BaseModel';
|
||||||
|
@ -17,6 +16,7 @@ import { PointFillTriangulation } from '../../core/triangulation';
|
||||||
// static pointLayer shader - not support animate
|
// static pointLayer shader - not support animate
|
||||||
import pointFillFrag from '../shaders/image/fillImage_frag.glsl';
|
import pointFillFrag from '../shaders/image/fillImage_frag.glsl';
|
||||||
import pointFillVert from '../shaders/image/fillImage_vert.glsl';
|
import pointFillVert from '../shaders/image/fillImage_vert.glsl';
|
||||||
|
import { SizeUnitType } from '../../core/interface'
|
||||||
|
|
||||||
export default class FillImageModel extends BaseModel {
|
export default class FillImageModel extends BaseModel {
|
||||||
private meter2coord: number = 1;
|
private meter2coord: number = 1;
|
||||||
|
@ -30,6 +30,7 @@ export default class FillImageModel extends BaseModel {
|
||||||
rotation,
|
rotation,
|
||||||
raisingHeight = 0.0,
|
raisingHeight = 0.0,
|
||||||
heightfixed = false,
|
heightfixed = false,
|
||||||
|
unit = 'pixel',
|
||||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||||
|
|
||||||
if (this.rendererService.getDirty()) {
|
if (this.rendererService.getDirty()) {
|
||||||
|
@ -98,7 +99,7 @@ export default class FillImageModel extends BaseModel {
|
||||||
return {
|
return {
|
||||||
u_raisingHeight: Number(raisingHeight),
|
u_raisingHeight: Number(raisingHeight),
|
||||||
u_heightfixed: Number(heightfixed),
|
u_heightfixed: Number(heightfixed),
|
||||||
u_isMeter: Number(this.isMeter),
|
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
|
||||||
u_RotateMatrix: new Float32Array([
|
u_RotateMatrix: new Float32Array([
|
||||||
Math.cos(this.radian),
|
Math.cos(this.radian),
|
||||||
Math.sin(this.radian),
|
Math.sin(this.radian),
|
||||||
|
@ -134,63 +135,10 @@ export default class FillImageModel extends BaseModel {
|
||||||
public async initModels():Promise<IModel[]> {
|
public async initModels():Promise<IModel[]> {
|
||||||
this.iconService.on('imageUpdate', this.updateTexture);
|
this.iconService.on('imageUpdate', this.updateTexture);
|
||||||
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();
|
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[]> {
|
public async buildModels():Promise<IModel[]> {
|
||||||
const {
|
const {
|
||||||
|
@ -313,8 +261,8 @@ export default class FillImageModel extends BaseModel {
|
||||||
) => {
|
) => {
|
||||||
const { size = 5 } = feature;
|
const { size = 5 } = feature;
|
||||||
return Array.isArray(size)
|
return Array.isArray(size)
|
||||||
? [size[0] * this.meter2coord]
|
? [size[0]]
|
||||||
: [(size as number) * this.meter2coord];
|
: [(size as number)];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,8 +9,6 @@ import NormalModel from './normal';
|
||||||
import Radar from './radar';
|
import Radar from './radar';
|
||||||
import SimplePoint from './simplePoint';
|
import SimplePoint from './simplePoint';
|
||||||
import TextModel from './text';
|
import TextModel from './text';
|
||||||
import TileTextModel from './tileText';
|
|
||||||
import TileFillModel from './tile';
|
|
||||||
|
|
||||||
export type PointType =
|
export type PointType =
|
||||||
| 'fillImage'
|
| 'fillImage'
|
||||||
|
@ -21,8 +19,6 @@ export type PointType =
|
||||||
| 'simplePoint'
|
| 'simplePoint'
|
||||||
| 'extrude'
|
| 'extrude'
|
||||||
| 'text'
|
| 'text'
|
||||||
| 'tile'
|
|
||||||
| 'tileText'
|
|
||||||
| 'earthFill'
|
| 'earthFill'
|
||||||
| 'earthExtrude';
|
| 'earthExtrude';
|
||||||
|
|
||||||
|
@ -35,8 +31,6 @@ const PointModels: { [key in PointType]: any } = {
|
||||||
simplePoint: SimplePoint,
|
simplePoint: SimplePoint,
|
||||||
extrude: ExtrudeModel,
|
extrude: ExtrudeModel,
|
||||||
text: TextModel,
|
text: TextModel,
|
||||||
tile: TileFillModel,
|
|
||||||
tileText: TileTextModel,
|
|
||||||
earthFill: EarthFillModel,
|
earthFill: EarthFillModel,
|
||||||
earthExtrude: EarthExtrudeModel,
|
earthExtrude: EarthExtrudeModel,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,21 +17,19 @@ import { PointFillTriangulation } from '../../core/triangulation';
|
||||||
|
|
||||||
import pointFillFrag from '../shaders/radar/radar_frag.glsl';
|
import pointFillFrag from '../shaders/radar/radar_frag.glsl';
|
||||||
import pointFillVert from '../shaders/radar/radar_vert.glsl';
|
import pointFillVert from '../shaders/radar/radar_vert.glsl';
|
||||||
|
import { SizeUnitType } from '../../core/interface'
|
||||||
import { Version } from '@antv/l7-maps';
|
|
||||||
|
|
||||||
export default class RadarModel extends BaseModel {
|
export default class RadarModel extends BaseModel {
|
||||||
public meter2coord: number = 1;
|
|
||||||
private isMeter: boolean = false;
|
|
||||||
public getUninforms(): IModelUniform {
|
public getUninforms(): IModelUniform {
|
||||||
const {
|
const {
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
blend,
|
blend,
|
||||||
speed = 1,
|
speed = 1,
|
||||||
|
unit = 'pixel'
|
||||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
u_isMeter: Number(this.isMeter),
|
u_Size_Unit: SizeUnitType[unit] as SizeUnitType,
|
||||||
u_speed: speed,
|
u_speed: speed,
|
||||||
u_additive: blend === 'additive' ? 1.0 : 0.0,
|
u_additive: blend === 'additive' ? 1.0 : 0.0,
|
||||||
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
||||||
|
@ -60,63 +58,10 @@ export default class RadarModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async initModels():Promise<IModel[]> {
|
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();
|
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[]> {
|
public async buildModels():Promise<IModel[]> {
|
||||||
const {
|
const {
|
||||||
|
@ -194,8 +139,8 @@ export default class RadarModel extends BaseModel {
|
||||||
) => {
|
) => {
|
||||||
const { size = 5 } = feature;
|
const { size = 5 } = feature;
|
||||||
return Array.isArray(size)
|
return Array.isArray(size)
|
||||||
? [size[0] * this.meter2coord]
|
? [size[0]]
|
||||||
: [(size as number) * this.meter2coord];
|
: [(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_ModelMatrix;
|
||||||
uniform mat4 u_Mvp;
|
uniform mat4 u_Mvp;
|
||||||
uniform float u_meter2coord;
|
uniform int u_Size_Unit;
|
||||||
uniform float u_meteryScale;
|
|
||||||
uniform float u_isMeter;
|
|
||||||
|
|
||||||
varying vec4 v_data;
|
varying vec4 v_data;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -42,7 +40,7 @@ void main() {
|
||||||
* setPickingSize 设置拾取大小
|
* setPickingSize 设置拾取大小
|
||||||
* u_meter2coord 在等面积大小的时候设置单位
|
* u_meter2coord 在等面积大小的时候设置单位
|
||||||
*/
|
*/
|
||||||
float newSize = setPickingSize(a_Size) * u_meter2coord;
|
float newSize = setPickingSize(a_Size);
|
||||||
// float newSize = setPickingSize(a_Size) * 0.00001038445708445579;
|
// float newSize = setPickingSize(a_Size) * 0.00001038445708445579;
|
||||||
|
|
||||||
// cal style mapping - 数据纹理映射部分的计算
|
// cal style mapping - 数据纹理映射部分的计算
|
||||||
|
@ -126,8 +124,10 @@ void main() {
|
||||||
|
|
||||||
// unpack color(vec2)
|
// unpack color(vec2)
|
||||||
v_color = a_Color;
|
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
|
// anti-alias
|
||||||
|
@ -136,25 +136,8 @@ void main() {
|
||||||
|
|
||||||
vec2 offset = (extrude.xy * (newSize + u_stroke_width) + textrueOffsets);
|
vec2 offset = (extrude.xy * (newSize + u_stroke_width) + textrueOffsets);
|
||||||
vec3 aPosition = a_Position;
|
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) {
|
offset = project_pixel(offset);
|
||||||
aPosition.x += offset.x / u_meteryScale;
|
|
||||||
aPosition.y += offset.y;
|
|
||||||
offset = vec2(0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODP: /abs(extrude.x) 是为了兼容地球模式
|
// TODP: /abs(extrude.x) 是为了兼容地球模式
|
||||||
v_data = vec4(extrude.x/abs(extrude.x), extrude.y/abs(extrude.y), antialiasblur,shape_type);
|
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_ModelMatrix;
|
||||||
uniform mat4 u_Mvp;
|
uniform mat4 u_Mvp;
|
||||||
uniform mat2 u_RotateMatrix;
|
uniform mat2 u_RotateMatrix;
|
||||||
uniform float u_isMeter;
|
uniform int u_Size_Unit;
|
||||||
|
|
||||||
varying vec2 v_uv; // 本身的 uv 坐标
|
varying vec2 v_uv; // 本身的 uv 坐标
|
||||||
varying vec2 v_Iconuv; // icon 贴图的 uv 坐标
|
varying vec2 v_Iconuv; // icon 贴图的 uv 坐标
|
||||||
|
@ -76,22 +76,16 @@ void main() {
|
||||||
highp float angle_sin = sin(a_Rotate);
|
highp float angle_sin = sin(a_Rotate);
|
||||||
highp float angle_cos = cos(a_Rotate);
|
highp float angle_cos = cos(a_Rotate);
|
||||||
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
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 = (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;
|
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) {
|
offset = project_pixel(offset);
|
||||||
aPosition.xy += offset;
|
|
||||||
offset.x = 0.0;
|
|
||||||
offset.y = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0));
|
vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0));
|
||||||
float raisingHeight = u_raisingHeight;
|
float raisingHeight = u_raisingHeight;
|
||||||
|
|
|
@ -7,7 +7,7 @@ uniform float u_time;
|
||||||
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
uniform mat4 u_Mvp;
|
uniform mat4 u_Mvp;
|
||||||
uniform float u_isMeter;
|
uniform int u_Size_Unit;
|
||||||
|
|
||||||
varying vec4 v_data;
|
varying vec4 v_data;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -31,30 +31,23 @@ void main() {
|
||||||
// unpack color(vec2)
|
// unpack color(vec2)
|
||||||
v_color = a_Color;
|
v_color = a_Color;
|
||||||
|
|
||||||
// radius(16-bit)
|
|
||||||
v_radius = newSize;
|
|
||||||
|
|
||||||
// anti-alias
|
// anti-alias
|
||||||
float blur = 0.0;
|
float blur = 0.0;
|
||||||
float antialiasblur = -max(2.0 / u_DevicePixelRatio / a_Size, blur);
|
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));
|
vec2 offset = (extrude.xy * (newSize));
|
||||||
vec3 aPosition = a_Position;
|
vec3 aPosition = a_Position;
|
||||||
if(u_isMeter < 1.0) {
|
|
||||||
// 不以米为实际单位
|
// 不以米为实际单位
|
||||||
offset = project_pixel(offset);
|
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);
|
v_data = vec4(extrude.x, extrude.y, antialiasblur, -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';
|
return 'ocean';
|
||||||
} else if (shape === 'line') {
|
} else if (shape === 'line') {
|
||||||
return 'line';
|
return 'line';
|
||||||
} else if (shape === 'tile') {
|
|
||||||
return 'tile';
|
|
||||||
} else {
|
} else {
|
||||||
return this.getPointModelType();
|
return this.getPointModelType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import TextModel from '../../point/models/text';
|
||||||
import ExtrudeModel from './extrude';
|
import ExtrudeModel from './extrude';
|
||||||
import FillModel from './fill';
|
import FillModel from './fill';
|
||||||
import Ocean from './ocean';
|
import Ocean from './ocean';
|
||||||
import TilePolygonModel from './tile';
|
|
||||||
import Water from './water';
|
import Water from './water';
|
||||||
|
|
||||||
export type PolygonModelType =
|
export type PolygonModelType =
|
||||||
|
@ -21,7 +20,6 @@ export type PolygonModelType =
|
||||||
| 'text'
|
| 'text'
|
||||||
| 'water'
|
| 'water'
|
||||||
| 'ocean'
|
| 'ocean'
|
||||||
| 'tile';
|
|
||||||
const PolygonModels: { [key in PolygonModelType]: any } = {
|
const PolygonModels: { [key in PolygonModelType]: any } = {
|
||||||
fill: FillModel,
|
fill: FillModel,
|
||||||
line: LineModel,
|
line: LineModel,
|
||||||
|
@ -34,7 +32,5 @@ const PolygonModels: { [key in PolygonModelType]: any } = {
|
||||||
water: Water,
|
water: Water,
|
||||||
ocean: Ocean,
|
ocean: Ocean,
|
||||||
// point_fill: PointModels.fill,
|
// point_fill: PointModels.fill,
|
||||||
|
|
||||||
tile: TilePolygonModel,
|
|
||||||
};
|
};
|
||||||
export default PolygonModels;
|
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() {
|
public getFocalDistance() {
|
||||||
return 1;
|
return 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,15 +36,15 @@ layer.style({
|
||||||
| offsets | `[number, number]` | 点偏移 | `[0, 0]` |
|
| offsets | `[number, number]` | 点偏移 | `[0, 0]` |
|
||||||
| raisingHeight | `number` | 抬升高度 | `0` |
|
| raisingHeight | `number` | 抬升高度 | `0` |
|
||||||
| heightfixed | `boolean` | 抬升高度是否随 `zoom` 变化 | `false` |
|
| heightfixed | `boolean` | 抬升高度是否随 `zoom` 变化 | `false` |
|
||||||
| unit | `string` | 点大小单位 | `l7size` |
|
| unit | `string` | 点大小单位 | `pixel` |
|
||||||
|
|
||||||
#### unit
|
#### unit
|
||||||
|
|
||||||
- l7size 默认值
|
- pixel 默认值
|
||||||
- meter 单位为米
|
- meter 单位为米
|
||||||
|
|
||||||
```js
|
```js
|
||||||
type IUnit = 'l7size' | 'meter';
|
type IUnit = 'pixel' | 'meter';
|
||||||
```
|
```
|
||||||
|
|
||||||
点图层支持等面积点,点大小的单位是米,同样通过 size 方法设置大小
|
点图层支持等面积点,点大小的单位是米,同样通过 size 方法设置大小
|
||||||
|
|
Loading…
Reference in New Issue