From 917a076e46f036dee6aad8fdffcdad3e92a17ce8 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Tue, 2 Jul 2019 20:54:49 +0800 Subject: [PATCH 1/6] update version --- package.json | 2 +- src/global.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e242c1a41f..3ba6024873 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7", - "version": "1.2.0-beta.0", + "version": "1.2.0-beta.1", "description": "Large-scale WebGL-powered Geospatial Data Visualization", "main": "build/l7.js", "browser": "build/l7.js", diff --git a/src/global.js b/src/global.js index 7dbbc33359..136c0eb7e2 100644 --- a/src/global.js +++ b/src/global.js @@ -5,7 +5,7 @@ // const Global = {}; const FONT_FAMILY = '"-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto,"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",SimSun, "sans-serif"'; const Global = { - version: '1.2.0-beta.0', + version: '1.2.0-beta.1', scene: { mapType: 'AMAP', zoom: 5, From 5e7447b2cb9775884b59635104c072509cd5a064 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Mon, 8 Jul 2019 16:10:22 +0800 Subject: [PATCH 2/6] feat(attr): add pattern --- demos/03_choropleths_polygon.html | 1 + src/attr/filter.js | 8 ++++---- src/attr/index.js | 2 ++ src/attr/pattern.js | 16 ++++++++++++++++ src/core/layer.js | 4 ++++ src/global.js | 1 + 6 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/attr/pattern.js diff --git a/demos/03_choropleths_polygon.html b/demos/03_choropleths_polygon.html index a9c6ba4da4..0700fcf2b9 100644 --- a/demos/03_choropleths_polygon.html +++ b/demos/03_choropleths_polygon.html @@ -81,6 +81,7 @@ scene.on('loaded', () => { } }) .shape('fill') + .pattern('id1') .active(true) .style({ opacity: 1 diff --git a/src/attr/filter.js b/src/attr/filter.js index 6a0b29f650..4e2b24ea1b 100644 --- a/src/attr/filter.js +++ b/src/attr/filter.js @@ -1,15 +1,15 @@ /* * @Author: ThinkGIS * @Date: 2018-06-14 20:13:18 - * @Last Modified by: ThinkGIS - * @Last Modified time: 2018-07-15 17:26:40 + * @Last Modified by: mikey.zhaopeng + * @Last Modified time: 2019-07-08 15:46:28 */ import Base from './base'; /** - * 视觉通道 symbol - * @class Attr.symbol + * 视觉通道 filter + * @class Attr.filter */ class Filter extends Base { constructor(cfg) { diff --git a/src/attr/index.js b/src/attr/index.js index eb4d45ba47..ef233b0018 100644 --- a/src/attr/index.js +++ b/src/attr/index.js @@ -7,6 +7,7 @@ import Shape from './shape'; import Position from './position'; import Symbol from './symbol'; import Filter from './filter'; +import Pattern from './pattern'; Base.Color = Color; Base.Size = Size; @@ -15,5 +16,6 @@ Base.Shape = Shape; Base.Position = Position; Base.Symbol = Symbol; Base.Filter = Filter; +Base.Pattern = Pattern; export default Base; diff --git a/src/attr/pattern.js b/src/attr/pattern.js new file mode 100644 index 0000000000..be4b34d29f --- /dev/null +++ b/src/attr/pattern.js @@ -0,0 +1,16 @@ + +import Base from './base'; + +/** + * 视觉通道 pattern + * @class Attr.pattern + */ +class Pattern extends Base { + constructor(cfg) { + super(cfg); + this.names = [ 'pattern' ]; + this.type = 'pattern'; + this.gradient = null; + } +} +export default Pattern; diff --git a/src/core/layer.js b/src/core/layer.js index cc7c82f962..f20c8535bd 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -176,6 +176,10 @@ export default class Layer extends Base { this._createAttrOption('shape', field, values, Global.shape); return this; } + pattern(field, values) { + this._createAttrOption('pattern', field, values, Global.pattern); + return this; + } /** * 是否允许使用默认的图形激活交互 * @param {Boolean} enable 是否允许激活开关 diff --git a/src/global.js b/src/global.js index 136c0eb7e2..f7cbf95720 100644 --- a/src/global.js +++ b/src/global.js @@ -21,6 +21,7 @@ const Global = { colors: [ 'rgb(103,0,31)', 'rgb(178,24,43)', 'rgb(214,96,77)', 'rgb(244,165,130)', 'rgb(253,219,199)', 'rgb(247,247,247)', 'rgb(209,229,240)', 'rgb(146,197,222)', 'rgb(67,147,195)', 'rgb(33,102,172)', 'rgb(5,48,97)' ], size: 10000, shape: 'circle', + pattern: '', snapArray: [ 0, 1, 2, 4, 5, 10 ], pointShape: { '2d': [ 'circle', 'triangle', 'square', 'pentagon', 'hexagon', 'octogon', 'hexagram', 'rhombus', 'vesica' ], From 4b4e33dc9f51d1184bdd612b66d12bfcd30d36d4 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Wed, 10 Jul 2019 11:18:40 +0800 Subject: [PATCH 3/6] fix(poylygon): json source --- demos/polygon_jsondata.html | 73 +++++++++++ src/core/controller/tile_mapping.js | 183 ++++++++++++++++++++++++++++ src/geom/buffer/factory.js | 12 ++ src/source/parser/json.js | 15 ++- 4 files changed, 278 insertions(+), 5 deletions(-) create mode 100644 demos/polygon_jsondata.html create mode 100644 src/core/controller/tile_mapping.js create mode 100644 src/geom/buffer/factory.js 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); From cd00d33fcc61d4b744ad498d7cd06420b50df0dc Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Wed, 10 Jul 2019 11:26:29 +0800 Subject: [PATCH 4/6] update version --- package.json | 4 +++- src/global.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3ba6024873..06e47cf633 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7", - "version": "1.2.0-beta.1", + "version": "1.2.0-beta.2", "description": "Large-scale WebGL-powered Geospatial Data Visualization", "main": "build/l7.js", "browser": "build/l7.js", @@ -98,6 +98,7 @@ "@antv/g": "^3.1.3", "@antv/geo-coord": "^1.0.8", "@antv/util": "~2.0.1", + "@mapbox/geojson-rewind": "^0.4.0", "@mapbox/tiny-sdf": "^1.1.0", "@mapbox/vector-tile": "^1.3.1", "@turf/bbox": "^6.0.1", @@ -108,6 +109,7 @@ "d3-hexbin": "^0.2.2", "earcut": "^2.1.3", "fecha": "^2.3.3", + "geojson-rewind": "^0.3.1", "gl-matrix": "^2.4.1", "gl-vec2": "^1.3.0", "lodash": "^4.17.5", diff --git a/src/global.js b/src/global.js index 136c0eb7e2..2256230e7c 100644 --- a/src/global.js +++ b/src/global.js @@ -5,7 +5,7 @@ // const Global = {}; const FONT_FAMILY = '"-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto,"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",SimSun, "sans-serif"'; const Global = { - version: '1.2.0-beta.1', + version: '1.2.0-beta.2', scene: { mapType: 'AMAP', zoom: 5, From e90dd7ef82aa28a02e8777ccec755c35ad4f2f92 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Wed, 10 Jul 2019 12:08:11 +0800 Subject: [PATCH 5/6] fix(extrude): add geojson rewind --- demos/polygon_jsondata.html | 69 +++++++++++++++++++++++++++++++++++- src/source/parser/geojson.js | 2 ++ src/source/parser/json.js | 8 ++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/demos/polygon_jsondata.html b/demos/polygon_jsondata.html index 14343e60e4..10d1ce6902 100644 --- a/demos/polygon_jsondata.html +++ b/demos/polygon_jsondata.html @@ -26,7 +26,7 @@ const scene = new L7.Scene({ mapStyle: 'dark', // 样式URL center: [121.576757,31.279873 ], pitch: 0, - zoom: 10, + zoom: 12, rotation:0 }); @@ -38,6 +38,73 @@ const testdata = [ "areaGeometry": "121.588443,31.260267;121.587893,31.260332;121.587385,31.260387;121.586751,31.26045;121.586099,31.260505;121.585549,31.260584;121.585499,31.260641;121.585475,31.260702;121.585469,31.26076;121.585473,31.260797;121.585721,31.261172;121.585957,31.261529;121.58623,31.261987;121.586426,31.26235;121.586646,31.262795;121.586791,31.263137;121.586924,31.263478;121.587054,31.263788;121.587256,31.264224;121.587319,31.264276;121.587421,31.264337;121.587503,31.264368;121.587542,31.264373;121.588431,31.264357;121.589115,31.264355;121.589253,31.264357;121.589339,31.264331;121.589409,31.264288;121.589547,31.264049;121.589752,31.263696;121.589973,31.263313;121.590156,31.262965;121.59029,31.262682;121.590285,31.262557;121.590257,31.262498;121.5902,31.262459;121.589712,31.262265;121.589543,31.262197;121.5895,31.262125;121.589484,31.262072;121.589499,31.262005;121.589638,31.261714;121.589709,31.261579;121.589911,31.261242;121.590037,31.261031;121.590413,31.261176;121.591041,31.26141;121.591095,31.261317;121.59128,31.26097;121.59132,31.260872;121.591495,31.26061;121.591573,31.260552;121.591628,31.26051;121.591846,31.260295;121.592266,31.259879;121.592656,31.259516;121.592781,31.259401;121.5928,31.259343;121.592801,31.259301;121.592789,31.259261;121.592718,31.259196;121.592689,31.259156;121.592266,31.25884;121.591889,31.258548;121.591681,31.258396;121.591423,31.258196;121.590993,31.257889;121.59091,31.257892;121.590849,31.257903;121.590782,31.257971;121.590504,31.25835;121.590177,31.258758;121.589896,31.259137;121.589722,31.259395;121.589449,31.259807;121.58932,31.260028;121.589223,31.26024;121.588443,31.260267;121.588443,31.260267" } ] +const data2 = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118.48068237304686, + 32.120964197033615 + ], + [ + 118.49578857421874, + 32.037184191435145 + ], + [ + 118.57131958007811, + 32.061627957476404 + ], + [ + 118.57131958007811, + 32.13492006367728 + ], + [ + 118.48068237304686, + 32.120964197033615 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118.71414184570311, + 31.966143862120095 + ], + [ + 118.67156982421875, + 31.811062019751912 + ], + [ + 118.77044677734375, + 31.75502854729287 + ], + [ + 118.85696411132814, + 31.927689274849715 + ], + [ + 118.71414184570311, + 31.966143862120095 + ] + ] + ] + } + } + ] +} scene.on('loaded', () => { const data = testdata.map(item=>{ diff --git a/src/source/parser/geojson.js b/src/source/parser/geojson.js index 67b3c89db6..c0500d23ca 100644 --- a/src/source/parser/geojson.js +++ b/src/source/parser/geojson.js @@ -1,7 +1,9 @@ import * as turfMeta from '@turf/meta'; import { getCoords } from '@turf/invariant'; import { djb2hash } from '../../util/bkdr-hash'; +import rewind from '@mapbox/geojson-rewind'; export default function geoJSON(data, cfg) { + rewind(data, true); const resultData = []; const featureKeys = {}; data.features = data.features.filter(item => { diff --git a/src/source/parser/json.js b/src/source/parser/json.js index a325bf01ef..2f0f8fb029 100644 --- a/src/source/parser/json.js +++ b/src/source/parser/json.js @@ -1,3 +1,4 @@ +import rewind from '@mapbox/geojson-rewind'; export default function json(data, cfg) { const { x, y, x1, y1, coordinates } = cfg; const resultdata = []; @@ -8,7 +9,12 @@ export default function json(data, cfg) { coords = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; } if (coordinates) { - coords = col[coordinates]; + const geometry = { + type: 'Polygon', + coordinates: col[coordinates] + }; + rewind(geometry, true); + coords = geometry.coordinates; delete col[coordinates]; } From 775c8452cb1ea14c524421bfd63fcb1c2e648835 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Wed, 10 Jul 2019 14:39:27 +0800 Subject: [PATCH 6/6] fix(map): map style map --- demos/polygon_jsondata.html | 18 +++++++++++------- package.json | 2 +- src/core/layer.js | 3 ++- src/core/scene.js | 3 +-- src/global.js | 2 +- src/map/AMap.js | 3 ++- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/demos/polygon_jsondata.html b/demos/polygon_jsondata.html index 10d1ce6902..cca750f0ca 100644 --- a/demos/polygon_jsondata.html +++ b/demos/polygon_jsondata.html @@ -21,14 +21,18 @@