mirror of https://gitee.com/antv-l7/antv-l7
refactor: line & polygon buffer
This commit is contained in:
parent
b8bfd1b9ef
commit
a88f6cab61
|
@ -31,6 +31,7 @@ const scene = new L7.Scene({
|
|||
|
||||
});
|
||||
window.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/xxvoBnsYNEPiAXGRmlPD.json', city => {
|
||||
citylayer = scene.PolygonLayer()
|
||||
|
@ -39,7 +40,7 @@ scene.on('loaded', () => {
|
|||
.shape('extrude')
|
||||
|
||||
.size('max',(value)=>{
|
||||
if(value<0)value =0;
|
||||
if(value<0)value =1;
|
||||
return value * 1000;
|
||||
})
|
||||
.active(true)
|
||||
|
@ -48,7 +49,6 @@ scene.on('loaded', () => {
|
|||
})
|
||||
.render();
|
||||
|
||||
|
||||
const citylayer2 = scene.PolygonLayer()
|
||||
.source(city)
|
||||
.shape('line')
|
||||
|
@ -56,7 +56,7 @@ scene.on('loaded', () => {
|
|||
.style({
|
||||
opacity: 1
|
||||
})
|
||||
.render();
|
||||
.render();
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,53 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="https://gw.alipayobjects.com/os/rmsportal/PqLCOJpqoOUfuPRacUzE.css" />
|
||||
<title>弧线图</title>
|
||||
<style> ::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="geometry" content="diagram">
|
||||
<link rel="stylesheet" href="./assets/common.css">
|
||||
<title>hexagon demo</title>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/ document.body.clientHeight; </script>
|
||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
||||
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
|
||||
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
|
||||
<script src="./assets/jquery-3.2.1.min.js"></script>
|
||||
<script src="./assets/dat.gui.min.js"></script>
|
||||
<script src="../build/L7.js"></script>
|
||||
<script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
|
||||
<style>
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
</style>
|
||||
<script>
|
||||
var scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
zoom: 4
|
||||
});
|
||||
scene.on('loaded', function() {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', function(data) {
|
||||
|
||||
const color1 = [ 'rgba(37, 140, 249, 0.8)', 'rgba(14, 241, 242, 0.8)', 'rgba(255, 255, 255, 0.8)' ];
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 116.2825, 39.9 ],
|
||||
pitch: 0,
|
||||
zoom: 3
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', data => {
|
||||
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
}).source(data, {
|
||||
parser:{
|
||||
type:'csv',
|
||||
scene.LineLayer({
|
||||
zIndex: 2
|
||||
})
|
||||
.source(data, {
|
||||
parser:{
|
||||
type: 'csv',
|
||||
x: 'lng1',
|
||||
y: 'lat1',
|
||||
x1: 'lng2',
|
||||
y1: 'lat2'
|
||||
}
|
||||
}
|
||||
).color('rgb(13,64,140)').style({
|
||||
opacity: 0.6
|
||||
})
|
||||
.shape('greatCircle')
|
||||
.size(1)
|
||||
.render();
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
.shape('greatCircle')
|
||||
.size(0.8)
|
||||
.color('rgb(13,64,140)')
|
||||
.style({
|
||||
opacity:0.6,
|
||||
})
|
||||
.render();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -47,14 +47,21 @@ scene.on('loaded', () => {
|
|||
parser:{
|
||||
type: 'mvt',
|
||||
sourceLayer:'county',
|
||||
idField:'id',
|
||||
maxZoom: 9,
|
||||
idField:'id',
|
||||
maxZoom: 9
|
||||
}
|
||||
})
|
||||
})
|
||||
.scale({
|
||||
'OBJECTID':{
|
||||
min:0,
|
||||
max:3000,
|
||||
type:'linear'
|
||||
}
|
||||
})
|
||||
.shape('fill')
|
||||
.size(2)
|
||||
.active(false)
|
||||
.color('red')
|
||||
.color('OBJECTID',['#d53e4f','#f46d43','#fdae61','#fee08b','#ffffbf','#e6f598','#abdda4','#66c2a5','#3288bd'])
|
||||
.style({
|
||||
opacity:1.0
|
||||
})
|
||||
|
|
|
@ -58,12 +58,13 @@ scene.on('loaded', () => {
|
|||
}
|
||||
})
|
||||
.shape('fill')
|
||||
.size(1000000)
|
||||
.active(false)
|
||||
.color('OBJECTID',['#d53e4f','#f46d43','#fdae61','#fee08b','#ffffbf','#e6f598','#abdda4','#66c2a5','#3288bd'])
|
||||
.style({
|
||||
opacity:1.0
|
||||
})
|
||||
.render();
|
||||
.render();
|
||||
const layer2 = scene.PolygonLayer({
|
||||
zIndex:10,
|
||||
})
|
||||
|
@ -81,7 +82,7 @@ scene.on('loaded', () => {
|
|||
.style({
|
||||
opacity:1.0
|
||||
})
|
||||
.render();
|
||||
.render();
|
||||
|
||||
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ export default class Renderer {
|
|||
}
|
||||
initRender() {
|
||||
this.renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
antialias: false,
|
||||
alpha: true,
|
||||
autoClear: false
|
||||
});
|
||||
|
@ -17,7 +17,7 @@ export default class Renderer {
|
|||
this.renderer.setPixelRatio(this.pixelRatio);
|
||||
this.renderer.gammaInput = true;
|
||||
this.renderer.gammaOutput = true;
|
||||
this.renderer.shadowMap.enabled = true;
|
||||
this.renderer.shadowMap.enabled = false;
|
||||
this.container.appendChild(this.renderer.domElement);
|
||||
}
|
||||
updateSize() {
|
||||
|
|
|
@ -479,6 +479,7 @@ export default class Layer extends Base {
|
|||
this.scene.on('pick-' + this.layerId, e => {
|
||||
let { featureId, point2d, type } = e;
|
||||
// TODO 瓦片图层获取选中数据信息
|
||||
|
||||
const lnglat = this.scene.containerToLngLat(point2d);
|
||||
let feature = null;
|
||||
let style = null;
|
||||
|
|
|
@ -77,12 +77,7 @@ export default class Scene extends Base {
|
|||
return this.style.getSource(id);
|
||||
}
|
||||
on(type, hander) {
|
||||
|
||||
if (this.map && type !== 'loaded') {
|
||||
this.map.on(type, hander);
|
||||
return;
|
||||
|
||||
}
|
||||
if (this.map) { this.map.on(type, hander); }
|
||||
super.on(type, hander);
|
||||
}
|
||||
off(type, hander) {
|
||||
|
|
|
@ -33,7 +33,9 @@ export default class Source extends Base {
|
|||
// 数据转换 统计,聚合,分类
|
||||
this._executeTrans();
|
||||
// 坐标转换
|
||||
this._projectCoords();
|
||||
if (!this.get('projected')) {
|
||||
this._projectCoords();
|
||||
}
|
||||
}
|
||||
setData(data, cfg = {}) {
|
||||
Object.assign(this._attrs, cfg);
|
||||
|
@ -60,7 +62,7 @@ export default class Source extends Base {
|
|||
// dataArray: clone(this.originData.dataArray)
|
||||
// }; // TODO 关闭数据备份
|
||||
this.data = this.originData;
|
||||
if (this.data !== null) {
|
||||
if (this.data !== null && !this.get('projected')) {
|
||||
this.data.extent = extent(this.data.dataArray);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ export {
|
|||
export { InstancedBufferAttribute } from 'three/src/core/InstancedBufferAttribute'
|
||||
// export * from '../../build/three.js';
|
||||
function Float32BufferAttribute( array, itemSize, normalized ) {
|
||||
if(Array.isArray( array )){
|
||||
array = new Float32Array( array )
|
||||
}
|
||||
BufferAttribute.call( this, array, itemSize, normalized );
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import Base from '../../core/base';
|
||||
export default class BufferBase extends Base {
|
||||
constructor(cfg) {
|
||||
super(cfg);
|
||||
this.attributes = {
|
||||
};
|
||||
this.verticesCount = 0;
|
||||
this.indexCount = 0;
|
||||
this.indexArray = new Int32Array(0);
|
||||
this._init();
|
||||
}
|
||||
_init() {
|
||||
this._calculateFeatures();
|
||||
this._initAttributes();
|
||||
this._buildFeatures();
|
||||
}
|
||||
_initAttributes() {
|
||||
this.attributes.positions = new Float32Array(this.verticesCount * 3);
|
||||
this.attributes.colors = new Float32Array(this.verticesCount * 4);
|
||||
this.attributes.pickingIds = new Float32Array(this.verticesCount);
|
||||
this.attributes.sizes = new Float32Array(this.verticesCount);
|
||||
this.attributes.pickingIds = new Float32Array(this.verticesCount);
|
||||
if (this.get('uv')) {
|
||||
this.attributes.uv = new Float32Array(this.verticesCount * 2);
|
||||
}
|
||||
this.indexArray = new Int32Array(this.indexCount);
|
||||
}
|
||||
addFeature() {
|
||||
|
||||
}
|
||||
// 更新渲染
|
||||
upload() {
|
||||
|
||||
}
|
||||
destroy() {
|
||||
|
||||
}
|
||||
resize() {
|
||||
|
||||
}
|
||||
checkIsClosed(points) {
|
||||
const p1 = points[0][0];
|
||||
const p2 = points[0][points[0].length - 1];
|
||||
return (p1[0] === p2[0] && p1[1] === p2[1]);
|
||||
}
|
||||
concat(arrayType, arrays) {
|
||||
let totalLength = 0;
|
||||
for (const arr of arrays) {
|
||||
totalLength += arr.length;
|
||||
}
|
||||
const arrayBuffer = new ArrayBuffer(totalLength * arrayType.BYTES_PER_ELEMENT);
|
||||
let offset = 0;
|
||||
const result = new arrayType(arrayBuffer);
|
||||
for (const arr of arrays) {
|
||||
result.set(arr, offset);
|
||||
offset += arr.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_encodeArray(feature, num) {
|
||||
const { color, id, pattern, size } = feature;
|
||||
const { verticesOffset } = feature.bufferInfo;
|
||||
const imagePos = this.get('imagePos');
|
||||
const start1 = verticesOffset;
|
||||
for (let i = 0; i < num; i++) {
|
||||
if (feature.hasOwnProperty('color')) {
|
||||
this.attributes.colors[start1 * 4 + i * 4] = color[0];
|
||||
this.attributes.colors[start1 * 4 + i * 4 + 1] = color[1];
|
||||
this.attributes.colors[start1 * 4 + i * 4 + 2] = color[2];
|
||||
this.attributes.colors[start1 * 4 + i * 4 + 3] = color[3];
|
||||
|
||||
}
|
||||
if (feature.hasOwnProperty('id')) {
|
||||
this.attributes.pickingIds[start1 + i] = id;
|
||||
}
|
||||
if (feature.hasOwnProperty('size')) {
|
||||
this.attributes.sizes[start1 + i ] = size[0] || size;
|
||||
}
|
||||
if (feature.hasOwnProperty('pattern')) {
|
||||
|
||||
const patternPos = imagePos[pattern] || { x: 0, y: 0 };
|
||||
this.attributes.patterns[start1 * 2 + i * 2 ] = patternPos.x;
|
||||
this.attributes.patterns[start1 * 2 + i * 2 + 1] = patternPos.y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
_calculateWall(feature) {
|
||||
const size = feature.size;
|
||||
const { vertices, indexOffset, verticesOffset, faceNum } = feature.bufferInfo;
|
||||
this._encodeArray(feature, faceNum * 4);
|
||||
for (let i = 0; i < faceNum; i++) {
|
||||
const prePoint = vertices.slice(i * 3, i * 3 + 3);
|
||||
const nextPoint = vertices.slice(i * 3 + 3, i * 3 + 6);
|
||||
this._calculateExtrudeFace(prePoint, nextPoint, verticesOffset + i * 4, indexOffset + i * 6, size);
|
||||
feature.bufferInfo.verticesOffset += 4;
|
||||
feature.bufferInfo.indexOffset += 6;
|
||||
}
|
||||
}
|
||||
|
||||
_calculateExtrudeFace(prePoint, nextPoint, positionOffset, indexOffset, size) {
|
||||
this.attributes.positions.set([
|
||||
prePoint[0], prePoint[1], size,
|
||||
nextPoint[0], nextPoint[1], size,
|
||||
prePoint[0], prePoint[1], 0,
|
||||
nextPoint[0], nextPoint[1], 0
|
||||
],
|
||||
positionOffset * 3);
|
||||
const indexArray = [ 1, 2, 0, 3, 2, 1 ].map(v => { return v + positionOffset; });
|
||||
if (this.get('uv')) {
|
||||
this.attributes.uv.set([ 0.1, 0, 0, 0, 0.1, size / 2000, 0, size / 2000 ], positionOffset * 2);
|
||||
}
|
||||
this.indexArray.set(indexArray, indexOffset);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -65,18 +65,12 @@ export default class BufferBase extends Base {
|
|||
return mergedAttributes;
|
||||
}
|
||||
_toPolygonAttributes(polygon) {
|
||||
|
||||
// Three components per vertex per face (3 x 3 = 9)
|
||||
const { style, indices, position, indexCount } = polygon;
|
||||
const vertices = new Float32Array(indexCount * 3);
|
||||
const normals = new Float32Array(indexCount * 3);
|
||||
const colors = new Float32Array(indexCount * 4);
|
||||
const pickingIds = new Float32Array(indexCount);
|
||||
const pA = new Vector3();
|
||||
const pB = new Vector3();
|
||||
const pC = new Vector3();
|
||||
|
||||
const cb = new Vector3();
|
||||
const ab = new Vector3();
|
||||
let lastIndex = 0;
|
||||
indices.forEach((indice, pIndex) => {
|
||||
for (let i = 0; i < indice.length / 3; i++) {
|
||||
|
@ -94,72 +88,48 @@ export default class BufferBase extends Base {
|
|||
const cx = position[pIndex][index][0];
|
||||
const cy = position[pIndex][index][1];
|
||||
const cz = position[pIndex][index][2];
|
||||
vertices.set([ ax, ay, az, bx, by, bz, cx, cy, cz ], lastIndex * 9);
|
||||
colors.set([ color[0], color[1], color[2], color[3], color[0], color[1], color[2], color[3], color[0], color[1], color[2], color[3] ], lastIndex * 12);
|
||||
pickingIds.fill(_pickingId, lastIndex * 3 + 0, lastIndex * 3 + 3);
|
||||
// vertices[lastIndex * 9 + 0] = ax;
|
||||
// vertices[lastIndex * 9 + 1] = ay;
|
||||
// vertices[lastIndex * 9 + 2] = az;
|
||||
|
||||
pA.set(ax, ay, az);
|
||||
pB.set(bx, by, bz);
|
||||
pC.set(cx, cy, cz);
|
||||
|
||||
cb.subVectors(pC, pB);
|
||||
ab.subVectors(pA, pB);
|
||||
cb.cross(ab);
|
||||
|
||||
cb.normalize();
|
||||
|
||||
const nx = cb.x;
|
||||
const ny = cb.y;
|
||||
const nz = cb.z;
|
||||
|
||||
vertices[lastIndex * 9 + 0] = ax;
|
||||
vertices[lastIndex * 9 + 1] = ay;
|
||||
vertices[lastIndex * 9 + 2] = az;
|
||||
|
||||
normals[lastIndex * 9 + 0] = nx;
|
||||
normals[lastIndex * 9 + 1] = ny;
|
||||
normals[lastIndex * 9 + 2] = nz;
|
||||
|
||||
colors[lastIndex * 12 + 0] = color[0];
|
||||
colors[lastIndex * 12 + 1] = color[1];
|
||||
colors[lastIndex * 12 + 2] = color[2];
|
||||
colors[lastIndex * 12 + 3] = color[3];
|
||||
// colors[lastIndex * 12 + 0] = color[0];
|
||||
// colors[lastIndex * 12 + 1] = color[1];
|
||||
// colors[lastIndex * 12 + 2] = color[2];
|
||||
// colors[lastIndex * 12 + 3] = color[3];
|
||||
|
||||
|
||||
vertices[lastIndex * 9 + 3] = bx;
|
||||
vertices[lastIndex * 9 + 4] = by;
|
||||
vertices[lastIndex * 9 + 5] = bz;
|
||||
// vertices[lastIndex * 9 + 3] = bx;
|
||||
// vertices[lastIndex * 9 + 4] = by;
|
||||
// vertices[lastIndex * 9 + 5] = bz;
|
||||
|
||||
normals[lastIndex * 9 + 3] = nx;
|
||||
normals[lastIndex * 9 + 4] = ny;
|
||||
normals[lastIndex * 9 + 5] = nz;
|
||||
// colors[lastIndex * 12 + 4] = color[0];
|
||||
// colors[lastIndex * 12 + 5] = color[1];
|
||||
// colors[lastIndex * 12 + 6] = color[2];
|
||||
// colors[lastIndex * 12 + 7] = color[3];
|
||||
|
||||
colors[lastIndex * 12 + 4] = color[0];
|
||||
colors[lastIndex * 12 + 5] = color[1];
|
||||
colors[lastIndex * 12 + 6] = color[2];
|
||||
colors[lastIndex * 12 + 7] = color[3];
|
||||
// vertices[lastIndex * 9 + 6] = cx;
|
||||
// vertices[lastIndex * 9 + 7] = cy;
|
||||
// vertices[lastIndex * 9 + 8] = cz;
|
||||
|
||||
vertices[lastIndex * 9 + 6] = cx;
|
||||
vertices[lastIndex * 9 + 7] = cy;
|
||||
vertices[lastIndex * 9 + 8] = cz;
|
||||
// colors[lastIndex * 12 + 8] = color[0];
|
||||
// colors[lastIndex * 12 + 9] = color[1];
|
||||
// colors[lastIndex * 12 + 10] = color[2];
|
||||
// colors[lastIndex * 12 + 11] = color[3];
|
||||
|
||||
normals[lastIndex * 9 + 6] = nx;
|
||||
normals[lastIndex * 9 + 7] = ny;
|
||||
normals[lastIndex * 9 + 8] = nz;
|
||||
|
||||
colors[lastIndex * 12 + 8] = color[0];
|
||||
colors[lastIndex * 12 + 9] = color[1];
|
||||
colors[lastIndex * 12 + 10] = color[2];
|
||||
colors[lastIndex * 12 + 11] = color[3];
|
||||
|
||||
pickingIds[lastIndex * 3 + 0] = _pickingId;
|
||||
pickingIds[lastIndex * 3 + 1] = _pickingId;
|
||||
pickingIds[lastIndex * 3 + 2] = _pickingId;
|
||||
// pickingIds[lastIndex * 3 + 0] = _pickingId;
|
||||
// pickingIds[lastIndex * 3 + 1] = _pickingId;
|
||||
// pickingIds[lastIndex * 3 + 2] = _pickingId;
|
||||
|
||||
lastIndex++;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
console.timeEnd(indexCount+':buffer');
|
||||
const attributes = {
|
||||
vertices,
|
||||
normals,
|
||||
colors,
|
||||
pickingIds,
|
||||
faceUv: new Float32Array(polygon.faceUv),
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
import PolygonBuffer from './polygon';
|
||||
import LineBuffer from './line';
|
||||
// export { default as textBuffer } from './textBuffer';
|
||||
|
||||
// Polygon
|
||||
|
||||
import FillBuffer from './polygon/fill_buffer';
|
||||
import LineBuffer from './polygon/line_buffer';
|
||||
import ExtrudeBuffer from './polygon/extrude_buffer';
|
||||
|
||||
// Line
|
||||
import MeshLineBuffer from './line/meshline';
|
||||
import ArcLineBuffer from './line/arcline';
|
||||
|
||||
import { registerBuffer, getBuffer } from './factory';
|
||||
registerBuffer('polygon', 'fill', PolygonBuffer);
|
||||
registerBuffer('polygon', 'extrude', PolygonBuffer);
|
||||
registerBuffer('polygon', 'line', PolygonBuffer);
|
||||
registerBuffer('line', 'line', LineBuffer);
|
||||
|
||||
registerBuffer('polygon', 'fill', FillBuffer);
|
||||
registerBuffer('polygon', 'extrude', ExtrudeBuffer);
|
||||
registerBuffer('polygon', 'line', LineBuffer);
|
||||
|
||||
// line
|
||||
registerBuffer('line', 'line', MeshLineBuffer);
|
||||
registerBuffer('line', 'arc', ArcLineBuffer);
|
||||
registerBuffer('line', 'greatCircle', ArcLineBuffer);
|
||||
|
||||
export { getBuffer };
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import BufferBase from '../buffer';
|
||||
export default class ArcLineBuffer extends BufferBase {
|
||||
_buildFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach((feature, index) => {
|
||||
this._calculateArc(feature, index);
|
||||
});
|
||||
}
|
||||
_initAttributes() {
|
||||
super._initAttributes();
|
||||
this.attributes.instanceArray = new Float32Array(this.verticesCount * 4);
|
||||
}
|
||||
_calculateArc(feature, offset) {
|
||||
const { segNum = 30 } = this.get('style');
|
||||
const { coordinates } = feature;
|
||||
for (let i = 0; i < segNum; i++) {
|
||||
this.attributes.positions.set([ i, 1, i, i, -1, i ], offset * segNum * 6 + i * 6);
|
||||
this.attributes.instanceArray.set([ coordinates[0][0], coordinates[0][1], coordinates[1][0], coordinates[1][1],
|
||||
coordinates[0][0], coordinates[0][1], coordinates[1][0], coordinates[1][1] ], offset * segNum * 8 + i * 8);
|
||||
if (i !== segNum - 1) {
|
||||
const indexArray = [ 0, 1, 2, 1, 3, 2 ].map(v => { return offset * segNum * 2 + i * 2 + v; });
|
||||
this.indexArray.set(indexArray, offset * segNum * 6 + i * 6 - offset * 6);
|
||||
}
|
||||
}
|
||||
feature.bufferInfo = { verticesOffset: offset * segNum * 2 };
|
||||
this._encodeArray(feature, segNum * 2);
|
||||
|
||||
}
|
||||
_calculateFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
const segNum = this.get('segNum') || 30;
|
||||
this.verticesCount = layerData.length * segNum * 2;
|
||||
this.indexCount = this.verticesCount * 3 - layerData.length * 6;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
import BufferBase from '../buffer';
|
||||
import getNormals from '../../../util/polyline-normals';
|
||||
export default class MeshLineBuffer extends BufferBase {
|
||||
_buildFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach(feature => {
|
||||
this._calculateLine(feature);
|
||||
delete feature.bufferInfo;
|
||||
});
|
||||
}
|
||||
_initAttributes() {
|
||||
super._initAttributes();
|
||||
this.attributes.dashArray = new Float32Array(this.verticesCount);
|
||||
this.attributes.attrDistance = new Float32Array(this.verticesCount);
|
||||
this.attributes.totalDistances = new Float32Array(this.verticesCount);
|
||||
this.attributes.patterns = new Float32Array(this.verticesCount * 2);
|
||||
this.attributes.miters = new Float32Array(this.verticesCount);
|
||||
this.attributes.normals = new Float32Array(this.verticesCount * 3);
|
||||
}
|
||||
_calculateFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
|
||||
// 计算长
|
||||
layerData.forEach(feature => {
|
||||
const bufferInfo = {};
|
||||
const { coordinates } = feature;
|
||||
const { normals, attrIndex, attrPos, attrDistance, miters } = getNormals(coordinates, false, this.verticesCount);
|
||||
bufferInfo.normals = normals;
|
||||
bufferInfo.arrayIndex = attrIndex;
|
||||
bufferInfo.positions = attrPos;
|
||||
bufferInfo.attrDistance = attrDistance;
|
||||
bufferInfo.miters = miters;
|
||||
bufferInfo.verticesOffset = this.verticesCount;
|
||||
bufferInfo.indexOffset = this.indexCount;
|
||||
this.verticesCount += attrPos.length / 3;
|
||||
this.indexCount += attrIndex.length;
|
||||
feature.bufferInfo = bufferInfo;
|
||||
});
|
||||
}
|
||||
_calculateLine(feature) {
|
||||
const { normals, arrayIndex, positions, attrDistance, miters, verticesOffset, indexOffset } = feature.bufferInfo;
|
||||
const { dashArray = 200 } = this.get('style');
|
||||
|
||||
this._encodeArray(feature, positions.length / 3);
|
||||
const totalLength = attrDistance[attrDistance.length - 1];
|
||||
// 增加长度
|
||||
const totalDistances = Array(positions.length / 3).fill(totalLength);
|
||||
// 虚线比例
|
||||
const ratio = dashArray / totalLength;
|
||||
const dashArrays = Array(positions.length / 3).fill(ratio);
|
||||
this.attributes.positions.set(positions, verticesOffset * 3);
|
||||
this.indexArray.set(arrayIndex, indexOffset);
|
||||
this.attributes.miters.set(miters, verticesOffset);
|
||||
this.attributes.normals.set(normals, verticesOffset * 3);
|
||||
this.attributes.attrDistance.set(attrDistance, verticesOffset);
|
||||
this.attributes.totalDistances.set(totalDistances, verticesOffset);
|
||||
this.attributes.dashArray.set(dashArrays, verticesOffset);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ export default class PolygonBuffer extends BufferBase {
|
|||
geometryBuffer() {
|
||||
const layerData = this.get('layerData');
|
||||
const shape = this.get('shape');
|
||||
const needFaceUv = this.get('faceUv');
|
||||
const positions = [];
|
||||
const faceUv = [];
|
||||
const sizes = [];
|
||||
|
@ -24,7 +25,7 @@ export default class PolygonBuffer extends BufferBase {
|
|||
}
|
||||
positions.push(extrudeData.positions);
|
||||
|
||||
if (shape !== 'line') {
|
||||
if (needFaceUv) {
|
||||
// faceUv.push(...extrudeData.faceUv);
|
||||
const count = extrudeData.faceUv.length / 2;
|
||||
for (let i = 0; i < count; i++) {
|
||||
|
@ -54,7 +55,6 @@ export default class PolygonBuffer extends BufferBase {
|
|||
} else {
|
||||
this.attributes = this._toPolygonLineAttributes(this.bufferStruct);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import BufferBase from '../buffer';
|
||||
import earcut from 'earcut';
|
||||
export default class ExtrudeButffer extends BufferBase {
|
||||
|
||||
_buildFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach(feature => {
|
||||
this._calculateTop(feature);
|
||||
this._calculateWall(feature);
|
||||
delete feature.bufferInfo;
|
||||
});
|
||||
}
|
||||
|
||||
_calculateFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
// 计算长
|
||||
layerData.forEach(feature => {
|
||||
const { coordinates } = feature;
|
||||
const bufferInfo = {};
|
||||
const flattengeo = earcut.flatten(coordinates);
|
||||
const n = this.checkIsClosed(coordinates[0]) ? coordinates[0].length - 1 : coordinates[0].length;
|
||||
const { vertices, dimensions, holes } = flattengeo;
|
||||
const indexArray = earcut(vertices, holes, dimensions).map(v => { return this.verticesCount + v; });
|
||||
bufferInfo.vertices = vertices;
|
||||
bufferInfo.indexArray = indexArray;
|
||||
bufferInfo.verticesOffset = this.verticesCount + 0;
|
||||
bufferInfo.indexOffset = this.indexCount + 0;
|
||||
bufferInfo.faceNum = n;
|
||||
this.indexCount += indexArray.length + n * 6;
|
||||
this.verticesCount += vertices.length / 3 + n * 4;
|
||||
feature.bufferInfo = bufferInfo;
|
||||
|
||||
});
|
||||
}
|
||||
_calculateTop(feature) {
|
||||
const size = feature.size;
|
||||
const { indexArray, vertices, indexOffset, verticesOffset } = feature.bufferInfo;
|
||||
const pointCount = vertices.length / 3;
|
||||
this._encodeArray(feature, vertices.length / 3);
|
||||
// 添加顶点
|
||||
for (let i = 0; i < pointCount; i++) {
|
||||
this.attributes.positions.set([ vertices[ i * 3 ], vertices[i * 3 + 1 ], size ], (verticesOffset + i) * 3);
|
||||
// 顶部文理坐标计算
|
||||
if (this.get('uv')) {
|
||||
// TODO 用过BBox计算纹理坐标
|
||||
this.attributes.uv.set([ -1, -1 ], (verticesOffset + i) * 2);
|
||||
}
|
||||
}
|
||||
feature.bufferInfo.verticesOffset += pointCount;
|
||||
// 添加顶点索引
|
||||
this.indexArray.set(indexArray, indexOffset); // 顶部坐标
|
||||
feature.bufferInfo.indexOffset += indexArray.length;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import BufferBase from '../buffer';
|
||||
import earcut from 'earcut';
|
||||
export default class FillBuffer extends BufferBase {
|
||||
|
||||
_buildFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach(feature => {
|
||||
this._calculateFill(feature);
|
||||
delete feature.bufferInfo;
|
||||
});
|
||||
}
|
||||
|
||||
_calculateFill(feature) {
|
||||
const { indexArray, vertices, indexOffset, verticesOffset } = feature.bufferInfo;
|
||||
const pointCount = vertices.length / 3;
|
||||
this._encodeArray(feature, vertices.length / 3);
|
||||
// 添加顶点
|
||||
for (let i = 0; i < pointCount; i++) {
|
||||
this.attributes.positions.set([ vertices[ i * 3 ], vertices[i * 3 + 1 ], 0 ], (verticesOffset + i) * 3);
|
||||
if (this.get('uv')) {
|
||||
// TODO 用过BBox计算纹理坐标
|
||||
this.attributes.uv.set([ 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 ], (verticesOffset + i) * 3);
|
||||
}
|
||||
}
|
||||
feature.bufferInfo.verticesOffset += pointCount;
|
||||
// 添加顶点索引
|
||||
this.indexArray.set(indexArray, indexOffset); // 顶部坐标
|
||||
feature.bufferInfo.indexOffset += indexArray.length;
|
||||
}
|
||||
|
||||
_calculateFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
// 计算长
|
||||
layerData.forEach(feature => {
|
||||
const { coordinates } = feature;
|
||||
const bufferInfo = {};
|
||||
const flattengeo = earcut.flatten(coordinates);
|
||||
const { vertices, dimensions, holes } = flattengeo;
|
||||
const indexArray = earcut(vertices, holes, dimensions).map(v => { return this.verticesCount + v; });
|
||||
bufferInfo.vertices = vertices;
|
||||
bufferInfo.indexArray = indexArray;
|
||||
bufferInfo.verticesOffset = this.verticesCount + 0;
|
||||
bufferInfo.indexOffset = this.indexCount + 0;
|
||||
this.indexCount += indexArray.length;
|
||||
this.verticesCount += vertices.length / 3;
|
||||
feature.bufferInfo = bufferInfo;
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import BufferBase from '../buffer';
|
||||
|
||||
export default class LineBuffer extends BufferBase {
|
||||
|
||||
|
||||
_buildFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
let offsetVertices = 0;
|
||||
let offsetIndex = 0;
|
||||
let offset = 0;
|
||||
layerData.forEach(feature => {
|
||||
const { coordinates } = feature;
|
||||
coordinates.forEach(coord => {
|
||||
const n = coord.length;
|
||||
feature.bufferInfo = {
|
||||
verticesOffset: offsetVertices
|
||||
};
|
||||
this._encodeArray(feature, n);
|
||||
for (let i = 0; i < n; i++) {
|
||||
this.attributes.positions[offsetVertices * 3] = coord[i][0];
|
||||
this.attributes.positions[offsetVertices * 3 + 1] = coord[i][1];
|
||||
this.attributes.positions[offsetVertices * 3 + 2] = coord[i][2];
|
||||
this.indexArray[offsetIndex * 2] = i + offset;
|
||||
this.indexArray[offsetIndex * 2 + 1] = i + offset + 1;
|
||||
if (i === n - 1) {
|
||||
this.indexArray[offsetIndex * 2 + 1] = offsetVertices - n + 1;
|
||||
}
|
||||
offsetVertices++;
|
||||
offsetIndex++;
|
||||
}
|
||||
offset += n;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_calculateBufferLength() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach(feature => {
|
||||
const { coordinates } = feature;
|
||||
coordinates.forEach(coord => {
|
||||
this.verticesCount += coord.length;
|
||||
this.indexCount += (coord.length * 2 - 2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_calculateFeatures() {
|
||||
const layerData = this.get('layerData');
|
||||
layerData.forEach(feature => {
|
||||
const { coordinates } = feature;
|
||||
coordinates.forEach(coord => {
|
||||
this.verticesCount += coord.length;
|
||||
this.indexCount += (coord.length * 2);
|
||||
});
|
||||
});
|
||||
}
|
||||
_calculateLine(feature) {
|
||||
let { indexOffset, verticesOffset } = feature.bufferInfo;
|
||||
feature.coordinates.forEach(coord => {
|
||||
const n = coord.length;
|
||||
this._encodeArray(feature, n);
|
||||
for (let i = 0; i < n; i++) {
|
||||
this.attributes.positions[(verticesOffset + i) * 3] = coord[i][0];
|
||||
this.attributes.positions[(verticesOffset + i) * 3 + 1] = coord[i][1];
|
||||
this.attributes.positions[(verticesOffset + i) * 3 + 2] = coord[i][2];
|
||||
this.indexArray[(indexOffset + i) * 2] = i + verticesOffset * 2;
|
||||
this.indexArray[(indexOffset + i) * 2 + 1] = i + verticesOffset * 2 + 1;
|
||||
if (i === n - 1) {
|
||||
this.indexArray[(indexOffset + i) * 2 + 1] = verticesOffset + 1;
|
||||
}
|
||||
|
||||
}
|
||||
verticesOffset += n;
|
||||
indexOffset += n;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ export default function extrudePolygon(points, extrude) {
|
|||
if (p1[0] === p2[0] && p1[1] === p2[1]) {
|
||||
points[0] = points[0].slice(0, points[0].length - 1);
|
||||
}
|
||||
|
||||
const n = points[0].length;
|
||||
const flattengeo = earcut.flatten(points);
|
||||
const positions = [];
|
||||
|
|
|
@ -16,7 +16,7 @@ varying vec4 v_color;
|
|||
|
||||
uniform float u_zoom : 0;
|
||||
uniform float u_opacity : 1.0;
|
||||
uniform float u_activeId : 0;
|
||||
uniform float u_activeId : -1;
|
||||
uniform vec4 u_activeColor : [1.0, 0.0, 0.0, 1.0];
|
||||
|
||||
#pragma include "lighting"
|
||||
|
@ -37,7 +37,7 @@ void main() {
|
|||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position + offset, 1.);
|
||||
|
||||
#ifdef LIGHTING
|
||||
if (normal != vec3(0., 0., 1.)) {
|
||||
if (normal != vec3(0., 0., 1.0)) {
|
||||
vec3 viewDir = normalize(cameraPosition - position);
|
||||
v_color.rgb *= calc_lighting(position, normal, viewDir);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
precision highp float;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0);
|
||||
gl_FragColor = vec4(0.0,0.,0.,1.0);
|
||||
}
|
|
@ -18,7 +18,7 @@ export default class LineLayer extends Layer {
|
|||
}
|
||||
draw() {
|
||||
this.type = 'line';
|
||||
this.add(getRender('line', this.shapeType || 'line')(this.layerData, this, this.layerSource));
|
||||
this.add(getRender('line', this.shapeType || 'line')(this.layerData, this));
|
||||
}
|
||||
}
|
||||
LineLayer.type = 'line';
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
import * as THREE from '../../../core/three';
|
||||
import LineBuffer from '../../../geom/buffer/line';
|
||||
import { ArcLineMaterial } from '../../../geom/material/lineMaterial';
|
||||
export default function DrawArcLine(layerdata, layer) {
|
||||
import { getBuffer } from '../../../geom/buffer/';
|
||||
export default function DrawArcLine(layerData, layer, buffer) {
|
||||
const style = layer.get('styleOptions');
|
||||
const activeOption = layer.get('activedOptions');
|
||||
const { attributes } = new LineBuffer({
|
||||
layerData: layerdata,
|
||||
shapeType: 'arc',
|
||||
style
|
||||
});
|
||||
if (!buffer) {
|
||||
const geometryBuffer = getBuffer(layer.type, layer.shapeType);
|
||||
buffer = new geometryBuffer({
|
||||
layerData,
|
||||
shapeType: layer.shapeType,
|
||||
style
|
||||
});
|
||||
|
||||
}
|
||||
const { attributes, indexArray } = buffer;
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setIndex(attributes.indexArray);
|
||||
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
|
||||
geometry.setIndex(new THREE.Uint32BufferAttribute(indexArray, 1));
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
|
||||
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
|
||||
geometry.addAttribute('a_instance', new THREE.Float32BufferAttribute(attributes.instances, 4));
|
||||
geometry.addAttribute('a_instance', new THREE.Float32BufferAttribute(attributes.instanceArray, 4));
|
||||
geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
|
||||
|
||||
const lineMaterial = new ArcLineMaterial({
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import * as THREE from '../../../core/three';
|
||||
import LineBuffer from '../../../geom/buffer/line';
|
||||
import { MeshLineMaterial } from '../../../geom/material/lineMaterial';
|
||||
import { getBuffer } from '../../../geom/buffer/';
|
||||
|
||||
export default function DrawLine(layerData, layer) {
|
||||
export default function DrawLine(layerData, layer, buffer) {
|
||||
|
||||
const style = layer.get('styleOptions');
|
||||
const animateOptions = layer.get('animateOptions');
|
||||
|
@ -12,25 +12,31 @@ export default function DrawLine(layerData, layer) {
|
|||
const hasPattern = layerData.some(layer => {
|
||||
return layer.pattern;
|
||||
});
|
||||
const { attributes } = new LineBuffer({
|
||||
layerData,
|
||||
shapeType: 'line',
|
||||
style,
|
||||
imagePos: layer.scene.image.imagePos
|
||||
});
|
||||
if (!buffer) {
|
||||
const geometryBuffer = getBuffer(layer.type, layer.shapeType);
|
||||
buffer = new geometryBuffer({
|
||||
layerData,
|
||||
shapeType: 'line',
|
||||
style,
|
||||
imagePos: layer.scene.image.imagePos
|
||||
});
|
||||
|
||||
}
|
||||
const { attributes, indexArray } = buffer;
|
||||
|
||||
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setIndex(attributes.indexArray);
|
||||
geometry.setIndex(new THREE.Uint32BufferAttribute(indexArray, 1));
|
||||
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
|
||||
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
|
||||
geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
|
||||
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normal, 3));
|
||||
geometry.addAttribute('a_miter', new THREE.Float32BufferAttribute(attributes.miter, 1));
|
||||
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
|
||||
geometry.addAttribute('a_miter', new THREE.Float32BufferAttribute(attributes.miters, 1));
|
||||
geometry.addAttribute('a_distance', new THREE.Float32BufferAttribute(attributes.attrDistance, 1));
|
||||
geometry.addAttribute('a_dash_array', new THREE.Float32BufferAttribute(attributes.attrDashArray, 1));
|
||||
geometry.addAttribute('a_texture_coord', new THREE.Float32BufferAttribute(attributes.textureCoord, 2));
|
||||
geometry.addAttribute('a_total_distance', new THREE.Float32BufferAttribute(attributes.totalDistance, 1));
|
||||
|
||||
geometry.addAttribute('a_dash_array', new THREE.Float32BufferAttribute(attributes.dashArray, 1));
|
||||
geometry.addAttribute('a_texture_coord', new THREE.Float32BufferAttribute(attributes.patterns, 2));
|
||||
geometry.addAttribute('a_total_distance', new THREE.Float32BufferAttribute(attributes.totalDistances, 1));
|
||||
const lineMaterial = new MeshLineMaterial({
|
||||
u_opacity: style.opacity,
|
||||
u_zoom: layer.scene.getZoom(),
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
import * as THREE from '../../../core/three';
|
||||
import PolygonBuffer from '../../../geom/buffer/polygon';
|
||||
import PolygonMaterial from '../../../geom/material/polygonMaterial';
|
||||
import { getBuffer } from '../../../geom/buffer/';
|
||||
import { generateLightingUniforms } from '../../../util/shaderModule';
|
||||
|
||||
export default function DrawAnimate(layerData, layer) {
|
||||
export default function DrawAnimate(layerData, layer, buffer) {
|
||||
const style = layer.get('styleOptions');
|
||||
const { near, far } = layer.map.getCameraState();
|
||||
layer.scene.startAnimate();
|
||||
const { attributes } = new PolygonBuffer({
|
||||
shape: 'extrude',
|
||||
layerData
|
||||
});
|
||||
if (!buffer) {
|
||||
const geometryBuffer = getBuffer(layer.type, 'extrude');
|
||||
buffer = new geometryBuffer({
|
||||
layerData,
|
||||
uv: true
|
||||
});
|
||||
|
||||
}
|
||||
const { attributes, indexArray } = buffer;
|
||||
const { opacity, baseColor, brightColor, windowColor, lights } = style;
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
|
||||
if (indexArray) {
|
||||
geometry.setIndex(new THREE.Uint32BufferAttribute(indexArray, 1));
|
||||
}
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
|
||||
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
|
||||
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
|
||||
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
|
||||
geometry.addAttribute('faceUv', new THREE.Float32BufferAttribute(attributes.faceUv, 2));
|
||||
geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
|
||||
geometry.addAttribute('faceUv', new THREE.Float32BufferAttribute(attributes.uv, 2));
|
||||
// geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
|
||||
geometry.computeVertexNormals();
|
||||
const material = new PolygonMaterial({
|
||||
u_opacity: opacity,
|
||||
u_baseColor: baseColor,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as THREE from '../../../core/three';
|
||||
import PolygonBuffer from '../../../geom/buffer/polygon';
|
||||
import PolygonMaterial from '../../../geom/material/polygonMaterial';
|
||||
import { generateLightingUniforms } from '../../../util/shaderModule';
|
||||
import { getBuffer } from '../../../geom/buffer/';
|
||||
|
||||
export default function DrawPolygonFill(layerData, layer, buffer) {
|
||||
const style = layer.get('styleOptions');
|
||||
|
@ -11,18 +11,22 @@ export default function DrawPolygonFill(layerData, layer, buffer) {
|
|||
activeColor: activeOption.fill
|
||||
};
|
||||
const { opacity, activeColor, lights } = config;
|
||||
let attributes = buffer;
|
||||
if (!attributes) {
|
||||
attributes = new PolygonBuffer({
|
||||
shape: layer.shape,
|
||||
if (!buffer) {
|
||||
const geometryBuffer = getBuffer(layer.type, layer.shape);
|
||||
buffer = new geometryBuffer({
|
||||
layerData
|
||||
}).attributes;
|
||||
});
|
||||
|
||||
}
|
||||
const { attributes, indexArray } = buffer;
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
|
||||
if (indexArray) {
|
||||
geometry.setIndex(new THREE.Uint32BufferAttribute(indexArray, 1));
|
||||
}
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
|
||||
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
|
||||
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
|
||||
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
|
||||
geometry.computeVertexNormals();
|
||||
const material = new PolygonMaterial({
|
||||
u_opacity: opacity,
|
||||
u_activeColor: activeColor,
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function DrawPolygonLine(layerData, layer, buffer) {
|
|||
activeColor: activeOption.fill
|
||||
};
|
||||
const { opacity } = config;
|
||||
let attributes = buffer;
|
||||
let { attributes, indexArray } = buffer;
|
||||
if (!attributes) {
|
||||
attributes = new PolygonBuffer({
|
||||
shape: layer.shape,
|
||||
|
@ -17,7 +17,10 @@ export default function DrawPolygonLine(layerData, layer, buffer) {
|
|||
}).attributes;
|
||||
}
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
|
||||
if (indexArray) {
|
||||
geometry.setIndex(new THREE.Uint32BufferAttribute(indexArray, 1));
|
||||
}
|
||||
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
|
||||
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
|
||||
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
|
||||
const lineMaterial = new LineMaterial({
|
||||
|
|
|
@ -27,7 +27,6 @@ export default class Tile extends Base {
|
|||
this._object3D.onBeforeRender = () => {
|
||||
};
|
||||
this._isLoaded = false;
|
||||
console.time(this._tile);
|
||||
this.requestTileAsync(data => this._init(data));
|
||||
}
|
||||
_init(data) {
|
||||
|
@ -41,7 +40,6 @@ export default class Tile extends Base {
|
|||
this.isValid = true;
|
||||
this._initControllers();
|
||||
this._createMesh();
|
||||
console.timeEnd(this._tile);
|
||||
}
|
||||
repaint() {
|
||||
this._initControllers();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { destoryObject, updateObjecteUniform } from '../../util/object3d-util';
|
||||
import * as THREE from '../../core/three';
|
||||
import MaskMaterial from '../../geom/material/tile/maskMaterial';
|
||||
import { aProjectFlat } from '../../geo/project';
|
||||
import { toLngLatBounds, toBounds } from '@antv/geo-coord';
|
||||
import { getRender } from '../render/index';
|
||||
const r2d = 180 / Math.PI;
|
||||
|
@ -18,8 +19,10 @@ export default class VectorTileMesh {
|
|||
|
||||
this._centerLnglat = this._tileLnglatBounds.getCenter();
|
||||
this._init(data);
|
||||
|
||||
this.maskScene = new THREE.Scene();
|
||||
const tileMesh = this._tileMaskMesh();
|
||||
// this._object3D.add(tileMesh);
|
||||
this.maskScene.add(tileMesh);
|
||||
}
|
||||
_init(data) {
|
||||
|
@ -30,8 +33,8 @@ export default class VectorTileMesh {
|
|||
if (this.layer.get('type') === 'point') {
|
||||
this.layer.shape = this.layer._getShape(layerData);
|
||||
}
|
||||
this.mesh = getRender(this.layer.get('type'), this.layer.shape)(null, this.layer, data.attributes);
|
||||
this.mesh.frustumCulled = false;
|
||||
this.mesh = getRender(this.layer.get('type'), this.layer.shape)(null, this.layer, data.buffer);
|
||||
// this._setTilePositon();
|
||||
if (this.mesh.type !== 'composer') { // 热力图的情况
|
||||
this.mesh.onBeforeRender = renderer => {
|
||||
this._renderMask(renderer);
|
||||
|
@ -52,14 +55,9 @@ export default class VectorTileMesh {
|
|||
}
|
||||
|
||||
_renderMask(renderer) {
|
||||
const zoom = this.layer.scene.getZoom();
|
||||
updateObjecteUniform(this.mesh, {
|
||||
u_time: this.layer.scene._engine.clock.getElapsedTime(),
|
||||
u_zoom: zoom
|
||||
});
|
||||
if (this.layer.get('layerType') === 'point') { // 点图层目前不需要mask
|
||||
return;
|
||||
}
|
||||
// if (this.layer.get('layerType') === 'point') { // 点图层目前不需要mask
|
||||
// return;
|
||||
// }
|
||||
const context = renderer.context;
|
||||
renderer.autoClear = false;
|
||||
renderer.clearDepth();
|
||||
|
@ -81,6 +79,16 @@ export default class VectorTileMesh {
|
|||
context.stencilFunc(context.EQUAL, 1, 0xffffffff); // draw if == 1
|
||||
context.stencilOp(context.KEEP, context.KEEP, context.KEEP);
|
||||
}
|
||||
_setTilePositon() {
|
||||
const tr = this._tileLnglatBounds.getNorthWest();
|
||||
const zoom = this.layer.scene.getZoom();
|
||||
// const centerPoint = this.layer.scene.crs.lngLatToPoint(tr, 20);
|
||||
const position = aProjectFlat([ tr.lng, tr.lat ]);
|
||||
// this.mesh.position.x = position.x;
|
||||
// this.mesh.position.y = position.y;
|
||||
// this.mesh.scale.x = 2 << (20 - this._tile[2]);
|
||||
// this.mesh.scale.y = 2 << (20 - this._tile[2]);
|
||||
}
|
||||
_tileMaskMesh() {
|
||||
const tilebound = this._tileBounds;
|
||||
const bl = [ tilebound.getBottomLeft().x, tilebound.getBottomLeft().y, 0 ];
|
||||
|
|
|
@ -6,6 +6,7 @@ import csv from './parser/csv';
|
|||
import json from './parser/json';
|
||||
import raster from './parser/raster';
|
||||
import mvt from './parser/mvt';
|
||||
import vector from './parser/vector';
|
||||
|
||||
import { registerTransform, registerParser } from './factory';
|
||||
import { aggregatorToGrid } from './transform/grid';
|
||||
|
@ -18,6 +19,7 @@ registerParser('csv', csv);
|
|||
registerParser('json', json);
|
||||
registerParser('raster', raster);
|
||||
registerParser('mvt', mvt);
|
||||
registerParser('vector', vector);
|
||||
// 注册transform
|
||||
|
||||
registerTransform('grid', aggregatorToGrid);
|
||||
|
|
|
@ -4,9 +4,8 @@ import { djb2hash } from '../../util/bkdr-hash';
|
|||
import rewind from '@mapbox/geojson-rewind';
|
||||
export default function geoJSON(data, cfg) {
|
||||
// 矢量瓦片图层不做 rewind
|
||||
if (!cfg.hasOwnProperty('sourceLayer')) {
|
||||
rewind(data, true);
|
||||
}
|
||||
|
||||
rewind(data, true);
|
||||
const resultData = [];
|
||||
const featureKeys = {};
|
||||
data.features = data.features.filter(item => {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
import { djb2hash } from '../../util/bkdr-hash';
|
||||
const Extent = 4096;
|
||||
export default function vector(data, cfg) {
|
||||
const tile = cfg.tile;
|
||||
const resultdata = [];
|
||||
const featureKeys = {};
|
||||
const x0 = Extent * tile[0];
|
||||
const y0 = Extent * tile[1];
|
||||
function covertP20(points) {
|
||||
return points.map(point => {
|
||||
const x1 = (x0 + point.x << 20 - tile[2] - 4) - 215440491;
|
||||
const y2 = (y0 + point.y << 20 - tile[2] - 4) - 106744817;
|
||||
return [ x1, -y2, 0 ];
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const feature = data.feature(i);
|
||||
const coords = feature.loadGeometry();
|
||||
const properties = feature.properties;
|
||||
let id = i + 1;
|
||||
if (cfg.idField && properties[cfg.idField]) {
|
||||
const value = properties[cfg.idField];
|
||||
id = djb2hash(value) % 1000019;
|
||||
featureKeys[id] = {
|
||||
index: i++,
|
||||
idField: value
|
||||
};
|
||||
}
|
||||
const geocoords = classifyRings(coords);
|
||||
for (let j = 0; j < geocoords.length; j++) {
|
||||
const geo = geocoords[j].map(coord => {
|
||||
return covertP20(coord);
|
||||
});
|
||||
resultdata.push({
|
||||
...properties,
|
||||
_id: feature.id || id,
|
||||
coordinates: geo
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
dataArray: resultdata,
|
||||
featureKeys
|
||||
};
|
||||
|
||||
}
|
||||
function signedArea(ring) {
|
||||
let sum = 0;
|
||||
for (let i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
|
||||
p1 = ring[i];
|
||||
p2 = ring[j];
|
||||
sum += (p2.x - p1.x) * (p1.y + p2.y);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
function classifyRings(rings) {
|
||||
const len = rings.length;
|
||||
if (len <= 1) return [ rings ];
|
||||
const polygons = [];
|
||||
let polygon;
|
||||
let ccw;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const area = signedArea(rings[i]);
|
||||
if (area === 0) continue;
|
||||
|
||||
if (ccw === undefined) ccw = area < 0;
|
||||
|
||||
if (ccw === area < 0) {
|
||||
if (polygon) polygons.push(polygon);
|
||||
polygon = [ rings[i] ];
|
||||
|
||||
} else {
|
||||
polygon.push(rings[i]);
|
||||
}
|
||||
}
|
||||
if (polygon) polygons.push(polygon);
|
||||
|
||||
return polygons;
|
||||
}
|
|
@ -10,7 +10,7 @@ export default class SouceCache extends Base {
|
|||
cacheLimit: 50,
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
keepBuffer: 1,
|
||||
keepBuffer: 0,
|
||||
...cfg
|
||||
});
|
||||
this._tileMap = {};// 视野内瓦片坐标序列
|
||||
|
@ -88,7 +88,7 @@ export default class SouceCache extends Base {
|
|||
_calculateTileIDs() {
|
||||
this._tileMap = {};
|
||||
this.updateTileList = [];
|
||||
const zoom = Math.floor(this.scene.getZoom()) - 1; // zoom - 1
|
||||
const zoom = Math.floor(this.scene.getZoom()); // - window.window.devicePixelRatio + 1; // zoom - 1
|
||||
const minSourceZoom = this.get('minZoom');
|
||||
const maxSourceZoom = this.get('maxZoom');
|
||||
this.tileZoom = zoom > maxSourceZoom ? maxSourceZoom : zoom;
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
* 对于 polyline-normal 的改进
|
||||
* 超过阈值,miter 转成 bevel 接头,
|
||||
* 要注意 Three.js 中默认 THREE.FrontFaceDirectionCCW
|
||||
* @see https://zhuanlan.zhihu.com/p/59541559
|
||||
*/
|
||||
import { direction, normal, computeMiter } from 'polyline-miter-util';
|
||||
import { create, copy, dot } from 'gl-vec2';
|
||||
|
||||
function extrusions(positions, out, point, normal, scale) {
|
||||
addNext(out, normal, -scale);
|
||||
addNext(out, normal, scale);
|
||||
positions.push(point);
|
||||
positions.push(point);
|
||||
}
|
||||
|
||||
function addNext(out, normal, length) {
|
||||
out.push([[ normal[0], normal[1] ], length ]);
|
||||
}
|
||||
|
||||
function lineSegmentDistance(end, start) {
|
||||
const dx = start[0] - end[0];
|
||||
const dy = start[1] - end[1];
|
||||
const dz = start[2] - end[2];
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
export default function(points, closed, indexOffset) {
|
||||
const lineA = [ 0, 0 ];
|
||||
const lineB = [ 0, 0 ];
|
||||
const tangent = [ 0, 0 ];
|
||||
const miter = [ 0, 0 ];
|
||||
let _lastFlip = -1;
|
||||
let _started = false;
|
||||
let _normal = null;
|
||||
const tmp = create();
|
||||
let count = indexOffset || 0;
|
||||
const miterLimit = 3;
|
||||
|
||||
const out = [];
|
||||
const attrPos = [];
|
||||
const attrIndex = [];
|
||||
const attrDistance = [ 0, 0 ];
|
||||
if (closed) {
|
||||
points = points.slice();
|
||||
points.push(points[0]);
|
||||
}
|
||||
|
||||
const total = points.length;
|
||||
|
||||
for (let i = 1; i < total; i++) {
|
||||
const index = count;
|
||||
const last = points[i - 1];
|
||||
const cur = points[i];
|
||||
const next = i < points.length - 1 ? points[i + 1] : null;
|
||||
const d = lineSegmentDistance(cur, last) + attrDistance[attrDistance.length - 1];
|
||||
|
||||
direction(lineA, cur, last);
|
||||
|
||||
if (!_normal) {
|
||||
_normal = [ 0, 0 ];
|
||||
normal(_normal, lineA);
|
||||
}
|
||||
|
||||
if (!_started) {
|
||||
_started = true;
|
||||
extrusions(attrPos, out, last, _normal, 1);
|
||||
}
|
||||
|
||||
attrIndex.push([ index + 0, index + 2, index + 1 ]);
|
||||
|
||||
// no miter, simple segment
|
||||
if (!next) {
|
||||
// reset normal
|
||||
normal(_normal, lineA);
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrDistance.push(d, d);
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
count += 2;
|
||||
} else {
|
||||
// get unit dir of next line
|
||||
direction(lineB, next, cur);
|
||||
|
||||
// stores tangent & miter
|
||||
let miterLen = computeMiter(tangent, miter, lineA, lineB, 1);
|
||||
|
||||
// get orientation
|
||||
const flip = (dot(tangent, _normal) < 0) ? -1 : 1;
|
||||
const bevel = Math.abs(miterLen) > miterLimit;
|
||||
|
||||
// 处理前后两条线段重合的情况,这种情况不需要使用任何接头(miter/bevel)。
|
||||
// 理论上这种情况下 miterLen = Infinity,本应通过 isFinite(miterLen) 判断,
|
||||
// 但是 AMap 投影变换后丢失精度,只能通过一个阈值(1000)判断。
|
||||
if (Math.abs(miterLen) > 1000) {
|
||||
normal(_normal, lineA);
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrDistance.push(d, d);
|
||||
attrIndex.push(
|
||||
_lastFlip === 1 ? [ index + 1, index + 3, index + 2 ]
|
||||
: [ index, index + 2, index + 3 ]
|
||||
);
|
||||
|
||||
// 避免在 Material 中使用 THREE.DoubleSide
|
||||
attrIndex.push([ index + 2, index + 3, index + 4 ]);
|
||||
|
||||
count += 2;
|
||||
_lastFlip = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bevel) {
|
||||
miterLen = miterLimit;
|
||||
|
||||
// next two points in our first segment
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
|
||||
// now add the bevel triangle
|
||||
attrIndex.push(flip === 1 ? [ index + 2, index + 4, index + 5 ] : [ index + 4, index + 5, index + 3 ]);
|
||||
|
||||
normal(tmp, lineB);
|
||||
copy(_normal, tmp); // store normal for next round
|
||||
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrDistance.push(d, d, d, d);
|
||||
|
||||
// the miter is now the normal for our next join
|
||||
count += 4;
|
||||
} else {
|
||||
// next two points in our first segment
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
|
||||
// now add the miter triangles
|
||||
addNext(out, miter, miterLen * -flip);
|
||||
attrPos.push(cur);
|
||||
attrIndex.push([ index + 2, index + 4, index + 3 ]);
|
||||
attrIndex.push([ index + 4, index + 5, index + 6 ]);
|
||||
normal(tmp, lineB);
|
||||
copy(_normal, tmp); // store normal for next round
|
||||
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrDistance.push(d, d, d, d, d);
|
||||
|
||||
// the miter is now the normal for our next join
|
||||
count += 5;
|
||||
}
|
||||
_lastFlip = flip;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
normals: out,
|
||||
attrIndex,
|
||||
attrPos,
|
||||
attrDistance
|
||||
};
|
||||
}
|
|
@ -7,15 +7,16 @@
|
|||
import { direction, normal, computeMiter } from 'polyline-miter-util';
|
||||
import { create, copy, dot } from 'gl-vec2';
|
||||
|
||||
function extrusions(positions, out, point, normal, scale) {
|
||||
addNext(out, normal, -scale);
|
||||
addNext(out, normal, scale);
|
||||
positions.push(point);
|
||||
positions.push(point);
|
||||
function extrusions(positions, out, miters, point, normal, scale) {
|
||||
addNext(out, miters, normal, -scale);
|
||||
addNext(out, miters, normal, scale);
|
||||
positions.push(...point);
|
||||
positions.push(...point);
|
||||
}
|
||||
|
||||
function addNext(out, normal, length) {
|
||||
out.push([[ normal[0], normal[1] ], length ]);
|
||||
function addNext(out, miters, normal, length) {
|
||||
out.push(normal[0], normal[1], 0);
|
||||
miters.push(length);
|
||||
}
|
||||
|
||||
function lineSegmentDistance(end, start) {
|
||||
|
@ -40,6 +41,7 @@ export default function(points, closed, indexOffset) {
|
|||
const out = [];
|
||||
const attrPos = [];
|
||||
const attrIndex = [];
|
||||
const miters = [];
|
||||
const attrDistance = [ 0, 0 ];
|
||||
if (closed) {
|
||||
points = points.slice();
|
||||
|
@ -64,18 +66,18 @@ export default function(points, closed, indexOffset) {
|
|||
|
||||
if (!_started) {
|
||||
_started = true;
|
||||
extrusions(attrPos, out, last, _normal, 1);
|
||||
extrusions(attrPos, out, miters, last, _normal, 1);
|
||||
}
|
||||
|
||||
attrIndex.push([ index + 0, index + 2, index + 1 ]);
|
||||
attrIndex.push(index + 0, index + 2, index + 1);
|
||||
|
||||
// no miter, simple segment
|
||||
if (!next) {
|
||||
// reset normal
|
||||
normal(_normal, lineA);
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
attrDistance.push(d, d);
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
attrIndex.push(index + 1, index + 2, index + 3);
|
||||
count += 2;
|
||||
} else {
|
||||
// get unit dir of next line
|
||||
|
@ -93,15 +95,14 @@ export default function(points, closed, indexOffset) {
|
|||
// 但是 AMap 投影变换后丢失精度,只能通过一个阈值(1000)判断。
|
||||
if (Math.abs(miterLen) > 1000) {
|
||||
normal(_normal, lineA);
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
attrDistance.push(d, d);
|
||||
attrIndex.push(
|
||||
_lastFlip === 1 ? [ index + 1, index + 3, index + 2 ]
|
||||
: [ index, index + 2, index + 3 ]
|
||||
);
|
||||
const indexData = _lastFlip === 1 ? [ index + 1, index + 3, index + 2 ]
|
||||
: [ index, index + 2, index + 3 ];
|
||||
attrIndex.push(...indexData);
|
||||
|
||||
// 避免在 Material 中使用 THREE.DoubleSide
|
||||
attrIndex.push([ index + 2, index + 3, index + 4 ]);
|
||||
attrIndex.push(index + 2, index + 3, index + 4);
|
||||
|
||||
count += 2;
|
||||
_lastFlip = -1;
|
||||
|
@ -112,35 +113,35 @@ export default function(points, closed, indexOffset) {
|
|||
miterLen = miterLimit;
|
||||
|
||||
// next two points in our first segment
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
attrIndex.push(index + 1, index + 2, index + 3);
|
||||
|
||||
// now add the bevel triangle
|
||||
attrIndex.push(flip === 1 ? [ index + 2, index + 4, index + 5 ] : [ index + 4, index + 5, index + 3 ]);
|
||||
attrIndex.push(...(flip === 1 ? [ index + 2, index + 4, index + 5 ] : [ index + 4, index + 5, index + 3 ]));
|
||||
|
||||
normal(tmp, lineB);
|
||||
copy(_normal, tmp); // store normal for next round
|
||||
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
attrDistance.push(d, d, d, d);
|
||||
|
||||
// the miter is now the normal for our next join
|
||||
count += 4;
|
||||
} else {
|
||||
// next two points in our first segment
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
attrIndex.push([ index + 1, index + 2, index + 3 ]);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
attrIndex.push(index + 1, index + 2, index + 3);
|
||||
|
||||
// now add the miter triangles
|
||||
addNext(out, miter, miterLen * -flip);
|
||||
attrPos.push(cur);
|
||||
attrIndex.push([ index + 2, index + 4, index + 3 ]);
|
||||
attrIndex.push([ index + 4, index + 5, index + 6 ]);
|
||||
addNext(out, miters, miter, miterLen * -flip);
|
||||
attrPos.push(...cur);
|
||||
attrIndex.push(index + 2, index + 4, index + 3);
|
||||
attrIndex.push(index + 4, index + 5, index + 6);
|
||||
normal(tmp, lineB);
|
||||
copy(_normal, tmp); // store normal for next round
|
||||
|
||||
extrusions(attrPos, out, cur, _normal, 1);
|
||||
extrusions(attrPos, out, miters, cur, _normal, 1);
|
||||
attrDistance.push(d, d, d, d, d);
|
||||
|
||||
// the miter is now the normal for our next join
|
||||
|
@ -154,6 +155,7 @@ export default function(points, closed, indexOffset) {
|
|||
normals: out,
|
||||
attrIndex,
|
||||
attrPos,
|
||||
attrDistance
|
||||
attrDistance,
|
||||
miters
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,37 +16,33 @@ export default class WorkerTile {
|
|||
const sourceLayerData = {};
|
||||
// 数据源解析
|
||||
for (const sourcelayer in sourceStyle) { // sourceLayer
|
||||
const features = [];
|
||||
const vectorLayer = data.layers[sourcelayer];
|
||||
if (vectorLayer === undefined) {
|
||||
return null;
|
||||
}
|
||||
for (let i = 0; i < vectorLayer.length; i++) {
|
||||
const feature = vectorLayer.feature(i);
|
||||
const geofeature = feature.toGeoJSON(tile[0], tile[1], tile[2]);
|
||||
features.push(geofeature);
|
||||
}
|
||||
const geodata = {
|
||||
type: 'FeatureCollection',
|
||||
features
|
||||
};
|
||||
delete data.layers[sourcelayer];
|
||||
const style = sourceStyle[sourcelayer][0];
|
||||
style.sourceOption.parser.type = 'vector';
|
||||
style.sourceOption.parser.tile = tile;
|
||||
const tileSource2 = new Source({
|
||||
...style.sourceOption,
|
||||
mapType: style.mapType,
|
||||
projected: true,
|
||||
data: data.layers[sourcelayer]
|
||||
});
|
||||
|
||||
for (let i = 0; i < sourceStyle[sourcelayer].length; i++) {
|
||||
const style = sourceStyle[sourcelayer][i];
|
||||
style.sourceOption.parser.type = 'geojson';
|
||||
const tileSource = new Source({
|
||||
...style.sourceOption,
|
||||
mapType: style.mapType,
|
||||
data: geodata
|
||||
});
|
||||
const tileMapping = new TileMapping(tileSource, style);
|
||||
const tileMapping = new TileMapping(tileSource2, style);
|
||||
const geometryBuffer = getBuffer(style.type, style.shape);
|
||||
const buffer = new geometryBuffer({
|
||||
layerData: tileMapping.layerData,
|
||||
shape: style.shape
|
||||
});
|
||||
sourceLayerData[style.layerId] = {
|
||||
attributes: buffer.attributes,
|
||||
buffer: {
|
||||
attributes: buffer.attributes,
|
||||
indexArray: buffer.indexArray
|
||||
},
|
||||
// layerData: tileMapping.layerData,
|
||||
// sourceData: tileSource.data,
|
||||
layerId: style.layerId,
|
||||
|
|
|
@ -35,5 +35,4 @@ export default class WorkerPool {
|
|||
}
|
||||
}
|
||||
|
||||
WorkerPool.workerCount = 1;
|
||||
// Math.max(Math.floor(window.navigator.hardwareConcurrency / 2), 1);
|
||||
WorkerPool.workerCount = Math.max(Math.floor(window.navigator.hardwareConcurrency / 2), 1);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
|||
import { expect } from 'chai';
|
||||
import FillBuffer from '../../../../../src/geom/buffer/polygon/fill_buffer';
|
||||
import { layerData } from '../../../../asset/data/layer_data';
|
||||
describe('FillBuffer', () => {
|
||||
it('fill buffer', () => {
|
||||
console.time('buffer');
|
||||
const fillBuffer = new FillBuffer({
|
||||
layerData
|
||||
});
|
||||
console.timeEnd('buffer');
|
||||
console.log(fillBuffer);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue