fix(filter):data filter

This commit is contained in:
李正学 2018-11-03 16:39:22 +08:00
parent 216d6253a7
commit 68394f3191
25 changed files with 400 additions and 220 deletions

View File

@ -28,9 +28,9 @@ const scene = new L7.Scene({
zoom: 14.6
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/rmsportal/epnZEheZeDgsiSjSPcCv.json', data => {
scene.PointLayer({
const circleLayer = scene.PointLayer({
zIndex: 2
})
.source(data)
@ -47,6 +47,9 @@ scene.on('load', () => {
opacity: 0.9
})
.render();
//circleLayer.size('value', [ 8, 1000 ]).render();
});
});

View File

@ -28,7 +28,7 @@ const scene = new L7.Scene({
zoom: 9.6
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.get('./data/spot.geojson', data => {
scene.PointLayer({
zIndex: 2

View File

@ -29,7 +29,7 @@ const scene = new L7.Scene({
zoom: 11
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/rmsportal/mUQPWCYaxOfiSznuANvG.txt', data => {
scene.PointLayer({
zIndex: 2

View File

@ -26,35 +26,43 @@ const scene = new L7.Scene({
mapStyle: 'light', // 样式URL
center: [ 120.1243238, 30.27331571 ],
pitch: 0,
zoom: 10,
zoom: 14,
minZoom: 9
});
window.scene = scene;
scene.image.addImage('bike', './image/Bike.png');
scene.on('load', () => {
$.get('./data/bike.json', data => {
scene.on('loaded', () => {
$.get('./data/pointbike.json', data => {
scene.PointLayer({
zIndex: 2
})
.source(data.object, {
type: 'array',
y: 'distY',
x: 'distX'
})
.size(128.0)
.source(data)
.color('#0198BD')
.size(40.0)
.shape('image:bike')
.color('#0198BD')
.render();
.render();
});
$.get('./data/fence.json', data => {
scene.PolygonLayer({
zIndex: 3
zIndex: 0
})
.source(data)
.shape('fill')
.color('#0198BD')
.style({
opacity:0.8
opacity:0.6
})
.render();
});
$.getJSON('./data/pointZone.json', data => {
scene.PolygonLayer({
zIndex: 1
})
.source(data)
.shape('fill')
.color("#F04850")
.style({
opacity:1.0
})
.render();
});

View File

@ -28,7 +28,7 @@ const scene = new L7.Scene({
pitch: 0,
zoom: 3
});
scene.on('load', () => {
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', data => {
scene.LineLayer({
zIndex: 2

View File

@ -30,7 +30,7 @@ const scene = new L7.Scene({
minZoom: 5,
maxZoom: 10
});
scene.on('load', () => {
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/rmsportal/lZGtNaYGNHtAIkcjVvfp.json', data => {
scene.LineLayer({
zIndex: 2

View File

@ -34,7 +34,7 @@ const scene = new L7.Scene({
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/oOzMjBOaxFROWLBYeqTB.json', city => {
citylayer = scene.PolygonLayer()
.source(city)

View File

@ -10,18 +10,31 @@
<title>hexagon demo</title>
<style>
body {margin: 0;}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<div id ="info" class ="tooltip">
<div id ="info" class ="tooltip" style="display:none">
</div>
<div class='info-panel top-right'>
<h4>全国各地市空气质量指数</h4>
<p>城市:<span id="city" class="lnglat"></span></p>
<p>AQI<span id="aqi" class="lnglat"></span></p>
<p>
<label>min</label><input name="minaqi" type="range" step="1" min="0" max="120" value=0> <label></label>
</p>
<p>
<label>max</label><input name="maxaqi" type="range" step="1" min="0" max="120" value="120"><label></label>
</p>
<p><label>color</label><select>
<option value ="blue">blue</option>
<option value ="red">red</option>
<option value="orange">orange</option>
<option value="green">green</option>
<option value="yellow">yellow</option>
<option value="purple">purple</option>
</select> </p>
<div>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
@ -29,6 +42,15 @@
<script src="./assets/dat.gui.min.js"></script>
<script src="../build/L7.js"></script>
<script>
const colorObj ={
blue: ["#E8FCFF", "#CFF6FF", "#98E3FA", "#65CEF7", "#3CB4F0", "#2894E0", "#1A76C7", "#105CB3", "#0D408C", "#002466"],
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"],
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"],
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"],
yellow:["#FFFFE8", "#FFFECC", "#FAF896", "#F7E463", "#F0CE3A", "#DBB125", "#C29117", "#AD7410", "#87500C", "#613000"],
purple:["#FCF2FF", "#F5DEFF", "#DDB3F2", "#BE7BE3", "#9B4ECF", "#7737B3", "#5B2899", "#411C85", "#270F5E", "#100338"]
}
const scene = new L7.Scene({
id: 'map',
mapStyle: 'light', // 样式URL
@ -38,22 +60,37 @@ const scene = new L7.Scene({
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json', city => {
const citylayer = scene.PolygonLayer()
.source(city)
.color('pm2_5_24h', [ '#002466', '#0D408C', '#105CB3', '#1A76C7', '#2894E0', '#3CB4F0', '#65CEF7', '#98E3FA', '#CFF6FF', '#E8FCFF' ])
.color('pm2_5_24h',colorObj.blue)
.shape('fill')
.active({ fill: '#fff' })
.active({ fill: "#5B2899" })
.style({
opacity: 1
})
.render();
citylayer.on('move',(e)=>{
$("#info").css({'left': e.pixel.x,'top':e.pixel.y});
$("#info").html(`<p>${e.feature.properties.area || e.feature.properties.name }<span">${e.feature.properties.aqi || 0}</span></p>`);
citylayer.on('click',(e)=>{
$("#info").css({'left': e.pixel.x,'top':e.pixel.y, display:'block'});
$("#info").html(`<p>${e.feature.properties.area || e.feature.properties.name }<span">${e.feature.properties.aqi || 0}</span></p>`);
})
$('.info-panel input').change(function(){
$(this).next().text($(this).val());
const min = $('.info-panel input').val();
const max = $($('.info-panel input')[1]).val();
citylayer.filter('pm2_5_24h',(value)=>{
return (value>=min && value<=max)
}).render();
})
$('.info-panel select').change(function(){
const color = $(this).val();
citylayer.color('pm2_5_24h',colorObj[color]).render();
citylayer.active({ fill: "red" }).render();
})
});
});

View File

@ -30,7 +30,7 @@ const scene = new L7.Scene({
maxZoom: 10
});
scene.on('load', () => {
scene.on('loaded', () => {
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json', city => {
citylayer = scene.PolygonLayer({
zIndex: 10

View File

@ -28,7 +28,7 @@ const scene = new L7.Scene({
zoom: 3
});
window.scene = scene;
scene.on('load', () => {
scene.on('loaded', () => {
$.get('./data/provincePoint.geojson', data => {
scene.PointLayer({
zIndex: 2

View File

@ -17,11 +17,22 @@
outline: none;
z-index: 10;
}
.info-panel p {
margin: 0px;
}
.info-panel h4 {
font-size: 1em;
font-weight: 500;
margin: 8px 0;
}
.info-panel label {
display: inline-block;
width: 30px;
margin-right: 10%;
color: #5a666d;
margin-bottom: 4px;
}
.tooltip {
position:absolute;
pointer-events: none;
@ -37,4 +48,4 @@
padding: 0;
margin: 0;
}
}

View File

@ -1,4 +1,5 @@
import EventEmitter from 'wolfy87-eventemitter';
import * as THREE from '../three';
import Scene from './scene';
import Camera from './camera';
import Renderer from './renderer';
@ -13,8 +14,9 @@ export default class Engine extends EventEmitter {
this._picking = Picking(this._world, this._renderer, this._camera, this._scene);
// this._renderer.context.getExtension('OES_texture_float');
// this._renderer.context.getExtension('OES_texture_float_linear');
this._renderer.context.getExtension('OES_texture_half_float');
this._renderer.context.getExtension('OES_texture_half_float_linear');
// this._renderer.context.getExtension('OES_texture_half_float');
// this._renderer.context.getExtension('OES_texture_half_float_linear');
this.clock = new THREE.Clock();
}
_initPostProcessing() {

View File

@ -1,20 +1,5 @@
import PickingScene from './pickingScene';
import * as THREE from '../../three';
// TODO: Look into a way of setting this up without passing in a renderer and
// camera from the engine
// TODO: Add a basic indicator on or around the mouse pointer when it is over
// something pickable / clickable
//
// A simple transparent disc or ring at the mouse point should work to start, or
// even just changing the cursor to the CSS 'pointer' style
//
// Probably want this on mousemove with a throttled update as not to spam the
// picking method
//
// Relies upon the picking method not redrawing the scene every call due to
// the way TileLayer invalidates the picking scene
let nextId = 1;
class Picking {
@ -52,7 +37,7 @@ class Picking {
this._mouseUpHandler = this._onMouseUp.bind(this);
this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);
this._world._container.addEventListener('mousemove', this._mouseUpHandler, false);
this._world._container.addEventListener('mousemove', this._onWorldMove.bind(this), false);
}
_onMouseUp(event) {
@ -70,6 +55,7 @@ class Picking {
}
_onWorldMove() {
this._needUpdate = true;
}
@ -85,26 +71,17 @@ class Picking {
this._needUpdate = true;
}
// TODO: Make this only re-draw the scene if both an update is needed and the
// camera has moved since the last update
//
// Otherwise it re-draws the scene on every click due to the way LOD updates
// work in TileLayer spamming this.add() and this.remove()
//
// TODO: Pause updates during map move / orbit / zoom as this is unlikely to
// be a point in time where the user cares for picking functionality
_update(point) {
// if (this._needUpdate) {
const texture = this._pickingTexture;
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);// this._pickingTexture this._pickingScene
// Read the rendering texture
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);
// this._needUpdate = false;
// }
}
_updateRender() {
this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);
@ -115,7 +92,7 @@ class Picking {
// Interpret the pixel as an ID
const 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) {
if (id === 16646655 || this.pixelBuffer[3]===0 ) {
return;
}

View File

@ -1,11 +1,14 @@
import * as THREE from './three';
import EventEmitter from 'wolfy87-eventemitter';
import { getImage } from '../util/ajax';
// 将图片标注绘制在512*512的画布上每个大小 64*64 支持 64种图片
export default class LoadImage extends EventEmitter {
constructor() {
super();
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.ctx.fillStyle="#FF0000";
this.ctx.fillRect(0,0,512,512);
this.imageWidth = 64;
this.canvas.width = this.imageWidth * 8;
this.canvas.height = this.imageWidth * 8;
@ -18,7 +21,7 @@ export default class LoadImage extends EventEmitter {
const imageCount = this.imagesCount;
const x = imageCount % 8 * 64;
const y = parseInt(imageCount / 8) * 64;
this.imagePos[id] = { x: x / 512, y: y / 512 };
if (typeof opt === 'string') {
getImage({ url: opt }, (err, img) => {
img.id = id;
@ -29,7 +32,6 @@ export default class LoadImage extends EventEmitter {
texture.minFilter = THREE.LinearFilter;
texture.needsUpdate = true;
this.texture = texture;
this.imagePos[id] = { x: x / 512, y: y / 512 };
if (this.images.length === this.imagesCount) {
this.emit('imageLoaded');
}

View File

@ -37,7 +37,7 @@ export default class Layer extends Base {
attrs: {},
// 样式配置项
styleOptions: {
stroke: 'rgb(255,255,255)',
stroke: [1.0,1.0,1.0,1.0],
strokeWidth: 1.0,
opacity: 1.0
},
@ -60,7 +60,7 @@ export default class Layer extends Base {
this.layerId = layerId;
this._activeIds = null;
// todo 用户参数
this._object3D.position.z = layerId;
this._object3D.position.z = this.get('zIndex')*100;
scene._engine._scene.add(this._object3D);
this.layerMesh = null;
@ -71,6 +71,10 @@ export default class Layer extends Base {
*/
add(object) {
this.layerMesh = object;
// 更新
if(this._needUpdateFilter) {
this._updateFilter();
}
this._object3D.add(object);
this._addPickMesh(object);
}
@ -94,6 +98,7 @@ export default class Layer extends Base {
return this;
}
color(field, values) {
this._needUpdateColor = true;//标识颜色是否需要更新
this._createAttrOption('color', field, values, Global.colors);
return this;
}
@ -162,6 +167,7 @@ export default class Layer extends Base {
return this;
}
filter(field, values) {
this._needUpdateFilter = true;
this._createAttrOption('filter', field, values, true);
return this;
}
@ -211,10 +217,12 @@ export default class Layer extends Base {
}
this._setAttrOptions(attrName, attrCfg);
}
// 初始化图层
init() {
this._initAttrs();
this._scaleByZoom();
this._mapping();
const activeHander = this._addActiveFeature.bind(this);
if (this.get('allowActive')) {
@ -250,30 +258,35 @@ export default class Layer extends Base {
_initAttrs() {
const self = this;
const attrs = this.get('attrs');
const attrOptions = this.get('attrOptions');
for (const type in attrOptions) {
if (attrOptions.hasOwnProperty(type)) {
const option = attrOptions[type];
const className = Util.upperFirst(type);
const fields = parseFields(option.field);
const scales = [];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const scale = self._createScale(field);
if (type === 'color' && Util.isNil(option.values)) { // 设置 color 的默认色值
option.values = Global.colors;
}
scales.push(scale);
}
option.scales = scales;
const attr = new Attr[className](option);
attrs[type] = attr;
this._updateAttr(type)
}
}
}
_updateAttr(type){
const self = this;
const attrs = this.get('attrs');
const attrOptions = this.get('attrOptions');
const option = attrOptions[type];
option.neadUpdate = true;
const className = Util.upperFirst(type);
const fields = parseFields(option.field);
const scales = [];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const scale = self._createScale(field);
if (type === 'color' && Util.isNil(option.values)) { // 设置 color 的默认色值
option.values = Global.colors;
}
scales.push(scale);
}
option.scales = scales;
const attr = new Attr[className](option);
attrs[type] = attr;
}
_updateSize(zoom) {
const sizeOption = this.get('attrOptions').size;
const fields = parseFields(sizeOption.field);
@ -303,6 +316,7 @@ export default class Layer extends Base {
for (const k in attrs) {
if (attrs.hasOwnProperty(k)) {
const attr = attrs[k];
attr.needUpdate = false;
const names = attr.names;
const values = self._getAttrValues(attr, record);
if (names.length > 1) { // position 之类的生成多个字段的属性
@ -323,26 +337,29 @@ export default class Layer extends Base {
this.StyleData = mappedData;
return mappedData;
}
_updateMap(attrName) {
_updateMaping() {
const self = this;
const attrs = self.get('attrs');
const data = this.layerSource.propertiesData;
for (let i = 0; i < data.length; i++) {
const record = data[i];
if (attrs.hasOwnProperty(attrName)) {
const attr = attrs[attrName];
const names = attr.names;
const values = self._getAttrValues(attr, record);
if (names.length > 1) { // position 之类的生成多个字段的属性
for (let j = 0; j < values.length; j++) {
const val = values[j];
const name = names[j];
this.StyleData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
this.StyleData[i][names[0]] = values.length === 1 ? values[0] : values;
for (const attrName in attrs) {
if (attrs.hasOwnProperty(attrName) && attrs[attrName].neadUpdate) {
const attr = attrs[attrName];
const names = attr.names;
const values = self._getAttrValues(attr, record);
if (names.length > 1) { // position 之类的生成多个字段的属性
for (let j = 0; j < values.length; j++) {
const val = values[j];
const name = names[j];
this.StyleData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
this.StyleData[i][names[0]] = values.length === 1 ? values[0] : values;
}
attr.neadUpdate = true;
}
}
}
@ -429,7 +446,7 @@ export default class Layer extends Base {
lnglat:{lng:lnglat.lng,lat:lnglat.lat}
}
this.emit('click', target);
this.emit('move', target);
// this.emit('move', target);
});
}
/**
@ -438,7 +455,7 @@ export default class Layer extends Base {
* @param {*} style 更新的要素样式
*/
updateStyle(featureStyleId, style) {
const {indices} = this.buffer.bufferStruct;
const {indices} = this._buffer.bufferStruct;
if (this._activeIds) {
this.resetStyle();
@ -473,12 +490,19 @@ export default class Layer extends Base {
colorAttr.needsUpdate =true
});
}
_updateColor(){
this._updateMaping();
}
/**
* 用于过滤数据
* @param {*} filterData 数据过滤标识符
*/
updateFilter(filterData) {
_updateFilter() {
this._updateMaping();
const filterData = this.StyleData;
this._activeIds = null; // 清空选中元素
let dataIndex = 0;
const colorAttr = this.layerMesh.geometry.attributes.a_color;
@ -499,13 +523,12 @@ export default class Layer extends Base {
colorAttr.needsUpdate =true;
return;
}
const {indices} = this.buffer.bufferStruct;
const {indices} = this._buffer.bufferStruct;
indices.forEach((vertIndexs, i) => {
const color = [ ...this.StyleData[i].color ];
if (filterData[i].hasOwnProperty('filter') && filterData[i].filter === false) {
color[3] = 0;
}
vertIndexs.forEach(() => {
colorAttr.array[dataIndex*4+0]=color[0];
colorAttr.array[dataIndex*4+1]=color[1];
@ -515,12 +538,14 @@ export default class Layer extends Base {
});
colorAttr.needsUpdate =true;
});
this._needUpdateFilter = false;
this._needUpdateColor = false;
}
/**
* 重置高亮要素
*/
resetStyle() {
const {indices} = this.buffer.bufferStruct;
const {indices} = this._buffer.bufferStruct;
const colorAttr = this.layerMesh.geometry.attributes.a_color;
let dataIndex = 0;
const id = this._activeIds[0];
@ -547,6 +572,9 @@ export default class Layer extends Base {
colorAttr.needsUpdate =true
});
}
/**
* 销毁Layer对象
*/
despose() {
this.destroy();
if(this._object3D && this._object3D.children){

View File

@ -5,7 +5,7 @@ import Base from './base';
import LoadImage from './image';
import Utils from '../util';
import { MapProvider } from '../map/provider';
import GaodeMap from '../map/gaodeMap';
import GaodeMap from '../map/gaodeMap';
import Global from '../global';
export default class Scene extends Base {
getDefaultCfg() {
@ -14,6 +14,7 @@ export default class Scene extends Base {
constructor(cfg) {
super(cfg);
this._initMap();
this._initAttribution();
this.addImage();
this._layers = [];
}
@ -34,11 +35,13 @@ export default class Scene extends Base {
this._initEngine(Map.renderDom);
const sceneMap = new GaodeMap(Map.map);
// eslint-disable-next-line
Utils.assign(this.__proto__, sceneMap.__proto__);
Object.getOwnPropertyNames(sceneMap.__proto__).forEach((key)=>{
if('key' !== 'constructor')
this.__proto__[key]=sceneMap.__proto__[key];
})
this.map = Map.map;
Map.asyncCamera(this._engine);
this.initLayer();
this.emit('load');
this.emit('loaded');
});
@ -53,11 +56,22 @@ export default class Scene extends Base {
};
}
}
_initAttribution() {
var message ='<a href="http://antv.alipay.com/zh-cn/index.html title="Large-scale WebGL-powered Geospatial Data Visualization">AntV | L7 </a>'
var element = document.createElement('div');
element.innerHTML = message;
element.style.cssText += 'position: absolute; pointer-events:none;background: rgba(255, 255, 255, 0.7);font-size: 11px;z-index:100; padding:4px;bottom: 0;right:0;';
this._container.appendChild(element);
}
addImage() {
this.image = new LoadImage();
}
_initEvent() {
}
getLayers(){
return this._layers;
}
_addLight() {
const scene = this._engine._scene;

View File

@ -1,43 +1,44 @@
// import 'three/src/polyfills.js';
// export * from 'three/src/constants.js';
// export { Scene } from 'three/src/scenes/Scene.js';
// export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
// export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
// export { Object3D } from 'three/src/core/Object3D.js';
// 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 { WebGLRenderTarget } from 'three/src/renderers/WebGLRenderTarget.js';
// export { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera.js';
// export { BufferGeometry } from 'three/src/core/BufferGeometry.js';
// 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 { 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 { ShaderMaterial } from 'three/src/materials/ShaderMaterial.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,
// Float32BufferAttribute,
// Uint32BufferAttribute,
// Int32BufferAttribute,
// Uint16BufferAttribute,
// Int16BufferAttribute,
// Uint8ClampedBufferAttribute,
// Uint8BufferAttribute,
// Int8BufferAttribute,
// BufferAttribute
// } from 'three/src/core/BufferAttribute.js';
import 'three/src/polyfills.js';
export * from 'three/src/constants.js';
export { Scene } from 'three/src/scenes/Scene.js';
export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js';
export { CanvasTexture } from 'three/src/textures/CanvasTexture.js';
export { Object3D } from 'three/src/core/Object3D.js';
export {Clock } from 'three/src/core/Clock';
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 { WebGLRenderTarget } from 'three/src/renderers/WebGLRenderTarget.js';
export { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera.js';
export { BufferGeometry } from 'three/src/core/BufferGeometry.js';
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 { 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 { ShaderMaterial } from 'three/src/materials/ShaderMaterial.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,
Float32BufferAttribute,
Uint32BufferAttribute,
Int32BufferAttribute,
Uint16BufferAttribute,
Int16BufferAttribute,
Uint8ClampedBufferAttribute,
Uint8BufferAttribute,
Int8BufferAttribute,
BufferAttribute
} from 'three/src/core/BufferAttribute.js';
export * from '../../build/Three.js';
// export * from '../../build/Three.js';

View File

@ -1,8 +1,21 @@
import * as THREE from '../../core/three';
export default class Material extends THREE.ShaderMaterial {
setValue(name, value) {
setUniformsValue(name, value) {
this.uniforms[name].value = value;
this.uniforms.needsUpdate = true;
}
setDefinesvalue(name, value){
this.defines.name = value;
this.needsUpdate =true;
}
setUniform(option){
const uniforms ={};
for(let key in option){
if(key.substr(0,2)==='u_'){
uniforms[key]= {value:option[key]};
}
}
return uniforms;
}
}

View File

@ -1,25 +1,36 @@
import * as THREE from '../../core/three';
import Material from './material';
import point_frag from '../shader/point_frag.glsl';
import point_vert from '../shader/point_vert.glsl';
export default function PointMaterial(options) {
const material = new THREE.ShaderMaterial({
uniforms: {
u_opacity: { value: options.u_opacity },
u_stroke: { value: options.u_stroke },
u_strokeWidth: { value: options.u_strokeWidth },
u_texture: { value: options.u_texture }
},
vertexShader: point_vert,
fragmentShader: point_frag,
blending: THREE.NormalBlending,
transparent: true,
defines: {
SHAPE: true,
TEXCOORD_0: !!options.u_texture
}
});
if (options.shape === false) {
material.blending = THREE.AdditiveBlending;
export default class PointMaterial extends Material {
getDefaultParameters() {
return {
uniforms:{
u_opacity: {value:1},
u_stroke: {value:[1.0,1.0,1.0,1.0]},
u_strokeWidth:{value:1}
},
defines: {
SHAPE: true,
TEXCOORD_0: false
}
};
}
return material;
}
constructor(_uniforms,_defines,parameters){
super(parameters);
const {uniforms,defines} = this.getDefaultParameters();
this.uniforms = Object.assign(uniforms,this.setUniform(_uniforms));
this.defines = Object.assign(defines,_defines)
this.type = 'PointMaterial'
this.vertexShader = point_vert;
this.fragmentShader =point_frag;
this.transparent = true;
if(_uniforms.u_texture){
this.defines.TEXCOORD_0 = true;
}
}
}

View File

@ -26,9 +26,7 @@ void main() {
// vec3 targetColor = mix( v_color.rgb, halo, haloWeight );
// gl_FragColor= vec4(v_color.rgb, alpha * v_color.a);;
// gl_FragColor = vec4( targetColor, alpha );
if(v_color.a == 0.)
discard;
vec4 pcolor = v_color * u_opacity;
#ifdef TEXCOORD_0
vec2 pos = v_uv + gl_PointCoord / 512.0 * 64.0;
pos.y = 1.0 - pos.y;
@ -36,6 +34,9 @@ void main() {
gl_FragColor =textureColor;
return;
#endif
if(v_color.a == 0.)
discard;
vec4 pcolor = v_color * u_opacity;
float ro = v_rs.x;
float ri = v_rs.y;
float d = 0.0;

View File

@ -1,7 +1,7 @@
precision highp float;
#define ambientRatio 0.65
#define diffuseRatio 0.6
#define specularRatio 0.4
#define ambientRatio 0.2
#define diffuseRatio 0.5
#define specularRatio 0.3
attribute vec4 a_color;
attribute vec4 a_idColor;
attribute vec2 faceUv;
@ -17,13 +17,12 @@ void main() {
// vec3 lightDir = normalize(vec3(0.05,-0.001,-1));
vec3 halfDir = normalize(viewDir+lightDir);
// //lambert
float lambert = 0.5 * dot(worldNormal, lightDir);
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_color =vec4(a_color.rgb * lightWeight, a_color.w);
v_color =vec4(a_color.rgb * lightWeight, a_color.w);
gl_Position = matModelViewProjection * vec4(position, 1.0);
}

View File

@ -19,6 +19,12 @@ export default class PointLayer extends Layer {
render() {
this.type = 'point';
this.init();
if(this.shapeType === 'text'){
this._textPoint();
return;
}
this._prepareRender(this.shapeType);
return;
switch (this.shapeType) {
case 'model':
this._staticModelPoint();
@ -42,10 +48,62 @@ export default class PointLayer extends Layer {
}
return this;
}
_prepareRender(){
const source = this.layerSource;
const { opacity, strokeWidth, stroke } = 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=='3d'){
mtl = new PolygonMaterial({
u_opacity: opacity
});
} else{
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')
});
}
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('a_size', new THREE.Float32BufferAttribute(attributes.sizes, 1));
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
if(this.shapeType ==='image'){
geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.uvs, 2));
}else if(this.shapeType=='2d'){
geometry.addAttribute('a_shape', new THREE.Float32BufferAttribute(attributes.shapes, 1));
} else if(this.shapeType=='3d')
{
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
}
let mesh;
if(this.shapeType!=='3d'){
mesh = new THREE.Points(geometry, mtl);
}else{
mesh = new THREE.Mesh(geometry, mtl);
}
this.add(mesh);
}
_imagePoint() {
const { opacity, strokeWidth, stroke } = this.get('styleOptions');
const source = this.layerSource;
this.scene.image.on('imageLoaded', () => {
const geometry = new THREE.BufferGeometry();
const buffer = new PointBuffer({
imagePos: this.scene.image.imagePos,
@ -66,9 +124,8 @@ export default class PointLayer extends Layer {
geometry.addAttribute('uv', new THREE.Float32BufferAttribute(attributes.uvs, 2));
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
const mesh = new THREE.Points(geometry, mtl);
console.log(mesh);
this.add(mesh);
});
return this;
}
// sdf 绘制多边形
@ -81,7 +138,7 @@ export default class PointLayer extends Layer {
coordinates: source.geoData,
properties: this.StyleData
});
this.buffer = buffer;
this._buffer = buffer;
const geometry = new THREE.BufferGeometry();
const mtl = new PointMaterial({
u_opacity: opacity,
@ -96,10 +153,7 @@ export default class PointLayer extends Layer {
geometry.addAttribute('a_shape', new THREE.Float32BufferAttribute(attributes.shapes, 1));
geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1));
const mesh = new THREE.Points(geometry, mtl);
this.remove(this.layerMesh);
this.add(mesh);
this.layerMesh = mesh;
this.updateFilter(this.StyleData);
}
_shapePoint() {

View File

@ -9,42 +9,61 @@ export default class PolygonLayer extends Layer {
return this;
}
render() {
this.type = 'polygon';
const { opacity } = this.get('styleOptions');
this.init();
const source = this.layerSource;
const geometry = this.geometry = new THREE.BufferGeometry();
const lineMaterial = new LineMaterial({
u_opacity: opacity
if(!this._hasRender) { // 首次渲染
this._hasRender = true;
this._prepareRender();
} else{
console.time('update');
this._initAttrs();
(this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter():null;
console.timeEnd('update');
}
);
const buffer = this.buffer = new PolygonBuffer({
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 } = 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));
this.geometry = geometry;
let polygonMesh = '';
if (this.shape === 'line') {
polygonMesh = new THREE.LineSegments(geometry, lineMaterial);
} else {
const material = new PolygonMaterial({
u_opacity: opacity
});
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
polygonMesh = new THREE.Mesh(geometry, material);
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(polygonMesh);
this.update();
return this;
}
_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 { opacity } = this.get('styleOptions');
const material = new PolygonMaterial({
u_opacity: opacity
});
const { attributes } = this._buffer;
this.geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
const polygonMesh = new THREE.Mesh(this.geometry, material);
this.add(polygonMesh);
}
update() {
this.updateFilter(this.StyleData);
// 动态更新相关属性

View File

@ -1,5 +1,5 @@
export default class GaodeMap {
constructor(map) {
constructor(map) {
this.map = map;
}
getZoom() {

View File

@ -81,7 +81,7 @@ export class MapProvider extends Base {
this.canvasContainer = canvasContainer;
this.renderDom = document.createElement('div');
this.renderDom.style.cssText += 'position: absolute;top: 0; z-index:1;height: 100%;width: 100%;pointer-events: none;';
this.renderDom.id = 'canvaslayer';
this.renderDom.id = 'l7_canvaslayer';
canvasContainer.appendChild(this.renderDom);
}
}