Merge pull request #49 from antvis/encode

feat(layers): add polygon3d , pointimagelayer
This commit is contained in:
@thinkinggis 2019-10-30 10:23:44 +08:00 committed by GitHub
commit 2490c98e9b
23 changed files with 912 additions and 136 deletions

View File

@ -246,7 +246,6 @@ export default class StyleAttributeService implements IStyleAttributeService {
const attributes: {
[attributeName: string]: IAttribute;
} = {};
descriptors.forEach((descriptor, attributeIdx) => {
if (descriptor) {
// IAttribute 参数透传

View File

@ -24,6 +24,7 @@
"@l7/utils": "^0.0.1",
"@turf/meta": "^6.0.2",
"@types/d3-color": "^1.2.2",
"inversify": "^5.0.1",
"d3-array": "^2.3.1",
"d3-color": "^1.4.0",
"d3-scale": "^3.1.0",

View File

@ -103,6 +103,9 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
protected layerSource: Source;
@lazyInject(TYPES.IRendererService)
protected readonly rendererService: IRendererService;
private encodedData: IEncodeFeature[];
private configSchema: object;
@ -117,9 +120,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
@lazyInject(TYPES.IShaderModuleService)
private readonly shaderModuleService: IShaderModuleService;
@lazyInject(TYPES.IRendererService)
private readonly rendererService: IRendererService;
@lazyInject(TYPES.IMapService)
private readonly map: IMapService;

View File

@ -0,0 +1,65 @@
export type IPosition = [number, number, number] | [number, number];
export type IPath = IPosition[];
export enum ShapeType3D {
CYLINDER = 'cylinder',
SQUARECOLUMN = 'squareColumn',
TRIANGLECOLUMN = 'triangleColumn',
HEXAGONCOLUMN = 'hexagonColumn',
PENTAGONCOLUMN = 'pentagonColumn',
}
export enum ShapeType2D {
CIRCLE = 'circle',
SQUARE = 'square',
TRIANGLE = 'triangle',
HEXAGON = 'hexagon',
PENTAGON = 'pentagon',
}
/**
*
* @param pointCount 3 =>
* @param start
*/
export function polygonPath(pointCount: number, start: number = 0): IPath {
const step = (Math.PI * 2) / pointCount;
const line = [];
for (let i = 0; i < pointCount; i++) {
line.push(step * i + (start * Math.PI) / 12);
}
const path: IPath = line.map((t) => {
const x = Math.sin(t + Math.PI / 4);
const y = Math.cos(t + Math.PI / 4);
return [x, y, 0];
});
// path.push(path[0]);
return path;
}
export function circle(): IPath {
return polygonPath(30);
}
export function square(): IPath {
return polygonPath(4);
}
export function triangle(): IPath {
return polygonPath(3);
}
export function hexagon(): IPath {
return polygonPath(6);
}
export function pentagon(): IPath {
return polygonPath(5);
}
export const geometryShape = {
[ShapeType2D.CIRCLE]: circle,
[ShapeType2D.HEXAGON]: hexagon,
[ShapeType2D.TRIANGLE]: triangle,
[ShapeType2D.SQUARE]: square,
[ShapeType2D.PENTAGON]: pentagon,
[ShapeType3D.CYLINDER]: circle,
[ShapeType3D.HEXAGONCOLUMN]: hexagon,
[ShapeType3D.TRIANGLECOLUMN]: triangle,
[ShapeType3D.SQUARECOLUMN]: square,
[ShapeType3D.PENTAGONCOLUMN]: pentagon,
};

View File

@ -0,0 +1,83 @@
import earcut from 'earcut';
import { IPath } from './Path';
export interface IExtrudeGeomety {
positions: number[];
index: number[];
}
/**
*
* @param paths
* @param extrude
*/
export default function extrudePolygon(path: IPath[]): IExtrudeGeomety {
const p1 = path[0][0];
const p2 = path[0][path[0].length - 1];
if (p1[0] === p2[0] && p1[1] === p2[1]) {
path[0] = path[0].slice(0, path[0].length - 1);
}
const n = path[0].length;
const flattengeo = earcut.flatten(path);
const { vertices, dimensions } = flattengeo;
const positions = [];
const indexArray = [];
// 设置顶部z值
for (let j = 0; j < vertices.length / dimensions; j++) {
if (dimensions === 2) {
positions.push(vertices[j * 2], vertices[j * 2 + 1], 1);
} else {
positions.push(vertices[j * 3], vertices[j * 3 + 1], 1);
}
}
const triangles = earcut(
flattengeo.vertices,
flattengeo.holes,
flattengeo.dimensions,
);
indexArray.push(...triangles);
for (let i = 0; i < n; i++) {
const prePoint = flattengeo.vertices.slice(
i * dimensions,
(i + 1) * dimensions,
);
let nextPoint = flattengeo.vertices.slice(
(i + 2) * dimensions,
(i + 3) * dimensions,
);
if (nextPoint.length === 0) {
nextPoint = flattengeo.vertices.slice(0, dimensions);
}
const indexOffset = positions.length / 3;
positions.push(
prePoint[0],
prePoint[1],
1,
nextPoint[0],
nextPoint[1],
1,
prePoint[0],
prePoint[1],
0,
nextPoint[0],
nextPoint[1],
0,
);
indexArray.push(...[1, 2, 0, 3, 2, 1].map((v) => v + indexOffset));
}
return {
positions,
index: indexArray,
};
}
export function fillPolygon(points: IPath[]) {
const flattengeo = earcut.flatten(points);
const triangles = earcut(
flattengeo.vertices,
flattengeo.holes,
flattengeo.dimensions,
);
return {
positions: flattengeo.vertices,
index: triangles,
};
}

View File

@ -1,11 +1,21 @@
import { IEncodeFeature } from '@l7/core';
import { vec3 } from 'gl-matrix';
import getNormals from '../utils/polylineNormal';
import extrudePolygon, { IExtrudeGeomety } from './shape/extrude';
import { geometryShape, ShapeType2D, ShapeType3D } from './shape/Path';
import {
geometryShape,
IPosition,
ShapeType2D,
ShapeType3D,
} from './shape/Path';
interface IGeometryCache {
[key: string]: IExtrudeGeomety;
}
const GeometryCache: IGeometryCache = {};
/**
* 2D
* @param feature feature
*/
export function PointFillTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
@ -15,6 +25,10 @@ export function PointFillTriangulation(feature: IEncodeFeature) {
};
}
/**
* 3D
* @param feature feature
*/
export function PointExtrudeTriangulation(feature: IEncodeFeature) {
const { shape } = feature;
const { positions, index } = getGeometry(shape as ShapeType3D);
@ -26,6 +40,46 @@ export function PointExtrudeTriangulation(feature: IEncodeFeature) {
};
}
/**
*
* @param feature feature
*/
export function PointImageTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
vertices: [...coordinates],
indices: [0],
size: coordinates.length,
};
}
/**
* 线
* @param feature feature
*/
export function LineTriangulation(feature: IEncodeFeature) {
const { coordinates } = feature;
const line = getNormals(coordinates as number[][], false, 0);
return {
vertices: line.attrPos, // [ x,y,z, distance, miter ]
indices: line.attrIndex,
normals: line.normals,
size: 5,
};
}
export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as IPosition[][];
const { positions, index } = extrudePolygon(coordinates);
return {
vertices: positions, // [ x, y, z ]
indices: index,
normals: Array.from(computeVertexNormals(positions, index)),
size: 3,
};
}
function getGeometry(shape: ShapeType3D): IExtrudeGeomety {
if (GeometryCache && GeometryCache[shape]) {
return GeometryCache[shape];
@ -37,6 +91,7 @@ function getGeometry(shape: ShapeType3D): IExtrudeGeomety {
GeometryCache[shape] = geometry;
return geometry;
}
function computeVertexNormals(
positions: number[],
indexArray: number[],
@ -75,6 +130,7 @@ function computeVertexNormals(
normalizeNormals(normals);
return normals;
}
function normalizeNormals(normals: Float32Array) {
for (let i = 0, li = normals.length; i < li; i += 3) {
const normal = vec3.fromValues(normals[i], normals[i + 1], normals[i + 2]);
@ -83,3 +139,9 @@ function normalizeNormals(normals: Float32Array) {
normals.set(newNormal, i);
}
}
function checkIsClosed(points: number[][][]) {
const p1 = points[0][0];
const p2 = points[0][points[0].length - 1];
return p1[0] === p2[0] && p1[1] === p2[1];
}

View File

@ -1,11 +1,13 @@
import { container, ILayerPlugin, TYPES } from '@l7/core';
import BaseLayer from './core/BaseLayer';
import Point3dLayer from './point/extrude';
// import HeatMapLayer from './heatmap';
// import Line from './line';
import LineLayer from './line/index';
import Point3dLayer from './point/extrude';
import PointImageLayer from './point/image';
import PointLayer from './point/index';
// import Point from './point/point';
import PolygonLayer from './polygon';
import Polygon3DLayer from './polygon/polygon3D';
// import ImageLayer from './raster';
import ConfigSchemaValidationPlugin from './plugins/ConfigSchemaValidationPlugin';
@ -65,7 +67,9 @@ export {
PointLayer,
PolygonLayer,
Point3dLayer,
// Point,
PointImageLayer,
LineLayer,
Polygon3DLayer,
// Line,
// ImageLayer,
// HeatMapLayer,

View File

@ -1,102 +1,154 @@
// import {
// gl,
// IRendererService,
// IShaderModuleService,
// lazyInject,
// TYPES,
// } from '@l7/core';
// import BaseLayer from '../core/BaseLayer';
// import LineBuffer from './buffers/line';
// import line_frag from './shaders/line_frag.glsl';
// import line_vert from './shaders/line_vert.glsl';
// export default class LineLayer extends BaseLayer {
// public name: string = 'LineLayer';
// @lazyInject(TYPES.IShaderModuleService)
// private readonly shaderModule: IShaderModuleService;
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { LineTriangulation } from '../core/triangulation';
import line_frag from './shaders/line_frag.glsl';
import line_vert from './shaders/line_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
}
export default class LineLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'LineLayer';
// @lazyInject(TYPES.IRendererService)
// private readonly renderer: IRendererService;
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
// protected renderModels() {
// this.models.forEach((model) =>
// model.draw({
// uniforms: {
// u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
// },
// }),
// );
// return this;
// }
// protected buildModels(): void {
// this.shaderModule.registerModule('line', {
// vs: line_vert,
// fs: line_frag,
// });
protected renderModels() {
const { opacity } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_Opacity: opacity || 0,
},
}),
);
return this;
}
// this.models = [];
// const { vs, fs, uniforms } = this.shaderModule.getModule('line');
// const buffer = new LineBuffer({
// data: this.getEncodedData(),
// style: this.styleOption,
// });
// const {
// createAttribute,
// createBuffer,
// createElements,
// createModel,
// } = this.renderer;
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'line',
vertexShader: line_vert,
fragmentShader: line_frag,
triangulation: LineTriangulation,
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}
// this.models.push(
// createModel({
// attributes: {
// a_Position: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.positions,
// type: gl.FLOAT,
// }),
// size: 3,
// }),
// a_normal: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.normals,
// type: gl.FLOAT,
// }),
// size: 3,
// }),
// a_color: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.colors,
// type: gl.FLOAT,
// }),
// size: 4,
// }),
// a_size: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.sizes,
// type: gl.FLOAT,
// }),
// size: 1,
// }),
// a_miter: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.miters,
// type: gl.FLOAT,
// }),
// size: 1,
// }),
// },
// uniforms: {
// ...uniforms,
// u_opacity: this.styleOption.opacity as number,
// },
// fs,
// vs,
// count: buffer.indexArray.length,
// elements: createElements({
// data: buffer.indexArray,
// type: gl.UNSIGNED_INT,
// }),
// }),
// );
// }
// }
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'miter',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Miter',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [vertex[4]];
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'distance',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Distance',
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 [vertex[3]];
},
},
});
}
}

View File

@ -1,11 +1,11 @@
attribute float a_miter;
attribute vec4 a_color;
attribute float a_size;
attribute float a_distance;
attribute float a_Miter;
attribute vec4 a_Color;
attribute float a_Size;
attribute float a_Distance;
attribute float a_dash_array;
attribute float a_total_distance;
attribute vec3 a_normal;
attribute vec3 a_Normal;
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
@ -14,9 +14,9 @@ varying float v_dash_array;
varying vec3 v_normal;
#pragma include "projection"
void main() {
v_normal = a_normal;
v_color = a_color;
vec3 size = a_miter * a_size * v_normal;
v_normal = a_Normal;
v_color = a_Color;
vec3 size = a_Miter * a_Size * v_normal;
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0, 1.0));

View File

@ -40,7 +40,9 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin {
featureIdx: number,
vertex: number[],
) => {
return vertex.length === 3 ? vertex : [vertex[0], vertex[1], 0];
return vertex.length === 2
? [vertex[0], vertex[1], 0]
: [vertex[0], vertex[1], vertex[2]];
},
},
});

View File

@ -1,8 +1,8 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { PointExtrudeTriangulation } from '../core/triangulation';
import pointExtrudeFrag from './shaders/extrude_frag.glsl';
import pointExtrudeVert from './shaders/extrude_vert.glsl';
import { PointExtrudeTriangulation } from './triangulation';
interface IPointLayerStyleOptions {
opacity: number;
}

View File

@ -0,0 +1,141 @@
import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerPlugin,
ILogService,
IStyleAttributeService,
lazyInject,
TYPES,
} from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { PointImageTriangulation } from '../core/triangulation';
import pointImageFrag from './shaders/image_frag.glsl';
import pointImageVert from './shaders/image_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
}
export function PointTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
extrude: [-1, -1, 1, -1, 1, 1, -1, 1],
indices: [0, 1, 2, 2, 3, 0],
size: coordinates.length,
};
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PointLayer';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const { opacity } = this.getStyleOptions();
const { createTexture2D } = this.rendererService;
this.models.forEach((model) =>
model.draw({
uniforms: {
u_Opacity: opacity || 0,
u_texture: createTexture2D({
data: this.iconService.getCanvas(),
width: 1024,
height: this.iconService.canvasHeight || 64,
}),
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.iconService.on('imageUpdate', () => {
this.renderModels();
});
this.models = [
this.buildLayerModel({
moduleName: 'pointImage',
vertexShader: pointImageVert,
fragmentShader: pointImageFrag,
triangulation: PointTriangulation,
primitive: gl.POINTS,
depth: { enable: false },
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'uv',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Uv',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const iconMap = this.iconService.getIconMap();
const { shape } = feature;
const { x, y } = iconMap[shape as string] || { x: 0, y: 0 };
return [x, y];
},
},
});
}
}

View File

@ -6,9 +6,9 @@ void main(){
// pos.y= 1.- pos.y;
vec4 textureColor=texture2D(u_texture,pos);
if(v_color == vec4(0.)){
gl_FragColor= textureColor;
gl_FragColor= textureColor;
}else {
gl_FragColor= step(0.01, textureColor.x) * v_color;
}
return;
}
}

View File

@ -1,18 +1,17 @@
precision highp float;
attribute vec3 a_Position;
attribute vec4 a_color;
attribute vec2 a_uv;
attribute float a_size;
attribute float a_shape;
attribute vec4 a_Color;
attribute vec2 a_Uv;
attribute float a_Size;
varying vec4 v_color;
varying vec2 v_uv;
uniform mat4 u_ModelMatrix;
#pragma include "projection"
void main() {
v_color = a_color;
v_uv = a_uv;
v_color = a_Color;
v_uv = a_Uv;
vec4 project_pos = project_position(vec4(a_Position, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
gl_PointSize = a_size;
}
gl_PointSize = a_Size;
}

View File

@ -0,0 +1,107 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { PolygonExtrudeTriangulation } from '../core/triangulation';
import pointExtrudeFrag from './shaders/polygon_extrude_frag.glsl';
import pointExtrudeVert from './shaders/polygon_extrude_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PolygonLayer';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const { opacity } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_Opacity: opacity || 0,
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'polygonExtrude',
vertexShader: pointExtrudeVert,
fragmentShader: pointExtrudeFrag,
triangulation: PolygonExtrudeTriangulation,
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
}
}

View File

@ -0,0 +1,10 @@
uniform float u_Opacity: 1.0;
varying vec4 v_Color;
#pragma include "picking"
void main() {
gl_FragColor = v_Color;
gl_FragColor.a *= u_Opacity;
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -0,0 +1,19 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec3 a_Normal;
attribute float a_Size;
uniform mat4 u_ModelMatrix;
varying vec4 v_Color;
#pragma include "projection"
#pragma include "picking"
void main() {
v_Color = vec4(a_Normal,1.0);
vec4 project_pos = project_position(vec4(a_Position.xy,a_Position.z * a_Size, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
setPickingColor(a_PickingColor);
}

View File

@ -1,6 +1,7 @@
attribute vec4 a_Color;
attribute vec4 a_Color;
attribute vec3 a_Position;
// attribute vec3 a_normal;
attribute vec3 a_Normal;
attribute float a_Size;
uniform mat4 u_ModelMatrix;
varying vec4 v_Color;
@ -9,8 +10,8 @@ varying vec4 v_Color;
#pragma include "picking"
void main() {
v_Color = a_Color;
vec4 project_pos = project_position(vec4(a_Position, 1.0));
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));
setPickingColor(a_PickingColor);

View File

@ -210,12 +210,20 @@ export default function(
}
}
}
const pickData = [];
for (let i = 0; i < miters.length; i++) {
pickData.push(
attrPos[i * 3],
attrPos[i * 3 + 1],
attrPos[i * 3 + 1],
attrDistance[i],
miters[i],
);
}
return {
normals: out,
attrIndex,
attrPos,
attrDistance,
miters,
attrPos: pickData, // [x,y,z, distance, miter ]
};
}
// [x,y,z, distance, miter ]

View File

@ -1,8 +1,15 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import LineLayer from './components/Line';
import PointDemo from './components/Point';
import Point3D from './components/Point3D';
import PointImage from './components/pointImage';
import Polygon3D from './components/polygon3D';
// @ts-ignore
storiesOf('图层', module)
.add('点图层', () => <PointDemo />)
.add('3D点', () => <Point3D />);
.add('3D点', () => <Point3D />)
.add('图片标注', () => <PointImage />)
.add('面3d图层', () => <Polygon3D />)
.add('线图层', () => <LineLayer />);

View File

@ -0,0 +1,80 @@
import { LineLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
import * as React from 'react';
export default class Point3D extends React.Component {
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const response = await fetch(
'https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json',
);
const testdata = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: [
[91.58203125, 34.95799531086792],
[96.767578125, 34.379712580462204],
[99.228515625, 33.7243396617476],
],
},
},
],
};
const scene = new Scene({
center: [102.602992, 23.107329],
id: 'map',
pitch: 0,
type: 'mapbox',
style: 'mapbox://styles/mapbox/dark-v9',
zoom: 13,
});
const lineLayer = new LineLayer({})
.source(await response.json())
.size(1)
.shape('line')
.color(
'ELEV',
[
'#E8FCFF',
'#CFF6FF',
'#A1E9ff',
'#65CEF7',
'#3CB1F0',
'#2894E0',
'#1772c2',
'#105CB3',
'#0D408C',
'#002466',
].reverse(),
)
.render();
scene.addLayer(lineLayer);
scene.render();
this.scene = scene;
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

View File

@ -0,0 +1,61 @@
import { PointImageLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
import * as React from 'react';
import data from '../data/data.json';
export default class PointImage extends React.Component {
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public componentDidMount() {
const scene = new Scene({
center: [120.19382669582967, 30.258134],
id: 'map',
pitch: 0,
type: 'mapbox',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 1,
});
const pointLayer = new PointImageLayer({});
const p1 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [83.671875, 44.84029065139799],
},
},
],
};
scene.addImage(
'00',
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*kzTMQqS2QdUAAAAAAAAAAABkARQnAQ',
);
pointLayer
.source(data)
.shape('00')
.size(30);
scene.addLayer(pointLayer);
scene.render();
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

View File

@ -0,0 +1,75 @@
// @ts-ignore
import { Polygon3DLayer } from '@l7/layers';
// @ts-ignore
import { Scene } from '@l7/scene';
import * as React from 'react';
function convertRGB2Hex(rgb: number[]) {
return (
'#' + rgb.map((r) => ('0' + Math.floor(r).toString(16)).slice(-2)).join('')
);
}
export default class Polygon3D extends React.Component {
private gui: dat.GUI;
private $stats: Node;
private scene: Scene;
public componentWillUnmount() {
if (this.gui) {
this.gui.destroy();
}
if (this.$stats) {
document.body.removeChild(this.$stats);
}
this.scene.destroy();
}
public async componentDidMount() {
const response = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
);
const scene = new Scene({
id: 'map',
type: 'mapbox',
style: 'mapbox://styles/mapbox/streets-v9',
center: [110.19382669582967, 50.258134],
pitch: 0,
zoom: 3,
});
this.scene = scene;
const layer = new Polygon3DLayer({});
layer
.source(await response.json())
.size('name', [0, 10000, 50000, 30000, 100000])
.color('name', [
'#2E8AE6',
'#69D1AB',
'#DAF291',
'#FFD591',
'#FF7A45',
'#CF1D49',
])
.shape('fill')
.style({
opacity: 1.0,
});
scene.addLayer(layer);
scene.render();
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}