refator(polygonLayer): update polygon Layer

This commit is contained in:
李正学 2019-01-20 20:44:49 +08:00
parent 16e0fefb1d
commit 000b941f61
49 changed files with 503 additions and 220 deletions

View File

@ -86,16 +86,16 @@ scene.on('loaded', () => {
opacity: 1 opacity: 1
}) })
.render(); .render();
/**
const citylayer2 = scene.PolygonLayer() const citylayer2 = scene.PolygonLayer()
.source(city) .source(city)
.shape('line') .shape('line')
.color('#fff') .color('#fff')
.style({ .style({
opacity: 0.1 opacity: 1.0
}) })
// .render(); .render();
**/
citylayer.on('click',(e)=>{ citylayer.on('click',(e)=>{
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'}); $("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 KiB

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -46,38 +46,16 @@ scene.on('loaded', () => {
interval:1, interval:1,
duration:2, duration:2,
trailLength:0.1, trailLength:0.1,
repeat:10, repeat:1,
}) })
.render(); .render();
linelayer.on('animateEnd',()=>{ linelayer.on('animateEnd',()=>{
console.log('动画结束'); scene.removeLayer(linelayer);
//linelayer.hide();
}) })
$.get('./data/yunqi.geojson', data => {
citylayer = scene.PolygonLayer({
zIndex: 2
})
.source(data)
.shape('fill')
.active({fill:'red'})
.size('floor',[10,2000])
.color('rgba(242,246,250,0.96)')
.render();
})
$.get('./data/test.json', data => {
citylayer2 = scene.PolygonLayer({
zIndex: 2
})
.source(data)
.shape('fill')
.active({fill:'red'})
// .size('floor',[10,2000])
.color('red')
.render();
})
}) })
</script> </script>
</body> </body>

View File

@ -53,7 +53,8 @@
"string-replace-loader": "~1.3.0", "string-replace-loader": "~1.3.0",
"torchjs": "~2.1.0", "torchjs": "~2.1.0",
"uglify-js": "~3.1.10", "uglify-js": "~3.1.10",
"webpack": "~3.10.0" "webpack": "~3.10.0",
"worker-loader": "^2.0.0"
}, },
"scripts": { "scripts": {
"build": "webpack", "build": "webpack",
@ -92,9 +93,6 @@
], ],
"silent": false "silent": false
}, },
"publishConfig": {
"registry": "http://registry.npm.alibaba-inc.com"
},
"dependencies": { "dependencies": {
"@antv/g": "^3.1.3", "@antv/g": "^3.1.3",
"@antv/util": "~1.2.5", "@antv/util": "~1.2.5",
@ -113,6 +111,7 @@
"three": "^0.96.0", "three": "^0.96.0",
"venn.js": "^0.2.20", "venn.js": "^0.2.20",
"viewport-mercator-project": "^5.2.0", "viewport-mercator-project": "^5.2.0",
"webworkify-webpack": "^2.1.3",
"wolfy87-eventemitter": "~5.2.4" "wolfy87-eventemitter": "~5.2.4"
} }
} }

View File

@ -4,7 +4,7 @@
*/ */
import EventEmitter from 'wolfy87-eventemitter'; import EventEmitter from 'wolfy87-eventemitter';
import Util from '../util'; import { assign } from '../util';
class Base extends EventEmitter { class Base extends EventEmitter {
@ -19,7 +19,7 @@ class Base extends EventEmitter {
}; };
const defaultCfg = this.getDefaultCfg(); const defaultCfg = this.getDefaultCfg();
this._attrs = attrs; this._attrs = attrs;
Util.assign(attrs, defaultCfg, cfg); assign(attrs, defaultCfg, cfg);
} }
get(name) { get(name) {

View File

@ -61,8 +61,6 @@ class Picking {
this._pickAllObject(point, normalisedPoint); this._pickAllObject(point, normalisedPoint);
// this._pick(point, normalisedPoint); // this._pick(point, normalisedPoint);
} }
_onWorldMove() { _onWorldMove() {
this._needUpdate = true; this._needUpdate = true;
@ -74,7 +72,6 @@ class Picking {
this._width = size.width; this._width = size.width;
this._height = size.height; this._height = size.height;
this._pickingTexture.setSize(this._width, this._height); this._pickingTexture.setSize(this._width, this._height);
this._pixelBuffer = new Uint8Array(4 * this._width * this._height); this._pixelBuffer = new Uint8Array(4 * this._width * this._height);
@ -203,15 +200,6 @@ class Picking {
} }
this._pickingScene.remove(child); this._pickingScene.remove(child);
// Probably not a good idea to dispose of geometry due to it being
// shared with the non-picking scene
// if (child.geometry) {
// // Dispose of mesh and materials
// child.geometry.dispose();
// child.geometry = null;
// }
if (child.material) { if (child.material) {
if (child.material.map) { if (child.material.map) {
child.material.map.dispose(); child.material.map.dispose();

View File

@ -42,6 +42,7 @@ export default class Layer extends Base {
strokeOpacity: 1.0, strokeOpacity: 1.0,
texture: false texture: false
}, },
destroyed: false,
// 选中时的配置项 // 选中时的配置项
selectedOptions: null, selectedOptions: null,
// active 时的配置项 // active 时的配置项
@ -65,7 +66,7 @@ export default class Layer extends Base {
scene._engine._scene.add(this._object3D); scene._engine._scene.add(this._object3D);
this.layerMesh = null; this.layerMesh = null;
this.layerLineMesh = null; this.layerLineMesh = null;
this._addPickingEvents(); this._initEvents();
} }
/** /**
@ -77,9 +78,8 @@ export default class Layer extends Base {
type === 'fill' ? this.layerMesh = object : this.layerLineMesh = object; type === 'fill' ? this.layerMesh = object : this.layerLineMesh = object;
this._visibleWithZoom(); this._visibleWithZoom();
this.scene.on('zoomchange', () => { this._zoomchangeHander = this._visibleWithZoom.bind(this);
this._visibleWithZoom(); this.scene.on('zoomchange', this._zoomchangeHander);
});
object.onBeforeRender = () => { object.onBeforeRender = () => {
const zoom = this.scene.getZoom(); const zoom = this.scene.getZoom();
@ -97,7 +97,6 @@ export default class Layer extends Base {
} }
remove(object) { remove(object) {
this._object3D.remove(object); this._object3D.remove(object);
} }
_getUniqueId() { _getUniqueId() {
return id++; return id++;
@ -113,6 +112,12 @@ export default class Layer extends Base {
cfg.mapType = this.get('mapType'); cfg.mapType = this.get('mapType');
this.layerSource = new source[type](cfg); this.layerSource = new source[type](cfg);
// this.scene.workerPool.runTask({
// command: 'geojson',
// data: cfg
// }).then(data => {
// console.log(data);
// });
return this; return this;
} }
@ -445,10 +450,10 @@ export default class Layer extends Base {
_addPickMesh(mesh) { _addPickMesh(mesh) {
this._pickingMesh = new THREE.Object3D(); this._pickingMesh = new THREE.Object3D();
this._pickingMesh.name = this.layerId; this._pickingMesh.name = this.layerId;
this._visibleWithZoom(); // this._visibleWithZoom();
this.scene.on('zoomchange', () => { // this.scene.on('zoomchange', () => {
this._visibleWithZoom(); // this._visibleWithZoom();
}); // });
this.addToPicking(this._pickingMesh); this.addToPicking(this._pickingMesh);
const pickmaterial = new PickingMaterial({ const pickmaterial = new PickingMaterial({
@ -467,16 +472,13 @@ export default class Layer extends Base {
_setPickingId() { _setPickingId() {
this._pickingId = this.getPickingId(); this._pickingId = this.getPickingId();
} }
_addPickingEvents() { _initEvents() {
// TODO: Find a way to properly remove this listener on destroy
this.scene.on('pick-' + this.layerId, e => { this.scene.on('pick-' + this.layerId, e => {
const { featureId, point2d, type } = e; const { featureId, point2d, type } = e;
if (featureId < -100 && this._activeIds !== null) { if (featureId < -100 && this._activeIds !== null) {
this.emit('mouseleave'); this.emit('mouseleave');
return; return;
} }
// if (intersects.length === 0) { return; }
const feature = this.layerSource.getSelectFeature(featureId); const feature = this.layerSource.getSelectFeature(featureId);
const lnglat = this.scene.containerToLngLat(point2d); const lnglat = this.scene.containerToLngLat(point2d);
const target = { const target = {
@ -555,8 +557,6 @@ export default class Layer extends Base {
}); });
colorAttr.needsUpdate = true; colorAttr.needsUpdate = true;
pickAttr.needsUpdate = true; pickAttr.needsUpdate = true;
// this._needUpdateFilter = false;
// this._needUpdateColor = false;
} }
_visibleWithZoom() { _visibleWithZoom() {
const zoom = this.scene.getZoom(); const zoom = this.scene.getZoom();
@ -601,8 +601,8 @@ export default class Layer extends Base {
/** /**
* 销毁Layer对象 * 销毁Layer对象
*/ */
despose() { destroy() {
this.destroy(); this.removeAllListeners();
if (this._object3D && this._object3D.children) { if (this._object3D && this._object3D.children) {
let child; let child;
for (let i = 0; i < this._object3D.children.length; i++) { for (let i = 0; i < this._object3D.children.length; i++) {
@ -612,7 +612,7 @@ export default class Layer extends Base {
} }
this.remove(child); this.remove(child);
if (child.geometry) { if (child.geometry) {
child.geometry.dispose(); // child.geometry.dispose();
child.geometry = null; child.geometry = null;
} }
if (child.material) { if (child.material) {
@ -624,10 +624,14 @@ export default class Layer extends Base {
child.material.dispose(); child.material.dispose();
child.material = null; child.material = null;
} }
child = null;
} }
} }
this._object3D = null; this._object3D = null;
this.scene = null; this.scene._engine._scene.remove(this._object3D);
this.scene._engine._picking.remove(this._pickingMesh);
this.scene.off('zoomchange', this._zoomchangeHander);
this.destroyed = true;
} }
_preRender() { _preRender() {

View File

@ -2,6 +2,7 @@ import Engine from './engine';
import * as layers from '../layer'; import * as layers from '../layer';
import Base from './base'; import Base from './base';
import LoadImage from './image'; import LoadImage from './image';
import WorkerPool from './worker';
import { MapProvider } from '../map/provider'; import { MapProvider } from '../map/provider';
import GaodeMap from '../map/gaodeMap'; import GaodeMap from '../map/gaodeMap';
import Global from '../global'; import Global from '../global';
@ -20,6 +21,7 @@ export default class Scene extends Base {
_initEngine(mapContainer) { _initEngine(mapContainer) {
this._engine = new Engine(mapContainer, this); this._engine = new Engine(mapContainer, this);
this._engine.run(); this._engine.run();
this.workerPool = new WorkerPool();
} }
// 为pickup场景添加 object 对象 // 为pickup场景添加 object 对象
addPickMesh(object) { addPickMesh(object) {
@ -59,6 +61,11 @@ export default class Scene extends Base {
if (this.map) { this.map.on(type, hander); } if (this.map) { this.map.on(type, hander); }
super.on(type, hander); super.on(type, hander);
} }
off(type, hander) {
if (this.map) { this.map.off(type, hander); }
super.off(type, hander);
}
_initAttribution() { _initAttribution() {
const message = '<a href="http://antv.alipay.com/zh-cn/index.html title="Large-scale WebGL-powered Geospatial Data Visualization">AntV | L7 </a>'; const message = '<a href="http://antv.alipay.com/zh-cn/index.html title="Large-scale WebGL-powered Geospatial Data Visualization">AntV | L7 </a>';
const element = document.createElement('div'); const element = document.createElement('div');
@ -105,13 +112,13 @@ export default class Scene extends Base {
}, false); }, false);
}); });
} }
// 代理map事件
removeLayer(layer) { removeLayer(layer) {
const layerIndex = this._layers.indexOf(layer); const layerIndex = this._layers.indexOf(layer);
if (layerIndex > -1) { if (layerIndex > -1) {
this._layers.splice(layerIndex, 1); this._layers.splice(layerIndex, 1);
} }
layer.destroy(); layer.destroy();
layer = null;
} }
} }

View File

@ -1,4 +1,4 @@
import Worker from './main.worker.js'; import Worker from '../worker/main.worker.js';
class WorkerPool { class WorkerPool {
constructor(workerCount) { constructor(workerCount) {
this.workerCount = workerCount || Math.max(Math.floor(window.navigator.hardwareConcurrency / 2), 1); this.workerCount = workerCount || Math.max(Math.floor(window.navigator.hardwareConcurrency / 2), 1);

View File

@ -68,10 +68,10 @@ export default class PointBuffer extends BufferBase {
this.bufferStruct.style = properties; this.bufferStruct.style = properties;
coordinates.forEach((geo, index) => { coordinates.forEach((geo, index) => {
let { size, shape } = properties[index]; let { size, shape } = properties[index];
let shapeType = ''; // let shapeType = '';
if (type === '2d' || (type === '3d' && size[2] === 0)) { if (type === '2d' || (type === '3d' && size[2] === 0)) {
shapeType = 'fill'; // let shapeType = 'fill';
Util.isArray(size) || (size = [ size, size, 0 ]); Util.isArray(size) || (size = [ size, size, 0 ]);
} else { } else {
Util.isArray(size) || (size = [ size, size, size ]); Util.isArray(size) || (size = [ size, size, size ]);
@ -80,7 +80,6 @@ export default class PointBuffer extends BufferBase {
uvs.push(0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0); uvs.push(0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0);
shape = 'square'; shape = 'square';
} }
// const vert = regularShape[shape](shapeType);
properties[index].size = size; properties[index].size = size;
const [ vert, polygonLine ] = this._getShape(properties[index], style, lineAttribute.miter.length); const [ vert, polygonLine ] = this._getShape(properties[index], style, lineAttribute.miter.length);

View File

@ -2,8 +2,181 @@
import { getJSON } from '../../../util/ajax'; import { getJSON } from '../../../util/ajax';
import * as THREE from '../../../core/three'; import * as THREE from '../../../core/three';
import EventEmitter from 'wolfy87-eventemitter';
import Global from '../../../global'; import Global from '../../../global';
const Space = 1; const Space = 1;
const metrics = {
buffer: 3,
family: 'ios9',
size: 24
};
export default function TextBuffer(coordinates, properties, style) { export default function TextBuffer(coordinates, properties, style) {
EventEmitter.call(this);
const attributes = {
originPoints: [],
textSizes: [],
textOffsets: [],
colors: [],
textureElements: []
};
const { textOffset = [ 0, 0 ] } = style;
const chars = [];
const textChars = {};
properties.forEach(element => {
let text = element.shape || '';
text = text.toString();
for (let j = 0; j < text.length; j++) {
const code = text.charCodeAt(j);
textChars[text] = 0;
if (chars.indexOf(code) === -1) {
chars.push(text.charCodeAt(j));
}
}
});
loadTextInfo(chars, (chars, texture) => {
properties.forEach((element, index) => {
const size = element.size;
const pos = coordinates[index];
const pen = { x: textOffset[0], y: textOffset[1] };
let text = element.shape || '';
text = text.toString();
for (let i = 0; i < text.length; i++) {
const color = element.color;
drawGlyph(chars, pos, text[i], pen, size, attributes.colors, attributes.textureElements, attributes.originPoints, attributes.textSizes, attributes.textOffsets, color);
}
this.emit('completed', { attributes, texture });
});
});
}
function loadTextInfo(chars, done) {
getJSON({
url: `${Global.sdfHomeUrl}/getsdfdata?chars=${chars.join('|')}`
}, (e, info) => {
loadTextTexture(info.url, texture => {
done(info.info, texture);
});
});
}
function loadTextTexture(url, cb) {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
const textTexture = this._creatTexture(img);
cb(textTexture);
};
img.src = url;
}
/**
* 计算每个标注词语的位置
* @param {*} chars 文本信息
* @param {*} pos 文字三维空间坐标
* @param {*} chr 字符
* @param {*} pen 字符在词语的偏移量
* @param {*} size 字体大小
* @param {*} colors 颜色
* @param {*} textureElements 纹理坐标
* @param {*} originPoints 初始位置数据
* @param {*} textSizes 文字大小数组
* @param {*} textOffsets 字体偏移量数据
* @param {*} color 文字颜色
*/
function drawGlyph(chars, pos, text, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
const chr = text.charCodeAt(0);
const metric = chars[chr];
if (!metric) return;
const scale = size / metrics.size;
let width = metric[0];
let height = metric[1];
const posX = metric[5];
const posY = metric[6];
const buffer = metrics.buffer;
if (width > 0 && height > 0) {
width += buffer * 2;
height += buffer * 2;
const originX = 0;
const originY = 0;
const offsetX = pen.x;
const offsetY = pen.y;
originPoints.push(
pos[0] + originX, pos[1] + originY, 0,
pos[0] + originX, pos[1] + originY, 0,
pos[0] + originX, pos[1] + originY, 0,
pos[0] + originX, pos[1] + originY, 0,
pos[0] + originX, pos[1] + originY, 0,
pos[0] + originX, pos[1] + originY, 0,
);
const bx = 0;
const by = metrics.size / 2 + buffer;
textSizes.push(
((bx - buffer + width) * scale), (height - by) * scale,
((bx - buffer) * scale), (height - by) * scale,
((bx - buffer) * scale), -by * scale,
((bx - buffer + width) * scale), (height - by) * scale,
((bx - buffer) * scale), -by * scale,
((bx - buffer + width) * scale), -by * scale,
);
textOffsets.push(
offsetX, offsetY,
offsetX, offsetY,
offsetX, offsetY,
offsetX, offsetY,
offsetX, offsetY,
offsetX, offsetY,
);
colors.push(
...color,
...color,
...color,
...color,
...color,
...color,
);
textureElements.push(
posX + width, posY,
posX, posY,
posX, posY + height,
posX + width, posY,
posX, posY + height,
posX + width, posY + height
);
}
pen.x = pen.x + size * 1.8;
}
function measureText(text, size) {
const dimensions = {
advance: 0
};
const metrics = this.metrics;
const scale = size / metrics.size;
for (let i = 0; i < text.length; i++) {
const code = text.charCodeAt(i);
const horiAdvance = metrics.chars[code][4];
dimensions.advance += (horiAdvance + Space) * scale;
}
return dimensions;
}
function creatTexture(image) {
this.bufferStruct.textSize = [ image.width, image.height ];
const texture = new THREE.Texture(image);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.ClampToEdgeWrapping;
texture.needsUpdate = true;
return texture;
} }

View File

@ -1,25 +1,55 @@
import polygon_frag from '../shader/polygon_frag.glsl'; import polygon_frag from '../shader/polygon_frag.glsl';
import polygon_vert from '../shader/polygon_vert.glsl'; import polygon_vert from '../shader/polygon_vert.glsl';
import Material from './material'; import Material from './material';
export default function PolygonMaterial(options) { // export default function PolygonMaterial(options) {
const material = new Material({ // const material = new Material({
uniforms: { // uniforms: {
u_opacity: { value: options.u_opacity || 1.0 }, // u_opacity: { value: options.u_opacity || 1.0 },
u_texture: { value: options.u_texture }, // u_texture: { value: options.u_texture },
u_time: { value: options.u_time || 0 }, // u_time: { value: options.u_time || 0 },
u_zoom: { value: options.u_zoom || 0 }, // u_zoom: { value: options.u_zoom || 0 },
u_baseColor: { value: options.u_baseColor || [ 1.0, 0, 0, 1.0 ] }, // u_baseColor: { value: options.u_baseColor || [ 1.0, 0, 0, 1.0 ] },
u_brightColor: { value: options.u_brightColor || [ 1.0, 0, 0, 1.0 ] }, // u_brightColor: { value: options.u_brightColor || [ 1.0, 0, 0, 1.0 ] },
u_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] }, // u_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] },
u_near: { value: options.u_near || 0.0 }, // u_near: { value: options.u_near || 0.0 },
u_far: { value: options.u_far || 1.0 } // u_far: { value: options.u_far || 1.0 }
}, // },
vertexShader: polygon_vert, // vertexShader: polygon_vert,
fragmentShader: polygon_frag, // fragmentShader: polygon_frag,
transparent: true, // transparent: true,
defines: { // defines: {
TEXCOORD_0: !!options.u_texture // TEXCOORD_0: !!options.u_texture
} // }
}); // });
return material; // return material;
// }
export default class PolygonMaterial extends Material {
getDefaultParameters() {
return {
uniforms: {
u_opacity: { value: 1.0 },
u_time: { value: 0 },
u_zoom: { value: 0 },
u_baseColor: { value: [ 1.0, 0, 0, 1.0 ] },
u_brightColor: { value: [ 1.0, 0, 0, 1.0 ] },
u_windowColor: { value: [ 1.0, 0, 0, 1.0 ] },
u_near: { value: 0.0 },
u_far: { value: 1.0 }
},
defines: {
}
};
}
constructor(_uniforms, _defines, parameters) {
super(parameters);
const { uniforms, defines } = this.getDefaultParameters();
this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms));
this.type = 'PolygonMaterial';
this.defines = Object.assign(defines, _defines);
this.vertexShader = polygon_vert;
this.fragmentShader = polygon_frag;
this.transparent = true;
}
} }

View File

@ -5,7 +5,7 @@ uniform float u_dashSmooth;
uniform float u_dashDistance; uniform float u_dashDistance;
varying vec4 v_color; varying vec4 v_color;
void main() { void main() {
float lineUMod = mod(v_lineU, 1.0/u_dashSteps) * u_dashSteps; float lineUMod = mod(v_lineU, 1.0/ u_dashSteps) * u_dashSteps;
float dash = smoothstep(u_dashDistance, u_dashDistance+u_dashSmooth, length(lineUMod-0.5)); float dash = smoothstep(u_dashDistance, u_dashDistance+u_dashSmooth, length(lineUMod-0.5));
gl_FragColor = vec4(v_color.xyz * vec3(dash), v_color.a*u_opacity * dash); gl_FragColor = vec4(v_color.xyz * vec3(dash), v_color.a*u_opacity * dash);
} }

View File

View File

@ -0,0 +1,48 @@
precision highp float;
#define ambientRatio 0.5
#define diffuseRatio 0.4
#define specularRatio 0.1
attribute vec4 a_color;
attribute vec4 a_idColor;
attribute vec2 faceUv;
attribute vec3 a_shape;
attribute vec3 a_size;
uniform float u_zoom;
varying vec2 v_texCoord;
varying vec4 v_color;
varying float v_lightWeight;
varying float v_size;
void main() {
float scale = pow(2.0,(20.0 - u_zoom));
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
vec3 newposition = position;
#ifdef SHAPE
newposition =position + a_size * scale* a_shape;
#endif
v_texCoord = faceUv;
if(normal == vec3(0.,0.,1.)){
v_color = a_color;
gl_Position = matModelViewProjection * vec4(newposition, 1.0);
return;
}
vec3 worldPos = vec3(vec4(newposition,1.0) * modelMatrix);
vec3 worldNormal = vec3(vec4(normal,1.0) * modelMatrix);
// //cal light weight
vec3 viewDir = normalize(cameraPosition - worldPos);
//vec3 lightDir = normalize(vec3(1, -10.5, 12));
vec3 lightDir = normalize(vec3(0.,-10.,1.));
vec3 halfDir = normalize(viewDir+lightDir);
// //lambert
float lambert = dot(worldNormal, lightDir);
//specular
float specular = pow( max(0.0, dot(worldNormal, halfDir)), 32.0);
//sum to light weight
float lightWeight = ambientRatio + diffuseRatio * lambert + specularRatio * specular;
v_texCoord = faceUv;
v_lightWeight = lightWeight;
// v_size = a_size;
v_color =vec4(a_color.rgb*lightWeight, a_color.w);
gl_Position = matModelViewProjection * vec4(newposition, 1.0);
}

View File

@ -55,8 +55,8 @@ export default class PointLayer extends Layer {
const meshStroke = drawPoint.DrawStroke(lineAttribute, this.get('styleOptions')); const meshStroke = drawPoint.DrawStroke(lineAttribute, this.get('styleOptions'));
this.add(meshStroke, 'line'); this.add(meshStroke, 'line');
} }
break;
} }
break;
case 'image':// 绘制图片标注 case 'image':// 绘制图片标注
{ {
const imageAttribute = PointBuffer.ImageBuffer(source.geoData, this.StyleData, { imagePos: this.scene.image.imagePos }); const imageAttribute = PointBuffer.ImageBuffer(source.geoData, this.StyleData, { imagePos: this.scene.image.imagePos });
@ -69,9 +69,13 @@ export default class PointLayer extends Layer {
const normalAttribute = PointBuffer.NormalBuffer(source.geoData, this.StyleData, style); const normalAttribute = PointBuffer.NormalBuffer(source.geoData, this.StyleData, style);
const normalPointMesh = drawPoint.DrawNormal(normalAttribute, style); const normalPointMesh = drawPoint.DrawNormal(normalAttribute, style);
this.add(normalPointMesh); this.add(normalPointMesh);
break;
} }
default:
return null;
} }
} }
_getShape() { _getShape() {
let shape = null; let shape = null;
if (!this.StyleData[0].hasOwnProperty('shape')) { if (!this.StyleData[0].hasOwnProperty('shape')) {
@ -83,7 +87,6 @@ export default class PointLayer extends Layer {
break; break;
} }
} }
if (pointShape['2d'].indexOf(shape) !== -1 || pointShape['3d'].indexOf(shape) !== -1) { if (pointShape['2d'].indexOf(shape) !== -1 || pointShape['3d'].indexOf(shape) !== -1) {
return 'fill'; return 'fill';
} else if (shape === 'text') { } else if (shape === 'text') {

View File

@ -1,8 +1,6 @@
import * as THREE from '../core/three';
import Layer from '../core/layer'; import Layer from '../core/layer';
import * as drawPolygon from './render/polygon';
import PolygonBuffer from '../geom/buffer/polygon'; import PolygonBuffer from '../geom/buffer/polygon';
import PolygonMaterial from '../geom/material/polygonMaterial';
import { LineMaterial } from '../geom/material/lineMaterial';
export default class PolygonLayer extends Layer { export default class PolygonLayer extends Layer {
shape(type) { shape(type) {
this.shape = type; this.shape = type;
@ -15,80 +13,38 @@ export default class PolygonLayer extends Layer {
} else { } else {
this._initAttrs(); this._initAttrs();
(this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter() : null; (this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter(this.layerMesh) : null;
const { opacity, baseColor, brightColor, windowColor } = this.get('styleOptions'); // TODO update Style;
this.layerMesh.material.upDateUninform({
u_opacity: opacity,
u_baseColor: baseColor,
u_brightColor: brightColor,
u_windowColor: windowColor
});
} }
return this; return this;
} }
_prepareRender() { _prepareRender() {
this.init(); this.init();
this.type = 'polygon'; this.type = 'polygon';
const source = this.layerSource; const source = this.layerSource;
this._buffer = new PolygonBuffer({ this._buffer = new PolygonBuffer({
shape: this.shape, shape: this.shape,
coordinates: source.geoData, coordinates: source.geoData,
properties: this.StyleData properties: this.StyleData
}); });
const { attributes } = this._buffer; this.add(this._getLayerRender());
this.geometry = new THREE.BufferGeometry();
this.geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
this.geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
this.geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
if (this.shape === 'line') {
this._renderLine();
} else {
this._renderPolygon();
}
} }
_renderLine() {
const { opacity } = this.get('styleOptions');
const lineMaterial = new LineMaterial({
u_opacity: opacity
});
const polygonLine = new THREE.LineSegments(this.geometry, lineMaterial);
this.add(polygonLine);
}
_renderPolygon() {
const animateOptions = this.get('animateOptions');
const { opacity, baseColor, brightColor, windowColor } = this.get('styleOptions');
const camera = this.map.getCameraState();
const material = new PolygonMaterial({
u_opacity: opacity,
u_baseColor: baseColor,
u_brightColor: brightColor,
u_windowColor: windowColor,
u_near: camera.near,
u_far: camera.far
});
const { attributes } = this._buffer;
this.geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
if (animateOptions.enable) {
material.setDefinesvalue('ANIMATE', true);
this.geometry.addAttribute('faceUv', new THREE.Float32BufferAttribute(attributes.faceUv, 2));
this.geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
}
// const pickmaterial = new PickingMaterial();
const polygonMesh = new THREE.Mesh(this.geometry, material);
this.add(polygonMesh);
}
update() { update() {
this.updateFilter(this.StyleData); this.updateFilter(this.layerMesh);
// 动态更新相关属性 // 动态更新相关属性
} }
_getLayerRender() {
const animateOptions = this.get('animateOptions');
const { attributes } = this._buffer;
const style = this.get('styleOptions');
if (this.shape === 'line') {
return drawPolygon.DrawLine(attributes, style);
} else if (animateOptions.enable) {
const { near, far } = this.map.getCameraState();
return drawPolygon.DrawAnimate(attributes, { ...style, near, far });
}
return drawPolygon.DrawFill(attributes, style);
}
} }

View File

@ -0,0 +1,19 @@
import * as THREE from '../../../core/three';
import { ArcLineMaterial } from '../../../geom/material/lineMaterial';
export default function DrawArcLine(attributes, style) {
const { opacity, zoom } = style;
const geometry = new THREE.BufferGeometry();
geometry.setIndex(attributes.indexArray);
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_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
const lineMaterial = new ArcLineMaterial({
u_opacity: opacity,
u_zoom: zoom
}, {
SHAPE: false
});
const arcMesh = new THREE.Mesh(geometry, lineMaterial);
return arcMesh;
}

View File

View File

@ -0,0 +1,27 @@
import * as THREE from '../../../core/three';
import { MeshLineMaterial } from '../../../geom/material/lineMaterial';
export default function DrawLine(attributes, style) {
const { opacity, zoom, animate, duration, interval, trailLength } = style;
const geometry = new THREE.BufferGeometry();
geometry.setIndex(attributes.indexArray);
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('a_distance', new THREE.Float32BufferAttribute(attributes.attrDistance, 1));
const lineMaterial = new MeshLineMaterial({
u_opacity: opacity,
u_zoom: zoom,
u_duration: duration,
u_interval: interval,
u_trailLength: trailLength,
u_time: 0
}, {
SHAPE: false,
ANIMATE: animate
});
const arcMesh = new THREE.Mesh(geometry, lineMaterial);
return arcMesh;
}

View File

@ -22,6 +22,7 @@ export default function DrawFill(attributes, style) {
SHAPE: true SHAPE: true
}); });
material.setDefinesvalue('SHAPE', true); material.setDefinesvalue('SHAPE', true);
material.depthTest = false;
const fillMesh = new THREE.Mesh(geometry, material); const fillMesh = new THREE.Mesh(geometry, material);
return fillMesh; return fillMesh;

View File

@ -18,6 +18,7 @@ export default function DrawImage(attributes, style) {
SHAPE: false, SHAPE: false,
TEXCOORD_0: true TEXCOORD_0: true
}); });
material.depthTest = false;
const strokeMesh = new THREE.Points(geometry, material); const strokeMesh = new THREE.Points(geometry, material);
return strokeMesh; return strokeMesh;
} }

View File

@ -1,4 +1,6 @@
/**
* 原生点绘制
*/
import * as THREE from '../../../core/three'; import * as THREE from '../../../core/three';
import PointMaterial from '../../../geom/material/pointMaterial'; import PointMaterial from '../../../geom/material/pointMaterial';
export default function DrawNormal(attributes, style) { export default function DrawNormal(attributes, style) {

View File

@ -1,23 +1,23 @@
import * as THREE from '../../../core/three'; // import * as THREE from '../../../core/three';
import TextMaterial from '../../../geom/material/textMaterial'; // import TextMaterial from '../../../geom/material/textMaterial';
export default function DawText(attributes, style) { // export default function DawText(attributes, texture, style) {
const geometry = new THREE.BufferGeometry(); // const geometry = new THREE.BufferGeometry();
const { strokeWidth, stroke, opacity } = style; // const { strokeWidth, stroke, opacity } = style;
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.originPoints, 3)); // geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.originPoints, 3));
geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.textureElements, 2)); // geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.textureElements, 2));
geometry.addAttribute('a_txtsize', new THREE.Float32BufferAttribute(attributes.textSizes, 2)); // geometry.addAttribute('a_txtsize', new THREE.Float32BufferAttribute(attributes.textSizes, 2));
geometry.addAttribute('a_txtOffsets', new THREE.Float32BufferAttribute(attributes.textOffsets, 2)); // geometry.addAttribute('a_txtOffsets', new THREE.Float32BufferAttribute(attributes.textOffsets, 2));
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4)); // geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
const material = new TextMaterial({ // const material = new TextMaterial({
name: this.layerId, // name: this.layerId,
u_texture: buffer.bufferStruct.textTexture, // u_texture: texture,
u_strokeWidth: 1, // u_strokeWidth: 1,
u_stroke: stroke, // u_stroke: stroke,
u_textSize: buffer.bufferStruct.textSize, // u_textSize: buffer.bufferStruct.textSize,
u_gamma: 0.11, // u_gamma: 0.11,
u_buffer: 0.8, // u_buffer: 0.8,
u_color: color, // u_color: color,
u_glSize: [ width, height ] // u_glSize: [ width, height ]
}); // });
const mesh = new THREE.Mesh(geometry, material); // const mesh = new THREE.Mesh(geometry, material);
} // }

View File

@ -0,0 +1,35 @@
import * as THREE from '../../../core/three';
import PolygonMaterial from '../../../geom/material/polygonMaterial';
export default function DrawAnimate(attributes, style) {
const { opacity, baseColor, brightColor, windowColor, near, far } = style;
const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 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));
const material = new PolygonMaterial({
u_opacity: opacity,
u_baseColor: baseColor,
u_brightColor: brightColor,
u_windowColor: windowColor,
u_near: near,
u_far: far
}, {
SHAPE: false,
ANIMATE: true
});
const fillPolygonMesh = new THREE.Mesh(geometry, material);
this.fillPolygonMesh = fillPolygonMesh;
return fillPolygonMesh;
}
DrawAnimate.prototype.updateStyle = function(style) {
this.fillPolygonMesh.material.upDateUninform({
u_opacity: style.opacity,
u_baseColor: style.baseColor,
u_brightColor: style.brightColor,
u_windowColor: style.windowColor
});
};

View File

@ -0,0 +1,18 @@
import * as THREE from '../../../core/three';
import PolygonMaterial from '../../../geom/material/polygonMaterial';
export default function DrawPolygonFill(attributes, style) {
const { opacity } = style;
const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 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));
const material = new PolygonMaterial({
u_opacity: opacity
}, {
SHAPE: false
});
const fillPolygonMesh = new THREE.Mesh(geometry, material);
return fillPolygonMesh;
}

View File

@ -0,0 +1,16 @@
import * as THREE from '../../../core/three';
import { LineMaterial } from '../../../geom/material/lineMaterial';
export default function DrawPolygonLine(attributes, style) {
const { opacity } = style;
const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
const lineMaterial = new LineMaterial({
u_opacity: opacity
}, {
SHAPE: false
});
const polygonLineMesh = new THREE.LineSegments(geometry, lineMaterial);
return polygonLineMesh;
}

View File

@ -0,0 +1,3 @@
export { default as DrawAnimate } from './drawAnimate';
export { default as DrawFill } from './drawFill';
export { default as DrawLine } from './drawLine';

View File

@ -1,6 +1,5 @@
import Source from '../core/source'; import Source from '../core/source';
import FeatureIndex from '../geo/featureIndex'; import FeatureIndex from '../geo/featureIndex';
import Util from '../util';
import { csvParse } from 'd3-dsv'; import { csvParse } from 'd3-dsv';
export default class CSVSource extends Source { export default class CSVSource extends Source {
prepareData() { prepareData() {
@ -14,7 +13,7 @@ export default class CSVSource extends Source {
this.propertiesData = [];// 临时使用 this.propertiesData = [];// 临时使用
this.geoData = []; this.geoData = [];
let csvdata = data; let csvdata = data;
Util.isArray(csvdata) || (csvdata = csvParse(data)); Array.isArray(csvdata) || (csvdata = csvParse(data));
this.propertiesData = csvdata; this.propertiesData = csvdata;
csvdata.forEach((col, featureIndex) => { csvdata.forEach((col, featureIndex) => {
let coordinates = []; let coordinates = [];

View File

@ -1,22 +1,2 @@
import { getJSON } from '../util/ajax';
import { GeojsonSource } from '../source/geojsonSource';
const EventEmitter = require('wolfy87-eventemitter');
export class geoJsonSourceWorker extends EventEmitter {
constructor(cfg) {
super();
this.source = new GeojsonSource(cfg);
}
_loadData(url) {
const data = this.source.get('data');
if (typeof (data) === 'string') {
this.emit('dataLoading');
getJSON(url, data => {
this.emit('dataLoaded', { data });
});
}
}
}

View File

@ -1,13 +1,4 @@
const extrude = require('geometry-extrude');
// import { geoJsonSourceWorker } from './geojsonSourceWorker';
/**
* workerOption
* {
* type:
* data:
*
* }
*/
self.addEventListener('message', e => { self.addEventListener('message', e => {
const res = e.data; const res = e.data;
// res = { // res = {
@ -17,12 +8,8 @@ self.addEventListener('message', e => {
let result; let result;
switch (res.command) { switch (res.command) {
case 'geojson': case 'geojson':
result = extrude.extrudeGeoJSON(res.data.data, res.data.options).polygon; result = res;
self.postMessage(result, [ result.indices.buffer, result.normal.buffer, result.position.buffer, result.uv.buffer ]); self.postMessage(result);
break;
case 'POLYLINE-EXTRUDE':
result = extrude.extrudeGeoJSON(res.data.data, res.data.options).polyline;
self.postMessage(result, [ result.indices.buffer, result.normal.buffer, result.position.buffer, result.uv.buffer ]);
break; break;
default: default:
self.postMessage(result); self.postMessage(result);

View File

@ -30,6 +30,16 @@ module.exports = {
loader: 'glsl-shaders-loader' loader: 'glsl-shaders-loader'
} }
}, },
{
test: /\.worker\.js$/,
use: {
loader: 'worker-loader',
options: {
inline: true,
fallback: false
}
}
},
{ {
test: /global\.js$/, test: /global\.js$/,
use: { use: {