Skip to content

Commit

Permalink
feat(layer): add controller
Browse files Browse the repository at this point in the history
  • Loading branch information
lzxue committed May 29, 2019
1 parent 1491a7b commit d562f86
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 364 deletions.
5 changes: 0 additions & 5 deletions demos/vectorTile.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
type:'log'
}
})
// cylinder
.shape('hexagon')
.size(2)
.active({fill:'red'})
Expand All @@ -73,10 +72,6 @@
})
console.log(layer);
});
//OBJECTID',(id)=>{
// const index = id % 8;
//return ['#9e0142','#d53e4f','#f46d43','#fdae61','#fee08b','#ffffbf','#e6f598','#abdda4','#66c2a5','#3288bd','#5e4fa2'][index];
//}
</script>
</body>
</html>
Expand Down
5 changes: 3 additions & 2 deletions demos/vectorTilepolygon.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
maxZoom: 17,
}
})
//.scale()
// cylinder
.filter('province',name =>{
return name =='山东省'
})
.shape('fill')
.size(2)
.active({fill:'red'})
Expand Down
6 changes: 6 additions & 0 deletions src/core/controller/event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Util from '../../util';
export default class EventContoller {
constructor(cfg) {
Util.assign(this, cfg);
}
}
8 changes: 7 additions & 1 deletion src/core/controller/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import Scale from './scale';
import Mapping from './mapping';
import Picking from './pick';
import Interaction from './interaction';
export default {
Scale
Scale,
Mapping,
Picking,
Interaction
};
39 changes: 39 additions & 0 deletions src/core/controller/interaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Util from '../../util';
import { getInteraction } from '../../interaction/index';
export default class InteractionController {
constructor(cfg) {
// defs 列定义
Util.assign(this, cfg);
}
// interaction 方法
clearAllInteractions() {
const interactions = this.layer.get('interactions');
Util.each(interactions, (interaction, key) => {
interaction.destory();
delete interactions[key];
});
return this;
}
clearInteraction(type) {
const interactions = this.layer.get('interactions');
if (interactions[type]) {
interactions[type].destory();
delete interactions[type];
}
return this;
}
addInteraction(type, cfg = {}) {
cfg.layer = this.layer;
const Ctor = getInteraction(type);
const interaction = new Ctor(cfg);
this._setInteraction(type, interaction);
return this;
}
_setInteraction(type, interaction) {
const interactions = this.layer.get('interactions');
if (interactions[type]) {
interactions[type].destory();
}
interactions[type] = interaction;
}
}
183 changes: 183 additions & 0 deletions src/core/controller/mapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import Util from '../../util';
import Global from '../../global';
import ScaleController from './scale';
import Attr from '../../attr/index';
export default class Mapping {
/** 初始化mapping
* 初始化mapping
* @param {*} cfg 配置
* @param {*} cfg.layer layer对象
* @param {*} cfg.mesh mesh对象
*/
constructor(cfg) {
Util.assign(this, cfg);
if (!this.mesh) this.mesh = this.layer;
this._init();
}
_init() {
this._initControllers();
this._initTileAttrs();
this._mapping();
}
update() {
this._updateMaping();
}
_initControllers() {
const scales = this.layer.get('scaleOptions');
const scaleController = new ScaleController({
defs: {
...scales
}
});
this.mesh.set('scaleController', scaleController);
}
_createScale(field) {
// TODO scale更新
const scales = this.mesh.get('scales');
let scale = scales[field];
if (!scale) {
scale = this.createScale(field);
scales[field] = scale;
}
return scale;
}
createScale(field) {
const data = this.mesh.layerSource.data.dataArray;
const scales = this.mesh.get('scales');
let scale = scales[field];
const scaleController = this.mesh.get('scaleController');
if (!scale) {
scale = scaleController.createScale(field, data);
scales[field] = scale;
}
return scale;
}
// 获取属性映射的值
_getAttrValues(attr, record) {
const scales = attr.scales;
const params = [];
for (let i = 0; i < scales.length; i++) {
const scale = scales[i];
const field = scale.field;
if (scale.type === 'identity') {
params.push(scale.value);
} else {
params.push(record[field]);
}
}
const indexZoom = params.indexOf('zoom');
indexZoom !== -1 ? params[indexZoom] = attr.zoom : null;
const values = attr.mapping(...params);
return values;
}
_mapping() {
const attrs = this.mesh.get('attrs');
const mappedData = [];
const data = this.mesh.layerSource.data.dataArray;
for (let i = 0; i < data.length; i++) {
const record = data[i];
const newRecord = {};
newRecord.id = data[i]._id;
for (const k in attrs) {
if (attrs.hasOwnProperty(k)) {
const attr = attrs[k];
const names = attr.names;
const values = this._getAttrValues(attr, record);
if (names.length > 1) { // position 之类的生成多个字段的属性
for (let j = 0; j < values.length; j++) {
const val = values[j];
const name = names[j];
newRecord[name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
newRecord[names[0]] = values.length === 1 ? values[0] : values;

}
}
}
newRecord.coordinates = record.coordinates;
mappedData.push(newRecord);
}
// 通过透明度过滤数据
if (attrs.hasOwnProperty('filter')) {
mappedData.forEach(item => {
item.filter === false && (item.color[3] = 0);
});
}
this.mesh.layerData = mappedData;
}

/**
* 更新数据maping
* @param {*} layerSource 数据源
* @param {*} layer map
*/
_updateMaping() {
const attrs = this.mesh.get('attrs');

const data = this.mesh.layerSource.data.dataArray;
const layerData = this.mesh.layerData;
for (let i = 0; i < data.length; i++) {
const record = data[i];
for (const attrName in attrs) {
if (attrs.hasOwnProperty(attrName) && attrs[attrName].neadUpdate) {
const attr = attrs[attrName];
const names = attr.names;
const values = this._getAttrValues(attr, record);
if (names.length > 1) { // position 之类的生成多个字段的属性
for (let j = 0; j < values.length; j++) {
const val = values[j];
const name = names[j];
layerData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
layerData[i][names[0]] = values.length === 1 ? values[0] : values;

}
attr.neadUpdate = true;
}
}
}
}


_initTileAttrs() {
const attrOptions = this.layer.get('attrOptions');
for (const type in attrOptions) {
if (attrOptions.hasOwnProperty(type)) {
this._updateTileAttr(type);
}
}
}
_updateTileAttr(type) {
const self = this;
const attrs = this.mesh.get('attrs');
const attrOptions = this.layer.get('attrOptions');
const option = attrOptions[type];
option.neadUpdate = true;
const className = Util.upperFirst(type);
const fields = this._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;
}
_parseFields(field) {
if (Util.isArray(field)) {
return field;
}
if (Util.isString(field)) {
return field.split('*');
}
return [ field ];
}
}
36 changes: 36 additions & 0 deletions src/core/controller/pick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Util from '../../util';
import * as THREE from '../three';
import pickingFragmentShader from '../engine/picking/picking_frag.glsl';
import { updateObjecteUniform } from '../../util/object3d-util';
export default class PickContoller {
constructor(cfg) {
Util.assign(this, cfg);
this.pickObject3D = new THREE.Object3D();
this.addToPicking(this.pickObject3D);
}
getPickingId() {
return this.layer.scene._engine._picking.getNextId();
}
addToPicking(object) {
object.name = this.layer.layerId;
this.layer.scene._engine._picking.add(object);
}
removePickingObject(object) {
this.layer.scene._engine._picking.remove(object);
}
removePickingMesh(mesh) {
this.Object3D.remove(mesh);
}
addPickMesh(mesh) {
const pickmaterial = mesh.material.clone();
pickmaterial.fragmentShader = pickingFragmentShader;
const pickingMesh = new THREE[mesh.type](mesh.geometry, pickmaterial);
pickingMesh.name = this.layerId;
pickingMesh.onBeforeRender = () => {
const zoom = this.layer.scene.getZoom();
updateObjecteUniform(pickingMesh, { u_zoom: zoom });
};
this.pickObject3D.add(pickingMesh);

}
}
Loading

0 comments on commit d562f86

Please sign in to comment.