diff --git a/demos/01_point_circle.html b/demos/01_point_circle.html
index 2b66ddd6a2..bb80671de8 100644
--- a/demos/01_point_circle.html
+++ b/demos/01_point_circle.html
@@ -35,7 +35,9 @@ const scene = new L7.Scene({
mapStyle: 'light', // 样式URL
center: [ 120.19382669582967, 30.258134 ],
pitch: 0,
- zoom: 12
+ zoom: 12,
+ maxZoom:14,
+ minZoom:11,
});
window.scene = scene;
scene.on('loaded', () => {
@@ -53,7 +55,7 @@ scene.on('loaded', () => {
.shape('2d:circle')
.size('value', [ 2, 80]) // default 1
//.size('value', [ 10, 300]) // default 1
- .active(true)
+ .active(false)
.filter('value', field_8 => {
return field_8 * 1 > 500;
})
@@ -65,7 +67,9 @@ scene.on('loaded', () => {
})
.render();
-
+ circleLayer.on('click',(e)=>{
+ console.log(e);
+ })
});
});
diff --git a/demos/01_point_column.html b/demos/01_point_column.html
index 354c58a316..8e1abda83c 100644
--- a/demos/01_point_column.html
+++ b/demos/01_point_column.html
@@ -38,7 +38,7 @@ scene.on('loaded', () => {
x: 'j',
y: 'w',
})
- .shape('3d:circle')
+ .shape('cylinder')
.size('t',(level)=> {
return [2,2,(level*3+20)];
})
diff --git a/demos/02_oneBletoneRoad.html b/demos/02_oneBletoneRoad.html
index c7a5f17796..ab9528f2a5 100644
--- a/demos/02_oneBletoneRoad.html
+++ b/demos/02_oneBletoneRoad.html
@@ -29,8 +29,6 @@ const scene = new L7.Scene({
scene.on('loaded', () => {
scene.image.addImage('local', 'https://gw.alipayobjects.com/zos/rmsportal/xZXhTxbglnuTmZEwqQrE.png');
-
-
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/UpapMomPYUeiBjbHNAma.json', region => {
const color = [ 'rgb(22,32,101)', 'rgb(28,43,127)', 'rgb(36,68,142)', 'rgb(45,94,158)', 'rgb(53,119,174)', 'rgb(61,145,190)', 'rgb(70,170,206)', 'rgb(98,190,210)', 'rgb(138,205,206)', 'rgb(179,221,204)', 'rgb(220,236,201)' ];
var points = region.features.map((feature)=>{
@@ -70,7 +68,7 @@ $.getJSON('https://gw.alipayobjects.com/os/rmsportal/dzpMOiLYBKxpdmsgBLoE.json',
.size([ 1.5, 0 ])
.shape('line')
.style({
- // 'lineType':'solid'
+ 'lineType':'dash'
})
.render();
});
diff --git a/demos/03_choropleths_polygon.html b/demos/03_choropleths_polygon.html
index 130c79ac28..832066b226 100644
--- a/demos/03_choropleths_polygon.html
+++ b/demos/03_choropleths_polygon.html
@@ -86,6 +86,7 @@ scene.on('loaded', () => {
opacity: 1
})
.render();
+ /**
const citylayer2 = scene.PolygonLayer()
.source(city)
.shape('line')
@@ -93,7 +94,8 @@ scene.on('loaded', () => {
.style({
opacity: 0.1
})
- .render();
+ // .render();
+ **/
citylayer.on('click',(e)=>{
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});
diff --git a/demos/06_text.html b/demos/06_text.html
index 37a66ba9d1..52c44ea774 100644
--- a/demos/06_text.html
+++ b/demos/06_text.html
@@ -35,7 +35,7 @@ scene.on('loaded', () => {
})
.source(data)
.shape('name', 'text')
- .size(10) // default 1
+ .size(12) // default 1
.color('#fff')
.style({
stroke: '#999',
diff --git a/demos/07_city.html b/demos/07_city.html
index 70dd134c51..032dfe9bcc 100644
--- a/demos/07_city.html
+++ b/demos/07_city.html
@@ -38,6 +38,7 @@ scene.on('loaded', () => {
})
.source(data)
.shape('fill')
+ .active({fill:'blue'})
.color('rgb(79,174,234)')
.render();
});
@@ -71,10 +72,12 @@ scene.on('loaded', () => {
.size('floor',[10,2000])
.color('rgba(242,246,250,0.96)')
.render();
+ /**
citylayer.on('click',(e)=>{
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});
$("#info").html(`
楼高${e.feature.properties.floor || 0}
`);
})
+ **/
});
});
diff --git a/demos/line.html b/demos/line.html
new file mode 100644
index 0000000000..6f7f23c30b
--- /dev/null
+++ b/demos/line.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+ city demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/point.html b/demos/point.html
new file mode 100644
index 0000000000..9769b40f3c
--- /dev/null
+++ b/demos/point.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+ point_circle
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/taxi.html b/demos/taxi.html
index a7e8f0fc40..d8ea264443 100644
--- a/demos/taxi.html
+++ b/demos/taxi.html
@@ -41,7 +41,7 @@ scene.on('loaded', () => {
.animate({enable:true})
.render();
});
- $.get('./data/2.geojson', data => {
+ $.get('https://gw.alipayobjects.com/os/rmsportal/vmvAxgsEwbpoSWbSYvix.json', data => {
buildLayer = scene.PolygonLayer({
zIndex: 2
})
diff --git a/package.json b/package.json
index 816c18fbbc..6b9922ad1a 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@antv/l7",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
"main": "build/l7.js",
"browser": "build/l7.js",
diff --git a/src/core/engine/picking/picking.js b/src/core/engine/picking/picking.js
index 1759a2c367..30832c81da 100755
--- a/src/core/engine/picking/picking.js
+++ b/src/core/engine/picking/picking.js
@@ -48,12 +48,12 @@ class Picking {
// return;
// }
- const point = { x: event.clientX, y: event.clientY };
+ const point = { x: event.clientX, y: event.clientY,type:event.type};
const normalisedPoint = { x: 0, y: 0 };
normalisedPoint.x = (point.x / this._width) * 2 - 1;
normalisedPoint.y = -(point.y / this._height) * 2 + 1;
-
- this._pick(point, normalisedPoint);
+ this._pickAllObject(point, normalisedPoint);
+ // this._pick(point, normalisedPoint);
}
_onWorldMove() {
@@ -76,10 +76,10 @@ class Picking {
_update(point) {
const texture = this._pickingTexture;
- if (this._needUpdate) {
- this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
- this._needUpdate = false;
- }
+ // if (this._needUpdate) {
+ this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
+ // this._needUpdate = false;
+ // }
this.pixelBuffer = new Uint8Array(4);
this._renderer.readRenderTargetPixels(texture, point.x, this._height - point.y, 1, 1, this.pixelBuffer);
@@ -99,17 +99,33 @@ class Picking {
});
}
+ _filterObject(id) {
+ this._pickingScene.children.forEach((object, index) => {
+ index === id ? object.visible = true : object.visible = false;
+ });
+ }
+ _pickAllObject(point, normalisedPoint) {
+ this._pickingScene.children.forEach((object, index) => {
+ this._filterObject(index);
+ const item = this._pick(point, normalisedPoint, object.name);
+ item.type = point.type;
+ this._world.emit('pick', item);
+ this._world.emit('pick-' + object.name, item);
+
+ });
+ }
_updateRender() {
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
}
- _pick(point, normalisedPoint) {
+ _pick(point, normalisedPoint, layerId) {
this._update(point);
// Interpret the pixel as an ID
- const id = (this.pixelBuffer[2] * 255 * 255) + (this.pixelBuffer[1] * 255) + (this.pixelBuffer[0]);
+ let id = (this.pixelBuffer[2] * 255 * 255) + (this.pixelBuffer[1] * 255) + (this.pixelBuffer[0]);
// Skip if ID is 16646655 (white) as the background returns this
if (id === 16646655 || this.pixelBuffer[3] === 0) {
- return;
+ id = -999;
+ // return;
}
this._raycaster.setFromCamera(normalisedPoint, this._camera);
@@ -118,7 +134,6 @@ class Picking {
//
// TODO: Only perform intersection test on the relevant picking mesh
const intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);
-
const _point2d = { x: point.x, y: point.y };
let _point3d;
@@ -131,13 +146,14 @@ class Picking {
//
// TODO: Look into the leak potential for passing so much by reference here
const item = {
+ layerId,
featureId: id - 1,
point2d: _point2d,
point3d: _point3d,
intersects
};
- this._world.emit('pick', item);
- // this._world.emit('pick-' + id, _point2d, _point3d, intersects);
+ return item
+
}
// Add mesh to picking scene
diff --git a/src/core/image.js b/src/core/image.js
index 60482885c0..845053d977 100644
--- a/src/core/image.js
+++ b/src/core/image.js
@@ -5,30 +5,32 @@ import { getImage } from '../util/ajax';
export default class LoadImage extends EventEmitter {
constructor() {
super();
- this.imageWidth = 64;
+ const pixelRatio = window.devicePixelRatio || 1;
+ this.imageWidth = 64 * pixelRatio;
this.canvas = document.createElement('canvas');
this.canvas.style.cssText += 'height: 512px;width: 512px;';
this.canvas.width = this.imageWidth * 8;
this.canvas.height = this.imageWidth * 8;
this.ctx = this.canvas.getContext('2d');
-
-
this.images = [];
this.imagesCount = 0;
this.imagePos = {};
+ this.imagesIds = [];
}
addImage(id, opt) {
this.imagesCount ++;
+ this.imagesIds.push(id);
const imageCount = this.imagesCount;
- const x = imageCount % 8 * 64;
- const y = parseInt(imageCount / 8) * 64;
- this.imagePos[id] = { x: x / 512, y: y / 512 };
+ const x = imageCount % 8 * this.imageWidth;
+ const y = parseInt(imageCount / 8) * this.imageWidth;
+ this.imagePos[id] = { x: x / this.canvas.width, y: y / this.canvas.height };
this.texture = new THREE.Texture(this.canvas);
if (typeof opt === 'string') {
getImage({ url: opt }, (err, img) => {
img.id = id;
+
this.images.push(img);
- this.ctx.drawImage(img, x, y, 64, 64);
+ this.ctx.drawImage(img, x, y, this.imageWidth, this.imageWidth);
this.texture.magFilter = THREE.LinearFilter;
this.texture.minFilter = THREE.LinearFilter;
@@ -47,7 +49,7 @@ export default class LoadImage extends EventEmitter {
image.data = data;
image.id = id;
this.images.push(image);
- this.ctx.drawImage(image, x, y, 64, 64);
+ this.ctx.drawImage(image, x, y, this.imageWidth, this.imageWidth);
this.texture = new THREE.CanvasTexture(this.canvas);
this.imagePos[id] = { x: x >> 9, y: y >> 9 };
if (this.images.length === this.imagesCount) {
diff --git a/src/core/layer.js b/src/core/layer.js
index a6b25b56bc..8d43b53735 100644
--- a/src/core/layer.js
+++ b/src/core/layer.js
@@ -36,9 +36,10 @@ export default class Layer extends Base {
attrs: {},
// 样式配置项
styleOptions: {
- stroke: [ 1.0, 1.0, 1.0, 1.0 ],
+ stroke: 'none',
strokeWidth: 1.0,
opacity: 1.0,
+ strokeOpacity: 1.0,
texture: false
},
// 选中时的配置项
@@ -63,31 +64,35 @@ export default class Layer extends Base {
this._activeIds = null;
scene._engine._scene.add(this._object3D);
this.layerMesh = null;
+ this.layerLineMesh = null;
}
/**
* 将图层添加加到 Object
* @param {*} object three 物体
+ * @param {*} type mesh类型是区别是填充还是边线
*/
- add(object) {
- this.layerMesh = object;
+ add(object, type = 'fill') {
+ type === 'fill' ? this.layerMesh = object : this.layerLineMesh = object;
+
this._visibleWithZoom();
this.scene.on('zoomchange', () => {
this._visibleWithZoom();
});
- this.layerMesh.onBeforeRender = () => {
+ object.onBeforeRender = () => {
const zoom = this.scene.getZoom();
- this.layerMesh.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime());
- this.layerMesh.material.setUniformsValue('u_zoom', zoom);
+ object.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime());
+ object.material.setUniformsValue('u_zoom', zoom);
+ this._preRender();
};
// 更新
if (this._needUpdateFilter) {
- this._updateFilter();
+ this._updateFilter(object);
}
this._object3D.add(object);
- this._addPickMesh(object);
+ if (type === 'fill') { this._addPickMesh(object); }
}
remove(object) {
this._object3D.remove(object);
@@ -131,7 +136,7 @@ export default class Layer extends Base {
}
values === 'text' ? this.shapeType = values : null;
- this._createAttrOption('shape', field, values, Global.sizes);
+ this._createAttrOption('shape', field, values, Global.shape);
return this;
}
/**
@@ -171,7 +176,7 @@ export default class Layer extends Base {
styleOptions.fields = fields;
Util.assign(styleOptions, cfg);
for (const item in cfg) {
- if (colorItem.indexOf(item) !== -1) {
+ if (colorItem.indexOf(item) !== -1 && styleOptions[item] !== 'none') {
styleOptions[item] = ColorUtil.color2RGBA(styleOptions[item]);
}
styleOptions[item] = styleOptions[item];
@@ -252,20 +257,24 @@ export default class Layer extends Base {
this._mapping();
const activeHander = this._addActiveFeature.bind(this);
+ const resetHander = this._resetStyle.bind(this);
if (this.get('allowActive')) {
- this.scene.on('pick', activeHander);
+ this.on('active', activeHander);
+ this.on('mouseleave', resetHander);
} else {
- this.scene.off('pick', activeHander);
+ this.off('active', activeHander);
+ this.off('mouseleave', resetHander);
}
}
_addActiveFeature(e) {
const { featureId } = e;
-
+ if (featureId < 0) return;
const activeStyle = this.get('activedOptions');
const selectFeatureIds = this.layerSource.getSelectFeatureId(featureId);
+ // 如果数据不显示状态则不进行高亮
if (this.StyleData[selectFeatureIds[0]].hasOwnProperty('filter') && this.StyleData[selectFeatureIds[0]].filter === false) { return; }
const style = Util.assign({}, this.StyleData[featureId]);
style.color = ColorUtil.toRGB(activeStyle.fill).map(e => e / 255);
@@ -434,6 +443,7 @@ 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();
@@ -445,6 +455,7 @@ export default class Layer extends Base {
});
const pickingMesh = new THREE[mesh.type](mesh.geometry, pickmaterial);
+ pickingMesh.name = this.layerId;
pickmaterial.setDefinesvalue(this.type, true);
pickingMesh.onBeforeRender = () => {
const zoom = this.scene.getZoom();
@@ -457,20 +468,40 @@ export default class Layer extends Base {
}
_addPickingEvents() {
// TODO: Find a way to properly remove this listener on destroy
- this.scene.on('pick', e => {
- // Re-emit click event from the layer
- const { featureId, point2d, intersects } = e;
- if (intersects.length === 0) { return; }
- const source = this.layerSource.get('data');
- const feature = source.features[featureId];
+ 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 = {
+ featureId,
feature,
pixel: point2d,
lnglat: { lng: lnglat.lng, lat: lnglat.lat }
};
- this.emit('click', target);
- // this.emit('move', target);
+ if(featureId>=0) {
+
+ switch(type) {
+ case 'mouseup':
+ this.emit('click', target);
+ break;
+ case 'mousemove':
+ this.emit('mousemove', target);
+ this.emit('active', target);
+ break;
+ default:
+ //this.emit('click', target);
+
+ }
+ }
+
+
+
});
}
/**
@@ -480,7 +511,7 @@ export default class Layer extends Base {
*/
updateStyle(featureStyleId, style) {
if (this._activeIds) {
- this.resetStyle();
+ this._resetStyle();
}
this._activeIds = featureStyleId;
const pickingId = this.layerMesh.geometry.attributes.pickingId.array;
@@ -507,15 +538,15 @@ export default class Layer extends Base {
}
/**
- * 用于过滤数据
- * @param {*} filterData 数据过滤标识符
+ * 用于过滤数据
+ * @param {*} object 需要过滤的mesh
*/
- _updateFilter() {
+ _updateFilter(object) {
this._updateMaping();
const filterData = this.StyleData;
this._activeIds = null; // 清空选中元素
- const colorAttr = this.layerMesh.geometry.attributes.a_color;
- const pickAttr = this.layerMesh.geometry.attributes.pickingId;
+ const colorAttr = object.geometry.attributes.a_color;
+ const pickAttr = object.geometry.attributes.pickingId;
pickAttr.array.forEach((id, index) => {
id = Math.abs(id);
const color = [ ...this.StyleData[id - 1].color ];
@@ -526,7 +557,7 @@ export default class Layer extends Base {
colorAttr.array[index * 4 + 1] = 0;
colorAttr.array[index * 4 + 2] = 0;
colorAttr.array[index * 4 + 3] = 0;
- pickAttr.array[index] = -id;
+ pickAttr.array[index] = -id; // 通过Id数据过滤 id<0 不显示
} else {
colorAttr.array[index * 4 + 0] = color[0];
colorAttr.array[index * 4 + 1] = color[1];
@@ -537,8 +568,8 @@ export default class Layer extends Base {
});
colorAttr.needsUpdate = true;
pickAttr.needsUpdate = true;
- this._needUpdateFilter = false;
- this._needUpdateColor = false;
+ // this._needUpdateFilter = false;
+ // this._needUpdateColor = false;
}
_visibleWithZoom() {
const zoom = this.scene.getZoom();
@@ -561,7 +592,8 @@ export default class Layer extends Base {
/**
* 重置高亮要素
*/
- resetStyle() {
+ _resetStyle() {
+
const pickingId = this.layerMesh.geometry.attributes.pickingId.array;
const colorAttr = this.layerMesh.geometry.attributes.a_color;
this._activeIds.forEach(index => {
@@ -577,6 +609,7 @@ export default class Layer extends Base {
}
});
colorAttr.needsUpdate = true;
+ this._activeIds = null;
}
/**
* 销毁Layer对象
@@ -609,5 +642,8 @@ export default class Layer extends Base {
this._object3D = null;
this.scene = null;
}
+ _preRender(){
+
+ }
}
diff --git a/src/core/scene.js b/src/core/scene.js
index 295c8d562a..f1e09140df 100644
--- a/src/core/scene.js
+++ b/src/core/scene.js
@@ -1,5 +1,4 @@
import Engine from './engine';
-import * as THREE from './three';
import * as layers from '../layer';
import Base from './base';
import LoadImage from './image';
@@ -19,6 +18,7 @@ export default class Scene extends Base {
}
_initEngine(mapContainer) {
+ this._el = mapContainer;
this._engine = new Engine(mapContainer, this);
this._engine.run();
}
@@ -77,16 +77,34 @@ export default class Scene extends Base {
return this._layers;
}
_addLight() {
- const scene = this._engine._scene;
- const ambientLight = new THREE.AmbientLight(0xaaaaaa);
- scene.add(ambientLight);
+ // const scene = this._engine._scene;
+ // //const ambientLight = new THREE.AmbientLight(0xaaaaaa);
+ // scene.add(ambientLight);
- const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
- scene.add(directionalLight);
+ // const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
+ // scene.add(directionalLight);
}
_addLayer() {
}
+ _registEvents(){
+ const events = [
+ 'mouseout',
+ 'mouseover',
+ 'mousemove',
+ 'mousedown',
+ 'mouseleave',
+ 'mouseup',
+ 'click',
+ 'dblclick'
+ ];
+ events.forEach((event)=>{
+ this._el.addEventListener(event, e => {
+
+ }, false);
+ })
+ }
+ // 代理map事件
removeLayer(layer) {
const layerIndex = this._layers.indexOf(layer);
if (layerIndex > -1) {
diff --git a/src/core/three.js b/src/core/three.js
index 6b60d4909e..19202f3e2d 100644
--- a/src/core/three.js
+++ b/src/core/three.js
@@ -9,8 +9,8 @@ export { Points } from 'three/src/objects/Points.js';
export { LineSegments } from 'three/src/objects/LineSegments.js';
export { Mesh } from 'three/src/objects/Mesh.js';
export { Texture } from 'three/src/textures/Texture.js';
-export { DirectionalLight } from 'three/src/lights/DirectionalLight.js';
-export { AmbientLight } from 'three/src/lights/AmbientLight.js';
+//export { DirectionalLight } from 'three/src/lights/DirectionalLight.js';
+//export { AmbientLight } from 'three/src/lights/AmbientLight.js';
export { WebGLRenderTarget } from 'three/src/renderers/WebGLRenderTarget.js';
export { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera.js';
export { BufferGeometry } from 'three/src/core/BufferGeometry.js';
@@ -18,15 +18,15 @@ export { Raycaster } from 'three/src/core/Raycaster.js';
export { Matrix4 } from 'three/src/math/Matrix4.js';
export { Matrix3 } from 'three/src/math/Matrix3.js';
export { Line } from 'three/src/objects/Line.js';
-export { LineLoop } from 'three/src/objects/LineLoop.js';
+// export { LineLoop } from 'three/src/objects/LineLoop.js';
export { Vector4 } from 'three/src/math/Vector4.js';
export { Vector3 } from 'three/src/math/Vector3.js';
export { Vector2 } from 'three/src/math/Vector2.js';
-export { TextureLoader } from 'three/src/loaders/TextureLoader.js';
-export { LineDashedMaterial } from 'three/src/materials/LineDashedMaterial.js';
+// export { TextureLoader } from 'three/src/loaders/TextureLoader.js';
+// export { LineDashedMaterial } from 'three/src/materials/LineDashedMaterial.js';
export { ShaderMaterial } from 'three/src/materials/ShaderMaterial.js';
-export { PointsMaterial } from 'three/src/materials/PointsMaterial.js';
-export { VideoTexture } from 'three/src/textures/VideoTexture.js';
+// export { PointsMaterial } from 'three/src/materials/PointsMaterial.js';
+// export { VideoTexture } from 'three/src/textures/VideoTexture.js';
export { DataTexture } from 'three/src/textures/DataTexture.js';
export {
Float64BufferAttribute,
diff --git a/src/geo/bound.js b/src/geo/bound.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/geo/lngLat.js b/src/geo/lngLat.js
new file mode 100644
index 0000000000..edc7b59576
--- /dev/null
+++ b/src/geo/lngLat.js
@@ -0,0 +1,20 @@
+export class LatLng {
+ constructor(lat, lng, alt) {
+ if (isNaN(lat) || isNaN(lng)) {
+ throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');
+ }
+ this.lat = +lat;
+ this.lng = +lng;
+ if (alt !== undefined) {
+ this.alt = +alt;
+ }
+
+ }
+ equal() {
+
+ }
+ distanceTo() {
+
+ }
+
+}
diff --git a/src/geom/buffer/point.js b/src/geom/buffer/point.js
index 7de8e3536e..fe7d961999 100644
--- a/src/geom/buffer/point.js
+++ b/src/geom/buffer/point.js
@@ -1,5 +1,9 @@
import BufferBase from './bufferBase';
import { regularShape } from '../shape/index';
+import * as polygonPath from '../shape/path';
+import * as polygonShape from '../shape/polygon';
+import * as lineShape from '../shape/line';
+import { pointShape } from '../../global';
import Util from '../../util';
export default class PointBuffer extends BufferBase {
geometryBuffer() {
@@ -43,8 +47,17 @@ export default class PointBuffer extends BufferBase {
this.attributes = this._toPointsAttributes(this.bufferStruct);
}
_3dRegularBuffer() {
+ const lineAttribute = {
+ shapes: [],
+ normal: [],
+ miter: [],
+ indexArray: [],
+ sizes: [],
+ positions: []
+ };
const coordinates = this.get('coordinates');
const properties = this.get('properties');
+ const style = this.get('style');
const type = this.get('type');
const positions = [];
const shapes = [];
@@ -55,7 +68,7 @@ export default class PointBuffer extends BufferBase {
this.bufferStruct.style = properties;
coordinates.forEach((geo, index) => {
let { size, shape } = properties[index];
- let shapeType = 'extrude';
+ let shapeType = '';
if (type === '2d' || (type === '3d' && size[2] === 0)) {
shapeType = 'fill';
@@ -67,7 +80,20 @@ 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);
+ // const vert = regularShape[shape](shapeType);
+ properties[index].size = size;
+
+ const [ vert, polygonLine ] = this._getShape(properties[index], style, lineAttribute.miter.length);
+ polygonLine.miter.forEach(() => {
+ lineAttribute.positions.push(...geo);
+ lineAttribute.sizes.push(...size);
+ });
+
+ lineAttribute.shapes.push(...polygonLine.positions);
+ lineAttribute.normal.push(...polygonLine.normal);
+ lineAttribute.miter.push(...polygonLine.miter);
+ lineAttribute.indexArray.push(...polygonLine.indexArray);
+
shapes.push(vert.positions);
positions.push(geo);
sizes.push(size);
@@ -81,6 +107,21 @@ export default class PointBuffer extends BufferBase {
this.bufferStruct.sizes = sizes;
this.bufferStruct.faceUv = uvs;
this.attributes = this._toPointShapeAttributes(this.bufferStruct);
+ this.lineAttribute = lineAttribute;
+ }
+ _getShape(props, style, positionsIndex) {
+ const { shape } = props;
+ const { stroke, strokeWidth } = style;
+ const path = polygonPath[shape]();
+ let polygon = null;
+ let polygonLine = null;
+ if (pointShape['3d'].indexOf(shape) === -1) {
+ polygon = polygonShape.fill([ path ]);
+ polygonLine = lineShape.Line(path, { size: [ strokeWidth, 0 ], color: stroke }, positionsIndex);
+ } else {
+ polygon = polygonShape.extrude([ path ]);
+ }
+ return [ polygon, polygonLine ];
}
}
diff --git a/src/geom/buffer/point/fillBuffer.js b/src/geom/buffer/point/fillBuffer.js
new file mode 100644
index 0000000000..84d257c3ee
--- /dev/null
+++ b/src/geom/buffer/point/fillBuffer.js
@@ -0,0 +1,81 @@
+import { pointShape } from '../../../global';
+import * as THREE from '../../../core/three';
+import * as polygonShape from '../../shape/polygon';
+import * as polygonPath from '../../shape/path';
+import Util from '../../../util';
+export default function fillBuffer(coordinates, properties) {
+ const attribute = {
+ vertices: [],
+ normals: [],
+ colors: [],
+ pickingIds: [],
+ shapePositions: [],
+ a_size: [],
+ faceUv: []
+
+ };
+ coordinates.forEach((geo, index) => {
+ let { size, shape, color, id } = properties[index];
+ let polygon = null;
+ const path = polygonPath[shape]();
+ if (pointShape['2d'].indexOf(shape) !== -1) {
+ Util.isArray(size) || (size = [ size, size, 0 ]);
+ polygon = polygonShape.fill([ path ]);
+ } else if (pointShape['3d'].indexOf(shape) !== -1) {
+ Util.isArray(size) || (size = [ size, size, size ]);
+ polygon = polygonShape.extrude([ path ]);
+ } else {
+ throw new Error('Invalid shape type: ' + shape);
+ }
+ toPointShapeAttributes(polygon, geo, { size, shape, color, id }, attribute);
+
+ });
+ return attribute;
+
+}
+function toPointShapeAttributes(polygon, geo, style, attribute) {
+ const { positionsIndex, positions } = polygon;
+ const pA = new THREE.Vector3();
+ const pB = new THREE.Vector3();
+ const pC = new THREE.Vector3();
+
+ const cb = new THREE.Vector3();
+ const ab = new THREE.Vector3();
+ for (let i = 0; i < positionsIndex.length / 3; i++) {
+ let index = positionsIndex[i * 3];
+ const { color, size, id } = style;
+ const ax = positions[index][0];
+ const ay = positions[index][1];
+ const az = positions[index][2];
+ index = positionsIndex[i * 3 + 1];
+ const bx = positions[index][0];
+ const by = positions[index][1];
+ const bz = positions[index][2];
+ index = positionsIndex[i * 3 + 2];
+ const cx = positions[index][0];
+ const cy = positions[index][1];
+ const cz = positions[index][2];
+
+ 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;
+
+ attribute.vertices.push(...geo, ...geo, ...geo);
+ attribute.shapePositions.push(ax, ay, az, bx, by, bz, cx, cy, cz);
+ attribute.a_size.push(...size, ...size, ...size);
+ attribute.normals.push(nx, ny, nz, nx, ny, nz, nx, ny, nz);
+ attribute.colors.push(...color, ...color, ...color);
+ attribute.pickingIds.push(id, id, id);
+
+ }
+}
diff --git a/src/geom/buffer/point/imageBuffer.js b/src/geom/buffer/point/imageBuffer.js
new file mode 100644
index 0000000000..6bc37b052a
--- /dev/null
+++ b/src/geom/buffer/point/imageBuffer.js
@@ -0,0 +1,23 @@
+export default function ImageBuffer(coordinates, properties, opt) {
+ const attributes = {
+ vertices: [],
+ colors: [],
+ sizes: [],
+ shapes: [],
+ pickingIds: [],
+ uv: []
+ };
+ coordinates.forEach((pos, index) => {
+ const { color, size, id, shape } = properties[index];
+ const { x, y } = opt.imagePos[shape];
+ attributes.vertices.push(...pos);
+ attributes.colors.push(...color);
+ attributes.pickingIds.push(id);
+ attributes.sizes.push(size * window.devicePixelRatio); //
+ attributes.uv.push(x, y);
+ attributes.shapes.push(shape);
+ });
+
+
+ return attributes;
+}
diff --git a/src/geom/buffer/point/index.js b/src/geom/buffer/point/index.js
new file mode 100644
index 0000000000..80d52c5ff1
--- /dev/null
+++ b/src/geom/buffer/point/index.js
@@ -0,0 +1,4 @@
+export { default as FillBuffer } from './fillBuffer';
+export { default as StrokeBuffer } from './strokeBuffer';
+export { default as ImageBuffer } from './imageBuffer';
+export { default as NormalBuffer } from './normalBuffer';
diff --git a/src/geom/buffer/point/normalBuffer.js b/src/geom/buffer/point/normalBuffer.js
new file mode 100644
index 0000000000..d35fd4217b
--- /dev/null
+++ b/src/geom/buffer/point/normalBuffer.js
@@ -0,0 +1,19 @@
+export default function NormalBuffer(coordinates, properties) {
+ const attributes = {
+ vertices: [],
+ colors: [],
+ sizes: [],
+ pickingIds: []
+ };
+ coordinates.forEach((pos, index) => {
+ const { color, size, id } = properties[index];
+ attributes.vertices.push(...pos);
+ attributes.colors.push(...color);
+ attributes.pickingIds.push(id);
+ attributes.sizes.push(size);
+
+ });
+
+
+ return attributes;
+}
diff --git a/src/geom/buffer/point/sdfCommonWords.js b/src/geom/buffer/point/sdfCommonWords.js
new file mode 100644
index 0000000000..4631cc11cf
--- /dev/null
+++ b/src/geom/buffer/point/sdfCommonWords.js
@@ -0,0 +1,246 @@
+const SDFCommonWordsKey = '_AMap_sdf_com_words';
+
+/**
+ * SDF 常用字获取/存储/check
+ *
+ */
+const SDFCommonWords = {
+
+ store() {
+
+ },
+
+ /**
+ * 检查一个字符是否在常用字中
+ * @param {*} charcode 汉字
+ */
+ check(charcode) {
+ const range = this.range || [];
+ const info = this.info || {};
+
+ if (typeof charcode !== 'number') {
+
+ charcode = charcode.substr(0).charCodeAt(0);
+ }
+
+ for (let i = 0; i < range.length; i++) {
+ const curRange = range[i];
+ const [ rangeStart, rangeEnd ] = curRange.split('-');
+
+ if (charcode >= rangeStart && charcode <= rangeEnd) {
+
+ const curInfo = info[curRange] && info[curRange].info || {};
+
+ if (curInfo[charcode]) {
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * 获取纹理和位置信息
+ * @param list
+ * @param cb
+ */
+ getImagesAndInfo(list, cb) {
+ const range = this.range;
+
+
+ },
+
+ loadCanvas(url, range, done) {
+
+ try {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+
+ // 直接用 blob 格式 load 图片文件,方便直接转换成 base64
+ // 转成 base64 便于存储
+ // 使用 canvas 转换 base64 容易有损
+ xhr.responseType = 'blob';
+ xhr.onerror = function() {
+ done({ code: 0 });
+ };
+
+ xhr.onload = function() {
+
+ if (xhr.status === 200) {
+ const reader = new FileReader();
+
+ reader.onload = () => {
+
+ done(reader.result, range);
+ };
+
+ reader.readAsDataURL(xhr.response);
+ } else {
+ done({ code: 0 });
+ }
+ };
+
+ xhr.send();
+ } catch (err) {
+
+ done({ code: 0 });
+ }
+ },
+
+ loadImages(urls = []) {
+ const deferred = $.Deferred();
+ const totalNumbers = urls.length;
+ const localInfo = this.info;
+ let loadPicNum = 0;
+
+ for (let i = 0; i < urls.length; i++) {
+ const { url, range } = urls[i];
+
+ this.loadCanvas(url, range, (base64, range) => {
+
+ // image to base64
+ loadPicNum++;
+
+ !localInfo[range] && (localInfo[range] = {});
+
+ localInfo[range].pic = base64;
+
+ this.info = localInfo;
+
+ // todo: temp 暂时用 localstorage 存储,因为数据比较大,最好使用 indexDB
+ localStorage.setItem(SDFCommonWordsKey, JSON.stringify(localInfo));
+
+ if (loadPicNum === totalNumbers) {
+
+ deferred.resolve();
+ }
+ });
+ }
+
+ return deferred;
+ },
+
+ loadInfo(urls) {
+ const deferred = $.Deferred();
+ const totalNumbers = urls.length;
+ const localInfo = this.info;
+ let loadInfoNum = 0;
+
+ for (let i = 0; i < urls.length; i++) {
+ const { url, range } = urls[i];
+
+ $.ajax({
+ url,
+ dataType: 'json',
+ success: data => {
+ loadInfoNum++;
+
+ !localInfo[range] && (localInfo[range] = {});
+
+ localInfo[range].info = data;
+
+ this.info = localInfo;
+
+ localStorage.setItem(SDFCommonWordsKey, JSON.stringify(localInfo));
+
+ if (loadInfoNum === totalNumbers) {
+
+ deferred.resolve();
+ }
+ },
+ error: () => {
+
+ }
+ });
+ }
+
+ return deferred;
+
+ },
+
+ getTotalAssets(info, cb) {
+ const { range = [], urlPrefix } = info;
+ const picUrls = [];
+ const infoUrls = [];
+
+ this.range = range;
+
+ for (let i = 0; i < range.length; i++) {
+ const curRange = range[i];
+ const baseUrl = urlPrefix + curRange;
+ const picUrl = baseUrl + '.png';
+ const infoUrl = baseUrl + '.json';
+
+ picUrls.push({ range: curRange, url: picUrl });
+ infoUrls.push({ range: curRange, url: infoUrl });
+ }
+
+ const imageDeferred = this.loadImages(picUrls);
+ const infoDeferred = this.loadInfo(infoUrls);
+
+ $.when(imageDeferred, infoDeferred)
+ .then(() => {
+
+ // all info load complete
+ // console.log("all info load complete", " -- ", 1);
+ cb && cb(this.info);
+ }, () => {
+
+ // fail
+ });
+ },
+ // 获取数据
+ getData(cb) {
+
+ if (!_.isEmpty(this.info)) {
+
+ cb && cb(this.info);
+ } else {
+
+ this.getRemoteData(cb);
+ }
+ },
+
+ /**
+ * 从服务获取数据,什么时候强制去取一回数据?过期?
+ * @param cb
+ */
+ getRemoteData(cb) {
+ const self = this;
+
+ $.ajax({
+ url: '/getcommonwords',
+ dataType: 'json',
+ success: data => {
+
+ if (data.code == 1) {
+
+ const info = data.data;
+
+ self.getTotalAssets(info, cb);
+ }
+ }
+ });
+ },
+
+ destroy() {
+
+ },
+
+ init() {
+ let info = localStorage.getItem(SDFCommonWordsKey);
+ this.range = [];
+ this.info = {};
+
+ if (info) {
+ info = JSON.parse(info);
+ this.range = Object.keys(info);
+ this.info = info;
+ }
+
+ this.info = info || {};
+ }
+};
+export default SDFCommonWords;
diff --git a/src/geom/buffer/point/strokeBuffer.js b/src/geom/buffer/point/strokeBuffer.js
new file mode 100644
index 0000000000..c71726cbd6
--- /dev/null
+++ b/src/geom/buffer/point/strokeBuffer.js
@@ -0,0 +1,53 @@
+import * as polygonPath from '../../shape/path';
+import * as polygonShape from '../../shape/polygon';
+import * as lineShape from '../../shape/line';
+import { pointShape } from '../../../global';
+import Util from '../../../util';
+export default function StrokeBuffer(coordinates, properties, style) {
+ const attribute = {
+ shapes: [],
+ normal: [],
+ miter: [],
+ indexArray: [],
+ sizes: [],
+ positions: [],
+ pickingIds: [],
+ colors: []
+ };
+ const { stroke, strokeWidth } = style;
+ coordinates.forEach((geo, index) => {
+ let { size, shape, id } = properties[index];
+ const path = polygonPath[shape]();
+ const positionsIndex = attribute.miter.length;
+ let polygon = null;
+ if (pointShape['2d'].indexOf(shape) !== -1) {
+ Util.isArray(size) || (size = [ size, size, 0 ]);
+ polygon = lineShape.Line([ path ], { size: [ strokeWidth, 0 ], color: stroke, id }, positionsIndex);
+ } else if (pointShape['3d'].indexOf(shape) !== -1) {
+ Util.isArray(size) || (size = [ size, size, size ]);
+ const polygonExtrudePath = polygonShape.extrudeline([ path ]);
+ // TODO 3d line
+ polygon = lineShape.Line([ polygonExtrudePath ], { size: [ strokeWidth, 0 ], color: stroke, id }, positionsIndex);
+
+
+ } else {
+ throw new Error('Invalid shape type: ' + shape);
+ }
+ polygonLineBuffer(polygon, geo, size, attribute);
+
+ });
+ return attribute;
+}
+function polygonLineBuffer(polygon, geo, size, attribute) {
+ attribute.shapes.push(...polygon.positions);
+ attribute.normal.push(...polygon.normal);
+ attribute.miter.push(...polygon.miter);
+ attribute.pickingIds.push(...polygon.pickingIds);
+ attribute.indexArray.push(...polygon.indexArray);
+ attribute.colors.push(...polygon.colors);
+ polygon.miter.forEach(() => {
+ attribute.positions.push(...geo); // 多边形位置
+ attribute.sizes.push(...size); // 多边形大小
+ });
+
+}
diff --git a/src/geom/buffer/point/textBuffer.js b/src/geom/buffer/point/textBuffer.js
new file mode 100644
index 0000000000..0f4801fb68
--- /dev/null
+++ b/src/geom/buffer/point/textBuffer.js
@@ -0,0 +1,9 @@
+
+
+import { getJSON } from '../../../util/ajax';
+import * as THREE from '../../../core/three';
+import Global from '../../../global';
+const Space = 1;
+export default function TextBuffer(coordinates, properties, style) {
+
+}
diff --git a/src/geom/buffer/text.js b/src/geom/buffer/text.js
index 710dfd1bdc..0607ec5aaf 100644
--- a/src/geom/buffer/text.js
+++ b/src/geom/buffer/text.js
@@ -1,6 +1,8 @@
import BufferBase from './bufferBase';
import { getJSON } from '../../util/ajax';
import * as THREE from '../../core/three';
+import TinySDF from '@mapbox/tiny-sdf';
+
import Global from '../../global';
const Space = 1;
export default class TextBuffer extends BufferBase {
@@ -15,16 +17,21 @@ export default class TextBuffer extends BufferBase {
const properties = this.get('properties');
const { textOffset = [ 0, 0 ] } = this.get('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));
}
}
});
+ const sdfTexture = this._updateSdf(Object.keys(textChars).join(''));
+ this.sdfTexture = sdfTexture;
+
this._loadTextInfo(chars);
this.on('SourceLoaded', () => {
const textureElements = [];
@@ -40,10 +47,10 @@ export default class TextBuffer extends BufferBase {
let text = element.shape || '';
text = text.toString();
for (let i = 0; i < text.length; i++) {
- const chr = text.charCodeAt(i);
+
const color = element.color;
- this._drawGlyph(pos, chr, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color);
+ this._drawGlyph(pos, text[i], pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color);
}
});
this.bufferStruct.style = properties;
@@ -64,6 +71,7 @@ export default class TextBuffer extends BufferBase {
url: `${Global.sdfHomeUrl}/getsdfdata?chars=${chars.join('|')}`
}, (e, info) => {
this.metrics.chars = info.info;
+
this._loadTextTexture(info.url);
});
}
@@ -73,8 +81,9 @@ export default class TextBuffer extends BufferBase {
const img = new Image();
img.crossOrigin = 'anonymous';
+
img.onload = () => {
- this.bufferStruct.textTexture = this._creatTexture(img);
+ this.bufferStruct.textTexture = this._creatTexture(this.sdfTexture.texure);
this.emit('SourceLoaded');
};
img.src = url;
@@ -93,22 +102,26 @@ export default class TextBuffer extends BufferBase {
* @param {*} textOffsets 字体偏移量数据
* @param {*} color 文字颜色
*/
- _drawGlyph(pos, chr, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
+ _drawGlyph(pos, text, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
const metrics = this.metrics;
+ const chr = text.charCodeAt(0);
const metric = metrics.chars[chr];
if (!metric) return;
-
+ const info = this.sdfTexture.info;
+ const { x, y } = info[text];
const scale = size / metrics.size;
- let width = metric[0];
- let height = metric[1];
+ let width = 24; // metric[0];
+ let height = 24;// metric[1];
const horiBearingX = metric[2];
- const horiBearingY = metric[3];
+ // const horiBearingY = metric[3];
const horiAdvance = metric[4];
- const posX = metric[5];
- const posY = metric[6];
+ // const posX = metric[5];
+ // const posY = metric[6];
+ const posX = x;
+ const posY = y;
const buffer = metrics.buffer;
@@ -117,12 +130,17 @@ export default class TextBuffer extends BufferBase {
height += buffer * 2;
// Add a quad (= two triangles) per glyph.
- const originX = (horiBearingX - buffer + width / 2) * scale;
- const originY = -(height / 2 - horiBearingY) * scale;
- // const originY = (height / 2 - horiBearingY) * scale;
- // const originY = 0;
- const offsetWidth = width / 2 * scale / (1.0 - horiBearingX * 1.5 / horiAdvance);
- const offsetHeight = (horiAdvance / 2) * scale;
+ // const originX = (horiBearingX - buffer + width / 2) * scale;
+ // const originY = -(height - horiBearingY) * scale;
+ const originX = 0;
+ const originY = 0;
+
+ // const offsetWidth = width / 2 * scale / (1.0 - horiBearingX * 1.5 / horiAdvance);
+ // const offsetHeight = (horiAdvance / 2) * scale;
+
+ // const offsetWidth = width/2 * scale;
+ // const offsetHeight = height / 2 * scale;
+ // const offsetHeight = height * scale;
const offsetX = pen.x;
const offsetY = pen.y;
@@ -135,14 +153,31 @@ export default class TextBuffer extends BufferBase {
pos[0] + originX, pos[1] + originY, 0,
);
+ // textSizes.push(
+ // offsetWidth, offsetHeight,
+ // -offsetWidth, offsetHeight,
+ // -offsetWidth, -offsetHeight,
+ // offsetWidth, offsetHeight,
+ // -offsetWidth, -offsetHeight,
+ // offsetWidth, -offsetHeight,
+ // );
+ const bx = 0;
+ const by = metrics.size / 2 + buffer;
textSizes.push(
- offsetWidth, offsetHeight,
- -offsetWidth, offsetHeight,
- -offsetWidth, -offsetHeight,
- offsetWidth, offsetHeight,
- -offsetWidth, -offsetHeight,
- offsetWidth, -offsetHeight,
+
+
+ ((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,
@@ -172,7 +207,8 @@ export default class TextBuffer extends BufferBase {
);
}
- pen.x = pen.x + (horiAdvance + Space) * scale;
+ // pen.x = pen.x + (horiAdvance + Space) * scale;
+ pen.x = pen.x + size * 1.8;
}
@@ -196,8 +232,46 @@ export default class TextBuffer extends BufferBase {
this.bufferStruct.textSize = [ image.width, image.height ];
const texture = new THREE.Texture(image);
texture.minFilter = THREE.LinearFilter;
- texture.magFilter = THREE.LinearFilter;
+ texture.magFilter = THREE.ClampToEdgeWrapping;
texture.needsUpdate = true;
return texture;
}
+ _updateSdf(chars) {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ const sdfs = {};
+
+
+ const fontSize = 24;
+ const fontWeight = 100;
+ const buffer = fontSize / 8;
+ const radius = fontSize / 3;
+ const canvasSize = Math.floor(Math.pow(chars.length, 0.5)) * (fontSize + buffer + radius);
+ canvas.width = canvasSize;
+ canvas.height = canvasSize;
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ const sdf = new TinySDF(fontSize, buffer, radius, null, null, fontWeight);
+ for (let y = 0, i = 0; y + sdf.size <= canvas.height && i < chars.length; y += sdf.size) {
+ for (let x = 0; x + sdf.size <= canvas.width && i < chars.length; x += sdf.size) {
+ ctx.putImageData(this._makeRGBAImageData(ctx, sdf.draw(chars[i]), sdf.size), x, y);
+ sdfs[chars[i]] = { x, y };
+ i++;
+ }
+ }
+ return {
+ info: sdfs,
+ texure: canvas
+ };
+ }
+ _makeRGBAImageData(ctx, alphaChannel, size) {
+ const imageData = ctx.createImageData(size, size);
+ const data = imageData.data;
+ for (let i = 0; i < alphaChannel.length; i++) {
+ data[4 * i + 0] = alphaChannel[i];
+ data[4 * i + 1] = alphaChannel[i];
+ data[4 * i + 2] = alphaChannel[i];
+ data[4 * i + 3] = 255;
+ }
+ return imageData;
+ }
}
diff --git a/src/geom/material/lineMaterial.js b/src/geom/material/lineMaterial.js
index 4af10d581a..a4b43c7eda 100644
--- a/src/geom/material/lineMaterial.js
+++ b/src/geom/material/lineMaterial.js
@@ -45,7 +45,10 @@ export function MeshLineMaterial(options) {
uniforms: {
u_opacity: { value: options.u_opacity || 1.0 },
u_time: { value: options.u_time || 0 },
- u_zoom: { value: options.u_zoom }
+ u_zoom: { value: options.u_zoom },
+ u_duration: { value: options.u_duration || 2.0 },
+ u_interval: { value: options.u_interval || 1.0 },
+ u_trailLength: { value: options.u_trailLength || 0.2 }
},
vertexShader: meshline_vert,
fragmentShader: meshline_frag,
diff --git a/src/geom/material/pointLineMaterial.js b/src/geom/material/pointLineMaterial.js
new file mode 100644
index 0000000000..cf89204eeb
--- /dev/null
+++ b/src/geom/material/pointLineMaterial.js
@@ -0,0 +1,29 @@
+import Material from './material';
+import point_frag from '../shader/point_meshLine_frag.glsl';
+import point_vert from '../shader/point_meshLine_vert.glsl';
+
+export default class PointLineMaterial extends Material {
+ getDefaultParameters() {
+ return {
+ uniforms: {
+ u_strokeOpacity: { value: 1 },
+ u_stroke: { value: [ 1.0, 1.0, 1.0, 1.0 ] },
+ u_strokeWidth: { value: 1.0 },
+ u_zoom: { value: 10 }
+
+ }
+ };
+ }
+ constructor(_uniforms, _defines, parameters) {
+ super(parameters);
+ const { uniforms } = this.getDefaultParameters();
+
+ this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms));
+ this.type = 'PointLineMaterial';
+ this.vertexShader = point_vert;
+ this.fragmentShader = point_frag;
+ this.transparent = true;
+ }
+
+
+}
diff --git a/src/geom/shader/meshline_frag.glsl b/src/geom/shader/meshline_frag.glsl
index 05adc838f1..3372d3c248 100644
--- a/src/geom/shader/meshline_frag.glsl
+++ b/src/geom/shader/meshline_frag.glsl
@@ -1,7 +1,11 @@
precision highp float;
uniform float u_opacity;
varying vec4 v_color;
+varying float vTime;
void main() {
gl_FragColor = v_color;
- gl_FragColor.a = v_color.a * u_opacity ;
+ gl_FragColor.a = v_color.a * u_opacity;
+ #ifdef ANIMATE
+ gl_FragColor.a *= vTime;
+ #endif
}
diff --git a/src/geom/shader/meshline_vert.glsl b/src/geom/shader/meshline_vert.glsl
index 30cc7935b4..14c8edb7cc 100644
--- a/src/geom/shader/meshline_vert.glsl
+++ b/src/geom/shader/meshline_vert.glsl
@@ -2,12 +2,30 @@ precision highp float;
attribute float a_miter;
attribute vec4 a_color;
attribute float a_size;
+attribute float a_distance;
uniform float u_zoom;
varying vec4 v_color;
+uniform float u_time;
+varying float vTime;
+// animate
+#ifdef ANIMATE
+uniform float u_duration; // 动画持续时间
+uniform float u_interval;
+uniform float u_repeat;
+uniform float u_trailLength;
+#endif
+
+
void main() {
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
vec3 pointPos = position.xyz + vec3(normal * a_size * pow(2.0,20.0-u_zoom) / 2.0 * a_miter);
v_color = a_color;
+ #ifdef ANIMATE
+ //mod(a_distance,0.2) * 5.
+ float alpa =1.0 - fract( mod(1.0- a_distance,u_interval)* (1.0/u_interval) + u_time / u_duration);
+ alpa = (alpa + u_trailLength -1.0) / u_trailLength;
+ vTime = clamp(alpa,0.,1.);
+ #endif
gl_Position = matModelViewProjection * vec4(pointPos, 1.0);
}
\ No newline at end of file
diff --git a/src/geom/shader/point_meshLine_frag.glsl b/src/geom/shader/point_meshLine_frag.glsl
new file mode 100644
index 0000000000..c291ef92a9
--- /dev/null
+++ b/src/geom/shader/point_meshLine_frag.glsl
@@ -0,0 +1,17 @@
+precision highp float;
+uniform float u_strokeOpacity;
+uniform vec4 u_stroke;
+varying float v_pickingId;
+
+void main() {
+ if(v_pickingId < -0.1) {
+ discard;
+ }
+ #ifdef ANIMATE
+ if (vTime > 1.0 || vTime < 0.0) {
+ discard;
+ }
+ #endif
+ gl_FragColor = u_stroke;
+ gl_FragColor.a = u_stroke.a * u_strokeOpacity ;
+}
diff --git a/src/geom/shader/point_meshLine_vert.glsl b/src/geom/shader/point_meshLine_vert.glsl
new file mode 100644
index 0000000000..3f8db3560b
--- /dev/null
+++ b/src/geom/shader/point_meshLine_vert.glsl
@@ -0,0 +1,23 @@
+precision highp float;
+attribute float a_miter;
+attribute vec3 a_size;
+attribute vec3 a_shape;
+attribute float pickingId;
+uniform float u_strokeWidth;
+uniform float u_zoom;
+varying float v_pickingId;
+uniform float u_time;
+varying float vTime;
+void main() {
+ mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
+ float scale = pow(2.0,(20.0 - u_zoom));
+ vec3 newposition = position + (a_size + vec3(u_strokeWidth/2.,u_strokeWidth/2.,0)) * scale* a_shape;
+ v_pickingId = pickingId;
+ #ifdef ANIMATE
+ vTime = 1.0- (mod(u_time*50.,3600.)- position.z) / 100.;
+ #endif
+ //vec3 pointPos = newposition.xyz + vec3(normal * u_strokeWidth * pow(2.0,20.0-u_zoom) / 2.0 * a_miter);
+ vec3 pointPos = newposition.xyz + vec3(normal * u_strokeWidth * scale / 2.0 * a_miter);
+ gl_Position = matModelViewProjection * vec4(pointPos, 1.0);
+
+}
\ No newline at end of file
diff --git a/src/geom/shader/text_frag.glsl b/src/geom/shader/text_frag.glsl
index dc987b8de6..886403db72 100644
--- a/src/geom/shader/text_frag.glsl
+++ b/src/geom/shader/text_frag.glsl
@@ -10,20 +10,19 @@ varying vec2 v_texcoord;
void main() {
- float dist = texture2D(u_texture, vec2(v_texcoord.x,1.0-v_texcoord.y)).r;
+ float dist =texture2D(u_texture, vec2(v_texcoord.x,1.0-v_texcoord.y)).r;
float alpha;
if(u_strokeWidth == 0.0){
- alpha = smoothstep(u_buffer - u_gamma, u_buffer, dist);
+ alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist);
gl_FragColor = vec4(v_color.rgb, alpha * v_color.a);
-
}else{
if(dist <= u_buffer - u_gamma){
- alpha = smoothstep(u_strokeWidth - u_gamma, u_strokeWidth, dist);
+ alpha = smoothstep(u_strokeWidth - u_gamma, u_strokeWidth+ u_gamma, dist);
gl_FragColor = vec4(u_stroke.rgb, alpha * u_stroke.a);
}else if(dist < u_buffer){
- alpha = smoothstep(u_buffer - u_gamma, u_buffer, dist);
+ alpha = smoothstep(u_buffer - u_gamma, u_buffer+u_gamma, dist);
gl_FragColor = vec4(alpha * v_color.rgb + (1.0 - alpha) * u_stroke.rgb, 1.0 * v_color.a * alpha + (1.0 - alpha) * u_stroke.a);
}else{
alpha = 1.0;
diff --git a/src/geom/shader/text_vert.glsl b/src/geom/shader/text_vert.glsl
index c5c09f0a8e..c20c18f6a7 100644
--- a/src/geom/shader/text_vert.glsl
+++ b/src/geom/shader/text_vert.glsl
@@ -13,8 +13,14 @@ varying vec4 v_color;
void main() {
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
vec4 cur_position = matModelViewProjection * vec4(position.xy, 0, 1);
- gl_Position = cur_position / cur_position.w + vec4((a_txtOffsets + a_txtsize)/ u_glSize * 2.0,0.0, 0.0) +vec4(abs(a_txtsize.x)/u_glSize.x *2.0, -abs(a_txtsize.y)/u_glSize.y* 2.0, 0.0, 0.0);
+ gl_Position = cur_position / cur_position.w + vec4((a_txtOffsets + a_txtsize)/ u_glSize * 2.0,0.0, 0.0) +vec4(abs(a_txtsize.x)/u_glSize.x *2.0, -abs(a_txtsize.y)/u_glSize.y* 2.0, 0.0, 0.0);
+ highp float camera_to_anchor_distance = gl_Position.w;
+ // highp float perspective_ratio = clamp(
+ // 0.5 + 0.5 * distance_ratio,
+ // 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles
+ // 4.0);
v_color = a_color;
+ v_color.a = v_color.a * camera_to_anchor_distance;
v_texcoord = uv / u_textSize;
}
diff --git a/src/geom/shape/line.js b/src/geom/shape/line.js
index f9b7569b70..23145645ff 100644
--- a/src/geom/shape/line.js
+++ b/src/geom/shape/line.js
@@ -120,7 +120,7 @@ export function defaultLine(geo, index) {
return { positions, indexes: indexArray };
}
// mesh line
-export function Line(path, props, positionsIndex, dash = false) {
+export function Line(path, props, positionsIndex) {
if (path.length === 1) path = path[0];// 面坐标转线坐标
const positions = [];
const pickingIds = [];
@@ -129,7 +129,7 @@ export function Line(path, props, positionsIndex, dash = false) {
const colors = [];
const indexArray = [];
const normals = getNormal(path);
- const attrDistance = [];
+ let attrDistance = [];
const sizes = [];
let c = 0;
let index = positionsIndex;
@@ -153,10 +153,14 @@ export function Line(path, props, positionsIndex, dash = false) {
point[2] = size[1];
positions.push(...point);
positions.push(...point);
- if (dash) {
- const d = pointIndex / (list.length - 1);
- attrDistance.push(d, d);
+
+ if(pointIndex===0){
+ attrDistance.push(0, 0);
+ } else{
+ const d = attrDistance[pointIndex * 2-1] + lineSegmentDistance(path[pointIndex-1],path[pointIndex]);
+ attrDistance.push(d,d);
}
+
index += 2;
});
normals.forEach(n => {
@@ -167,6 +171,9 @@ export function Line(path, props, positionsIndex, dash = false) {
miter.push(-m);
miter.push(m);
});
+ attrDistance = attrDistance.map((d)=>{
+ return d / attrDistance[attrDistance.length-1];
+ })
return {
positions,
normal,
@@ -179,3 +186,9 @@ export function Line(path, props, positionsIndex, dash = false) {
};
}
+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);
+}
diff --git a/src/geom/shape/path.js b/src/geom/shape/path.js
new file mode 100644
index 0000000000..6f9c269388
--- /dev/null
+++ b/src/geom/shape/path.js
@@ -0,0 +1,45 @@
+/**
+ * @author lzxue
+ * @email lzx199065@gmail.com
+ * @create date 2018-11-28 11:01:33
+ * @modify date 2018-11-28 11:01:33
+ * @desc 点,线,面 coordinates
+*/
+
+function circle() {
+ return polygonPath(30);
+}
+function square() {
+ return polygonPath(4);
+}
+function triangle() {
+ return polygonPath(3);
+}
+function hexagon() {
+ return polygonPath(6);
+}
+export {
+ circle,
+ square,
+ triangle,
+ hexagon,
+ circle as cylinder,
+ triangle as triangleColumn,
+ hexagon as hexagonColumn,
+ square as squareColumn
+};
+
+export function polygonPath(pointCount) {
+ const step = Math.PI * 2 / pointCount;
+ const line = [];
+ for (let i = 0; i < pointCount; i++) {
+ line.push(step * i);
+ }
+ const path = line.map(t => {
+ const x = Math.sin(t + Math.PI / 4),
+ y = Math.cos(t + Math.PI / 4);
+ return [ x, y, 0 ];
+ });
+ path.push(path[0]);
+ return path;
+}
diff --git a/src/geom/shape/point.js b/src/geom/shape/point.js
index 2eda870006..7a5349d87b 100644
--- a/src/geom/shape/point.js
+++ b/src/geom/shape/point.js
@@ -1,12 +1,12 @@
-
import * as polygonShape from './polygon';
+import { polygonPath } from './path';
/**
* shape circle
* @param {enum} type 渲染类型
* @return {object} 顶点坐标和索引坐标
*/
export function circle(type) {
- const points = polygonPoint(30);
+ const points = polygonPath(30);
return polygonShape[type]([ points ]);
}
/**
@@ -15,7 +15,7 @@ export function circle(type) {
* @return {object} 顶点坐标和索引坐标
*/
export function triangle(type) {
- const points = polygonPoint(3);
+ const points = polygonPath(3);
return polygonShape[type]([ points ]);
}
@@ -25,7 +25,7 @@ export function triangle(type) {
* @return {object} 顶点坐标和索引坐标
*/
export function diamond(type) {
- const points = polygonPoint(4);
+ const points = polygonPath(4);
return polygonShape[type]([ points ]);
}
@@ -39,26 +39,6 @@ export function square(type) {
* @return {object} 顶点坐标和索引坐标
*/
export function hexagon(type) {
- const points = polygonPoint(6);
+ const points = polygonPath(6);
return polygonShape[type]([ points ]);
}
-/**
- * 规则多边形
- * @param {*} pointCount 顶点个数
- * @param {*} extrude 是否拔高
- * @return {Array} 顶点坐标
- */
-function polygonPoint(pointCount) {
- const step = Math.PI * 2 / pointCount;
- const line = [];
- for (let i = 0; i < pointCount; i++) {
- line.push(step * i);
- }
- // debugger
- const points = line.map(t => {
- const x = Math.sin(t + Math.PI / 4),
- y = Math.cos(t + Math.PI / 4);
- return [ x, y, 0 ];
- });
- return points;
-}
diff --git a/src/geom/shape/polygon.js b/src/geom/shape/polygon.js
index 12a87dd1f1..289f7a45c4 100644
--- a/src/geom/shape/polygon.js
+++ b/src/geom/shape/polygon.js
@@ -55,8 +55,9 @@ export function extrudeline(points) {
vertIndex.push(vertCount, 0);
vertIndex.push(vertCount, vertCount + pointCount);
vertIndex.push(vertCount + pointCount, pointCount);
- return {
- positions,
- positionsIndex: vertIndex
- };
+ const newPositions = [];
+ vertIndex.forEach(index => {
+ newPositions.push(positions[index]);
+ });
+ return newPositions;
}
diff --git a/src/global.js b/src/global.js
index b537d8db38..be038b3e66 100644
--- a/src/global.js
+++ b/src/global.js
@@ -4,7 +4,7 @@
*/
// const Global = {};
const Global = {
- version: '____L7_VERSION____',
+ version: '1.0.0',
scene: {
mapType: 'AMAP',
zoom: 5,
@@ -22,6 +22,11 @@ const Global = {
// 指定固定 tick 数的逼近值
snapCountArray: [ 0, 1, 1.2, 1.5, 1.6, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10 ],
size: 10000,
+ shape: 'circle',
+ pointShape: {
+ '2d': [ 'circle', 'square', 'hexagon', 'triangle' ],
+ '3d': [ 'cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn' ]
+ },
sdfHomeUrl: 'https://sdf.amap.com',
scales: {
}
diff --git a/src/index.js b/src/index.js
index c884916f78..3117424cd7 100755
--- a/src/index.js
+++ b/src/index.js
@@ -1,8 +1,17 @@
// import Util from './util';
import Scene from './core/scene';
-const version = '0.0.1';
+import Global from './global';
+
+const version = Global.version;
+const track = function(enable) {
+ Global.trackable = enable;
+};
+require('./track');
export {
version,
- Scene
+ Scene,
+ track
+
};
+
diff --git a/src/layer/lineLayer.js b/src/layer/lineLayer.js
index 49d2542cde..f201a69c9d 100644
--- a/src/layer/lineLayer.js
+++ b/src/layer/lineLayer.js
@@ -46,6 +46,7 @@ export default class LineLayer extends Layer {
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 lineType = style.lineType;
let material;
@@ -55,6 +56,20 @@ export default class LineLayer extends Layer {
u_opacity: opacity,
u_zoom: this.scene.getZoom()
});
+
+ if (animateOptions.enable) {
+
+ material.setDefinesvalue('ANIMATE', true);
+ const {duration,interval,trailLength,repeat = Infinity} = animateOptions;
+ this.animateDuration = this.scene._engine.clock.getElapsedTime() + duration * repeat;
+ material.upDateUninform({
+ u_duration: duration,
+ u_interval: interval,
+ u_trailLength:trailLength,
+ });
+
+
+ }
} else {
geometry.addAttribute('a_distance', new THREE.Float32BufferAttribute(attributes.attrDistance, 1));
material = new DashLineMaterial({
@@ -80,4 +95,11 @@ export default class LineLayer extends Layer {
}
return this;
}
+ _preRender(){
+ if(this.animateDuration>0 && this.animateDuration< this.scene._engine.clock.getElapsedTime()){
+ this.layerMesh.material.setDefinesvalue('ANIMATE', false);
+ this.emit('animateEnd');
+ this.animateDuration = Infinity;
+ }
+ }
}
diff --git a/src/layer/pointLayer.js b/src/layer/pointLayer.js
index f589eec221..56ff49bcf7 100644
--- a/src/layer/pointLayer.js
+++ b/src/layer/pointLayer.js
@@ -1,12 +1,11 @@
import Layer from '../core/layer';
import * as THREE from '../core/three';
-import PointBuffer from '../geom/buffer/point';
-import PointMaterial from '../geom/material/pointMaterial';
-import PolygonMaterial from '../geom/material/polygonMaterial';
+import * as drawPoint from '../layer/render/point';
+import { pointShape } from '../global';
+// import PointBuffer from '../geom/buffer/point';
import TextBuffer from '../geom/buffer/text';
import TextMaterial from '../geom/material/textMaterial';
-import radar from '../geom/shader/radar_frag.glsl';
-import warn from '../geom/shader/warn_frag.glsl';
+import * as PointBuffer from '../geom/buffer/point/index';
/**
@@ -33,83 +32,64 @@ export default class PointLayer extends Layer {
return this;
}
_prepareRender() {
+ const { opacity, strokeWidth, stroke, strokeOpacity, shape, fill } = this.get('styleOptions');
if (this.shapeType === 'text') { // 绘制文本图层
this._textPoint();
return;
}
const source = this.layerSource;
- const { opacity, strokeWidth, stroke, shape } = this.get('styleOptions');
- this._buffer = new PointBuffer({
- type: this.shapeType,
- imagePos: this.scene.image.imagePos,
- coordinates: source.geoData,
- properties: this.StyleData
- });
- const geometry = this.geometry = new THREE.BufferGeometry();
- let mtl;
- if (this.shapeType === '2d' || this.shapeType === '3d') {
- mtl = new PolygonMaterial({
- u_opacity: opacity,
- u_zoom: this.scene.getZoom()
- });
- // mtl= new pickingMaterial({
- // u_opacity: opacity,
- // u_zoom: this.scene.getZoom()
- // })
- // mtl.setDefinesvalue('point', true);
- mtl.setDefinesvalue('SHAPE', true);
- if (shape === 'radar') {
- mtl.fragmentShader = radar;
+ const style = this.get('styleOptions');
+ const pointShapeType = this._getShape();
- }
- if (shape === 'warn') {
- mtl.fragmentShader = warn;
- }
-
-
- } else { // sdf 绘制点
- mtl = new PointMaterial({
- u_opacity: opacity,
- u_strokeWidth: strokeWidth,
- u_stroke: stroke,
- shape: this.shapeType || false,
- u_texture: this.scene.image.texture
- }, {
- SHAPE: (this.shapeType !== 'image'),
- TEXCOORD_0: (this.shapeType === 'image')
- });
+ switch (pointShapeType) {
+ case 'fill' :// 填充图形
+ {
+ if (fill !== 'none') { // 是否填充
+ const attributes = PointBuffer.FillBuffer(source.geoData, this.StyleData, style);
+ const meshfill = drawPoint.DrawFill(attributes, this.get('styleOptions'));
+ this.add(meshfill);
+ }
+ if (stroke !== 'none') { // 是否绘制边界
+ const lineAttribute = PointBuffer.StrokeBuffer(source.geoData, this.StyleData, style);
+ const meshStroke = drawPoint.DrawStroke(lineAttribute, this.get('styleOptions'));
+ this.add(meshStroke, 'line');
+ }
+ }
+ break;
+ case 'image':// 绘制图片标注
+ const imageAttribute = PointBuffer.ImageBuffer(source.geoData, this.StyleData, { imagePos: this.scene.image.imagePos });
+ const imageMesh = drawPoint.DrawImage(imageAttribute, { ...style, texture: this.scene.image.texture });
+ this.add(imageMesh);
+ break;
+ case 'normal' : // 原生点
+ const normalAttribute = PointBuffer.NormalBuffer(source.geoData, this.StyleData, style);
+ const normalPointMesh = drawPoint.DrawNormal(normalAttribute, style);
+ this.add(normalPointMesh);
}
-
- const { attributes } = this._buffer;
- 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));
- if (this.shapeType === 'image') {
- geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.uvs, 2));
- geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
- } else if (this.shapeType === undefined) {
- geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
- } else { // 多边形面
- geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
- geometry.addAttribute('a_shape', new THREE.Float32BufferAttribute(attributes.shapePositions, 3));
- geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.a_size, 3));
- if (shape) {
- geometry.addAttribute('faceUv', new THREE.Float32BufferAttribute(attributes.faceUv, 2));
+ }
+ _getShape() {
+ let shape = null;
+ if (!this.StyleData[0].hasOwnProperty('shape')) {
+ return 'normal';
+ }
+ for (let i = 0; i < this.StyleData.length; i++) {
+ shape = this.StyleData[i].shape;
+ if (shape !== undefined) {
+ break;
}
}
- let mesh;
- if (this.shapeType === 'image') {
- mesh = new THREE.Points(geometry, mtl);
- } else if (this.shapeType === undefined) { // 散点图
- mesh = new THREE.Points(geometry, mtl);
-
- } else {
- mesh = new THREE.Mesh(geometry, mtl);
+ if (pointShape['2d'].indexOf(shape) !== -1 || pointShape['3d'].indexOf(shape) !== -1) {
+ return 'fill';
+ } else if (shape == 'text') {
+ return 'text';
+ } else if (this.scene.image.imagesIds.indexOf(shape) !== -1) {
+ return 'image';
}
+ return 'normal';
+
- this.add(mesh);
}
_textPoint() {
const source = this.layerSource;
@@ -133,11 +113,11 @@ export default class PointLayer extends Layer {
const material = new TextMaterial({
name: this.layerId,
u_texture: buffer.bufferStruct.textTexture,
- u_strokeWidth: 1,
+ u_strokeWidth: styleOptions.strokeWidth,
u_stroke: stroke,
u_textSize: buffer.bufferStruct.textSize,
- u_gamma: 0.11,
- u_buffer: 0.8,
+ u_gamma: 2 * 1.4142 / 64,
+ u_buffer: 0.65,
u_color: color,
u_glSize: [ width, height ]
});
diff --git a/src/layer/render/point/drawFill.js b/src/layer/render/point/drawFill.js
new file mode 100644
index 0000000000..5389855d35
--- /dev/null
+++ b/src/layer/render/point/drawFill.js
@@ -0,0 +1,28 @@
+/**
+ * @author lzxue
+ * @email lzx199065@gmail.com
+ * @create date 2018-11-29 16:07:24
+ * @modify date 2018-11-29 16:07:24
+ * @desc [description] 绘制点图层的面状填充,圆,三角形,六边形
+*/
+import * as THREE from '../../../core/three';
+import PolygonMaterial from '../../../geom/material/polygonMaterial';
+export default function DrawFill(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));
+ geometry.addAttribute('a_shape', new THREE.Float32BufferAttribute(attributes.shapePositions, 3));
+ geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.a_size, 3));
+ const material = new PolygonMaterial({
+ u_opacity: opacity
+ }, {
+ SHAPE: true
+ });
+ material.setDefinesvalue('SHAPE', true);
+ 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
new file mode 100644
index 0000000000..99fc430a09
--- /dev/null
+++ b/src/layer/render/point/drawImage.js
@@ -0,0 +1,23 @@
+
+import * as THREE from '../../../core/three';
+import PointMaterial from '../../../geom/material/pointMaterial';
+export default function DrawImage(attributes, style) {
+ const geometry = new THREE.BufferGeometry();
+ const { strokeWidth, stroke, opacity, texture } = style;
+ 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('uv', new THREE.Float32BufferAttribute(attributes.uv, 2));
+ geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
+ const material = new PointMaterial({
+ u_opacity: opacity,
+ u_strokeWidth: strokeWidth,
+ u_stroke: stroke,
+ u_texture: texture
+ }, {
+ SHAPE: false,
+ TEXCOORD_0: true
+ });
+ 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
new file mode 100644
index 0000000000..c0c86e231b
--- /dev/null
+++ b/src/layer/render/point/drawNormal.js
@@ -0,0 +1,19 @@
+
+import * as THREE from '../../../core/three';
+import PointMaterial from '../../../geom/material/pointMaterial';
+export default function DrawNormal(attributes, style) {
+ const geometry = new THREE.BufferGeometry();
+ const { opacity } = style;
+ 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('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
+ const material = new PointMaterial({
+ u_opacity: opacity
+ }, {
+ SHAPE: false,
+ TEXCOORD_0: false
+ });
+ const strokeMesh = new THREE.Points(geometry, material);
+ return strokeMesh;
+}
diff --git a/src/layer/render/point/drawStroke.js b/src/layer/render/point/drawStroke.js
new file mode 100644
index 0000000000..8b5c780e48
--- /dev/null
+++ b/src/layer/render/point/drawStroke.js
@@ -0,0 +1,29 @@
+/**
+ * @author lzxue
+ * @email lzx199065@gmail.com
+ * @create date 2018-11-29 16:35:34
+ * @modify date 2018-11-29 16:35:34
+ * @desc [description] 绘制图形的边框
+*/
+
+import PointLineMaterial from '../../../geom/material/pointLineMaterial';
+import * as THREE from '../../../core/three';
+export default function DrawStroke(attributes, style) {
+ const { strokeWidth, stroke, strokeOpacity } = style;
+ const geometry = new THREE.BufferGeometry();
+ geometry.setIndex(attributes.indexArray);
+ geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.positions, 3));
+ geometry.addAttribute('a_shape', new THREE.Float32BufferAttribute(attributes.shapes, 3));
+ geometry.addAttribute('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 3));
+ geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normal, 3));
+ geometry.addAttribute('a_miter', new THREE.Float32BufferAttribute(attributes.miter, 1));
+ geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
+ geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4));
+ const material = new PointLineMaterial({
+ u_strokeOpacity: strokeOpacity,
+ u_stroke: stroke,
+ u_strokeWidth: strokeWidth
+ });
+ const strokeMesh = new THREE.Mesh(geometry, material);
+ return strokeMesh;
+}
diff --git a/src/layer/render/point/drawText.js b/src/layer/render/point/drawText.js
new file mode 100644
index 0000000000..178f7c0960
--- /dev/null
+++ b/src/layer/render/point/drawText.js
@@ -0,0 +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);
+}
diff --git a/src/layer/render/point/index.js b/src/layer/render/point/index.js
new file mode 100644
index 0000000000..ba399312ab
--- /dev/null
+++ b/src/layer/render/point/index.js
@@ -0,0 +1,4 @@
+export { default as DrawFill } from './drawFill';
+export { default as DrawImage } from './drawImage';
+export { default as DrawStroke } from './drawStroke';
+export { default as DrawNormal } from './drawNormal';
diff --git a/src/map/provider.js b/src/map/provider.js
index d341130ffe..19763e8f45 100644
--- a/src/map/provider.js
+++ b/src/map/provider.js
@@ -23,6 +23,7 @@ export class MapProvider extends Base {
initMap() {
const mapStyle = this.get('mapStyle');
+
switch (mapStyle) {
case 'dark' :
this.set('mapStyle', Theme.DarkTheme.mapStyle);
@@ -31,7 +32,7 @@ export class MapProvider extends Base {
this.set('mapStyle', Theme.LightTheme.mapStyle);
break;
default:
- this.set('mapStyle', Theme.LightTheme.mapStyle);
+ this.set('mapStyle', mapStyle);
}
this.set('zooms', [ this.get('minZoom'), this.get('maxZoom') ]);
this.map = new AMap.Map(this.container, this._attrs);
diff --git a/src/source/csvSource.js b/src/source/csvSource.js
index 89dc55b1cc..8266d1604b 100644
--- a/src/source/csvSource.js
+++ b/src/source/csvSource.js
@@ -39,6 +39,10 @@ export default class CSVSource extends Source {
getSelectFeatureId(featureId) {
return [ featureId ];
}
+ getSelectFeature(featureId) {
+ return this.propertiesData[featureId];
+
+ }
_getCoord(geo) {
if (geo.geometry) {
// GeoJSON feature
diff --git a/src/source/geojsonSource.js b/src/source/geojsonSource.js
index 0a611e8da9..df38e3fd13 100644
--- a/src/source/geojsonSource.js
+++ b/src/source/geojsonSource.js
@@ -39,5 +39,9 @@ export default class GeojsonSource extends Source {
return selectFeatureIds;
}
+ getSelectFeature(featureId){
+ const data = this.get('data');
+ return data.features[featureId];
+ }
}
diff --git a/src/track.js b/src/track.js
new file mode 100644
index 0000000000..8b75ab2c5a
--- /dev/null
+++ b/src/track.js
@@ -0,0 +1,22 @@
+/**
+ * @fileOverview track g2
+ * @author dxq613@gmail.com
+ */
+const Global = require('./global');
+const SERVER_URL = 'https://kcart.alipay.com/web/bi.do';
+
+// 延迟发送请求
+setTimeout(function() {
+ if (Global.trackable) {
+ const image = new Image();
+ const newObj = {
+ pg: document.URL,
+ r: new Date().getTime(),
+ l7: true,
+ version: Global.version,
+ page_type: 'syslog'
+ };
+ const d = encodeURIComponent(JSON.stringify([ newObj ]));
+ image.src = `${SERVER_URL}?BIProfile=merge&d=${d}`;
+ }
+}, 3000);
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index f5d9835416..abb0056d8d 100755
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -4,7 +4,7 @@ const pkg = require('./package.json');
module.exports = {
devtool: 'cheap-source-map',
entry: {
- L7: './src/index.js'
+ l7: './src/index.js'
},
output: {
filename: '[name].js',