diff --git a/demos/03_choropleths_polygon.html b/demos/03_choropleths_polygon.html index 832066b226..4ccebb1bc4 100644 --- a/demos/03_choropleths_polygon.html +++ b/demos/03_choropleths_polygon.html @@ -86,16 +86,16 @@ scene.on('loaded', () => { opacity: 1 }) .render(); - /** + const citylayer2 = scene.PolygonLayer() .source(city) .shape('line') .color('#fff') .style({ - opacity: 0.1 + opacity: 1.0 }) - // .render(); - **/ + .render(); + citylayer.on('click',(e)=>{ $("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'}); diff --git a/demos/assets/screenshots/01_point_circle.png b/demos/assets/screenshots/01_point_circle.png index 67cb6b0eba..c049a40aad 100644 Binary files a/demos/assets/screenshots/01_point_circle.png and b/demos/assets/screenshots/01_point_circle.png differ diff --git a/demos/assets/screenshots/01_point_column.png b/demos/assets/screenshots/01_point_column.png index 807c0a1e42..0d451be5b9 100644 Binary files a/demos/assets/screenshots/01_point_column.png and b/demos/assets/screenshots/01_point_column.png differ diff --git a/demos/assets/screenshots/01_point_distribute.png b/demos/assets/screenshots/01_point_distribute.png index 7e8d28f85c..f2345f8351 100644 Binary files a/demos/assets/screenshots/01_point_distribute.png and b/demos/assets/screenshots/01_point_distribute.png differ diff --git a/demos/assets/screenshots/01_point_image.png b/demos/assets/screenshots/01_point_image.png index 407ec7c710..d22999aecd 100644 Binary files a/demos/assets/screenshots/01_point_image.png and b/demos/assets/screenshots/01_point_image.png differ diff --git a/demos/assets/screenshots/02_contour.png b/demos/assets/screenshots/02_contour.png index 5ec3ccfdf6..8832d56b21 100644 Binary files a/demos/assets/screenshots/02_contour.png and b/demos/assets/screenshots/02_contour.png differ diff --git a/demos/assets/screenshots/02_oneBletoneRoad.png b/demos/assets/screenshots/02_oneBletoneRoad.png index 978be27763..9f9d920822 100644 Binary files a/demos/assets/screenshots/02_oneBletoneRoad.png and b/demos/assets/screenshots/02_oneBletoneRoad.png differ diff --git a/demos/assets/screenshots/03_1_extrude_polygon.png b/demos/assets/screenshots/03_1_extrude_polygon.png index d932b8b5da..c049a40aad 100644 Binary files a/demos/assets/screenshots/03_1_extrude_polygon.png and b/demos/assets/screenshots/03_1_extrude_polygon.png differ diff --git a/demos/assets/screenshots/03_choropleths_polygon.png b/demos/assets/screenshots/03_choropleths_polygon.png index 78116be3bf..64e3e8d621 100644 Binary files a/demos/assets/screenshots/03_choropleths_polygon.png and b/demos/assets/screenshots/03_choropleths_polygon.png differ diff --git a/demos/assets/screenshots/04_image.png b/demos/assets/screenshots/04_image.png index 5163f0d7e0..c049a40aad 100644 Binary files a/demos/assets/screenshots/04_image.png and b/demos/assets/screenshots/04_image.png differ diff --git a/demos/assets/screenshots/05_raster_dem.png b/demos/assets/screenshots/05_raster_dem.png index b74cb7f7b9..c049a40aad 100644 Binary files a/demos/assets/screenshots/05_raster_dem.png and b/demos/assets/screenshots/05_raster_dem.png differ diff --git a/demos/assets/screenshots/06_text.png b/demos/assets/screenshots/06_text.png index d7244b72c8..c049a40aad 100644 Binary files a/demos/assets/screenshots/06_text.png and b/demos/assets/screenshots/06_text.png differ diff --git a/demos/assets/screenshots/07_city.png b/demos/assets/screenshots/07_city.png index 49b9a8b62d..c049a40aad 100644 Binary files a/demos/assets/screenshots/07_city.png and b/demos/assets/screenshots/07_city.png differ diff --git a/demos/assets/screenshots/08_arc_line.png b/demos/assets/screenshots/08_arc_line.png new file mode 100644 index 0000000000..68525450f4 Binary files /dev/null and b/demos/assets/screenshots/08_arc_line.png differ diff --git a/demos/assets/screenshots/08_point_shape.png b/demos/assets/screenshots/08_point_shape.png new file mode 100644 index 0000000000..68525450f4 Binary files /dev/null and b/demos/assets/screenshots/08_point_shape.png differ diff --git a/demos/assets/screenshots/line.png b/demos/assets/screenshots/line.png new file mode 100644 index 0000000000..e253ba1c99 Binary files /dev/null and b/demos/assets/screenshots/line.png differ diff --git a/demos/assets/screenshots/meshline.png b/demos/assets/screenshots/meshline.png new file mode 100644 index 0000000000..bb78696ae8 Binary files /dev/null and b/demos/assets/screenshots/meshline.png differ diff --git a/demos/assets/screenshots/point.png b/demos/assets/screenshots/point.png new file mode 100644 index 0000000000..20809a9ecb Binary files /dev/null and b/demos/assets/screenshots/point.png differ diff --git a/demos/assets/screenshots/taxi.png b/demos/assets/screenshots/taxi.png new file mode 100644 index 0000000000..c049a40aad Binary files /dev/null and b/demos/assets/screenshots/taxi.png differ diff --git a/demos/line.html b/demos/line.html index 6f7f23c30b..7c38f6cf1d 100644 --- a/demos/line.html +++ b/demos/line.html @@ -46,38 +46,16 @@ scene.on('loaded', () => { interval:1, duration:2, trailLength:0.1, - repeat:10, + repeat:1, }) .render(); 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(); - }) - + }) diff --git a/package.json b/package.json index 6b9922ad1a..07d4ab98ea 100755 --- a/package.json +++ b/package.json @@ -53,7 +53,8 @@ "string-replace-loader": "~1.3.0", "torchjs": "~2.1.0", "uglify-js": "~3.1.10", - "webpack": "~3.10.0" + "webpack": "~3.10.0", + "worker-loader": "^2.0.0" }, "scripts": { "build": "webpack", @@ -92,9 +93,6 @@ ], "silent": false }, - "publishConfig": { - "registry": "http://registry.npm.alibaba-inc.com" - }, "dependencies": { "@antv/g": "^3.1.3", "@antv/util": "~1.2.5", @@ -113,6 +111,7 @@ "three": "^0.96.0", "venn.js": "^0.2.20", "viewport-mercator-project": "^5.2.0", + "webworkify-webpack": "^2.1.3", "wolfy87-eventemitter": "~5.2.4" } } diff --git a/src/core/base.js b/src/core/base.js index 55ba028668..e5b3e92d7a 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -4,7 +4,7 @@ */ import EventEmitter from 'wolfy87-eventemitter'; -import Util from '../util'; +import { assign } from '../util'; class Base extends EventEmitter { @@ -19,7 +19,7 @@ class Base extends EventEmitter { }; const defaultCfg = this.getDefaultCfg(); this._attrs = attrs; - Util.assign(attrs, defaultCfg, cfg); + assign(attrs, defaultCfg, cfg); } get(name) { diff --git a/src/core/engine/picking/picking.js b/src/core/engine/picking/picking.js index 301d29d49a..e4fb4c2ee1 100755 --- a/src/core/engine/picking/picking.js +++ b/src/core/engine/picking/picking.js @@ -61,8 +61,6 @@ class Picking { this._pickAllObject(point, normalisedPoint); // this._pick(point, normalisedPoint); } - - _onWorldMove() { this._needUpdate = true; @@ -74,7 +72,6 @@ class Picking { this._width = size.width; this._height = size.height; - this._pickingTexture.setSize(this._width, this._height); this._pixelBuffer = new Uint8Array(4 * this._width * this._height); @@ -203,15 +200,6 @@ class Picking { } 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.map) { child.material.map.dispose(); diff --git a/src/core/layer.js b/src/core/layer.js index 233c602ee6..50f2858587 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -42,6 +42,7 @@ export default class Layer extends Base { strokeOpacity: 1.0, texture: false }, + destroyed: false, // 选中时的配置项 selectedOptions: null, // active 时的配置项 @@ -65,7 +66,7 @@ export default class Layer extends Base { scene._engine._scene.add(this._object3D); this.layerMesh = 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; this._visibleWithZoom(); - this.scene.on('zoomchange', () => { - this._visibleWithZoom(); - }); + this._zoomchangeHander = this._visibleWithZoom.bind(this); + this.scene.on('zoomchange', this._zoomchangeHander); object.onBeforeRender = () => { const zoom = this.scene.getZoom(); @@ -97,7 +97,6 @@ export default class Layer extends Base { } remove(object) { this._object3D.remove(object); - } _getUniqueId() { return id++; @@ -113,6 +112,12 @@ export default class Layer extends Base { cfg.mapType = this.get('mapType'); this.layerSource = new source[type](cfg); + // this.scene.workerPool.runTask({ + // command: 'geojson', + // data: cfg + // }).then(data => { + // console.log(data); + // }); return this; } @@ -445,10 +450,10 @@ export default class Layer extends Base { _addPickMesh(mesh) { this._pickingMesh = new THREE.Object3D(); this._pickingMesh.name = this.layerId; - this._visibleWithZoom(); - this.scene.on('zoomchange', () => { - this._visibleWithZoom(); - }); + // this._visibleWithZoom(); + // this.scene.on('zoomchange', () => { + // this._visibleWithZoom(); + // }); this.addToPicking(this._pickingMesh); const pickmaterial = new PickingMaterial({ @@ -467,16 +472,13 @@ export default class Layer extends Base { _setPickingId() { this._pickingId = this.getPickingId(); } - _addPickingEvents() { - // TODO: Find a way to properly remove this listener on destroy + _initEvents() { this.scene.on('pick-' + this.layerId, e => { const { featureId, point2d, type } = e; - if (featureId < -100 && this._activeIds !== null) { this.emit('mouseleave'); return; } - // if (intersects.length === 0) { return; } const feature = this.layerSource.getSelectFeature(featureId); const lnglat = this.scene.containerToLngLat(point2d); const target = { @@ -555,8 +557,6 @@ export default class Layer extends Base { }); colorAttr.needsUpdate = true; pickAttr.needsUpdate = true; - // this._needUpdateFilter = false; - // this._needUpdateColor = false; } _visibleWithZoom() { const zoom = this.scene.getZoom(); @@ -601,8 +601,8 @@ export default class Layer extends Base { /** * 销毁Layer对象 */ - despose() { - this.destroy(); + destroy() { + this.removeAllListeners(); if (this._object3D && this._object3D.children) { let child; for (let i = 0; i < this._object3D.children.length; i++) { @@ -612,7 +612,7 @@ export default class Layer extends Base { } this.remove(child); if (child.geometry) { - child.geometry.dispose(); + // child.geometry.dispose(); child.geometry = null; } if (child.material) { @@ -624,10 +624,14 @@ export default class Layer extends Base { child.material.dispose(); child.material = null; } + child = 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() { diff --git a/src/core/scene.js b/src/core/scene.js index e9f10b3ecb..30820daa8a 100644 --- a/src/core/scene.js +++ b/src/core/scene.js @@ -2,6 +2,7 @@ import Engine from './engine'; import * as layers from '../layer'; import Base from './base'; import LoadImage from './image'; +import WorkerPool from './worker'; import { MapProvider } from '../map/provider'; import GaodeMap from '../map/gaodeMap'; import Global from '../global'; @@ -20,6 +21,7 @@ export default class Scene extends Base { _initEngine(mapContainer) { this._engine = new Engine(mapContainer, this); this._engine.run(); + this.workerPool = new WorkerPool(); } // 为pickup场景添加 object 对象 addPickMesh(object) { @@ -59,6 +61,11 @@ export default class Scene extends Base { if (this.map) { this.map.on(type, hander); } super.on(type, hander); } + off(type, hander) { + if (this.map) { this.map.off(type, hander); } + + super.off(type, hander); + } _initAttribution() { const message = 'AntV | L7 '; const element = document.createElement('div'); @@ -105,13 +112,13 @@ export default class Scene extends Base { }, false); }); } - // 代理map事件 removeLayer(layer) { const layerIndex = this._layers.indexOf(layer); if (layerIndex > -1) { this._layers.splice(layerIndex, 1); } layer.destroy(); + layer = null; } } diff --git a/src/core/worker.js b/src/core/worker.js index c15f685145..91fcc4dd56 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -1,4 +1,4 @@ -import Worker from './main.worker.js'; +import Worker from '../worker/main.worker.js'; class WorkerPool { constructor(workerCount) { this.workerCount = workerCount || Math.max(Math.floor(window.navigator.hardwareConcurrency / 2), 1); diff --git a/src/geom/buffer/point.js b/src/geom/buffer/point.js index fe7d961999..009c90452e 100644 --- a/src/geom/buffer/point.js +++ b/src/geom/buffer/point.js @@ -68,10 +68,10 @@ export default class PointBuffer extends BufferBase { this.bufferStruct.style = properties; coordinates.forEach((geo, index) => { let { size, shape } = properties[index]; - let shapeType = ''; + // let shapeType = ''; if (type === '2d' || (type === '3d' && size[2] === 0)) { - shapeType = 'fill'; + // let shapeType = 'fill'; Util.isArray(size) || (size = [ size, size, 0 ]); } else { 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); shape = 'square'; } - // const vert = regularShape[shape](shapeType); properties[index].size = size; const [ vert, polygonLine ] = this._getShape(properties[index], style, lineAttribute.miter.length); diff --git a/src/geom/buffer/point/textBuffer.js b/src/geom/buffer/point/textBuffer.js index 0f4801fb68..a1937bc9ee 100644 --- a/src/geom/buffer/point/textBuffer.js +++ b/src/geom/buffer/point/textBuffer.js @@ -2,8 +2,181 @@ import { getJSON } from '../../../util/ajax'; import * as THREE from '../../../core/three'; +import EventEmitter from 'wolfy87-eventemitter'; import Global from '../../../global'; const Space = 1; +const metrics = { + buffer: 3, + family: 'ios9', + size: 24 +}; 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; } diff --git a/src/geom/material/polygonMaterial.js b/src/geom/material/polygonMaterial.js index 221823f836..d47eb72065 100644 --- a/src/geom/material/polygonMaterial.js +++ b/src/geom/material/polygonMaterial.js @@ -1,25 +1,55 @@ import polygon_frag from '../shader/polygon_frag.glsl'; import polygon_vert from '../shader/polygon_vert.glsl'; import Material from './material'; -export default function PolygonMaterial(options) { - const material = new Material({ - uniforms: { - u_opacity: { value: options.u_opacity || 1.0 }, - u_texture: { value: options.u_texture }, - u_time: { value: options.u_time || 0 }, - u_zoom: { value: options.u_zoom || 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_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] }, - u_near: { value: options.u_near || 0.0 }, - u_far: { value: options.u_far || 1.0 } - }, - vertexShader: polygon_vert, - fragmentShader: polygon_frag, - transparent: true, - defines: { - TEXCOORD_0: !!options.u_texture - } - }); - return material; +// export default function PolygonMaterial(options) { +// const material = new Material({ +// uniforms: { +// u_opacity: { value: options.u_opacity || 1.0 }, +// u_texture: { value: options.u_texture }, +// u_time: { value: options.u_time || 0 }, +// u_zoom: { value: options.u_zoom || 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_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] }, +// u_near: { value: options.u_near || 0.0 }, +// u_far: { value: options.u_far || 1.0 } +// }, +// vertexShader: polygon_vert, +// fragmentShader: polygon_frag, +// transparent: true, +// defines: { +// TEXCOORD_0: !!options.u_texture +// } +// }); +// 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; + } } diff --git a/src/geom/shader/dashline_frag.glsl b/src/geom/shader/dashline_frag.glsl index 970ddeb8d1..f7d56d8da9 100644 --- a/src/geom/shader/dashline_frag.glsl +++ b/src/geom/shader/dashline_frag.glsl @@ -5,7 +5,7 @@ uniform float u_dashSmooth; uniform float u_dashDistance; varying vec4 v_color; 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)); gl_FragColor = vec4(v_color.xyz * vec3(dash), v_color.a*u_opacity * dash); } \ No newline at end of file diff --git a/src/geom/shader/polygon_frag1.glsl b/src/geom/shader/polygon_frag1.glsl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/geom/shader/polygon_vert1.glsl b/src/geom/shader/polygon_vert1.glsl new file mode 100644 index 0000000000..9c8508c674 --- /dev/null +++ b/src/geom/shader/polygon_vert1.glsl @@ -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); +} \ No newline at end of file diff --git a/src/layer/pointLayer.js b/src/layer/pointLayer.js index f49f2220af..a21a80b4a7 100644 --- a/src/layer/pointLayer.js +++ b/src/layer/pointLayer.js @@ -55,8 +55,8 @@ export default class PointLayer extends Layer { const meshStroke = drawPoint.DrawStroke(lineAttribute, this.get('styleOptions')); this.add(meshStroke, 'line'); } + break; } - break; case 'image':// 绘制图片标注 { 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 normalPointMesh = drawPoint.DrawNormal(normalAttribute, style); this.add(normalPointMesh); + break; } + default: + return null; } } + _getShape() { let shape = null; if (!this.StyleData[0].hasOwnProperty('shape')) { @@ -83,7 +87,6 @@ export default class PointLayer extends Layer { break; } } - if (pointShape['2d'].indexOf(shape) !== -1 || pointShape['3d'].indexOf(shape) !== -1) { return 'fill'; } else if (shape === 'text') { diff --git a/src/layer/polygonLayer.js b/src/layer/polygonLayer.js index be1b3535dd..53e7c9903e 100644 --- a/src/layer/polygonLayer.js +++ b/src/layer/polygonLayer.js @@ -1,8 +1,6 @@ -import * as THREE from '../core/three'; import Layer from '../core/layer'; +import * as drawPolygon from './render/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 { shape(type) { this.shape = type; @@ -15,80 +13,38 @@ export default class PolygonLayer extends Layer { } else { this._initAttrs(); - (this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter() : null; - const { opacity, baseColor, brightColor, windowColor } = this.get('styleOptions'); - this.layerMesh.material.upDateUninform({ - u_opacity: opacity, - u_baseColor: baseColor, - u_brightColor: brightColor, - u_windowColor: windowColor - }); - + (this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter(this.layerMesh) : null; + // TODO update Style; } - - return this; } _prepareRender() { this.init(); this.type = 'polygon'; - const source = this.layerSource; this._buffer = new PolygonBuffer({ shape: this.shape, coordinates: source.geoData, properties: this.StyleData }); - const { attributes } = this._buffer; - 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(); - } + this.add(this._getLayerRender()); } - _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() { - 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); + + } } diff --git a/src/layer/render/line/drawArc.js b/src/layer/render/line/drawArc.js new file mode 100644 index 0000000000..246b8b55aa --- /dev/null +++ b/src/layer/render/line/drawArc.js @@ -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; +} diff --git a/src/layer/render/line/drawDashLine.js b/src/layer/render/line/drawDashLine.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/layer/render/line/drawLine.js b/src/layer/render/line/drawLine.js new file mode 100644 index 0000000000..e0a6f7a228 --- /dev/null +++ b/src/layer/render/line/drawLine.js @@ -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; +} diff --git a/src/layer/render/point/drawFill.js b/src/layer/render/point/drawFill.js index 5389855d35..de10dc8cc1 100644 --- a/src/layer/render/point/drawFill.js +++ b/src/layer/render/point/drawFill.js @@ -22,6 +22,7 @@ export default function DrawFill(attributes, style) { SHAPE: true }); material.setDefinesvalue('SHAPE', true); + material.depthTest = false; const fillMesh = new THREE.Mesh(geometry, material); return fillMesh; diff --git a/src/layer/render/point/drawImage.js b/src/layer/render/point/drawImage.js index 99fc430a09..f6fc926aac 100644 --- a/src/layer/render/point/drawImage.js +++ b/src/layer/render/point/drawImage.js @@ -18,6 +18,7 @@ export default function DrawImage(attributes, style) { SHAPE: false, TEXCOORD_0: true }); + material.depthTest = false; const strokeMesh = new THREE.Points(geometry, material); return strokeMesh; } diff --git a/src/layer/render/point/drawNormal.js b/src/layer/render/point/drawNormal.js index c0c86e231b..0bf40509e7 100644 --- a/src/layer/render/point/drawNormal.js +++ b/src/layer/render/point/drawNormal.js @@ -1,4 +1,6 @@ - +/** + * 原生点绘制 + */ import * as THREE from '../../../core/three'; import PointMaterial from '../../../geom/material/pointMaterial'; export default function DrawNormal(attributes, style) { diff --git a/src/layer/render/point/drawText.js b/src/layer/render/point/drawText.js index 178f7c0960..0be1854239 100644 --- a/src/layer/render/point/drawText.js +++ b/src/layer/render/point/drawText.js @@ -1,23 +1,23 @@ -import * as THREE from '../../../core/three'; -import TextMaterial from '../../../geom/material/textMaterial'; -export default function DawText(attributes, style) { - const geometry = new THREE.BufferGeometry(); - const { strokeWidth, stroke, opacity } = style; - geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.originPoints, 3)); - geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.textureElements, 2)); - geometry.addAttribute('a_txtsize', new THREE.Float32BufferAttribute(attributes.textSizes, 2)); - geometry.addAttribute('a_txtOffsets', new THREE.Float32BufferAttribute(attributes.textOffsets, 2)); - geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4)); - const material = new TextMaterial({ - name: this.layerId, - u_texture: buffer.bufferStruct.textTexture, - u_strokeWidth: 1, - u_stroke: stroke, - u_textSize: buffer.bufferStruct.textSize, - u_gamma: 0.11, - u_buffer: 0.8, - u_color: color, - u_glSize: [ width, height ] - }); - const mesh = new THREE.Mesh(geometry, material); -} +// import * as THREE from '../../../core/three'; +// import TextMaterial from '../../../geom/material/textMaterial'; +// export default function DawText(attributes, texture, style) { +// const geometry = new THREE.BufferGeometry(); +// const { strokeWidth, stroke, opacity } = style; +// geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.originPoints, 3)); +// geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.textureElements, 2)); +// geometry.addAttribute('a_txtsize', new THREE.Float32BufferAttribute(attributes.textSizes, 2)); +// geometry.addAttribute('a_txtOffsets', new THREE.Float32BufferAttribute(attributes.textOffsets, 2)); +// geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4)); +// const material = new TextMaterial({ +// name: this.layerId, +// u_texture: texture, +// u_strokeWidth: 1, +// u_stroke: stroke, +// u_textSize: buffer.bufferStruct.textSize, +// u_gamma: 0.11, +// u_buffer: 0.8, +// u_color: color, +// u_glSize: [ width, height ] +// }); +// const mesh = new THREE.Mesh(geometry, material); +// } diff --git a/src/layer/render/polygon/drawAnimate.js b/src/layer/render/polygon/drawAnimate.js new file mode 100644 index 0000000000..534a96ea7d --- /dev/null +++ b/src/layer/render/polygon/drawAnimate.js @@ -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 + }); +}; diff --git a/src/layer/render/polygon/drawFill.js b/src/layer/render/polygon/drawFill.js new file mode 100644 index 0000000000..0ad4808576 --- /dev/null +++ b/src/layer/render/polygon/drawFill.js @@ -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; +} + diff --git a/src/layer/render/polygon/drawLine.js b/src/layer/render/polygon/drawLine.js new file mode 100644 index 0000000000..8755a4f573 --- /dev/null +++ b/src/layer/render/polygon/drawLine.js @@ -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; +} diff --git a/src/layer/render/polygon/index.js b/src/layer/render/polygon/index.js new file mode 100644 index 0000000000..afde7904a6 --- /dev/null +++ b/src/layer/render/polygon/index.js @@ -0,0 +1,3 @@ +export { default as DrawAnimate } from './drawAnimate'; +export { default as DrawFill } from './drawFill'; +export { default as DrawLine } from './drawLine'; diff --git a/src/source/csvSource.js b/src/source/csvSource.js index 8266d1604b..901a9d46c0 100644 --- a/src/source/csvSource.js +++ b/src/source/csvSource.js @@ -1,6 +1,5 @@ import Source from '../core/source'; import FeatureIndex from '../geo/featureIndex'; -import Util from '../util'; import { csvParse } from 'd3-dsv'; export default class CSVSource extends Source { prepareData() { @@ -14,7 +13,7 @@ export default class CSVSource extends Source { this.propertiesData = [];// 临时使用 this.geoData = []; let csvdata = data; - Util.isArray(csvdata) || (csvdata = csvParse(data)); + Array.isArray(csvdata) || (csvdata = csvParse(data)); this.propertiesData = csvdata; csvdata.forEach((col, featureIndex) => { let coordinates = []; diff --git a/src/worker/geojsonSourceWorker.js b/src/worker/geojsonSourceWorker.js index 03ecf5defd..139597f9cb 100644 --- a/src/worker/geojsonSourceWorker.js +++ b/src/worker/geojsonSourceWorker.js @@ -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 }); - - }); - } - - } -} diff --git a/src/worker/main.worker.js b/src/worker/main.worker.js index 61f73c16d5..97321b3ed1 100644 --- a/src/worker/main.worker.js +++ b/src/worker/main.worker.js @@ -1,13 +1,4 @@ -const extrude = require('geometry-extrude'); -// import { geoJsonSourceWorker } from './geojsonSourceWorker'; -/** - * workerOption - * { - * type: - * data: - * - * } - */ + self.addEventListener('message', e => { const res = e.data; // res = { @@ -17,12 +8,8 @@ self.addEventListener('message', e => { let result; switch (res.command) { case 'geojson': - result = extrude.extrudeGeoJSON(res.data.data, res.data.options).polygon; - self.postMessage(result, [ result.indices.buffer, result.normal.buffer, result.position.buffer, result.uv.buffer ]); - 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 ]); + result = res; + self.postMessage(result); break; default: self.postMessage(result); diff --git a/webpack.config.js b/webpack.config.js index abb0056d8d..9106df5d7f 100755 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,6 +30,16 @@ module.exports = { loader: 'glsl-shaders-loader' } }, + { + test: /\.worker\.js$/, + use: { + loader: 'worker-loader', + options: { + inline: true, + fallback: false + } + } + }, { test: /global\.js$/, use: {