From a317d8ed0629fd69a725f68897d5cbf09a166a2e Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Tue, 19 Nov 2019 10:21:43 +0800 Subject: [PATCH] refactor(layer): point,polygon line model --- examples/gallery/basic/demo/arcCircle.js | 4 +- examples/gallery/basic/demo/column_dark.js | 4 +- examples/gallery/basic/demo/normal.js | 4 +- examples/gallery/basic/demo/point.js | 4 +- examples/line/arc/demo/arc.js | 10 +- examples/line/arc/demo/arcCircle.js | 41 +++--- examples/line/arc/demo/trip_arc.js | 7 +- examples/line/arc/demo/trip_arc_dark.js | 6 +- examples/point/bubble/demo/color.js | 2 +- examples/point/bubble/demo/meta.json | 18 +-- examples/point/bubble/demo/point.js | 2 +- .../point/{scatter => bubble}/demo/scatter.js | 0 examples/point/bubble/demo/world.js | 3 +- examples/point/column/demo/clumn_shape.js | 16 +-- .../point/column/demo/clumn_shape_light.js | 18 +-- examples/point/column/demo/column_dark.js | 18 +-- examples/point/column/demo/column_light.js | 14 +- examples/point/image/demo/image.js | 34 ++--- examples/point/image/demo/locate.js | 18 ++- examples/point/image/demo/weather.js | 8 +- examples/point/scatter/demo/meta.json | 7 +- examples/point/scatter/demo/normal.js | 4 +- .../normal.js => scatter/demo/normal2.js} | 4 +- examples/polygon/3d/demo/polygon.js | 6 +- .../core/src/services/layer/ILayerService.ts | 21 ++- packages/layers/src/core/BaseLayer.ts | 23 ++-- packages/layers/src/core/baseModel.ts | 55 ++++++++ packages/layers/src/core/triangulation.ts | 15 +- packages/layers/src/index.ts | 19 +-- packages/layers/src/line/index.ts | 129 ++---------------- packages/layers/src/line/{ => models}/arc.ts | 67 ++++----- .../src/line/{arc3d.ts => models/arc_3d.ts} | 62 ++++----- packages/layers/src/line/models/dash.ts | 22 +++ .../line/{arc2d.ts => models/great_circle.ts} | 70 ++++------ packages/layers/src/line/models/index.ts | 15 ++ packages/layers/src/line/models/line.ts | 120 ++++++++++++++++ .../layers/src/point/buffers/ExtrudeBuffer.ts | 79 ----------- .../layers/src/point/buffers/ImageBuffer.ts | 22 --- packages/layers/src/point/index.ts | 57 ++++++-- .../layers/src/point/{ => models}/extrude.ts | 60 ++++---- .../layers/src/point/{ => models}/fill.ts | 75 ++++------ .../layers/src/point/{ => models}/image.ts | 78 ++++------- packages/layers/src/point/models/index.ts | 17 +++ .../layers/src/point/{ => models}/normal.ts | 64 +++------ packages/layers/src/point/models/text.ts | 30 ++++ packages/layers/src/polygon/index.ts | 41 ++---- packages/layers/src/polygon/models/extrude.ts | 92 +++++++++++++ packages/layers/src/polygon/models/fill.ts | 47 +++++++ packages/layers/src/polygon/models/index.ts | 11 ++ packages/layers/src/polygon/polygon3D.ts | 8 +- 50 files changed, 829 insertions(+), 722 deletions(-) rename examples/point/{scatter => bubble}/demo/scatter.js (100%) rename examples/point/{bubble/demo/normal.js => scatter/demo/normal2.js} (90%) create mode 100644 packages/layers/src/core/baseModel.ts rename packages/layers/src/line/{ => models}/arc.ts (58%) rename packages/layers/src/line/{arc3d.ts => models/arc_3d.ts} (58%) create mode 100644 packages/layers/src/line/models/dash.ts rename packages/layers/src/line/{arc2d.ts => models/great_circle.ts} (58%) create mode 100644 packages/layers/src/line/models/index.ts create mode 100644 packages/layers/src/line/models/line.ts delete mode 100644 packages/layers/src/point/buffers/ExtrudeBuffer.ts delete mode 100644 packages/layers/src/point/buffers/ImageBuffer.ts rename packages/layers/src/point/{ => models}/extrude.ts (68%) rename packages/layers/src/point/{ => models}/fill.ts (61%) rename packages/layers/src/point/{ => models}/image.ts (58%) create mode 100644 packages/layers/src/point/models/index.ts rename packages/layers/src/point/{ => models}/normal.ts (58%) create mode 100644 packages/layers/src/point/models/text.ts create mode 100644 packages/layers/src/polygon/models/extrude.ts create mode 100644 packages/layers/src/polygon/models/fill.ts create mode 100644 packages/layers/src/polygon/models/index.ts diff --git a/examples/gallery/basic/demo/arcCircle.js b/examples/gallery/basic/demo/arcCircle.js index 597aeae5e0..06ffc318b8 100644 --- a/examples/gallery/basic/demo/arcCircle.js +++ b/examples/gallery/basic/demo/arcCircle.js @@ -1,4 +1,4 @@ -import { Arc2DLineLayer } from '@l7/layers'; +import { LineLayer } from '@l7/layers'; import { Scene } from '@l7/scene'; const scene = new Scene({ id: 'map', @@ -13,7 +13,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt') .then((res) => res.text()) .then((data) => { const layer = - new Arc2DLineLayer({}) + new LineLayer({}) .source(data, { parser: { type: 'csv', diff --git a/examples/gallery/basic/demo/column_dark.js b/examples/gallery/basic/demo/column_dark.js index 3633414bf5..13ae28f991 100644 --- a/examples/gallery/basic/demo/column_dark.js +++ b/examples/gallery/basic/demo/column_dark.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { Point3dLayer} from '@l7/layers' +import { PointLayer} from '@l7/layers' const scene = new Scene({ id: 'map', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json') .then((res) => res.json()) .then((data) => { const pointLayer = - new Point3dLayer({ + new PointLayer({ }) .source(data.list, { parser: { diff --git a/examples/gallery/basic/demo/normal.js b/examples/gallery/basic/demo/normal.js index 2ff1f932ab..6c52952426 100644 --- a/examples/gallery/basic/demo/normal.js +++ b/examples/gallery/basic/demo/normal.js @@ -1,6 +1,6 @@ import { Scene } from '@l7/scene'; -import { PointNormalLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', type: 'amap', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/BElVQFEFvpAKzddxFZxJ.txt') .then((res) => res.text()) .then((data) => { const pointLayer = - new PointNormalLayer({ + new PointLayer({ }) .source(data, { parser: { diff --git a/examples/gallery/basic/demo/point.js b/examples/gallery/basic/demo/point.js index 019931bf2b..a5269a917c 100644 --- a/examples/gallery/basic/demo/point.js +++ b/examples/gallery/basic/demo/point.js @@ -1,6 +1,6 @@ import { Scene } from '@l7/scene'; -import { PointNormalLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 64.88, @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7 .then((res) => res.json()) .then((data) => { const pointLayer = - new PointNormalLayer({ + new PointLayer({ }) .source(data) diff --git a/examples/line/arc/demo/arc.js b/examples/line/arc/demo/arc.js index 7b398c7da1..6b33943cce 100644 --- a/examples/line/arc/demo/arc.js +++ b/examples/line/arc/demo/arc.js @@ -1,4 +1,4 @@ -import { ArcLineLayer } from '@l7/layers'; +import { LineLayer } from '@l7/layers'; import { Scene } from '@l7/scene'; const scene = new Scene({ id: 'map', @@ -8,11 +8,11 @@ const scene = new Scene({ center: [0., 23.107329], zoom: 0, }); - +console.time('loadData'); fetch('https://gw.alipayobjects.com/os/basement_prod/b83699f9-a96d-49b8-b2ea-f99299faebaf.json') .then((res) => res.json()) .then((data) => { - + console.timeEnd('loadData'); function getAirportCoord(idx) { return [data.airports[idx][3], data.airports[idx][4]]; } @@ -24,9 +24,9 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/b83699f9-a96d-49b8-b2ea-f99 ] } }); - + console.timeEnd('loadData'); const layer = - new ArcLineLayer({}) + new LineLayer({}) .source(routes, { parser: { type: 'json', diff --git a/examples/line/arc/demo/arcCircle.js b/examples/line/arc/demo/arcCircle.js index 597aeae5e0..4e68836834 100644 --- a/examples/line/arc/demo/arcCircle.js +++ b/examples/line/arc/demo/arcCircle.js @@ -1,4 +1,4 @@ -import { Arc2DLineLayer } from '@l7/layers'; +import { LineLayer } from '@l7/layers'; import { Scene } from '@l7/scene'; const scene = new Scene({ id: 'map', @@ -8,28 +8,27 @@ const scene = new Scene({ center: [107.77791556935472, 35.443286920228644], zoom: 2.9142882493605033, }); -window.mapScene = scene; fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt') .then((res) => res.text()) .then((data) => { const layer = - new Arc2DLineLayer({}) - .source(data, { - parser: { - type: 'csv', - x: 'lng1', - y: 'lat1', - x1: 'lng2', - y1: 'lat2', - }, - }) - .size(1) - .shape('arc') - .color('#8C1EB2') - .style({ - opacity: 0.8, - blur: 0.99 - }) - ; - scene.addLayer(layer); + new LineLayer({}) + .source(data, { + parser: { + type: 'csv', + x: 'lng1', + y: 'lat1', + x1: 'lng2', + y1: 'lat2', + }, + }) + .size(1) + .shape('greatcircle') + .color('#8C1EB2') + .style({ + opacity: 0.8, + blur: 0.99 + }) + ; + scene.addLayer(layer); }) diff --git a/examples/line/arc/demo/trip_arc.js b/examples/line/arc/demo/trip_arc.js index 0b838e8304..7f2cee60cf 100644 --- a/examples/line/arc/demo/trip_arc.js +++ b/examples/line/arc/demo/trip_arc.js @@ -1,4 +1,4 @@ -import { Arc3DLineLayer } from '@l7/layers'; +import { LineLayer } from '@l7/layers'; import { Scene } from '@l7/scene'; const scene = new Scene({ id: 'map', @@ -8,12 +8,11 @@ const scene = new Scene({ center: [-74.06355155037261,40.73507179789368], zoom: 11.8623, }); -window.mapScene = scene; fetch('https://gw.alipayobjects.com/os/basement_prod/bd33a685-a17e-4686-bc79-b0e6a89fd950.csv') .then((res) => res.text()) .then((data) => { const layer = - new Arc3DLineLayer({}) + new LineLayer({}) .source(data, { parser: { type: 'csv', @@ -24,7 +23,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/bd33a685-a17e-4686-bc79-b0e }, }) .size(1) - .shape('arc') + .shape('arc3d') .color('#0C47BF') .style({ opacity: 1, diff --git a/examples/line/arc/demo/trip_arc_dark.js b/examples/line/arc/demo/trip_arc_dark.js index fc11f18c29..f09d7bf956 100644 --- a/examples/line/arc/demo/trip_arc_dark.js +++ b/examples/line/arc/demo/trip_arc_dark.js @@ -1,4 +1,4 @@ -import { Arc3DLineLayer } from '@l7/layers'; +import { LineLayer } from '@l7/layers'; import { Scene } from '@l7/scene'; const scene = new Scene({ id: 'map', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt') .then((res) => res.text()) .then((data) => { const layer = - new Arc3DLineLayer({}) + new LineLayer({}) .source(data, { parser: { type: 'csv', @@ -26,7 +26,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt') }, }) .size(1) - .shape('arc') + .shape('arc3d') .color('#FF7C6A') .style({ opacity: 0.8, diff --git a/examples/point/bubble/demo/color.js b/examples/point/bubble/demo/color.js index 09dddb35d8..81cf0df2ba 100644 --- a/examples/point/bubble/demo/color.js +++ b/examples/point/bubble/demo/color.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { PointLayer, PointImageLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 0, diff --git a/examples/point/bubble/demo/meta.json b/examples/point/bubble/demo/meta.json index ac14fcf566..9c9bf0e4ca 100644 --- a/examples/point/bubble/demo/meta.json +++ b/examples/point/bubble/demo/meta.json @@ -8,8 +8,8 @@ "filename": "point.js", "title": "气泡图", "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_9ETS5_1yCEAAAAAAAAAAABkARQnAQ" - - }, + + }, { "filename": "color.js", "title": "形状映射", @@ -19,13 +19,13 @@ "filename": "world.js", "title": "气泡图", "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*DMREQYwsCF4AAAAAAAAAAABkARQnAQ" - - }, - { - "filename": "normal.js", - "title": "城市亮度图", - "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Xp7iRaORYuIAAAAAAAAAAABkARQnAQ" - + + }, { + "filename": "scatter.js", + "title": "定点图", + "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Jt3ZSb8VH98AAAAAAAAAAABkARQnAQ" + } + ] } diff --git a/examples/point/bubble/demo/point.js b/examples/point/bubble/demo/point.js index 3866c4b935..cf8b433ced 100644 --- a/examples/point/bubble/demo/point.js +++ b/examples/point/bubble/demo/point.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { PointLayer, PointImageLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 0, diff --git a/examples/point/scatter/demo/scatter.js b/examples/point/bubble/demo/scatter.js similarity index 100% rename from examples/point/scatter/demo/scatter.js rename to examples/point/bubble/demo/scatter.js diff --git a/examples/point/bubble/demo/world.js b/examples/point/bubble/demo/world.js index 78c8e426c8..7071939514 100644 --- a/examples/point/bubble/demo/world.js +++ b/examples/point/bubble/demo/world.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { PointLayer, PointImageLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 0, @@ -9,7 +9,6 @@ const scene = new Scene({ zoom: 2.194613775109773, maxZoom: 10 }); -window.mapScene = scene; fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json') .then((res) => res.json()) .then((data) => { diff --git a/examples/point/column/demo/clumn_shape.js b/examples/point/column/demo/clumn_shape.js index 5a3e9c1c76..b0e15f99a8 100644 --- a/examples/point/column/demo/clumn_shape.js +++ b/examples/point/column/demo/clumn_shape.js @@ -1,11 +1,11 @@ import { Scene } from '@l7/scene'; -import { Point3dLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 65.68421052631578, type: 'amap', style: 'dark', - center: [121.3917,31.259242], + center: [121.3917, 31.259242], zoom: 14.55, rotation: 120 @@ -16,7 +16,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9 .then((res) => res.json()) .then((data) => { const pointLayer = - new Point3dLayer({ + new PointLayer({ }) .source(data, { parser: { @@ -24,16 +24,16 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9 x: 'longitude', y: 'latitude' } - }).shape('name',['cylinder', 'triangleColumn', 'hexagonColumn','squareColumn']) - .size('unit_price', (h)=>{ - return [ 6,6, h / 500 ] + }).shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn']) + .size('unit_price', (h) => { + return [6, 6, h / 500] }) - .color('name',['#739DFF', "#61FCBF",'#FFDE74','#FF896F']) + .color('name', ['#739DFF', "#61FCBF", '#FFDE74', '#FF896F']) .style({ opacity: 1.0, }) - scene.addLayer(pointLayer); + scene.addLayer(pointLayer); }); diff --git a/examples/point/column/demo/clumn_shape_light.js b/examples/point/column/demo/clumn_shape_light.js index 1b04e5549e..fc56b053db 100644 --- a/examples/point/column/demo/clumn_shape_light.js +++ b/examples/point/column/demo/clumn_shape_light.js @@ -1,12 +1,12 @@ import { Scene } from '@l7/scene'; -import { Point3dLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 65.68421052631578, type: 'mapbox', style: 'light', - center: [121.3917,31.259242], - zoom: 14.55, + center: [121.3917, 31.259242], + zoom: 13.55, rotation: 120 }); @@ -16,7 +16,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9 .then((res) => res.json()) .then((data) => { const pointLayer = - new Point3dLayer({ + new PointLayer({ }) .source(data, { parser: { @@ -24,16 +24,16 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9 x: 'longitude', y: 'latitude' } - }).shape('name',['cylinder', 'triangleColumn', 'hexagonColumn','squareColumn']) - .size('unit_price', (h)=>{ - return [ 6,6, h / 500 ] + }).shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn']) + .size('unit_price', (h) => { + return [6, 6, h / 500] }) - .color('name',['#5B8FF9', "#70E3B5",'#FFD458','#FF7C6A']) + .color('name', ['#5B8FF9', "#70E3B5", '#FFD458', '#FF7C6A']) .style({ opacity: 1.0, }) - scene.addLayer(pointLayer); + scene.addLayer(pointLayer); }); diff --git a/examples/point/column/demo/column_dark.js b/examples/point/column/demo/column_dark.js index 3633414bf5..510a465964 100644 --- a/examples/point/column/demo/column_dark.js +++ b/examples/point/column/demo/column_dark.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { Point3dLayer} from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json') .then((res) => res.json()) .then((data) => { const pointLayer = - new Point3dLayer({ + new PointLayer({ }) .source(data.list, { parser: { @@ -23,22 +23,22 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json') x: 'j', y: 'w' } - }) + }) .shape('cylinder') - .size('t', function(level) { + .size('t', function (level) { return [1, 2, level * 2 + 20]; }) - .color('t',[ + .color('t', [ '#094D4A', '#146968', '#1D7F7E', '#289899', '#34B6B7', '#4AC5AF', '#5FD3A6', '#7BE39E', '#A1EDB8', '#CEF8D6' - ],) + ]) .style({ opacity: 1.0, }) - scene.addLayer(pointLayer); - console.log(pointLayer); - + scene.addLayer(pointLayer); + console.log(pointLayer); + }); \ No newline at end of file diff --git a/examples/point/column/demo/column_light.js b/examples/point/column/demo/column_light.js index 533383f793..adcc29fa43 100644 --- a/examples/point/column/demo/column_light.js +++ b/examples/point/column/demo/column_light.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { Point3dLayer} from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json') .then((res) => res.json()) .then((data) => { const pointLayer = - new Point3dLayer({ + new PointLayer({ }) .source(data.list, { parser: { @@ -23,16 +23,16 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json') x: 'j', y: 'w' } - }) + }) .shape('cylinder') - .size('t', function(level) { + .size('t', function (level) { return [1, 2, level * 2 + 20]; }) .color('#006CFF') .style({ opacity: 1.0, }) - scene.addLayer(pointLayer); - console.log(pointLayer); - + scene.addLayer(pointLayer); + console.log(pointLayer); + }); \ No newline at end of file diff --git a/examples/point/image/demo/image.js b/examples/point/image/demo/image.js index 7a27ead997..5da7f57cb4 100644 --- a/examples/point/image/demo/image.js +++ b/examples/point/image/demo/image.js @@ -1,31 +1,31 @@ import { Scene } from '@l7/scene'; -import { PointImageLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' console.log(this); const scene = new Scene({ id: 'map', pitch: 0, type: 'amap', style: 'light', - center: [121.434765,31.256735], + center: [121.434765, 31.256735], zoom: 14.83, }); fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') .then((res) => res.json()) .then((data) => { - scene.addImage( - '00', - 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', - ); - scene.addImage( - '01', - 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', - ); - scene.addImage( - '02', - 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', - ); - const imageLayer = new PointImageLayer() + scene.addImage( + '00', + 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', + ); + scene.addImage( + '01', + 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', + ); + scene.addImage( + '02', + 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', + ); + const imageLayer = new PointLayer() .source(data, { parser: { type: 'json', @@ -33,9 +33,9 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9 y: 'latitude' } }) - .shape('name', ['00', '01','02']) + .shape('name', ['00', '01', '02']) .size(20); - scene.addLayer(imageLayer); + scene.addLayer(imageLayer); }); diff --git a/examples/point/image/demo/locate.js b/examples/point/image/demo/locate.js index 1ae31084bb..c067cabf80 100644 --- a/examples/point/image/demo/locate.js +++ b/examples/point/image/demo/locate.js @@ -1,6 +1,5 @@ import { Scene } from '@l7/scene'; -import { PointImageLayer } from '@l7/layers' -console.log(this); +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 0, @@ -13,18 +12,17 @@ const scene = new Scene({ fetch('https://gw.alipayobjects.com/os/basement_prod/e2fc6e0a-af2a-4320-96e5-d9f5a5fda442.json') .then((res) => res.json()) .then((data) => { - scene.addImage( - 'marker', - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ', - ); - const imageLayer = new PointImageLayer() - .source(data,) + scene.addImage( + 'marker', + 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ', + ); + const imageLayer = new PointLayer() + .source(data) .shape('marker') .size(12); - scene.addLayer(imageLayer); + scene.addLayer(imageLayer); }); -window.mapscene =scene; diff --git a/examples/point/image/demo/weather.js b/examples/point/image/demo/weather.js index 9df619e98d..d7634d3d56 100644 --- a/examples/point/image/demo/weather.js +++ b/examples/point/image/demo/weather.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { PointImageLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', type: 'amap', @@ -25,13 +25,13 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/c6042c6b-45fd-4e2e-adf8-fdb .then((res) => res.json()) .then((data) => { - const imageLayer = new PointImageLayer() + const imageLayer = new PointLayer() .source(data) - .shape('w', function(w) { + .shape('w', function (w) { return w; }) .size(15) - scene.addLayer(imageLayer); + scene.addLayer(imageLayer); }); diff --git a/examples/point/scatter/demo/meta.json b/examples/point/scatter/demo/meta.json index 2072bea186..f592a11c51 100644 --- a/examples/point/scatter/demo/meta.json +++ b/examples/point/scatter/demo/meta.json @@ -5,10 +5,9 @@ }, "demos": [ { - "filename": "scatter.js", - "title": "定点图", - "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Jt3ZSb8VH98AAAAAAAAAAABkARQnAQ" - + "filename": "normal2.js", + "title": "城市亮度图", + "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Xp7iRaORYuIAAAAAAAAAAABkARQnAQ" }, { "filename": "normal.js", diff --git a/examples/point/scatter/demo/normal.js b/examples/point/scatter/demo/normal.js index 2ff1f932ab..6c52952426 100644 --- a/examples/point/scatter/demo/normal.js +++ b/examples/point/scatter/demo/normal.js @@ -1,6 +1,6 @@ import { Scene } from '@l7/scene'; -import { PointNormalLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', type: 'amap', @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/BElVQFEFvpAKzddxFZxJ.txt') .then((res) => res.text()) .then((data) => { const pointLayer = - new PointNormalLayer({ + new PointLayer({ }) .source(data, { parser: { diff --git a/examples/point/bubble/demo/normal.js b/examples/point/scatter/demo/normal2.js similarity index 90% rename from examples/point/bubble/demo/normal.js rename to examples/point/scatter/demo/normal2.js index 019931bf2b..a5269a917c 100644 --- a/examples/point/bubble/demo/normal.js +++ b/examples/point/scatter/demo/normal2.js @@ -1,6 +1,6 @@ import { Scene } from '@l7/scene'; -import { PointNormalLayer } from '@l7/layers' +import { PointLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 64.88, @@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7 .then((res) => res.json()) .then((data) => { const pointLayer = - new PointNormalLayer({ + new PointLayer({ }) .source(data) diff --git a/examples/polygon/3d/demo/polygon.js b/examples/polygon/3d/demo/polygon.js index 2774579d1c..90521c91ef 100644 --- a/examples/polygon/3d/demo/polygon.js +++ b/examples/polygon/3d/demo/polygon.js @@ -1,5 +1,5 @@ import { Scene } from '@l7/scene'; -import { Polygon3DLayer } from '@l7/layers' +import { PolygonLayer } from '@l7/layers' const scene = new Scene({ id: 'map', pitch: 15.05263, @@ -14,10 +14,10 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae .then((res) => res.json()) .then((data) => { const layer = - new Polygon3DLayer ({ + new PolygonLayer ({ }) .source(data) - .shape('fill') + .shape('extrude') .size('h20',[100, 120, 160, 200, 260, 500]) .color('h20', ['#816CAD', '#A67FB5', '#C997C7', diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index d84e9b0c8b..f1361fbf20 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -1,8 +1,9 @@ import { SyncBailHook, SyncHook } from 'tapable'; import Clock from '../../utils/clock'; import { IGlobalConfigService } from '../config/IConfigService'; -import { IModel } from '../renderer/IModel'; +import { IModel, IModelInitializationOptions } from '../renderer/IModel'; import { IMultiPassRenderer } from '../renderer/IMultiPassRenderer'; +import { IUniform } from '../renderer/IUniform'; import { ISource, ISourceCFG } from '../source/ISourceService'; import { IAnimateOption, @@ -12,6 +13,7 @@ import { IStyleAttributeService, StyleAttrField, StyleAttributeOption, + Triangulation, } from './IStyleAttributeService'; export interface ILayerGlobalConfig { @@ -24,6 +26,19 @@ export interface ILayerGlobalConfig { [key: string]: IScale; }; } +export interface ILayerModelInitializationOptions { + moduleName: string; + vertexShader: string; + fragmentShader: string; + triangulation: Triangulation; +} +export interface ILayerModel { + getUninforms(): IModelUniform; + buildModels(): IModel[]; +} +export interface IModelUniform { + [key: string]: IUniform; +} export interface IPickedFeature { x: number; @@ -59,6 +74,10 @@ export interface ILayer { }; multiPassRenderer: IMultiPassRenderer; styleAttributeService: IStyleAttributeService; + buildLayerModel( + options: ILayerModelInitializationOptions & + Partial, + ): IModel; init(): ILayer; size(field: StyleAttrField, value?: StyleAttributeOption): ILayer; color(field: StyleAttrField, value?: StyleAttributeOption): ILayer; diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index fcb90df68b..d429712f89 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -9,6 +9,8 @@ import { IInteractionService, ILayer, ILayerInitializationOptions, + ILayerModel, + ILayerModelInitializationOptions, ILayerPlugin, ILayerService, IMapService, @@ -38,13 +40,6 @@ import { SyncBailHook, SyncHook } from 'tapable'; import { normalizePasses } from '../plugins/MultiPassRendererPlugin'; import baseLayerSchema from './schema'; -export interface ILayerModelInitializationOptions { - moduleName: string; - vertexShader: string; - fragmentShader: string; - triangulation: Triangulation; -} - /** * 分配 layer id */ @@ -110,15 +105,15 @@ export default class BaseLayer extends EventEmitter public readonly configService: IGlobalConfigService; @lazyInject(TYPES.IIconService) - protected readonly iconService: IIconService; + public readonly iconService: IIconService; @lazyInject(TYPES.IFontService) - protected readonly fontService: IFontService; - - protected layerSource: Source; + public readonly fontService: IFontService; @lazyInject(TYPES.IRendererService) - protected readonly rendererService: IRendererService; + public readonly rendererService: IRendererService; + + protected layerSource: Source; @lazyInject(TYPES.IShaderModuleService) protected readonly shaderModuleService: IShaderModuleService; @@ -129,6 +124,8 @@ export default class BaseLayer extends EventEmitter @lazyInject(TYPES.ILayerService) protected readonly layerService: ILayerService; + protected layerModel: ILayerModel; + protected enodeOptions: { [type: string]: { field: StyleAttributeField; @@ -441,7 +438,7 @@ export default class BaseLayer extends EventEmitter this.interactionService.triggerHover({ x, y }); } - protected buildLayerModel( + public buildLayerModel( options: ILayerModelInitializationOptions & Partial, ): IModel { diff --git a/packages/layers/src/core/baseModel.ts b/packages/layers/src/core/baseModel.ts new file mode 100644 index 0000000000..78201d7479 --- /dev/null +++ b/packages/layers/src/core/baseModel.ts @@ -0,0 +1,55 @@ +import { + AttributeType, + gl, + IEncodeFeature, + IFontService, + IGlobalConfigService, + IIconService, + ILayer, + ILayerModel, + ILayerPlugin, + ILogService, + IMapService, + IModel, + IModelUniform, + IRendererService, + IStyleAttributeService, + lazyInject, + TYPES, +} from '@l7/core'; + +export default class BaseModel implements ILayerModel { + protected layer: ILayer; + + @lazyInject(TYPES.IGlobalConfigService) + protected readonly configService: IGlobalConfigService; + + @lazyInject(TYPES.IIconService) + protected readonly iconService: IIconService; + + @lazyInject(TYPES.IFontService) + protected readonly fontService: IFontService; + + @lazyInject(TYPES.IRendererService) + protected readonly rendererService: IRendererService; + + @lazyInject(TYPES.IMapService) + protected readonly map: IMapService; + + constructor(layer: ILayer) { + this.layer = layer; + this.registerBuiltinAttributes(); + } + + public getUninforms(): IModelUniform { + throw new Error('Method not implemented.'); + } + + public buildModels(): IModel[] { + throw new Error('Method not implemented.'); + } + + protected registerBuiltinAttributes() { + throw new Error('Method not implemented.'); + } +} diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts index 97495b5bb9..896309f71f 100644 --- a/packages/layers/src/core/triangulation.ts +++ b/packages/layers/src/core/triangulation.ts @@ -1,5 +1,6 @@ import { IEncodeFeature } from '@l7/core'; import { aProjectFlat, lngLatToMeters } from '@l7/utils'; +import earcut from 'earcut'; import { vec3 } from 'gl-matrix'; import getNormals from '../utils/polylineNormal'; import extrudePolygon, { @@ -82,6 +83,18 @@ export function LineTriangulation(feature: IEncodeFeature) { }; } +export function polygonTriangulation(feature: IEncodeFeature) { + const { coordinates } = feature; + const flattengeo = earcut.flatten(coordinates as number[][][]); + const { vertices, dimensions, holes } = flattengeo; + + return { + indices: earcut(vertices, holes, dimensions), + vertices, + size: dimensions, + }; +} + export function PolygonExtrudeTriangulation(feature: IEncodeFeature) { const coordinates = feature.coordinates as IPosition[][]; const { positions, index, normals } = extrude_PolygonNormal( @@ -155,7 +168,7 @@ export function RasterImageTriangulation(feature: IEncodeFeature) { * @param segNum 弧线线段数 */ export function LineArcTriangulation(feature: IEncodeFeature) { - const segNum = 30; + const segNum = 20; const coordinates = feature.coordinates as IPosition[]; const positions = []; const indexArray = []; diff --git a/packages/layers/src/index.ts b/packages/layers/src/index.ts index e52676d63d..f638f93223 100644 --- a/packages/layers/src/index.ts +++ b/packages/layers/src/index.ts @@ -4,20 +4,15 @@ import HeatMapGrid3dLayer from './heatmap/gird3d'; import HeatMapGridLayer from './heatmap/grid'; import HeatMapLayer from './heatmap/heatmap'; import HeatMapHexagonLayer from './heatmap/hexagon'; -import ArcLineLayer from './line/arc'; -import Arc2DLineLayer from './line/arc2d'; -import Arc3DLineLayer from './line/arc3d'; + import DashLineLayer from './line/dash'; import LineLayer from './line/index'; -import Point3dLayer from './point/extrude'; -import PointLayer from './point/fill'; -import PointImageLayer from './point/image'; -import PointNormalLayer from './point/normal'; +import PointLayer from './point'; import TextLayer from './point/text'; // import Point from './point/point'; import PolygonLayer from './polygon'; -import Polygon3DLayer from './polygon/polygon3D'; +// import Polygon3DLayer from './polygon/polygon3D'; import ImageLayer from './raster/image'; import RasterLayer from './raster/raster'; import Raster2DLayer from './raster/raster2d'; @@ -83,19 +78,13 @@ export { BaseLayer, PointLayer, PolygonLayer, - Point3dLayer, - PointImageLayer, LineLayer, DashLineLayer, - Polygon3DLayer, + // Polygon3DLayer, ImageLayer, - ArcLineLayer, - Arc2DLineLayer, - Arc3DLineLayer, RasterLayer, HeatMapLayer, TextLayer, - PointNormalLayer, HeatMapGrid3dLayer, HeatMapHexagonLayer, HeatMapGridLayer, diff --git a/packages/layers/src/line/index.ts b/packages/layers/src/line/index.ts index 66a8e3f3bf..a7f431164a 100644 --- a/packages/layers/src/line/index.ts +++ b/packages/layers/src/line/index.ts @@ -1,8 +1,6 @@ import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; import BaseLayer from '../core/BaseLayer'; -import { LineTriangulation } from '../core/triangulation'; -import line_frag from './shaders/line_frag.glsl'; -import line_vert from './shaders/line_vert.glsl'; +import LineModels, { LineModelType } from './models'; interface IPointLayerStyleOptions { opacity: number; } @@ -24,129 +22,24 @@ export default class LineLayer extends BaseLayer { } protected renderModels() { - const { - enable, - interval = 0.2, - trailLength = 0.2, - duration = 2, - } = this.animateOptions; - const animate = enable ? 1 : 0; - const { opacity } = this.getStyleOptions(); this.models.forEach((model) => model.draw({ - uniforms: { - u_opacity: opacity || 1.0, - u_time: - this.layerService.clock.getElapsedTime() - this.animateStartTime, - u_animate: [animate, duration, interval, trailLength], - }, + uniforms: this.layerModel.getUninforms(), }), ); return this; } protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ - moduleName: 'line', - vertexShader: line_vert, - fragmentShader: line_frag, - triangulation: LineTriangulation, - blend: { - enable: true, - func: { - srcRGB: gl.SRC_ALPHA, - srcAlpha: 1, - dstRGB: gl.ONE_MINUS_SRC_ALPHA, - dstAlpha: 1, - }, - }, - }), - ]; - // this.initAnimate(); + const shape = this.getModelType(); + this.layerModel = new LineModels[shape](this); + this.models = this.layerModel.buildModels(); } - - private registerBuiltinAttributes(layer: ILayer) { - // point layer size; - layer.styleAttributeService.registerStyleAttribute({ - name: 'size', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Size', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 2, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - ) => { - const { size } = feature; - return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0]; - }, - }, - }); - - // point layer size; - layer.styleAttributeService.registerStyleAttribute({ - name: 'normal', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Normal', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.STATIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 3, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - normal: number[], - ) => { - return normal; - }, - }, - }); - - layer.styleAttributeService.registerStyleAttribute({ - name: 'miter', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Miter', - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - ) => { - return [vertex[4]]; - }, - }, - }); - } - // 拆分的动画插件 - private initAnimate() { - const { enable } = this.animateOptions; - if (enable) { - this.layerService.startAnimate(); - this.animateStartTime = this.layerService.clock.getElapsedTime(); - } + private getModelType(): LineModelType { + const shapeAttribute = this.styleAttributeService.getLayerStyleAttribute( + 'shape', + ); + const shape = shapeAttribute?.scale?.field as LineModelType; + return shape || 'line'; } } diff --git a/packages/layers/src/line/arc.ts b/packages/layers/src/line/models/arc.ts similarity index 58% rename from packages/layers/src/line/arc.ts rename to packages/layers/src/line/models/arc.ts index aa325cfc13..ef8a5816f7 100644 --- a/packages/layers/src/line/arc.ts +++ b/packages/layers/src/line/models/arc.ts @@ -1,46 +1,39 @@ -import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { LineArcTriangulation } from '../core/triangulation'; -import line_arc_frag from './shaders/line_arc_frag.glsl'; -import line_arc2d_vert from './shaders/line_bezier_vert.glsl'; +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, + IModelUniform, +} from '@l7/core'; + +import BaseModel from '../../core/baseModel'; +import { LineArcTriangulation } from '../../core/triangulation'; +import line_arc_frag from '../shaders/line_arc_frag.glsl'; +import line_arc2d_vert from '../shaders/line_bezier_vert.glsl'; + interface IArcLayerStyleOptions { opacity: number; segmentNumber: number; blur: number; } -export default class ArcLineLayer extends BaseLayer { - public name: string = 'LineLayer'; - - protected getConfigSchema() { +export default class ArcModel extends BaseModel { + public getUninforms(): IModelUniform { + const { + opacity, + blur = 0.99, + } = this.layer.getStyleOptions() as IArcLayerStyleOptions; return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, + u_opacity: opacity || 1, + segmentNumber: 30, + u_blur: blur, }; } - protected renderModels() { - const { opacity, blur = 0.99 } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1, - segmentNumber: 30, - u_blur: blur, - }, - }), - ); - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'arc2dline', vertexShader: line_arc2d_vert, fragmentShader: line_arc_frag, @@ -59,9 +52,9 @@ export default class ArcLineLayer extends BaseLayer { ]; } - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -85,7 +78,7 @@ export default class ArcLineLayer extends BaseLayer { }, }); - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'instance', // 弧线起始点信息 type: AttributeType.Attribute, descriptor: { diff --git a/packages/layers/src/line/arc3d.ts b/packages/layers/src/line/models/arc_3d.ts similarity index 58% rename from packages/layers/src/line/arc3d.ts rename to packages/layers/src/line/models/arc_3d.ts index 369ca56356..5c3ff2bd72 100644 --- a/packages/layers/src/line/arc3d.ts +++ b/packages/layers/src/line/models/arc_3d.ts @@ -1,44 +1,33 @@ -import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { LineArcTriangulation } from '../core/triangulation'; -import line_arc_frag from './shaders/line_arc_frag.glsl'; -import line_arc_vert from './shaders/line_arc_vert.glsl'; +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, + IModelUniform, +} from '@l7/core'; +import BaseModel from '../../core/baseModel'; +import { LineArcTriangulation } from '../../core/triangulation'; +import line_arc_frag from '../shaders/line_arc_frag.glsl'; +import line_arc_vert from '../shaders/line_arc_vert.glsl'; + interface IArcLayerStyleOptions { opacity: number; segmentNumber: number; } -export default class Arc3DLineLayer extends BaseLayer { - public name: string = 'LineLayer'; - - protected getConfigSchema() { +export default class Arc3DModel extends BaseModel { + public getUninforms(): IModelUniform { + const { opacity } = this.layer.getStyleOptions() as IArcLayerStyleOptions; return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, + u_opacity: opacity || 1, + segmentNumber: 30, }; } - protected renderModels() { - const { opacity } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1, - segmentNumber: 30, - }, - }), - ); - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'arcline', vertexShader: line_arc_vert, fragmentShader: line_arc_frag, @@ -55,10 +44,9 @@ export default class Arc3DLineLayer extends BaseLayer { }), ]; } - - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -82,7 +70,7 @@ export default class Arc3DLineLayer extends BaseLayer { }, }); - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'instance', // 弧线起始点信息 type: AttributeType.Attribute, descriptor: { diff --git a/packages/layers/src/line/models/dash.ts b/packages/layers/src/line/models/dash.ts new file mode 100644 index 0000000000..7aa44a4dbc --- /dev/null +++ b/packages/layers/src/line/models/dash.ts @@ -0,0 +1,22 @@ +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, +} from '@l7/core'; + +import BaseModel from '../../core/baseModel'; +export default class ArcModel extends BaseModel { + public getUninforms() { + throw new Error('Method not implemented.'); + } + + public buildModels(): IModel[] { + throw new Error('Method not implemented.'); + } + private registerBuiltinAttributes() { + throw new Error('Method not implemented.'); + } +} diff --git a/packages/layers/src/line/arc2d.ts b/packages/layers/src/line/models/great_circle.ts similarity index 58% rename from packages/layers/src/line/arc2d.ts rename to packages/layers/src/line/models/great_circle.ts index c35b23edba..5a990694e5 100644 --- a/packages/layers/src/line/arc2d.ts +++ b/packages/layers/src/line/models/great_circle.ts @@ -1,48 +1,39 @@ -import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { LineArcTriangulation } from '../core/triangulation'; -import line_arc2d_vert from './shaders/line_arc2d_vert.glsl'; -import line_arc_frag from './shaders/line_arc_frag.glsl'; +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, + IModelUniform, +} from '@l7/core'; + +import BaseModel from '../../core/baseModel'; +import { LineArcTriangulation } from '../../core/triangulation'; +import line_arc2d_vert from '../shaders/line_arc2d_vert.glsl'; +import line_arc_frag from '../shaders/line_arc_frag.glsl'; + interface IArcLayerStyleOptions { opacity: number; segmentNumber: number; blur: number; } -export default class ArcCircleLineLayer extends BaseLayer< - IArcLayerStyleOptions -> { - public name: string = 'LineLayer'; - - protected getConfigSchema() { +export default class GreatCircleModel extends BaseModel { + public getUninforms(): IModelUniform { + const { + opacity, + blur = 0.99, + } = this.layer.getStyleOptions() as IArcLayerStyleOptions; return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, + u_opacity: opacity || 1, + segmentNumber: 30, + u_blur: blur, }; } - protected renderModels() { - const { opacity, blur = 0.99 } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1, - segmentNumber: 30, - u_blur: blur, - }, - }), - ); - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'arc2dline', vertexShader: line_arc2d_vert, fragmentShader: line_arc_frag, @@ -60,10 +51,9 @@ export default class ArcCircleLineLayer extends BaseLayer< }), ]; } - - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -87,7 +77,7 @@ export default class ArcCircleLineLayer extends BaseLayer< }, }); - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'instance', // 弧线起始点信息 type: AttributeType.Attribute, descriptor: { diff --git a/packages/layers/src/line/models/index.ts b/packages/layers/src/line/models/index.ts new file mode 100644 index 0000000000..54a3a124e8 --- /dev/null +++ b/packages/layers/src/line/models/index.ts @@ -0,0 +1,15 @@ +import ArcModel from './arc'; +import Arc3DModel from './arc_3d'; +import GreatCircleModel from './great_circle'; +import LineModel from './line'; + +export type LineModelType = 'arc' | 'arc3d' | 'greatcircle' | 'line'; + +const LineModels: { [key in LineModelType]: any } = { + arc: ArcModel, + arc3d: Arc3DModel, + greatcircle: GreatCircleModel, + line: LineModel, +}; + +export default LineModels; diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts new file mode 100644 index 0000000000..c4c8bcd0c3 --- /dev/null +++ b/packages/layers/src/line/models/line.ts @@ -0,0 +1,120 @@ +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, + IModelUniform, +} from '@l7/core'; + +import BaseModel from '../../core/baseModel'; +import { LineTriangulation } from '../../core/triangulation'; +import line_frag from '../shaders/line_frag.glsl'; +import line_vert from '../shaders/line_vert.glsl'; + +interface ILineLayerStyleOptions { + opacity: number; +} +export default class LineModel extends BaseModel { + public getUninforms(): IModelUniform { + const { opacity } = this.layer.getStyleOptions() as ILineLayerStyleOptions; + return { + u_opacity: opacity || 1.0, + }; + } + + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ + moduleName: 'line', + vertexShader: line_vert, + fragmentShader: line_frag, + triangulation: LineTriangulation, + blend: { + enable: true, + func: { + srcRGB: gl.SRC_ALPHA, + srcAlpha: 1, + dstRGB: gl.ONE_MINUS_SRC_ALPHA, + dstAlpha: 1, + }, + }, + }), + ]; + } + protected registerBuiltinAttributes() { + // point layer size; + this.layer.styleAttributeService.registerStyleAttribute({ + name: 'size', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Size', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.DYNAMIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 2, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + ) => { + const { size } = feature; + return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0]; + }, + }, + }); + + // point layer size; + this.layer.styleAttributeService.registerStyleAttribute({ + name: 'normal', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Normal', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 3, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + normal: number[], + ) => { + return normal; + }, + }, + }); + + this.layer.styleAttributeService.registerStyleAttribute({ + name: 'miter', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Miter', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.DYNAMIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 1, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + ) => { + return [vertex[4]]; + }, + }, + }); + } +} diff --git a/packages/layers/src/point/buffers/ExtrudeBuffer.ts b/packages/layers/src/point/buffers/ExtrudeBuffer.ts deleted file mode 100644 index f0cd0d8d1a..0000000000 --- a/packages/layers/src/point/buffers/ExtrudeBuffer.ts +++ /dev/null @@ -1,79 +0,0 @@ -// import BaseBuffer, { -// IBufferInfo, -// IEncodeFeature, -// Position, -// } from '../../core/BaseBuffer'; -// import extrudePolygon, { IExtrudeGeomety } from '../shape/extrude'; -// import { geometryShape, ShapeType2D, ShapeType3D } from '../shape/Path'; -// interface IGeometryCache { -// [key: string]: IExtrudeGeomety; -// } -// export default class ExtrudeBuffer extends BaseBuffer { -// private indexOffset: number = 0; -// private verticesOffset: number = 0; -// private geometryCache: IGeometryCache; -// public buildFeatures() { -// const layerData = this.data as IEncodeFeature[]; -// layerData.forEach((feature: IEncodeFeature) => { -// this.calculateFill(feature); -// }); -// } - -// protected calculateFeatures() { -// const layerData = this.data as IEncodeFeature[]; -// this.geometryCache = {}; -// this.verticesOffset = 0; -// this.indexOffset = 0; -// layerData.forEach((feature: IEncodeFeature) => { -// const { shape } = feature; -// const { positions, index } = this.getGeometry(shape as ShapeType3D); -// this.verticesCount += positions.length / 3; -// this.indexCount += index.length; -// }); -// } -// protected initAttributes() { -// super.initAttributes(); -// this.attributes.miters = new Float32Array(this.verticesCount * 3); -// this.attributes.normals = new Float32Array(this.verticesCount * 3); -// this.attributes.sizes = new Float32Array(this.verticesCount * 3); -// } -// private calculateFill(feature: IEncodeFeature) { -// const { coordinates, shape } = feature; -// const instanceGeometry = this.getGeometry(shape as ShapeType3D); -// const numPoint = instanceGeometry.positions.length / 3; -// feature.bufferInfo = { -// verticesOffset: this.verticesOffset, -// indexOffset: this.indexOffset, -// dimensions: 3, -// }; -// this.encodeArray(feature, numPoint); -// this.attributes.miters.set( -// instanceGeometry.positions, -// this.verticesOffset * 3, -// ); -// const indexArray = instanceGeometry.index.map((v) => { -// return v + this.verticesOffset; -// }); -// this.indexArray.set(indexArray, this.indexOffset); -// const position: number[] = []; -// for (let i = 0; i < numPoint; i++) { -// const coor = coordinates as Position; -// position.push(coor[0], coor[1], coor[2] || 0); -// } -// this.attributes.positions.set(position, this.verticesOffset * 3); -// this.verticesOffset += numPoint; -// this.indexOffset += indexArray.length; -// } - -// private getGeometry(shape: ShapeType3D): IExtrudeGeomety { -// if (this.geometryCache && this.geometryCache[shape]) { -// return this.geometryCache[shape]; -// } -// const path = geometryShape[shape] -// ? geometryShape[shape]() -// : geometryShape.cylinder(); -// const geometry = extrudePolygon([path]); -// this.geometryCache[shape] = geometry; -// return geometry; -// } -// } diff --git a/packages/layers/src/point/buffers/ImageBuffer.ts b/packages/layers/src/point/buffers/ImageBuffer.ts deleted file mode 100644 index 03aef61af5..0000000000 --- a/packages/layers/src/point/buffers/ImageBuffer.ts +++ /dev/null @@ -1,22 +0,0 @@ -// import BaseBuffer, { IEncodeFeature, Position } from '../../core/BaseBuffer'; -// export default class ImageBuffer extends BaseBuffer { -// protected calculateFeatures() { -// const layerData = this.data as IEncodeFeature[]; -// this.verticesCount = layerData.length; -// this.indexCount = layerData.length; -// } -// protected buildFeatures() { -// const layerData = this.data as IEncodeFeature[]; -// this.attributes.uv = new Float32Array(this.verticesCount * 2); -// layerData.forEach((item: IEncodeFeature, index: number) => { -// const { color = [0, 0, 0, 0], size, id, shape, coordinates } = item; -// const { x, y } = this.iconMap[shape as string] || { x: 0, y: 0 }; -// const coor = coordinates as Position; -// this.attributes.positions.set(coor, index * 3); -// this.attributes.colors.set(color, index * 4); -// this.attributes.pickingIds.set([id as number], index); -// this.attributes.sizes.set([size as number], index); // -// this.attributes.uv.set([x, y], index * 2); -// }); -// } -// } diff --git a/packages/layers/src/point/index.ts b/packages/layers/src/point/index.ts index 5ff8f0ff9a..d2a556c092 100644 --- a/packages/layers/src/point/index.ts +++ b/packages/layers/src/point/index.ts @@ -1,18 +1,6 @@ -import { - AttributeType, - gl, - IEncodeFeature, - ILayer, - ILayerPlugin, - ILogService, - IStyleAttributeService, - lazyInject, - TYPES, -} from '@l7/core'; +import { IEncodeFeature } from '@l7/core'; import BaseLayer from '../core/BaseLayer'; -import { rgb2arr } from '../utils/color'; -import pointFillFrag from './shaders/fill_frag.glsl'; -import pointFillVert from './shaders/fill_vert.glsl'; +import PointModels, { PointType } from './models/index'; interface IPointLayerStyleOptions { opacity: number; strokeWidth: number; @@ -20,7 +8,6 @@ interface IPointLayerStyleOptions { } export default class PointLayer extends BaseLayer { public name: string = 'PointLayer'; - protected getConfigSchema() { return { properties: { @@ -32,4 +19,44 @@ export default class PointLayer extends BaseLayer { }, }; } + protected renderModels() { + this.models.forEach((model) => + model.draw({ + uniforms: this.layerModel.getUninforms(), + }), + ); + return this; + } + + protected buildModels() { + const modelType = this.getModelType(); + this.layerModel = new PointModels[modelType](this); + this.models = this.layerModel.buildModels(); + } + + private getModelType(): PointType { + // pointlayer + // 2D、 3d、 shape、image、text、normal、 + const layerData = this.getEncodedData(); + const { shape2d, shape3d } = this.configService.getConfig(); + const iconMap = this.iconService.getIconMap(); + const item = layerData.find((fe: IEncodeFeature) => { + return fe.hasOwnProperty('shape'); + }); + if (!item) { + return 'normal'; + } else { + const shape = item.shape; + if (shape2d?.indexOf(shape as string) !== -1) { + return 'fill'; + } + if (shape3d?.indexOf(shape as string) !== -1) { + return 'extrude'; + } + if (iconMap.hasOwnProperty(shape as string)) { + return 'image'; + } + return 'text'; + } + } } diff --git a/packages/layers/src/point/extrude.ts b/packages/layers/src/point/models/extrude.ts similarity index 68% rename from packages/layers/src/point/extrude.ts rename to packages/layers/src/point/models/extrude.ts index 82d4cf7ce3..0b7495f7b1 100644 --- a/packages/layers/src/point/extrude.ts +++ b/packages/layers/src/point/models/extrude.ts @@ -1,42 +1,29 @@ -import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { PointExtrudeTriangulation } from '../core/triangulation'; -import pointExtrudeFrag from './shaders/extrude_frag.glsl'; -import pointExtrudeVert from './shaders/extrude_vert.glsl'; +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, +} from '@l7/core'; +import BaseModel from '../../core/baseModel'; +import { PointExtrudeTriangulation } from '../../core/triangulation'; +import pointExtrudeFrag from '../shaders/extrude_frag.glsl'; +import pointExtrudeVert from '../shaders/extrude_vert.glsl'; interface IPointLayerStyleOptions { opacity: number; } -export default class PointLayer extends BaseLayer { - public name: string = 'PointLayer'; - - protected getConfigSchema() { +export default class ExtrudeModel extends BaseModel { + public getUninforms() { + const { opacity } = this.layer.getStyleOptions() as IPointLayerStyleOptions; return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, + u_opacity: opacity || 1.0, }; } - protected renderModels() { - const { opacity } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1.0, - }, - }), - ); - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'pointExtrude', vertexShader: pointExtrudeVert, fragmentShader: pointExtrudeFrag, @@ -53,10 +40,9 @@ export default class PointLayer extends BaseLayer { }), ]; } - - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -93,7 +79,7 @@ export default class PointLayer extends BaseLayer { }); // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { @@ -116,7 +102,7 @@ export default class PointLayer extends BaseLayer { }, }, }); - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'pos', type: AttributeType.Attribute, descriptor: { diff --git a/packages/layers/src/point/fill.ts b/packages/layers/src/point/models/fill.ts similarity index 61% rename from packages/layers/src/point/fill.ts rename to packages/layers/src/point/models/fill.ts index a94fefbe69..2a1277a9b3 100644 --- a/packages/layers/src/point/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -3,78 +3,52 @@ import { gl, IEncodeFeature, ILayer, + ILayerModel, ILayerPlugin, ILogService, + IModel, IStyleAttributeService, lazyInject, TYPES, } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { rgb2arr } from '../utils/color'; -import pointFillFrag from './shaders/fill_frag.glsl'; -import pointFillVert from './shaders/fill_vert.glsl'; +import BaseModel from '../../core/baseModel'; +import { PointFillTriangulation } from '../../core/triangulation'; +import { rgb2arr } from '../../utils/color'; +import pointFillFrag from '../shaders/fill_frag.glsl'; +import pointFillVert from '../shaders/fill_vert.glsl'; interface IPointLayerStyleOptions { opacity: number; strokeWidth: number; strokeColor: string; } -export function PointTriangulation(feature: IEncodeFeature) { - const coordinates = feature.coordinates as number[]; - return { - vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates], - extrude: [-1, -1, 1, -1, 1, 1, -1, 1], - indices: [0, 1, 2, 2, 3, 0], - size: coordinates.length, - }; -} -export default class PointLayer extends BaseLayer { - public name: string = 'PointLayer'; - - protected getConfigSchema() { - return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, - }; - } - - protected renderModels() { +export default class FillModel extends BaseModel { + public getUninforms() { const { opacity = 1, strokeColor = 'rgb(0,0,0,0)', strokeWidth = 1, - } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity, - u_stroke_width: strokeWidth, - u_stroke_color: rgb2arr(strokeColor), - }, - }), - ); - return this; + } = this.layer.getStyleOptions() as IPointLayerStyleOptions; + return { + u_opacity: opacity, + u_stroke_width: strokeWidth, + u_stroke_color: rgb2arr(strokeColor), + }; } - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'pointfill', vertexShader: pointFillVert, fragmentShader: pointFillFrag, - triangulation: PointTriangulation, + triangulation: PointFillTriangulation, depth: { enable: false }, }), ]; } - private registerBuiltinAttributes(layer: ILayer) { - layer.styleAttributeService.registerStyleAttribute({ + protected registerBuiltinAttributes() { + this.layer.styleAttributeService.registerStyleAttribute({ name: 'extrude', type: AttributeType.Attribute, descriptor: { @@ -100,7 +74,7 @@ export default class PointLayer extends BaseLayer { }); // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -125,7 +99,7 @@ export default class PointLayer extends BaseLayer { }); // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'shape', type: AttributeType.Attribute, descriptor: { @@ -144,7 +118,8 @@ export default class PointLayer extends BaseLayer { attributeIdx: number, ) => { const { shape = 2 } = feature; - const shape2d = layer.configService.getConfig().shape2d as string[]; + const shape2d = this.layer.configService.getConfig() + .shape2d as string[]; const shapeIndex = shape2d.indexOf(shape as string); return [shapeIndex]; }, diff --git a/packages/layers/src/point/image.ts b/packages/layers/src/point/models/image.ts similarity index 58% rename from packages/layers/src/point/image.ts rename to packages/layers/src/point/models/image.ts index 0112f7be08..569b7935d6 100644 --- a/packages/layers/src/point/image.ts +++ b/packages/layers/src/point/models/image.ts @@ -3,73 +3,44 @@ import { gl, IEncodeFeature, ILayer, - ILayerPlugin, - ILogService, - IStyleAttributeService, + ILayerModel, + IModel, ITexture2D, - lazyInject, - TYPES, } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { PointImageTriangulation } from '../core/triangulation'; -import pointImageFrag from './shaders/image_frag.glsl'; -import pointImageVert from './shaders/image_vert.glsl'; + +import BaseModel from '../../core/baseModel'; +import { PointImageTriangulation } from '../../core/triangulation'; +import pointImageFrag from '../shaders/image_frag.glsl'; +import pointImageVert from '../shaders/image_vert.glsl'; interface IPointLayerStyleOptions { opacity: number; } -export function PointTriangulation(feature: IEncodeFeature) { - const coordinates = feature.coordinates as number[]; - return { - vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates], - extrude: [-1, -1, 1, -1, 1, 1, -1, 1], - indices: [0, 1, 2, 2, 3, 0], - size: coordinates.length, - }; -} -export default class PointLayer extends BaseLayer { - public name: string = 'PointLayer'; + +export default class ImageModel extends BaseModel { private texture: ITexture2D; - protected getConfigSchema() { + + public getUninforms() { + const { opacity } = this.layer.getStyleOptions() as IPointLayerStyleOptions; return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, + u_opacity: opacity || 1.0, + u_texture: this.texture, + u_textSize: [1024, this.iconService.canvasHeight || 128], }; } - protected renderModels() { - const { opacity } = this.getStyleOptions(); - const { createTexture2D } = this.rendererService; - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity || 1.0, - u_texture: this.texture, - u_textSize: [1024, this.iconService.canvasHeight || 128], - }, - }), - ); - - return this; - } - - protected buildModels() { - this.registerBuiltinAttributes(this); + public buildModels(): IModel[] { + this.registerBuiltinAttributes(); this.updateTexture(); this.iconService.on('imageUpdate', () => { this.updateTexture(); - this.renderModels(); + this.layer.render(); // TODO 调用全局render }); - this.models = [ - this.buildLayerModel({ + return [ + this.layer.buildLayerModel({ moduleName: 'pointImage', vertexShader: pointImageVert, fragmentShader: pointImageFrag, - triangulation: PointTriangulation, + triangulation: PointImageTriangulation, primitive: gl.POINTS, depth: { enable: false }, blend: { @@ -85,9 +56,9 @@ export default class PointLayer extends BaseLayer { ]; } - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { @@ -112,7 +83,7 @@ export default class PointLayer extends BaseLayer { }); // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { @@ -139,6 +110,7 @@ export default class PointLayer extends BaseLayer { }, }); } + private updateTexture() { const { createTexture2D } = this.rendererService; this.texture = createTexture2D({ diff --git a/packages/layers/src/point/models/index.ts b/packages/layers/src/point/models/index.ts new file mode 100644 index 0000000000..8dd5b347a6 --- /dev/null +++ b/packages/layers/src/point/models/index.ts @@ -0,0 +1,17 @@ +import { ILayerModel } from '@l7/core'; +import ExtrudeModel from './extrude'; +import FillModel from './fill'; +import IMageModel from './image'; +import NormalModel from './normal'; + +export type PointType = 'fill' | 'image' | 'normal' | 'extrude' | 'text'; + +const PointModels: { [key in PointType]: any } = { + fill: FillModel, + image: IMageModel, + normal: NormalModel, + extrude: ExtrudeModel, + text: null, +}; + +export default PointModels; diff --git a/packages/layers/src/point/normal.ts b/packages/layers/src/point/models/normal.ts similarity index 58% rename from packages/layers/src/point/normal.ts rename to packages/layers/src/point/models/normal.ts index 85c725619b..1d4dd89172 100644 --- a/packages/layers/src/point/normal.ts +++ b/packages/layers/src/point/models/normal.ts @@ -3,16 +3,15 @@ import { gl, IEncodeFeature, ILayer, - ILayerPlugin, - ILogService, - IStyleAttributeService, - lazyInject, - TYPES, + ILayerModel, + IModel, } from '@l7/core'; -import BaseLayer from '../core/BaseLayer'; -import { rgb2arr } from '../utils/color'; -import normalFrag from './shaders/normal_frag.glsl'; -import normalVert from './shaders/normal_vert.glsl'; + +import BaseModel from '../../core/baseModel'; +import { rgb2arr } from '../../utils/color'; +import normalFrag from '../shaders/normal_frag.glsl'; +import normalVert from '../shaders/normal_vert.glsl'; + interface IPointLayerStyleOptions { opacity: number; strokeWidth: number; @@ -26,45 +25,24 @@ export function PointTriangulation(feature: IEncodeFeature) { size: coordinates.length, }; } -export default class PointNormalLayer extends BaseLayer< - IPointLayerStyleOptions -> { - public name: string = 'PointLayer'; - protected getConfigSchema() { - return { - properties: { - opacity: { - type: 'number', - minimum: 0, - maximum: 1, - }, - }, - }; - } - - protected renderModels() { +export default class NormalModel extends BaseModel { + public getUninforms() { const { opacity = 1, strokeColor = 'rgb(0,0,0,0)', strokeWidth = 1, - } = this.getStyleOptions(); - this.models.forEach((model) => - model.draw({ - uniforms: { - u_opacity: opacity, - u_stroke_width: strokeWidth, - u_stroke_color: rgb2arr(strokeColor), - }, - }), - ); - return this; + } = this.layer.getStyleOptions() as IPointLayerStyleOptions; + return { + u_opacity: opacity, + u_stroke_width: strokeWidth, + u_stroke_color: rgb2arr(strokeColor), + }; } - protected buildModels() { - this.registerBuiltinAttributes(this); - this.models = [ - this.buildLayerModel({ + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ moduleName: 'normalpoint', vertexShader: normalVert, fragmentShader: normalFrag, @@ -84,9 +62,9 @@ export default class PointNormalLayer extends BaseLayer< ]; } - private registerBuiltinAttributes(layer: ILayer) { + protected registerBuiltinAttributes() { // point layer size; - layer.styleAttributeService.registerStyleAttribute({ + this.layer.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { diff --git a/packages/layers/src/point/models/text.ts b/packages/layers/src/point/models/text.ts new file mode 100644 index 0000000000..202557d9e5 --- /dev/null +++ b/packages/layers/src/point/models/text.ts @@ -0,0 +1,30 @@ +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + IModel, +} from '@l7/core'; +import BaseLayer from '../core/BaseLayer'; +import { PointExtrudeTriangulation } from '../core/triangulation'; +import pointExtrudeFrag from './shaders/extrude_frag.glsl'; +import pointExtrudeVert from './shaders/extrude_vert.glsl'; + +export default class ExtrudeModel implements ILayerModel { + private layer: ILayer; + constructor(layer: ILayer) { + this.layer = layer; + this.registerBuiltinAttributes(); + } + public getUninforms() { + throw new Error('Method not implemented.'); + } + + public buildModels(): IModel[] { + throw new Error('Method not implemented.'); + } + private registerBuiltinAttributes() { + throw new Error('Method not implemented.'); + } +} diff --git a/packages/layers/src/polygon/index.ts b/packages/layers/src/polygon/index.ts index 715caf4cf2..52e663069b 100644 --- a/packages/layers/src/polygon/index.ts +++ b/packages/layers/src/polygon/index.ts @@ -1,25 +1,11 @@ import { IEncodeFeature } from '@l7/core'; -import earcut from 'earcut'; import BaseLayer from '../core/BaseLayer'; -import polygon_frag from './shaders/polygon_frag.glsl'; -import polygon_vert from './shaders/polygon_vert.glsl'; +import PolygonModels, { PolygonModelType } from './models/'; interface IPolygonLayerStyleOptions { opacity: number; } -export function polygonTriangulation(feature: IEncodeFeature) { - const { coordinates } = feature; - const flattengeo = earcut.flatten(coordinates as number[][][]); - const { vertices, dimensions, holes } = flattengeo; - - return { - indices: earcut(vertices, holes, dimensions), - vertices, - size: dimensions, - }; -} - export default class PolygonLayer extends BaseLayer { public name: string = 'PolygonLayer'; @@ -36,26 +22,25 @@ export default class PolygonLayer extends BaseLayer { } protected renderModels() { - const { opacity } = this.getStyleOptions(); this.models.forEach((model) => model.draw({ - uniforms: { - u_opacity: opacity || 1.0, - }, + uniforms: this.layerModel.getUninforms(), }), ); return this; } protected buildModels() { - this.models = [ - this.buildLayerModel({ - moduleName: 'polygon', - vertexShader: polygon_vert, - fragmentShader: polygon_frag, - triangulation: polygonTriangulation, - depth: { enable: false }, - }), - ]; + const shape = this.getModelType(); + this.layerModel = new PolygonModels[shape](this); + this.models = this.layerModel.buildModels(); + } + + private getModelType(): PolygonModelType { + const shapeAttribute = this.styleAttributeService.getLayerStyleAttribute( + 'shape', + ); + const shape = shapeAttribute?.scale?.field as PolygonModelType; + return shape || 'fill'; } } diff --git a/packages/layers/src/polygon/models/extrude.ts b/packages/layers/src/polygon/models/extrude.ts new file mode 100644 index 0000000000..ac4dafc960 --- /dev/null +++ b/packages/layers/src/polygon/models/extrude.ts @@ -0,0 +1,92 @@ +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + ILayerPlugin, + ILogService, + IModel, + IStyleAttributeService, + lazyInject, + TYPES, +} from '@l7/core'; +import BaseModel from '../../core/baseModel'; +import { PolygonExtrudeTriangulation } from '../../core/triangulation'; +import polygonExtrudeFrag from '../shaders/polygon_extrude_frag.glsl'; +import polygonExtrudeVert from '../shaders/polygon_extrude_vert.glsl'; +interface IPolygonLayerStyleOptions { + opacity: number; +} +export default class ExtrudeModel extends BaseModel { + public getUninforms() { + const { + opacity = 1, + } = this.layer.getStyleOptions() as IPolygonLayerStyleOptions; + return { + u_opacity: opacity, + }; + } + + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ + moduleName: 'polygonExtrude', + vertexShader: polygonExtrudeVert, + fragmentShader: polygonExtrudeFrag, + triangulation: PolygonExtrudeTriangulation, + }), + ]; + } + + protected registerBuiltinAttributes() { + // point layer size; + this.layer.styleAttributeService.registerStyleAttribute({ + name: 'normal', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Normal', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 3, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + normal: number[], + ) => { + return normal; + }, + }, + }); + + this.layer.styleAttributeService.registerStyleAttribute({ + name: 'size', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Size', + buffer: { + // give the WebGL driver a hint that this buffer may change + usage: gl.DYNAMIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 1, + update: ( + feature: IEncodeFeature, + featureIdx: number, + vertex: number[], + attributeIdx: number, + ) => { + const { size } = feature; + return Array.isArray(size) ? [size[0]] : [size as number]; + }, + }, + }); + } +} diff --git a/packages/layers/src/polygon/models/fill.ts b/packages/layers/src/polygon/models/fill.ts new file mode 100644 index 0000000000..26c88f60aa --- /dev/null +++ b/packages/layers/src/polygon/models/fill.ts @@ -0,0 +1,47 @@ +import { + AttributeType, + gl, + IEncodeFeature, + ILayer, + ILayerModel, + ILayerPlugin, + ILogService, + IModel, + IStyleAttributeService, + lazyInject, + TYPES, +} from '@l7/core'; +import BaseModel from '../../core/baseModel'; +import { polygonTriangulation } from '../../core/triangulation'; +import polygon_frag from '../shaders/polygon_frag.glsl'; +import polygon_vert from '../shaders/polygon_vert.glsl'; + +interface IPolygonLayerStyleOptions { + opacity: number; +} +export default class FillModel extends BaseModel { + public getUninforms() { + const { + opacity = 1, + } = this.layer.getStyleOptions() as IPolygonLayerStyleOptions; + return { + u_opacity: opacity, + }; + } + + public buildModels(): IModel[] { + return [ + this.layer.buildLayerModel({ + moduleName: 'polygon', + vertexShader: polygon_vert, + fragmentShader: polygon_frag, + triangulation: polygonTriangulation, + depth: { enable: false }, + }), + ]; + } + + protected registerBuiltinAttributes() { + // point layer size; + } +} diff --git a/packages/layers/src/polygon/models/index.ts b/packages/layers/src/polygon/models/index.ts new file mode 100644 index 0000000000..cf0495ccca --- /dev/null +++ b/packages/layers/src/polygon/models/index.ts @@ -0,0 +1,11 @@ +import ExtrudeModel from './extrude'; +import FillModel from './fill'; + +export type PolygonModelType = 'fill' | 'extrude'; + +const PolygonModels: { [key in PolygonModelType]: any } = { + fill: FillModel, + extrude: ExtrudeModel, +}; + +export default PolygonModels; diff --git a/packages/layers/src/polygon/polygon3D.ts b/packages/layers/src/polygon/polygon3D.ts index afdb5d86ed..a320d45145 100644 --- a/packages/layers/src/polygon/polygon3D.ts +++ b/packages/layers/src/polygon/polygon3D.ts @@ -1,8 +1,8 @@ import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core'; import BaseLayer from '../core/BaseLayer'; import { PolygonExtrudeTriangulation } from '../core/triangulation'; -import pointExtrudeFrag from './shaders/polygon_extrude_frag.glsl'; -import pointExtrudeVert from './shaders/polygon_extrude_vert.glsl'; +import polygonExtrudeFrag from './shaders/polygon_extrude_frag.glsl'; +import polygonExtrudeVert from './shaders/polygon_extrude_vert.glsl'; interface IPointLayerStyleOptions { opacity: number; } @@ -38,8 +38,8 @@ export default class PolygonLayer extends BaseLayer { this.models = [ this.buildLayerModel({ moduleName: 'polygonExtrude', - vertexShader: pointExtrudeVert, - fragmentShader: pointExtrudeFrag, + vertexShader: polygonExtrudeVert, + fragmentShader: polygonExtrudeFrag, triangulation: PolygonExtrudeTriangulation, }), ];