diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000000..196f07b8e7
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,5 @@
+# don't ever lint node_modules
+node_modules
+# don't lint build output (make sure it's set to your correct build folder name)
+dist
+
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index 83444bc2cb..febd5ba076 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -21,8 +21,11 @@ addParameters({
});
// automatically import all files ending in *.stories.tsx
+
// const req = require.context('../stories', true, /\.stories\.tsx$/);
-const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
+const req = require.context('../stories/layerbuild', true, /\.stories\.tsx$/);
+// const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
+// const req = require.context('../stories/MapPerformance', true, /\.stories\.tsx$/);
// const req = require.context('../stories/tile', true, /\.stories\.tsx$/);
function loadStories() {
diff --git a/babel.config.js b/babel.config.js
index 411f735e9e..2216dec9ed 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,12 +1,12 @@
// @see https://babeljs.io/docs/en/next/config-files#project-wide-configuration
-module.exports = api => {
+module.exports = (api) => {
api.cache(() => process.env.NODE_ENV);
const isSite = api.env('site');
const isCDNBundle = api.env('bundle');
const isCommonJS = api.env('cjs');
const isESModule = api.env('esm');
const isTest = api.env('test');
-
+
if (isSite) {
return {
presets: [
@@ -14,8 +14,8 @@ module.exports = api => {
[
'@babel/preset-react',
{
- development: isCommonJS
- }
+ development: isCommonJS,
+ },
],
// 'babel-preset-gatsby', {
// silence: true
@@ -28,8 +28,8 @@ module.exports = api => {
[
'@babel/plugin-proposal-decorators',
{
- legacy: true
- }
+ legacy: true,
+ },
],
[
// import glsl as raw text
@@ -38,11 +38,11 @@ module.exports = api => {
extensions: [
// 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本
'.pbf',
- '.glsl'
- ]
- }
- ]
- ]
+ '.glsl',
+ ],
+ },
+ ],
+ ],
};
}
@@ -53,24 +53,24 @@ module.exports = api => {
{
// https://babeljs.io/docs/en/babel-preset-env#usebuiltins
// useBuiltIns: 'usage',
- ...isCDNBundle ? { corejs: 3 } : {},
+ ...(isCDNBundle ? { corejs: 3 } : {}),
useBuiltIns: isCDNBundle ? 'usage' : false,
// set `modules: false` when building CDN bundle, let rollup do commonjs works
// @see https://github.com/rollup/rollup-plugin-babel#modules
- modules: (isCDNBundle || isESModule) ? false : 'auto',
+ modules: isCDNBundle || isESModule ? false : 'auto',
targets: {
chrome: 58,
- browsers: [ 'ie >= 11' ]
- }
- }
+ browsers: ['ie >= 11'],
+ },
+ },
],
[
'@babel/preset-react',
{
- development: isCommonJS
- }
+ development: isCommonJS,
+ },
],
- '@babel/preset-typescript'
+ '@babel/preset-typescript',
],
plugins: [
isCDNBundle ? {} : '@babel/plugin-transform-runtime',
@@ -83,61 +83,70 @@ module.exports = api => {
[
'@babel/plugin-proposal-decorators',
{
- legacy: true
- }
+ legacy: true,
+ },
],
[
'@babel/plugin-proposal-class-properties',
{
// @see https://github.com/storybookjs/storybook/issues/6069#issuecomment-472544973
- loose: false
- }
+ loose: false,
+ },
],
'@babel/plugin-syntax-dynamic-import',
// let rollup do commonjs works
// @see https://github.com/rollup/rollup-plugin-babel#modules
- (isCDNBundle || isESModule) ? {} : '@babel/plugin-transform-modules-commonjs',
+ isCDNBundle || isESModule
+ ? {}
+ : '@babel/plugin-transform-modules-commonjs',
// 开发模式下以原始文本引入,便于调试
- isCDNBundle ? {} : [
- // import glsl as raw text
- 'babel-plugin-inline-import',
- {
- extensions: [
- // 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本
- // '.json',
- '.glsl'
- ]
- }
- ],
- isCDNBundle ? {} : [
- 'transform-import-css-l7'
- // 'transform-import-styles' // babel 编译将样式打包到js
- ],
+ isCDNBundle
+ ? {}
+ : [
+ // import glsl as raw text
+ 'babel-plugin-inline-import',
+ {
+ extensions: [
+ // 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本
+ // '.json',
+ '.glsl',
+ '.worker.js',
+ ],
+ },
+ ],
+ isCDNBundle
+ ? {}
+ : [
+ 'transform-import-css-l7',
+ // 'transform-import-styles' // babel 编译将样式打包到js
+ ],
[
// @see https://github.com/babel/babel/issues/8741#issuecomment-509041135
'const-enum',
{
- transform: 'constObject'
- }
+ transform: 'constObject',
+ },
],
// 按需引用 @see https://github.com/lodash/babel-plugin-lodash
- 'lodash'
+ 'lodash',
// 内联 WebGL 常量 @see https://www.npmjs.com/package/babel-plugin-inline-webgl-constants
// isCDNBundle ? 'inline-webgl-constants' : {},
],
ignore: [
// /node_modules\/(?![kdbush|supercluster|async])/,
'node_modules',
- ...!isTest ? [
- '**/*.test.tsx',
- '**/*.test.ts',
- '**/*.story.tsx',
- '__snapshots__',
- '__tests__',
- '__stories__',
- '**/*/__snapshots__',
- '**/*/__tests__'
- ] : []
- ]
+ ...(!isTest
+ ? [
+ '**/*.test.tsx',
+ '**/*.test.ts',
+ '**/*.story.tsx',
+ '__snapshots__',
+ '__tests__',
+ '__stories__',
+ '**/*/__snapshots__',
+ '**/*/__tests__',
+ ]
+ : []),
+ ],
};
};
diff --git a/build/rollup-plugin-inline-worker.js b/build/rollup-plugin-inline-worker.js
new file mode 100644
index 0000000000..dc6b152620
--- /dev/null
+++ b/build/rollup-plugin-inline-worker.js
@@ -0,0 +1,16 @@
+import { createFilter } from 'rollup-pluginutils';
+
+export default function inlineWorker(include) {
+ const filter = createFilter(include);
+ return {
+ name: 'inline-worker',
+ transform(code, id) {
+ if (!filter(id)) return;
+
+ return {
+ code: `export default ${JSON.stringify(code)};`,
+ map: { mappings: '' },
+ };
+ },
+ };
+}
diff --git a/build/rollup.config.js b/build/rollup.config.js
index 6c164e5d3b..1a88ea3554 100644
--- a/build/rollup.config.js
+++ b/build/rollup.config.js
@@ -7,19 +7,18 @@ import { terser } from 'rollup-plugin-terser';
import analyze from 'rollup-plugin-analyzer';
import babel from 'rollup-plugin-babel';
import glsl from './rollup-plugin-glsl';
+import inlineWorker from './rollup-plugin-inline-worker';
import postcss from 'rollup-plugin-postcss';
import url from 'postcss-url';
-
const { BUILD, MINIFY } = process.env;
const minified = MINIFY === 'true';
const production = BUILD === 'production';
const outputFile = !production
? 'packages/l7/dist/l7-dev.js'
: minified
- ? 'packages/l7/dist/l7.js'
- : 'packages/l7/dist/l7-dev.js';
-
+ ? 'packages/l7/dist/l7.js'
+ : 'packages/l7/dist/l7-dev.js';
function resolveFile(filePath) {
return path.join(__dirname, '..', filePath);
@@ -33,49 +32,41 @@ module.exports = [
format: 'umd',
name: 'L7',
globals: {
- 'mapbox-gl': 'mapboxgl'
- }
+ 'mapbox-gl': 'mapboxgl',
+ },
},
- external: [
- 'mapbox-gl'
- ],
+ external: ['mapbox-gl'],
treeshake: minified,
plugins: [
- alias(
- {
- resolve: [ '.tsx', '.ts' ],
- entries: [
- {
- find: /^@antv\/l7-(.*)/,
- replacement: resolveFile('packages/$1/src')
- },
- {
- find: /^@antv\/l7$/,
- replacement: resolveFile('packages/l7/src')
- }
- ]
- }
- ),
+ alias({
+ resolve: ['.tsx', '.ts'],
+ entries: [
+ {
+ find: /^@antv\/l7-(.*)/,
+ replacement: resolveFile('packages/$1/src'),
+ },
+ {
+ find: /^@antv\/l7$/,
+ replacement: resolveFile('packages/l7/src'),
+ },
+ ],
+ }),
resolve({
browser: true,
preferBuiltins: false,
- extensions: [ '.js', '.ts' ]
+ extensions: ['.js', '.ts'],
}),
- glsl(
- [ '**/*.glsl' ],
- true
- ),
+ glsl(['**/*.glsl'], true),
+ inlineWorker(['**/*.worker.js']),
json(),
postcss({
extract: false,
- plugins: [
- url({ url: 'inline' })
- ]
+ plugins: [url({ url: 'inline' })],
}),
// @see https://github.com/rollup/rollup-plugin-node-resolve#using-with-rollup-plugin-commonjs
commonjs({
namedExports: {
- eventemitter3: [ 'EventEmitter' ],
+ eventemitter3: ['EventEmitter'],
// inversify: [ 'inject', 'injectable', 'postConstruct', 'Container', 'decorate', 'interfaces' ],
// @see https://github.com/rollup/rollup-plugin-commonjs/issues/266
lodash: [
@@ -87,22 +78,22 @@ module.exports = [
'cloneDeep',
'isString',
'isNumber',
- 'merge'
- ]
+ 'merge',
+ ],
},
dynamicRequireTargets: [
- 'node_modules/inversify/lib/syntax/binding_{on,when}_syntax.js'
- ]
+ 'node_modules/inversify/lib/syntax/binding_{on,when}_syntax.js',
+ ],
}),
babel({
- extensions: [ '.js', '.ts' ]
+ extensions: ['.js', '.ts'],
}),
// terser(),
minified ? terser() : false,
analyze({
summaryOnly: true,
- limit: 20
- })
- ]
- }
+ limit: 20,
+ }),
+ ],
+ },
];
diff --git a/build/rollup.config.worker.js b/build/rollup.config.worker.js
new file mode 100644
index 0000000000..c2ccf59313
--- /dev/null
+++ b/build/rollup.config.worker.js
@@ -0,0 +1,64 @@
+import path from 'path';
+import alias from '@rollup/plugin-alias';
+import json from '@rollup/plugin-json';
+import resolve from '@rollup/plugin-node-resolve';
+import commonjs from '@rollup/plugin-commonjs';
+import { terser } from 'rollup-plugin-terser';
+// import analyze from 'rollup-plugin-analyzer';
+import babel from 'rollup-plugin-babel';
+
+const { BUILD } = process.env;
+const production = BUILD === 'production';
+const outputFile = production
+ ? 'packages/utils/dist/l7-utils.worker.js'
+ : 'packages/utils/dist/l7-utils.worker.js';
+function resolveFile(filePath) {
+ return path.join(__dirname, '..', filePath);
+}
+
+module.exports = [
+ {
+ input: resolveFile('packages/utils/src/workers/index.ts'),
+ output: {
+ file: resolveFile(outputFile),
+ format: 'iife',
+ name: 'L7',
+ },
+ context: 'self',
+ treeshake: true,
+ plugins: [
+ alias({
+ resolve: ['.tsx', '.ts'],
+ entries: [
+ {
+ find: /^@antv\/l7-(.*)\/src\/(.*)/,
+ replacement: resolveFile('packages/$1/src/$2'),
+ },
+ {
+ find: /^@antv\/l7-(.*)/,
+ replacement: resolveFile('packages/$1/src'),
+ },
+ {
+ find: /^@antv\/l7$/,
+ replacement: resolveFile('packages/l7/src'),
+ },
+ ],
+ }),
+ resolve({
+ browser: true,
+ preferBuiltins: false,
+ extensions: ['.js', '.ts'],
+ }),
+ json(),
+ commonjs(),
+ babel({
+ extensions: ['.js', '.ts'],
+ }),
+ production ? terser() : false,
+ // analyze({
+ // summaryOnly: true,
+ // limit: 20,
+ // }),
+ ],
+ },
+];
diff --git a/demos/tutorial/control/demo/meta.json b/demos/tutorial/control/demo/meta.json
index d921629ac5..f4615691cd 100644
--- a/demos/tutorial/control/demo/meta.json
+++ b/demos/tutorial/control/demo/meta.json
@@ -6,7 +6,7 @@
"demos": [
{
"filename": "amap.js",
- "title": "高德底图组件",
+ "title": "高德底图组件"
},
{
"filename": "mapbox.js",
diff --git a/examples/engine/three/demo/space_click.js b/examples/engine/three/demo/space_click.js
index 94a61bc858..7e0194867b 100644
--- a/examples/engine/three/demo/space_click.js
+++ b/examples/engine/three/demo/space_click.js
@@ -334,7 +334,7 @@ scene.on('loaded', () => {
.animate(true);
scene.addLayer(threeJSLayer);
// @ts-ignore
- let currentCamera = threeJSLayer.threeRenderService.getRenderCamera();
+ let currentCamera = threeJSLayer.threeRenderService?.getRenderCamera();
const currentView = {
lng: center.lng,
lat: center.lat,
diff --git a/examples/gallery/animate/demo/plane_animate.js b/examples/gallery/animate/demo/plane_animate.js
index 2cfaeccdd0..d12ac80b5e 100644
--- a/examples/gallery/animate/demo/plane_animate.js
+++ b/examples/gallery/animate/demo/plane_animate.js
@@ -93,18 +93,7 @@ scene.on('loaded', () => {
});
const flyLine = new LineLayer({
blend: 'additive',
- zIndex: 2,
- enableMultiPassRenderer: true,
- passes: [
- [
- 'bloom',
- {
- bloomBaseRadio: 0.8,
- bloomRadius: 2,
- bloomIntensity: 1
- }
- ]
- ]
+ zIndex: 2
})
.source(flydata, {
parser: {
diff --git a/examples/gallery/animate/demo/timeline.js b/examples/gallery/animate/demo/timeline.js
index 6c61b6a962..785313a403 100644
--- a/examples/gallery/animate/demo/timeline.js
+++ b/examples/gallery/animate/demo/timeline.js
@@ -1,7 +1,8 @@
import { Scene, PointLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
-let currentTimeKey = '0000';
+const currentTimeKey = '0000';
let timeKeys = [];
+let wrap = null;
let layer = null;
const modelDatas = {};
const parser = {
@@ -21,7 +22,6 @@ const scene = new Scene({
})
});
scene.on('loaded', () => {
- setDragBar();
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/82d85bb6-db7c-4583-af26-35b11c7b2d0d.json'
@@ -48,12 +48,36 @@ scene.on('loaded', () => {
scene.addLayer(layer);
- getModelDatas(originData);
+ layer.on('modelLoaded', () => {
+ getModelDatas(originData);
+
+ run();
+ });
+
return '';
});
return '';
});
+function run() {
+ let count = 0;
+ const timer = setInterval(() => {
+ if (count > 47) {
+ clearInterval(timer);
+ }
+
+ const key = getTimeKey(count, '');
+ const key2 = getTimeKey(count, ':');
+ const data = modelDatas[key];
+ if (layer && scene && data) {
+ layer.updateModelData(data);
+ wrap.innerHTML = key2;
+ scene.render();
+ }
+
+ count++;
+ }, 300);
+}
function getModelDatas(originData) {
timeKeys.map(timeKey => {
@@ -62,103 +86,18 @@ function getModelDatas(originData) {
});
}
-function updateTime() {
- if (layer && scene) {
- layer.updateModelData(modelDatas[currentTimeKey]);
- scene.render();
- }
-}
-
-function setDragBar() {
- const script = document.createElement('script');
- script.setAttribute('type', 'text/javascript');
- script.setAttribute('src', 'https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js');
- script.async = true;
- document.head.appendChild(script);
-
- script.onload = () => {
- const bar = document.getElementById('progress');
- const barWidth = bar.getBoundingClientRect().width;
- let tag = false,
- ox = 0,
- left = 0,
- bgleft = 0;
- const $ = window.$;
- $('.progress_btn').mousedown(function(e) {
- ox = e.pageX - left;
- tag = true;
- });
-
- $(document).mouseup(function() { tag = false; });
-
- $(document).mousemove(function(e) { // 鼠标移动
- if (tag) {
- left = e.pageX - ox;
- currentTimeKey = setText(left, barWidth);
- updateTime();
- }
- });
-
- $('.progress_bg').click(function(e) { // 鼠标点击
- if (!tag) {
- bgleft = $('.progress_bg').offset().left;
- left = e.pageX - bgleft;
- currentTimeKey = setText(left, barWidth);
- updateTime();
- }
- });
- return '';
- };
-
-
- function setText(left, barWidth) {
-
- if (left <= 0) {
- left = 0;
- } else if (left > barWidth) {
- left = barWidth;
- }
- const $ = window.$;
- $('.progress_btn').css('left', left);
-
- const time = parseInt((left / barWidth) * 48);
- const timeText = getTimeKey(time, ':');
- const timeKey = getTimeKey(time, '');
- $('.text').html(timeText);
- return timeKey;
- }
-}
function insetDom() {
const mapContrainer = document.getElementById('map');
- const wrap = document.createElement('div');
- wrap.id = 'progress';
+ wrap = document.createElement('div');
wrap.style.zIndex = 10;
wrap.style.position = 'absolute';
- wrap.style.bottom = '50px';
- wrap.style.left = '10%';
- wrap.style.right = '10%';
- wrap.innerHTML = `
-
-
-
- `;
+ wrap.style.top = '50px';
+ wrap.style.left = '5%';
+ wrap.style.right = '5%';
+ wrap.style.color = '#fff';
+ wrap.style.fontSize = '18px';
+ wrap.innerHTML = '00:00';
mapContrainer.appendChild(wrap);
}
diff --git a/examples/line/isoline/demo/ele_dark.js b/examples/line/isoline/demo/ele_dark.js
index a4dd683548..72d9e73463 100644
--- a/examples/line/isoline/demo/ele_dark.js
+++ b/examples/line/isoline/demo/ele_dark.js
@@ -17,17 +17,6 @@ scene.on('loaded', () => {
.then(res => res.json())
.then(data => {
const layer = new LineLayer({
- enableMultiPassRenderer: true,
- passes: [
- [
- 'bloom',
- {
- bloomBaseRadio: 0.8,
- bloomRadius: 2,
- bloomIntensity: 1
- }
- ]
- ]
})
.source(data)
.size('ELEV', h => {
diff --git a/examples/polygon/fill/demo/usa.js b/examples/polygon/fill/demo/usa.js
index dbb3f92f77..79b24eea6d 100644
--- a/examples/polygon/fill/demo/usa.js
+++ b/examples/polygon/fill/demo/usa.js
@@ -20,7 +20,7 @@ scene.on('loaded', () => {
const layer = new PolygonLayer({})
.source(data)
.scale('density', {
- type: 'quantize'
+ type: 'quantile'
})
.color(
'density', color
diff --git a/examples/tile/vector/demo/line.js b/examples/tile/vector/demo/line.js
index d63950f9ca..99724f6bdc 100644
--- a/examples/tile/vector/demo/line.js
+++ b/examples/tile/vector/demo/line.js
@@ -23,7 +23,8 @@ scene.on('loaded', () => {
type: 'mvt',
tileSize: 256,
zoomOffset: 0,
- maxZoom: 9
+ maxZoom: 9,
+ extent: [ -180, -85.051129, 179, 85.051129 ]
}
}
)
diff --git a/examples/tile/vector/demo/point.js b/examples/tile/vector/demo/point.js
index ff4c1a32d5..cd1872f617 100644
--- a/examples/tile/vector/demo/point.js
+++ b/examples/tile/vector/demo/point.js
@@ -23,7 +23,8 @@ scene.on('loaded', () => {
type: 'mvt',
tileSize: 256,
zoomOffset: 0,
- maxZoom: 9
+ maxZoom: 9,
+ extent: [ -180, -85.051129, 179, 85.051129 ]
}
}
)
diff --git a/examples/tile/vector/demo/polygon.js b/examples/tile/vector/demo/polygon.js
index 735044dbd0..fe8dec0cfd 100644
--- a/examples/tile/vector/demo/polygon.js
+++ b/examples/tile/vector/demo/polygon.js
@@ -23,7 +23,8 @@ scene.on('loaded', () => {
type: 'mvt',
tileSize: 256,
zoomOffset: 0,
- maxZoom: 9
+ maxZoom: 9,
+ extent: [ -180, -85.051129, 179, 85.051129 ]
}
}
)
diff --git a/package.json b/package.json
index e61408d4db..d538e58c08 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"@antv/l7-district": "^2.3.9",
"@antv/l7-draw": "2.4.18",
"@antv/l7-react": "^2.3.3",
- "@antv/l7plot": "^0.0.4",
+ "@antv/l7plot": "^0.1.0",
"@babel/cli": "^7.6.4",
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-decorators": "^7.6.0",
@@ -87,10 +87,10 @@
"glsl-minifier": "^0.0.13",
"html-webpack-plugin": "^4.3.0",
"husky": "^3.0.9",
- "lerc": "^3.0.0",
"jest": "^24.9.0",
"jest-electron": "^0.1.11",
"jest-styled-components": "^6.2.1",
+ "lerc": "^3.0.0",
"lerna": "^3.16.4",
"lint-staged": "^9.2.4",
"mockjs": "^1.1.0",
@@ -148,9 +148,9 @@
"site:publish": "gh-pages -d public",
"storybook": "start-storybook -p 6006",
"prebuild": "run-p tsc lint",
- "build": "yarn clean && lerna run build",
+ "build": "yarn clean && yarn worker && lerna run build",
"postbuild": "yarn build:declarations",
- "build:declarations": "lerna exec --stream --no-bail 'tsc --project ./tsconfig.build.json'",
+ "build:declarations": "lerna run tsc --stream --no-bail",
"fix": "run-p -c 'lint:ts-* --fix'",
"lint:fix": "prettier --write docs/api/**/*.md docs/api/*.md stories/**/**/*.tsx *.md",
"lint:examples": "eslint examples --fix --ext .js",
@@ -163,20 +163,22 @@
"version": "lerna version --force-publish --conventional-commits --exact --no-changelog",
"version:prerelease": "lerna version --force-publish --exact --conventional-prerelease",
"prerelease": "yarn build && yarn bundle",
- "release-beta": "yarn run prerelease && lerna publish --dist-tag beta from-package --force-publish && lerna run sync",
- "release": "lerna publish from-package --force-publish && lerna run sync",
+ "release-beta": "yarn run prerelease && lerna publish --dist-tag beta from-package --force-publish && yarn sync",
+ "release": "lerna publish from-package --force-publish && yarn sync",
"release-cdn": "antv-bin upload -n @antv/l7",
"test": "cross-env BABEL_ENV=test jest",
"test-live": "cross-env BABEL_ENV=test DEBUG_MODE=1 jest --watch",
"coveralls": "jest --coverage && cat ./tests/coverage/lcov.info | coveralls",
"tsc": "tsc",
- "watch": "yarn clean && lerna exec --parallel -- cross-env BABEL_ENV=cjs NODE_ENV=production babel --watch src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "bundle": "cross-env BABEL_ENV=bundle NODE_ENV=production yarn rollup -c build/rollup.config.js --environment BUILD:production,MINIFY:true",
- "bundle-dev": "cross-env BABEL_ENV=bundle yarn rollup -c build/rollup.config.js --environment BUILD:production,MINIFY:false",
+ "watch": "yarn clean && yarn worker && lerna run watch --parallel",
+ "bundle": "yarn worker && cross-env BABEL_ENV=bundle NODE_ENV=production yarn rollup -c build/rollup.config.js --environment BUILD:production,MINIFY:true",
+ "bundle-dev": "yarn worker && cross-env BABEL_ENV=bundle yarn rollup -c build/rollup.config.js --environment BUILD:production,MINIFY:false",
"bundle:watch": "cross-env BABEL_ENV=bundle yarn rollup -c build/rollup.config.js --watch",
"glsl-minify": "yarn glsl-minifier -i build/example.frag -o build/example.min.frag",
- "clean": "lerna run clean",
- "sync": "lerna run sync"
+ "worker": "cross-env BABEL_ENV=bundle NODE_ENV=production yarn rollup -c build/rollup.config.worker.js --environment BUILD:production",
+ "worker:watch": "cross-env BABEL_ENV=bundle NODE_ENV=production yarn rollup -c build/rollup.config.worker.js --environment BUILD:development --watch",
+ "clean": "lerna run clean --parallel",
+ "sync": "lerna run sync --parallel"
},
"workspaces": [
"packages/*",
@@ -207,5 +209,6 @@
},
"tnpm": {
"mode": "yarn"
- }
+ },
+ "dependencies": {}
}
diff --git a/packages/component/package.json b/packages/component/package.json
index 1dc47bb476..b7036892d8 100644
--- a/packages/component/package.json
+++ b/packages/component/package.json
@@ -15,9 +15,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"lint:ts": "run-p -c lint:ts-*",
"test": "jest",
"sync": "tnpm sync"
diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts
index 92b65f91ed..0ec72fdeac 100644
--- a/packages/core/src/services/layer/ILayerService.ts
+++ b/packages/core/src/services/layer/ILayerService.ts
@@ -59,12 +59,19 @@ export interface IDataState {
featureScaleNeedUpdate: boolean;
StyleAttrNeedUpdate: boolean;
}
+
+export interface IWorkerOption {
+ modelType: string;
+ [key: string]: any;
+}
export interface ILayerModelInitializationOptions {
moduleName: string;
vertexShader: string;
fragmentShader: string;
triangulation: Triangulation;
segmentNumber?: number;
+ workerEnabled?: boolean;
+ workerOptions?: IWorkerOption;
}
export interface ILayerModel {
@@ -73,8 +80,8 @@ export interface ILayerModel {
getUninforms(): IModelUniform;
getDefaultStyle(): unknown;
getAnimateUniforms(): IModelUniform;
- buildModels(): IModel[];
- initModels(): IModel[];
+ buildModels(callbackModel: (models: IModel[]) => void): void;
+ initModels(callbackModel: (models: IModel[]) => void): void;
needUpdate(): boolean;
clearModels(): void;
@@ -161,6 +168,8 @@ export interface ISubLayerInitOptions {
coords?: string;
sourceLayer?: string;
featureId?: string;
+
+ workerEnabled?: boolean;
}
export interface ITilePickManager {
@@ -281,6 +290,7 @@ export interface ILayer {
layerType?: string | undefined;
isVector?: boolean;
triangulation?: Triangulation | undefined;
+
/**
* threejs 适配兼容相关的方法
* @param lnglat
@@ -314,7 +324,7 @@ export interface ILayer {
buildLayerModel(
options: ILayerModelInitializationOptions &
Partial,
- ): IModel;
+ ): Promise;
createAttrubutes(
options: ILayerModelInitializationOptions &
Partial,
@@ -555,6 +565,8 @@ export interface ILayerConfig {
* layer point text 是否是 iconfont 模式
*/
iconfont: boolean;
+
+ workerEnabled?: boolean;
onHover(pickedFeature: IPickedFeature): void;
onClick(pickedFeature: IPickedFeature): void;
}
diff --git a/packages/core/src/services/layer/IStyleAttributeService.ts b/packages/core/src/services/layer/IStyleAttributeService.ts
index d04c1676ac..8990976d51 100644
--- a/packages/core/src/services/layer/IStyleAttributeService.ts
+++ b/packages/core/src/services/layer/IStyleAttributeService.ts
@@ -216,6 +216,11 @@ export interface IStyleAttributeService {
};
elements: IElements;
};
+ createAttributesAndIndicesAscy(
+ encodedFeatures: IEncodeFeature[],
+ segmentNumber?: number,
+ workerOptions?: any,
+ ): Promise;
/**
* 根据 feature range 更新指定属性
*/
diff --git a/packages/core/src/services/layer/StyleAttributeService.ts b/packages/core/src/services/layer/StyleAttributeService.ts
index c83e963a09..c16573934b 100644
--- a/packages/core/src/services/layer/StyleAttributeService.ts
+++ b/packages/core/src/services/layer/StyleAttributeService.ts
@@ -1,3 +1,4 @@
+import { executeWorkerTask } from '@antv/l7-utils';
import { inject, injectable, optional } from 'inversify';
import 'reflect-metadata';
import { TYPES } from '../../types';
@@ -6,7 +7,7 @@ import { IAttribute } from '../renderer/IAttribute';
import { IElements } from '../renderer/IElements';
import { IRendererService } from '../renderer/IRendererService';
import { IParseDataItem } from '../source/ISourceService';
-import { ILayer } from './ILayerService';
+import { ILayer, IWorkerOption } from './ILayerService';
import {
IAttributeScale,
IEncodeFeature,
@@ -185,6 +186,80 @@ export default class StyleAttributeService implements IStyleAttributeService {
}
}
+ public createAttributesAndIndicesAscy(
+ features: IEncodeFeature[],
+ segmentNumber: number,
+ workerOptions: IWorkerOption,
+ ) {
+ // 每次创建的初始化化 LayerOut
+ this.featureLayout = {
+ sizePerElement: 0,
+ elements: [],
+ };
+
+ const descriptors = this.attributes
+ .map((attr) => {
+ attr.resetDescriptor();
+ return attr.descriptor;
+ })
+ .filter((d) => d);
+ const { modelType, ...restOptions } = workerOptions;
+
+ const {
+ createAttribute,
+ createBuffer,
+ createElements,
+ } = this.rendererService;
+ const attributes: {
+ [attributeName: string]: IAttribute;
+ } = {};
+ return new Promise((resolve, reject) => {
+ executeWorkerTask(modelType, {
+ // Tip: worker 不支持传递 function 函数
+ descriptors: this.getDescriptorsWithOutFunc(descriptors),
+ features,
+ segmentNumber,
+ ...restOptions,
+ })
+ .then((e) => {
+ e.descriptors.forEach(
+ (descriptor: IVertexAttributeDescriptor, attributeIdx: number) => {
+ if (descriptor) {
+ // IAttribute 参数透传
+ const { buffer, update, name, ...rest } = descriptor;
+
+ const vertexAttribute = createAttribute({
+ // IBuffer 参数透传
+ buffer: createBuffer(buffer),
+ ...rest,
+ });
+ attributes[descriptor.name || ''] = vertexAttribute;
+
+ // 在 StyleAttribute 上保存对 VertexAttribute 的引用
+ this.attributes[attributeIdx].vertexAttribute = vertexAttribute;
+ }
+ },
+ );
+ this.featureLayout = e.featureLayout;
+ const elements = createElements({
+ data: e.indices,
+ type: gl.UNSIGNED_INT,
+ count: e.indices.length,
+ });
+ this.attributesAndIndices = {
+ attributes,
+ elements,
+ };
+
+ resolve(this.attributesAndIndices);
+ })
+ .catch((err: Error) => {
+ console.warn(err);
+ reject(err);
+ });
+ });
+ }
+
public createAttributesAndIndices(
features: IEncodeFeature[],
triangulation: Triangulation,
@@ -434,4 +509,14 @@ export default class StyleAttributeService implements IStyleAttributeService {
this.attributesAndIndices?.elements.destroy();
this.attributes = [];
}
+
+ private getDescriptorsWithOutFunc(descriptors: IVertexAttributeDescriptor[]) {
+ return descriptors.map((d) => {
+ return {
+ buffer: d.buffer,
+ name: d.name,
+ size: d.size,
+ };
+ });
+ }
}
diff --git a/packages/core/src/services/scene/SceneService.ts b/packages/core/src/services/scene/SceneService.ts
index c60372797f..63789f36c3 100644
--- a/packages/core/src/services/scene/SceneService.ts
+++ b/packages/core/src/services/scene/SceneService.ts
@@ -302,13 +302,11 @@ export default class Scene extends EventEmitter implements ISceneService {
public addLayer(layer: ILayer) {
this.layerService.sceneService = this;
this.layerService.add(layer);
- this.render();
}
public addMask(mask: ILayer) {
this.layerService.sceneService = this;
this.layerService.addMask(mask);
- this.render();
}
public async render() {
diff --git a/packages/core/src/services/source/ISourceService.ts b/packages/core/src/services/source/ISourceService.ts
index b03fc5d887..3fa6894591 100644
--- a/packages/core/src/services/source/ISourceService.ts
+++ b/packages/core/src/services/source/ISourceService.ts
@@ -60,6 +60,7 @@ export interface IJsonItem {
export type IJsonData = IJsonItem[];
export interface ISource {
+ inited: boolean;
data: IParserData;
center: [number, number];
parser: IParserCfg;
@@ -79,6 +80,10 @@ export interface ISource {
properties: Record,
): void;
destroy(): void;
+ // Event
+ on(type: string, handler: (...args: any[]) => void): void;
+ off(type: string, handler: (...args: any[]) => void): void;
+ once(type: string, handler: (...args: any[]) => void): void;
}
export interface IRasterCfg {
extent: [number, number, number, number];
diff --git a/packages/l7/package.json b/packages/l7/package.json
index 6b2faeb3c9..c7eaa19a79 100644
--- a/packages/l7/package.json
+++ b/packages/l7/package.json
@@ -17,9 +17,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "antv",
diff --git a/packages/l7/src/index.ts b/packages/l7/src/index.ts
index dafcc0cee3..fc535e244c 100644
--- a/packages/l7/src/index.ts
+++ b/packages/l7/src/index.ts
@@ -1,4 +1,5 @@
import Source from '@antv/l7-source';
+
export * from '@antv/l7-core';
export * from '@antv/l7-scene';
export * from '@antv/l7-maps';
@@ -6,4 +7,5 @@ export * from '@antv/l7-layers';
export * from '@antv/l7-component';
export * from '@antv/l7-utils';
export * from './version';
+
export { Source };
diff --git a/packages/l7/tsconfig.build.json b/packages/l7/tsconfig.build.json
index 17f6c4525a..99200a9677 100644
--- a/packages/l7/tsconfig.build.json
+++ b/packages/l7/tsconfig.build.json
@@ -6,4 +6,4 @@
"baseUrl": "./"
},
"include": ["./src"]
-}
\ No newline at end of file
+}
diff --git a/packages/layers/package.json b/packages/layers/package.json
index 3968494d90..0c3acfe165 100644
--- a/packages/layers/package.json
+++ b/packages/layers/package.json
@@ -9,6 +9,7 @@
"./es/index.js"
],
"files": [
+ "dist",
"lib",
"es",
"README.md"
@@ -17,9 +18,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "xiaoiver",
diff --git a/packages/layers/src/Geometry/index.ts b/packages/layers/src/Geometry/index.ts
index b340725447..18df78239c 100644
--- a/packages/layers/src/Geometry/index.ts
+++ b/packages/layers/src/Geometry/index.ts
@@ -9,10 +9,13 @@ export default class GeometryLayer extends BaseLayer<
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new GeometryModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
diff --git a/packages/layers/src/Geometry/models/billboard.ts b/packages/layers/src/Geometry/models/billboard.ts
index a15a8d3e85..5853a9ade5 100644
--- a/packages/layers/src/Geometry/models/billboard.ts
+++ b/packages/layers/src/Geometry/models/billboard.ts
@@ -3,10 +3,11 @@ import {
gl,
IAttrubuteAndElements,
IEncodeFeature,
+ IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
-import { getMask, isMini } from '@antv/l7-utils';
+import { getMask } from '@antv/l7-utils';
import BaseModel from '../../core/BaseModel';
import { IGeometryLayerStyleOptions } from '../../core/interface';
import planeFrag from '../shaders/billboard_frag.glsl';
@@ -81,7 +82,7 @@ export default class BillBoardModel extends BaseModel {
this.texture?.destroy();
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -98,9 +99,9 @@ export default class BillBoardModel extends BaseModel {
this.updateTexture(drawCanvas);
}
- return [
- this.layer.buildLayerModel({
- moduleName: 'geometry_billboard',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'geometryBillboard',
vertexShader: planeVert,
fragmentShader: planeFrag,
triangulation: this.planeGeometryTriangulation,
@@ -108,12 +109,18 @@ export default class BillBoardModel extends BaseModel {
depth: { enable: true },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
public updateTexture(drawCanvas: (canvas: HTMLCanvasElement) => void): void {
diff --git a/packages/layers/src/Geometry/models/plane.ts b/packages/layers/src/Geometry/models/plane.ts
index 1eb6ab8d8a..66fa63caea 100644
--- a/packages/layers/src/Geometry/models/plane.ts
+++ b/packages/layers/src/Geometry/models/plane.ts
@@ -3,11 +3,12 @@ import {
gl,
IAttrubuteAndElements,
IEncodeFeature,
+ IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
import { Version } from '@antv/l7-maps';
-import { getMask, isMini } from '@antv/l7-utils';
+import { getMask } from '@antv/l7-utils';
// import { mat4, vec3 } from 'gl-matrix';
import BaseModel from '../../core/BaseModel';
import { IGeometryLayerStyleOptions } from '../../core/interface';
@@ -134,7 +135,7 @@ export default class PlaneModel extends BaseModel {
this.texture?.destroy();
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -149,27 +150,33 @@ export default class PlaneModel extends BaseModel {
});
this.updateTexture(mapTexture);
- return [
- this.layer.buildLayerModel({
- moduleName: 'geometry_plane',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'geometryPlane',
vertexShader: planeVert,
fragmentShader: planeFrag,
triangulation: this.planeGeometryTriangulation,
primitive: gl.TRIANGLES,
- // primitive: gl.LINES,
depth: { enable: true },
- blend: this.getBlend(),
stencil: getMask(mask, maskInside),
+ blend: this.getBlend(),
cull: {
enable: true,
face: gl.BACK, // gl.FRONT | gl.BACK;
},
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
public createModelData(options?: any) {
diff --git a/packages/layers/src/Geometry/models/sprite.ts b/packages/layers/src/Geometry/models/sprite.ts
index 5aba2c9d79..2df492ad94 100644
--- a/packages/layers/src/Geometry/models/sprite.ts
+++ b/packages/layers/src/Geometry/models/sprite.ts
@@ -4,6 +4,7 @@ import {
IAnimateOption,
IEncodeFeature,
ILayerConfig,
+ IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
@@ -153,7 +154,7 @@ export default class SpriteModel extends BaseModel {
this.texture?.destroy();
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mapTexture,
spriteTop = 5000000,
@@ -179,21 +180,27 @@ export default class SpriteModel extends BaseModel {
this.updateModel();
}, 100);
- return [
- this.layer.buildLayerModel({
- moduleName: 'geometry_sprite',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'geometrySprite',
vertexShader: spriteVert,
fragmentShader: spriteFrag,
triangulation: this.planeGeometryTriangulation,
primitive: gl.POINTS,
depth: { enable: false },
blend: this.getBlend(),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
public updateTexture(mapTexture: string | undefined): void {
diff --git a/packages/layers/src/canvas/index.ts b/packages/layers/src/canvas/index.ts
index 519f8a2bd7..981da540f9 100644
--- a/packages/layers/src/canvas/index.ts
+++ b/packages/layers/src/canvas/index.ts
@@ -6,10 +6,13 @@ export default class CanvasLayer extends BaseLayer {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new CanvasModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
return {
diff --git a/packages/layers/src/citybuliding/building.ts b/packages/layers/src/citybuliding/building.ts
index 267e620449..e713da8d64 100644
--- a/packages/layers/src/citybuliding/building.ts
+++ b/packages/layers/src/citybuliding/building.ts
@@ -1,4 +1,3 @@
-import { IEncodeFeature } from '@antv/l7-core';
import BaseLayer from '../core/BaseLayer';
import CityBuildModel from './models/build';
@@ -6,10 +5,13 @@ export default class CityBuildingLayer extends BaseLayer {
public type: string = 'PolygonLayer';
public buildModels() {
this.layerModel = new CityBuildModel(this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
public setLight(t: number) {
this.updateLayerConfig({
diff --git a/packages/layers/src/citybuliding/models/build.ts b/packages/layers/src/citybuliding/models/build.ts
index 8102bc8039..b3a1e5211a 100644
--- a/packages/layers/src/citybuliding/models/build.ts
+++ b/packages/layers/src/citybuliding/models/build.ts
@@ -75,22 +75,34 @@ export default class CityBuildModel extends BaseModel {
}
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.calCityGeo();
this.startModelAnimate();
- return [
- this.layer.buildLayerModel({
+
+ this.buildModels(callbackModel);
+ }
+
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.layer
+ .buildLayerModel({
moduleName: 'cityBuilding',
vertexShader: buildVert,
fragmentShader: buildFrag,
triangulation: PolygonExtrudeTriangulation,
+ depth: { enable: true },
cull: {
enable: true,
face: gl.BACK,
},
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts
index bce6e20953..bcfade0185 100644
--- a/packages/layers/src/core/BaseLayer.ts
+++ b/packages/layers/src/core/BaseLayer.ts
@@ -50,7 +50,7 @@ import {
TYPES,
} from '@antv/l7-core';
import Source from '@antv/l7-source';
-import { encodePickingColor } from '@antv/l7-utils';
+import { encodePickingColor, WorkerSourceMap } from '@antv/l7-utils';
import { EventEmitter } from 'eventemitter3';
import { Container } from 'inversify';
import { isFunction, isObject, isUndefined } from 'lodash';
@@ -432,7 +432,7 @@ export default class BaseLayer
}
public createModelData(data: any, option?: ISourceCFG) {
- if (this.layerModel.createModelData) {
+ if (this.layerModel?.createModelData) {
// 在某些特殊图层中单独构建 attribute & elements
return this.layerModel.createModelData(option);
}
@@ -654,7 +654,9 @@ export default class BaseLayer
// @ts-ignore
if (lastConfig && lastConfig.mask === true && options.mask === false) {
this.clearModels();
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => {
+ this.models = models;
+ });
}
return this;
}
@@ -688,7 +690,7 @@ export default class BaseLayer
return this;
}
// TODO: this.getEncodedData().length !== 0 这个判断是为了解决在 2.5.x 引入数据纹理后产生的 空数据渲染导致 texture 超出上限问题
- if (this.getEncodedData().length !== 0) {
+ if (this.getEncodedData() && this.getEncodedData().length !== 0) {
this.renderModels();
}
return this;
@@ -698,7 +700,7 @@ export default class BaseLayer
* renderMultiPass 专门用于渲染支持 multipass 的 layer
*/
public async renderMultiPass() {
- if (this.getEncodedData().length !== 0) {
+ if (this.getEncodedData() && this.getEncodedData().length !== 0) {
if (this.multiPassRenderer && this.multiPassRenderer.getRenderFlag()) {
// multi render 开始执行 multiPassRender 的渲染流程
await this.multiPassRenderer.render();
@@ -983,7 +985,7 @@ export default class BaseLayer
this.hooks.beforeDestroy.call();
// 清除sources事件
- this.layerSource.off('update', this.sourceEvent);
+ this.layerSource.off('sourceUpdate', this.sourceEvent);
this.multiPassRenderer.destroy();
// console.log(this.styleAttributeService.getAttributes())
@@ -1023,7 +1025,7 @@ export default class BaseLayer
}
public clearModels() {
this.models.forEach((model) => model.destroy());
- this.layerModel.clearModels();
+ this.layerModel?.clearModels();
this.models = [];
}
@@ -1041,7 +1043,7 @@ export default class BaseLayer
public setSource(source: Source) {
// 清除旧 sources 事件
if (this.layerSource) {
- this.layerSource.off('update', this.sourceEvent);
+ this.layerSource.off('sourceUpdate', this.sourceEvent);
}
this.layerSource = source;
@@ -1053,7 +1055,13 @@ export default class BaseLayer
this.layerSource.updateClusterData(zoom);
}
// source 可能会复用,会在其它layer被修改
- this.layerSource.on('update', this.sourceEvent);
+ if (this.layerSource.inited) {
+ this.sourceEvent();
+ }
+ // this.layerSource.inited 为 true 后,sourceUpdate 事件不会再触发
+ this.layerSource.on('sourceUpdate', () => {
+ this.sourceEvent();
+ });
}
public getSource() {
return this.layerSource;
@@ -1136,37 +1144,70 @@ export default class BaseLayer
public buildLayerModel(
options: ILayerModelInitializationOptions &
Partial,
- ): IModel {
+ ): Promise {
const {
moduleName,
vertexShader,
fragmentShader,
triangulation,
segmentNumber,
+ workerEnabled = false,
+ workerOptions,
...rest
} = options;
+
this.shaderModuleService.registerModule(moduleName, {
vs: vertexShader,
fs: fragmentShader,
});
const { vs, fs, uniforms } = this.shaderModuleService.getModule(moduleName);
const { createModel } = this.rendererService;
- const {
- attributes,
- elements,
- } = this.styleAttributeService.createAttributesAndIndices(
- this.encodedData,
- triangulation,
- segmentNumber,
- );
- return createModel({
- attributes,
- uniforms,
- fs,
- vs,
- elements,
- blend: BlendTypes[BlendType.normal],
- ...rest,
+ return new Promise((resolve, reject) => {
+ // filter supported worker & worker enabled layer
+ if (
+ workerOptions &&
+ workerOptions.modelType in WorkerSourceMap &&
+ workerEnabled
+ ) {
+ this.styleAttributeService
+ .createAttributesAndIndicesAscy(
+ this.encodedData,
+ segmentNumber,
+ workerOptions,
+ )
+ .then(({ attributes, elements }) => {
+ const m = createModel({
+ attributes,
+ uniforms,
+ fs,
+ vs,
+ elements,
+ blend: BlendTypes[BlendType.normal],
+ ...rest,
+ });
+ resolve(m);
+ })
+ .catch((err) => reject(err));
+ } else {
+ const {
+ attributes,
+ elements,
+ } = this.styleAttributeService.createAttributesAndIndices(
+ this.encodedData,
+ triangulation,
+ segmentNumber,
+ );
+ const m = createModel({
+ attributes,
+ uniforms,
+ fs,
+ vs,
+ elements,
+ blend: BlendTypes[BlendType.normal],
+ ...rest,
+ });
+ resolve(m);
+ }
});
}
@@ -1241,15 +1282,18 @@ export default class BaseLayer
public renderModels(isPicking?: boolean) {
// TODO: this.getEncodedData().length > 0 这个判断是为了解决在 2.5.x 引入数据纹理后产生的 空数据渲染导致 texture 超出上限问题
- if (this.getEncodedData().length > 0) {
+ if (this.getEncodedData() && this.getEncodedData().length > 0) {
if (this.layerModelNeedUpdate && this.layerModel) {
- this.models = this.layerModel.buildModels();
- this.hooks.beforeRender.call();
- this.layerModelNeedUpdate = false;
+ this.layerModel.buildModels((models: IModel[]) => {
+ this.models = models;
+ this.hooks.beforeRender.call();
+ this.layerModelNeedUpdate = false;
+ });
}
- if (this.layerModel.renderUpdate) {
+ if (this?.layerModel?.renderUpdate) {
this.layerModel.renderUpdate();
}
+
this.models.forEach((model) => {
model.draw(
{
@@ -1321,9 +1365,9 @@ export default class BaseLayer
private sourceEvent = () => {
this.dataState.dataSourceNeedUpdate = true;
- const { autoFit, fitBoundsOptions } = this.getLayerConfig();
- if (autoFit) {
- this.fitBounds(fitBoundsOptions);
+ const layerConfig = this.getLayerConfig();
+ if (layerConfig && layerConfig.autoFit) {
+ this.fitBounds(layerConfig.fitBoundsOptions);
}
// 对外暴露事件 迁移到 DataMappingPlugin generateMapping,保证在重新重新映射后触发
// this.emit('dataUpdate');
diff --git a/packages/layers/src/core/BaseModel.ts b/packages/layers/src/core/BaseModel.ts
index 604cda96f7..af45efd78d 100644
--- a/packages/layers/src/core/BaseModel.ts
+++ b/packages/layers/src/core/BaseModel.ts
@@ -514,10 +514,10 @@ export default class BaseModel
public needUpdate(): boolean {
return false;
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void): void {
throw new Error('Method not implemented.');
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void): void {
throw new Error('Method not implemented.');
}
public clearModels() {
diff --git a/packages/layers/src/core/interface.ts b/packages/layers/src/core/interface.ts
index 93061f54aa..79c93d4904 100644
--- a/packages/layers/src/core/interface.ts
+++ b/packages/layers/src/core/interface.ts
@@ -50,6 +50,8 @@ export interface ILineLayerStyleOptions {
rampColors?: IColorRamp;
featureId?: string;
sourceLayer?: string;
+ enablePicking?: boolean;
+ workerEnabled?: boolean;
}
export interface IPointLayerStyleOptions {
diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts
index c8c2cb4dac..7e48f08995 100644
--- a/packages/layers/src/core/triangulation.ts
+++ b/packages/layers/src/core/triangulation.ts
@@ -1,5 +1,10 @@
import { IEncodeFeature } from '@antv/l7-core';
-import { aProjectFlat, lngLatToMeters } from '@antv/l7-utils';
+import {
+ aProjectFlat,
+ calculateCentroid,
+ calculatePointsCenterAndRadius,
+ lngLatToMeters,
+} from '@antv/l7-utils';
import earcut from 'earcut';
// @ts-ignore
import { mat4, vec3 } from 'gl-matrix';
@@ -11,10 +16,6 @@ import {
primitiveSphere,
} from '../earth/utils';
import ExtrudePolyline from '../utils/extrude_polyline';
-import {
- calculateCentroid,
- calculatePointsCenterAndRadius,
-} from '../utils/geo';
import SimpleLine from '../utils/simpleLine';
import extrudePolygon, {
extrude_PolygonNormal,
diff --git a/packages/layers/src/earth/index.ts b/packages/layers/src/earth/index.ts
index 0824b1f8a2..253bda8192 100644
--- a/packages/layers/src/earth/index.ts
+++ b/packages/layers/src/earth/index.ts
@@ -24,7 +24,10 @@ export default class EarthLayer extends BaseLayer {
public buildModels() {
const shape = this.getModelType();
this.layerModel = new EarthModels[shape](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
/**
@@ -35,7 +38,7 @@ export default class EarthLayer extends BaseLayer {
if (this.layerModel && this.layerModel.setEarthTime) {
this.layerModel.setEarthTime(time);
} else {
- console.error('请在 scene loaded 之后执行该方法!');
+ console.warn('请在 scene loaded 之后执行该方法!');
}
}
diff --git a/packages/layers/src/earth/models/atmosphere.ts b/packages/layers/src/earth/models/atmosphere.ts
index 9134e583d2..091ab9688e 100644
--- a/packages/layers/src/earth/models/atmosphere.ts
+++ b/packages/layers/src/earth/models/atmosphere.ts
@@ -25,29 +25,33 @@ export default class EarthAtomSphereModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
public clearModels() {
return '';
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
// TODO: 调整图层的绘制顺序 地球大气层
this.layer.zIndex = -997;
- return [
- this.layer.buildLayerModel({
- moduleName: 'earthAtmoSphere',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'earthAtmo',
vertexShader: atmoSphereVert,
fragmentShader: atmoSphereFrag,
triangulation: earthTriangulation,
- depth: {
- enable: false,
- },
+ depth: { enable: false },
blend: this.getBlend(),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/earth/models/base.ts b/packages/layers/src/earth/models/base.ts
index 56d9ce634a..04c24429df 100644
--- a/packages/layers/src/earth/models/base.ts
+++ b/packages/layers/src/earth/models/base.ts
@@ -62,7 +62,7 @@ export default class BaseEarthModel extends BaseModel {
this.layerService.renderLayers();
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const { globelOtions } = this.layer.getLayerConfig();
if (globelOtions?.earthTime !== undefined) {
this.setEarthTime(globelOtions.earthTime);
@@ -84,26 +84,33 @@ export default class BaseEarthModel extends BaseModel {
this.layerService.renderLayers();
});
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
return '';
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
// TODO: 调整图层的绘制顺序 地球大气层
this.layer.zIndex = -998;
- return [
- this.layer.buildLayerModel({
- moduleName: 'baseEarth',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'earthBase',
vertexShader: baseVert,
fragmentShader: baseFrag,
triangulation: earthTriangulation,
depth: { enable: true },
blend: this.getBlend(),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/earth/models/bloomsphere.ts b/packages/layers/src/earth/models/bloomsphere.ts
index 0d20bd8f4f..59d9405c51 100644
--- a/packages/layers/src/earth/models/bloomsphere.ts
+++ b/packages/layers/src/earth/models/bloomsphere.ts
@@ -25,29 +25,33 @@ export default class EarthBloomSphereModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
public clearModels() {
return '';
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
// TODO: 调整图层的绘制顺序,让它保持在地球后面(减少锯齿现象)
this.layer.zIndex = -999;
- return [
- this.layer.buildLayerModel({
- moduleName: 'earthBloomSphere',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'earthBloom',
vertexShader: bloomSphereVert,
fragmentShader: bloomSphereFrag,
triangulation: earthOuterTriangulation,
- depth: {
- enable: false,
- },
+ depth: { enable: false },
blend: this.getBlend(),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/heatmap/index.ts b/packages/layers/src/heatmap/index.ts
index c29511bb7a..0388e0e2f4 100644
--- a/packages/layers/src/heatmap/index.ts
+++ b/packages/layers/src/heatmap/index.ts
@@ -8,10 +8,13 @@ export default class HeatMapLayer extends BaseLayer {
public buildModels() {
const shape = this.getModelType();
this.layerModel = new HeatMapModels[shape](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
public renderModels() {
const shape = this.getModelType();
@@ -23,7 +26,9 @@ export default class HeatMapLayer extends BaseLayer {
return this;
}
if (this.layerModelNeedUpdate) {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
+ // @ts-ignore
+ // this.models = this.layerModel.buildModels();
this.layerModelNeedUpdate = false;
}
this.models.forEach((model) =>
diff --git a/packages/layers/src/heatmap/models/grid.ts b/packages/layers/src/heatmap/models/grid.ts
index 72caec2971..a631dbcf09 100644
--- a/packages/layers/src/heatmap/models/grid.ts
+++ b/packages/layers/src/heatmap/models/grid.ts
@@ -29,27 +29,32 @@ export default class GridModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'gridheatmap',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'heatmapGrid',
vertexShader: heatmapGridVert,
fragmentShader: heatmapGridFrag,
triangulation: HeatmapGridTriangulation,
- depth: { enable: false },
primitive: gl.TRIANGLES,
- blend: this.getBlend(),
+ depth: { enable: false },
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
diff --git a/packages/layers/src/heatmap/models/grid3d.ts b/packages/layers/src/heatmap/models/grid3d.ts
index 3a62566951..fa8f839657 100644
--- a/packages/layers/src/heatmap/models/grid3d.ts
+++ b/packages/layers/src/heatmap/models/grid3d.ts
@@ -29,26 +29,33 @@ export default class Grid3DModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'grid3dheatmap',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'heatmapGrid3d',
vertexShader: heatmapGrid3dVert,
fragmentShader: heatmapGridFrag,
triangulation: PointExtrudeTriangulation,
+ primitive: gl.TRIANGLES,
depth: { enable: true },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
// point layer size;
diff --git a/packages/layers/src/heatmap/models/heatmap.ts b/packages/layers/src/heatmap/models/heatmap.ts
index f244dc5ec5..39d3e3b4ee 100644
--- a/packages/layers/src/heatmap/models/heatmap.ts
+++ b/packages/layers/src/heatmap/models/heatmap.ts
@@ -60,7 +60,7 @@ export default class HeatMapModel extends BaseModel {
throw new Error('Method not implemented.');
}
- public initModels(): IModel[] {
+ public async initModels(callbackModel: (models: IModel[]) => void) {
const {
createFramebuffer,
clear,
@@ -74,7 +74,7 @@ export default class HeatMapModel extends BaseModel {
const shapeType = shapeAttr?.scale?.field || 'heatmap';
this.shapeType = shapeType as string;
// 生成热力图密度图
- this.intensityModel = this.buildHeatMapIntensity();
+ this.intensityModel = await this.buildHeatMapIntensity();
// 渲染到屏幕
this.colorModel =
shapeType === 'heatmap'
@@ -98,11 +98,11 @@ export default class HeatMapModel extends BaseModel {
this.updateColorTexture();
- return [this.intensityModel, this.colorModel];
+ callbackModel([this.intensityModel, this.colorModel]);
}
- public buildModels(): IModel[] {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
protected registerBuiltinAttributes() {
@@ -154,10 +154,10 @@ export default class HeatMapModel extends BaseModel {
},
});
}
- private buildHeatMapIntensity(): IModel {
+ private async buildHeatMapIntensity() {
this.layer.triangulation = HeatmapTriangulation;
- return this.layer.buildLayerModel({
- moduleName: 'heatmapintensity',
+ const model = await this.layer.buildLayerModel({
+ moduleName: 'heatmapIntensity',
vertexShader: heatmapFramebufferVert,
fragmentShader: heatmapFramebufferFrag,
triangulation: HeatmapTriangulation,
@@ -178,6 +178,7 @@ export default class HeatMapModel extends BaseModel {
},
},
});
+ return model;
}
private buildHeatmapColor(): IModel {
@@ -241,7 +242,7 @@ export default class HeatMapModel extends BaseModel {
intensity = 10,
radius = 5,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
- this.intensityModel.draw({
+ this.intensityModel?.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_radius: radius,
@@ -254,7 +255,7 @@ export default class HeatMapModel extends BaseModel {
const {
opacity,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
- this.colorModel.draw({
+ this.colorModel?.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_colorTexture: this.colorTexture,
@@ -281,7 +282,7 @@ export default class HeatMapModel extends BaseModel {
this.cameraService.getViewProjectionMatrixUncentered() as mat4,
);
- this.colorModel.draw({
+ this.colorModel?.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_colorTexture: this.colorTexture,
diff --git a/packages/layers/src/heatmap/models/hexagon.ts b/packages/layers/src/heatmap/models/hexagon.ts
index 405fbdf52c..3b876b3c88 100644
--- a/packages/layers/src/heatmap/models/hexagon.ts
+++ b/packages/layers/src/heatmap/models/hexagon.ts
@@ -30,18 +30,18 @@ export default class HexagonModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'hexagonheatmap',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'heatmapHexagon',
vertexShader: heatmapGridVert,
fragmentShader: heatmapGridFrag,
triangulation: HeatmapGridTriangulation,
@@ -49,8 +49,14 @@ export default class HexagonModel extends BaseModel {
primitive: gl.TRIANGLES,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
diff --git a/packages/layers/src/image/index.ts b/packages/layers/src/image/index.ts
index a635ed8bc1..9e26e64ca2 100644
--- a/packages/layers/src/image/index.ts
+++ b/packages/layers/src/image/index.ts
@@ -6,10 +6,13 @@ export default class ImageLayer extends BaseLayer {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new ImageModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
return {
diff --git a/packages/layers/src/image/models/dataImage.ts b/packages/layers/src/image/models/dataImage.ts
index c8ec6189fa..213ab384a7 100644
--- a/packages/layers/src/image/models/dataImage.ts
+++ b/packages/layers/src/image/models/dataImage.ts
@@ -2,6 +2,7 @@ import {
AttributeType,
gl,
IEncodeFeature,
+ IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
@@ -54,7 +55,7 @@ export default class ImageDataModel extends BaseModel {
u_colorTexture: this.colorTexture,
};
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -109,8 +110,8 @@ export default class ImageDataModel extends BaseModel {
flipY: false,
});
- return [
- this.layer.buildLayerModel({
+ this.layer
+ .buildLayerModel({
moduleName: 'RasterImage',
vertexShader: ImageVert,
fragmentShader: ImageFrag,
@@ -119,8 +120,14 @@ export default class ImageDataModel extends BaseModel {
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels(): void {
@@ -128,8 +135,8 @@ export default class ImageDataModel extends BaseModel {
this.colorTexture?.destroy();
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
protected getConfigSchema() {
diff --git a/packages/layers/src/image/models/image.ts b/packages/layers/src/image/models/image.ts
index 159b5465b0..cca4a28c7f 100644
--- a/packages/layers/src/image/models/image.ts
+++ b/packages/layers/src/image/models/image.ts
@@ -2,6 +2,7 @@ import {
AttributeType,
gl,
IEncodeFeature,
+ IModel,
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
@@ -21,7 +22,8 @@ export default class ImageModel extends BaseModel {
u_texture: this.texture,
};
}
- public initModels() {
+
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -64,26 +66,31 @@ export default class ImageModel extends BaseModel {
);
}
- return [
- this.layer.buildLayerModel({
- moduleName: 'RasterImage',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'rasterImage',
vertexShader: ImageVert,
fragmentShader: ImageFrag,
triangulation: RasterImageTriangulation,
primitive: gl.TRIANGLES,
depth: { enable: false },
- blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels(): void {
this.texture?.destroy();
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
protected getConfigSchema() {
diff --git a/packages/layers/src/line/index.ts b/packages/layers/src/line/index.ts
index 52557b4b5a..0f9eb7994b 100644
--- a/packages/layers/src/line/index.ts
+++ b/packages/layers/src/line/index.ts
@@ -8,10 +8,13 @@ export default class LineLayer extends BaseLayer {
public buildModels() {
const shape = this.getModelType();
this.layerModel = new LineModels[shape](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
@@ -34,7 +37,6 @@ export default class LineLayer extends BaseLayer {
wall: {},
arc3d: { blend: 'additive' },
arc: { blend: 'additive' },
- arcmini: { blend: 'additive' },
greatcircle: { blend: 'additive' },
vectorline: {},
tileLine: {},
diff --git a/packages/layers/src/line/models/arc.ts b/packages/layers/src/line/models/arc.ts
index bb065afff8..ab129e0526 100644
--- a/packages/layers/src/line/models/arc.ts
+++ b/packages/layers/src/line/models/arc.ts
@@ -129,11 +129,11 @@ export default class ArcModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -152,7 +152,7 @@ export default class ArcModel extends BaseModel {
return {
frag: arc_dash_frag,
vert: arc_dash_vert,
- type: 'dash',
+ type: 'Dash',
};
}
@@ -161,28 +161,28 @@ export default class ArcModel extends BaseModel {
return {
frag: arc_linear_frag,
vert: arc_linear_vert,
- type: 'linear',
+ type: 'Linear',
};
} else {
return {
frag: arc_line_frag,
vert: arc_line_vert,
- type: 'normal',
+ type: '',
};
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
- // primitive: gl.POINTS,
- moduleName: 'arc2dline' + type,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineArc2d' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineArcTriangulation,
@@ -190,8 +190,14 @@ export default class ArcModel extends BaseModel {
blend: this.getBlend(),
segmentNumber,
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/line/models/arc_3d.ts b/packages/layers/src/line/models/arc_3d.ts
index 1fb1c7c7a4..c52839777d 100644
--- a/packages/layers/src/line/models/arc_3d.ts
+++ b/packages/layers/src/line/models/arc_3d.ts
@@ -123,11 +123,11 @@ export default class Arc3DModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -147,36 +147,42 @@ export default class Arc3DModel extends BaseModel {
return {
frag: arc3d_linear_frag,
vert: arc3d_linear_vert,
- type: 'linear',
+ type: 'Linear',
};
} else {
return {
frag: arc3d_line_frag,
vert: arc3d_line_vert,
- type: 'normal',
+ type: '',
};
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
- moduleName: 'arc3Dline' + type,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineArc3d' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineArcTriangulation,
blend: this.getBlend(),
segmentNumber,
- // primitive: gl.POINTS,
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
// point layer size;
diff --git a/packages/layers/src/line/models/arcmini.ts b/packages/layers/src/line/models/arcmini.ts
deleted file mode 100644
index 02af3137d7..0000000000
--- a/packages/layers/src/line/models/arcmini.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import {
- AttributeType,
- gl,
- IAnimateOption,
- IEncodeFeature,
- ILayerConfig,
- IModel,
- IModelUniform,
-} from '@antv/l7-core';
-import { rgb2arr } from '@antv/l7-utils';
-import { isNumber } from 'lodash';
-import BaseModel from '../../core/BaseModel';
-import { ILineLayerStyleOptions } from '../../core/interface';
-import { LineArcTriangulation } from '../../core/triangulation';
-import line_arcmini_frag from '../shaders/line_arcmini_frag.glsl';
-import line_arcmini_vert from '../shaders/line_arcmini_vert.glsl';
-
-export default class ArcMiniModel extends BaseModel {
- public getUninforms(): IModelUniform {
- const {
- opacity = 1,
- sourceColor,
- targetColor,
- forward = true,
- segmentNumber = 30,
- thetaOffset = 0.314,
- } = this.layer.getLayerConfig() as ILineLayerStyleOptions;
-
- // 转化渐变色
- let useLinearColor = 0; // 默认不生效
- let sourceColorArr = [0, 0, 0, 0];
- let targetColorArr = [0, 0, 0, 0];
- if (sourceColor && targetColor) {
- sourceColorArr = rgb2arr(sourceColor);
- targetColorArr = rgb2arr(targetColor);
- useLinearColor = 1;
- }
-
- return {
- u_thetaOffset: thetaOffset,
-
- u_opacity: isNumber(opacity) ? opacity : 1.0,
-
- segmentNumber,
- u_blur: 0.9,
- u_lineDir: forward ? 1 : -1,
-
- // 渐变色支持参数
- u_linearColor: useLinearColor,
- u_sourceColor: sourceColorArr,
- u_targetColor: targetColorArr,
- };
- }
-
- public getAnimateUniforms(): IModelUniform {
- const { animateOption } = this.layer.getLayerConfig() as ILayerConfig;
- return {
- u_aimate: this.animateOption2Array(animateOption as IAnimateOption),
- u_time: this.layer.getLayerAnimateTime(),
- };
- }
-
- public initModels(): IModel[] {
- return this.buildModels();
- }
-
- public buildModels(): IModel[] {
- const {
- segmentNumber = 30,
- } = this.layer.getLayerConfig() as ILineLayerStyleOptions;
-
- return [
- this.layer.buildLayerModel({
- moduleName: 'arc2dminiline',
- vertexShader: line_arcmini_vert,
- fragmentShader: line_arcmini_frag,
- triangulation: LineArcTriangulation,
- depth: { enable: false },
- blend: this.getBlend(),
- segmentNumber,
- }),
- ];
- }
-
- protected registerBuiltinAttributes() {
- // point layer size;
- this.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 = 1 } = feature;
- return Array.isArray(size) ? [size[0]] : [size as number];
- },
- },
- });
-
- this.styleAttributeService.registerStyleAttribute({
- name: 'instance', // 弧线起始点信息
- type: AttributeType.Attribute,
- descriptor: {
- name: 'a_Instance',
- buffer: {
- usage: gl.STATIC_DRAW,
- data: [],
- type: gl.FLOAT,
- },
- size: 4,
- update: (
- feature: IEncodeFeature,
- featureIdx: number,
- vertex: number[],
- attributeIdx: number,
- ) => {
- return [vertex[3], vertex[4], vertex[5], vertex[6]];
- },
- },
- });
- }
-}
diff --git a/packages/layers/src/line/models/earthArc_3d.ts b/packages/layers/src/line/models/earthArc_3d.ts
index 1fb1c7c7a4..7a0654dab6 100644
--- a/packages/layers/src/line/models/earthArc_3d.ts
+++ b/packages/layers/src/line/models/earthArc_3d.ts
@@ -90,7 +90,7 @@ export default class Arc3DModel extends BaseModel {
}
return {
- u_globel: this.mapService.version === 'GLOBEL' ? 1 : 0,
+ u_globel: 1,
u_globel_radius: EARTH_RADIUS, // 地球半径
u_global_height: globalArcHeight,
@@ -123,11 +123,11 @@ export default class Arc3DModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -147,36 +147,42 @@ export default class Arc3DModel extends BaseModel {
return {
frag: arc3d_linear_frag,
vert: arc3d_linear_vert,
- type: 'linear',
+ type: 'Linear',
};
} else {
return {
frag: arc3d_line_frag,
vert: arc3d_line_vert,
- type: 'normal',
+ type: '',
};
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
segmentNumber = 30,
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
- moduleName: 'arc3Dline' + type,
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineEarthArc3d' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineArcTriangulation,
+ depth: { enable: true },
blend: this.getBlend(),
segmentNumber,
- // primitive: gl.POINTS,
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
// point layer size;
diff --git a/packages/layers/src/line/models/great_circle.ts b/packages/layers/src/line/models/great_circle.ts
index c7d8234f6c..bd1de86f4b 100644
--- a/packages/layers/src/line/models/great_circle.ts
+++ b/packages/layers/src/line/models/great_circle.ts
@@ -112,11 +112,11 @@ export default class GreatCircleModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -125,22 +125,28 @@ export default class GreatCircleModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'greatcircleline',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineGreatCircle',
vertexShader: line_arc2d_vert,
fragmentShader: line_arc_frag,
triangulation: LineArcTriangulation,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
diff --git a/packages/layers/src/line/models/half.ts b/packages/layers/src/line/models/half.ts
index 7b7df78dba..c92d9aca1e 100644
--- a/packages/layers/src/line/models/half.ts
+++ b/packages/layers/src/line/models/half.ts
@@ -84,15 +84,15 @@ export default class LineModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
public clearModels() {
this.dataTexture?.destroy();
}
- public buildModels(): IModel[] {
+ public async buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -100,18 +100,24 @@ export default class LineModel extends BaseModel {
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert } = this.getShaders();
this.layer.triangulation = LineTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'line_half',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineHalf',
vertexShader: vert,
fragmentShader: frag,
triangulation: LineTriangulation,
- primitive: gl.TRIANGLES,
- blend: this.getBlend(),
depth: { enable: depth },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
/**
diff --git a/packages/layers/src/line/models/index.ts b/packages/layers/src/line/models/index.ts
index 4bc5a6af45..7e59b0a9e8 100644
--- a/packages/layers/src/line/models/index.ts
+++ b/packages/layers/src/line/models/index.ts
@@ -1,7 +1,6 @@
import LineTileModel from '../../tile/models/tileModel';
import ArcModel from './arc';
import Arc3DModel from './arc_3d';
-import ArcMiniModel from './arcmini';
import EarthArc3DModel from './earthArc_3d';
import GreatCircleModel from './great_circle';
import LineHalfModel from './half';
@@ -13,7 +12,6 @@ import LineWallModel from './wall';
export type LineModelType =
| 'arc'
- | 'arcmini'
| 'arc3d'
| 'greatcircle'
| 'wall'
@@ -27,7 +25,6 @@ export type LineModelType =
const LineModels: { [key in LineModelType]: any } = {
arc: ArcModel,
- arcmini: ArcMiniModel,
arc3d: Arc3DModel,
greatcircle: GreatCircleModel,
wall: LineWallModel,
diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts
index e461d36876..b1c54d6368 100644
--- a/packages/layers/src/line/models/line.ts
+++ b/packages/layers/src/line/models/line.ts
@@ -9,11 +9,11 @@ import {
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
-import { getMask, rgb2arr } from '@antv/l7-utils';
+import { getMask, LineTriangulation, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions } from '../../core/interface';
-import { LineTriangulation } from '../../core/triangulation';
+// import { LineTriangulation } from '../../core/triangulation';
// dash line shader
import line_dash_frag from '../shaders/dash/line_dash_frag.glsl';
import line_dash_vert from '../shaders/dash/line_dash_vert.glsl';
@@ -143,11 +143,11 @@ export default class LineModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -156,27 +156,39 @@ export default class LineModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
depth = false,
+ workerEnabled = false,
+ enablePicking,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
this.layer.triangulation = LineTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'line_' + type,
+ this.layer
+ .buildLayerModel({
+ moduleName: 'line' + type,
vertexShader: vert,
fragmentShader: frag,
triangulation: LineTriangulation,
- primitive: gl.TRIANGLES,
- blend: this.getBlend(),
depth: { enable: depth },
- // depth: { enable: true },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ workerEnabled,
+ workerOptions: {
+ modelType: 'line' + type,
+ enablePicking,
+ iconMap: this.iconService.getIconMap(),
+ },
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
/**
@@ -194,7 +206,7 @@ export default class LineModel extends BaseModel {
return {
frag: line_dash_frag,
vert: line_dash_vert,
- type: 'dash',
+ type: 'Dash',
};
}
@@ -203,13 +215,13 @@ export default class LineModel extends BaseModel {
return {
frag: linear_line_frag,
vert: line_vert,
- type: 'linear',
+ type: 'Linear',
};
} else {
return {
frag: line_frag,
vert: line_vert,
- type: 'normal',
+ type: '',
};
}
}
diff --git a/packages/layers/src/line/models/linearline.ts b/packages/layers/src/line/models/linearline.ts
index 59c6c80ea6..993100d8c7 100644
--- a/packages/layers/src/line/models/linearline.ts
+++ b/packages/layers/src/line/models/linearline.ts
@@ -74,9 +74,9 @@ export default class LinearLineModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -84,38 +84,32 @@ export default class LinearLineModel extends BaseModel {
this.dataTexture?.destroy();
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
depth = false,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
- const { frag, vert, type } = this.getShaders();
+
this.layer.triangulation = LineTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'line_' + type,
- vertexShader: vert,
- fragmentShader: frag,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineRampColors',
+ vertexShader: linear_line_vert,
+ fragmentShader: linear_line_frag,
triangulation: LineTriangulation,
- primitive: gl.TRIANGLES,
- blend: this.getBlend(),
depth: { enable: depth },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
- }
-
- /**
- * 根据参数获取不同的 shader 代码
- * @returns
- */
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: linear_line_frag,
- vert: linear_line_vert,
- type: 'linear_rampColors',
- };
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/line/models/simpleLine.ts b/packages/layers/src/line/models/simpleLine.ts
index 38cc21c08a..19ff3df987 100644
--- a/packages/layers/src/line/models/simpleLine.ts
+++ b/packages/layers/src/line/models/simpleLine.ts
@@ -78,8 +78,8 @@ export default class SimpleLineModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -96,36 +96,43 @@ export default class SimpleLineModel extends BaseModel {
return {
frag: simle_linear_frag,
vert: simple_line_vert,
- type: 'simple_linear',
+ type: 'lineSimpleLinear',
};
} else {
return {
frag: simple_line_frag,
vert: simple_line_vert,
- type: 'simple_normal',
+ type: 'lineSimpleNormal',
};
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
+
+ this.layer
+ .buildLayerModel({
moduleName: type,
vertexShader: vert,
fragmentShader: frag,
triangulation: SimpleLineTriangulation,
- primitive: gl.LINES, // gl.LINES gl.TRIANGLES
- blend: this.getBlend(),
+ primitive: gl.LINES,
depth: { enable: false },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
diff --git a/packages/layers/src/line/models/tile.ts b/packages/layers/src/line/models/tile.ts
index c2a615dc1a..ab87517505 100644
--- a/packages/layers/src/line/models/tile.ts
+++ b/packages/layers/src/line/models/tile.ts
@@ -103,11 +103,11 @@ export default class LineModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -116,39 +116,33 @@ export default class LineModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
- public buildModels(): IModel[] {
+ public async buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
depth = false,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
- const { frag, vert, type } = this.getShaders();
+
this.layer.triangulation = LineTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: type,
- vertexShader: vert,
- fragmentShader: frag,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineTile',
+ vertexShader: line_tile_vert,
+ fragmentShader: line_tile_frag,
triangulation: LineTriangulation,
- primitive: gl.TRIANGLES,
blend: this.getBlend(),
depth: { enable: depth },
// depth: { enable: true },
stencil: getMask(mask, maskInside),
- }),
- ];
- }
-
- /**
- * 根据参数获取不同的 shader 代码
- * @returns
- */
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: line_tile_frag,
- vert: line_tile_vert,
- type: 'line_tile',
- };
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
diff --git a/packages/layers/src/line/models/wall.ts b/packages/layers/src/line/models/wall.ts
index c7a60f5b3a..6b3c1794e2 100644
--- a/packages/layers/src/line/models/wall.ts
+++ b/packages/layers/src/line/models/wall.ts
@@ -103,11 +103,11 @@ export default class LineWallModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -116,18 +116,23 @@ export default class LineWallModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
- public buildModels(): IModel[] {
- return [
- this.layer.buildLayerModel({
- moduleName: 'linewall',
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.layer
+ .buildLayerModel({
+ moduleName: 'lineWall',
vertexShader: line_vert,
fragmentShader: line_frag,
triangulation: LineTriangulation,
- primitive: gl.TRIANGLES,
- blend: this.getBlend(),
depth: { enable: false },
- }),
- ];
+ blend: this.getBlend(),
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
diff --git a/packages/layers/src/line/shaders/line_arcmini_frag.glsl b/packages/layers/src/line/shaders/line_arcmini_frag.glsl
deleted file mode 100644
index b091e2d355..0000000000
--- a/packages/layers/src/line/shaders/line_arcmini_frag.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-#define Animate 0.0
-
-uniform float u_opacity;
-uniform float u_blur : 0.9;
-// varying vec2 v_normal;
-varying vec4 v_color;
-
-uniform float u_time;
-uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
-
-uniform float segmentNumber;
-varying float v_distance_ratio;
-
-uniform float u_linearColor: 0;
-uniform vec4 u_sourceColor;
-uniform vec4 u_targetColor;
-
-#pragma include "picking"
-
-void main() {
-
- // 设置弧线的底色
- if(u_linearColor == 1.0) { // 使用渐变颜色
- gl_FragColor = mix(u_sourceColor, u_targetColor, v_distance_ratio);
- } else { // 使用 color 方法传入的颜色
- gl_FragColor = v_color;
- }
-
-
- gl_FragColor.a *= u_opacity;
-
- if(u_aimate.x == Animate) {
- float animateSpeed = u_time / u_aimate.y; // 运动速度
- float alpha =1.0 - fract( mod(1.0- v_distance_ratio, u_aimate.z)* (1.0/ u_aimate.z) + u_time / u_aimate.y);
- alpha = (alpha + u_aimate.w -1.0) / u_aimate.w;
- // alpha = smoothstep(0., 1., alpha);
- alpha = clamp(alpha, 0.0, 1.0);
- gl_FragColor.a *= alpha;
- }
-}
\ No newline at end of file
diff --git a/packages/layers/src/line/shaders/line_arcmini_vert.glsl b/packages/layers/src/line/shaders/line_arcmini_vert.glsl
deleted file mode 100644
index 2b1019288e..0000000000
--- a/packages/layers/src/line/shaders/line_arcmini_vert.glsl
+++ /dev/null
@@ -1,101 +0,0 @@
-#define Animate 0.0
-
-attribute vec4 a_Color;
-attribute vec3 a_Position;
-attribute vec4 a_Instance;
-attribute float a_Size;
-uniform mat4 u_ModelMatrix;
-uniform mat4 u_Mvp;
-uniform float segmentNumber;
-uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
-varying vec4 v_color;
-
-uniform float u_lineDir: 1.0;
-
-// 偏移量
-uniform float u_thetaOffset: 0.314;
-
-uniform float u_opacity: 1.0;
-varying float v_distance_ratio;
-
-#pragma include "projection"
-#pragma include "project"
-#pragma include "picking"
-
-float bezier3(vec3 arr, float t) {
- float ut = 1. - t;
- return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t;
-}
-vec2 midPoint(vec2 source, vec2 target) {
- vec2 center = target - source;
- float r = length(center);
- float theta = atan(center.y, center.x);
- float thetaOffset = u_thetaOffset;
- float r2 = r / 2.0 / cos(thetaOffset);
- float theta2 = theta + thetaOffset;
- vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
- if(u_lineDir == 1.0) { // 正向
- return mid;
- } else { // 逆向
- // (mid + vmin)/2 = (s + t)/2
- vec2 vmid = source + target - mid;
- return vmid;
- }
- // return mid;
-}
-float getSegmentRatio(float index) {
- return smoothstep(0.0, 1.0, index / (segmentNumber - 1.));
-}
-vec2 interpolate (vec2 source, vec2 target, float t) {
- // if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
- vec2 mid = midPoint(source, target);
- vec3 x = vec3(source.x, mid.x, target.x);
- vec3 y = vec3(source.y, mid.y, target.y);
- return vec2(bezier3(x ,t), bezier3(y,t));
-}
-vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
- // normalized direction of the line
- vec2 dir_screenspace = normalize(line_clipspace);
- // rotate by 90 degrees
- dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
- vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
- return offset;
-}
-vec2 getNormal(vec2 line_clipspace, float offset_direction) {
- // normalized direction of the line
- vec2 dir_screenspace = normalize(line_clipspace);
- // rotate by 90 degrees
- dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
- return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction);
-}
-
-void main() {
- v_color = a_Color;
-
- vec2 source = a_Instance.rg; // 起始点
- vec2 target = a_Instance.ba; // 终点
- float segmentIndex = a_Position.x;
- float segmentRatio = getSegmentRatio(segmentIndex);
-
- float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
- float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
-
- v_distance_ratio = segmentIndex / segmentNumber;
-
- if(u_aimate.x == Animate && u_lineDir != 1.0) {
- v_distance_ratio = 1.0 - v_distance_ratio;
- }
-
- vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio), 0.0, 1.0));
- vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio), 0.0, 1.0));
- // v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
- //unProjCustomCoord
-
- vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
-
- if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
- gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
- } else {
- gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
- }
-}
diff --git a/packages/layers/src/mask/index.ts b/packages/layers/src/mask/index.ts
index d8d6b982b1..f6955905b8 100644
--- a/packages/layers/src/mask/index.ts
+++ b/packages/layers/src/mask/index.ts
@@ -7,10 +7,13 @@ export default class MaskLayer extends BaseLayer {
public buildModels() {
const shape = this.getModelType();
this.layerModel = new MaskModels[shape](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
return {
diff --git a/packages/layers/src/mask/models/fill.ts b/packages/layers/src/mask/models/fill.ts
index 2d27520774..3b9362f277 100644
--- a/packages/layers/src/mask/models/fill.ts
+++ b/packages/layers/src/mask/models/fill.ts
@@ -16,20 +16,19 @@ export default class MaskModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
- return [
- this.layer.buildLayerModel({
+ public async buildModels(callbackModel: (models: IModel[]) => void) {
+ this.layer
+ .buildLayerModel({
moduleName: 'mask',
vertexShader: mask_vert,
fragmentShader: mask_frag,
triangulation: polygonTriangulation,
- blend: this.getBlend(),
depth: { enable: false },
-
+ blend: this.getBlend(),
stencil: {
enable: true,
mask: 0xff,
@@ -44,8 +43,14 @@ export default class MaskModel extends BaseModel {
zpass: gl.REPLACE,
},
},
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/plugins/DataMappingPlugin.ts b/packages/layers/src/plugins/DataMappingPlugin.ts
index 6934d4f90e..726298e2d6 100644
--- a/packages/layers/src/plugins/DataMappingPlugin.ts
+++ b/packages/layers/src/plugins/DataMappingPlugin.ts
@@ -38,24 +38,43 @@ export default class DataMappingPlugin implements ILayerPlugin {
) {
layer.hooks.init.tap('DataMappingPlugin', () => {
// 初始化重新生成 map
- this.generateMaping(layer, { styleAttributeService });
+ const source = layer.getSource();
+ if (source.inited) {
+ this.generateMaping(layer, { styleAttributeService });
+ } else {
+ source.once('sourceUpdate', () => {
+ this.generateMaping(layer, { styleAttributeService });
+ });
+ }
+ // this.generateMaping(layer, { styleAttributeService });
});
layer.hooks.beforeRenderData.tap('DataMappingPlugin', () => {
layer.dataState.dataMappingNeedUpdate = false;
- this.generateMaping(layer, { styleAttributeService });
+ const source = layer.getSource();
+ if (source.inited) {
+ this.generateMaping(layer, { styleAttributeService });
+ } else {
+ source.once('sourceUpdate', () => {
+ this.generateMaping(layer, { styleAttributeService });
+ });
+ }
+
+ // this.generateMaping(layer, { styleAttributeService });
+
return true;
});
// remapping before render
layer.hooks.beforeRender.tap('DataMappingPlugin', () => {
- if (layer.layerModelNeedUpdate) {
+ const source = layer.getSource();
+ if (layer.layerModelNeedUpdate || !source || !source.inited) {
return;
}
const bottomColor = layer.getBottomColor();
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
const filter = styleAttributeService.getLayerStyleAttribute('filter');
- const { dataArray } = layer.getSource().data;
+ const { dataArray } = source.data;
const attributesToRemapping = attributes.filter(
(attribute) => attribute.needRemapping, // 如果filter变化
diff --git a/packages/layers/src/plugins/DataSourcePlugin.ts b/packages/layers/src/plugins/DataSourcePlugin.ts
index c480bb2ae6..5f9dd42ad3 100644
--- a/packages/layers/src/plugins/DataSourcePlugin.ts
+++ b/packages/layers/src/plugins/DataSourcePlugin.ts
@@ -5,7 +5,11 @@ import {
IMapService,
TYPES,
} from '@antv/l7-core';
-import Source, { DEFAULT_DATA, DEFAULT_PARSER } from '@antv/l7-source';
+import Source, {
+ DEFAULT_DATA,
+ DEFAULT_PARSER,
+ DEFAULT_SOURCE,
+} from '@antv/l7-source';
import { injectable } from 'inversify';
import 'reflect-metadata';
@@ -15,17 +19,28 @@ export default class DataSourcePlugin implements ILayerPlugin {
public apply(layer: ILayer) {
this.mapService = layer.getContainer().get(TYPES.IMapService);
layer.hooks.init.tap('DataSourcePlugin', () => {
- const source = layer.getSource();
+ let source = layer.getSource();
if (!source) {
// TODO: 允许用户不使用 layer 的 source 方法,在这里传入一个默认的替换的默认数据
- const { data, options } = layer.sourceOption || {
+ const defaultSourceConfig = DEFAULT_SOURCE[
+ layer.type as 'PointLayer' | 'LineLayer'
+ ] || {
data: DEFAULT_DATA,
options: DEFAULT_PARSER,
};
- layer.setSource(new Source(data, options));
+ const { data, options } = layer.sourceOption || defaultSourceConfig;
+ source = new Source(data, options);
+ layer.setSource(source);
}
-
- this.updateClusterData(layer);
+ if (source.inited) {
+ this.updateClusterData(layer);
+ } else {
+ source.once('sourceUpdate', () => {
+ this.updateClusterData(layer);
+ // TODO: layer.hooks.init.call();
+ });
+ }
+ // this.updateClusterData(layer);
});
// 检测数据是否需要更新
diff --git a/packages/layers/src/plugins/LayerModelPlugin.ts b/packages/layers/src/plugins/LayerModelPlugin.ts
index acb6624cfa..3b053236fb 100644
--- a/packages/layers/src/plugins/LayerModelPlugin.ts
+++ b/packages/layers/src/plugins/LayerModelPlugin.ts
@@ -6,23 +6,45 @@ import 'reflect-metadata';
*/
@injectable()
export default class LayerModelPlugin implements ILayerPlugin {
+ public initLayerModel(layer: ILayer) {
+ // 更新Model 配置项
+ layer.prepareBuildModel();
+ // 初始化 Model
+ layer.buildModels();
+ // emit layer model loaded
+ layer.emit('modelLoaded', null);
+ layer.styleNeedUpdate = false;
+ }
+
+ public prepareLayerModel(layer: ILayer) {
+ // 更新Model 配置项
+ layer.prepareBuildModel();
+ layer.clearModels();
+ // 初始化 Model
+ layer.buildModels();
+ // emit layer model loaded
+ layer.emit('modelLoaded', null);
+ layer.layerModelNeedUpdate = false;
+ }
+
public apply(layer: ILayer) {
layer.hooks.init.tap('LayerModelPlugin', () => {
- // 更新Model 配置项
- layer.prepareBuildModel();
- // 初始化 Model
- layer.buildModels();
- layer.styleNeedUpdate = false;
+ layer.inited = true;
+ const source = layer.getSource();
+ if (source.inited) {
+ this.initLayerModel(layer);
+ }
});
layer.hooks.beforeRenderData.tap('DataSourcePlugin', () => {
- // 更新Model 配置项
- layer.prepareBuildModel();
-
- layer.clearModels();
- // 初始化 Model
- layer.buildModels();
- layer.layerModelNeedUpdate = false;
+ const source = layer.getSource();
+ if (source.inited) {
+ this.prepareLayerModel(layer);
+ } else {
+ source.once('sourceUpdate', () => {
+ this.prepareLayerModel(layer);
+ });
+ }
return false;
});
}
diff --git a/packages/layers/src/plugins/PixelPickingPlugin.ts b/packages/layers/src/plugins/PixelPickingPlugin.ts
index cd899f660c..43600d9d24 100644
--- a/packages/layers/src/plugins/PixelPickingPlugin.ts
+++ b/packages/layers/src/plugins/PixelPickingPlugin.ts
@@ -35,8 +35,8 @@ export default class PixelPickingPlugin implements ILayerPlugin {
) {
// TODO: 由于 Shader 目前无法根据是否开启拾取进行内容修改,因此即使不开启也需要生成 a_PickingColor
layer.hooks.init.tap('PixelPickingPlugin', () => {
- // const { enablePicking, enableMultiPassRenderer } = layer.getLayerConfig();
- const enablePicking = true;
+ const { enablePicking, enableMultiPassRenderer } = layer.getLayerConfig();
+ // const enablePicking = true;
styleAttributeService.registerStyleAttribute({
name: 'pickingColor',
type: AttributeType.Attribute,
diff --git a/packages/layers/src/point/index.ts b/packages/layers/src/point/index.ts
index 3358f7d494..7492b53e69 100644
--- a/packages/layers/src/point/index.ts
+++ b/packages/layers/src/point/index.ts
@@ -8,10 +8,14 @@ export default class PointLayer extends BaseLayer {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new PointModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.layerService.updateLayerRenderList();
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
/**
@@ -62,7 +66,6 @@ export default class PointLayer extends BaseLayer {
fill: { blend: 'normal' },
extrude: {},
image: {},
- icon: {},
text: {
blend: 'normal',
},
@@ -84,7 +87,6 @@ export default class PointLayer extends BaseLayer {
'simplePoint',
'extrude',
'text',
- 'icon',
'vectorpoint',
'tile',
'earthFill',
@@ -93,9 +95,7 @@ export default class PointLayer extends BaseLayer {
if (this.layerSource.parser.type === 'mvt') {
return 'vectorpoint';
}
- if (this.layerType && PointTypes.includes(this.layerType)) {
- return this.layerType as PointType;
- }
+
// pointlayer
// 2D、 3d、 shape、image、text、normal、
const layerData = this.getEncodedData();
@@ -104,8 +104,8 @@ export default class PointLayer extends BaseLayer {
const item = layerData.find((fe: IEncodeFeature) => {
return fe.hasOwnProperty('shape');
});
+
if (!item) {
- // return 'normal';
return this.getModelTypeWillEmptyData();
} else {
const shape = item.shape;
@@ -118,21 +118,26 @@ export default class PointLayer extends BaseLayer {
if (shape === 'radar') {
return 'radar';
}
- if (shape === 'fillImage') {
+ if (this.layerType === 'fillImage') {
return 'fillImage';
}
if (shape2d?.indexOf(shape as string) !== -1) {
- return 'fill';
+ if (this.mapService.version === 'GLOBEL') {
+ return 'earthFill';
+ } else {
+ return 'fill';
+ }
}
if (shape3d?.indexOf(shape as string) !== -1) {
- return 'extrude';
+ if (this.mapService.version === 'GLOBEL') {
+ return 'earthExtrude';
+ } else {
+ return 'extrude';
+ }
}
if (iconMap.hasOwnProperty(shape as string)) {
return 'image';
}
- if (this.fontService.getGlyph(shape as string) !== '') {
- return 'icon';
- }
return 'text';
}
}
diff --git a/packages/layers/src/point/models/earthExtrude.ts b/packages/layers/src/point/models/earthExtrude.ts
index 03474379fa..b227d3bf3f 100644
--- a/packages/layers/src/point/models/earthExtrude.ts
+++ b/packages/layers/src/point/models/earthExtrude.ts
@@ -5,13 +5,12 @@ import {
ILayerConfig,
IModel,
} from '@antv/l7-core';
-import { getCullFace, rgb2arr } from '@antv/l7-utils';
+import { calculateCentroid, getCullFace, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import { PointExtrudeTriangulation } from '../../core/triangulation';
import { lglt2xyz } from '../../earth/utils';
-import { calculateCentroid } from '../../utils/geo';
import pointExtrudeFrag from '../shaders/earth/extrude_frag.glsl';
import pointExtrudeVert from '../shaders/earth/extrude_vert.glsl';
@@ -130,33 +129,37 @@ export default class ExtrudeModel extends BaseModel {
u_lightEnable: Number(lightEnable),
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
// GAODE1.x GAODE2.x MAPBOX
const {
- depth = true,
animateOption: { repeat = 1 },
} = this.layer.getLayerConfig() as ILayerConfig;
this.raiserepeat = repeat;
- return [
- this.layer.buildLayerModel({
- moduleName: 'pointExtrude2',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointEarthExtrude',
vertexShader: pointExtrudeVert,
fragmentShader: pointExtrudeFrag,
triangulation: PointExtrudeTriangulation,
- blend: this.getBlend(),
+ depth: { enable: true },
cull: {
enable: true,
face: getCullFace(this.mapService.version),
},
- depth: {
- enable: depth,
- },
- }),
- ];
+ blend: this.getBlend(),
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
this.dataTexture?.destroy();
diff --git a/packages/layers/src/point/models/earthFill.ts b/packages/layers/src/point/models/earthFill.ts
index 61f847a8c0..d83c078112 100644
--- a/packages/layers/src/point/models/earthFill.ts
+++ b/packages/layers/src/point/models/earthFill.ts
@@ -99,35 +99,29 @@ export default class FillModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
- const { frag, vert, type } = this.getShaders();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
this.layer.triangulation = GlobelPointFillTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'pointfill_' + type,
- vertexShader: vert,
- fragmentShader: frag,
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointEarthFill',
+ vertexShader: pointFillVert,
+ fragmentShader: pointFillFrag,
triangulation: GlobelPointFillTriangulation,
depth: { enable: true },
- blend: this.getBlend(),
- }),
- ];
- }
- /**
- * 根据 animateOption 的值返回对应的 shader 代码
- * @returns
- */
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: pointFillFrag,
- vert: pointFillVert,
- type: 'point_earth_fill',
- };
+ blend: this.getBlend(),
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/point/models/extrude.ts b/packages/layers/src/point/models/extrude.ts
index 62a55779e1..b75d4fd9ac 100644
--- a/packages/layers/src/point/models/extrude.ts
+++ b/packages/layers/src/point/models/extrude.ts
@@ -5,12 +5,11 @@ import {
ILayerConfig,
IModel,
} from '@antv/l7-core';
-import { getCullFace, rgb2arr } from '@antv/l7-utils';
+import { calculateCentroid, getCullFace, rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import { PointExtrudeTriangulation } from '../../core/triangulation';
-import { calculateCentroid } from '../../utils/geo';
import pointExtrudeFrag from '../shaders/extrude/extrude_frag.glsl';
import pointExtrudeVert from '../shaders/extrude/extrude_vert.glsl';
@@ -128,20 +127,21 @@ export default class ExtrudeModel extends BaseModel {
u_lightEnable: Number(lightEnable),
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public async buildModels(callbackModel: (models: IModel[]) => void) {
// GAODE1.x GAODE2.x MAPBOX
const {
depth = true,
animateOption: { repeat = 1 },
} = this.layer.getLayerConfig() as ILayerConfig;
this.raiserepeat = repeat;
- return [
- this.layer.buildLayerModel({
- moduleName: 'pointExtrude2',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointExtrude',
vertexShader: pointExtrudeVert,
fragmentShader: pointExtrudeFrag,
triangulation: PointExtrudeTriangulation,
@@ -153,8 +153,14 @@ export default class ExtrudeModel extends BaseModel {
depth: {
enable: depth,
},
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
this.dataTexture?.destroy();
diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts
index 40b7a19a62..8a4efa771e 100644
--- a/packages/layers/src/point/models/fill.ts
+++ b/packages/layers/src/point/models/fill.ts
@@ -9,11 +9,11 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
-import { $window, getMask } from '@antv/l7-utils';
+import { $window, getMask, PointFillTriangulation } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
-import { PointFillTriangulation } from '../../core/triangulation';
+// import { PointFillTriangulation } from '../../core/triangulation';
// animate pointLayer shader - support animate
import waveFillFrag from '../shaders/animate/wave_frag.glsl';
// static pointLayer shader - not support animate
@@ -21,6 +21,7 @@ import pointFillFrag from '../shaders/fill_frag.glsl';
import pointFillVert from '../shaders/fill_vert.glsl';
import { Version } from '@antv/l7-maps';
+
export default class FillModel extends BaseModel {
private meter2coord: number = 1;
private meteryScale: number = 1; // 兼容 mapbox
@@ -130,10 +131,9 @@ export default class FillModel extends BaseModel {
);
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateUnit('l7size');
-
- return this.buildModels();
+ this.buildModels(callbackModel);
}
/**
@@ -186,28 +186,44 @@ export default class FillModel extends BaseModel {
}
}
- public buildModels(): IModel[] {
+ public async buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
animateOption = { enable: false },
+ workerEnabled = false,
+ enablePicking,
+ shape2d,
} = this.layer.getLayerConfig() as Partial<
ILayerConfig & IPointLayerStyleOptions
>;
const { frag, vert, type } = this.getShaders(animateOption);
this.layer.triangulation = PointFillTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'pointfill_' + type,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: type,
vertexShader: vert,
fragmentShader: frag,
triangulation: PointFillTriangulation,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ workerEnabled,
+ workerOptions: {
+ modelType: type,
+ enablePicking,
+ shape2d,
+ },
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
/**
@@ -223,20 +239,20 @@ export default class FillModel extends BaseModel {
return {
frag: waveFillFrag,
vert: pointFillVert,
- type: 'wave',
+ type: 'pointWave',
};
default:
return {
frag: waveFillFrag,
vert: pointFillVert,
- type: 'wave',
+ type: 'pointWave',
};
}
} else {
return {
frag: pointFillFrag,
vert: pointFillVert,
- type: 'normal',
+ type: 'pointFill',
};
}
}
@@ -250,6 +266,8 @@ export default class FillModel extends BaseModel {
return [option.enable ? 0 : 1.0, option.speed || 1, option.rings || 3, 0];
}
protected registerBuiltinAttributes() {
+ const shape2d = this.layer.getLayerConfig().shape2d as string[];
+
this.styleAttributeService.registerStyleAttribute({
name: 'extrude',
type: AttributeType.Attribute,
@@ -299,7 +317,7 @@ export default class FillModel extends BaseModel {
attributeIdx: number,
) => {
const { size = 5 } = feature;
- return Array.isArray(size) ? [size[0]] : [size as number];
+ return Array.isArray(size) ? [size[0]] : [size];
},
},
});
@@ -324,7 +342,6 @@ export default class FillModel extends BaseModel {
attributeIdx: number,
) => {
const { shape = 2 } = feature;
- const shape2d = this.layer.getLayerConfig().shape2d as string[];
const shapeIndex = shape2d.indexOf(shape as string);
return [shapeIndex];
},
diff --git a/packages/layers/src/point/models/fillmage.ts b/packages/layers/src/point/models/fillmage.ts
index 802bba3006..2e71f737c1 100644
--- a/packages/layers/src/point/models/fillmage.ts
+++ b/packages/layers/src/point/models/fillmage.ts
@@ -127,7 +127,7 @@ export default class FillImageModel extends BaseModel {
);
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
@@ -144,7 +144,7 @@ export default class FillImageModel extends BaseModel {
this.calMeter2Coord();
}
- return this.buildModels();
+ this.buildModels(callbackModel);
}
/**
@@ -189,17 +189,17 @@ export default class FillImageModel extends BaseModel {
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
- const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
- moduleName: type,
- vertexShader: vert,
- fragmentShader: frag,
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointFillImage',
+ vertexShader: pointFillVert,
+ fragmentShader: pointFillFrag,
triangulation: PointFillTriangulation,
depth: { enable: false },
blend: this.getBlend(),
@@ -208,16 +208,14 @@ export default class FillImageModel extends BaseModel {
enable: true,
face: getCullFace(this.mapService.version),
},
- }),
- ];
- }
-
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: pointFillFrag,
- vert: pointFillVert,
- type: 'point_fillImage',
- };
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/point/models/icon-font.ts b/packages/layers/src/point/models/icon-font.ts
deleted file mode 100644
index c558ad22b2..0000000000
--- a/packages/layers/src/point/models/icon-font.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-import {
- AttributeType,
- gl,
- IEncodeFeature,
- IModel,
- IModelUniform,
- ITexture2D,
-} from '@antv/l7-core';
-
-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 IIconIFontStyleOptions {
- opacity: number;
- fontWeight: string;
- fontFamily: string;
-}
-
-export default class IconeModel extends BaseModel {
- private texture: ITexture2D;
-
- public getUninforms(): IModelUniform {
- const { opacity } = this.layer.getLayerConfig() as IIconIFontStyleOptions;
- return {
- u_opacity: opacity || 1.0,
- u_texture: this.texture,
- u_textSize: [1024, this.iconService.canvasHeight || 128],
- };
- }
-
- public initModels(): IModel[] {
- this.initIconFontGlyphs();
- this.registerBuiltinAttributes();
- this.updateTexture();
- this.iconService.on('imageUpdate', () => {
- this.updateTexture();
- this.layer.render(); // TODO 调用全局render
- });
- return [
- this.layer.buildLayerModel({
- moduleName: 'pointiconImage',
- vertexShader: pointImageVert,
- fragmentShader: pointImageFrag,
- triangulation: PointImageTriangulation,
- primitive: gl.POINTS,
- depth: { enable: false },
- blend: this.getBlend(),
- }),
- ];
- }
-
- public clearModels() {
- this.dataTexture?.destroy();
- }
-
- protected registerBuiltinAttributes() {
- // point layer size;
- this.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];
- },
- },
- });
-
- // point layer size;
- this.styleAttributeService.registerStyleAttribute({
- name: 'uv',
- type: AttributeType.Attribute,
- descriptor: {
- name: 'a_Uv',
- 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 { mapping } = this.fontService;
- const { shape } = feature;
- const icon = this.fontService.getGlyph(shape as string);
- const { x, y } = mapping[icon];
- return [x, y];
- },
- },
- });
- }
-
- private updateTexture() {
- const { createTexture2D } = this.rendererService;
- const { canvas } = this.fontService;
- this.texture = createTexture2D({
- data: canvas,
- mag: gl.LINEAR,
- min: gl.LINEAR,
- width: canvas.width,
- height: canvas.height,
- });
- }
-
- private initIconFontGlyphs() {
- const {
- fontWeight = 'normal',
- fontFamily = 'sans-serif',
- } = this.layer.getLayerConfig() as IIconIFontStyleOptions;
- const data = this.layer.getEncodedData();
- const characterSet: string[] = [];
- data.forEach((item: IEncodeFeature) => {
- let { shape = '' } = item;
- shape = shape.toString();
- const icon = this.fontService.getGlyph(shape);
- if (characterSet.indexOf(icon) === -1) {
- characterSet.push(icon);
- }
- });
- this.fontService.setFontOptions({
- characterSet,
- fontWeight,
- fontFamily,
- fontSize: 48,
- });
- }
-}
diff --git a/packages/layers/src/point/models/image.ts b/packages/layers/src/point/models/image.ts
index f7b2aff2a8..b4d6964d53 100644
--- a/packages/layers/src/point/models/image.ts
+++ b/packages/layers/src/point/models/image.ts
@@ -76,11 +76,11 @@ export default class ImageModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.registerBuiltinAttributes();
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
- return this.buildModels();
+ this.buildModels(callbackModel);
}
public clearModels() {
@@ -89,23 +89,30 @@ export default class ImageModel extends BaseModel {
this.iconService.off('imageUpdate', this.updateTexture);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
+
+ this.layer
+ .buildLayerModel({
moduleName: 'pointImage',
vertexShader: pointImageVert,
fragmentShader: pointImageFrag,
triangulation: PointImageTriangulation,
- primitive: gl.POINTS,
depth: { enable: false },
+ primitive: gl.POINTS,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
protected registerBuiltinAttributes() {
// point layer size;
diff --git a/packages/layers/src/point/models/index.ts b/packages/layers/src/point/models/index.ts
index 2e17487d3b..217a7fbe76 100644
--- a/packages/layers/src/point/models/index.ts
+++ b/packages/layers/src/point/models/index.ts
@@ -5,7 +5,6 @@ import EarthFillModel from './earthFill';
import ExtrudeModel from './extrude';
import FillModel from './fill';
import FillImageModel from './fillmage';
-import IconModel from './icon-font';
import IMageModel from './image';
import NormalModel from './normal';
import Radar from './radar';
@@ -22,7 +21,6 @@ export type PointType =
| 'simplePoint'
| 'extrude'
| 'text'
- | 'icon'
| 'vectorpoint'
| 'tile'
| 'earthFill'
@@ -37,7 +35,6 @@ const PointModels: { [key in PointType]: any } = {
simplePoint: SimplePopint,
extrude: ExtrudeModel,
text: TextModel,
- icon: IconModel,
vectorpoint: PointTileModel,
tile: TileFillModel,
earthFill: EarthFillModel,
diff --git a/packages/layers/src/point/models/normal.ts b/packages/layers/src/point/models/normal.ts
index 5eee353f13..11a1da0f0c 100644
--- a/packages/layers/src/point/models/normal.ts
+++ b/packages/layers/src/point/models/normal.ts
@@ -83,19 +83,20 @@ export default class NormalModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.layer.triangulation = PointTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'normalpoint',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointNormal',
vertexShader: normalVert,
fragmentShader: normalFrag,
triangulation: PointTriangulation,
@@ -103,8 +104,14 @@ export default class NormalModel extends BaseModel {
primitive: gl.POINTS,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/point/models/radar.ts b/packages/layers/src/point/models/radar.ts
index 969ee79f68..73c957cd6b 100644
--- a/packages/layers/src/point/models/radar.ts
+++ b/packages/layers/src/point/models/radar.ts
@@ -9,7 +9,7 @@ import {
IModel,
IModelUniform,
} from '@antv/l7-core';
-import { getCullFace, getMask } from '@antv/l7-utils';
+import { getMask } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
@@ -106,7 +106,7 @@ export default class RadarModel extends BaseModel {
);
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
unit = 'l7size',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
@@ -120,7 +120,7 @@ export default class RadarModel extends BaseModel {
this.calMeter2Coord();
}
- return this.buildModels();
+ this.buildModels(callbackModel);
}
/**
@@ -165,36 +165,29 @@ export default class RadarModel extends BaseModel {
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
- const { frag, vert, type } = this.getShaders();
- return [
- this.layer.buildLayerModel({
- moduleName: type,
- vertexShader: vert,
- fragmentShader: frag,
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointRadar',
+ vertexShader: pointFillVert,
+ fragmentShader: pointFillFrag,
triangulation: PointFillTriangulation,
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
- }
-
- /**
- * 根据 animateOption 的值返回对应的 shader 代码
- * @returns
- */
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: pointFillFrag,
- vert: pointFillVert,
- type: 'point_radar',
- };
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/point/models/simplePoint.ts b/packages/layers/src/point/models/simplePoint.ts
index 863bd8b4c8..d19bbe7cb4 100644
--- a/packages/layers/src/point/models/simplePoint.ts
+++ b/packages/layers/src/point/models/simplePoint.ts
@@ -93,19 +93,20 @@ export default class SimplePointModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.layer.triangulation = PointTriangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: 'simplepoint',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointSimple',
vertexShader: simplePointVert,
fragmentShader: simplePointFrag,
triangulation: PointTriangulation,
@@ -113,8 +114,14 @@ export default class SimplePointModel extends BaseModel {
primitive: gl.POINTS,
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/point/models/text.ts b/packages/layers/src/point/models/text.ts
index b0192b05be..ace9357245 100644
--- a/packages/layers/src/point/models/text.ts
+++ b/packages/layers/src/point/models/text.ts
@@ -6,12 +6,16 @@ import {
IModelUniform,
ITexture2D,
} from '@antv/l7-core';
-import { boundsContains, getMask, padBounds } from '@antv/l7-utils';
+import {
+ boundsContains,
+ calculateCentroid,
+ getMask,
+ padBounds,
+} from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPointLayerStyleOptions } from '../../core/interface';
import CollisionIndex from '../../utils/collision-index';
-import { calculateCentroid } from '../../utils/geo';
import {
getGlyphQuads,
IGlyphQuad,
@@ -172,8 +176,8 @@ export default class TextModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- this.layer.on('remapping', this.buildModels);
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.layer.on('remapping', this.mapping);
this.extent = this.textExtent();
const {
textAnchor = 'center',
@@ -183,20 +187,18 @@ export default class TextModel extends BaseModel {
textAnchor,
textAllowOverlap,
};
- return this.buildModels();
+ this.buildModels(callbackModel);
}
- public buildModels = () => {
+ public buildModels = async (callbackModel: (models: IModel[]) => void) => {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
- this.initGlyph();
- this.updateTexture();
- this.filterGlyphs();
- this.reBuildModel();
- return [
- this.layer.buildLayerModel({
+ this.mapping();
+
+ this.layer
+ .buildLayerModel({
moduleName: 'pointText',
vertexShader: textVert,
fragmentShader: textFrag,
@@ -204,8 +206,14 @@ export default class TextModel extends BaseModel {
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
};
public needUpdate() {
const {
@@ -229,7 +237,7 @@ export default class TextModel extends BaseModel {
public clearModels() {
this.texture?.destroy();
this.dataTexture?.destroy();
- this.layer.off('remapping', this.buildModels);
+ this.layer.off('remapping', this.mapping);
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
@@ -326,6 +334,13 @@ export default class TextModel extends BaseModel {
},
});
}
+
+ private mapping = () => {
+ this.initGlyph();
+ this.updateTexture();
+ this.filterGlyphs();
+ this.reBuildModel();
+ };
private textExtent(): [[number, number], [number, number]] {
const bounds = this.mapService.getBounds();
return padBounds(bounds, 0.5);
@@ -519,8 +534,8 @@ export default class TextModel extends BaseModel {
maskInside = true,
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
this.filterGlyphs();
- this.layer.models = [
- this.layer.buildLayerModel({
+ this.layer
+ .buildLayerModel({
moduleName: 'pointText',
vertexShader: textVert,
fragmentShader: textFrag,
@@ -528,7 +543,14 @@ export default class TextModel extends BaseModel {
depth: { enable: false },
blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ this.layer.models = [model];
+ this.layer.renderLayers();
+ })
+ .catch((err) => {
+ console.warn(err);
+ this.layer.models = [];
+ });
}
}
diff --git a/packages/layers/src/point/models/tile.ts b/packages/layers/src/point/models/tile.ts
index dad0629029..281fd48c81 100644
--- a/packages/layers/src/point/models/tile.ts
+++ b/packages/layers/src/point/models/tile.ts
@@ -112,7 +112,7 @@ export default class FillModel extends BaseModel {
);
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
unit = 'l7size',
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
@@ -126,7 +126,7 @@ export default class FillModel extends BaseModel {
this.calMeter2Coord();
}
- return this.buildModels();
+ this.buildModels(callbackModel);
}
/**
@@ -171,44 +171,41 @@ export default class FillModel extends BaseModel {
}
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
+ workerEnabled = false,
} = this.layer.getLayerConfig() as Partial<
ILayerConfig & IPointLayerStyleOptions
>;
- const { frag, vert, type } = this.getShaders();
this.layer.triangulation = PointFillTriangulation;
- return [
- this.layer.buildLayerModel({
- // primitive: gl.POINTS,
- moduleName: type,
- vertexShader: vert,
- fragmentShader: frag,
+ this.layer
+ .buildLayerModel({
+ moduleName: 'pointTile',
+ vertexShader: point_tile_vert,
+ fragmentShader: point_tile_frag,
triangulation: PointFillTriangulation,
depth: { enable: false },
- blend: this.getBlend(),
- stencil: getMask(mask, maskInside),
cull: {
enable: true,
face: getCullFace(this.mapService.version),
},
- }),
- ];
- }
-
- /**
- * 根据 animateOption 的值返回对应的 shader 代码
- * @returns
- */
- public getShaders(): { frag: string; vert: string; type: string } {
- return {
- frag: point_tile_frag,
- vert: point_tile_vert,
- type: 'point_fill_tile',
- };
+ blend: this.getBlend(),
+ stencil: getMask(mask, maskInside),
+ workerEnabled,
+ workerOptions: {
+ modelType: 'pointTile',
+ },
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/polygon/index.ts b/packages/layers/src/polygon/index.ts
index 3aac6fe8fe..089d0f5509 100644
--- a/packages/layers/src/polygon/index.ts
+++ b/packages/layers/src/polygon/index.ts
@@ -8,10 +8,13 @@ export default class PolygonLayer extends BaseLayer {
public buildModels() {
const shape = this.getModelType();
this.layerModel = new PolygonModels[shape](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
return {
diff --git a/packages/layers/src/polygon/models/extrude.ts b/packages/layers/src/polygon/models/extrude.ts
index 3f35210347..0dd1d710b7 100644
--- a/packages/layers/src/polygon/models/extrude.ts
+++ b/packages/layers/src/polygon/models/extrude.ts
@@ -93,28 +93,33 @@ export default class ExtrudeModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.loadTexture();
- return this.buildModels();
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
const { frag, vert, type } = this.getShaders();
-
- return [
- this.layer.buildLayerModel({
+ this.layer
+ .buildLayerModel({
moduleName: type,
vertexShader: vert,
fragmentShader: frag,
triangulation: PolygonExtrudeTriangulation,
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public getShaders() {
diff --git a/packages/layers/src/polygon/models/fill.ts b/packages/layers/src/polygon/models/fill.ts
index 2a4eac2a60..5952591200 100644
--- a/packages/layers/src/polygon/models/fill.ts
+++ b/packages/layers/src/polygon/models/fill.ts
@@ -2,17 +2,15 @@ import {
AttributeType,
gl,
IEncodeFeature,
+ ILayerConfig,
IModel,
Triangulation,
} from '@antv/l7-core';
-import { getMask } from '@antv/l7-utils';
+import { getMask, polygonFillTriangulation } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { IPolygonLayerStyleOptions } from '../../core/interface';
-import {
- polygonTriangulation,
- polygonTriangulationWithCenter,
-} from '../../core/triangulation';
+import { polygonTriangulationWithCenter } from '../../core/triangulation';
import polygon_frag from '../shaders/polygon_frag.glsl';
import polygon_linear_frag from '../shaders/polygon_linear_frag.glsl';
import polygon_linear_vert from '../shaders/polygon_linear_vert.glsl';
@@ -69,28 +67,44 @@ export default class FillModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const { frag, vert, triangulation, type } = this.getModelParams();
const {
mask = false,
maskInside = true,
- } = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
+ workerEnabled = false,
+ enablePicking,
+ } = this.layer.getLayerConfig() as Partial<
+ ILayerConfig & IPolygonLayerStyleOptions
+ >;
this.layer.triangulation = triangulation;
- return [
- this.layer.buildLayerModel({
+ this.layer
+ .buildLayerModel({
moduleName: type,
vertexShader: vert,
fragmentShader: frag,
triangulation,
- blend: this.getBlend(),
+ primitive: gl.TRIANGLES,
depth: { enable: false },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ workerEnabled,
+ workerOptions: {
+ modelType: type,
+ enablePicking,
+ },
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
@@ -147,15 +161,15 @@ export default class FillModel extends BaseModel {
return {
frag: polygon_linear_frag,
vert: polygon_linear_vert,
- type: 'polygon_linear',
+ type: 'polygonLinear',
triangulation: polygonTriangulationWithCenter,
};
} else {
return {
frag: polygon_frag,
vert: polygon_vert,
- type: 'polygon_fill',
- triangulation: polygonTriangulation,
+ type: 'polygonFill',
+ triangulation: polygonFillTriangulation,
};
}
}
diff --git a/packages/layers/src/polygon/models/ocean.ts b/packages/layers/src/polygon/models/ocean.ts
index 683f78ec6e..e8b883d88b 100644
--- a/packages/layers/src/polygon/models/ocean.ts
+++ b/packages/layers/src/polygon/models/ocean.ts
@@ -70,26 +70,33 @@ export default class OceanModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.loadTexture();
- return this.buildModels();
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'polygon_ocean',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'polygonOcean',
vertexShader: ocean_vert,
fragmentShader: ocean_frag,
triangulation: polygonTriangulation,
+ primitive: gl.TRIANGLES,
depth: { enable: false },
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/polygon/models/tile.ts b/packages/layers/src/polygon/models/tile.ts
index 93a497f9fd..fc2b6df5dd 100644
--- a/packages/layers/src/polygon/models/tile.ts
+++ b/packages/layers/src/polygon/models/tile.ts
@@ -53,28 +53,34 @@ export default class FillModel extends BaseModel {
};
}
- public initModels(): IModel[] {
- return this.buildModels();
+ public initModels(callbackModel: (models: IModel[]) => void) {
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
- const { frag, vert, triangulation, type } = this.getModelParams();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
- this.layer.triangulation = triangulation;
- return [
- this.layer.buildLayerModel({
- moduleName: type,
- vertexShader: vert,
- fragmentShader: frag,
- triangulation,
- blend: this.getBlend(),
+ this.layer.triangulation = polygonTriangulation;
+ this.layer
+ .buildLayerModel({
+ moduleName: 'polygonTile',
+ vertexShader: polygon_tile_vert,
+ fragmentShader: polygon_tile_frag,
+ triangulation: polygonTriangulation,
+ primitive: gl.TRIANGLES,
depth: { enable: false },
+ blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
@@ -84,18 +90,4 @@ export default class FillModel extends BaseModel {
protected registerBuiltinAttributes() {
//
}
-
- private getModelParams(): {
- frag: string;
- vert: string;
- type: string;
- triangulation: Triangulation;
- } {
- return {
- frag: polygon_tile_frag,
- vert: polygon_tile_vert,
- type: 'polygon_tile',
- triangulation: polygonTriangulation,
- };
- }
}
diff --git a/packages/layers/src/polygon/models/water.ts b/packages/layers/src/polygon/models/water.ts
index 8e92ca5cc7..0a4c52e29c 100644
--- a/packages/layers/src/polygon/models/water.ts
+++ b/packages/layers/src/polygon/models/water.ts
@@ -64,26 +64,33 @@ export default class WaterModel extends BaseModel {
};
}
- public initModels(): IModel[] {
+ public initModels(callbackModel: (models: IModel[]) => void) {
this.loadTexture();
- return this.buildModels();
+ this.buildModels(callbackModel);
}
- public buildModels(): IModel[] {
+ public buildModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
- return [
- this.layer.buildLayerModel({
- moduleName: 'polygon_water',
+ this.layer
+ .buildLayerModel({
+ moduleName: 'polygonWater',
vertexShader: water_vert,
fragmentShader: water_frag,
triangulation: polygonTriangulation,
+ primitive: gl.TRIANGLES,
depth: { enable: false },
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public clearModels() {
diff --git a/packages/layers/src/raster/image.ts b/packages/layers/src/raster/image.ts
deleted file mode 100644
index 0722b79a59..0000000000
--- a/packages/layers/src/raster/image.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-// import {
-// AttributeType,
-// gl,
-// IEncodeFeature,
-// ILayer,
-// ITexture2D,
-// } from '@antv/l7-core';
-// import BaseLayer from '../core/BaseLayer';
-// import { RasterImageTriangulation } from '../core/triangulation';
-// import rasterImageFrag from './shaders/image_frag.glsl';
-// import rasterImageVert from './shaders/image_vert.glsl';
-// interface IRaterLayerStyleOptions {
-// opacity: number;
-// }
-
-// export default class ImageLayer extends BaseLayer {
-// public type: string = 'ImageLayer';
-// protected texture: ITexture2D;
-
-// protected getConfigSchema() {
-// return {
-// properties: {
-// opacity: {
-// type: 'number',
-// minimum: 0,
-// maximum: 1,
-// },
-// },
-// };
-// }
-
-// protected renderModels() {
-// const { opacity } = this.getLayerConfig();
-// if (this.texture) {
-// this.models.forEach((model) =>
-// model.draw({
-// uniforms: {
-// u_opacity: opacity || 1,
-// u_texture: this.texture,
-// },
-// }),
-// );
-// }
-
-// return this;
-// }
-
-// public buildModels() {
-// this.registerBuiltinAttributes();
-// const source = this.getSource();
-// const { createTexture2D } = this.rendererService;
-// source.data.images.then((imageData: HTMLImageElement[]) => {
-// this.texture = createTexture2D({
-// data: imageData[0],
-// width: imageData[0].width,
-// height: imageData[0].height,
-// });
-// this.renderModels();
-// });
-// this.models = [
-// this.buildLayerModel({
-// moduleName: 'RasterImage',
-// vertexShader: rasterImageVert,
-// fragmentShader: rasterImageFrag,
-// triangulation: RasterImageTriangulation,
-// primitive: gl.TRIANGLES,
-// depth: { enable: false },
-// blend: {
-// enable: true,
-// func: {
-// srcRGB: gl.SRC_ALPHA,
-// srcAlpha: 1,
-// dstRGB: gl.ONE_MINUS_SRC_ALPHA,
-// dstAlpha: 1,
-// },
-// },
-// }),
-// ];
-// }
-
-// private registerBuiltinAttributes() {
-// // point layer size;
-// this.styleAttributeService.registerStyleAttribute({
-// name: 'uv',
-// type: AttributeType.Attribute,
-// descriptor: {
-// name: 'a_Uv',
-// 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,
-// ) => {
-// return [vertex[3], vertex[4]];
-// },
-// },
-// });
-// }
-// }
diff --git a/packages/layers/src/raster/index.ts b/packages/layers/src/raster/index.ts
index f86c6d4b91..754eec0c51 100644
--- a/packages/layers/src/raster/index.ts
+++ b/packages/layers/src/raster/index.ts
@@ -6,10 +6,13 @@ export default class RaterLayer extends BaseLayer {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new RasterModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getConfigSchema() {
return {
diff --git a/packages/layers/src/raster/models/raster.ts b/packages/layers/src/raster/models/raster.ts
index ba604ec8f0..4c7766ad26 100644
--- a/packages/layers/src/raster/models/raster.ts
+++ b/packages/layers/src/raster/models/raster.ts
@@ -2,6 +2,7 @@ import {
AttributeType,
gl,
IEncodeFeature,
+ IModel,
ITexture2D,
lazyInject,
TYPES,
@@ -42,7 +43,7 @@ export default class RasterModel extends BaseModel {
};
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
mask = false,
maskInside = true,
@@ -69,22 +70,28 @@ export default class RasterModel extends BaseModel {
height: imageData.height,
flipY: false,
});
- return [
- this.layer.buildLayerModel({
- moduleName: 'RasterImageData',
+
+ this.layer
+ .buildLayerModel({
+ moduleName: 'rasterImageData',
vertexShader: rasterVert,
fragmentShader: rasterFrag,
triangulation: RasterImageTriangulation,
primitive: gl.TRIANGLES,
depth: { enable: false },
- blend: this.getBlend(),
stencil: getMask(mask, maskInside),
- }),
- ];
+ })
+ .then((model) => {
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
public clearModels(): void {
diff --git a/packages/layers/src/raster/raster2d.ts b/packages/layers/src/raster/raster2d.ts
deleted file mode 100644
index 1820ba87ba..0000000000
--- a/packages/layers/src/raster/raster2d.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { AttributeType, gl, IEncodeFeature, ITexture2D } from '@antv/l7-core';
-import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
-import BaseLayer from '../core/BaseLayer';
-import { RasterImageTriangulation } from '../core/triangulation';
-import rasterImageFrag from './shaders/raster_2d_frag.glsl';
-import rasterImageVert from './shaders/raster_2d_vert.glsl';
-interface IRasterLayerStyleOptions {
- opacity: number;
- min: number;
- max: number;
- rampColors: IColorRamp;
-}
-
-export default class Raster2dLayer extends BaseLayer {
- public type: string = 'RasterLayer';
- protected rasterTexture: ITexture2D;
- protected colorTexture: ITexture2D;
-
- public buildModels() {
- this.registerBuiltinAttributes();
- const source = this.getSource();
- const { createTexture2D } = this.rendererService;
- const parserDataItem = this.getSource().data.dataArray[0];
- this.rasterTexture = createTexture2D({
- data: parserDataItem.data,
- width: parserDataItem.width,
- height: parserDataItem.height,
- format: gl.LUMINANCE,
- type: gl.FLOAT,
- aniso: 4,
- });
- const { rampColors } = this.getLayerConfig();
- const imageData = generateColorRamp(rampColors as IColorRamp);
- this.colorTexture = createTexture2D({
- data: imageData.data,
- width: imageData.width,
- height: imageData.height,
- flipY: false,
- });
- this.models = [
- this.buildLayerModel({
- moduleName: 'Raster3DImage',
- vertexShader: rasterImageVert,
- fragmentShader: rasterImageFrag,
- triangulation: RasterImageTriangulation,
- primitive: gl.TRIANGLES,
- depth: { enable: false },
- blend: {
- enable: true,
- func: {
- srcRGB: gl.SRC_ALPHA,
- srcAlpha: 1,
- dstRGB: gl.ONE_MINUS_SRC_ALPHA,
- dstAlpha: 1,
- },
- },
- }),
- ];
- }
- public renderModels() {
- const { opacity } = this.getLayerConfig();
- const parserDataItem = this.getSource().data.dataArray[0];
- const { min, max } = parserDataItem;
- if (this.rasterTexture) {
- this.models.forEach((model) =>
- model.draw({
- uniforms: {
- u_opacity: opacity || 1,
- u_texture: this.rasterTexture,
- u_min: min,
- u_max: max,
- u_colorTexture: this.colorTexture,
- },
- }),
- );
- }
-
- return this;
- }
-
- protected getConfigSchema() {
- return {
- properties: {
- opacity: {
- type: 'number',
- minimum: 0,
- maximum: 1,
- },
- },
- };
- }
-
- private registerBuiltinAttributes() {
- // point layer size;
- this.styleAttributeService.registerStyleAttribute({
- name: 'uv',
- type: AttributeType.Attribute,
- descriptor: {
- name: 'a_Uv',
- 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,
- ) => {
- return [vertex[3], vertex[4]];
- },
- },
- });
- }
-}
diff --git a/packages/layers/src/tile/manager/tileLayerManager.ts b/packages/layers/src/tile/manager/tileLayerManager.ts
index be208dbc7f..903b3b2d63 100644
--- a/packages/layers/src/tile/manager/tileLayerManager.ts
+++ b/packages/layers/src/tile/manager/tileLayerManager.ts
@@ -150,6 +150,7 @@ export class TileLayerManager implements ITileLayerManager {
positions: [0, 0.25, 0.5, 0.75, 1.0],
},
featureId = 'id',
+ workerEnabled = false,
sourceLayer,
pixelConstant = 0,
@@ -197,6 +198,8 @@ export class TileLayerManager implements ITileLayerManager {
domain,
rampColors,
rampColorsData: this.rampColorsData,
+ // worker
+ workerEnabled,
pixelConstant,
pixelConstantR,
diff --git a/packages/layers/src/tile/manager/tilePickerManager.ts b/packages/layers/src/tile/manager/tilePickerManager.ts
index aae59a0f36..aaa8cb0fff 100644
--- a/packages/layers/src/tile/manager/tilePickerManager.ts
+++ b/packages/layers/src/tile/manager/tilePickerManager.ts
@@ -50,6 +50,7 @@ export default class TilePickManager extends EventEmitter
framebuffer: null,
});
layer.masks.map((m: ILayer) => {
+ m.hooks.beforeRenderData.call();
m.hooks.beforeRender.call();
m.render();
m.hooks.afterRender.call();
diff --git a/packages/layers/src/tile/tileFactory/base.ts b/packages/layers/src/tile/tileFactory/base.ts
index 8ed24e330a..06fc03c65d 100644
--- a/packages/layers/src/tile/tileFactory/base.ts
+++ b/packages/layers/src/tile/tileFactory/base.ts
@@ -129,10 +129,6 @@ export default class TileFactory implements ITileFactory {
// set scale
this.setScale(layer);
- // console.log(this.parentLayer.getScaleOptions())
- // console.log()
-
- // console.log(this.parentLayer.tileLayer.scaleCfg)
// set scale attribute field
this.setStyleAttributeField(layer, 'shape', shape);
diff --git a/packages/layers/src/tile/tileFactory/point.ts b/packages/layers/src/tile/tileFactory/point.ts
index 69e66fdad8..2c1b1dc2a7 100644
--- a/packages/layers/src/tile/tileFactory/point.ts
+++ b/packages/layers/src/tile/tileFactory/point.ts
@@ -23,14 +23,12 @@ export default class VectorPolygonTile extends TileFactory {
layerIDList: [],
};
}
-
const layer = this.createLayer({
tile,
initOptions,
vectorTileLayer,
source: source as Source,
});
-
return {
layers: [layer],
layerIDList: [layer.id],
diff --git a/packages/layers/src/tile/tileFactory/rasterDataLayer.ts b/packages/layers/src/tile/tileFactory/rasterDataLayer.ts
index c2afa386b9..36bebcd234 100644
--- a/packages/layers/src/tile/tileFactory/rasterDataLayer.ts
+++ b/packages/layers/src/tile/tileFactory/rasterDataLayer.ts
@@ -9,11 +9,14 @@ export default class RasterTiffLayer extends BaseLayer<
public buildModels() {
const model = this.getModelType();
this.layerModel = new model(this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getModelType() {
diff --git a/packages/layers/src/tile/tileFactory/vectorLayer.ts b/packages/layers/src/tile/tileFactory/vectorLayer.ts
index f764fcaeeb..841a42d076 100644
--- a/packages/layers/src/tile/tileFactory/vectorLayer.ts
+++ b/packages/layers/src/tile/tileFactory/vectorLayer.ts
@@ -31,11 +31,14 @@ export default class VectorLayer extends BaseLayer<
public buildModels() {
const model = this.getModelType();
this.layerModel = new model(this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
protected getModelType() {
diff --git a/packages/layers/src/utils/geo.ts b/packages/layers/src/utils/geo.ts
deleted file mode 100644
index 366ce9dc8d..0000000000
--- a/packages/layers/src/utils/geo.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-type Position = number[];
-import { isNumber } from 'lodash';
-export function calculateCentroid(
- coord: Position | Position[] | Position[][],
-): Position {
- // let pos = coord as Position;
- if (isNumber(coord[0])) {
- return coord as Position;
- } else if (isNumber(coord[0][0])) {
- throw new Error('当前数据不支持标注');
- } else if (isNumber(coord[0][0][0])) {
- const coords = coord as Position[][];
- let xSum = 0;
- let ySum = 0;
- let len = 0;
- coords.forEach((coor: Position[]) => {
- coor.forEach((pos) => {
- xSum += pos[0];
- ySum += pos[1];
- len++;
- });
- });
- return [xSum / len, ySum / len, 0];
- } else {
- throw new Error('当前数据不支持标注');
- }
-}
-
-/**
- * 计算
- * @param points
- * @returns
- */
-export function calculatePointsCenterAndRadius(points: number[]) {
- let maxX = points[0];
- let maxY = points[1];
- let minX = points[0];
- let minY = points[1];
- let xCount = 0;
- let yCount = 0;
- let pCount = 0;
-
- for (let i = 0; i < points.length; i += 2) {
- const x = points[i];
- const y = points[i + 1];
- if (x && y) {
- maxX = Math.max(x, maxX);
- maxY = Math.max(y, maxY);
- minX = Math.min(x, minX);
- minY = Math.min(y, minY);
- xCount += x;
- yCount += y;
- pCount++;
- }
- }
- return {
- center: [xCount / pCount, yCount / pCount],
- radius: Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2)) / 2,
- };
-}
diff --git a/packages/layers/src/wind/index.ts b/packages/layers/src/wind/index.ts
index c4e00b62da..4ccab5b618 100644
--- a/packages/layers/src/wind/index.ts
+++ b/packages/layers/src/wind/index.ts
@@ -6,10 +6,13 @@ export default class WindLayer extends BaseLayer {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new WindModels[modelType](this);
- this.models = this.layerModel.initModels();
+ this.layerModel.initModels((models) => {
+ this.models = models;
+ this.renderLayers();
+ });
}
public rebuildModels() {
- this.models = this.layerModel.buildModels();
+ this.layerModel.buildModels((models) => (this.models = models));
}
public renderModels() {
diff --git a/packages/layers/src/wind/models/wind.ts b/packages/layers/src/wind/models/wind.ts
index dc0979f7d5..ff2707ccd4 100644
--- a/packages/layers/src/wind/models/wind.ts
+++ b/packages/layers/src/wind/models/wind.ts
@@ -50,7 +50,7 @@ export default class WindModel extends BaseModel {
throw new Error('Method not implemented.');
}
- public initModels() {
+ public initModels(callbackModel: (models: IModel[]) => void) {
const {
uMin = -21.32,
uMax = 26.8,
@@ -114,18 +114,24 @@ export default class WindModel extends BaseModel {
this.layerService.renderLayers();
});
- this.colorModel = this.layer.buildLayerModel({
- moduleName: 'WindLayer',
- vertexShader: WindVert,
- fragmentShader: WindFrag,
- triangulation: RasterImageTriangulation,
- primitive: gl.TRIANGLES,
- depth: { enable: false },
- blend: this.getBlend(),
- stencil: getMask(mask, maskInside),
- });
-
- return [this.colorModel];
+ this.layer
+ .buildLayerModel({
+ moduleName: 'wind',
+ vertexShader: WindVert,
+ fragmentShader: WindFrag,
+ triangulation: RasterImageTriangulation,
+ primitive: gl.TRIANGLES,
+ depth: { enable: false },
+ blend: this.getBlend(),
+ })
+ .then((model) => {
+ this.colorModel = model;
+ callbackModel([model]);
+ })
+ .catch((err) => {
+ console.warn(err);
+ callbackModel([]);
+ });
}
public getWindSize() {
@@ -143,8 +149,8 @@ export default class WindModel extends BaseModel {
return { imageWidth, imageHeight };
}
- public buildModels() {
- return this.initModels();
+ public buildModels(callbackModel: (models: IModel[]) => void) {
+ this.initModels(callbackModel);
}
public clearModels(): void {
@@ -254,7 +260,8 @@ export default class WindModel extends BaseModel {
m.render();
m.hooks.afterRender.call();
});
- this.colorModel.draw({
+
+ this.colorModel?.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_texture: this.texture,
diff --git a/packages/map/package.json b/packages/map/package.json
index bb80994b4a..886efd1a6c 100644
--- a/packages/map/package.json
+++ b/packages/map/package.json
@@ -27,9 +27,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"test": "jest"
},
"bugs": {
diff --git a/packages/maps/package.json b/packages/maps/package.json
index 728d2e45a8..0054282d10 100644
--- a/packages/maps/package.json
+++ b/packages/maps/package.json
@@ -18,9 +18,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "xiaoiver",
diff --git a/packages/mini/package.json b/packages/mini/package.json
index e3ad017147..c2c764cb55 100644
--- a/packages/mini/package.json
+++ b/packages/mini/package.json
@@ -17,9 +17,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "antv",
diff --git a/packages/renderer/package.json b/packages/renderer/package.json
index 8c72893d2b..d66f63d3c8 100644
--- a/packages/renderer/package.json
+++ b/packages/renderer/package.json
@@ -15,9 +15,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "xiaoiver",
diff --git a/packages/scene/package.json b/packages/scene/package.json
index f414656150..da7ec75763 100644
--- a/packages/scene/package.json
+++ b/packages/scene/package.json
@@ -15,9 +15,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "xiaoiver",
diff --git a/packages/source/package.json b/packages/source/package.json
index 074ef7ac3b..7aec61b71f 100644
--- a/packages/source/package.json
+++ b/packages/source/package.json
@@ -15,9 +15,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"lint:ts": "run-p -c lint:ts-*",
"test": "jest",
"sync": "tnpm sync"
diff --git a/packages/source/src/index.ts b/packages/source/src/index.ts
index e951743583..2d7063b771 100644
--- a/packages/source/src/index.ts
+++ b/packages/source/src/index.ts
@@ -2,7 +2,7 @@ import { registerParser, registerTransform } from './factory';
import csv from './parser/csv';
import geojson from './parser/geojson';
import image from './parser/image';
-import json, { defaultData, defaultParser } from './parser/json';
+import json, { defaultData, defaultParser, defaultSource } from './parser/json';
import mapboxVectorTile from './parser/mvt';
import raster from './parser/raster';
import rasterTile from './parser/raster-tile';
@@ -37,6 +37,7 @@ export {
export * from './interface';
+export const DEFAULT_SOURCE = defaultSource;
export const DEFAULT_DATA = defaultData;
export const DEFAULT_PARSER = defaultParser;
diff --git a/packages/source/src/parser/json.ts b/packages/source/src/parser/json.ts
index 5d0596bb01..c1baa293d0 100644
--- a/packages/source/src/parser/json.ts
+++ b/packages/source/src/parser/json.ts
@@ -53,6 +53,38 @@ export default function json(data: IJsonData, cfg: IParserCfg): IParserData {
};
}
+export const defaultSource = {
+ PointLayer: {
+ data: [],
+ options: {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ },
+ LineLayer: {
+ data: [
+ {
+ lng1: 100,
+ lat1: 30.0,
+ lng2: 130,
+ lat2: 30,
+ },
+ ],
+ options: {
+ parser: {
+ type: 'json',
+ x: 'lng1',
+ y: 'lat1',
+ x1: 'lng2',
+ y1: 'lat2',
+ },
+ },
+ },
+};
+
// TODO: 提供默认数据和解析器
export const defaultData = [
{
diff --git a/packages/source/src/source.ts b/packages/source/src/source.ts
index eff19a2097..295d917594 100644
--- a/packages/source/src/source.ts
+++ b/packages/source/src/source.ts
@@ -34,6 +34,7 @@ function mergeCustomizer(objValue: any, srcValue: any) {
}
export default class Source extends EventEmitter implements ISource {
+ public inited: boolean = false;
public data: IParserData;
public center: [number, number];
// 数据范围
@@ -75,15 +76,6 @@ export default class Source extends EventEmitter implements ISource {
this.originData = data;
this.initCfg(cfg);
- this.hooks.init.tap('parser', () => {
- this.excuteParser();
- });
- this.hooks.init.tap('cluster', () => {
- this.initCluster();
- });
- this.hooks.init.tap('transform', () => {
- this.executeTrans();
- });
this.init();
}
@@ -188,7 +180,6 @@ export default class Source extends EventEmitter implements ISource {
this.dataArrayChanged = false;
this.initCfg(options);
this.init();
- this.emit('update');
}
public destroy() {
@@ -200,6 +191,19 @@ export default class Source extends EventEmitter implements ISource {
this.tileset?.destroy();
}
+ private handleData() {
+ return new Promise((resolve, reject) => {
+ try {
+ this.excuteParser();
+ this.initCluster();
+ this.executeTrans();
+ resolve({});
+ } catch (err) {
+ reject(err);
+ }
+ });
+ }
+
private initCfg(option?: ISourceCFG) {
this.cfg = mergeWith(this.cfg, option, mergeCustomizer);
const cfg = this.cfg;
@@ -222,7 +226,12 @@ export default class Source extends EventEmitter implements ISource {
}
private init() {
- this.hooks.init.call(this);
+ // this.hooks.init.call(this);
+ this.inited = false;
+ this.handleData().then(() => {
+ this.inited = true;
+ this.emit('sourceUpdate');
+ });
}
/**
diff --git a/packages/three/package.json b/packages/three/package.json
index 60eca49271..74ffaa0283 100644
--- a/packages/three/package.json
+++ b/packages/three/package.json
@@ -31,9 +31,9 @@
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"build:cdn": "yarn rollup -c",
"lint:ts": "run-p -c lint:ts-*",
"test": "jest",
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 32e4153736..e927e7a13f 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -9,15 +9,16 @@
"files": [
"lib",
"es",
+ "dist",
"README.md"
],
"scripts": {
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
- "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
- "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:cjs": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "build:esm": "cross-env BABEL_ENV=esm NODE_ENV=production babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
+ "watch": "cross-env BABEL_ENV=cjs NODE_ENV=production babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"sync": "tnpm sync"
},
"author": "lzxue",
@@ -26,10 +27,13 @@
"@babel/runtime": "^7.7.7",
"@turf/bbox-polygon": "^6.5.0",
"@turf/helpers": "^6.1.4",
- "d3-color": "^1.4.0"
+ "d3-color": "^1.4.0",
+ "web-worker-helper": "^0.0.3",
+ "earcut": "^2.2.1"
},
"devDependencies": {
- "@types/d3-color": "^1.2.2"
+ "@types/d3-color": "^1.2.2",
+ "@types/earcut": "^2.1.0"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",
"publishConfig": {
diff --git a/packages/utils/src/geo.ts b/packages/utils/src/geo.ts
index 464e263e38..dfb1618932 100644
--- a/packages/utils/src/geo.ts
+++ b/packages/utils/src/geo.ts
@@ -6,6 +6,7 @@ import {
radiansToLength,
Units,
} from '@turf/helpers';
+import { isNumber } from './math';
export type IBounds = [[number, number], [number, number]];
interface ILngLat {
@@ -357,3 +358,66 @@ export function flow(coords: Point[], time: number = 100) {
});
return path;
}
+
+type Position = number[];
+
+export function calculateCentroid(
+ coord: Position | Position[] | Position[][],
+): Position {
+ // let pos = coord as Position;
+ if (isNumber(coord[0])) {
+ return coord as Position;
+ // @ts-ignore
+ } else if (isNumber(coord[0][0])) {
+ throw new Error('当前数据不支持标注');
+ // @ts-ignore
+ } else if (isNumber(coord[0][0][0])) {
+ const coords = coord as Position[][];
+ let xSum = 0;
+ let ySum = 0;
+ let len = 0;
+ coords.forEach((coor: Position[]) => {
+ coor.forEach((pos) => {
+ xSum += pos[0];
+ ySum += pos[1];
+ len++;
+ });
+ });
+ return [xSum / len, ySum / len, 0];
+ } else {
+ throw new Error('当前数据不支持标注');
+ }
+}
+
+/**
+ * 计算
+ * @param points
+ * @returns
+ */
+export function calculatePointsCenterAndRadius(points: number[]) {
+ let maxX = points[0];
+ let maxY = points[1];
+ let minX = points[0];
+ let minY = points[1];
+ let xCount = 0;
+ let yCount = 0;
+ let pCount = 0;
+
+ for (let i = 0; i < points.length; i += 2) {
+ const x = points[i];
+ const y = points[i + 1];
+ if (x && y) {
+ maxX = Math.max(x, maxX);
+ maxY = Math.max(y, maxY);
+ minX = Math.min(x, minX);
+ minY = Math.min(y, minY);
+ xCount += x;
+ yCount += y;
+ pCount++;
+ }
+ }
+ return {
+ center: [xCount / pCount, yCount / pCount],
+ radius: Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2)) / 2,
+ };
+}
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index ca457a70c5..74055a7c30 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -14,6 +14,8 @@ export * from './event';
export * from './color';
export * from './anchor';
export * from './stencli';
+export * from './worker-helper';
export * from './cull';
export * from './env';
export * from './tileset-manager';
+export * from './workers/triangulation';
diff --git a/packages/utils/src/math.ts b/packages/utils/src/math.ts
new file mode 100644
index 0000000000..f98e5617c8
--- /dev/null
+++ b/packages/utils/src/math.ts
@@ -0,0 +1,3 @@
+export function isNumber(n: any) {
+ return typeof n === 'number';
+}
diff --git a/packages/utils/src/worker-helper/index.ts b/packages/utils/src/worker-helper/index.ts
new file mode 100644
index 0000000000..5733fe9f6f
--- /dev/null
+++ b/packages/utils/src/worker-helper/index.ts
@@ -0,0 +1,44 @@
+import { WorkerFarm } from 'web-worker-helper';
+// @ts-ignore
+import WorkerInlineSource from '../../dist/l7-utils.worker.js';
+import { WorkerSourceMap } from '../workers';
+import { getWorkerSource, registerWorkerSource } from './worker-map';
+
+export { WorkerSourceMap };
+
+const L7_WORKER_NAME = 'l7-worker';
+const WORKER_MAX_CONCURRENCY = 3;
+const WORKER_REUSE = true;
+
+export function setL7WorkerSource(workerSource: string) {
+ registerWorkerSource(L7_WORKER_NAME, workerSource);
+}
+
+function getL7WorkerSource(): string {
+ const workerSource = getWorkerSource(L7_WORKER_NAME);
+
+ if (!workerSource) {
+ throw new Error(`get worker failed by workerName: ${L7_WORKER_NAME}.`);
+ }
+
+ return workerSource;
+}
+
+export async function executeWorkerTask(workerType: string, data: any) {
+ const source = getL7WorkerSource();
+ const workerFarm = WorkerFarm.getWorkerFarm({
+ maxConcurrency: WORKER_MAX_CONCURRENCY,
+ reuseWorkers: WORKER_REUSE,
+ });
+ const workerPool = workerFarm.getWorkerPool({ name: L7_WORKER_NAME, source });
+ const job = await workerPool.startJob(L7_WORKER_NAME, (myJob, type, myData) =>
+ myJob.done(myData),
+ );
+
+ job.postMessage('process', { input: { workerType, data } });
+
+ const result = await job.result;
+ return result.result;
+}
+
+setL7WorkerSource(WorkerInlineSource);
diff --git a/packages/utils/src/worker-helper/worker-map.ts b/packages/utils/src/worker-helper/worker-map.ts
new file mode 100644
index 0000000000..63ecf27ba8
--- /dev/null
+++ b/packages/utils/src/worker-helper/worker-map.ts
@@ -0,0 +1,10 @@
+const WorkerSourceMap = new Map();
+
+export function registerWorkerSource(workerName: string, workerSource: string) {
+ WorkerSourceMap.set(workerName, workerSource);
+}
+
+export function getWorkerSource(workerName: string) {
+ const workerSource = WorkerSourceMap.get(workerName);
+ return workerSource;
+}
diff --git a/packages/utils/src/workers/commonFeatureFunc.ts b/packages/utils/src/workers/commonFeatureFunc.ts
new file mode 100644
index 0000000000..696f254024
--- /dev/null
+++ b/packages/utils/src/workers/commonFeatureFunc.ts
@@ -0,0 +1,30 @@
+import { IEncodeFeature, IVertexAttributeDescriptor } from '@antv/l7-core';
+
+export function a_Color(feature: IEncodeFeature, featureIdx: number) {
+ const { color } = feature;
+ return !color || !color.length ? [1, 1, 1, 1] : color;
+}
+
+export function a_Position(
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+) {
+ return vertex.length === 2
+ ? [vertex[0], vertex[1], 0]
+ : [vertex[0], vertex[1], vertex[2]];
+}
+
+export function a_filter(feature: IEncodeFeature, featureIdx: number) {
+ const { filter } = feature;
+ return filter ? [1] : [0];
+}
+
+export function a_vertexId(
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+) {
+ return [featureIdx];
+}
diff --git a/packages/utils/src/workers/extrude_polyline.ts b/packages/utils/src/workers/extrude_polyline.ts
new file mode 100644
index 0000000000..60cc74642f
--- /dev/null
+++ b/packages/utils/src/workers/extrude_polyline.ts
@@ -0,0 +1,866 @@
+import { vec2, vec3 } from 'gl-matrix';
+import { aProjectFlat } from '../geo';
+const tmp = vec2.create();
+const capEnd = vec2.create();
+const lineA = vec2.create();
+const lineB = vec2.create();
+const tangent = vec2.create();
+
+export function computeMiter(
+ lineTangent: vec2,
+ miter: vec2,
+ start: vec2,
+ end: vec2,
+ halfThick: number,
+): [number, vec2] {
+ vec2.add(lineTangent, start, end);
+ vec2.normalize(lineTangent, lineTangent);
+ miter = vec2.fromValues(-lineTangent[1], lineTangent[0]);
+ const tmpvec = vec2.fromValues(-start[1], start[0]);
+ return [halfThick / vec2.dot(miter, tmpvec), miter];
+}
+export function computeNormal(out: vec2, dir: vec2) {
+ return vec2.set(out, -dir[1], dir[0]);
+}
+
+export function direction(out: vec2, a: vec2, b: vec2) {
+ vec2.sub(out, a, b);
+ vec2.normalize(out, out);
+ return out;
+}
+
+function isPointEqual(a: vec2, b: vec2) {
+ return a[0] === b[0] && a[1] === b[1];
+}
+
+function getArrayUnique(matrix: number[][]) {
+ const map = new Map();
+ for (let i = 0; i < matrix.length; i++) {
+ const key = matrix[0].toString() + '-' + matrix[1].toString();
+ if (map.get(key)) {
+ matrix.splice(i, 1);
+ i++;
+ } else {
+ map.set(key, key);
+ }
+ }
+ return matrix;
+}
+
+export interface IExtrudeLineOption {
+ join: string;
+ cap: string;
+ dash: boolean;
+ closed: boolean;
+ indexOffset: number;
+ miterLimit: number;
+ thickness: number;
+}
+export default class ExtrudePolyline {
+ public complex: {
+ positions: number[];
+ indices: number[];
+ normals: number[];
+ startIndex: number;
+ indexes: number[];
+ };
+ private join: string;
+ private cap: string;
+ private miterLimit: number;
+ private thickness: number;
+ private normal: vec2 | null;
+ private lastFlip: number = -1;
+ private miter: vec2 = vec2.fromValues(0, 0);
+ private started: boolean = false;
+ private dash: boolean = false;
+ private totalDistance: number = 0;
+ private currentIndex: number = 0;
+
+ constructor(opts: Partial = {}) {
+ this.join = opts.join || 'miter';
+ this.cap = opts.cap || 'butt';
+ this.miterLimit = opts.miterLimit || 10;
+ this.thickness = opts.thickness || 1;
+ this.dash = opts.dash || false;
+ this.complex = {
+ positions: [],
+ indices: [],
+ normals: [],
+ startIndex: 0,
+ indexes: [],
+ };
+ }
+
+ public extrude_gaode2(points: number[][], originPoints: number[][]) {
+ const complex = this.complex;
+ if (points.length <= 1) {
+ return complex;
+ }
+ this.lastFlip = -1;
+ this.started = false;
+ this.normal = null;
+ this.totalDistance = 0;
+ // 去除数组里重复的点
+ // points = getArrayUnique(points);
+ const total = points.length;
+ let count = complex.startIndex;
+ for (let i = 1; i < total; i++) {
+ const last = points[i - 1];
+ last.push(originPoints[i - 1][2] ?? 0);
+ // @ts-ignore
+ const originLast = originPoints[i - 1] as vec3;
+
+ const cur = points[i];
+ cur.push(originPoints[i][2] ?? 0);
+ // @ts-ignore
+ const originCur = originPoints[i] as vec3;
+
+ const next =
+ i < points.length - 1
+ ? [...points[i + 1], originPoints[i + 1][2] ?? 0]
+ : null;
+ const originNext =
+ i < originPoints.length - 1 ? originPoints[i + 1] : null;
+
+ const amt = this.segment_gaode2(
+ complex,
+ count,
+ // @ts-ignore
+ last as vec3,
+ // @ts-ignore
+ cur as vec3,
+ // @ts-ignore
+ next as vec3,
+ // @ts-ignore
+ originLast,
+ originCur,
+ // @ts-ignore
+ originNext as vec3,
+ );
+ count += amt;
+ }
+ if (this.dash) {
+ for (let i = 0; i < complex.positions.length / 6; i++) {
+ complex.positions[i * 6 + 5] = this.totalDistance;
+ }
+ }
+ complex.startIndex = complex.positions.length / 6;
+ return complex;
+ }
+ public simpleExtrude_gaode2(points: number[][], originPoints: number[][]) {
+ const complex = this.complex;
+ if (points.length <= 1) {
+ return complex;
+ }
+ this.lastFlip = -1;
+ this.started = false;
+ this.normal = null;
+ this.totalDistance = 0;
+ // 去除数组里重复的点
+ // points = getArrayUnique(points);
+ const total = points.length;
+ let count = complex.startIndex;
+ for (let i = 1; i < total; i++) {
+ const last = points[i - 1];
+ last.push(originPoints[i - 1][2] ?? 0);
+ // @ts-ignore
+ const originLast = originPoints[i - 1] as vec3;
+
+ const cur = points[i];
+ cur.push(originPoints[i][2] ?? 0);
+ // @ts-ignore
+ const originCur = originPoints[i] as vec3;
+
+ const next =
+ i < points.length - 1
+ ? [...points[i + 1], originPoints[i + 1][2] ?? 0]
+ : null;
+ const originNext =
+ i < originPoints.length - 1 ? originPoints[i + 1] : null;
+
+ const amt = this.simpleSegment(
+ complex,
+ count,
+ // @ts-ignore
+ last as vec3,
+ // @ts-ignore
+ cur as vec3,
+ // @ts-ignore
+ next as vec3,
+ // @ts-ignore
+ originLast,
+ originCur,
+ // @ts-ignore
+ originNext as vec3,
+ );
+ count += amt;
+ }
+ if (this.dash) {
+ for (let i = 0; i < complex.positions.length / 6; i++) {
+ complex.positions[i * 6 + 5] = this.totalDistance;
+ }
+ }
+ complex.startIndex = complex.positions.length / 6;
+ return complex;
+ }
+ public extrude(points: number[][]) {
+ const complex = this.complex;
+ if (points.length <= 1) {
+ return complex;
+ }
+ this.lastFlip = -1;
+ this.started = false;
+ this.normal = null;
+ this.totalDistance = 0;
+ // 去除数组里重复的点
+ // points = getArrayUnique(points);
+ const total = points.length;
+ let count = complex.startIndex;
+ for (let i = 1; i < total; i++) {
+ const last = points[i - 1] as vec3;
+ const cur = points[i] as vec3;
+ const next = i < points.length - 1 ? points[i + 1] : null;
+ const amt = this.segment(complex, count, last, cur, next as vec3);
+ count += amt;
+ }
+ if (this.dash) {
+ for (let i = 0; i < complex.positions.length / 6; i++) {
+ complex.positions[i * 6 + 5] = this.totalDistance;
+ }
+ }
+ complex.startIndex = complex.positions.length / 6;
+ return complex;
+ }
+ public simpleExtrude(points: number[][]) {
+ const complex = this.complex;
+ if (points.length <= 1) {
+ return complex;
+ }
+ this.lastFlip = -1;
+ this.started = false;
+ this.normal = null;
+ this.totalDistance = 0;
+
+ const total = points.length;
+ let count = complex.startIndex;
+ for (let i = 1; i < total; i++) {
+ const last = points[i - 1] as vec3;
+ const cur = points[i] as vec3;
+ const next = i < points.length - 1 ? points[i + 1] : null;
+ const amt = this.simpleSegment(complex, count, last, cur, next as vec3);
+ count += amt;
+ }
+
+ if (this.dash) {
+ for (let i = 0; i < complex.positions.length / 6; i++) {
+ complex.positions[i * 6 + 5] = this.totalDistance;
+ }
+ }
+ complex.startIndex = complex.positions.length / 6;
+ return complex;
+ }
+ private segment_gaode2(
+ complex: any,
+ index: number,
+ last: vec3,
+ cur: vec3,
+ next: vec3,
+ originLast: vec3,
+ originCur: vec3,
+ originNext: vec3,
+ ) {
+ let count = 0;
+ const indices = complex.indices;
+ const positions = complex.positions;
+ const normals = complex.normals;
+ const capSquare = this.cap === 'square';
+ const joinBevel = this.join === 'bevel';
+ const flatCur = aProjectFlat([originCur[0], originCur[1]]) as [
+ number,
+ number,
+ ];
+ const flatLast = aProjectFlat([originLast[0], originLast[1]]) as [
+ number,
+ number,
+ ];
+ // @ts-ignore
+ direction(lineA, cur as vec3, last as vec3);
+ let segmentDistance = 0;
+ if (this.dash) {
+ // @ts-ignore
+ segmentDistance = this.lineSegmentDistance(flatCur, flatLast);
+ this.totalDistance += segmentDistance;
+ }
+
+ if (!this.normal) {
+ this.normal = vec2.create();
+ computeNormal(this.normal, lineA);
+ }
+ if (!this.started) {
+ this.started = true;
+
+ // if the end cap is type square, we can just push the verts out a bit
+ if (capSquare) {
+ // vec2.scaleAndAdd(capEnd, last, lineA, -this.thickness);
+ const out1 = vec2.create();
+ const out2 = vec2.create();
+ vec2.add(out1, this.normal, lineA);
+ vec2.add(out2, this.normal, lineA);
+ normals.push(out2[0], out2[1], 0);
+ normals.push(out1[0], out1[1], 0);
+ positions.push(
+ last[0],
+ last[1],
+ last[2] | 0,
+ this.totalDistance - segmentDistance,
+ -this.thickness,
+ last[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ last[0],
+ last[1],
+ last[2] | 0,
+ this.totalDistance - segmentDistance,
+ this.thickness,
+ last[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ last,
+ this.normal,
+ this.thickness,
+ this.totalDistance - segmentDistance,
+ );
+ }
+ }
+
+ indices.push(index + 0, index + 1, index + 2);
+
+ if (!next) {
+ computeNormal(this.normal, lineA);
+ if (capSquare) {
+ const out1 = vec2.create();
+ const out2 = vec2.create();
+ vec2.sub(out2, lineA, this.normal);
+ vec2.add(out1, lineA, this.normal);
+
+ normals.push(out2[0], out2[1], 0);
+ normals.push(out1[0], out1[1], 0);
+
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ this.normal,
+ this.thickness,
+ this.totalDistance,
+ );
+ }
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+ count += 2;
+ } else {
+ // @ts-ignore
+ if (isPointEqual(cur as vec2, next as vec2)) {
+ vec2.add(
+ // @ts-ignore
+ next as vec2,
+ // @ts-ignore
+ cur as vec2,
+ vec2.normalize(
+ // @ts-ignore
+ next as vec2,
+ // @ts-ignore
+ vec2.subtract(next as vec2, cur as vec2, last as vec2),
+ ),
+ );
+ }
+ // @ts-ignore
+ direction(lineB, next as vec2, cur as vec2);
+ // stores tangent & miter
+
+ const [miterLen, miter] = computeMiter(
+ tangent,
+ vec2.create(),
+ lineA,
+ lineB,
+ this.thickness,
+ );
+ // normal(tmp, lineA)
+
+ // get orientation
+ let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1;
+ let bevel = joinBevel;
+ if (!bevel && this.join === 'miter') {
+ const limit = miterLen;
+ if (limit > this.miterLimit) {
+ bevel = true;
+ }
+ }
+
+ if (bevel) {
+ normals.push(this.normal[0], this.normal[1], 0);
+ normals.push(miter[0], miter[1], 0);
+
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ -this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ indices.push(
+ ...(this.lastFlip !== -flip
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+
+ // now add the bevel triangle
+ indices.push(index + 2, index + 3, index + 4);
+
+ computeNormal(tmp, lineB);
+ vec2.copy(this.normal, tmp); // store normal for next round
+ normals.push(this.normal[0], this.normal[1], 0);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ -this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ count += 3;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ miter,
+ miterLen,
+ this.totalDistance,
+ );
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+
+ flip = -1;
+
+ // the miter is now the normal for our next join
+ vec2.copy(this.normal, miter);
+ count += 2;
+ }
+ this.lastFlip = flip;
+ }
+ return count;
+ }
+ private simpleSegment(
+ complex: any,
+ index: number,
+ last: vec3,
+ cur: vec3,
+ next: vec3,
+ ) {
+ let count = 0;
+ const indices = complex.indices;
+ const positions = complex.positions;
+ const normals = complex.normals;
+ const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number];
+ const flatLast = aProjectFlat([last[0], last[1]]) as [number, number];
+ // @ts-ignore
+ direction(lineA, flatCur, flatLast);
+ let segmentDistance = 0;
+ if (this.dash) {
+ // @ts-ignore
+ segmentDistance = this.lineSegmentDistance(flatCur, flatLast);
+ this.totalDistance += segmentDistance;
+ }
+
+ if (!this.normal) {
+ this.normal = vec2.create();
+ computeNormal(this.normal, lineA);
+ }
+ if (!this.started) {
+ this.started = true;
+
+ this.extrusions(
+ positions,
+ normals,
+ last,
+ this.normal,
+ this.thickness,
+ this.totalDistance - segmentDistance,
+ );
+ }
+
+ indices.push(index + 0, index + 1, index + 2);
+
+ if (!next) {
+ computeNormal(this.normal, lineA);
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ this.normal,
+ this.thickness,
+ this.totalDistance,
+ );
+
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+ count += 2;
+ } else {
+ const flatNext = aProjectFlat([next[0], next[1]]) as [number, number];
+ if (isPointEqual(flatCur, flatNext)) {
+ vec2.add(
+ flatNext,
+ flatCur,
+ vec2.normalize(flatNext, vec2.subtract(flatNext, flatCur, flatLast)),
+ );
+ }
+ direction(lineB, flatNext, flatCur);
+
+ // stores tangent & miter
+
+ const [miterLen, miter] = computeMiter(
+ tangent,
+ vec2.create(),
+ lineA,
+ lineB,
+ this.thickness,
+ );
+ // normal(tmp, lineA)
+
+ // get orientation
+ let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1;
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ miter,
+ miterLen,
+ this.totalDistance,
+ );
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+
+ flip = -1;
+
+ // the miter is now the normal for our next join
+ vec2.copy(this.normal, miter);
+ count += 2;
+ this.lastFlip = flip;
+ }
+ return count;
+ }
+ private segment(
+ complex: any,
+ index: number,
+ last: vec3,
+ cur: vec3,
+ next: vec3,
+ ) {
+ let count = 0;
+ const indices = complex.indices;
+ const positions = complex.positions;
+ const normals = complex.normals;
+ const capSquare = this.cap === 'square';
+ const joinBevel = this.join === 'bevel';
+ const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number];
+ const flatLast = aProjectFlat([last[0], last[1]]) as [number, number];
+ // @ts-ignore
+ direction(lineA, flatCur, flatLast);
+ let segmentDistance = 0;
+ if (this.dash) {
+ // @ts-ignore
+ segmentDistance = this.lineSegmentDistance(flatCur, flatLast);
+ this.totalDistance += segmentDistance;
+ }
+
+ if (!this.normal) {
+ this.normal = vec2.create();
+ computeNormal(this.normal, lineA);
+ }
+ if (!this.started) {
+ this.started = true;
+
+ // if the end cap is type square, we can just push the verts out a bit
+ if (capSquare) {
+ // vec2.scaleAndAdd(capEnd, last, lineA, -this.thickness);
+ const out1 = vec2.create();
+ const out2 = vec2.create();
+ vec2.add(out1, this.normal, lineA);
+ vec2.add(out2, this.normal, lineA);
+ normals.push(out2[0], out2[1], 0);
+ normals.push(out1[0], out1[1], 0);
+ positions.push(
+ last[0],
+ last[1],
+ last[2] | 0,
+ this.totalDistance - segmentDistance,
+ -this.thickness,
+ last[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ last[0],
+ last[1],
+ last[2] | 0,
+ this.totalDistance - segmentDistance,
+ this.thickness,
+ last[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ // this.extrusions(positions, normals, last, out, this.thickness);
+ // last = capEnd;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ last,
+ this.normal,
+ this.thickness,
+ this.totalDistance - segmentDistance,
+ );
+ }
+ }
+
+ indices.push(index + 0, index + 1, index + 2);
+
+ if (!next) {
+ computeNormal(this.normal, lineA);
+ if (capSquare) {
+ // vec2.scaleAndAdd(capEnd, cur, lineA, this.thickness);
+ // cur = capEnd;
+ const out1 = vec2.create();
+ const out2 = vec2.create();
+ vec2.sub(out2, lineA, this.normal);
+ vec2.add(out1, lineA, this.normal);
+ // this.extrusions(positions, normals, cur, out, this.thickness);
+ normals.push(out2[0], out2[1], 0);
+ normals.push(out1[0], out1[1], 0);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ this.normal,
+ this.thickness,
+ this.totalDistance,
+ );
+ }
+
+ // this.extrusions(positions, normals, cur, this.normal, this.thickness);
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+ count += 2;
+ } else {
+ const flatNext = aProjectFlat([next[0], next[1]]) as [number, number];
+ if (isPointEqual(flatCur, flatNext)) {
+ vec2.add(
+ flatNext,
+ flatCur,
+ vec2.normalize(flatNext, vec2.subtract(flatNext, flatCur, flatLast)),
+ );
+ }
+ direction(lineB, flatNext, flatCur);
+
+ // stores tangent & miter
+
+ const [miterLen, miter] = computeMiter(
+ tangent,
+ vec2.create(),
+ lineA,
+ lineB,
+ this.thickness,
+ );
+ // normal(tmp, lineA)
+
+ // get orientation
+ let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1;
+ let bevel = joinBevel;
+ if (!bevel && this.join === 'miter') {
+ const limit = miterLen;
+ if (limit > this.miterLimit) {
+ bevel = true;
+ }
+ }
+
+ if (bevel) {
+ normals.push(this.normal[0], this.normal[1], 0);
+ normals.push(miter[0], miter[1], 0);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ -this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ indices.push(
+ ...(this.lastFlip !== -flip
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+
+ // now add the bevel triangle
+ indices.push(index + 2, index + 3, index + 4);
+
+ computeNormal(tmp, lineB);
+ vec2.copy(this.normal, tmp); // store normal for next round
+ normals.push(this.normal[0], this.normal[1], 0);
+ positions.push(
+ cur[0],
+ cur[1],
+ cur[2] | 0,
+ this.totalDistance,
+ -this.thickness * flip,
+ cur[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ count += 3;
+ } else {
+ this.extrusions(
+ positions,
+ normals,
+ cur,
+ miter,
+ miterLen,
+ this.totalDistance,
+ );
+ indices.push(
+ ...(this.lastFlip === 1
+ ? [index, index + 2, index + 3]
+ : [index + 2, index + 1, index + 3]),
+ );
+
+ flip = -1;
+
+ // the miter is now the normal for our next join
+ vec2.copy(this.normal, miter);
+ count += 2;
+ }
+ this.lastFlip = flip;
+ }
+ return count;
+ }
+ private extrusions(
+ positions: number[],
+ normals: number[],
+ point: vec3, // 顶点
+ normal: vec2, // 法向量
+ thickness: number, // 高度
+ distanceRadio: number,
+ ) {
+ normals.push(normal[0], normal[1], 0);
+ normals.push(normal[0], normal[1], 0);
+ positions.push(
+ point[0],
+ point[1],
+ point[2] | 0,
+ distanceRadio,
+ -thickness,
+ point[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ positions.push(
+ point[0],
+ point[1],
+ point[2] | 0,
+ distanceRadio,
+ thickness,
+ point[2] | 0,
+ );
+ this.complex.indexes.push(this.currentIndex);
+ this.currentIndex++;
+ }
+ private lineSegmentDistance(b1: vec3, a1: vec3) {
+ const dx = a1[0] - b1[0];
+ const dy = a1[1] - b1[1];
+ return Math.sqrt(dx * dx + dy * dy);
+ }
+}
diff --git a/packages/utils/src/workers/index.ts b/packages/utils/src/workers/index.ts
new file mode 100644
index 0000000000..c98775f6fa
--- /dev/null
+++ b/packages/utils/src/workers/index.ts
@@ -0,0 +1,30 @@
+import { createWorker } from 'web-worker-helper';
+import { lineModel } from './lineModel';
+import { pointFillModel } from './pointFillModel';
+import { polygonFillModel } from './polygonFillModel';
+
+// current support worker
+export const WorkerSourceMap = {
+ pointFill: pointFillModel,
+ line: lineModel,
+ polygonFill: polygonFillModel,
+};
+
+const workerTypes: Record Promise> = {
+ ...WorkerSourceMap,
+};
+
+async function worker({ workerType, data }: { workerType: string; data: any }) {
+ if (workerTypes[workerType]) {
+ return workerTypes[workerType](data);
+ }
+
+ return Promise.reject(
+ new Error(`Worker with type "${workerType}" non-existent.`),
+ );
+}
+
+createWorker(worker);
+
+// export default createWorker(worker);
+export { createWorker, worker };
diff --git a/packages/utils/src/workers/lineModel.ts b/packages/utils/src/workers/lineModel.ts
new file mode 100644
index 0000000000..70f528034d
--- /dev/null
+++ b/packages/utils/src/workers/lineModel.ts
@@ -0,0 +1,175 @@
+import { IEncodeFeature, IVertexAttributeDescriptor } from '@antv/l7-core';
+import { encodePickingColor } from '../color';
+import { a_Color, a_filter, a_Position, a_vertexId } from './commonFeatureFunc';
+import { LineTriangulation as triangulation } from './triangulation';
+
+export const lineModel = async ({
+ descriptors,
+ features,
+ enablePicking,
+ iconMap,
+}: {
+ descriptors: IVertexAttributeDescriptor[];
+ features: IEncodeFeature[];
+ enablePicking: boolean;
+ iconMap: any;
+}) => {
+ const updateFuncs = {
+ // fixed feature func
+ a_Color,
+ a_Position,
+ filter: a_filter,
+ a_vertexId,
+ a_PickingColor: (feature: IEncodeFeature, featureIdx: number) => {
+ const { id } = feature;
+ return enablePicking ? encodePickingColor(id as number) : [0, 0, 0];
+ },
+
+ // pointFill feature func
+ a_DistanceAndIndex: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ normal: number[],
+ vertexIndex?: number,
+ ) => {
+ return vertexIndex === undefined
+ ? [vertex[3], 10]
+ : [vertex[3], vertexIndex];
+ },
+ a_Total_Distance: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ return [vertex[5]];
+ },
+ a_Size: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ const { size: pointSize = 1 } = feature;
+ return Array.isArray(pointSize)
+ ? [pointSize[0], pointSize[1]]
+ : [pointSize as number, 0];
+ },
+ a_Normal: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ normal: number[],
+ ) => {
+ return normal;
+ },
+ a_Miter: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ return [vertex[4]];
+ },
+ a_iconMapUV: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ const { texture } = feature;
+ const { x, y } = iconMap[texture as string] || { x: 0, y: 0 };
+ return [x, y];
+ },
+ };
+
+ const featureLayout: {
+ sizePerElement: number;
+ elements: Array<{
+ featureIdx: number;
+ vertices: number[];
+ normals: number[];
+ offset: number;
+ indexes?: number[];
+ }>;
+ } = {
+ sizePerElement: 0,
+ elements: [],
+ };
+
+ let verticesNum = 0;
+ const indices: number[] = [];
+ let size = 3;
+ features.forEach((feature: IEncodeFeature, featureIdx: number) => {
+ const {
+ indices: indicesForCurrentFeature,
+ vertices: verticesForCurrentFeature,
+ // @ts-ignore
+ normals: normalsForCurrentFeature,
+ size: vertexSize,
+ // @ts-ignore
+ indexes,
+ } = triangulation(feature);
+ indicesForCurrentFeature.forEach((i) => {
+ indices.push(i + verticesNum);
+ });
+ size = vertexSize;
+ const verticesNumForCurrentFeature =
+ verticesForCurrentFeature.length / vertexSize;
+
+ featureLayout.sizePerElement = size;
+
+ featureLayout.elements.push({
+ featureIdx,
+ vertices: verticesForCurrentFeature,
+ normals: normalsForCurrentFeature,
+ offset: verticesNum,
+ });
+
+ verticesNum += verticesNumForCurrentFeature;
+ for (
+ let vertexIdx = 0;
+ vertexIdx < verticesNumForCurrentFeature;
+ vertexIdx++
+ ) {
+ const normal =
+ normalsForCurrentFeature?.slice(vertexIdx * 3, vertexIdx * 3 + 3) || [];
+ const vertice = verticesForCurrentFeature.slice(
+ vertexIdx * vertexSize,
+ vertexIdx * vertexSize + vertexSize,
+ );
+
+ let vertexIndex = 0;
+ if (indexes && indexes[vertexIdx] !== undefined) {
+ vertexIndex = indexes[vertexIdx];
+ }
+
+ descriptors.forEach((descriptor, attributeIdx: number) => {
+ // @ts-ignore
+ if (descriptor && updateFuncs[descriptor.name]) {
+ // @ts-ignore
+ descriptor.buffer.data.push(
+ // @ts-ignore
+ ...updateFuncs[descriptor.name](
+ feature,
+ featureIdx,
+ vertice,
+ vertexIdx,
+ normal,
+ vertexIndex,
+ ),
+ );
+ }
+ });
+ }
+ });
+
+ return {
+ descriptors,
+ featureLayout,
+ indices,
+ };
+};
diff --git a/packages/utils/src/workers/pointFillModel.ts b/packages/utils/src/workers/pointFillModel.ts
new file mode 100644
index 0000000000..5d3ca5164c
--- /dev/null
+++ b/packages/utils/src/workers/pointFillModel.ts
@@ -0,0 +1,149 @@
+import { IEncodeFeature, IVertexAttributeDescriptor } from '@antv/l7-core';
+import { encodePickingColor } from '../color';
+import { a_Color, a_filter, a_Position, a_vertexId } from './commonFeatureFunc';
+import { PointFillTriangulation as triangulation } from './triangulation';
+
+export const pointFillModel = async ({
+ descriptors,
+ features,
+ enablePicking,
+ shape2d,
+}: {
+ descriptors: IVertexAttributeDescriptor[];
+ features: IEncodeFeature[];
+ enablePicking: boolean;
+ shape2d: string[];
+}) => {
+ const updateFuncs = {
+ // fixed feature func
+ a_Color,
+ a_Position,
+ filter: a_filter,
+ a_vertexId,
+ a_PickingColor: (feature: IEncodeFeature, featureIdx: number) => {
+ const { id } = feature;
+ return enablePicking ? encodePickingColor(id as number) : [0, 0, 0];
+ },
+
+ // pointFill feature func
+ a_Shape: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ const { shape = 2 } = feature;
+ const shapeIndex = shape2d.indexOf(shape as string);
+ return [shapeIndex];
+ },
+ a_Extrude: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number[],
+ attributeIdx: number,
+ ) => {
+ const extrude = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0];
+ const extrudeIndex = (attributeIdx % 4) * 3;
+ return [
+ extrude[extrudeIndex],
+ extrude[extrudeIndex + 1],
+ extrude[extrudeIndex + 2],
+ ];
+ },
+ a_Size: (
+ feature: IEncodeFeature,
+ featureIdx: number,
+ vertex: number,
+ attributeIdx: number[],
+ ) => {
+ const { size: pointSize = 5 } = feature;
+ return Array.isArray(pointSize) ? [pointSize[0]] : [pointSize];
+ },
+ };
+
+ const featureLayout: {
+ sizePerElement: number;
+ elements: Array<{
+ featureIdx: number;
+ vertices: number[];
+ normals: number[];
+ offset: number;
+ indexes?: number[];
+ }>;
+ } = {
+ sizePerElement: 0,
+ elements: [],
+ };
+
+ let verticesNum = 0;
+ const indices: number[] = [];
+ let size = 3;
+ features.forEach((feature: IEncodeFeature, featureIdx: number) => {
+ const {
+ indices: indicesForCurrentFeature,
+ vertices: verticesForCurrentFeature,
+ // @ts-ignore
+ normals: normalsForCurrentFeature,
+ size: vertexSize,
+ // @ts-ignore
+ indexes,
+ } = triangulation(feature);
+ indicesForCurrentFeature.forEach((i) => {
+ indices.push(i + verticesNum);
+ });
+ size = vertexSize;
+ const verticesNumForCurrentFeature =
+ verticesForCurrentFeature.length / vertexSize;
+
+ featureLayout.sizePerElement = size;
+
+ featureLayout.elements.push({
+ featureIdx,
+ vertices: verticesForCurrentFeature,
+ normals: normalsForCurrentFeature,
+ offset: verticesNum,
+ });
+
+ verticesNum += verticesNumForCurrentFeature;
+ for (
+ let vertexIdx = 0;
+ vertexIdx < verticesNumForCurrentFeature;
+ vertexIdx++
+ ) {
+ const normal =
+ normalsForCurrentFeature?.slice(vertexIdx * 3, vertexIdx * 3 + 3) || [];
+ const vertice = verticesForCurrentFeature.slice(
+ vertexIdx * vertexSize,
+ vertexIdx * vertexSize + vertexSize,
+ );
+
+ let vertexIndex = 0;
+ if (indexes && indexes[vertexIdx] !== undefined) {
+ vertexIndex = indexes[vertexIdx];
+ }
+
+ descriptors.forEach((descriptor, attributeIdx: number) => {
+ // @ts-ignore
+ if (descriptor && updateFuncs[descriptor.name]) {
+ // @ts-ignore
+ descriptor.buffer.data.push(
+ // @ts-ignore
+ ...updateFuncs[descriptor.name](
+ feature,
+ featureIdx,
+ vertice,
+ vertexIdx,
+ normal,
+ vertexIndex,
+ ),
+ );
+ }
+ });
+ }
+ });
+ return {
+ descriptors,
+ featureLayout,
+ indices,
+ };
+};
diff --git a/packages/utils/src/workers/polygonFillModel.ts b/packages/utils/src/workers/polygonFillModel.ts
new file mode 100644
index 0000000000..8d372b3439
--- /dev/null
+++ b/packages/utils/src/workers/polygonFillModel.ts
@@ -0,0 +1,115 @@
+import { IEncodeFeature, IVertexAttributeDescriptor } from '@antv/l7-core';
+import { encodePickingColor } from '../color';
+import { a_Color, a_filter, a_Position, a_vertexId } from './commonFeatureFunc';
+import { polygonFillTriangulation as triangulation } from './triangulation';
+
+export const polygonFillModel = async ({
+ descriptors,
+ features,
+ enablePicking,
+}: {
+ descriptors: IVertexAttributeDescriptor[];
+ features: IEncodeFeature[];
+ enablePicking: boolean;
+}) => {
+ const updateFuncs = {
+ // fixed feature func
+ a_Color,
+ a_Position,
+ filter: a_filter,
+ a_vertexId,
+ a_PickingColor: (feature: IEncodeFeature, featureIdx: number) => {
+ const { id } = feature;
+ return enablePicking ? encodePickingColor(id as number) : [0, 0, 0];
+ },
+
+ // polygonFill feature func
+ // empty
+ };
+
+ const featureLayout: {
+ sizePerElement: number;
+ elements: Array<{
+ featureIdx: number;
+ vertices: number[];
+ normals: number[];
+ offset: number;
+ indexes?: number[];
+ }>;
+ } = {
+ sizePerElement: 0,
+ elements: [],
+ };
+
+ let verticesNum = 0;
+ const indices: number[] = [];
+ let size = 3;
+ features.forEach((feature: IEncodeFeature, featureIdx: number) => {
+ const {
+ indices: indicesForCurrentFeature,
+ vertices: verticesForCurrentFeature,
+ // @ts-ignore
+ normals: normalsForCurrentFeature,
+ size: vertexSize,
+ // @ts-ignore
+ indexes,
+ } = triangulation(feature);
+ indicesForCurrentFeature.forEach((i) => {
+ indices.push(i + verticesNum);
+ });
+ size = vertexSize;
+ const verticesNumForCurrentFeature =
+ verticesForCurrentFeature.length / vertexSize;
+
+ featureLayout.sizePerElement = size;
+
+ featureLayout.elements.push({
+ featureIdx,
+ vertices: verticesForCurrentFeature,
+ normals: normalsForCurrentFeature,
+ offset: verticesNum,
+ });
+
+ verticesNum += verticesNumForCurrentFeature;
+ for (
+ let vertexIdx = 0;
+ vertexIdx < verticesNumForCurrentFeature;
+ vertexIdx++
+ ) {
+ const normal =
+ normalsForCurrentFeature?.slice(vertexIdx * 3, vertexIdx * 3 + 3) || [];
+ const vertice = verticesForCurrentFeature.slice(
+ vertexIdx * vertexSize,
+ vertexIdx * vertexSize + vertexSize,
+ );
+
+ let vertexIndex = 0;
+ if (indexes && indexes[vertexIdx] !== undefined) {
+ vertexIndex = indexes[vertexIdx];
+ }
+
+ descriptors.forEach((descriptor, attributeIdx: number) => {
+ // @ts-ignore
+ if (descriptor && updateFuncs[descriptor.name]) {
+ // @ts-ignore
+ descriptor.buffer.data.push(
+ // @ts-ignore
+ ...updateFuncs[descriptor.name](
+ feature,
+ featureIdx,
+ vertice,
+ vertexIdx,
+ normal,
+ vertexIndex,
+ ),
+ );
+ }
+ });
+ }
+ });
+ return {
+ descriptors,
+ featureLayout,
+ indices,
+ };
+};
diff --git a/packages/utils/src/workers/triangulation.ts b/packages/utils/src/workers/triangulation.ts
new file mode 100644
index 0000000000..7e4b8651d8
--- /dev/null
+++ b/packages/utils/src/workers/triangulation.ts
@@ -0,0 +1,74 @@
+import { IEncodeFeature, IVertexAttributeDescriptor } from '@antv/l7-core';
+import earcut from 'earcut';
+import { calculateCentroid } from '../geo';
+import ExtrudePolyline from './extrude_polyline';
+
+export function LineTriangulation(feature: IEncodeFeature) {
+ const { coordinates, originCoordinates, version } = feature;
+ // let path = coordinates as number[][][] | number[][];
+ // if (!Array.isArray(path[0][0])) {
+ // path = [coordinates] as number[][][];
+ // }
+
+ const line = new ExtrudePolyline({
+ dash: true,
+ join: 'bevel',
+ });
+
+ if (version === 'GAODE2.x') {
+ // 处理高德2.0几何体构建
+ let path1 = coordinates as number[][][] | number[][]; // 计算位置
+ if (!Array.isArray(path1[0][0])) {
+ path1 = [coordinates] as number[][][];
+ }
+ let path2 = originCoordinates as number[][][] | number[][]; // 计算法线
+ if (!Array.isArray(path2[0][0])) {
+ path2 = [originCoordinates] as number[][][];
+ }
+
+ for (let i = 0; i < path1.length; i++) {
+ // 高德2.0在计算线时,需要使用经纬度计算发现,使用 customCoords.lnglatToCoords 计算的数据来计算顶点的位置
+ const item1 = path1[i];
+ const item2 = path2[i];
+ line.extrude_gaode2(item1 as number[][], item2 as number[][]);
+ }
+ } else {
+ // 处理非高德2.0的几何体构建
+ let path = coordinates as number[][][] | number[][];
+ if (path[0] && !Array.isArray(path[0][0])) {
+ path = [coordinates] as number[][][];
+ }
+ path.forEach((item: any) => {
+ line.extrude(item as number[][]);
+ });
+ }
+
+ const linebuffer = line.complex;
+ return {
+ vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ]
+ indices: linebuffer.indices,
+ normals: linebuffer.normals,
+ indexes: linebuffer.indexes,
+ size: 6,
+ };
+}
+
+export function PointFillTriangulation(feature: IEncodeFeature) {
+ const coordinates = calculateCentroid(feature.coordinates);
+ return {
+ vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
+ indices: [0, 1, 2, 2, 3, 0],
+ size: coordinates.length,
+ };
+}
+
+export function polygonFillTriangulation(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,
+ };
+}
diff --git a/stories/Map/components/amap2demo_image.tsx b/stories/Map/components/amap2demo_image.tsx
index 4c2bf65d26..787d79dd74 100644
--- a/stories/Map/components/amap2demo_image.tsx
+++ b/stories/Map/components/amap2demo_image.tsx
@@ -50,11 +50,11 @@ export default class Amap2demo_image extends React.Component {
})
.shape('name', ['00', '01', '02'])
// .rotate('name', () => Math.random() * Math.PI)
- // .rotate(Math.PI/2)
- // .style({
- // // layerType: 'fillImage',
- // rotation: 0,
- // })
+ .rotate(Math.PI / 2)
+ .style({
+ layerType: 'fillImage',
+ // rotation: 90,
+ })
// .active({
// color: '#00f',
// mix: 0.6,
diff --git a/stories/Map/components/amap2demo_styleMap.tsx b/stories/Map/components/amap2demo_styleMap.tsx
index 1eb7315c85..70822d4184 100644
--- a/stories/Map/components/amap2demo_styleMap.tsx
+++ b/stories/Map/components/amap2demo_styleMap.tsx
@@ -26,7 +26,7 @@ export default class Amap2demo_styleMap extends React.Component {
)
.then((res) => res.json())
.then((data) => {
- let layer = new PointLayer({}) // blend: "additive"
+ let layer = new PointLayer({ workerEnabled: true }) // blend: "additive"
.source(data, {
parser: {
type: 'json',
@@ -36,7 +36,6 @@ export default class Amap2demo_styleMap extends React.Component {
})
.shape('circle')
.color('color')
- // .color('#f00')
.size('value', (v) => 5 + 15 * v)
.style({
// blur: 2.5,
diff --git a/stories/Map/components/amap2demo_text.tsx b/stories/Map/components/amap2demo_text.tsx
index f354c2bea7..40dce643dd 100644
--- a/stories/Map/components/amap2demo_text.tsx
+++ b/stories/Map/components/amap2demo_text.tsx
@@ -105,7 +105,7 @@ export default class Amap2demo_text extends React.Component {
.color('w', ['#0e0030', '#0e0030', '#0e0030'])
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
- textOffset: [0, 0], // 文本相对锚点的偏移量 [水平, 垂直]
+ textOffset: [10, 0], // 文本相对锚点的偏移量 [水平, 垂直]
spacing: 2, // 字符间距
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
diff --git a/stories/Map/components/bugfix.tsx b/stories/Map/components/bugfix.tsx
index bbec3423a6..e3aee87f41 100644
--- a/stories/Map/components/bugfix.tsx
+++ b/stories/Map/components/bugfix.tsx
@@ -13,6 +13,7 @@ import {
HeatmapLayer,
LineLayer,
Source,
+ PolygonLayer,
} from '@antv/l7';
export default class Amap2demo extends React.Component {
@@ -33,29 +34,48 @@ export default class Amap2demo extends React.Component {
},
);
- let c = 0,
- scene,
- layer;
- scene = new Scene({
+ const scene = new Scene({
id: 'map',
- // map: new Mapbox({
- // map: new GaodeMap({
- map: new GaodeMapV2({
- // map: new Map({
- style: 'dark',
- center: [120, 30],
- zoom: 4,
+ map: new Mapbox({
+ pitch: 0,
+ style: 'light',
+ center: [-96, 37.8],
+ zoom: 3,
}),
});
- const layer = new PointLayer()
- .source(source)
- .shape('circle')
- .size(10)
- .color('#f00');
-
scene.on('loaded', () => {
- scene.addLayer(layer);
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/d36ad90e-3902-4742-b8a2-d93f7e5dafa2.json',
+ )
+ .then((res) => res.json())
+ .then((data) => {
+ // console.log(data)
+ const color = [
+ 'rgb(255,255,217)',
+ 'rgb(237,248,177)',
+ 'rgb(199,233,180)',
+ 'rgb(127,205,187)',
+ 'rgb(65,182,196)',
+ 'rgb(29,145,192)',
+ 'rgb(34,94,168)',
+ 'rgb(12,44,132)',
+ ];
+ const layer = new PolygonLayer({})
+ .source(data)
+ .scale('density', {
+ type: 'quantile',
+ })
+ .color('density', color)
+ .shape('fill')
+ .active(true)
+ .style({
+ opacity: 1.0,
+ });
+
+ scene.addLayer(layer);
+ console.log(layer);
+ });
});
}
diff --git a/stories/MapPerformance/components/Map.tsx b/stories/MapPerformance/components/Points.tsx
similarity index 56%
rename from stories/MapPerformance/components/Map.tsx
rename to stories/MapPerformance/components/Points.tsx
index 74bdf476c5..bba64a861b 100644
--- a/stories/MapPerformance/components/Map.tsx
+++ b/stories/MapPerformance/components/Points.tsx
@@ -1,6 +1,6 @@
// @ts-nocheck
// @ts-ignore
-import { Scene } from '@antv/l7';
+import { Scene, Source } from '@antv/l7';
import { PointLayer } from '@antv/l7-layers';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
@@ -25,13 +25,30 @@ export default class PointTest extends React.Component {
// let address = 'https://gw.alipayobjects.com/os/bmw-prod/e76d89f4-aa69-4974-90b7-b236904a43b1.json' // 100
// let address = 'https://gw.alipayobjects.com/os/bmw-prod/edc8219a-b095-4451-98e9-3e387e290087.json' // 10000
// let address = 'https://gw.alipayobjects.com/os/bmw-prod/2c37f08b-3fe6-4c68-a699-dc15cfc217f1.json' // 50000
- // let address = 'https://gw.alipayobjects.com/os/bmw-prod/8adff753-64e6-4ffa-9e7b-1f3dc6f4fd76.json'; // 100000
let address =
- 'https://gw.alipayobjects.com/os/bmw-prod/577a70fb-fc19-4582-83ed-7cddb7b77645.json'; // 20 0000
+ 'https://gw.alipayobjects.com/os/bmw-prod/8adff753-64e6-4ffa-9e7b-1f3dc6f4fd76.json'; // 100000
+ // let address =
+ // 'https://gw.alipayobjects.com/os/bmw-prod/577a70fb-fc19-4582-83ed-7cddb7b77645.json'; // 20 0000
fetch(address)
.then((res) => res.json())
.then((data) => {
- const layer = new PointLayer()
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+
+ const layer = new PointLayer({ workerEnabled: true })
.source(data, {
parser: {
type: 'json',
@@ -39,19 +56,30 @@ export default class PointTest extends React.Component {
y: 'lat',
},
})
+ // .source(source)
.size(10)
.color('#f00')
- // .shape('circle') // circle simple
- .shape('simple')
- .style({
- opacity: 1.0,
- })
- .select(true);
- // .animate(true)
- // .active(true);
+ .shape('circle')
+ .active(true);
+
scene.on('loaded', () => {
- console.log('loaded');
+ let t = new Date().getTime();
scene.addLayer(layer);
+ console.log(new Date().getTime() - t);
+
+ // setTimeout(() => {
+ // layer.setData([{
+ // lng: 120, lat: 30
+ // }])
+ // }, 2000)
+
+ // layer.on('inited', () => {
+ // console.log('inited ***')
+ layer.setData([
+ { lng: 120, lat: 30 },
+ { lng: 130, lat: 30 },
+ ]);
+ // })
});
});
}
diff --git a/stories/MapPerformance/components/updataPointsTimeLine.tsx b/stories/MapPerformance/components/updataPointsTimeLine.tsx
index 8b5680a7b2..8da8ff6d24 100644
--- a/stories/MapPerformance/components/updataPointsTimeLine.tsx
+++ b/stories/MapPerformance/components/updataPointsTimeLine.tsx
@@ -86,7 +86,9 @@ export default class Demo extends React.Component {
scene.addLayer(layer);
this.layer = layer;
- this.getModelDatas(layer, originData, times, parser);
+ layer.on('modelLoaded', () => {
+ this.getModelDatas(layer, originData, times, parser);
+ });
let c = 0;
let t = setInterval(() => {
diff --git a/stories/MapPerformance/map.stories.tsx b/stories/MapPerformance/map.stories.tsx
index 36c85599be..061363908d 100644
--- a/stories/MapPerformance/map.stories.tsx
+++ b/stories/MapPerformance/map.stories.tsx
@@ -8,7 +8,7 @@ import UpdateAttrAndEle_planeGeometry from './components/updateAttrAndEle_planeG
import UpdateAttrTimeLine from './components/updataPointsTimeLine';
import UpdateAttrShenZhen from './components/updateAttrAndEleShenZhen';
import UpdateHeatMap from './components/updataHeatMap';
-import PointTest from './components/Map';
+import PointTest from './components/Points';
import BigLine from './components/BigLine';
import DataUpdate from './components/DataUpdate';
diff --git a/stories/layerbuild/components/Billboard.tsx b/stories/layerbuild/components/Billboard.tsx
new file mode 100644
index 0000000000..a39f885ccb
--- /dev/null
+++ b/stories/layerbuild/components/Billboard.tsx
@@ -0,0 +1,79 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { GeometryLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ pitch: 80,
+ style: 'dark',
+ center: [120, 30],
+ zoom: 5,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ const img = new Image();
+ img.crossOrigin = '';
+ img.onload = () => {
+ let billboard = new GeometryLayer().shape('billboard').style({
+ width: 90,
+ height: 30,
+ canvasWidth: 360,
+ canvasHeight: 120,
+ center: [120, 30],
+ drawCanvas: (canvas: HTMLCanvasElement) => {
+ let { width, height } = canvas;
+ let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
+ ctx.globalAlpha = 0.5;
+ ctx.drawImage(
+ img,
+ 0,
+ 0,
+ img.width,
+ img.height,
+ 0,
+ 0,
+ width,
+ height,
+ );
+ ctx.globalAlpha = 1;
+ ctx.fillStyle = '#0ff';
+ ctx.textAlign = 'center';
+ ctx.textBaseline = 'middle';
+ ctx.font = '36px Georgia';
+ ctx.fillText('Hello World! 蚂蚁', width / 2, height / 2);
+ },
+ raisingHeight: 100,
+ });
+ billboard.active({
+ color: '#0ff',
+ mix: 0.5,
+ });
+ scene.addLayer(billboard);
+ };
+ img.src =
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*zMw0T6gEIZYAAAAAAAAAAAAAARQnAQ';
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/CityBuilding.tsx b/stories/layerbuild/components/CityBuilding.tsx
new file mode 100644
index 0000000000..5fe3fc6f52
--- /dev/null
+++ b/stories/layerbuild/components/CityBuilding.tsx
@@ -0,0 +1,67 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { CityBuildingLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120.145, 30.238915],
+ pitch: 60,
+ zoom: 13.2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json',
+ ).then(async (res) => {
+ const pointLayer = new CityBuildingLayer();
+ pointLayer
+ .source(await res.json())
+ .size('floor', [0, 500])
+ .color('rgba(242,246,250,1.0)')
+ .animate({
+ enable: true,
+ })
+ .active({
+ color: '#0ff',
+ mix: 0.5,
+ })
+ .style({
+ opacity: 0.7,
+ baseColor: 'rgb(16, 16, 16)',
+ windowColor: 'rgb(30, 60, 89)',
+ brightColor: 'rgb(255, 176, 38)',
+ sweep: {
+ enable: true,
+ sweepRadius: 2,
+ sweepColor: '#1990FF',
+ sweepSpeed: 0.5,
+ sweepCenter: [120.145319, 30.238915],
+ },
+ });
+ scene.addLayer(pointLayer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Heatmap.tsx b/stories/layerbuild/components/Heatmap.tsx
new file mode 100644
index 0000000000..bfcc725cca
--- /dev/null
+++ b/stories/layerbuild/components/Heatmap.tsx
@@ -0,0 +1,64 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { HeatmapLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
+ )
+ .then((res) => res.json())
+ .then((data) => {
+ const layer = new HeatmapLayer({})
+ .source(data)
+ .shape('heatmap')
+ .size('mag', [0, 1.0]) // weight映射通道
+ .style({
+ intensity: 2,
+ radius: 20,
+ opacity: 1.0,
+ rampColors: {
+ colors: [
+ '#FF4818',
+ '#F7B74A',
+ '#FFF598',
+ '#F27DEB',
+ '#8C1EB2',
+ '#421EB2',
+ ].reverse(),
+ positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
+ },
+ });
+ scene.addLayer(layer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Heatmap3d.tsx b/stories/layerbuild/components/Heatmap3d.tsx
new file mode 100644
index 0000000000..5e315cf5bf
--- /dev/null
+++ b/stories/layerbuild/components/Heatmap3d.tsx
@@ -0,0 +1,64 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { HeatmapLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
+ )
+ .then((res) => res.json())
+ .then((data) => {
+ const layer = new HeatmapLayer({})
+ .source(data)
+ .shape('heatmap3d')
+ .size('mag', [0, 1.0]) // weight映射通道
+ .style({
+ intensity: 2,
+ radius: 20,
+ opacity: 1.0,
+ rampColors: {
+ colors: [
+ '#FF4818',
+ '#F7B74A',
+ '#FFF598',
+ '#F27DEB',
+ '#8C1EB2',
+ '#421EB2',
+ ].reverse(),
+ positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
+ },
+ });
+ scene.addLayer(layer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/HeatmapGrid.tsx b/stories/layerbuild/components/HeatmapGrid.tsx
new file mode 100644
index 0000000000..7bfa7d3ffd
--- /dev/null
+++ b/stories/layerbuild/components/HeatmapGrid.tsx
@@ -0,0 +1,85 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { HeatmapLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/7359a5e9-3c5e-453f-b207-bc892fb23b84.csv',
+ )
+ .then((res) => res.text())
+ .then((data) => {
+ const layer = new HeatmapLayer({})
+ .source(data, {
+ parser: {
+ type: 'csv',
+ x: 'lng',
+ y: 'lat',
+ },
+ transforms: [
+ {
+ type: 'grid',
+ size: 20000,
+ field: 'v',
+ method: 'sum',
+ },
+ ],
+ })
+ .shape('square')
+ .style({
+ coverage: 1,
+ angle: 0,
+ })
+ .color(
+ 'count',
+ [
+ '#0B0030',
+ '#100243',
+ '#100243',
+ '#1B048B',
+ '#051FB7',
+ '#0350C1',
+ '#0350C1',
+ '#0072C4',
+ '#0796D3',
+ '#2BA9DF',
+ '#30C7C4',
+ '#6BD5A0',
+ '#A7ECB2',
+ '#D0F4CA',
+ ].reverse(),
+ );
+
+ scene.addLayer(layer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/HeatmapGrid3d.tsx b/stories/layerbuild/components/HeatmapGrid3d.tsx
new file mode 100644
index 0000000000..927430a8d6
--- /dev/null
+++ b/stories/layerbuild/components/HeatmapGrid3d.tsx
@@ -0,0 +1,83 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { HeatmapLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 40,
+ zoom: 9,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/a1a8158d-6fe3-424b-8e50-694ccf61c4d7.csv',
+ )
+ .then((res) => res.text())
+ .then((data) => {
+ const layer = new HeatmapLayer({})
+ .source(data, {
+ parser: {
+ type: 'csv',
+ x: 'lng',
+ y: 'lat',
+ },
+ transforms: [
+ {
+ type: 'hexagon',
+ size: 2500,
+ field: 'v',
+ method: 'sum',
+ },
+ ],
+ })
+ .size('sum', (sum) => {
+ return sum * 200;
+ })
+ .shape('hexagonColumn')
+ .style({
+ coverage: 0.8,
+ angle: 0,
+ opacity: 1.0,
+ })
+ .color('sum', [
+ '#094D4A',
+ '#146968',
+ '#1D7F7E',
+ '#289899',
+ '#34B6B7',
+ '#4AC5AF',
+ '#5FD3A6',
+ '#7BE39E',
+ '#A1EDB8',
+ '#C3F9CC',
+ '#DEFAC0',
+ '#ECFFB1',
+ ]);
+ scene.addLayer(layer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/HeatmapHexagon.tsx b/stories/layerbuild/components/HeatmapHexagon.tsx
new file mode 100644
index 0000000000..5a92e113ef
--- /dev/null
+++ b/stories/layerbuild/components/HeatmapHexagon.tsx
@@ -0,0 +1,78 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { HeatmapLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 40,
+ zoom: 5,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ fetch(
+ 'https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json',
+ )
+ .then((res) => res.json())
+ .then((data) => {
+ const layer = new HeatmapLayer({})
+ .source(data, {
+ transforms: [
+ {
+ type: 'hexagon',
+ size: 90000,
+ field: 'capacity',
+ method: 'sum',
+ },
+ ],
+ })
+ .shape('hexagon')
+ .style({
+ coverage: 0.9,
+ angle: 0,
+ opacity: 1.0,
+ })
+ .color(
+ 'sum',
+ [
+ '#3F4BBA',
+ '#3F4BBA',
+ '#3F4BBA',
+ '#3F4BBA',
+ '#3C73DA',
+ '#3C73DA',
+ '#3C73DA',
+ '#0F62FF',
+ '#0F62FF',
+ '#30B2E9',
+ '#30B2E9',
+ '#40C4CE',
+ ].reverse(),
+ );
+ scene.addLayer(layer);
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/ImageLayer.tsx b/stories/layerbuild/components/ImageLayer.tsx
new file mode 100644
index 0000000000..3c8b2fa484
--- /dev/null
+++ b/stories/layerbuild/components/ImageLayer.tsx
@@ -0,0 +1,48 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { ImageLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [121.168, 30.2828],
+ zoom: 8,
+ }),
+ });
+
+ const layer = new ImageLayer({});
+ layer.source(
+ 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
+ {
+ parser: {
+ type: 'image',
+ extent: [121.168, 30.2828, 121.384, 30.4219],
+ },
+ },
+ );
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Line.tsx b/stories/layerbuild/components/Line.tsx
new file mode 100644
index 0000000000..552b742dc8
--- /dev/null
+++ b/stories/layerbuild/components/Line.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer({ workerEnabled: true })
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('line')
+ .color('#f00')
+ .size(5);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineArc.tsx b/stories/layerbuild/components/LineArc.tsx
new file mode 100644
index 0000000000..8f16eaa2cc
--- /dev/null
+++ b/stories/layerbuild/components/LineArc.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('arc')
+ .color('#f00')
+ .size(5);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineArc3d.tsx b/stories/layerbuild/components/LineArc3d.tsx
new file mode 100644
index 0000000000..9aee212a54
--- /dev/null
+++ b/stories/layerbuild/components/LineArc3d.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('arc3d')
+ .color('#f00')
+ .size(5);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineEarthArc3D.tsx b/stories/layerbuild/components/LineEarthArc3D.tsx
new file mode 100644
index 0000000000..21f03e6ccd
--- /dev/null
+++ b/stories/layerbuild/components/LineEarthArc3D.tsx
@@ -0,0 +1,93 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer, EarthLayer } from '@antv/l7-layers';
+import { GaodeMap, Earth } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Earth({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 3,
+ }),
+ });
+
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('earthArc3d')
+ .color('#f00')
+ .size(2);
+ const earthlayer = new EarthLayer()
+ .source(
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*3-3NSpqRqUoAAAAAAAAAAAAAARQnAQ',
+ {
+ parser: {
+ type: 'image',
+ },
+ },
+ )
+ .shape('base')
+ .style({
+ globelOtions: {
+ ambientRatio: 0.6, // 环境光
+ diffuseRatio: 0.4, // 漫反射
+ specularRatio: 0.1, // 高光反射
+ earthTime: 0.1,
+ },
+ })
+ .animate(true);
+
+ const atomLayer = new EarthLayer()
+ .color('#2E8AE6')
+ .shape('atomSphere')
+ .style({
+ opacity: 1,
+ });
+
+ const bloomLayer = new EarthLayer().color('#fff').shape('bloomSphere');
+
+ scene.on('loaded', () => {
+ scene.addLayer(earthlayer);
+ scene.addLayer(layer);
+
+ scene.addLayer(atomLayer);
+ scene.addLayer(bloomLayer);
+
+ earthlayer.setEarthTime(4.0);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineGreatCircle.tsx b/stories/layerbuild/components/LineGreatCircle.tsx
new file mode 100644
index 0000000000..101185762c
--- /dev/null
+++ b/stories/layerbuild/components/LineGreatCircle.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('greatcircle')
+ .color('#f00')
+ .size(5);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineHalf.tsx b/stories/layerbuild/components/LineHalf.tsx
new file mode 100644
index 0000000000..011523b288
--- /dev/null
+++ b/stories/layerbuild/components/LineHalf.tsx
@@ -0,0 +1,62 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 28],
+ [115.48828125000001, 28],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('halfLine')
+ .color('#f00')
+ .size(10)
+ .style({
+ arrow: {
+ enable: true,
+ },
+ });
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineLinear.tsx b/stories/layerbuild/components/LineLinear.tsx
new file mode 100644
index 0000000000..94ab34e074
--- /dev/null
+++ b/stories/layerbuild/components/LineLinear.tsx
@@ -0,0 +1,70 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('linearline')
+ .color('#f00')
+ .size(5)
+ .style({
+ rampColors: {
+ colors: [
+ '#FF4818',
+ '#F7B74A',
+ '#FFF598',
+ '#91EABC',
+ '#2EA9A1',
+ '#206C7C',
+ ],
+ positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
+ },
+ });
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineSimple.tsx b/stories/layerbuild/components/LineSimple.tsx
new file mode 100644
index 0000000000..2103e2c3ac
--- /dev/null
+++ b/stories/layerbuild/components/LineSimple.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('simple')
+ .color('#f00')
+ .size(5);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineTile.tsx b/stories/layerbuild/components/LineTile.tsx
new file mode 100644
index 0000000000..36466af6f3
--- /dev/null
+++ b/stories/layerbuild/components/LineTile.tsx
@@ -0,0 +1,61 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ stencil: true,
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 4,
+ }),
+ });
+
+ const layer = new LineLayer({
+ featureId: 'COLOR',
+ sourceLayer: 'ecoregions2', // woods hillshade contour ecoregions ecoregions2 city
+ workerEnabled: true,
+ });
+ layer
+ .source(
+ 'http://ganos.oss-cn-hangzhou.aliyuncs.com/m2/rs_l7/{z}/{x}/{y}.pbf',
+ {
+ parser: {
+ type: 'mvt',
+ tileSize: 256,
+ zoomOffset: 0,
+ maxZoom: 9,
+ extent: [-180, -85.051129, 179, 85.051129],
+ },
+ },
+ )
+ .color('COLOR')
+ .size(2)
+ .select(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/LineWall.tsx b/stories/layerbuild/components/LineWall.tsx
new file mode 100644
index 0000000000..c2dd0be401
--- /dev/null
+++ b/stories/layerbuild/components/LineWall.tsx
@@ -0,0 +1,57 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { LineLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [105, 30],
+ pitch: 40,
+ zoom: 4,
+ }),
+ });
+ const layer = new LineLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'LineString',
+ coordinates: [
+ [95.625, 38.47939467327645],
+ [115.48828125000001, 28.92163128242129],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('wall')
+ .color('#f00')
+ .size(40);
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Plane.tsx b/stories/layerbuild/components/Plane.tsx
new file mode 100644
index 0000000000..d422d33ecf
--- /dev/null
+++ b/stories/layerbuild/components/Plane.tsx
@@ -0,0 +1,108 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { GeometryLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120.1025, 30.2594],
+ style: 'dark',
+ pitch: 65,
+ rotation: 180,
+ zoom: 14,
+ }),
+ });
+
+ let currentZoom = 14,
+ currentModelData = '100x100';
+
+ scene.on('loaded', () => {
+ const layer = new GeometryLayer().shape('plane').style({
+ width: 0.074,
+ height: 0.061,
+ center: [120.1025, 30.2594],
+ widthSegments: 100,
+ heightSegments: 100,
+ terrainClipHeight: 1,
+ mapTexture:
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*gA0NRbuOF5cAAAAAAAAAAAAAARQnAQ',
+ terrainTexture:
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ',
+ rgb2height: (r, g, b) => {
+ let h =
+ -10000.0 +
+ (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1;
+ h = h / 20 - 127600;
+ h = Math.max(0, h);
+ return h;
+ },
+ });
+ scene.addLayer(layer);
+
+ let modelData10,
+ modelData20 = null,
+ modelData100;
+
+ layer.on('terrainImageLoaded', () => {
+ modelData10 = layer.createModelData([], {
+ widthSegments: 10,
+ heightSegments: 10,
+ });
+
+ modelData20 = layer.createModelData([], {
+ widthSegments: 20,
+ heightSegments: 20,
+ });
+
+ modelData100 = layer.createModelData([], {
+ widthSegments: 100,
+ heightSegments: 100,
+ });
+ });
+
+ scene.on('zoom', ({ value }) => {
+ const zoom = Math.floor(value);
+ if (currentZoom !== zoom) {
+ if (zoom > 13) {
+ if (currentModelData !== '100x100') {
+ layer.updateModelData(modelData100);
+ currentModelData = '100x100';
+ }
+ } else if (zoom > 12) {
+ if (currentModelData !== '20x20') {
+ layer.updateModelData(modelData20);
+ currentModelData = '20x20';
+ }
+ } else {
+ if (currentModelData !== '10x10') {
+ layer.updateModelData(modelData10);
+ currentModelData = '10x10';
+ }
+ }
+ currentZoom = zoom;
+ }
+ return '';
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Points.tsx b/stories/layerbuild/components/Points.tsx
new file mode 100644
index 0000000000..dcfcf22e9e
--- /dev/null
+++ b/stories/layerbuild/components/Points.tsx
@@ -0,0 +1,95 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ // let address = 'https://gw.alipayobjects.com/os/bmw-prod/e76d89f4-aa69-4974-90b7-b236904a43b1.json' // 100
+ // let address = 'https://gw.alipayobjects.com/os/bmw-prod/edc8219a-b095-4451-98e9-3e387e290087.json' // 10000
+ // let address = 'https://gw.alipayobjects.com/os/bmw-prod/2c37f08b-3fe6-4c68-a699-dc15cfc217f1.json' // 50000
+ let address =
+ 'https://gw.alipayobjects.com/os/bmw-prod/8adff753-64e6-4ffa-9e7b-1f3dc6f4fd76.json'; // 100000
+ // let address =
+ // 'https://gw.alipayobjects.com/os/bmw-prod/577a70fb-fc19-4582-83ed-7cddb7b77645.json'; // 20 0000
+ fetch(address)
+ .then((res) => res.json())
+ .then((data) => {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+
+ const layer = new PointLayer({ workerEnabled: true })
+ .source(data, {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ })
+ // .source(source)
+ .size(10)
+ .color('#f00')
+ .shape('circle')
+ .active(true);
+
+ scene.on('loaded', () => {
+ let t = new Date().getTime();
+ scene.addLayer(layer);
+ console.log(new Date().getTime() - t);
+
+ // setTimeout(() => {
+ // layer.setData([{
+ // lng: 120, lat: 30
+ // }])
+ // }, 2000)
+
+ // layer.on('inited', () => {
+ // console.log('inited ***')
+ // layer.setData([
+ // { lng: 120, lat: 30 },
+ // { lng: 130, lat: 30 },
+ // ]);
+ // })
+ });
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsEarthExtrude.tsx b/stories/layerbuild/components/PointsEarthExtrude.tsx
new file mode 100644
index 0000000000..b6bbc19ce0
--- /dev/null
+++ b/stories/layerbuild/components/PointsEarthExtrude.tsx
@@ -0,0 +1,106 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer, EarthLayer } from '@antv/l7-layers';
+import { GaodeMap, Earth } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Earth({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 3,
+ }),
+ });
+
+ const pointlayer = new PointLayer({})
+ .source(
+ [
+ { lng: 121.61865234375, lat: 25.29437116258816 },
+ { lng: 121.058349609375, lat: 25.015928763367857 },
+ { lng: 120.7177734375, lat: 24.587090339209634 },
+ { lng: 120.28930664062499, lat: 23.936054914599815 },
+ { lng: 120.12451171875, lat: 23.553916518321625 },
+ { lng: 121.124267578125, lat: 22.806567100271522 },
+ { lng: 121.56372070312499, lat: 23.915970370510227 },
+ { lng: 121.88232421875, lat: 24.557116164309626 },
+ { lng: 121.95922851562501, lat: 25.075648445630527 },
+ { lng: 109.97314453125, lat: 20.076570104545173 },
+ { lng: 108.896484375, lat: 19.663280219987662 },
+ { lng: 108.61083984375, lat: 18.979025953255267 },
+ { lng: 108.80859375, lat: 18.47960905583197 },
+ { lng: 109.599609375, lat: 18.35452552912664 },
+ { lng: 110.32470703125, lat: 18.771115062337024 },
+ { lng: 111.005859375, lat: 19.78738018198621 },
+ { lng: 110, lat: 30 },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .shape('cylinder')
+ .color('#f00')
+ .size([1, 1, 10])
+ .active(true);
+ const earthlayer = new EarthLayer()
+ .source(
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*3-3NSpqRqUoAAAAAAAAAAAAAARQnAQ',
+ {
+ parser: {
+ type: 'image',
+ },
+ },
+ )
+ .shape('base')
+ .style({
+ globelOtions: {
+ ambientRatio: 0.6, // 环境光
+ diffuseRatio: 0.4, // 漫反射
+ specularRatio: 0.1, // 高光反射
+ earthTime: 0.1,
+ },
+ })
+ .animate(true);
+
+ const atomLayer = new EarthLayer()
+ .color('#2E8AE6')
+ .shape('atomSphere')
+ .style({
+ opacity: 1,
+ });
+
+ const bloomLayer = new EarthLayer().color('#fff').shape('bloomSphere');
+
+ scene.on('loaded', () => {
+ scene.addLayer(earthlayer);
+ scene.addLayer(pointlayer);
+
+ scene.addLayer(atomLayer);
+ scene.addLayer(bloomLayer);
+
+ earthlayer.setEarthTime(4.0);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsEarthFill.tsx b/stories/layerbuild/components/PointsEarthFill.tsx
new file mode 100644
index 0000000000..6d715afa1a
--- /dev/null
+++ b/stories/layerbuild/components/PointsEarthFill.tsx
@@ -0,0 +1,106 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer, EarthLayer } from '@antv/l7-layers';
+import { GaodeMap, Earth } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Earth({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 3,
+ }),
+ });
+
+ const pointlayer = new PointLayer({})
+ .source(
+ [
+ { lng: 121.61865234375, lat: 25.29437116258816 },
+ { lng: 121.058349609375, lat: 25.015928763367857 },
+ { lng: 120.7177734375, lat: 24.587090339209634 },
+ { lng: 120.28930664062499, lat: 23.936054914599815 },
+ { lng: 120.12451171875, lat: 23.553916518321625 },
+ { lng: 121.124267578125, lat: 22.806567100271522 },
+ { lng: 121.56372070312499, lat: 23.915970370510227 },
+ { lng: 121.88232421875, lat: 24.557116164309626 },
+ { lng: 121.95922851562501, lat: 25.075648445630527 },
+ { lng: 109.97314453125, lat: 20.076570104545173 },
+ { lng: 108.896484375, lat: 19.663280219987662 },
+ { lng: 108.61083984375, lat: 18.979025953255267 },
+ { lng: 108.80859375, lat: 18.47960905583197 },
+ { lng: 109.599609375, lat: 18.35452552912664 },
+ { lng: 110.32470703125, lat: 18.771115062337024 },
+ { lng: 111.005859375, lat: 19.78738018198621 },
+ { lng: 110, lat: 30 },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .shape('circle')
+ .color('#f00')
+ .size(20)
+ .active(true);
+ const earthlayer = new EarthLayer()
+ .source(
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*3-3NSpqRqUoAAAAAAAAAAAAAARQnAQ',
+ {
+ parser: {
+ type: 'image',
+ },
+ },
+ )
+ .shape('base')
+ .style({
+ globelOtions: {
+ ambientRatio: 0.6, // 环境光
+ diffuseRatio: 0.4, // 漫反射
+ specularRatio: 0.1, // 高光反射
+ earthTime: 0.1,
+ },
+ })
+ .animate(true);
+
+ const atomLayer = new EarthLayer()
+ .color('#2E8AE6')
+ .shape('atomSphere')
+ .style({
+ opacity: 1,
+ });
+
+ const bloomLayer = new EarthLayer().color('#fff').shape('bloomSphere');
+
+ scene.on('loaded', () => {
+ scene.addLayer(earthlayer);
+ scene.addLayer(pointlayer);
+
+ scene.addLayer(atomLayer);
+ scene.addLayer(bloomLayer);
+
+ earthlayer.setEarthTime(4.0);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsExtrude.tsx b/stories/layerbuild/components/PointsExtrude.tsx
new file mode 100644
index 0000000000..f9cf1ae82e
--- /dev/null
+++ b/stories/layerbuild/components/PointsExtrude.tsx
@@ -0,0 +1,59 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ const layer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .size([10, 10, 100])
+ .color('#f00')
+ .shape('cylinder')
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsFillImage.tsx b/stories/layerbuild/components/PointsFillImage.tsx
new file mode 100644
index 0000000000..1e0cd8d4bc
--- /dev/null
+++ b/stories/layerbuild/components/PointsFillImage.tsx
@@ -0,0 +1,65 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ scene.addImage(
+ 'img',
+ 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*rd3kTp1VFxIAAAAAAAAAAAAAARQnAQ',
+ );
+ const imageData = [
+ {
+ lng: 120,
+ lat: 30,
+ img: 'img',
+ },
+ ];
+
+ const layer = new PointLayer({ layerType: 'fillImage' })
+ .source(imageData, {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ })
+ .size(15)
+ .shape('img', ['img'])
+ .active({
+ color: '#f00',
+ mix: 0.5,
+ });
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsIconFont.tsx b/stories/layerbuild/components/PointsIconFont.tsx
new file mode 100644
index 0000000000..7cb9942d91
--- /dev/null
+++ b/stories/layerbuild/components/PointsIconFont.tsx
@@ -0,0 +1,74 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ const fontFamily = 'iconfont';
+ // 指定 iconfont 字体文件
+ const fontPath =
+ '//at.alicdn.com/t/font_2534097_fcae9o2mxbv.woff2?t=1622200439140';
+ // 全局添加资源
+ scene.addFontFace(fontFamily, fontPath);
+ // 全局添加 iconfont 字段的映射;
+ scene.addIconFont('icon1', '');
+
+ scene.on('loaded', () => {
+ const imageLayer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ icon: 'icon1',
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .color('#44ff00')
+ .shape('icon', 'text')
+ .size(30)
+ .style({
+ padding: [0, 0], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
+ stroke: '#ffffff', // 描边颜色
+ fontFamily,
+ iconfont: true,
+ textAllowOverlap: true,
+ });
+ scene.addLayer(imageLayer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsImage.tsx b/stories/layerbuild/components/PointsImage.tsx
new file mode 100644
index 0000000000..863dd249df
--- /dev/null
+++ b/stories/layerbuild/components/PointsImage.tsx
@@ -0,0 +1,65 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ scene.addImage(
+ 'img',
+ 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*rd3kTp1VFxIAAAAAAAAAAAAAARQnAQ',
+ );
+ const imageData = [
+ {
+ lng: 120,
+ lat: 30,
+ img: 'img',
+ },
+ ];
+
+ const layer = new PointLayer({})
+ .source(imageData, {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ })
+ .size(15)
+ .shape('img', ['img'])
+ .active({
+ color: '#f00',
+ mix: 0.5,
+ });
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsNormal.tsx b/stories/layerbuild/components/PointsNormal.tsx
new file mode 100644
index 0000000000..f371a1ade6
--- /dev/null
+++ b/stories/layerbuild/components/PointsNormal.tsx
@@ -0,0 +1,60 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 40,
+ zoom: 2,
+ }),
+ });
+
+ const layer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ t: 'text1',
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .size(15)
+ .color('#f00')
+ .shape('dot')
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsRadar.tsx b/stories/layerbuild/components/PointsRadar.tsx
new file mode 100644
index 0000000000..47acfb60a7
--- /dev/null
+++ b/stories/layerbuild/components/PointsRadar.tsx
@@ -0,0 +1,61 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ const layer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ t: 'text1',
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .size(15)
+ .color('#f00')
+ .shape('radar')
+ .animate(true)
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsSimple.tsx b/stories/layerbuild/components/PointsSimple.tsx
new file mode 100644
index 0000000000..4651ed0910
--- /dev/null
+++ b/stories/layerbuild/components/PointsSimple.tsx
@@ -0,0 +1,60 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 40,
+ zoom: 2,
+ }),
+ });
+
+ const layer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ t: 'text1',
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .size(15)
+ .color('#f00')
+ .shape('simple')
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsText.tsx b/stories/layerbuild/components/PointsText.tsx
new file mode 100644
index 0000000000..cca5da7d79
--- /dev/null
+++ b/stories/layerbuild/components/PointsText.tsx
@@ -0,0 +1,60 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+
+ const layer = new PointLayer()
+ .source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ t: 'text1',
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ )
+ .size(15)
+ .color('#f00')
+ .shape('t', 'text')
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsTextTile.tsx b/stories/layerbuild/components/PointsTextTile.tsx
new file mode 100644
index 0000000000..55de24e84b
--- /dev/null
+++ b/stories/layerbuild/components/PointsTextTile.tsx
@@ -0,0 +1,64 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 4,
+ }),
+ });
+
+ const layer = new PointLayer({
+ featureId: 'COLOR',
+ sourceLayer: 'ecoregions2', // woods hillshade contour ecoregions ecoregions2 city
+ });
+ layer
+ .source(
+ 'http://ganos.oss-cn-hangzhou.aliyuncs.com/m2/rs_l7/{z}/{x}/{y}.pbf',
+ {
+ parser: {
+ type: 'mvt',
+ tileSize: 256,
+ zoomOffset: 0,
+ maxZoom: 9,
+ extent: [-180, -85.051129, 179, 85.051129],
+ },
+ },
+ )
+ .shape('NNH_NAME', 'text')
+ .color('COLOR')
+ .size(12)
+ .style({
+ stroke: '#00f',
+ strokeWidth: 1,
+ textAllowOverlap: false,
+ });
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PointsTile.tsx b/stories/layerbuild/components/PointsTile.tsx
new file mode 100644
index 0000000000..c1aec4536e
--- /dev/null
+++ b/stories/layerbuild/components/PointsTile.tsx
@@ -0,0 +1,60 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap, Map } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Map({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 4,
+ }),
+ });
+
+ const layer = new PointLayer({
+ featureId: 'COLOR',
+ sourceLayer: 'ecoregions2', // woods hillshade contour ecoregions ecoregions2 city
+ workerEnabled: true,
+ });
+ layer
+ .source(
+ 'http://ganos.oss-cn-hangzhou.aliyuncs.com/m2/rs_l7/{z}/{x}/{y}.pbf',
+ {
+ parser: {
+ type: 'mvt',
+ tileSize: 256,
+ zoomOffset: 0,
+ maxZoom: 9,
+ extent: [-180, -85.051129, 179, 85.051129],
+ },
+ },
+ )
+ .color('COLOR')
+ .size(10)
+ .select(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Polygon.tsx b/stories/layerbuild/components/Polygon.tsx
new file mode 100644
index 0000000000..db67ed4900
--- /dev/null
+++ b/stories/layerbuild/components/Polygon.tsx
@@ -0,0 +1,61 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PolygonLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new PolygonLayer({ workerEnabled: true })
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [104.4140625, 35.460669951495305],
+ [98.7890625, 24.206889622398023],
+ [111.796875, 27.371767300523047],
+ [104.4140625, 35.460669951495305],
+ ],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('fill')
+ .color('#f00');
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PolygonExtrude.tsx b/stories/layerbuild/components/PolygonExtrude.tsx
new file mode 100644
index 0000000000..166bd9220f
--- /dev/null
+++ b/stories/layerbuild/components/PolygonExtrude.tsx
@@ -0,0 +1,62 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PolygonLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [105, 30],
+ pitch: 40,
+ zoom: 5,
+ }),
+ });
+ const layer = new PolygonLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [104.4140625, 35.460669951495305],
+ [98.7890625, 24.206889622398023],
+ [111.796875, 27.371767300523047],
+ [104.4140625, 35.460669951495305],
+ ],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('extrude')
+ .color('#f00')
+ .size(1000000000);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PolygonOcean.tsx b/stories/layerbuild/components/PolygonOcean.tsx
new file mode 100644
index 0000000000..3bd8663ea8
--- /dev/null
+++ b/stories/layerbuild/components/PolygonOcean.tsx
@@ -0,0 +1,65 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PolygonLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new PolygonLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [104.4140625, 35.460669951495305],
+ [98.7890625, 24.206889622398023],
+ [111.796875, 27.371767300523047],
+ [104.4140625, 35.460669951495305],
+ ],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('ocean')
+ .animate(true)
+ .color('#f00')
+ .style({
+ watercolor: '#6D99A8',
+ });
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PolygonTile.tsx b/stories/layerbuild/components/PolygonTile.tsx
new file mode 100644
index 0000000000..d2c34fbacf
--- /dev/null
+++ b/stories/layerbuild/components/PolygonTile.tsx
@@ -0,0 +1,60 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PolygonLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ stencil: true,
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 4,
+ }),
+ });
+
+ const layer = new PolygonLayer({
+ featureId: 'COLOR',
+ sourceLayer: 'ecoregions2', // woods hillshade contour ecoregions ecoregions2 city
+ workerEnabled: true,
+ });
+ layer
+ .source(
+ 'http://ganos.oss-cn-hangzhou.aliyuncs.com/m2/rs_l7/{z}/{x}/{y}.pbf',
+ {
+ parser: {
+ type: 'mvt',
+ tileSize: 256,
+ zoomOffset: 0,
+ maxZoom: 9,
+ extent: [-180, -85.051129, 179, 85.051129],
+ },
+ },
+ )
+ .color('COLOR')
+ .active(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/PolygonWater.tsx b/stories/layerbuild/components/PolygonWater.tsx
new file mode 100644
index 0000000000..8c99702a48
--- /dev/null
+++ b/stories/layerbuild/components/PolygonWater.tsx
@@ -0,0 +1,66 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PolygonLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [120, 30],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ const layer = new PolygonLayer()
+ .source({
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ properties: {},
+ geometry: {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [104.4140625, 35.460669951495305],
+ [98.7890625, 24.206889622398023],
+ [111.796875, 27.371767300523047],
+ [104.4140625, 35.460669951495305],
+ ],
+ ],
+ },
+ },
+ ],
+ })
+ .shape('water')
+ .color('#1E90FF')
+ .style({
+ speed: 0.4,
+ // waterTexture: 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*EojwT4VzSiYAAAAAAAAAAAAAARQnAQ'
+ })
+ .animate(true);
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/RasterDataTile.tsx b/stories/layerbuild/components/RasterDataTile.tsx
new file mode 100644
index 0000000000..99d765cf38
--- /dev/null
+++ b/stories/layerbuild/components/RasterDataTile.tsx
@@ -0,0 +1,104 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { RasterLayer } from '@antv/l7-layers';
+import { Map } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Map({
+ center: [105.732421875, 32.24997445586331],
+ pitch: 0,
+ style: 'dark',
+ zoom: 2,
+ }),
+ });
+
+ const canvas = document.createElement('canvas');
+ canvas.width = 256;
+ canvas.height = 256;
+ const ctx = canvas.getContext('2d');
+
+ scene.on('loaded', () => {
+ const layer = new RasterLayer();
+ layer
+ .source(
+ // 'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
+ // 'https://api.mapbox.com/raster/v1/mapbox.mapbox-terrain-dem-v1/{zoom}/{x}/{y}.pngraw?sku=YOUR_MAPBOX_SKU_TOKEN&access_token=pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2s5OXVzdHlzMDVneDNscDVjdzVmeXl0dyJ9.81SQ5qaJS0xExYLbDZAGpQ',
+ 'https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2s5OXVzdHlzMDVneDNscDVjdzVmeXl0dyJ9.81SQ5qaJS0xExYLbDZAGpQ',
+ // 'https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/{z}/{y}/{x}.tif',
+ // 'http://rd1yhmrzc.hn-bkt.clouddn.com/Mapnik/{z}/{x}/{y}.png',
+ {
+ parser: {
+ type: 'rasterTile',
+ dataType: 'arraybuffer',
+ tileSize: 256,
+ zoomOffset: 0,
+ extent: [-180, -85.051129, 179, 85.051129],
+ minZoom: 0,
+ format: async (data: any) => {
+ const blob: Blob = new Blob([new Uint8Array(data)], {
+ type: 'image/png',
+ });
+ const img = await createImageBitmap(blob);
+ ctx.clearRect(0, 0, 256, 256);
+ ctx.drawImage(img, 0, 0, 256, 256);
+ let imgData = ctx.getImageData(0, 0, 256, 256).data;
+ let arr = [];
+ for (let i = 0; i < imgData.length; i += 4) {
+ const R = imgData[i];
+ const G = imgData[i + 1];
+ const B = imgData[i + 2];
+ const d = -10000 + (R * 256 * 256 + G * 256 + B) * 0.1;
+ arr.push(d);
+ }
+ return {
+ rasterData: arr,
+ width: 256,
+ height: 256,
+ };
+ },
+ },
+ },
+ )
+ .style({
+ domain: [0, 1014],
+ clampLow: true,
+ rampColors: {
+ colors: [
+ '#f7fcf5',
+ '#e5f5e0',
+ '#c7e9c0',
+ '#a1d99b',
+ '#74c476',
+ '#41ab5d',
+ '#238b45',
+ '#006d2c',
+ '#00441b',
+ ],
+ positions: [0, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0],
+ },
+ });
+
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/RasterImageTile.tsx b/stories/layerbuild/components/RasterImageTile.tsx
new file mode 100644
index 0000000000..8c39c149f8
--- /dev/null
+++ b/stories/layerbuild/components/RasterImageTile.tsx
@@ -0,0 +1,51 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { RasterLayer } from '@antv/l7-layers';
+import { Map } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new Map({
+ center: [105.732421875, 32.24997445586331],
+ pitch: 0,
+ style: 'dark',
+ zoom: 2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ const layer = new RasterLayer({}).source(
+ 'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
+ {
+ parser: {
+ type: 'rasterTile',
+ tileSize: 256,
+ zoomOffset: 0,
+ updateStrategy: 'overlap',
+ },
+ },
+ );
+
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/RasterLayer.tsx b/stories/layerbuild/components/RasterLayer.tsx
new file mode 100644
index 0000000000..dcb61e481c
--- /dev/null
+++ b/stories/layerbuild/components/RasterLayer.tsx
@@ -0,0 +1,92 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { ImageLayer, RasterLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+import * as GeoTIFF from 'geotiff';
+
+async function getTiffData() {
+ const response = await fetch(
+ 'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat',
+ );
+ const arrayBuffer = await response.arrayBuffer();
+ const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer);
+ const image = await tiff.getImage();
+ const width = image.getWidth();
+ const height = image.getHeight();
+ const values = await image.readRasters();
+ return {
+ data: values[0],
+ width,
+ height,
+ min: 0,
+ max: 8000,
+ };
+}
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [121.268, 30.3628],
+ zoom: 3,
+ }),
+ });
+
+ async function addLayer() {
+ const tiffdata = await getTiffData();
+
+ const layer = new RasterLayer({});
+ layer
+ .source(tiffdata.data, {
+ parser: {
+ type: 'raster',
+ width: tiffdata.width,
+ height: tiffdata.height,
+ min: 0,
+ max: 80,
+ extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963],
+ },
+ })
+ .style({
+ heightRatio: 100,
+ opacity: 0.8,
+ rampColors: {
+ colors: [
+ '#FF4818',
+ '#F7B74A',
+ '#FFF598',
+ '#91EABC',
+ '#2EA9A1',
+ '#206C7C',
+ ].reverse(),
+ positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
+ },
+ });
+ return layer;
+ }
+
+ const layer = await addLayer();
+
+ scene.on('loaded', () => {
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/SourceTest.tsx b/stories/layerbuild/components/SourceTest.tsx
new file mode 100644
index 0000000000..3f4ff29cfe
--- /dev/null
+++ b/stories/layerbuild/components/SourceTest.tsx
@@ -0,0 +1,415 @@
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { PointLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ private scene: Scene;
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [110.19382669582967, 30.258134],
+ pitch: 0,
+ zoom: 2,
+ }),
+ });
+ this.scene = scene;
+
+ // 检测方案
+ // https://www.yuque.com/antv/l7/cpkdtl
+ // this.test1();
+ // this.test2();
+ // this.test3();
+ // this.test4();
+ // this.test5();
+ // this.test6();
+ // this.test7();
+ // this.test8();
+ // this.test9();
+ this.test10();
+ }
+
+ private test1() {
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ this.scene.addLayer(layer);
+ }
+
+ private test2() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ const layer = new PointLayer();
+ layer.source(source);
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ this.scene.addLayer(layer);
+ }
+
+ private test3() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ source.on('sourceUpdate', () => {
+ const layer = new PointLayer();
+ layer.source(source);
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ this.scene.addLayer(layer);
+ });
+ }
+
+ private test4() {
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ layer.setData([
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ]);
+ this.scene.addLayer(layer);
+ }
+
+ private test5() {
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ this.scene.addLayer(layer);
+ setTimeout(() => {
+ layer.setData([
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ]);
+ }, 2000);
+ }
+
+ private test6() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ layer.source(source);
+ this.scene.addLayer(layer);
+ }
+
+ private test7() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ this.scene.addLayer(layer);
+ setTimeout(() => {
+ layer.source(source);
+ this.scene.render();
+ }, 2000);
+ }
+
+ private test8() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ source.on('sourceUpdate', () => {
+ layer.source(source);
+ });
+ this.scene.addLayer(layer);
+ }
+
+ private test9() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+
+ const layer = new PointLayer();
+ layer.source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ source.on('sourceUpdate', () => {
+ setTimeout(() => {
+ layer.source(source);
+ }, 2000);
+ });
+ this.scene.addLayer(layer);
+ }
+
+ private test10() {
+ const source = new Source(
+ [
+ {
+ lng: 120,
+ lat: 30,
+ },
+ {
+ lng: 130,
+ lat: 30,
+ },
+ ],
+ {
+ parser: {
+ type: 'json',
+ x: 'lng',
+ y: 'lat',
+ },
+ },
+ );
+
+ const layer = new PointLayer();
+ layer
+ .shape('circle')
+ .size(10)
+ .color('#f00');
+ source.on('sourceUpdate', () => {
+ setTimeout(() => {
+ layer.source(source);
+ }, 2000);
+ });
+ this.scene.addLayer(layer);
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Sprite.tsx b/stories/layerbuild/components/Sprite.tsx
new file mode 100644
index 0000000000..d655b1e8e4
--- /dev/null
+++ b/stories/layerbuild/components/Sprite.tsx
@@ -0,0 +1,53 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { GeometryLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ pitch: 90,
+ style: 'dark',
+ center: [120, 30],
+ zoom: 6,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ const layer = new GeometryLayer()
+ .shape('sprite')
+ .size(10)
+ .style({
+ opacity: 0.3,
+ mapTexture:
+ 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*w2SFSZJp4nIAAAAAAAAAAAAAARQnAQ', // rain
+ center: [120, 30],
+ spriteCount: 120,
+ spriteRadius: 10,
+ spriteTop: 2500000,
+ spriteUpdate: 20000,
+ spriteScale: 0.6,
+ });
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/components/Wind.tsx b/stories/layerbuild/components/Wind.tsx
new file mode 100644
index 0000000000..314a7f58f5
--- /dev/null
+++ b/stories/layerbuild/components/Wind.tsx
@@ -0,0 +1,68 @@
+// @ts-nocheck
+// @ts-ignore
+import { Scene, Source } from '@antv/l7';
+import { WindLayer } from '@antv/l7-layers';
+import { GaodeMap } from '@antv/l7-maps';
+import * as React from 'react';
+
+export default class Demo extends React.Component {
+ public async componentDidMount() {
+ const scene = new Scene({
+ id: 'map',
+ map: new GaodeMap({
+ center: [105.732421875, 32.24997445586331],
+ pitch: 0,
+ style: 'dark',
+ zoom: 2,
+ }),
+ });
+
+ scene.on('loaded', () => {
+ const layer = new WindLayer({});
+ layer
+ .source(
+ 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*wcU8S5xMEDYAAAAAAAAAAAAAARQnAQ',
+ {
+ parser: {
+ type: 'image',
+ extent: [-180, -85, 180, 85],
+ },
+ },
+ )
+ .animate(true)
+ .style({
+ uMin: -21.32,
+ uMax: 26.8,
+ vMin: -21.57,
+ vMax: 21.42,
+ numParticles: 35535,
+ fadeOpacity: 0.996,
+ sizeScale: 1.2,
+ rampColors: {
+ 0.0: '#c6dbef',
+ 0.1: '#9ecae1',
+ 0.2: '#6baed6',
+ 0.3: '#4292c6',
+ 0.4: '#2171b5',
+ 0.5: '#084594',
+ },
+ });
+ scene.addLayer(layer);
+ });
+ }
+
+ public render() {
+ return (
+
+ );
+ }
+}
diff --git a/stories/layerbuild/map.stories.tsx b/stories/layerbuild/map.stories.tsx
new file mode 100644
index 0000000000..c1f6713b52
--- /dev/null
+++ b/stories/layerbuild/map.stories.tsx
@@ -0,0 +1,111 @@
+import { storiesOf } from '@storybook/react';
+import * as React from 'react';
+
+import PointFill from './components/Points';
+import PointExtrue from './components/PointsExtrude';
+import PointText from './components/PointsText';
+import PointSimple from './components/PointsSimple';
+import PointsNormal from './components/PointsNormal';
+import PointsFillImage from './components/PointsFillImage';
+import PointImage from './components/PointsImage';
+import PointIconFont from './components/PointsIconFont';
+import PointRader from './components/PointsRadar';
+import PointTile from './components/PointsTile';
+import PointsTextTile from './components/PointsTextTile';
+import PointEarthFill from './components/PointsEarthFill';
+import PointEarthExtrude from './components/PointsEarthExtrude';
+
+import Line from './components/Line';
+import LineArc from './components/LineArc';
+import LineArc3d from './components/LineArc3d';
+import LineLinear from './components/LineLinear';
+import LineSimple from './components/LineSimple';
+import LineHalf from './components/LineHalf';
+import LineGreatCircle from './components/LineGreatCircle';
+import LineWall from './components/LineWall';
+import LineEarthArc3D from './components/LineEarthArc3D';
+import LineTile from './components/LineTile';
+
+import PolygonFill from './components/Polygon';
+import PolygonExtrude from './components/PolygonExtrude';
+import PolygonOcean from './components/PolygonOcean';
+import PolygonWater from './components/PolygonWater';
+import PolygonTile from './components/PolygonTile';
+
+import Heatmap from './components/Heatmap';
+import Heatmap3d from './components/Heatmap3d';
+import HeatmapGrid from './components/HeatmapGrid';
+import HeatmapGrid3d from './components/HeatmapGrid3d';
+import HeatmapHexagon from './components/HeatmapHexagon';
+
+import CityBuilding from './components/CityBuilding';
+
+import ImageLayer from './components/ImageLayer';
+
+import RasterLayer from './components/RasterLayer';
+
+import Billboard from './components/Billboard';
+import Sprite from './components/Sprite';
+import Plane from './components/Plane';
+
+import Wind from './components/Wind';
+
+import RasterImageTile from './components/RasterImageTile';
+import RasterDataTile from './components/RasterDataTile';
+
+import SourceTest from './components/SourceTest';
+
+storiesOf('图层渲染流程改造', module)
+ .add('pointFill', () => )
+ .add('PointExtrue', () => )
+ .add('PointText', () => )
+ .add('PointSimple', () => )
+ .add('PointsNormal', () => )
+ .add('PointsFillImage', () => )
+ .add('PointImage', () => )
+ .add('PointIconFont', () => )
+ .add('PointRader', () => )
+ .add('PointEarthFill', () => )
+ .add('PointEarthExtrude', () => )
+
+ .add('Line', () => )
+ .add('LineArc', () => )
+ .add('LineArc3d', () => )
+ .add('LineLinear', () => )
+ .add('LineSimple', () => )
+ .add('LineHalf', () => )
+ .add('LineGreatCircle', () => )
+ .add('LineWall', () => )
+ .add('LineEarthArc3D', () => )
+
+ .add('PolygonFill', () => )
+ .add('PolygonExtrude', () => )
+ .add('PolygonOcean', () => )
+ .add('PolygonWater', () => )
+
+ .add('Heatmap', () => )
+ .add('Heatmap3d', () => )
+ .add('HeatmapGrid', () => )
+ .add('HeatmapGrid3d', () => )
+ .add('HeatmapHexagon', () => )
+
+ .add('CityBuilding', () => )
+
+ .add('ImageLayer', () => )
+
+ .add('RasterLayer', () => )
+
+ .add('Billboard', () => )
+ .add('Sprite', () => )
+ .add('Plane', () => )
+
+ .add('Wind', () => )
+
+ .add('TilePoint', () => )
+ .add('TileLine', () => )
+ .add('TilePolygon', () => )
+ .add('TilePointText', () => )
+ .add('TileRasterImage', () => )
+ .add('TileRasterData', () => )
+
+ .add('SourceTest', () => )
diff --git a/tsconfig.json b/tsconfig.json
index 334c8ec166..ad538ddb9c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -31,7 +31,7 @@
"@antv/l7-utils": ["packages/utils/src"],
"@antv/l7": ["packages/l7/src"],
"*": ["packages", "typings/*"]
- },
+ }
},
"awesomeTypescriptLoaderOptions": {
"useBabel": true,
@@ -40,5 +40,4 @@
},
"include": ["packages"],
"exclude": ["node_modules", "packages/**/dist"]
-
}
diff --git a/tslint.json b/tslint.json
index 215422356f..4bb984e1ef 100644
--- a/tslint.json
+++ b/tslint.json
@@ -19,7 +19,8 @@
"object-literal-sort-keys": false,
"no-implicit-dependencies": [true, "dev"],
"interface-over-type-literal": false,
- "no-this-assignment": false
+ "no-this-assignment": false,
+ "no-submodule-imports": false
},
"globals": {
"AMap": true