feat(layer): add controller

This commit is contained in:
thinkinggis 2019-05-29 15:35:24 +08:00
parent 5e4bddf7db
commit 55cf7a0dda
11 changed files with 327 additions and 364 deletions

View File

@ -57,7 +57,6 @@ scene.on('loaded', () => {
type:'log' type:'log'
} }
}) })
// cylinder
.shape('hexagon') .shape('hexagon')
.size(2) .size(2)
.active({fill:'red'}) .active({fill:'red'})
@ -73,10 +72,6 @@ scene.on('loaded', () => {
}) })
console.log(layer); console.log(layer);
}); });
//OBJECTID',(id)=>{
// const index = id % 8;
//return ['#9e0142','#d53e4f','#f46d43','#fdae61','#fee08b','#ffffbf','#e6f598','#abdda4','#66c2a5','#3288bd','#5e4fa2'][index];
//}
</script> </script>
</body> </body>
</html> </html>

View File

@ -52,8 +52,9 @@ scene.on('loaded', () => {
maxZoom: 17, maxZoom: 17,
} }
}) })
//.scale() .filter('province',name =>{
// cylinder return name =='山东省'
})
.shape('fill') .shape('fill')
.size(2) .size(2)
.active({fill:'red'}) .active({fill:'red'})

View File

@ -0,0 +1,6 @@
import Util from '../../util';
export default class EventContoller {
constructor(cfg) {
Util.assign(this, cfg);
}
}

View File

@ -1,4 +1,10 @@
import Scale from './scale'; import Scale from './scale';
import Mapping from './mapping';
import Picking from './pick';
import Interaction from './interaction';
export default { export default {
Scale Scale,
Mapping,
Picking,
Interaction
}; };

View File

@ -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;
}
}

View File

@ -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 ];
}
}

View File

@ -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);
}
}

View File

@ -7,9 +7,6 @@ import * as THREE from './three';
import ColorUtil from '../attr/color-util'; import ColorUtil from '../attr/color-util';
import Controller from './controller/index'; import Controller from './controller/index';
import source from './source'; import source from './source';
import pickingFragmentShader from '../core/engine/picking/picking_frag.glsl';
import { getInteraction } from '../interaction/index';
import Attr from '../attr/index';
import diff from '../util/diff'; import diff from '../util/diff';
import { updateObjecteUniform } from '../util/object3d-util'; import { updateObjecteUniform } from '../util/object3d-util';
import Util from '../util'; import Util from '../util';
@ -24,7 +21,6 @@ function parseFields(field) {
} }
return [ field ]; return [ field ];
} }
export default class Layer extends Base { export default class Layer extends Base {
getDefaultCfg() { getDefaultCfg() {
return { return {
@ -110,7 +106,8 @@ export default class Layer extends Base {
}; };
this._object3D.add(object); this._object3D.add(object);
if (type === 'fill') { if (type === 'fill') {
this._addPickMesh(object);// 不对边界线进行拾取 this.get('pickingController').addPickMesh(object);
// this._addPickMesh(object);// 不对边界线进行拾取
} }
setTimeout(() => this.scene._engine.update(), 500); setTimeout(() => this.scene._engine.update(), 500);
} }
@ -302,26 +299,14 @@ export default class Layer extends Base {
this._setAttrOptions(attrName, attrCfg); this._setAttrOptions(attrName, attrCfg);
} }
_initControllers() { _initControllers() {
const scales = this.get('scaleOptions'); const mappingCtr = new Controller.Mapping({ layer: this });
const scaleController = new Controller.Scale({ const pickCtr = new Controller.Picking({ layer: this });
defs: { const interactionCtr = new Controller.Interaction({ layer: this });
...scales this.set('mappingController', mappingCtr);
} this.set('pickingController', pickCtr);
}); this.set('interacionController', interactionCtr);
this.set('scaleController', scaleController);
} }
createScale(field) {
const data = this.layerSource ? this.layerSource.data.dataArray : null;
const scales = this.get('scales');
let scale = scales[field];
const scaleController = this.get('scaleController');
if (!scale) {
scale = scaleController.createScale(field, data);
scales[field] = scale;
}
return scale;
}
render() { render() {
this.init(); this.init();
this.scene._engine.update(); this.scene._engine.update();
@ -331,19 +316,19 @@ export default class Layer extends Base {
repaint() { repaint() {
this.set('scales', {}); this.set('scales', {});
this._initControllers(); this._initControllers();
this._initAttrs(); // this._initAttrs();
this._mapping(); // this._mapping();
this.redraw(); this.redraw();
} }
// 初始化图层 // 初始化图层
init() { init() {
this._initControllers(); this._initControllers();
this._initAttrs(); // this._initAttrs();
this._updateDraw(); this._updateDraw();
} }
_initInteraction() { _initInteraction() {
if (this.get('allowActive')) { if (this.get('allowActive')) {
this.interaction('active'); this.get('interacionController').addInteraction('active');
} }
} }
_initMapEvent() { _initMapEvent() {
@ -389,16 +374,6 @@ export default class Layer extends Base {
updateObjecteUniform(this._object3D, { u_activeId: featureId }); updateObjecteUniform(this._object3D, { u_activeId: featureId });
} }
_initAttrs() {
// 对比 options变化判断如何更新
const attrOptions = this.get('attrOptions');
for (const type in attrOptions) {
if (attrOptions.hasOwnProperty(type)) {
this._updateAttr(type);
}
}
}
_setPreOption() { _setPreOption() {
const nextAttrs = this.get('attrOptions'); const nextAttrs = this.get('attrOptions');
const nextStyle = this.get('styleOptions'); const nextStyle = this.get('styleOptions');
@ -411,7 +386,7 @@ export default class Layer extends Base {
const preStyle = this.get('preStyleOption'); const preStyle = this.get('preStyleOption');
const nextStyle = this.get('styleOptions'); const nextStyle = this.get('styleOptions');
if (preAttrs === undefined && preStyle === undefined) { // 首次渲染 if (preAttrs === undefined && preStyle === undefined) { // 首次渲染
this._mapping(); // this._mapping();
this._setPreOption(); this._setPreOption();
this._scaleByZoom(); this._scaleByZoom();
this._initInteraction(); this._initInteraction();
@ -449,28 +424,6 @@ export default class Layer extends Base {
this._setPreOption(); this._setPreOption();
} }
_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) { _updateSize(zoom) {
const sizeOption = this.get('attrOptions').size; const sizeOption = this.get('attrOptions').size;
const fields = parseFields(sizeOption.field); const fields = parseFields(sizeOption.field);
@ -495,96 +448,6 @@ export default class Layer extends Base {
} }
updateObjecteUniform(this._object3D, newOption); updateObjecteUniform(this._object3D, newOption);
} }
_mapping(source) {
const self = this;
const attrs = self.get('attrs');
const mappedData = [];
// const data = this.layerSource.propertiesData;
let data;
source ? data = source.data.dataArray : data = this.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 = 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];
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.layerData = mappedData;
return mappedData;
}
// 更新地图映射
_updateMaping(source, layer) {
const self = this;
const attrs = self.get('attrs');
const data = source ? source.data.dataArray : this.layerSource.data.dataArray;
const layerData = layer || this.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 = 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];
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;
}
}
}
}
// 获取属性映射的值
_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;
}
_scaleByZoom() { _scaleByZoom() {
if (this._zoomScale) { if (this._zoomScale) {
this.map.on('zoomend', () => { this.map.on('zoomend', () => {
@ -594,30 +457,6 @@ export default class Layer extends Base {
} }
} }
getPickingId() {
return this.scene._engine._picking.getNextId();
}
addToPicking(object) {
this.scene._engine._picking.add(object);
}
removeFromPicking(object) {
this.scene._engine._picking.remove(object);
}
_addPickMesh(mesh) {
this._pickingMesh = new THREE.Object3D();
this._pickingMesh.name = this.layerId;
this.addToPicking(this._pickingMesh);
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.scene.getZoom();
updateObjecteUniform(pickingMesh, { u_zoom: zoom });
};
this._pickingMesh.add(pickingMesh);
}
_initEvents() { _initEvents() {
this.scene.on('pick-' + this.layerId, e => { this.scene.on('pick-' + this.layerId, e => {
let { featureId, point2d, type } = e; let { featureId, point2d, type } = e;
@ -656,7 +495,7 @@ export default class Layer extends Base {
* @param {*} object 更新颜色和数据过滤 * @param {*} object 更新颜色和数据过滤
*/ */
_updateAttributes(object) { _updateAttributes(object) {
this._updateMaping(); this.get('mappingController').update();
const filterData = this.layerData; const filterData = this.layerData;
this._activeIds = null; // 清空选中元素 this._activeIds = null; // 清空选中元素
const colorAttr = object.geometry.attributes.a_color; const colorAttr = object.geometry.attributes.a_color;
@ -720,37 +559,6 @@ export default class Layer extends Base {
} }
// interaction 方法
clearAllInteractions() {
const interactions = this.get('interactions');
Util.each(interactions, (interaction, key) => {
interaction.destory();
delete interactions[key];
});
return this;
}
clearInteraction(type) {
const interactions = this.get('interactions');
if (interactions[type]) {
interactions[type].destory();
delete interactions[type];
}
return this;
}
interaction(type, cfg = {}) {
cfg.layer = this;
const Ctor = getInteraction(type);
const interaction = new Ctor(cfg);
this._setInteraction(type, interaction);
return this;
}
_setInteraction(type, interaction) {
const interactions = this.get('interactions');
if (interactions[type]) {
interactions[type].destory();
}
interactions[type] = interaction;
}
styleCfg() { styleCfg() {
} }

View File

@ -2,21 +2,9 @@ import * as THREE from '../../core/three';
import Base from '../../core/base'; import Base from '../../core/base';
import { destoryObject } from '../../util/object3d-util'; import { destoryObject } from '../../util/object3d-util';
import Controller from '../../core/controller/index'; import Controller from '../../core/controller/index';
import Util from '../../util';
import Global from '../../global';
import Attr from '../../attr/index';
import { toLngLatBounds, toBounds } from '@antv/geo-coord'; import { toLngLatBounds, toBounds } from '@antv/geo-coord';
const r2d = 180 / Math.PI; const r2d = 180 / Math.PI;
const tileURLRegex = /\{([zxy])\}/g; const tileURLRegex = /\{([zxy])\}/g;
function parseFields(field) {
if (Util.isArray(field)) {
return field;
}
if (Util.isString(field)) {
return field.split('*');
}
return [ field ];
}
export default class Tile extends Base { export default class Tile extends Base {
constructor(key, url, layer) { constructor(key, url, layer) {
super({ super({
@ -40,127 +28,15 @@ export default class Tile extends Base {
this.requestTileAsync(data => this._init(data)); this.requestTileAsync(data => this._init(data));
} }
_init(data) { _init(data) {
this._initControllers();
this._creatSource(data); this._creatSource(data);
this._initTileAttrs(); this._initControllers();
this._mapping();
this._createMesh(); this._createMesh();
} }
_initControllers() { _initControllers() {
const scales = this.layer.get('scaleOptions'); this.mapping = new Controller.Mapping({
const scaleController = new Controller.Scale({ layer: this.layer,
defs: { mesh: this
...scales
}
}); });
this.set('scaleController', scaleController);
}
_createScale(field) {
// TODO scale更新
const scales = this.get('scales');
let scale = scales[field];
if (!scale) {
scale = this.createScale(field);
scales[field] = scale;
}
return scale;
}
createScale(field) {
const data = this.source.data.dataArray;
const scales = this.get('scales');
let scale = scales[field];
const scaleController = this.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.get('attrs');
const mappedData = [];
// const data = this.layerSource.propertiesData;
const data = this.source.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.layerData = mappedData;
}
_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.get('attrs');
const attrOptions = this.layer.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;
} }
_createMesh() {} _createMesh() {}
_getTileURL(urlParams) { _getTileURL(urlParams) {
@ -223,6 +99,9 @@ export default class Tile extends Base {
return false; return false;
} }
_preRender() { _preRender() {
}
repaint() {
} }
destroy() { destroy() {
super.destroy(); super.destroy();

View File

@ -1,10 +1,10 @@
import Layer from '../../core/layer'; import Layer from '../../core/layer';
import source from '../../core/source'; import source from '../../core/source';
import * as THREE from '../../core/three'; import * as THREE from '../../core/three';
import Controller from '../../core/controller/index';
import Global from '../../global'; import Global from '../../global';
const { pointShape } = Global; const { pointShape } = Global;
import TileCache from './tileCache'; import TileCache from './tileCache';
import pickingFragmentShader from '../../core/engine/picking/picking_frag.glsl';
import { throttle, deepMix } from '@antv/util'; import { throttle, deepMix } from '@antv/util';
import { toLngLat, Bounds, Point } from '@antv/geo-coord'; import { toLngLat, Bounds, Point } from '@antv/geo-coord';
import { wrapNum } from '@antv/geo-coord/lib/util/index'; import { wrapNum } from '@antv/geo-coord/lib/util/index';
@ -18,9 +18,9 @@ export default class TileLayer extends Layer {
this._tileCache = new TileCache(100, this._destroyTile); this._tileCache = new TileCache(100, this._destroyTile);
this._crs = epsg3857; this._crs = epsg3857;
this._tiles = new THREE.Object3D(); this._tiles = new THREE.Object3D();
this._pickTiles = new THREE.Object3D(); // this._pickTiles = new THREE.Object3D();
this._pickTiles.name = this.layerId; // this._pickTiles.name = this.layerId;
this.scene._engine._picking.add(this._pickTiles); // this.scene._engine._picking.add(this._pickTiles);
this._tiles.frustumCulled = false; this._tiles.frustumCulled = false;
this._tileKeys = []; this._tileKeys = [];
this.tileList = {}; this.tileList = {};
@ -50,8 +50,14 @@ export default class TileLayer extends Layer {
deepMix(tileSourceCfg, this.sourceCfg, cfg); deepMix(tileSourceCfg, this.sourceCfg, cfg);
return new source(tileSourceCfg); return new source(tileSourceCfg);
} }
_initControllers() {
const pickCtr = new Controller.Picking({ layer: this });
const interactionCtr = new Controller.Interaction({ layer: this });
this.set('pickingController', pickCtr);
this.set('interacionController', interactionCtr);
}
render() { render() {
// this._initControllers(); this._initControllers();
this._initMapEvent(); this._initMapEvent();
// this._initAttrs(); // this._initAttrs();
this._initInteraction(); this._initInteraction();
@ -84,6 +90,13 @@ export default class TileLayer extends Layer {
* 需要显示 current * 需要显示 current
* 是否保留 retain * 是否保留 retain
*/ */
const minZoom = this.get('minZoom');
const maxZoom = this.get('maxZoom');
const currentZoom = this.scene.getZoom();
if (currentZoom < minZoom || currentZoom > maxZoom) {
this._removeOutTiles();
return;
}
this.updateTileList = []; this.updateTileList = [];
const zoom = Math.round(this.scene.getZoom()) - 1; const zoom = Math.round(this.scene.getZoom()) - 1;
const center = this.scene.getCenter(); const center = this.scene.getCenter();
@ -207,17 +220,9 @@ export default class TileLayer extends Layer {
} }
} }
_addPickTile(meshobj) { _addPickTile(meshobj) {
const pickCtr = this.get('pickingController');
const mesh = meshobj.children[0]; const mesh = meshobj.children[0];
const pickmaterial = mesh.material.clone(); pickCtr.addPickMesh(mesh);
pickmaterial.fragmentShader = pickingFragmentShader;
const pickingMesh = new THREE[mesh.type](mesh.geometry, pickmaterial);
pickingMesh.name = this.layerId;
pickingMesh.onBeforeRender = () => {
const zoom = this.scene.getZoom();
pickingMesh.material.setUniformsValue('u_zoom', zoom);
};
this._pickTiles.add(pickingMesh);
} }
// 根据距离优先级查找 // 根据距离优先级查找
getSelectFeature(id, lnglat) { getSelectFeature(id, lnglat) {
@ -374,6 +379,10 @@ export default class TileLayer extends Layer {
tile.destroy(); tile.destroy();
tile = null; tile = null;
} }
_updateAttributes() {
// 更新mapping
// 更新attribute
}
destroy() { destroy() {
} }
} }

View File

@ -32,17 +32,18 @@ export default class VectorTile extends Tile {
}); });
} }
_creatSource(data) { _creatSource(data) {
this.source = this.layer.tileSource(data, { this.layerSource = this.layer.tileSource(data, {
parser: { parser: {
tile: this._tile tile: this._tile
} }
}); });
} }
_createMesh() { _createMesh() {
const layerData = this.layerData;
if (this.layer.get('layerType') === 'point') { if (this.layer.get('layerType') === 'point') {
this.layer.shape = this.layer._getShape(this.layerData); this.layer.shape = this.layer._getShape(layerData);
} }
this.mesh = getRender(this.layer.get('layerType'), this.layer.shape)(this.layerData, this.layer); this.mesh = getRender(this.layer.get('layerType'), this.layer.shape)(layerData, this.layer);
if (this.mesh.type !== 'composer') { // 热力图的情况 if (this.mesh.type !== 'composer') { // 热力图的情况
this.mesh.onBeforeRender = renderer => { this.mesh.onBeforeRender = renderer => {
this._renderMask(renderer); this._renderMask(renderer);
@ -114,9 +115,9 @@ export default class VectorTile extends Tile {
this.xhrRequest.abort(); this.xhrRequest.abort();
} }
getSelectFeature(id) { getSelectFeature(id) {
const featureIndex = this.source.originData.featureKeys[id]; const featureIndex = this.layerSource.originData.featureKeys[id];
if (featureIndex) { if (featureIndex) {
return this.source.originData.dataArray[featureIndex]; return this.layerSource.originData.dataArray[featureIndex];
} }
return null; return null;
} }
@ -126,7 +127,7 @@ export default class VectorTile extends Tile {
this._object3D = null; this._object3D = null;
this.maskScene = null; this.maskScene = null;
this.layerData = null; this.layerData = null;
this.source.destroy(); this.layerSource.destroy();
this.source = null; this.layerSource = null;
} }
} }