mirror of https://gitee.com/antv-l7/antv-l7
Merge branch 'master' of https://github.com/antvis/L7
This commit is contained in:
commit
8338df942e
|
@ -33,14 +33,14 @@ export default () => {
|
|||
'https://gw.alipayobjects.com/zos/bmw-prod/904d047a-16a5-461b-a921-98fa537fc04a.svg',
|
||||
);
|
||||
const data = await response.json();
|
||||
const newData = data.map((item: any) => {
|
||||
item.type = ['00', '01', '02'][Math.floor(Math.random() * 3)];
|
||||
const newData = data.map((item: any,index: number) => {
|
||||
item.type = ['00', '01', '02',''][index % 4];
|
||||
return item;
|
||||
});
|
||||
const imageLayer = new PointLayer({
|
||||
autoFit:false
|
||||
})
|
||||
.source(newData, {
|
||||
.source(newData.slice(0,4), {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'longitude',
|
||||
|
@ -52,25 +52,9 @@ export default () => {
|
|||
})
|
||||
.active(false)
|
||||
.size(20);
|
||||
|
||||
scene.addLayer(imageLayer);
|
||||
setInterval(()=>{
|
||||
scene.addImage(
|
||||
'00',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*g8cUQ7pPT9YAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'01',
|
||||
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*LTcXTLBM7kYAAAAAAAAAAAAAARQnAQ',
|
||||
);
|
||||
scene.addImage(
|
||||
'02',
|
||||
'https://gw.alipayobjects.com/zos/bmw-prod/904d047a-16a5-461b-a921-98fa537fc04a.svg',
|
||||
);
|
||||
const data = newData.slice(0,5+ Math.round(Math.random()*10));
|
||||
imageLayer.setData(data)
|
||||
console.log(imageLayer)
|
||||
console.log('更新')
|
||||
},3000)
|
||||
|
||||
|
||||
|
||||
}, []);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -298,20 +298,8 @@ export default class FontService extends EventEmitter implements IFontService {
|
|||
}
|
||||
|
||||
private getKey() {
|
||||
return 'key';
|
||||
const {
|
||||
fontFamily,
|
||||
fontWeight,
|
||||
fontSize,
|
||||
buffer,
|
||||
sdf,
|
||||
radius,
|
||||
cutoff,
|
||||
} = this.fontOptions;
|
||||
if (sdf) {
|
||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer} ${radius} ${cutoff} `;
|
||||
}
|
||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
|
||||
const { fontFamily, fontWeight } = this.fontOptions;
|
||||
return `${fontFamily}_${fontWeight}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,12 +5,7 @@ import 'reflect-metadata';
|
|||
import { buildIconMaping } from '../../utils/font_util';
|
||||
import { ITexture2D } from '../renderer/ITexture2D';
|
||||
import { ISceneService } from '../scene/ISceneService';
|
||||
import {
|
||||
IIcon,
|
||||
IICONMap,
|
||||
IIconService,
|
||||
IImage,
|
||||
} from './IIconService';
|
||||
import { IIcon, IICONMap, IIconService, IImage } from './IIconService';
|
||||
const BUFFER = 3;
|
||||
const MAX_CANVAS_WIDTH = 1024;
|
||||
const imageSize = 64;
|
||||
|
@ -47,8 +42,8 @@ export default class IconService extends EventEmitter implements IIconService {
|
|||
size: imageSize,
|
||||
});
|
||||
}
|
||||
this.updateIconMap();// 先存储 ID,
|
||||
imagedata = await this.loadImage(image) as HTMLImageElement;
|
||||
this.updateIconMap(); // 先存储 ID,
|
||||
imagedata = (await this.loadImage(image)) as HTMLImageElement;
|
||||
const iconImage = this.iconData.find((icon: IIcon) => {
|
||||
return icon.id === id;
|
||||
});
|
||||
|
@ -58,9 +53,8 @@ export default class IconService extends EventEmitter implements IIconService {
|
|||
iconImage.height = imagedata.height;
|
||||
}
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 适配小程序
|
||||
* @param id
|
||||
|
|
|
@ -12,17 +12,14 @@ import {
|
|||
import { getMask, PointFillTriangulation } from '@antv/l7-utils';
|
||||
import { isNumber } from 'lodash';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { IPointLayerStyleOptions } from '../../core/interface';
|
||||
import { IPointLayerStyleOptions, SizeUnitType } from '../../core/interface';
|
||||
// animate pointLayer shader - support animate
|
||||
import waveFillFrag from '../shaders/animate/wave_frag.glsl';
|
||||
// static pointLayer shader - not support animate
|
||||
import pointFillFrag from '../shaders/fill_frag.glsl';
|
||||
import pointFillVert from '../shaders/fill_vert.glsl';
|
||||
import { SizeUnitType } from '../../core/interface'
|
||||
|
||||
|
||||
export default class FillModel extends BaseModel {
|
||||
|
||||
public getUninforms(): IModelUniform {
|
||||
const {
|
||||
opacity = 1,
|
||||
|
@ -100,9 +97,8 @@ export default class FillModel extends BaseModel {
|
|||
};
|
||||
}
|
||||
public getAnimateUniforms(): IModelUniform {
|
||||
const {
|
||||
animateOption = { enable: false },
|
||||
} = this.layer.getLayerConfig() as ILayerConfig;
|
||||
const { animateOption = { enable: false } } =
|
||||
this.layer.getLayerConfig() as ILayerConfig;
|
||||
return {
|
||||
u_animate: this.animateOption2Array(animateOption),
|
||||
u_time: this.layer.getLayerAnimateTime(),
|
||||
|
@ -122,10 +118,10 @@ export default class FillModel extends BaseModel {
|
|||
}
|
||||
|
||||
public async initModels(): Promise<IModel[]> {
|
||||
return await this.buildModels();
|
||||
return this.buildModels();
|
||||
}
|
||||
|
||||
public async buildModels():Promise<IModel[]> {
|
||||
public async buildModels(): Promise<IModel[]> {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
|
@ -139,32 +135,33 @@ export default class FillModel extends BaseModel {
|
|||
const { frag, vert, type } = this.getShaders(animateOption);
|
||||
|
||||
this.layer.triangulation = PointFillTriangulation;
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: type,
|
||||
vertexShader: vert,
|
||||
fragmentShader: frag,
|
||||
triangulation: PointFillTriangulation,
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
workerEnabled,
|
||||
workerOptions: {
|
||||
modelType: type,
|
||||
enablePicking,
|
||||
shape2d,
|
||||
},
|
||||
});
|
||||
return [model];
|
||||
const model = await this.layer.buildLayerModel({
|
||||
moduleName: type,
|
||||
vertexShader: vert,
|
||||
fragmentShader: frag,
|
||||
triangulation: PointFillTriangulation,
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
workerEnabled,
|
||||
workerOptions: {
|
||||
modelType: type,
|
||||
enablePicking,
|
||||
shape2d,
|
||||
},
|
||||
});
|
||||
return [model];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 animateOption 的值返回对应的 shader 代码
|
||||
* @returns
|
||||
*/
|
||||
public getShaders(
|
||||
animateOption: Partial<IAnimateOption>,
|
||||
): { frag: string; vert: string; type: string } {
|
||||
public getShaders(animateOption: Partial<IAnimateOption>): {
|
||||
frag: string;
|
||||
vert: string;
|
||||
type: string;
|
||||
} {
|
||||
if (animateOption.enable) {
|
||||
switch (animateOption.type) {
|
||||
case 'wave':
|
||||
|
@ -242,9 +239,7 @@ export default class FillModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { size = 5 } = feature;
|
||||
return Array.isArray(size) ? [size[0]] : [size];
|
||||
},
|
||||
|
@ -264,9 +259,7 @@ export default class FillModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { shape = 2 } = feature;
|
||||
const shapeIndex = shape2d.indexOf(shape as string);
|
||||
return [shapeIndex];
|
||||
|
@ -274,6 +267,4 @@ export default class FillModel extends BaseModel {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -11,12 +11,11 @@ import {
|
|||
import { getCullFace, getMask } from '@antv/l7-utils';
|
||||
import { isNumber } from 'lodash';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { IPointLayerStyleOptions } from '../../core/interface';
|
||||
import { IPointLayerStyleOptions, SizeUnitType } from '../../core/interface';
|
||||
import { PointFillTriangulation } from '../../core/triangulation';
|
||||
// static pointLayer shader - not support animate
|
||||
import pointFillFrag from '../shaders/image/fillImage_frag.glsl';
|
||||
import pointFillVert from '../shaders/image/fillImage_vert.glsl';
|
||||
import { SizeUnitType } from '../../core/interface'
|
||||
|
||||
export default class FillImageModel extends BaseModel {
|
||||
private meter2coord: number = 1;
|
||||
|
@ -132,35 +131,29 @@ export default class FillImageModel extends BaseModel {
|
|||
);
|
||||
}
|
||||
|
||||
public async initModels():Promise<IModel[]> {
|
||||
public async initModels(): Promise<IModel[]> {
|
||||
this.iconService.on('imageUpdate', this.updateTexture);
|
||||
this.updateTexture();
|
||||
return await this.buildModels();
|
||||
return this.buildModels();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async buildModels():Promise<IModel[]> {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointFillImage',
|
||||
vertexShader: pointFillVert,
|
||||
fragmentShader: pointFillFrag,
|
||||
triangulation: PointFillTriangulation,
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
cull: {
|
||||
enable: true,
|
||||
face: getCullFace(this.mapService.version),
|
||||
},
|
||||
});
|
||||
return [model]
|
||||
|
||||
public async buildModels(): Promise<IModel[]> {
|
||||
const { mask = false, maskInside = true } =
|
||||
this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const model = await this.layer.buildLayerModel({
|
||||
moduleName: 'pointFillImage',
|
||||
vertexShader: pointFillVert,
|
||||
fragmentShader: pointFillFrag,
|
||||
triangulation: PointFillTriangulation,
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
cull: {
|
||||
enable: true,
|
||||
face: getCullFace(this.mapService.version),
|
||||
},
|
||||
});
|
||||
return [model];
|
||||
}
|
||||
|
||||
public clearModels() {
|
||||
|
@ -182,9 +175,7 @@ export default class FillImageModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { rotate = 0 } = feature;
|
||||
return Array.isArray(rotate) ? [rotate[0]] : [rotate as number];
|
||||
},
|
||||
|
@ -202,12 +193,10 @@ export default class FillImageModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 2,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const iconMap = this.iconService.getIconMap();
|
||||
const { shape } = feature;
|
||||
const { x, y } = iconMap[shape as string] || { x: 0, y: 0 };
|
||||
const { x, y } = iconMap[shape as string] || { x: -64, y: -64 };
|
||||
return [x, y];
|
||||
},
|
||||
},
|
||||
|
@ -256,13 +245,9 @@ export default class FillImageModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { size = 5 } = feature;
|
||||
return Array.isArray(size)
|
||||
? [size[0]]
|
||||
: [(size as number)];
|
||||
return Array.isArray(size) ? [size[0]] : [size as number];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -48,21 +48,21 @@ export default class ImageModel extends BaseModel {
|
|||
this.dataTexture =
|
||||
this.cellLength > 0 && data.length > 0
|
||||
? this.createTexture2D({
|
||||
flipY: true,
|
||||
data,
|
||||
format: gl.LUMINANCE,
|
||||
type: gl.FLOAT,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
flipY: true,
|
||||
data,
|
||||
format: gl.LUMINANCE,
|
||||
type: gl.FLOAT,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
: this.createTexture2D({
|
||||
flipY: true,
|
||||
data: [1],
|
||||
format: gl.LUMINANCE,
|
||||
type: gl.FLOAT,
|
||||
width: 1,
|
||||
height: 1,
|
||||
});
|
||||
flipY: true,
|
||||
data: [1],
|
||||
format: gl.LUMINANCE,
|
||||
type: gl.FLOAT,
|
||||
width: 1,
|
||||
height: 1,
|
||||
});
|
||||
}
|
||||
return {
|
||||
u_raisingHeight: Number(raisingHeight),
|
||||
|
@ -83,7 +83,7 @@ export default class ImageModel extends BaseModel {
|
|||
public async initModels(): Promise<IModel[]> {
|
||||
this.iconService.on('imageUpdate', this.updateTexture);
|
||||
this.updateTexture();
|
||||
return await this.buildModels();
|
||||
return this.buildModels();
|
||||
}
|
||||
|
||||
public clearModels() {
|
||||
|
@ -93,25 +93,21 @@ export default class ImageModel extends BaseModel {
|
|||
}
|
||||
|
||||
public async buildModels(): Promise<IModel[]> {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const { mask = false, maskInside = true } =
|
||||
this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointImage',
|
||||
vertexShader: pointImageVert,
|
||||
fragmentShader: pointImageFrag,
|
||||
triangulation: PointImageTriangulation,
|
||||
depth: { enable: false },
|
||||
primitive: gl.POINTS,
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
|
||||
return [model]
|
||||
const model = await this.layer.buildLayerModel({
|
||||
moduleName: 'pointImage',
|
||||
vertexShader: pointImageVert,
|
||||
fragmentShader: pointImageFrag,
|
||||
triangulation: PointImageTriangulation,
|
||||
depth: { enable: false },
|
||||
primitive: gl.POINTS,
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
|
||||
return [model];
|
||||
}
|
||||
protected registerBuiltinAttributes() {
|
||||
// point layer size;
|
||||
|
@ -127,9 +123,7 @@ export default class ImageModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { size = 5 } = feature;
|
||||
return Array.isArray(size) ? [size[0]] : [size as number];
|
||||
},
|
||||
|
@ -149,12 +143,10 @@ export default class ImageModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 2,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const iconMap = this.iconService.getIconMap();
|
||||
const { shape } = feature;
|
||||
const { x, y } = iconMap[shape as string] || { x: 0, y: 0 };
|
||||
const { x, y } = iconMap[shape as string] || { x: -64, y: -64 }; // 非画布区域,默认的图标改为透明
|
||||
return [x, y];
|
||||
},
|
||||
},
|
||||
|
@ -172,9 +164,10 @@ export default class ImageModel extends BaseModel {
|
|||
});
|
||||
// 更新完纹理后在更新的图层的时候需要更新所有的图层
|
||||
// this.layer.layerModelNeedUpdate = true;
|
||||
setTimeout(() => { // 延迟渲染
|
||||
setTimeout(() => {
|
||||
// 延迟渲染
|
||||
this.layerService.throttleRenderLayers();
|
||||
})
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getMask,
|
||||
padBounds,
|
||||
} from '@antv/l7-utils';
|
||||
import { isNumber } from 'lodash';
|
||||
import { isEqual, isNumber } from 'lodash';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { IPointLayerStyleOptions } from '../../core/interface';
|
||||
import CollisionIndex from '../../utils/collision-index';
|
||||
|
@ -102,9 +102,6 @@ export default class TextModel extends BaseModel {
|
|||
opacity = 1.0,
|
||||
stroke = '#fff',
|
||||
strokeWidth = 0,
|
||||
textAnchor = 'center',
|
||||
textOffset,
|
||||
textAllowOverlap = false,
|
||||
halo = 0.5,
|
||||
gamma = 2.0,
|
||||
raisingHeight = 0,
|
||||
|
@ -116,11 +113,7 @@ export default class TextModel extends BaseModel {
|
|||
this.textCount = Object.keys(mapping).length;
|
||||
}
|
||||
|
||||
this.preTextStyle = {
|
||||
textAnchor,
|
||||
textAllowOverlap,
|
||||
textOffset,
|
||||
};
|
||||
this.preTextStyle = this.getTextStyle();
|
||||
|
||||
if (
|
||||
this.dataTextureTest &&
|
||||
|
@ -176,85 +169,96 @@ export default class TextModel extends BaseModel {
|
|||
u_sdf_map: this.texture,
|
||||
u_halo_blur: halo,
|
||||
u_gamma_scale: gamma,
|
||||
u_sdf_map_size: [canvas?.width || 1, canvas?.height ||1],
|
||||
u_sdf_map_size: [canvas?.width || 1, canvas?.height || 1],
|
||||
};
|
||||
}
|
||||
|
||||
public async initModels():Promise<IModel[]> {
|
||||
|
||||
public async initModels(): Promise<IModel[]> {
|
||||
// 绑定事件
|
||||
this.bindEvent();
|
||||
this.extent = this.textExtent();
|
||||
const {
|
||||
textAnchor = 'center',
|
||||
textAllowOverlap = true,
|
||||
textOffset,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.preTextStyle = {
|
||||
textAnchor,
|
||||
textAllowOverlap,
|
||||
textOffset
|
||||
};
|
||||
return await this.buildModels();
|
||||
this.preTextStyle = this.getTextStyle();
|
||||
return this.buildModels();
|
||||
}
|
||||
|
||||
public async buildModels():Promise<IModel[]> {
|
||||
public async buildModels(): Promise<IModel[]> {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
textAllowOverlap = false
|
||||
textAllowOverlap = false,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
|
||||
|
||||
// this.mapping(); 重复调用
|
||||
this.initGlyph(); //
|
||||
this.updateTexture();
|
||||
if(!textAllowOverlap) {
|
||||
this.filterGlyphs();
|
||||
}
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
vertexShader: textVert,
|
||||
fragmentShader: textFrag,
|
||||
triangulation: TextTriangulation.bind(this),
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
return [model]
|
||||
|
||||
|
||||
// this.mapping(); 重复调用
|
||||
this.initGlyph(); //
|
||||
this.updateTexture();
|
||||
if (!textAllowOverlap) {
|
||||
this.filterGlyphs();
|
||||
}
|
||||
const model = await this.layer.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
vertexShader: textVert,
|
||||
fragmentShader: textFrag,
|
||||
triangulation: TextTriangulation.bind(this),
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
return [model];
|
||||
}
|
||||
|
||||
public async needUpdate():Promise<boolean> {
|
||||
// 需要更新的场景
|
||||
// 1. 文本偏移量发生改变
|
||||
// 2. 文本锚点发生改变
|
||||
// 3. 文本允许重叠发生改变
|
||||
// 4. 文本字体发生改变
|
||||
// 5. 文本字体粗细发生改变
|
||||
public async needUpdate(): Promise<boolean> {
|
||||
const {
|
||||
textAllowOverlap = false,
|
||||
textAnchor = 'center',
|
||||
textOffset
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const data = this.layer.getEncodedData();
|
||||
if(JSON.stringify(textOffset) !==JSON.stringify(this.preTextStyle.textOffset) ||textAnchor!==this.preTextStyle.textAnchor ) {
|
||||
textOffset,
|
||||
padding,
|
||||
fontFamily,
|
||||
fontWeight,
|
||||
} = this.getTextStyle() as IPointLayerStyleOptions;
|
||||
if (
|
||||
!isEqual(padding, this.preTextStyle.padding) ||
|
||||
!isEqual(textOffset, this.preTextStyle.textOffset) ||
|
||||
!isEqual(textAnchor, this.preTextStyle.textAnchor) ||
|
||||
!isEqual(fontFamily, this.preTextStyle.fontFamily) ||
|
||||
!isEqual(fontWeight, this.preTextStyle.fontWeight)
|
||||
) {
|
||||
await this.mapping();
|
||||
return true;
|
||||
}
|
||||
if(data.length < 5 || textAllowOverlap) { // 小于不做避让
|
||||
|
||||
// if (
|
||||
// JSON.stringify(textOffset) !==
|
||||
// JSON.stringify(this.preTextStyle.textOffset) ||
|
||||
// textAnchor !== this.preTextStyle.textAnchor
|
||||
// ) {
|
||||
// await this.mapping();
|
||||
// return true;
|
||||
// }
|
||||
if (textAllowOverlap) {
|
||||
// 小于不做避让
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// textAllowOverlap 发生改变
|
||||
const zoom = this.mapService.getZoom();
|
||||
const extent = this.mapService.getBounds();
|
||||
const flag = boundsContains(this.extent, extent);
|
||||
// 文本不能压盖则进行过滤
|
||||
if (
|
||||
((Math.abs(this.currentZoom - zoom) > 1 || !flag)) ||
|
||||
Math.abs(this.currentZoom - zoom) > 0.5 ||
|
||||
!flag ||
|
||||
textAllowOverlap !== this.preTextStyle.textAllowOverlap
|
||||
) {
|
||||
// TODO this.mapping 数据未变化,避让
|
||||
await this.reBuildModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -277,9 +281,7 @@ export default class TextModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { rotate = 0 } = feature;
|
||||
return Array.isArray(rotate) ? [rotate[0]] : [rotate as number];
|
||||
},
|
||||
|
@ -320,9 +322,7 @@ export default class TextModel extends BaseModel {
|
|||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
) => {
|
||||
update: (feature: IEncodeFeature) => {
|
||||
const { size = 12 } = feature;
|
||||
return Array.isArray(size) ? [size[0]] : [size as number];
|
||||
},
|
||||
|
@ -352,17 +352,17 @@ export default class TextModel extends BaseModel {
|
|||
}
|
||||
|
||||
private bindEvent() {
|
||||
if(!this.layer.isTileLayer) {
|
||||
if (!this.layer.isTileLayer) {
|
||||
// 重新绑定
|
||||
this.layer.on('remapping', this.mapping);
|
||||
}
|
||||
}
|
||||
|
||||
private mapping = async(): Promise<void> =>{
|
||||
private mapping = async (): Promise<void> => {
|
||||
this.initGlyph(); //
|
||||
this.updateTexture();
|
||||
await this.reBuildModel();
|
||||
}
|
||||
};
|
||||
|
||||
private textExtent(): [[number, number], [number, number]] {
|
||||
const bounds = this.mapService.getBounds();
|
||||
|
@ -372,10 +372,7 @@ export default class TextModel extends BaseModel {
|
|||
* 生成文字纹理(生成文字纹理字典)
|
||||
*/
|
||||
private initTextFont() {
|
||||
const {
|
||||
fontWeight = '400',
|
||||
fontFamily = 'sans-serif',
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const { fontWeight, fontFamily } = this.getTextStyle();
|
||||
const data = this.layer.getEncodedData();
|
||||
const characterSet: string[] = [];
|
||||
data.forEach((item: IEncodeFeature) => {
|
||||
|
@ -400,10 +397,7 @@ export default class TextModel extends BaseModel {
|
|||
* 生成 iconfont 纹理字典
|
||||
*/
|
||||
private initIconFontTex() {
|
||||
const {
|
||||
fontWeight = '400',
|
||||
fontFamily = 'sans-serif',
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const { fontWeight, fontFamily } = this.getTextStyle();
|
||||
const data = this.layer.getEncodedData();
|
||||
const characterSet: string[] = [];
|
||||
data.forEach((item: IEncodeFeature) => {
|
||||
|
@ -421,6 +415,33 @@ export default class TextModel extends BaseModel {
|
|||
});
|
||||
}
|
||||
|
||||
private getTextStyle() {
|
||||
const {
|
||||
fontWeight = '400',
|
||||
fontFamily = 'sans-serif',
|
||||
textAllowOverlap = false,
|
||||
padding = [0, 0],
|
||||
textAnchor = 'center',
|
||||
textOffset = [0, 0],
|
||||
opacity = 1,
|
||||
strokeOpacity = 1,
|
||||
strokeWidth = 0,
|
||||
stroke = '#000',
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
return {
|
||||
fontWeight,
|
||||
fontFamily,
|
||||
textAllowOverlap,
|
||||
padding,
|
||||
textAnchor,
|
||||
textOffset,
|
||||
opacity,
|
||||
strokeOpacity,
|
||||
strokeWidth,
|
||||
stroke,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成文字布局(对照文字纹理字典提取对应文字的位置很好信息)
|
||||
*/
|
||||
|
@ -435,7 +456,7 @@ export default class TextModel extends BaseModel {
|
|||
const data = this.layer.getEncodedData();
|
||||
|
||||
this.glyphInfo = data.map((feature: IEncodeFeature) => {
|
||||
const { shape = '', id, size = 1, } = feature;
|
||||
const { shape = '', id, size = 1 } = feature;
|
||||
|
||||
const shaping = shapeText(
|
||||
shape.toString(),
|
||||
|
@ -445,7 +466,7 @@ export default class TextModel extends BaseModel {
|
|||
textAnchor,
|
||||
'left',
|
||||
spacing,
|
||||
textOffset || feature.textOffset || [0,0],
|
||||
textOffset || feature.textOffset || [0, 0],
|
||||
iconfont,
|
||||
);
|
||||
const glyphQuads = getGlyphQuads(shaping, textOffset, false);
|
||||
|
@ -473,13 +494,10 @@ export default class TextModel extends BaseModel {
|
|||
* 文字避让 depend on originCentorid
|
||||
*/
|
||||
private filterGlyphs() {
|
||||
const {
|
||||
padding = [0, 0],
|
||||
textAllowOverlap = false,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const { padding = [0, 0], textAllowOverlap = false } =
|
||||
this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
if (textAllowOverlap) {
|
||||
// 如果允许文本覆盖
|
||||
// this.layer.setEncodedData(this.glyphInfo);
|
||||
return;
|
||||
}
|
||||
this.glyphInfoMap = {};
|
||||
|
@ -491,9 +509,11 @@ export default class TextModel extends BaseModel {
|
|||
const { shaping, id = 0 } = feature;
|
||||
// const centroid = feature.centroid as [number, number];
|
||||
// const centroid = feature.originCentroid as [number, number];
|
||||
const centroid = (feature.version === 'GAODE2.x'
|
||||
? feature.originCentroid
|
||||
: feature.centroid) as [number, number];
|
||||
const centroid = (
|
||||
feature.version === 'GAODE2.x'
|
||||
? feature.originCentroid
|
||||
: feature.centroid
|
||||
) as [number, number];
|
||||
const size = feature.size as number;
|
||||
const fontScale: number = size / 16;
|
||||
const pixels = this.mapService.lngLatToContainer(centroid);
|
||||
|
@ -525,8 +545,6 @@ export default class TextModel extends BaseModel {
|
|||
const { iconfont = false } = this.layer.getLayerConfig();
|
||||
// 1.生成文字纹理(或是生成 iconfont)
|
||||
iconfont ? this.initIconFontTex() : this.initTextFont();
|
||||
// this.initTextFont();
|
||||
|
||||
// 2.生成文字布局
|
||||
this.generateGlyphLayout(iconfont);
|
||||
}
|
||||
|
@ -550,22 +568,19 @@ export default class TextModel extends BaseModel {
|
|||
}
|
||||
|
||||
private async reBuildModel() {
|
||||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.filterGlyphs();
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
vertexShader: textVert,
|
||||
fragmentShader: textFrag,
|
||||
triangulation: TextTriangulation.bind(this),
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
// TODO 渲染流程待修改
|
||||
this.layer.models = [model];
|
||||
const { mask = false, maskInside = true } =
|
||||
this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.filterGlyphs();
|
||||
const model = await this.layer.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
vertexShader: textVert,
|
||||
fragmentShader: textFrag,
|
||||
triangulation: TextTriangulation.bind(this),
|
||||
depth: { enable: false },
|
||||
blend: this.getBlend(),
|
||||
stencil: getMask(mask, maskInside),
|
||||
});
|
||||
// TODO 渲染流程待修改
|
||||
this.layer.models = [model];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ layer.scale('value'); // L7 能够自动推断为 identify
|
|||
|
||||
```ts
|
||||
|
||||
pointLayer.size('type', (type) => {
|
||||
pointLayer.filter('type', (type) => {
|
||||
// 回调函数
|
||||
if (type === 'a') {
|
||||
return false;
|
||||
|
|
|
@ -1,133 +1,159 @@
|
|||
|
||||
import { IRasterData } from '../../interface';
|
||||
|
||||
/** 数学运算 根据计算表达式进行数学运算
|
||||
* * * Math operators:
|
||||
* `['*', value1, value2]`
|
||||
* `['*', value1, value2]`
|
||||
* `['/', value1, value2]`
|
||||
* `['+', value1, value2]`
|
||||
* `['-', value1, value2]`
|
||||
* `['%', value1, value2]`
|
||||
* `['^', value1, value2]`
|
||||
* `['abs', value1]`
|
||||
* `['floor', value1]`
|
||||
* `['round', value1]`
|
||||
* `['ceil', value1]`
|
||||
* `['sin', value1]`
|
||||
* `['cos', value1]`
|
||||
* `['atan', value1, value2]`
|
||||
* `['+', value1, value2]`
|
||||
* `['-', value1, value2]`
|
||||
* `['%', value1, value2]`
|
||||
* `['^', value1, value2]`
|
||||
* `['abs', value1]`
|
||||
* `['floor', value1]`
|
||||
* `['round', value1]`
|
||||
* `['ceil', value1]`
|
||||
* `['sin', value1]`
|
||||
* `['cos', value1]`
|
||||
* `['atan', value1, value2]`
|
||||
*/
|
||||
export function mathematical(symbol: string, n1: number, n2: number) {
|
||||
switch(symbol) {
|
||||
case '+': return n1 + n2;
|
||||
case '-': return n1 - n2;
|
||||
case '*': return n1 * n2;
|
||||
case '/': return n1 / n2;
|
||||
case '%': return n1 % n2;
|
||||
export function mathematical(symbol: string, n1: number, n2: number) {
|
||||
switch (symbol) {
|
||||
case '+':
|
||||
return n1 + n2;
|
||||
case '-':
|
||||
return n1 - n2;
|
||||
case '*':
|
||||
return n1 * n2;
|
||||
case '/':
|
||||
return n1 / n2;
|
||||
case '%':
|
||||
return n1 % n2;
|
||||
|
||||
case '^': return Math.pow(n1, n2);
|
||||
case 'abs': return Math.abs(n1);
|
||||
case 'floor': return Math.floor(n1);
|
||||
case 'round': return Math.round(n1);
|
||||
case 'ceil': return Math.ceil(n1);
|
||||
case 'sin': return Math.sin(n1);
|
||||
case 'cos': return Math.cos(n1);
|
||||
case 'atan': return (n2 === -1) ? Math.atan(n1): Math.atan2(n1, n2);
|
||||
|
||||
default:
|
||||
console.warn('Calculate symbol err! Return default 0');
|
||||
return 0;
|
||||
}
|
||||
case '^':
|
||||
return Math.pow(n1, n2);
|
||||
case 'abs':
|
||||
return Math.abs(n1);
|
||||
case 'floor':
|
||||
return Math.floor(n1);
|
||||
case 'round':
|
||||
return Math.round(n1);
|
||||
case 'ceil':
|
||||
return Math.ceil(n1);
|
||||
case 'sin':
|
||||
return Math.sin(n1);
|
||||
case 'cos':
|
||||
return Math.cos(n1);
|
||||
case 'atan':
|
||||
return n2 === -1 ? Math.atan(n1) : Math.atan2(n1, n2);
|
||||
case 'min':
|
||||
return Math.min(n1, n2);
|
||||
case 'max':
|
||||
return Math.max(n1, n2);
|
||||
case 'log10':
|
||||
return Math.log(n1);
|
||||
case 'log2':
|
||||
return Math.log2(n1);
|
||||
default:
|
||||
console.warn('Calculate symbol err! Return default 0');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表达式计算
|
||||
* @param express
|
||||
* @param bandsData
|
||||
* @param express
|
||||
* @param bandsData
|
||||
*/
|
||||
export function calculate(express: any[], bandsData: IRasterData[]) {
|
||||
const {width, height} = bandsData[0];
|
||||
const dataArray = bandsData.map(band => band.rasterData) as Uint8Array[];
|
||||
const length = width * height;
|
||||
const rasterData = [];
|
||||
const originExp = JSON.stringify(express);
|
||||
for(let i = 0;i < length; i++) {
|
||||
const exp = JSON.parse(originExp);
|
||||
// 将表达式中的 ['band', 0]、['band', 1] 等替换为实际的栅格数据
|
||||
const expResult = spellExpress(exp, dataArray, i);
|
||||
if(typeof expResult === 'number') {
|
||||
// exp: ['band', 0] => exp: 2 ...
|
||||
// exp 直接指定了波段值,替换完后直接就是数值了,无需计算
|
||||
rasterData.push(expResult);
|
||||
} else {
|
||||
const result = calculateExpress(exp);
|
||||
rasterData.push(result);
|
||||
}
|
||||
|
||||
const { width, height } = bandsData[0];
|
||||
const dataArray = bandsData.map((band) => band.rasterData) as Uint8Array[];
|
||||
const length = width * height;
|
||||
const rasterData = [];
|
||||
const originExp = JSON.stringify(express);
|
||||
for (let i = 0; i < length; i++) {
|
||||
const exp = JSON.parse(originExp);
|
||||
// 将表达式中的 ['band', 0]、['band', 1] 等替换为实际的栅格数据
|
||||
const expResult = spellExpress(exp, dataArray, i);
|
||||
if (typeof expResult === 'number') {
|
||||
// exp: ['band', 0] => exp: 2 ...
|
||||
// exp 直接指定了波段值,替换完后直接就是数值了,无需计算
|
||||
rasterData.push(expResult);
|
||||
} else {
|
||||
const result = calculateExpress(exp);
|
||||
rasterData.push(result);
|
||||
}
|
||||
return rasterData as unknown as Uint8Array;
|
||||
}
|
||||
return rasterData as unknown as Uint8Array;
|
||||
}
|
||||
|
||||
type IExpress = any[];
|
||||
|
||||
/**
|
||||
* 将表达式中的指定波段替换为对应波段的栅格数据
|
||||
* @param express
|
||||
* @param dataArray
|
||||
* @param index
|
||||
* @param express
|
||||
* @param dataArray
|
||||
* @param index
|
||||
*/
|
||||
export function spellExpress(express: IExpress, dataArray: Uint8Array[], index: number) {
|
||||
/**
|
||||
* 用户直接指定波段数值,无需计算
|
||||
*/
|
||||
if(express.length === 2 && express[0] === 'band' && typeof express[1] === 'number') {
|
||||
try {
|
||||
return dataArray[express[1]][index];
|
||||
} catch(err) {
|
||||
console.warn('Raster Data err!');
|
||||
return 0;
|
||||
}
|
||||
export function spellExpress(
|
||||
express: IExpress,
|
||||
dataArray: Uint8Array[],
|
||||
index: number,
|
||||
) {
|
||||
/**
|
||||
* 用户直接指定波段数值,无需计算
|
||||
*/
|
||||
if (
|
||||
express.length === 2 &&
|
||||
express[0] === 'band' &&
|
||||
typeof express[1] === 'number'
|
||||
) {
|
||||
try {
|
||||
return dataArray[express[1]][index];
|
||||
} catch (err) {
|
||||
console.warn('Raster Data err!');
|
||||
return 0;
|
||||
}
|
||||
express.map((e, i) => {
|
||||
if(Array.isArray(e) && e.length > 0) {
|
||||
switch(e[0]) {
|
||||
case 'band':
|
||||
try {
|
||||
express[i] = dataArray[e[1]][index];
|
||||
} catch(err) {
|
||||
console.warn('Raster Data err!');
|
||||
express[i] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
spellExpress(e, dataArray, index);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
express.map((e, i) => {
|
||||
if (Array.isArray(e) && e.length > 0) {
|
||||
switch (e[0]) {
|
||||
case 'band':
|
||||
try {
|
||||
express[i] = dataArray[e[1]][index];
|
||||
} catch (err) {
|
||||
console.warn('Raster Data err!');
|
||||
express[i] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
spellExpress(e, dataArray, index);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function formatExpress(express: IExpress) {
|
||||
const [symbol1, symbol2 = -1, symbol3 = -1] = express;
|
||||
if(symbol1 === undefined) {
|
||||
console.warn('Express err!')
|
||||
return ['+', 0, 0];
|
||||
}
|
||||
const symbol = symbol1.replace(/\s+/g, '');
|
||||
const [symbol1, symbol2 = -1, symbol3 = -1] = express;
|
||||
if (symbol1 === undefined) {
|
||||
console.warn('Express err!');
|
||||
return ['+', 0, 0];
|
||||
}
|
||||
const symbol = symbol1.replace(/\s+/g, '');
|
||||
|
||||
return [symbol, symbol2, symbol3];
|
||||
return [symbol, symbol2, symbol3];
|
||||
}
|
||||
|
||||
export function calculateExpress(express: IExpress) {
|
||||
const formatExp = formatExpress(express);
|
||||
const str = formatExp[0];
|
||||
let left = formatExp[1];
|
||||
let right = formatExp[2];
|
||||
|
||||
if(Array.isArray(left)) {
|
||||
left = calculateExpress(express[1]);
|
||||
}
|
||||
if(Array.isArray(right)) {
|
||||
right = calculateExpress(express[2]);
|
||||
}
|
||||
return mathematical(str, left, right);
|
||||
}
|
||||
const formatExp = formatExpress(express);
|
||||
const str = formatExp[0];
|
||||
let left = formatExp[1];
|
||||
let right = formatExp[2];
|
||||
|
||||
if (Array.isArray(left)) {
|
||||
left = calculateExpress(express[1]);
|
||||
}
|
||||
if (Array.isArray(right)) {
|
||||
right = calculateExpress(express[2]);
|
||||
}
|
||||
return mathematical(str, left, right);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as d3 from 'd3-color';
|
|||
import { Context } from 'vm';
|
||||
import { $window, isMini } from './mini-adapter';
|
||||
export interface IColorRamp {
|
||||
type?: 'cat' | 'linear' | 'quantize' | 'custom'
|
||||
type?: 'cat' | 'linear' | 'quantize' | 'custom';
|
||||
positions: number[];
|
||||
colors: string[];
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ export function generateColorRamp(
|
|||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 256, 1);
|
||||
|
||||
|
||||
if (!isMini) {
|
||||
data = ctx.getImageData(0, 0, 256, 1).data;
|
||||
// 使用 createImageData 替代 new ImageData、兼容 IE11
|
||||
|
@ -114,8 +113,7 @@ export function generateLinearRamp(
|
|||
const step = domain[1] - domain[0];
|
||||
|
||||
for (let i = 0; i < colorRamp.colors.length; ++i) {
|
||||
const value = Math.max((colorRamp.positions[i] - domain[0]) / step,0);
|
||||
console.log(value)
|
||||
const value = Math.max((colorRamp.positions[i] - domain[0]) / step, 0);
|
||||
gradient.addColorStop(value, colorRamp.colors[i]);
|
||||
}
|
||||
ctx.fillStyle = gradient;
|
||||
|
@ -127,16 +125,11 @@ export function generateLinearRamp(
|
|||
canvas = null;
|
||||
// @ts-ignore
|
||||
ctx = null;
|
||||
return imageData
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
||||
|
||||
// 枚举类型
|
||||
export function generateCatRamp(
|
||||
colorRamp: IColorRamp,
|
||||
): ImageData | IImagedata {
|
||||
|
||||
export function generateCatRamp(colorRamp: IColorRamp): ImageData | IImagedata {
|
||||
let canvas = $window.document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
canvas.width = 256;
|
||||
|
@ -144,12 +137,12 @@ export function generateCatRamp(
|
|||
const imageData = ctx.createImageData(256, 1);
|
||||
imageData.data.fill(0);
|
||||
colorRamp.positions.forEach((p: number, index: number) => {
|
||||
const colorArray = rgb2arr(colorRamp.colors[index])
|
||||
const colorArray = rgb2arr(colorRamp.colors[index]);
|
||||
imageData.data[p * 4 + 0] = colorArray[0] * 255;
|
||||
imageData.data[p * 4 + 1] = colorArray[1] * 255;
|
||||
imageData.data[p * 4 + 2] = colorArray[2] * 255;
|
||||
imageData.data[p * 4 + 3] = colorArray[3] * 255;
|
||||
})
|
||||
});
|
||||
// @ts-ignore
|
||||
canvas = null;
|
||||
// @ts-ignore
|
||||
|
@ -163,10 +156,10 @@ export function generateQuantizeRamp(
|
|||
): ImageData | IImagedata {
|
||||
let canvas = $window.document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
ctx.globalAlpha = 1.0
|
||||
ctx.globalAlpha = 1.0;
|
||||
canvas.width = 256;
|
||||
canvas.height = 1;
|
||||
const step = 256 / colorRamp.colors.length;// TODO 精度问题
|
||||
const step = 256 / colorRamp.colors.length; // TODO 精度问题
|
||||
// draw linear color
|
||||
for (let i = 0; i < colorRamp.colors.length; i++) {
|
||||
ctx.beginPath();
|
||||
|
@ -176,14 +169,12 @@ export function generateQuantizeRamp(
|
|||
ctx.moveTo(i * step, 0); // positioned at 50,25
|
||||
ctx.lineTo((i + 1) * step, 0);
|
||||
ctx.stroke();
|
||||
|
||||
}
|
||||
|
||||
const data = ctx.getImageData(0, 0, 256, 1).data;
|
||||
// 使用 createImageData 替代 new ImageData、兼容 IE11
|
||||
const imageData = toIEIMageData(ctx, data);
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
canvas = null;
|
||||
// @ts-ignore
|
||||
|
@ -197,25 +188,25 @@ export function generateCustomRamp(
|
|||
colorRamp: IColorRamp,
|
||||
domain: [number, number],
|
||||
): ImageData | IImagedata {
|
||||
|
||||
let canvas = $window.document.createElement('canvas');
|
||||
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
ctx.globalAlpha = 1.0
|
||||
ctx.globalAlpha = 1.0;
|
||||
canvas.width = 256;
|
||||
canvas.height = 1;
|
||||
const step = domain[1] - domain[0];
|
||||
if(colorRamp.positions.length - colorRamp.colors.length !==1) {
|
||||
console.warn('positions 的数字个数应当比 colors 的样式多一个,poisitions 的首尾值一般为数据的最大最新值')
|
||||
if (colorRamp.positions.length - colorRamp.colors.length !== 1) {
|
||||
console.warn(
|
||||
'positions 的数字个数应当比 colors 的样式多一个,poisitions 的首尾值一般为数据的最大最新值',
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 0; i < colorRamp.colors.length; i++) {
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = colorRamp.colors[i];
|
||||
ctx.moveTo((colorRamp.positions[i] - domain[0]) / step * 255, 0); // positioned at 50,25
|
||||
ctx.lineTo((colorRamp.positions[i + 1]- domain[0]) / step * 255, 0);
|
||||
ctx.moveTo(((colorRamp.positions[i] - domain[0]) / step) * 255, 0); // positioned at 50,25
|
||||
ctx.lineTo(((colorRamp.positions[i + 1] - domain[0]) / step) * 255, 0);
|
||||
ctx.stroke();
|
||||
|
||||
}
|
||||
const data = ctx.getImageData(0, 0, 256, 1).data;
|
||||
const imageData = toIEIMageData(ctx, data);
|
||||
|
@ -233,15 +224,15 @@ function toIEIMageData(ctx: Context, data: Uint8ClampedArray) {
|
|||
imageData.data[i + 2] = data[i + 2];
|
||||
imageData.data[i + 3] = data[i + 3];
|
||||
}
|
||||
return imageData
|
||||
return imageData;
|
||||
}
|
||||
|
||||
export function getDefaultDomain(rampColors:IColorRamp) {
|
||||
export function getDefaultDomain(rampColors: IColorRamp) {
|
||||
switch (rampColors.type) {
|
||||
case 'cat' :
|
||||
return [0,255]
|
||||
default:
|
||||
[0,1]
|
||||
case 'cat':
|
||||
return [0, 255];
|
||||
default:
|
||||
[0, 1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +1,19 @@
|
|||
// @ts-ignore
|
||||
export { djb2hash, BKDRHash } from './hash';
|
||||
|
||||
import * as DOM from './dom';
|
||||
import * as Satistics from './statistics';
|
||||
|
||||
export { DOM, Satistics };
|
||||
|
||||
export * from './mini-adapter/index';
|
||||
export * from './ajax';
|
||||
export * from './geo';
|
||||
export * from './lru_cache';
|
||||
export * from './event';
|
||||
export * from './color';
|
||||
export * from './anchor';
|
||||
export * from './stencli';
|
||||
export * from './worker-helper';
|
||||
export * from './color';
|
||||
export * from './cull';
|
||||
export * as DOM from './dom';
|
||||
export * from './env';
|
||||
export * from './tileset-manager';
|
||||
export * from './workers/triangulation';
|
||||
export * from './event';
|
||||
export * from './geo';
|
||||
export { BKDRHash, djb2hash } from './hash';
|
||||
export * from './lineAtOffset';
|
||||
export * from './lru_cache';
|
||||
export * from './mini-adapter/index';
|
||||
export * as Satistics from './statistics';
|
||||
export * from './stencli';
|
||||
export * from './tileset-manager';
|
||||
export * from './worker-helper';
|
||||
export * from './workers/triangulation';
|
||||
|
||||
|
|
Loading…
Reference in New Issue