feat: 样式数据映射 1.2 代码结构优化

This commit is contained in:
2912401452 2021-06-22 20:58:12 +08:00
parent 535665ba31
commit 3b06bd6738
9 changed files with 448 additions and 424 deletions

View File

@ -12,7 +12,7 @@ import pickingVert from '../../shaders/picking.vert.glsl';
import project from '../../shaders/project.glsl';
import projection from '../../shaders/projection.glsl';
import sdf2d from '../../shaders/sdf_2d.glsl';
// import styleTextureMapping_frag from '../../shaders/styleTextureMapping_frag.glsl'
import styleMapping from '../../shaders/styleMapping.glsl';
const precisionRegExp = /precision\s+(high|low|medium)p\s+float/;
const globalDefaultprecision =
@ -34,7 +34,7 @@ export default class ShaderModuleService implements IShaderModuleService {
this.registerModule('lighting', { vs: lighting, fs: '' });
this.registerModule('light', { vs: light, fs: '' });
this.registerModule('picking', { vs: pickingVert, fs: pickingFrag });
// this.registerModule('styleTextureMapping_frag', { vs: '', fs: styleTextureMapping_frag });
this.registerModule('styleMapping', { vs: styleMapping, fs: '' });
}
public registerModule(moduleName: string, moduleParams: IModuleParams) {

View File

@ -0,0 +1,95 @@
attribute float a_vertexId;
uniform mat4 u_cellTypeLayout; // 描述数据纹理 cell 结构的矩阵
uniform sampler2D u_dataTexture; // 数据纹理
bool hasOpacity() { // 判断 cell 中是否存在 opacity 的数据
return u_cellTypeLayout[1][0] > 0.0;
}
bool hasStrokeOpacity() { // 判断 cell 中是否存在 strokeOpacity 的数据
return u_cellTypeLayout[1][1] > 0.0;
}
bool hasStrokeWidth() { // 判断 cell 中是否存在 strokeWidth 的数据
return u_cellTypeLayout[1][2] > 0.0;
}
bool hasStroke() { // 判断 cell 中是否存在 stroke 的数据
return u_cellTypeLayout[1][3] > 0.0;
}
bool hasOffsets() { // 判断 cell 中是否存在 offsets 的数据
return u_cellTypeLayout[2][0] > 0.0;
}
// 根据坐标位置先是计算 uv ,然后根据 uv 从数据纹理中取值
float pos2value(vec2 pos, float columnWidth, float rowHeight) {
float u = (pos.r - 1.0) * columnWidth + columnWidth/2.0;
float v = 1.0 - ((pos.g - 1.0) * rowHeight + rowHeight/2.0);
return texture2D(u_dataTexture, vec2(u, v)).r;
}
/*
currentRow 当前行
currentColumn 当前列
columnCount 有多少列
nextStep 需要计算当前 cell 后的第几个 cell (当前 cell 则 nextStep = 0
*/
vec2 nextPos(float currentRow, float currentColumn, float columnCount, float nextStep) {
float nextColumn = currentColumn;
float nextRow = currentRow;
if(currentColumn + nextStep <= columnCount){
nextColumn = currentColumn + nextStep;
} else {
nextColumn = mod(currentColumn + nextStep, columnCount); // 不会出现跨两行
nextRow = currentRow + 1.0;
}
return vec2(nextColumn, nextRow);
}
// 计算 opacity 和标示在 cell 中取值位置的偏移量 textureOffset
vec2 calOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasOpacity()) { // 数据纹理中不存在 opacity 的时候取默认值(用户在 style 中传入的是常量)
return vec2(u_opacity, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureOpacity = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureOpacity, textureOffset + 1.0);
}
}
// 计算 strokeOpaicty 和标示在 cell 中取值位置的偏移量 textureOffset
vec2 calStrokeOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasStrokeOpacity()) {
return vec2(u_stroke_opacity, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureStrokeOpacity = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureStrokeOpacity, textureOffset + 1.0);
}
}
// 计算 strokeWidth 和标示在 cell 中取值位置的偏移量 textureOffset
vec2 calStrokeWidthAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasStrokeWidth()) {
return vec2(u_stroke_width, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureStrokeWidth = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureStrokeWidth, textureOffset + 1.0);
}
}
// 计算当前单个 cell 的大小
float calCellCount() {
// u_cellTypeLayout
// cal_height, WIDTH, 0.0, 0.0, // rowCount columnCount - 几行几列
// 1.0, 1.0, 1.0, 0.0, // opacity strokeOpacity strokeWidth stroke - 1.0 表示有数据映射、0.0 表示没有
// 1.0, 0.0, 0.0, 0.0, // offsets
// 0.0, 0.0, 0.0, 0.0
return u_cellTypeLayout[1][0] + // opacity
u_cellTypeLayout[1][1] + // strokeOpacity
u_cellTypeLayout[1][2] + // strokeWidth
u_cellTypeLayout[1][3] * 4.0 + // stroke
u_cellTypeLayout[2][0] * 2.0; // offsets
}

View File

@ -1,10 +1,12 @@
import {
BlendType,
gl,
IAnimateOption,
IAttribute,
IBlendOptions,
ICameraService,
IElements,
IEncodeFeature,
IFontService,
IGlobalConfigService,
IIconService,
@ -24,13 +26,34 @@ import {
Triangulation,
TYPES,
} from '@antv/l7-core';
import { isColor, rgb2arr } from '@antv/l7-utils';
import { rgb2arr } from '@antv/l7-utils';
import { color } from 'd3-color';
import { isArray, isEqual, isFunction, isNumber, isString } from 'lodash';
import { BlendTypes } from '../utils/blend';
interface ICellProperty {
attr: string;
count: number;
}
export type styleSingle =
| number
| string
| [string, (single: any) => number]
| [string, [number, number]];
export type styleOffset =
| string
| [number, number]
| [string, (single: any) => number];
export type styleColor =
| string
| [string, (single: any) => string]
| [string, [string, string]];
export interface IDataTextureFrame {
data: number[];
width: number;
height: number;
}
export default class BaseModel<ChildLayerStyleOptions = {}>
implements ILayerModel {
public triangulation: Triangulation;
@ -41,13 +64,15 @@ export default class BaseModel<ChildLayerStyleOptions = {}>
) => ITexture2D;
protected layer: ILayer;
protected defaultDataTexture: ITexture2D; // 默认的数据纹理
protected dataTexture: ITexture2D; // 用于数据传递的数据纹理
protected DATA_TEXTURE_WIDTH: number; // 默认有多少列(宽度)
protected rowCount: number; // 计算得到的当前数据纹理有多少行(高度)
protected curretnOpacity: any = ''; // 当前的 opacity 值
protected curretnStrokeOpacity: any = ''; // 当前的 strokeOpacity 值
protected currentStrokeColor: any = ''; // 当前的 strokeColor 值
protected currentStrokeWidth: any = ''; // 当前的 strokeWidth 值
protected currentOffsets: any = ''; // 当前的 strokeOffsets 值
protected curretnOpacity: styleSingle | undefined = undefined; // 当前的 opacity 值
protected curretnStrokeOpacity: styleSingle | undefined = undefined; // 当前的 strokeOpacity 值
protected currentStrokeColor: styleColor | undefined = undefined; // 当前的 strokeColor 值
protected currentStrokeWidth: styleSingle | undefined = undefined; // 当前的 strokeWidth 值
protected currentOffsets: styleOffset | undefined = undefined; // 当前的 strokeOffsets 值
protected cellLength: number; // 单个 cell 的长度
protected cellProperties: ICellProperty[]; // 需要进行数据映射的属性集合
protected hasOpacity: number = 0;
@ -111,10 +136,161 @@ export default class BaseModel<ChildLayerStyleOptions = {}>
this.rowCount = 1;
this.cellLength = 0;
this.cellProperties = [];
this.defaultDataTexture = createTexture2D({
flipY: true,
data: [1],
format: gl.LUMINANCE,
type: gl.FLOAT,
width: 1,
height: 1,
});
}
// style datatexture mapping
/**
* -
*/
public clearLastCalRes() {
this.cellProperties = []; // 清空上一次计算的需要进行数据映射的属性集合
this.cellLength = 0; // 清空上一次计算的 cell 的长度
this.hasOpacity = 0; // 清空上一次是否需要对 opacity 属性进行数据映射的判断
this.hasStrokeOpacity = 0; // 清空上一次是否需要对 strokeOpacity 属性进行数据映射的判断
this.hasStrokeWidth = 0; // 清空上一次是否需要对 strokeWidth 属性进行数据映射的判断
this.hasStroke = 0; // 清空上一次是否需要对 stroke 属性进行数据映射的判断
this.hasOffsets = 0; // 清空上一次是否需要对 offsets 属性进行数据映射的判断
}
/**
* -
* @param options
* @returns
*/
public dataTextureNeedUpdate(options: {
opacity?: styleSingle;
strokeOpacity?: styleSingle;
strokeWidth?: styleSingle;
stroke?: styleColor;
offsets?: styleOffset;
}): boolean {
let isUpdate = false;
if (!isEqual(options.opacity, this.curretnOpacity)) {
isUpdate = true;
this.curretnOpacity = options.opacity;
}
if (!isEqual(options.strokeOpacity, this.curretnStrokeOpacity)) {
isUpdate = true;
this.curretnStrokeOpacity = options.strokeOpacity;
}
if (!isEqual(options.strokeWidth, this.currentStrokeWidth)) {
isUpdate = true;
this.currentStrokeWidth = options.strokeWidth;
}
if (!isEqual(options.stroke, this.currentStrokeColor)) {
isUpdate = true;
this.currentStrokeColor = options.stroke;
}
if (!isEqual(options.offsets, this.currentOffsets)) {
isUpdate = true;
this.currentOffsets = options.offsets;
}
if (this.defaultDataTexture) {
isUpdate = true;
}
if (this.dataTexture === undefined) {
isUpdate = true;
}
return isUpdate;
}
/**
*
* @param options
*/
public judgeStyleAttributes(options: {
opacity?: styleSingle;
strokeOpacity?: styleSingle;
strokeWidth?: styleSingle;
stroke?: styleColor;
offsets?: styleOffset;
}) {
this.clearLastCalRes(); // 清除上一次的计算结果 - 全量清除
if (options.opacity !== undefined && !isNumber(options.opacity)) {
// 数据映射
this.cellProperties.push({ attr: 'opacity', count: 1 });
this.hasOpacity = 1;
this.cellLength += 1;
}
if (
options.strokeOpacity !== undefined &&
!isNumber(options.strokeOpacity)
) {
// 数据映射
this.cellProperties.push({ attr: 'strokeOpacity', count: 1 });
this.hasStrokeOpacity = 1;
this.cellLength += 1;
}
if (options.strokeWidth !== undefined && !isNumber(options.strokeWidth)) {
// 数据映射
this.cellProperties.push({ attr: 'strokeWidth', count: 1 });
this.hasStrokeWidth = 1;
this.cellLength += 1;
}
if (options.stroke !== undefined && !this.isStaticColor(options.stroke)) {
// 数据映射
this.cellProperties.push({ attr: 'stroke', count: 4 });
this.cellLength += 4;
this.hasStroke = 1;
}
if (
options.offsets !== undefined &&
!this.isOffsetStatic(options.offsets)
) {
// 数据映射
this.cellProperties.push({ attr: 'offsets', count: 2 });
this.cellLength += 2;
this.hasOffsets = 1;
}
}
/**
* stroke
* @param stroke
* @returns
*/
public isStaticColor(stroke: styleColor): boolean {
if (isString(stroke)) {
if (color(stroke)) {
return true;
} else {
return false;
}
}
return false;
}
/**
* offsets
* @param offsets
* @returns
*/
public isOffsetStatic(offsets: styleOffset) {
if (
isArray(offsets) &&
offsets.length === 2 &&
isNumber(offsets[0]) &&
isNumber(offsets[1])
) {
return true;
} else {
return false;
}
}
/**
*
* @param d
@ -132,34 +308,29 @@ export default class BaseModel<ChildLayerStyleOptions = {}>
* @param cellData
* @param cellPropertiesLayouts
*/
public patchData(d: number[], cellData: any, cellPropertiesLayouts: any) {
public patchData(
d: number[],
cellData: IEncodeFeature,
cellPropertiesLayouts: ICellProperty[],
) {
for (const layout of cellPropertiesLayouts) {
const { attr, count } = layout;
if (!cellData) {
const value = cellData[attr];
if (value) {
// 数据中存在该属性
if (attr === 'stroke') {
d.push(-1, -1, -1, -1);
d.push(...rgb2arr(value));
} else if (attr === 'offsets') {
d.push(-1, -1);
// d.push(...value)
d.push(-value[0], value[1]);
} else {
d.push(-1);
d.push(value);
}
} else {
const value = cellData[attr];
if (value) {
// 数据中存在该属性
if (attr === 'stroke') {
d.push(...rgb2arr(value));
} else if (attr === 'offsets') {
// d.push(...value)
d.push(-value[0], value[1]);
} else {
d.push(value);
}
} else {
// 若不存在时则补位
this.patchMod(d, count);
}
// 若不存在时则补位
this.patchMod(d, count);
}
}
}
@ -173,14 +344,9 @@ export default class BaseModel<ChildLayerStyleOptions = {}>
*/
public calDataFrame(
cellLength: number,
encodeData: any,
cellPropertiesLayouts: any,
): any {
if (cellLength > this.DATA_TEXTURE_WIDTH) {
// console.log('failed');
return false;
}
encodeData: IEncodeFeature[],
cellPropertiesLayouts: ICellProperty[],
): IDataTextureFrame {
const encodeDatalength = encodeData.length;
const rowCount = Math.ceil(
(encodeDatalength * cellLength) / this.DATA_TEXTURE_WIDTH,

View File

@ -91,25 +91,28 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin {
},
},
});
// styleAttributeService.registerStyleAttribute({
// name: 'strokeOpacity',
// type: AttributeType.Attribute,
// descriptor: {
// name: 'a_stroke_opacity',
// buffer: {
// // give the WebGL driver a hint that this buffer may change
// usage: gl.DYNAMIC_DRAW,
// data: [],
// type: gl.FLOAT,
// },
// size: 1,
// update: (feature: IEncodeFeature, featureIdx: number) => {
// const { strokeOpacity } = feature;
// // console.log('feature', feature)
// // console.log('strokeOpacity', strokeOpacity)
// return !isNumber(strokeOpacity) ? [1.0] : [strokeOpacity];
// },
// },
// });
styleAttributeService.registerStyleAttribute({
// 统一注册每个顶点的唯一编号(目前用于样式的数据映射计算使用)
name: 'vertexId',
type: AttributeType.Attribute,
descriptor: {
name: 'a_vertexId',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [featureIdx];
},
},
});
}
}

View File

@ -8,106 +8,23 @@ import {
ILayerConfig,
IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { isColor, rgb2arr } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { rgb2arr } from '@antv/l7-utils';
import BaseModel, { styleColor, styleOffset, styleSingle } from '../../core/BaseModel';
import { PointFillTriangulation } from '../../core/triangulation';
import pointFillFrag from '../shaders/fill_frag.glsl';
import pointFillVert from '../shaders/fill_vert.glsl';
import { isArray, isNumber, isString } from 'lodash';
import { isNumber, isString } from 'lodash';
interface IPointLayerStyleOptions {
opacity: any;
strokeWidth: number;
stroke: string;
strokeOpacity: number;
offsets: [number, number];
opacity: styleSingle;
strokeWidth: styleSingle;
stroke: styleColor;
strokeOpacity: styleSingle;
offsets: styleOffset;
}
// 判断当前使用的 style 中的变量属性是否需要进行数据映射
export default class FillModel extends BaseModel {
protected dataTexture: ITexture2D;
/**
* offsets
* @param offsets
* @returns
*/
public isOffsetStatic(offsets: any) {
if (
isArray(offsets) &&
offsets.length === 2 &&
isNumber(offsets[0]) &&
isNumber(offsets[1])
) {
return true;
} else {
return false;
}
}
/**
* - layer
* @param opacity
* @param strokeOpacity
* @param strokeWidth
* @param stroke
* @param offsets
* @returns
*/
public isDataTextureUpdate(
opacity: any,
strokeOpacity: any,
strokeWidth: any,
stroke: any,
offsets: any,
) {
let isUpdate = false;
if (this.curretnOpacity !== JSON.stringify(opacity)) {
// 判断 opacity 是否发生改变
isUpdate = true;
this.curretnOpacity = JSON.stringify(opacity);
}
if (this.curretnStrokeOpacity !== JSON.stringify(strokeOpacity)) {
// 判断 strokeOpacity 是否发生改变
isUpdate = true;
this.curretnStrokeOpacity = JSON.stringify(strokeOpacity);
}
if (this.currentStrokeWidth !== JSON.stringify(strokeWidth)) {
// 判断 strokeWidth 是否发生改变
isUpdate = true;
this.currentStrokeWidth = JSON.stringify(strokeWidth);
}
if (this.currentStrokeColor !== JSON.stringify(stroke)) {
// 判断 stroke 是否发生改变
isUpdate = true;
this.currentStrokeColor = JSON.stringify(stroke);
}
if (this.currentOffsets !== JSON.stringify(offsets)) {
// 判断 offsets 是否发生改变
isUpdate = true;
this.currentOffsets = JSON.stringify(offsets);
}
if (this.dataTexture === undefined) {
isUpdate = true;
}
return isUpdate;
}
/**
* - layer
*/
public clearLastCalRes() {
this.cellProperties = []; // 清空上一次计算的需要进行数据映射的属性集合
this.cellLength = 0; // 清空上一次计算的 cell 的长度
this.hasOpacity = 0; // 清空上一次是否需要对 opacity 属性进行数据映射的判断
this.hasStrokeOpacity = 0; // 清空上一次是否需要对 strokeOpacity 属性进行数据映射的判断
this.hasStrokeWidth = 0; // 清空上一次是否需要对 strokeWidth 属性进行数据映射的判断
this.hasStroke = 0; // 清空上一次是否需要对 stroke 属性进行数据映射的判断
this.hasOffsets = 0; // 清空上一次是否需要对 offsets 属性进行数据映射的判断
}
public getUninforms(): IModelUniform {
const {
opacity = 1,
@ -118,80 +35,42 @@ export default class FillModel extends BaseModel {
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
if (
this.isDataTextureUpdate(
this.dataTextureNeedUpdate({
opacity,
strokeOpacity,
strokeWidth,
stroke,
offsets,
)
})
) {
this.clearLastCalRes(); // 清除上一次的计算结果
if (!isNumber(opacity)) {
// 数据映射
this.cellProperties.push({ attr: 'opacity', count: 1 });
this.hasOpacity = 1;
this.cellLength += 1;
}
if (!isNumber(strokeOpacity)) {
// 数据映射
this.cellProperties.push({ attr: 'strokeOpacity', count: 1 });
this.hasStrokeOpacity = 1;
this.cellLength += 1;
}
if (!isNumber(strokeWidth)) {
// 数据映射
this.cellProperties.push({ attr: 'strokeWidth', count: 1 });
this.hasStrokeWidth = 1;
this.cellLength += 1;
}
if (!isColor(stroke)) {
// 数据映射
this.cellProperties.push({ attr: 'stroke', count: 4 });
this.cellLength += 4;
this.hasStroke = 1;
}
if (!this.isOffsetStatic(offsets)) {
// 数据映射
this.cellProperties.push({ attr: 'offsets', count: 2 });
this.cellLength += 2;
this.hasOffsets = 1;
}
// 判断当前的样式中哪些是需要进行数据映射的,哪些是常量,同时计算用于构建数据纹理的一些中间变量
this.judgeStyleAttributes({
opacity,
strokeOpacity,
strokeWidth,
stroke,
offsets,
});
const encodeData = this.layer.getEncodedData();
if (this.cellLength > 0) {
// 需要构建数据纹理
const { data, width, height } = this.calDataFrame(
this.cellLength,
encodeData,
this.cellProperties,
);
this.rowCount = height; // 当前数据纹理有多少行
const { data, width, height } = this.calDataFrame(
this.cellLength,
encodeData,
this.cellProperties,
);
this.rowCount = height; // 当前数据纹理有多少行
this.dataTexture = this.createTexture2D({
flipY: true,
data,
format: gl.LUMINANCE,
type: gl.FLOAT,
width,
height,
});
} else {
// 不需要构建数据纹理 - 构建一个空纹理
this.dataTexture = this.createTexture2D({
flipY: true,
data: [1],
format: gl.LUMINANCE,
type: gl.FLOAT,
width: 1,
height: 1,
});
}
this.dataTexture =
this.cellLength > 0
? this.createTexture2D({
flipY: true,
data,
format: gl.LUMINANCE,
type: gl.FLOAT,
width,
height,
})
: this.defaultDataTexture;
}
return {
@ -220,9 +99,11 @@ export default class FillModel extends BaseModel {
u_stroke_opacity: isNumber(strokeOpacity) ? strokeOpacity : 1.0,
u_stroke_width: isNumber(strokeWidth) ? strokeWidth : 0.0,
u_stroke_color:
isString(stroke) && isColor(stroke) ? rgb2arr(stroke) : [0, 0, 0, 0],
isString(stroke) && this.isStaticColor(stroke)
? rgb2arr(stroke)
: [0, 0, 0, 0],
u_offsets: this.isOffsetStatic(offsets)
? [-offsets[0], offsets[1]]
? (offsets as [number, number])
: [0, 0],
};
}
@ -317,30 +198,6 @@ export default class FillModel extends BaseModel {
},
});
// vertex id 用于作为数据纹理取值的唯一编号
this.styleAttributeService.registerStyleAttribute({
name: 'vertexId',
type: AttributeType.Attribute,
descriptor: {
name: 'a_vertexId',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [featureIdx];
},
},
});
// point layer size;
this.styleAttributeService.registerStyleAttribute({
name: 'shape',

View File

@ -4,10 +4,7 @@ attribute vec2 a_Extrude;
attribute float a_Size;
attribute float a_Shape;
attribute float a_vertexId;
uniform mat4 u_cellTypeLayout;
uniform sampler2D u_dataTexture;
varying mat4 styleMappingMat;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
@ -22,101 +19,11 @@ uniform float u_stroke_width : 2;
uniform vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0];
uniform vec2 u_offsets;
#pragma include "styleMapping"
#pragma include "projection"
#pragma include "picking"
/*
currentRow 当前行
currentColumn 当前列
columnCount 有多少列
nextStep 需要计算当前 cell 后的第几个 cell (当前 cell 则 nextStep = 0
*/
vec2 nextPos(float currentRow, float currentColumn, float columnCount, float nextStep) {
float nextColumn = currentColumn;
float nextRow = currentRow;
if(currentColumn + nextStep <= columnCount){
nextColumn = currentColumn + nextStep;
} else {
nextColumn = mod(currentColumn + nextStep, columnCount); // 不会出现跨两行
nextRow = currentRow + 1.0;
}
return vec2(nextColumn, nextRow);
}
// 根据坐标位置先是计算 uv ,然后根据 uv 从数据纹理中取值
float pos2value(vec2 pos, float columnWidth, float rowHeight) {
float u = (pos.r - 1.0) * columnWidth + columnWidth/2.0;
float v = 1.0 - ((pos.g - 1.0) * rowHeight + rowHeight/2.0);
return texture2D(u_dataTexture, vec2(u, v)).r;
}
bool hasOpacity() { // 判断 cell 中是否存在 opacity 的数据
return u_cellTypeLayout[1][0] > 0.0;
}
bool hasStrokeOpacity() { // 判断 cell 中是否存在 strokeOpacity 的数据
return u_cellTypeLayout[1][1] > 0.0;
}
bool hasStrokeWidth() { // 判断 cell 中是否存在 strokeWidth 的数据
return u_cellTypeLayout[1][2] > 0.0;
}
bool hasStroke() { // 判断 cell 中是否存在 stroke 的数据
return u_cellTypeLayout[1][3] > 0.0;
}
bool hasOffsets() { // 判断 cell 中是否存在 offsets 的数据
return u_cellTypeLayout[2][0] > 0.0;
}
// 计算 opacity 和标志在 cell 中取值用的 offset
vec2 calOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasOpacity()) { // 数据纹理中不存在 opacity 的时候取默认值(用户在 style 中传入的是常量)
return vec2(u_opacity, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureOpacity = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureOpacity, textureOffset + 1.0);
}
}
vec2 calStrokeOpacityAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasStrokeOpacity()) {
return vec2(u_stroke_opacity, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureStrokeOpacity = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureStrokeOpacity, textureOffset + 1.0);
}
}
vec2 calStrokeWidthAndOffset(float cellCurrentRow, float cellCurrentColumn, float columnCount, float textureOffset, float columnWidth, float rowHeight) {
if(!hasStrokeWidth()) {
return vec2(u_stroke_width, textureOffset);
} else {
vec2 valuePos = nextPos(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset);
float textureStrokeWidth = pos2value(valuePos, columnWidth, rowHeight);
return vec2(textureStrokeWidth, textureOffset + 1.0);
}
}
float calCellCount() { // 计算当前单个 cell 的大小
// u_cellTypeLayout
// cal_height, WIDTH, 0.0, 0.0, // rowCount columnCount - 几行几列
// 1.0, 1.0, 1.0, 0.0, // opacity strokeOpacity strokeWidth stroke - 1.0 表示有数据映射、0.0 表示没有
// 1.0, 0.0, 0.0, 0.0, // offsets
// 0.0, 0.0, 0.0, 0.0
return u_cellTypeLayout[1][0] + // opacity
u_cellTypeLayout[1][1] + // strokeOpacity
u_cellTypeLayout[1][2] + // strokeWidth
u_cellTypeLayout[1][3] * 4.0 + // stroke
u_cellTypeLayout[2][0] * 2.0; // offsets
}
void main() {
vec2 extrude = a_Extrude;
float shape_type = a_Shape;

View File

@ -15,10 +15,6 @@ export function rgb2arr(str: string) {
return arr;
}
export function isColor(str: string) {
return d3.color(str);
}
export function decodePickingColor(color: Uint8Array): number {
const i1 = color && color[0];
const i2 = color && color[1];

View File

@ -17,7 +17,7 @@ export default class Amap2demo extends React.Component {
center: [121.107846, 30.267069],
pitch: 0,
style: 'normal',
zoom: 2,
zoom: 20,
animateEnable: false,
}),
});
@ -26,7 +26,7 @@ export default class Amap2demo extends React.Component {
lng: 121.107846,
lat: 30.267069,
opacity2: 0.2,
strokeOpacity2: 0.2,
strokeOpacity2: 0.4,
strokeColor: '#000',
strokeWidth: 0.5,
// offsets2: [0, 0]
@ -36,7 +36,7 @@ export default class Amap2demo extends React.Component {
lng: 121.107,
lat: 30.267069,
opacity2: 0.4,
strokeOpacity2: 0.4,
strokeOpacity2: 0.6,
strokeColor: '#0f0',
strokeWidth: 2,
offsets2: [100, 100],
@ -45,7 +45,7 @@ export default class Amap2demo extends React.Component {
lng: 121.107846,
lat: 30.26718,
opacity2: 0.6,
strokeOpacity2: 0.6,
strokeOpacity2: 0.8,
strokeColor: '#f00',
strokeWidth: 4,
// offsets2: [200, 200]
@ -67,92 +67,92 @@ export default class Amap2demo extends React.Component {
'https://gw-office.alipayobjects.com/bmw-prod/ccc91465-d3ea-4eda-a178-7c1815dac32b.json';
scene.on('loaded', () => {
for (let i = 0; i < 1; i++) {
fetch(thousandMhundred)
.then((res) => res.text())
.then((data) => {
// console.log('data', data)
// lng: Math.random() * 180, // 0 ~ 180
// lat: Math.random() * 100 - 50, // -50 ~ 50
// customOpacity: Math.random(),
// customStroke: `rgb(${Math.random()*255}, ${Math.random()*255}, ${Math.random()*255}, 1)`,
// customStrokeOpacity: Math.random(),
// customStrokeWidth: Math.random() * 5,
let layer = new PointLayer()
.source(JSON.parse(data), {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('circle')
.color('rgba(255, 0, 0, 1.0)')
.size(10)
.style({
opacity: 'customOpacity',
// strokeOpacity: 'customStrokeOpacity',
// strokeWidth: 'customStrokeWidth',
// stroke: 'customStroke',
});
scene.addLayer(layer);
});
// let layer = new PointLayer()
// .source(originData, {
// parser: {
// type: 'json',
// x: 'lng',
// y: 'lat',
// },
// })
// .shape('circle')
// // .shape('normal')
// // .shape('fill')
// // .color('rgba(255, 0, 0, 0.9)')
// .color('rgba(255, 0, 0, 1.0)')
// .size(10)
// // .offsets('123')
// .style({
// // stroke: '#000',
// // stroke: 'rgba(0, 255, 0, 1)',
// stroke: 'strokeColor',
// // stroke: ['strokeColor', (d: any) => {
// // return d
// // }],
// // stroke: ['strokeColor', ["#f00", "#ff0"]],
// fetch(thousandMhundred)
// .then((res) => res.text())
// .then((data) => {
// // console.log('data', data)
// // lng: Math.random() * 180, // 0 ~ 180
// // lat: Math.random() * 100 - 50, // -50 ~ 50
// // customOpacity: Math.random(),
// // customStroke: `rgb(${Math.random()*255}, ${Math.random()*255}, ${Math.random()*255}, 1)`,
// // customStrokeOpacity: Math.random(),
// // customStrokeWidth: Math.random() * 5,
// let layer = new PointLayer()
// .source(JSON.parse(data), {
// parser: {
// type: 'json',
// x: 'lng',
// y: 'lat',
// },
// })
// .shape('circle')
// .color('rgba(255, 0, 0, 1.0)')
// .size(10)
// .style({
// opacity: 'customOpacity',
// // strokeOpacity: 'customStrokeOpacity',
// // strokeWidth: 'customStrokeWidth',
// // stroke: 'customStroke',
// });
// scene.addLayer(layer);
// });
let layer = new PointLayer()
.source(originData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('circle')
// .shape('normal')
// .shape('fill')
// .color('rgba(255, 0, 0, 0.9)')
.color('rgba(255, 0, 0, 1.0)')
.size(10)
// .offsets('123')
.style({
// stroke: '#000',
// stroke: 'rgba(0, 255, 0, 1)',
// stroke: 'strokeColor',
// stroke: ['strokeColor', (d: any) => {
// return d
// }],
// stroke: ['strokeColor', ["#f00", "#ff0"]],
// // strokeWidth: 4,
// // strokeWidth: "strokeWidth",
// // strokeWidth: ["strokeWidth", [1, 2]],
// strokeWidth: ["strokeWidth", (d: any) => {
// return d * 2
// }],
// strokeWidth: 4,
// strokeWidth: "strokeWidth",
// strokeWidth: ["strokeWidth", [1, 2]],
// strokeWidth: ["strokeWidth", (d: any) => {
// return d * 2
// }],
// // strokeOpacity: 0.5,
// // strokeOpacity: 'strokeOpacity2',
// // strokeOpacity: 1.0,
// // strokeOpacity: [
// // 'strokeOpacity2',
// // (d: any) => {
// // // console.log('strokeOpacity2', d)
// // return d*2;
// // },
// // ],
// // strokeOpacity: ['opacity2', [0.2, 0.6]],
// strokeOpacity: 0.5,
strokeOpacity: 'strokeOpacity2',
// strokeOpacity: 1.0,
// strokeOpacity: [
// 'strokeOpacity2',
// (d: any) => {
// // console.log('strokeOpacity2', d)
// return d*2;
// },
// ],
// strokeOpacity: ['opacity2', [0.2, 0.6]],
// // offsets: [100, 100],
// offsets: 'offsets2',
// // offsets: ['offsets2', (d: any) => d],
// offsets: [100, 100],
// offsets: 'offsets2',
// offsets: ['offsets2', (d: any) => d],
// opacity: 'opacity2',
// // opacity: 0.2
// // opacity: 0,
// // opacity: ['opacity2', (d: any) => {
// // return d
// // }]
// // opacity: ['opacity2', [0.2, 0.6]],
// })
// .active(true);
// scene.addLayer(layer);
opacity: 'opacity2',
// opacity: 0.2
// opacity: 0,
// opacity: ['opacity2', (d: any) => {
// return d
// }]
// opacity: ['opacity2', [0.2, 0.6]],
})
.active(true);
scene.addLayer(layer);
}
});
}