diff --git a/demos/polygon_jsondata.html b/demos/polygon_jsondata.html new file mode 100644 index 0000000000..14343e60e4 --- /dev/null +++ b/demos/polygon_jsondata.html @@ -0,0 +1,73 @@ + + + + + + + + + + extrude Polygon + + + + +
+
+ + + + + + + + diff --git a/src/core/controller/tile_mapping.js b/src/core/controller/tile_mapping.js new file mode 100644 index 0000000000..f8e70c1b3c --- /dev/null +++ b/src/core/controller/tile_mapping.js @@ -0,0 +1,183 @@ +import Util from '../../util'; +import Global from '../../global'; +import ScaleController from './scale'; +import Base from '../base'; +import Attr from '../../attr/index'; +export default class TileMapping extends Base { + constructor(source, cfg) { + super(cfg); + this.source = source; + this._init(); + } + _init() { + this._initControllers(); + this._initTileAttrs(); + this._mapping(); + } + update() { + this.set('scales', {}); + this._initTileAttrs(); + this._updateMaping(); + } + _initControllers() { + const scalesOption = this.get('scaleOptions'); + const scaleController = new ScaleController({ + defs: { + ...scalesOption + } + }); + this.set('scaleController', scaleController); + } + _createScale(field) { + const scales = this.get('scales'); + this._initControllers(); // scale更新 + 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.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 => { + if (item.filter === false) { + (item.color[3] = 0); + item.id = -item.id; + } + }); + } + this.layerData = mappedData; + } + + /** + * 更新数据maping + * @param {*} layerSource 数据源 + * @param {*} layer map + */ + _updateMaping() { + const attrs = this.get('attrs'); + + const data = this.source.data.dataArray; + const layerData = 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 = 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.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.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 ]; + } +} diff --git a/src/geom/buffer/factory.js b/src/geom/buffer/factory.js new file mode 100644 index 0000000000..25c0afb52c --- /dev/null +++ b/src/geom/buffer/factory.js @@ -0,0 +1,12 @@ +export const Buffer_MAP = {}; +export const getBuffer = (bufferType, shapeType) => { + return Buffer_MAP[bufferType.toLowerCase()] && Buffer_MAP[bufferType.toLowerCase()][shapeType.toLowerCase()]; +}; +export const registerBuffer = (bufferType, shapeType, render) => { + if (getBuffer(bufferType, shapeType)) { + throw new Error(`Render shapeType '${shapeType}' existed.`); + } + // 存储到 map 中 + if (!Buffer_MAP[bufferType.toLowerCase()]) Buffer_MAP[bufferType.toLowerCase()] = {}; + Buffer_MAP[bufferType.toLowerCase()][shapeType.toLowerCase()] = render; +}; diff --git a/src/source/parser/json.js b/src/source/parser/json.js index 37128bebce..a325bf01ef 100644 --- a/src/source/parser/json.js +++ b/src/source/parser/json.js @@ -1,16 +1,21 @@ export default function json(data, cfg) { - const { x, y, x1, y1 } = cfg; + const { x, y, x1, y1, coordinates } = cfg; const resultdata = []; data.forEach((col, featureIndex) => { - let coordinates = []; - if (x && y) { coordinates = [ col[x], col[y] ]; } // 点数据 + let coords = []; + if (x && y) { coords = [ col[x], col[y] ]; } // 点数据 if (x1 && y1) { // 弧线 或者线段 - coordinates = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; + coords = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; } + if (coordinates) { + coords = col[coordinates]; + delete col[coordinates]; + } + col._id = featureIndex + 1; const dataItem = { ...col, - coordinates + coordinates: coords }; resultdata.push(dataItem);