* feat: 增加着色器的拾取计算控制、完善 arcmini

* feat: 完善 enableShaderPick/disableShaderPick 功能

* style: lint style

* feat: 补充调用高德地图公交线路查询 demo

* style: lint style

* feat: 优化弧线的纹理动画

* style: lint style

* feat: 去除greatCircle 的纹理动画优化

* feat: 扩展点图层圆柱效果

* feat: 增加几何体的径向渐变配置

* style: lint style

* fix: 修复bug 图层触发的事件跟图层设置的zIndex无关,只跟插入图层先后顺序有关

* style: lint style

* feat: 补全挤出几何体拾取颜色的光照配置

* style: lint style

* fix: 修复圆柱 cull 问题 mapbox amap 不同

* feat: 图层销毁时的内存泄漏

* style: lint style

* feat: 平面弧线新增弧线偏移量的数据映射能力

* style: lint style

* fix: 修复重复销毁bug

* style: lint style

* feat: 修复 texture 重复销毁问题

* style: lint style

* fix: 修复图层叠加模式下的拾取失效问题

* style: lint style

* fix: 修复纹理贴图在 zoom 大于 12 时存在的问题

* fix: 修复水波点颜色偏暗

* feat: 优化点图层的渲染效果,叠加渲染效果

* style: lint style

* fix: 修复 layer contextmenu 事件丢失

* fix: 修复 map 类型 resize 失效

* style: lint style

* feat: 增加瓦片地图的请求节流

* style: lint style

* feat: 优化热力图在 radius 数值比较大时热力点边缘发生裁剪的现象

* style: lint style

* fix: 修复resize 后 picking shiqu 拾取失败的问题

* feat: 优化 marker/popup 在容器边缘的表现

* feat: 增加 setEnableRender 方法

* style: lint style

* feat: 增加城市图层扫光特效

* style: lint style

* feat: 补全拾取色混合配置

* style: lint style

* feat: 增加高德地图的面积大小点

* style: lint style

* feat: 点优化边缘锯齿

* fix: 修复pointLayer stroke 变暗问题

* fix: 修复混合导致的拾取错误

* feat: add simple point 1.0

* style: lint style

* feat: simple point support stroke

* style: lint style

* feat: 优化 simple point 边缘的锯齿

* style: lint style

* feat: add point cylinder raising animate

* style: lint style

* feat: 优化点图层 icon 在小尺寸下的锯齿问题

* style: lint style

* feat: 修复 layer destroy 报错、未清理、未重绘、补充触发 destroy 事件

* fix: 修复 marker 在 cluster getMakers 失效

* style: lint style

* feat: 清除 marker layer cluster fix

* style: lint style

* fix: 修复 markerLayer hide show 方法缺少 cluster 模式下的控制

* style: lint style

* feat: 取消在 shape 方法执行后的暴力更新

* style: lint style

* feat: 增加图层保底颜色设置

* style: lint style

* feat: 将兜底颜色改为 bottomColor

* fix: color bottom

* style: lint style

* feat: 修改颜色兜底判断逻辑

* style: lint style

* feat: add tnpm dist-tag

* feat: 增加line border 边框

* style: lint style

* feat: 增加 layer 重复销毁过滤

* style: lint style

* feat: 新增 wall 图层

* style: lint style

* feat: add image minimap

* style: lint style

* feat: 增加 pointLayer image mipmap 支持

* style: lint style

* feat: 调整点图层 image size 和之前保持一致

* fix: 修复线图层在存在高度的情况下,不同地图,不同场景下的效果兼容

* style: lint style

* fix: 修复线纹理在 mapbox 下表现不一致

* style: lint style

* fix: 修复 threejs 图层导致 L7 图层失效的问题

* style: lint style

* feat: 增加 simple line、修复 pointLayer meter 单个数据失效的情况

* style: lint style

* feat: 优化 simple line 效果

* style: lint style

* feat: 完善 demo

* style: lint style

* feat: adjust demo

* style: lint style

* feat: 修改简单线体层的 shape 参数

* feat: change simple lint type

* feat: demo fix

* style: lint style

* fix: 修复聚合图在放大、缩小时计算的 data 数量不同的问题

* style: lint style

* feat: demo 调整

* feat: 完善 demo

* feat: 提供相机运动相关方法 0.1

* feat: 增加 mask 0.1

* style: lint style

* feat: 增加 demo

* style: lint style

* feat: pickbox 返回值增加选中id

* style: lint style

* feat: 完善掩模能力

* style: lint style

* feat: 完善蒙层方案

* style: lint style

* feat: 增加 点图层 mask 支持

* style: lint style

* feat: 图片图层支持 mask

* style: lint style

* feat: heatmap support mask

* style: lint style

* feat: rasterLayer support mask

* style: lint style

* feat: polygonLayer support mask

* style: lint style

* feat: change raster mask demo

* style: lint style

* feat: pointLayer text support mask

* style: lint style

* feat: 改变 maskLayer 的默认透明度

* style: lint style
This commit is contained in:
YiQianYao 2022-01-24 17:46:10 +08:00 committed by GitHub
parent 0f2e7c5a3e
commit 755c9d23db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 2429 additions and 207 deletions

View File

@ -13,6 +13,8 @@ export interface ISceneConfig extends IRenderConfig {
animate?: boolean;
fitBoundsOptions?: unknown;
pickBufferScale?: number;
// TODO: 场景是否支持 stencil mask
stencil?: boolean;
}
// interface IValidateResult {

View File

@ -18,6 +18,8 @@ export interface IRenderConfig {
passes?: Array<IPass<unknown>>;
antialias?: boolean;
preserveDrawingBuffer?: boolean;
// TODO: 场景是否支持 stencil mask
stencil?: boolean;
}
export interface IClearOptions {

View File

@ -1,4 +1,11 @@
import { styleSingle } from '../core/BaseModel';
import { generateColorRamp, getMask, IColorRamp } from '@antv/l7-utils';
import { styleColor, styleOffset, styleSingle } from '../core/BaseModel';
import {
anchorType,
getGlyphQuads,
IGlyphQuad,
shapeText,
} from '../utils/symbol-layout';
export enum lineStyleType {
'solid' = 0.0,
'dash' = 1.0,
@ -26,4 +33,72 @@ export interface ILineLayerStyleOptions {
borderColor?: string; // 可选参数 线边框颜色
heightfixed?: boolean; // 可选参数 高度是否固定
mask?: boolean; // 可选参数 时候允许蒙层
maskInside?: boolean; // 可选参数 控制图层是否显示在蒙层的内部
}
export interface IPointLayerStyleOptions {
opacity: number;
strokeOpacity: number;
strokeWidth: number;
stroke: string;
textOffset?: [number, number];
textAnchor?: anchorType;
spacing?: number;
padding?: [number, number];
halo?: number;
gamma?: number;
fontWeight?: string;
fontFamily?: string;
textAllowOverlap?: boolean;
offsets?: styleOffset;
blend?: string;
unit?: string;
mask?: boolean;
maskInside?: boolean;
}
export interface IPolygonLayerStyleOptions {
opacity: styleSingle;
opacityLinear: {
enable: boolean;
dir: string;
};
pickLight: boolean;
mask?: boolean;
maskInside?: boolean;
}
export interface IImageLayerStyleOptions {
opacity: number;
mask?: boolean;
maskInside?: boolean;
}
export interface IHeatMapLayerStyleOptions {
opacity: number;
intensity: number;
radius: number;
angle: number;
rampColors: IColorRamp;
mask?: boolean;
maskInside?: boolean;
coverage?: number;
}
export interface IRasterLayerStyleOptions {
opacity: number;
domain: [number, number];
noDataValue: number;
clampLow: boolean;
clampHigh: boolean;
rampColors: IColorRamp;
mask?: boolean;
maskInside?: boolean;
}

View File

@ -1,9 +1,6 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@antv/l7-core';
import BaseLayer from '../core/BaseLayer';
import { IHeatMapLayerStyleOptions } from '../core/interface';
import HeatMapModels, { HeatMapModelType } from './models';
interface IHeatMapLayerStyleOptions {
opacity: number;
}
export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
public type: string = 'HeatMapLayer';

View File

@ -5,15 +5,12 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import { getMask } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IHeatMapLayerStyleOptions } from '../../core/interface';
import { HeatmapGridTriangulation } from '../../core/triangulation';
import heatmapGridVert from '../shaders/grid_vert.glsl';
import heatmapGridFrag from '../shaders/hexagon_frag.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
angle: number;
}
export default class GridModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
@ -37,6 +34,10 @@ export default class GridModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'gridheatmap',
@ -46,6 +47,7 @@ export default class GridModel extends BaseModel {
depth: { enable: false },
primitive: gl.TRIANGLES,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -5,16 +5,12 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import { aProjectFlat, Satistics, unProjectFlat } from '@antv/l7-utils';
import { getMask } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IHeatMapLayerStyleOptions } from '../../core/interface';
import { PointExtrudeTriangulation } from '../../core/triangulation';
import heatmapGrid3dVert from '../shaders/hexagon_3d_vert.glsl';
import heatmapGridFrag from '../shaders/hexagon_frag.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
angle: number;
}
export default class Grid3DModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
@ -38,6 +34,10 @@ export default class Grid3DModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'grid3dheatmap',
@ -46,6 +46,7 @@ export default class Grid3DModel extends BaseModel {
triangulation: PointExtrudeTriangulation,
depth: { enable: true },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -7,11 +7,12 @@ import {
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
import { generateColorRamp, getMask, IColorRamp } from '@antv/l7-utils';
import { mat4 } from 'gl-matrix';
import { inject, injectable } from 'inversify';
import 'reflect-metadata';
import BaseModel from '../../core/BaseModel';
import { IHeatMapLayerStyleOptions } from '../../core/interface';
import { HeatmapTriangulation } from '../../core/triangulation';
import heatmap3DFrag from '../shaders/heatmap_3d_frag.glsl';
import heatmap3DVert from '../shaders/heatmap_3d_vert.glsl';
@ -20,13 +21,6 @@ import heatmapFramebufferFrag from '../shaders/heatmap_framebuffer_frag.glsl';
import heatmapFramebufferVert from '../shaders/heatmap_framebuffer_vert.glsl';
import heatmapColorVert from '../shaders/heatmap_vert.glsl';
import { heatMap3DTriangulation } from '../triangulation';
interface IHeatMapLayerStyleOptions {
opacity: number;
intensity: number;
radius: number;
angle: number;
rampColors: IColorRamp;
}
@injectable()
export default class HeatMapModel extends BaseModel {
protected texture: ITexture2D;
@ -173,6 +167,10 @@ export default class HeatMapModel extends BaseModel {
}
private buildHeatmapColor(): IModel {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
this.shaderModuleService.registerModule('heatmapColor', {
vs: heatmapColorVert,
fs: heatmapColorFrag,
@ -219,6 +217,7 @@ export default class HeatMapModel extends BaseModel {
type: gl.UNSIGNED_INT,
count: 6,
}),
stencil: getMask(mask, maskInside),
});
}
@ -279,6 +278,10 @@ export default class HeatMapModel extends BaseModel {
});
}
private build3dHeatMap() {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
const { getViewportSize } = this.rendererService;
const { width, height } = getViewportSize();
const triangulation = heatMap3DTriangulation(width / 4.0, height / 4.0);
@ -336,6 +339,7 @@ export default class HeatMapModel extends BaseModel {
type: gl.UNSIGNED_INT,
count: triangulation.indices.length,
}),
stencil: getMask(mask, maskInside),
});
}
private updateStyle() {

View File

@ -5,17 +5,13 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import { getMask } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IHeatMapLayerStyleOptions } from '../../core/interface';
import { HeatmapGridTriangulation } from '../../core/triangulation';
import heatmapGridFrag from '../shaders/hexagon_frag.glsl';
import heatmapGridVert from '../shaders/hexagon_vert.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
angle: number;
}
export default class HexagonModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
@ -39,6 +35,10 @@ export default class HexagonModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'hexagonheatmap',
@ -48,6 +48,7 @@ export default class HexagonModel extends BaseModel {
depth: { enable: false },
primitive: gl.TRIANGLES,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,8 +1,6 @@
import BaseLayer from '../core/BaseLayer';
import { IImageLayerStyleOptions } from '../core/interface';
import ImageModels, { ImageModelType } from './models/index';
interface IImageLayerStyleOptions {
opacity: number;
}
export default class ImageLayer extends BaseLayer<IImageLayerStyleOptions> {
public type: string = 'ImageLayer';
public buildModels() {

View File

@ -2,25 +2,16 @@ import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerPlugin,
IModel,
IModelUniform,
IRasterParserDataItem,
IStyleAttributeService,
ITexture2D,
lazyInject,
TYPES,
} from '@antv/l7-core';
import { isMini } from '@antv/l7-utils';
import { getMask, isMini } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IImageLayerStyleOptions } from '../../core/interface';
import { RasterImageTriangulation } from '../../core/triangulation';
import ImageFrag from '../shaders/image_frag.glsl';
import ImageVert from '../shaders/image_vert.glsl';
interface IImageLayerStyleOptions {
opacity: number;
}
export default class ImageModel extends BaseModel {
protected texture: ITexture2D;
public getUninforms(): IModelUniform {
@ -31,6 +22,11 @@ export default class ImageModel extends BaseModel {
};
}
public initModels() {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IImageLayerStyleOptions;
const source = this.layer.getSource();
const { createTexture2D } = this.rendererService;
this.texture = createTexture2D({
@ -76,6 +72,7 @@ export default class ImageModel extends BaseModel {
primitive: gl.TRIANGLES,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -12,6 +12,7 @@ import RasterLayer from './raster';
import EarthLayer from './earth';
import MaskLayer from './mask';
import WindLayer from './wind';
// import ConfigSchemaValidationPlugin from './plugins/ConfigSchemaValidationPlugin';
@ -146,4 +147,5 @@ export {
HeatmapLayer,
EarthLayer,
WindLayer,
MaskLayer,
};

View File

@ -9,7 +9,7 @@ import {
ITexture2D,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
@ -139,6 +139,8 @@ export default class ArcModel extends BaseModel {
public buildModels(): IModel[] {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return [
@ -150,6 +152,7 @@ export default class ArcModel extends BaseModel {
depth: { enable: false },
blend: this.getBlend(),
segmentNumber,
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -8,7 +8,7 @@ import {
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
@ -135,6 +135,8 @@ export default class Arc3DModel extends BaseModel {
public buildModels(): IModel[] {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return [
this.layer.buildLayerModel({
@ -145,6 +147,7 @@ export default class Arc3DModel extends BaseModel {
blend: this.getBlend(),
segmentNumber,
// primitive: gl.POINTS,
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -9,12 +9,11 @@ import {
ITexture2D,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
import { LineArcTriangulation } from '../../core/triangulation';
// import line_arc_frag from '../shaders/line_arc_frag.glsl';
import line_arc_frag from '../shaders/line_arc_great_circle_frag.glsl';
import line_arc2d_vert from '../shaders/line_arc_great_circle_vert.glsl';
const lineStyleObj: { [key: string]: number } = {
@ -36,7 +35,6 @@ export default class GreatCircleModel extends BaseModel {
iconStep = 100,
segmentNumber = 30,
} = this.layer.getLayerConfig() as Partial<ILineLayerStyleOptions>;
// console.log('opacity', opacity)
if (dashArray.length === 2) {
dashArray.push(0, 0);
}
@ -129,14 +127,19 @@ export default class GreatCircleModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'arc2dline',
moduleName: 'greatcircleline',
vertexShader: line_arc2d_vert,
fragmentShader: line_arc_frag,
triangulation: LineArcTriangulation,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -10,7 +10,7 @@ import {
ITexture2D,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions, lineStyleType } from '../../core/interface';
@ -135,6 +135,10 @@ export default class LineModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'line',
@ -144,6 +148,7 @@ export default class LineModel extends BaseModel {
primitive: gl.TRIANGLES,
blend: this.getBlend(),
depth: { enable: false },
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -8,7 +8,7 @@ import {
IModelUniform,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions } from '../../core/interface';
@ -95,6 +95,11 @@ export default class SimpleLineModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'simpleline',
@ -104,6 +109,7 @@ export default class SimpleLineModel extends BaseModel {
primitive: gl.LINES, // gl.LINES gl.TRIANGLES
blend: this.getBlend(),
depth: { enable: false },
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -0,0 +1,23 @@
import { IEncodeFeature } from '@antv/l7-core';
import { polygonTriangulation } from '../../core/triangulation';
describe('PolygonTriangulation', () => {
it('should do triangulation with a polygon correctly', () => {
const mockFeature: IEncodeFeature = {
coordinates: [
[
[0, 0],
[1, 0],
[1, 1],
[0, 1],
],
],
color: [1, 0, 0, 0],
};
const { indices, vertices, size } = polygonTriangulation(mockFeature);
expect(indices).toEqual([2, 3, 0, 0, 1, 2]);
expect(vertices).toEqual([0, 0, 1, 0, 1, 1, 0, 1]);
expect(size).toEqual(2);
});
});

View File

@ -0,0 +1,33 @@
import BaseLayer from '../core/BaseLayer';
import MaskModels, { MaskModelType } from './models';
interface IMaskLayerStyleOptions {
opacity: number;
}
export default class MaskLayer extends BaseLayer<IMaskLayerStyleOptions> {
public type: string = 'MaskLayer';
public buildModels() {
const shape = this.getModelType();
this.layerModel = new MaskModels[shape](this);
this.models = this.layerModel.initModels();
}
public rebuildModels() {
this.models = this.layerModel.buildModels();
}
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected getModelType(): MaskModelType {
return 'fill';
}
}

View File

@ -0,0 +1,59 @@
import { gl, IModel } from '@antv/l7-core';
import { isNumber } from 'lodash';
import BaseModel, { styleSingle } from '../../core/BaseModel';
import { polygonTriangulation } from '../../core/triangulation';
import mask_frag from '../shaders/mask_frag.glsl';
import mask_vert from '../shaders/mask_vert.glsl';
interface IMaskStyleOptions {
opacity: styleSingle;
}
export default class MaskModel extends BaseModel {
public getUninforms() {
const { opacity = 0 } = this.layer.getLayerConfig() as IMaskStyleOptions;
return {
u_opacity: isNumber(opacity) ? opacity : 0.0,
};
}
public initModels(): IModel[] {
// TODO: 瓦片组件默认在最下层
this.layer.zIndex = -1000;
return this.buildModels();
}
public buildModels(): IModel[] {
return [
this.layer.buildLayerModel({
moduleName: 'mask',
vertexShader: mask_vert,
fragmentShader: mask_frag,
triangulation: polygonTriangulation,
blend: this.getBlend(),
depth: { enable: false },
stencil: {
enable: true,
mask: 0xff,
func: {
cmp: gl.ALWAYS,
ref: 1,
mask: 0xff,
},
opFront: {
fail: gl.REPLACE,
zfail: gl.REPLACE,
zpass: gl.REPLACE,
},
},
}),
];
}
public clearModels() {
this.dataTexture?.destroy();
}
protected registerBuiltinAttributes() {
return '';
}
}

View File

@ -0,0 +1,8 @@
import FillModel from './fill';
export type MaskModelType = 'fill';
const MaskModels: { [key in MaskModelType]: any } = {
fill: FillModel,
};
export default MaskModels;

View File

@ -0,0 +1,7 @@
uniform float u_opacity;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
gl_FragColor.a *= u_opacity;
}

View File

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

View File

@ -1,11 +1,8 @@
import { IEncodeFeature } from '@antv/l7-core';
import BaseLayer from '../core/BaseLayer';
import { IPointLayerStyleOptions } from '../core/interface';
import PointModels, { PointType } from './models/index';
interface IPointLayerStyleOptions {
opacity: number;
strokeWidth: number;
stroke: string;
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public type: string = 'PointLayer';
public buildModels() {

View File

@ -9,11 +9,9 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import BaseModel, {
styleColor,
styleOffset,
styleSingle,
} from '../../core/BaseModel';
import { getMask } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import {
GlobelPointFillTriangulation,
PointFillTriangulation,
@ -25,16 +23,6 @@ import { isNumber } from 'lodash';
import { Version } from '@antv/l7-maps';
import { mat4, vec3 } from 'gl-matrix';
interface IPointLayerStyleOptions {
opacity: styleSingle;
strokeWidth: styleSingle;
stroke: styleColor;
strokeOpacity: styleSingle;
offsets: styleOffset;
blend: string;
unit: string;
}
// 判断当前使用的 style 中的变量属性是否需要进行数据映射
export default class FillModel extends BaseModel {
public meter2coord: number = 1;
private isMeter: boolean = false;
@ -169,6 +157,10 @@ export default class FillModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
// TODO: 判断当前的点图层的模型是普通地图模式还是地球模式
const isGlobel = this.mapService.version === 'GLOBEL';
return [
@ -182,6 +174,7 @@ export default class FillModel extends BaseModel {
// depth: { enable: false },
depth: { enable: isGlobel },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -2,20 +2,17 @@ import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel, { styleOffset, styleSingle } from '../../core/BaseModel';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import { PointImageTriangulation } from '../../core/triangulation';
import pointImageFrag from '../shaders/image_frag.glsl';
import pointImageVert from '../shaders/image_vert.glsl';
interface IImageLayerStyleOptions {
opacity: styleSingle;
offsets: styleOffset;
}
export default class ImageModel extends BaseModel {
private texture: ITexture2D;
@ -23,7 +20,7 @@ export default class ImageModel extends BaseModel {
const {
opacity,
offsets = [0, 0],
} = this.layer.getLayerConfig() as IImageLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
if (this.rendererService.getDirty()) {
this.texture.bind();
}
@ -95,6 +92,10 @@ export default class ImageModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'pointImage',
@ -104,6 +105,7 @@ export default class ImageModel extends BaseModel {
primitive: gl.POINTS,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,4 +1,3 @@
import { ILayerModel } from '@antv/l7-core';
import ExtrudeModel from './extrude';
import FillModel from './fill';
import IconModel from './icon-font';

View File

@ -7,17 +7,13 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel, { styleOffset, styleSingle } from '../../core/BaseModel';
import { BlendTypes } from '../../utils/blend';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import normalFrag from '../shaders/normal_frag.glsl';
import normalVert from '../shaders/normal_vert.glsl';
interface IPointLayerStyleOptions {
opacity: styleSingle;
offsets: styleOffset;
}
export function PointTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
@ -81,10 +77,6 @@ export default class NormalModel extends BaseModel {
return {
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
u_cellTypeLayout: this.getCellTypeLayout(),
// u_opacity: opacity,
// u_stroke_width: strokeWidth,
// u_stroke_color: rgb2arr(stroke),
// u_offsets: [-offsets[0], offsets[1]],
u_opacity: isNumber(opacity) ? opacity : 1.0,
u_offsets: this.isOffsetStatic(offsets)
? (offsets as [number, number])
@ -97,6 +89,10 @@ export default class NormalModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'normalpoint',
@ -106,6 +102,7 @@ export default class NormalModel extends BaseModel {
depth: { enable: false },
primitive: gl.POINTS,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -8,24 +8,14 @@ import {
IModelUniform,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel, {
styleColor,
styleOffset,
styleSingle,
} from '../../core/BaseModel';
import { BlendTypes } from '../../utils/blend';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import simplePointFrag from '../shaders/simplePoint_frag.glsl';
import simplePointVert from '../shaders/simplePoint_vert.glsl';
interface IPointLayerStyleOptions {
opacity: styleSingle;
offsets: styleOffset;
blend: string;
strokeOpacity: styleSingle;
strokeWidth: styleSingle;
stroke: styleColor;
}
export function PointTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
@ -110,6 +100,10 @@ export default class SimplePointModel extends BaseModel {
}
public buildModels(): IModel[] {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
return [
this.layer.buildLayerModel({
moduleName: 'simplepoint',
@ -119,6 +113,7 @@ export default class SimplePointModel extends BaseModel {
depth: { enable: false },
primitive: gl.POINTS,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,46 +1,25 @@
import {
AttributeType,
BlendType,
gl,
IEncodeFeature,
ILayer,
ILayerConfig,
IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { boundsContains, padBounds, rgb2arr } from '@antv/l7-utils';
import { isNumber, isString } from 'lodash';
import BaseModel, {
styleColor,
styleOffset,
styleSingle,
} from '../../core/BaseModel';
import { boundsContains, getMask, padBounds } 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 { calculateCentroid } from '../../utils/geo';
import {
anchorType,
getGlyphQuads,
IGlyphQuad,
shapeText,
} from '../../utils/symbol-layout';
import textFrag from '../shaders/text_frag.glsl';
import textVert from '../shaders/text_vert.glsl';
interface IPointTextLayerStyleOptions {
opacity: styleSingle;
strokeWidth: styleSingle;
stroke: styleColor;
textOffset: [number, number];
textAnchor: anchorType;
spacing: number;
padding: [number, number];
halo: number;
gamma: number;
fontWeight: string;
fontFamily: string;
textAllowOverlap: boolean;
}
export function TextTriangulation(feature: IEncodeFeature) {
// @ts-ignore
const that = this as TextModel;
@ -113,7 +92,7 @@ export default class TextModel extends BaseModel {
private extent: [[number, number], [number, number]];
private textureHeight: number = 0;
private textCount: number = 0;
private preTextStyle: Partial<IPointTextLayerStyleOptions> = {};
private preTextStyle: Partial<IPointLayerStyleOptions> = {};
public getUninforms(): IModelUniform {
const {
opacity = 1.0,
@ -123,7 +102,7 @@ export default class TextModel extends BaseModel {
textAllowOverlap = false,
halo = 0.5,
gamma = 2.0,
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const { canvas, mapping } = this.fontService;
if (Object.keys(mapping).length !== this.textCount) {
this.updateTexture();
@ -197,7 +176,7 @@ export default class TextModel extends BaseModel {
const {
textAnchor = 'center',
textAllowOverlap = true,
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.preTextStyle = {
textAnchor,
textAllowOverlap,
@ -206,6 +185,10 @@ export default class TextModel extends BaseModel {
}
public buildModels = () => {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.initGlyph();
this.updateTexture();
this.filterGlyphs();
@ -218,13 +201,14 @@ export default class TextModel extends BaseModel {
triangulation: TextTriangulation.bind(this),
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
};
public needUpdate() {
const {
textAllowOverlap = false,
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
// textAllowOverlap 发生改变
const zoom = this.mapService.getZoom();
const extent = this.mapService.getBounds();
@ -285,7 +269,6 @@ export default class TextModel extends BaseModel {
vertex: number[],
attributeIdx: number,
) => {
// console.log([vertex[5], vertex[6]])
return [vertex[5], vertex[6]];
},
},
@ -351,7 +334,7 @@ export default class TextModel extends BaseModel {
const {
fontWeight = '400',
fontFamily = 'sans-serif',
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const data = this.layer.getEncodedData();
const characterSet: string[] = [];
data.forEach((item: IEncodeFeature) => {
@ -379,7 +362,7 @@ export default class TextModel extends BaseModel {
const {
fontWeight = '400',
fontFamily = 'sans-serif',
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const data = this.layer.getEncodedData();
const characterSet: string[] = [];
data.forEach((item: IEncodeFeature) => {
@ -407,7 +390,7 @@ export default class TextModel extends BaseModel {
spacing = 2,
textAnchor = 'center',
// textOffset,
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
const data = this.layer.getEncodedData();
this.glyphInfo = data.map((feature: IEncodeFeature) => {
@ -452,7 +435,7 @@ export default class TextModel extends BaseModel {
const {
padding = [4, 4],
textAllowOverlap = false,
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
if (textAllowOverlap) {
// 如果允许文本覆盖
// this.layer.setEncodedData(this.glyphInfo);
@ -528,6 +511,10 @@ export default class TextModel extends BaseModel {
}
private reBuildModel() {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.filterGlyphs();
this.layer.models = [
this.layer.buildLayerModel({
@ -537,6 +524,7 @@ export default class TextModel extends BaseModel {
triangulation: TextTriangulation.bind(this),
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,12 +1,8 @@
import { IEncodeFeature } from '@antv/l7-core';
import BaseLayer from '../core/BaseLayer';
import { PointType } from '../point/models/';
import { IPolygonLayerStyleOptions } from '../core/interface';
import PolygonModels, { PolygonModelType } from './models/';
interface IPolygonLayerStyleOptions {
opacity: number;
}
export default class PolygonLayer extends BaseLayer<IPolygonLayerStyleOptions> {
public type: string = 'PolygonLayer';
public buildModels() {

View File

@ -1,16 +1,13 @@
import { AttributeType, gl, IEncodeFeature, IModel } from '@antv/l7-core';
import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel, { styleSingle } from '../../core/BaseModel';
import BaseModel from '../../core/BaseModel';
import { IPolygonLayerStyleOptions } from '../../core/interface';
import { PolygonExtrudeTriangulation } from '../../core/triangulation';
import polygonExtrudeFrag from '../shaders/polygon_extrude_frag.glsl';
import polygonExtrudePickLightFrag from '../shaders/polygon_extrude_picklight_frag.glsl';
import polygonExtrudePickLightVert from '../shaders/polygon_extrude_picklight_vert.glsl';
import polygonExtrudeVert from '../shaders/polygon_extrude_vert.glsl';
interface IPolygonLayerStyleOptions {
opacity: styleSingle;
pickLight: boolean;
}
export default class ExtrudeModel extends BaseModel {
public getUninforms() {
const {
@ -62,6 +59,8 @@ export default class ExtrudeModel extends BaseModel {
public buildModels(): IModel[] {
const {
pickLight = false,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
return [
this.layer.buildLayerModel({
@ -73,6 +72,7 @@ export default class ExtrudeModel extends BaseModel {
? polygonExtrudePickLightFrag
: polygonExtrudeFrag,
triangulation: PolygonExtrudeTriangulation,
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,17 +1,8 @@
import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerModel,
ILayerPlugin,
IModel,
IStyleAttributeService,
lazyInject,
TYPES,
} from '@antv/l7-core';
import { AttributeType, gl, IEncodeFeature, IModel } from '@antv/l7-core';
import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel, { styleSingle } from '../../core/BaseModel';
import BaseModel from '../../core/BaseModel';
import { IPolygonLayerStyleOptions } from '../../core/interface';
import {
polygonTriangulation,
polygonTriangulationWithCenter,
@ -20,15 +11,6 @@ import polygon_frag from '../shaders/polygon_frag.glsl';
import polygon_linear_frag from '../shaders/polygon_linear_frag.glsl';
import polygon_linear_vert from '../shaders/polygon_linear_vert.glsl';
import polygon_vert from '../shaders/polygon_vert.glsl';
interface IPolygonLayerStyleOptions {
opacity: styleSingle;
opacityLinear: {
enable: boolean;
dir: string;
};
}
export default class FillModel extends BaseModel {
public getUninforms() {
const {
@ -88,6 +70,8 @@ export default class FillModel extends BaseModel {
enable: false,
dir: 'in',
},
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
return [
this.layer.buildLayerModel({
@ -102,6 +86,8 @@ export default class FillModel extends BaseModel {
: polygonTriangulation,
blend: this.getBlend(),
depth: { enable: false },
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -1,14 +1,6 @@
import { IColorRamp } from '@antv/l7-utils';
import BaseLayer from '../core/BaseLayer';
import { IRasterLayerStyleOptions } from '../core/interface';
import RasterModels, { RasterModelType } from './models/index';
interface IRasterLayerStyleOptions {
opacity: number;
domain: [number, number];
noDataValue: number;
clampLow: boolean;
clampHigh: boolean;
rampColors: IColorRamp;
}
export default class RaterLayer extends BaseLayer<IRasterLayerStyleOptions> {
public type: string = 'RasterLayer';
public buildModels() {

View File

@ -2,30 +2,16 @@ import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerPlugin,
IModel,
IModelUniform,
IRasterParserDataItem,
IStyleAttributeService,
ITexture2D,
lazyInject,
TYPES,
} from '@antv/l7-core';
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
import { generateColorRamp, getMask, IColorRamp } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IRasterLayerStyleOptions } from '../../core/interface';
import { RasterImageTriangulation } from '../../core/triangulation';
import rasterFrag from '../shaders/raster_2d_frag.glsl';
import rasterVert from '../shaders/raster_2d_vert.glsl';
interface IRasterLayerStyleOptions {
opacity: number;
domain: [number, number];
noDataValue: number;
clampLow: boolean;
clampHigh: boolean;
rampColors: IColorRamp;
}
export default class RasterModel extends BaseModel {
protected texture: ITexture2D;
protected colorTexture: ITexture2D;
@ -50,6 +36,10 @@ export default class RasterModel extends BaseModel {
}
public initModels() {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IRasterLayerStyleOptions;
const source = this.layer.getSource();
const { createTexture2D } = this.rendererService;
const parserDataItem = source.data.dataArray[0];
@ -80,6 +70,7 @@ export default class RasterModel extends BaseModel {
primitive: gl.TRIANGLES,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
}),
];
}

View File

@ -103,6 +103,11 @@ export default class ReglModel implements IModel {
enable: false,
};
pickDrawParams.stencil = {
...pickDrawParams.stencil,
enable: false,
};
this.drawPickCommand = reGl(pickDrawParams);
this.drawParams = drawParams;
}

View File

@ -62,6 +62,8 @@ export default class ReglRendererService implements IRendererService {
antialias: cfg.antialias,
premultipliedAlpha: true,
preserveDrawingBuffer: cfg.preserveDrawingBuffer,
stencil: cfg.stencil,
},
// TODO: use extensions
extensions: [

View File

@ -8,5 +8,6 @@ export * from './lru_cache';
export * from './event';
export * from './color';
export * from './anchor';
export * from './stencli';
import * as Satistics from './statistics';
export { DOM, Satistics };

View File

@ -0,0 +1,12 @@
// TODO: 提供模版配置
export function getMask(mask: boolean, maskInside: boolean) {
return {
enable: mask,
mask: 0xff,
func: {
cmp: 514, // gl.EQUAL,
ref: maskInside ? 1 : 0,
mask: 0xff,
},
};
}

View File

@ -1,4 +1,4 @@
import { LineLayer, Scene, PointLayer } from '@antv/l7';
import { LineLayer, Scene, PointLayer, PolygonLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
@ -14,7 +14,7 @@ export default class Amap2demo_road2 extends React.Component {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [120.165, 30.25],
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
viewMode: '3D',
@ -22,18 +22,75 @@ export default class Amap2demo_road2 extends React.Component {
}),
});
this.scene = scene;
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new PolygonLayer({})
.source(data)
.shape('fill')
.color('red');
scene.addLayer(polygonlayer);
const polygonlayer2 = new PolygonLayer({})
.source(data2)
.shape('fill')
.color('#ff0');
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json',
)
.then((res) => res.json())
.then((data) => {
scene.addImage(
'02',
'https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg',
);
// @ts-ignore
const layer = new LineLayer({})
.source(data)
.size(5)

View File

@ -0,0 +1,194 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class Amap2demo_road2 extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
viewMode: '3D',
style: 'dark',
}),
});
this.scene = scene;
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
const data3 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [[]],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
let points = new PointLayer({ zIndex: 2 })
.source(
[
{
lng: 120.14871597290039,
lat: 30.268407989758884,
},
{
lng: 120.15352249145508,
lat: 30.271669642392517,
},
{
lng: 120.16502380371092,
lat: 30.26944580007901,
},
{
lng: 120.16485214233397,
lat: 30.26425663877134,
},
{
lng: 120.16073226928711,
lat: 30.259067203213018,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('circle')
.size(25)
.color('#0ff')
.style({
opacity: 0.3,
});
scene.addLayer(points);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json',
)
.then((res) => res.json())
.then((data) => {
const layer = new LineLayer({ mask: true, maskInside: true }) // mask: true maskInside: true
.source(data)
.size(5)
.shape('line')
.color('rgb(20, 180, 90)')
.style({
borderWidth: 0.35,
borderColor: '#fff',
// opacity: 0.5,
// lineTexture: true, // 开启线的贴图功能
// iconStep: 80, // 设置贴图纹理的间距
})
.active(true);
scene.addLayer(layer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -77,6 +77,7 @@ import GridTile2 from './components/gridTile2'
import Cluster from './components/cluster'
import Hot from './components/hot'
import Hot2 from './components/hot2'
import Mask from './components/mask'
// @ts-ignore
storiesOf('地图方法', module)
@ -158,4 +159,4 @@ storiesOf('地图方法', module)
.add('Cluster', () => <Cluster/>)
.add('Hot1', () => <Hot/>)
.add('Hot2', () => <Hot2/>)
.add('Mask', () => <Mask/>)

View File

@ -0,0 +1,155 @@
import {
LineLayer,
Scene,
MaskLayer,
HeatmapLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 2,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[125.15625000000001, 8.407168163601076],
[116.54296874999999, -21.289374355860424],
[156.26953125, -20.632784250388013],
[150.29296875, 2.1088986592431382],
],
],
[
[
[78.57421875, 46.92025531537451],
[51.67968749999999, 37.020098201368114],
[87.890625, 28.76765910569123],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[133.2421875, 44.33956524809713],
[123.04687499999999, 31.50362930577303],
[154.3359375, 20.632784250388028],
[157.32421875, 38.54816542304656],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
)
.then((res) => res.json())
.then((data) => {
// const heatmapLayer = new HeatmapLayer({ mask: true, maskInside: true })
const heatmapLayer = new HeatmapLayer({
mask: true,
maskInside: false,
})
.source(data)
.shape('heatmap3D') // heatmap3D heatmap
.size('mag', [0, 1.0]) // weight映射通道
.style({
intensity: 2,
radius: 20,
opacity: 1.0,
rampColors: {
colors: [
'#FF4818',
'#F7B74A',
'#FFF598',
'#91EABC',
'#2EA9A1',
'#206C7C',
].reverse(),
positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
},
});
scene.addLayer(heatmapLayer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,172 @@
import {
LineLayer,
Scene,
MaskLayer,
HeatmapLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 2,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[125.15625000000001, 8.407168163601076],
[116.54296874999999, -21.289374355860424],
[156.26953125, -20.632784250388013],
[150.29296875, 2.1088986592431382],
],
],
[
[
[78.57421875, 46.92025531537451],
[51.67968749999999, 37.020098201368114],
[87.890625, 28.76765910569123],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[133.2421875, 44.33956524809713],
[123.04687499999999, 31.50362930577303],
[154.3359375, 20.632784250388028],
[157.32421875, 38.54816542304656],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/7359a5e9-3c5e-453f-b207-bc892fb23b84.csv',
)
.then((res) => res.text())
.then((data) => {
const heatmapLayer = new HeatmapLayer({
mask: true,
maskInside: true,
})
// const heatmapLayer = new HeatmapLayer({ mask: true, maskInside: false })
.source(data, {
parser: {
type: 'csv',
x: 'lng',
y: 'lat',
},
transforms: [
{
type: 'grid', // grid
size: 20000,
field: 'v',
method: 'sum',
},
],
})
.shape('circle')
.style({
coverage: 0.9,
angle: 0,
})
.color(
'count',
[
'#8C1EB2',
'#8C1EB2',
'#DA05AA',
'#F0051A',
'#FF2A3C',
'#FF4818',
'#FF4818',
'#FF8B18',
'#F77B00',
'#ED9909',
'#ECC357',
'#EDE59C',
].reverse(),
);
scene.addLayer(heatmapLayer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,157 @@
import {
LineLayer,
Scene,
MaskLayer,
HeatmapLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
style: 'light',
pitch: 56.499,
center: [114.07737552216226, 22.542656745583486],
rotation: 39.19,
zoom: 12.47985,
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[113.94058227539062, 22.67484735118852],
[113.83895874023438, 22.62415215809042],
[113.9447021484375, 22.55187920514417],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[114.11087036132811, 22.669778674332314],
[114.02847290039062, 22.59372606392931],
[114.11636352539062, 22.485912942320958],
[114.22622680664062, 22.51255695405145],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json',
)
.then((res) => res.json())
.then((data) => {
// const layer = new HeatmapLayer({ mask: true })
const layer = new HeatmapLayer({ mask: true, maskInside: false })
.source(data, {
transforms: [
{
type: 'grid',
size: 100,
field: 'h12',
method: 'sum',
},
],
})
.size('sum', [0, 600])
.shape('cylinder')
.style({
coverage: 0.8,
angle: 0,
opacity: 1.0,
})
.color(
'sum',
[
'#094D4A',
'#146968',
'#1D7F7E',
'#289899',
'#34B6B7',
'#4AC5AF',
'#5FD3A6',
'#7BE39E',
'#A1EDB8',
'#CEF8D6',
].reverse(),
);
scene.addLayer(layer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,170 @@
import {
LineLayer,
Scene,
MaskLayer,
HeatmapLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 6,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[117.20214843749999, 30.29701788337205],
[119.66308593749999, 30.050076521698735],
[117.20214843749999, 29.286398892934763],
],
],
[
[
[119.13574218749999, 28.188243641850313],
[119.64111328125, 29.19053283229458],
[120.60791015625, 27.955591004642553],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[121.4208984375, 30.486550842588485],
[120.7177734375, 30.183121842195515],
[121.06933593749999, 29.248063243796576],
[121.75048828124999, 29.57345707301757],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/a1a8158d-6fe3-424b-8e50-694ccf61c4d7.csv',
)
.then((res) => res.text())
.then((data) => {
// const layer = new HeatmapLayer({ mask: true })
const layer = new HeatmapLayer({ mask: true, maskInside: false })
.source(data, {
parser: {
type: 'csv',
x: 'lng',
y: 'lat',
},
transforms: [
{
type: 'hexagon',
size: 2500,
field: 'v',
method: 'sum',
},
],
})
.size('sum', (sum) => {
return sum * 20000;
})
.shape('hexagonColumn')
.style({
coverage: 0.8,
angle: 0,
opacity: 1.0,
})
.color('sum', [
'#094D4A',
'#146968',
'#1D7F7E',
'#289899',
'#34B6B7',
'#4AC5AF',
'#5FD3A6',
'#7BE39E',
'#A1EDB8',
'#C3F9CC',
'#DEFAC0',
'#ECFFB1',
]);
scene.addLayer(layer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,142 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
ImageLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
// let points = new PointLayer({ zIndex: 2, mask: true, maskInside: false }) // maskInside: true
const layer = new ImageLayer({ mask: true, maskInside: false });
layer.source(
'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
{
parser: {
type: 'image',
extent: [
120.14802932739258,
30.262773970881057,
120.17669677734374,
30.25239466884559,
],
},
},
);
scene.addLayer(layer);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,142 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
ImageTileLayer,
ImageLayer,
} from '@antv/l7';
import { GaodeMap, Map } from '@antv/l7-maps';
import * as React from 'react';
export default class ImageTile extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
// stencil: true,
map: new Map({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
// let points = new PointLayer({ zIndex: 2, mask: true, maskInside: false }) // maskInside: true
const layer = new ImageTileLayer({});
layer
.source(
'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'imagetile',
},
},
)
.style({
resolution: 'low', // low height
// resolution: 'height'
maxSourceZoom: 17,
});
scene.addLayer(layer);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,192 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class Amap2demo_road2 extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
viewMode: '3D',
style: 'dark',
}),
});
this.scene = scene;
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
const data3 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [[]],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
let points = new PointLayer({ zIndex: 2, mask: true })
.source(
[
{
lng: 120.14871597290039,
lat: 30.268407989758884,
},
{
lng: 120.15352249145508,
lat: 30.271669642392517,
},
{
lng: 120.16502380371092,
lat: 30.26944580007901,
},
{
lng: 120.16485214233397,
lat: 30.26425663877134,
},
{
lng: 120.16073226928711,
lat: 30.259067203213018,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('circle')
.size(25)
.color('#0ff')
.style({
opacity: 0.3,
});
scene.addLayer(points);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json',
)
.then((res) => res.json())
.then((data) => {
// const layer = new LineLayer({ mask: true, maskInside: false }) // mask: true maskInside: true
const layer = new LineLayer({ mask: true, maskInside: true }) // mask: true maskInside: true
.source(data)
.size(5)
.shape('arc3d') // line arc greatcircle simple
.color('rgb(20, 180, 90)')
.style({
borderWidth: 0.35,
borderColor: '#fff',
})
.active(true);
scene.addLayer(layer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,176 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
// let points = new PointLayer({ zIndex: 2, mask: true, maskInside: false }) // maskInside: true
let points = new PointLayer({ zIndex: 2, mask: true, maskInside: true })
.source(
[
{
name: 'n1',
lng: 120.14871597290039,
lat: 30.268407989758884,
},
{
name: 'n2',
lng: 120.15352249145508,
lat: 30.271669642392517,
},
{
name: 'n3',
lng: 120.16502380371092,
lat: 30.26944580007901,
},
{
name: 'n4',
lng: 120.16485214233397,
lat: 30.26425663877134,
},
{
name: 'n5',
lng: 120.16073226928711,
lat: 30.259067203213018,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
// .shape('circle')
// .shape('text', 'test')
// .shape('00')
.shape('simple')
.size(30)
// .color('#0ff')
.style({
opacity: 0.6,
})
.active({
color: '#00f',
mix: 0.6,
});
scene.addLayer(points);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,158 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 15,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16021728515624, 30.259660295442085],
[120.15987396240234, 30.25313608393673],
[120.16605377197266, 30.253729211980726],
[120.1658821105957, 30.258474107402265],
],
],
[
[
[120.1703453063965, 30.258474107402265],
[120.17086029052733, 30.254174055663515],
[120.17583847045898, 30.254915457324778],
[120.17446517944336, 30.258474107402265],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[120.16536712646484, 30.26336704072365],
[120.16777038574219, 30.2657392842738],
[120.17086029052733, 30.26232916614846],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.1,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.1,
});
scene.addLayer(polygonlayer2);
// let points = new PointLayer({ zIndex: 2, mask: true, maskInside: false }) // maskInside: true
let points = new PolygonLayer({ mask: true })
// let points = new PolygonLayer({ mask: true, maskInside: false })
.source({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [
[
[120.13429641723633, 30.22836979266676],
[120.19214630126953, 30.22836979266676],
[120.19214630126953, 30.276265423522855],
[120.13429641723633, 30.276265423522855],
[120.13429641723633, 30.22836979266676],
],
],
},
},
],
})
// .shape('circle')
// .shape('text', 'test')
// .shape('00')
.shape('extrude') // fill
.size(30)
.color('#0ff')
.style({
opacity: 0.6,
});
scene.addLayer(points);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,119 @@
import { LineLayer, Scene, MaskLayer, RasterLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
// @ts-ignore
import * as GeoTIFF from 'geotiff';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
private async getTiffData() {
const response = await fetch(
'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat',
// 'https://gw.alipayobjects.com/zos/antvdemo/assets/2019_clip/ndvi_201905.tiff',
);
const arrayBuffer = await response.arrayBuffer();
const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer);
const image = await tiff.getImage();
const width = image.getWidth();
const height = image.getHeight();
const values = await image.readRasters();
return {
data: values[0],
width,
height,
min: 0,
max: 8000,
};
}
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [120.165, 30.26],
pitch: 0,
zoom: 2,
style: 'dark',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
)
.then((res) => res.json())
.then((data) => {
let layer = new MaskLayer({}) // autoFit: true
.source(data);
scene.addLayer(layer);
});
});
const tiffdata = await this.getTiffData();
const layer = new RasterLayer({ mask: true });
// const layer = new RasterLayer({ mask: true, maskInside: false });
const mindata = -0;
const maxdata = 8000;
layer
.source(tiffdata.data, {
parser: {
type: 'raster',
width: tiffdata.width,
height: tiffdata.height,
extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963],
// extent: [
// 73.4766000000000048,
// 18.1054999999999993,
// 135.1066187,
// 57.630046,
// ],
},
})
.style({
opacity: 0.8,
domain: [mindata, maxdata],
clampLow: true,
rampColors: {
colors: [
'rgb(166,97,26)',
'rgb(223,194,125)',
'rgb(245,245,245)',
'rgb(128,205,193)',
'rgb(1,133,113)',
],
positions: [0, 0.25, 0.5, 0.75, 1.0],
},
});
scene.addLayer(layer);
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,151 @@
import {
LineLayer,
Scene,
MaskLayer,
PolygonLayer,
PointLayer,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class MaskPoints extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [105, 32],
pitch: 0,
zoom: 4,
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
);
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[112.8515625, 47.635783590864854],
[117.59765625, 38.54816542304656],
[125.15625000000001, 45.02695045318546],
],
],
[
[
[88.681640625, 40.17887331434696],
[100.37109375, 35.460669951495305],
[89.82421875, 29.53522956294847],
],
],
],
},
},
],
};
const data2 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [
[
[
[116.71874999999999, 30.221101852485987],
[113.90625, 24.686952411999155],
[123.48632812499999, 23.725011735951796],
[122.08007812499999, 28.22697003891834],
],
],
],
},
},
],
};
scene.on('loaded', () => {
const polygonlayer = new MaskLayer({})
.source(data)
.shape('fill')
.color('red')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer);
const polygonlayer2 = new MaskLayer({})
.source(data2)
.shape('fill')
.color('#ff0')
.style({
opacity: 0.3,
});
scene.addLayer(polygonlayer2);
fetch(
'https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json',
)
.then((res) => res.json())
.then((data) => {
// const pointLayer = new PointLayer({ mask: true })
const pointLayer = new PointLayer({ mask: true, maskInside: false })
.source(data.list, {
parser: {
type: 'json',
x: 'j',
y: 'w',
},
})
.shape('m', 'text')
.size(12)
.color('w', ['#0e0030', '#0e0030', '#0e0030'])
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: [0, 0], // 文本相对锚点的偏移量 [水平, 垂直]
spacing: 2, // 字符间距
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
strokeWidth: 0.3, // 描边宽度
strokeOpacity: 1.0,
// textAllowOverlap: true
});
scene.addLayer(pointLayer);
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,27 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import Line from './components/line'
import Polygon from './components/polygon'
import Point from './components/point'
import Image from './components/image'
import ImageTile from './components/imageTile'
import Heatmap from './components/heatmap'
import HeatmapGrid from './components/heatmapgrid'
import HeatmapGrid3D from './components/heatmapgrid3d'
import Hexgon from './components/hexgon'
import Raster from './components/raster'
import Text from './components/text'
storiesOf('Mask 方法', module)
.add('Point', () => <Point/>)
.add('Polygon', () => <Polygon/>)
.add('Line', () => <Line/>)
.add('Image', () => <Image/>)
.add('ImageTile', () => <ImageTile/>)
.add('Heatmap', () => <Heatmap/>)
.add('HeatmapGrid', () => <HeatmapGrid/>)
.add('HeatmapGrid3D', () => <HeatmapGrid3D/>)
.add('Hexgon', () => <Hexgon/>)
.add('Raster', () => <Raster/>)
.add('Text', () => <Text/>)