feat(layer): point layer

This commit is contained in:
thinkinggis 2019-10-29 17:33:37 +08:00
parent 896b02c1e7
commit cfabee3d03
33 changed files with 7875 additions and 2018 deletions

View File

@ -9,7 +9,7 @@ addParameters({
showSearchBox: false,
panelPosition: 'bottom',
hierarchySeparator: /\./,
hierarchyRootSeparator: /\|/,
// hierarchyRootSeparator: /\|/,
enableShortcuts: true,
theme: create({
base: 'light',

View File

@ -22,7 +22,6 @@ module.exports = (api) => {
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-proposal-optional-chaining',
[
'@babel/plugin-proposal-decorators',
{
@ -36,6 +35,7 @@ module.exports = (api) => {
loose: true,
}
],
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-modules-commonjs',
[

330
package-lock.json generated
View File

@ -3,12 +3,12 @@
"lockfileVersion": 1,
"dependencies": {
"@babel/cli": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.5.5.tgz",
"integrity": "sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==",
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.6.4.tgz",
"integrity": "sha512-tqrDyvPryBM6xjIyKKUwr3s8CzmmYidwgdswd7Uc/Cv0ogZcuS1TYQTLx/eWKP3UbJ6JxZAiYlBZabXm/rtRsQ==",
"dev": true,
"requires": {
"chokidar": "^2.0.4",
"chokidar": "^2.1.8",
"commander": "^2.8.1",
"convert-source-map": "^1.1.0",
"fs-readdir-recursive": "^1.1.0",
@ -24,24 +24,23 @@
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/core": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz",
"integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==",
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz",
"integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.5.5",
"@babel/helpers": "^7.5.5",
"@babel/parser": "^7.5.5",
"@babel/template": "^7.4.4",
"@babel/traverse": "^7.5.5",
"@babel/types": "^7.5.5",
"@babel/generator": "^7.6.4",
"@babel/helpers": "^7.6.2",
"@babel/parser": "^7.6.4",
"@babel/template": "^7.6.0",
"@babel/traverse": "^7.6.3",
"@babel/types": "^7.6.3",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
@ -72,7 +71,6 @@
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz",
"integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==",
"dev": true,
"requires": {
"@babel/types": "^7.6.3",
"jsesc": "^2.5.1",
@ -124,7 +122,6 @@
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz",
"integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-member-expression-to-functions": "^7.5.5",
@ -159,7 +156,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
"integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
"dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.0.0",
"@babel/template": "^7.1.0",
@ -170,7 +166,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
"integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
@ -188,7 +183,6 @@
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz",
"integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==",
"dev": true,
"requires": {
"@babel/types": "^7.5.5"
}
@ -220,7 +214,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
"integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
@ -228,8 +221,7 @@
"@babel/helper-plugin-utils": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
"integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==",
"dev": true
"integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA=="
},
"@babel/helper-regex": {
"version": "7.5.5",
@ -257,7 +249,6 @@
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz",
"integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==",
"dev": true,
"requires": {
"@babel/helper-member-expression-to-functions": "^7.5.5",
"@babel/helper-optimise-call-expression": "^7.0.0",
@ -279,7 +270,6 @@
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
@ -311,7 +301,6 @@
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
@ -321,8 +310,7 @@
"@babel/parser": {
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz",
"integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==",
"dev": true
"integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A=="
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.2.0",
@ -349,7 +337,6 @@
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz",
"integrity": "sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg==",
"dev": true,
"requires": {
"@babel/helper-create-class-features-plugin": "^7.6.0",
"@babel/helper-plugin-utils": "^7.0.0",
@ -396,6 +383,16 @@
"@babel/plugin-syntax-optional-catch-binding": "^7.2.0"
}
},
"@babel/plugin-proposal-optional-chaining": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.6.0.tgz",
"integrity": "sha512-kj4gkZ6qUggkprRq3Uh5KP8XnE1MdIO0J7MhdDX8+rAbB6dJ2UrensGIS+0NPZAaaJ1Vr0PN6oLUgXMU1uMcSg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-optional-chaining": "^7.2.0"
}
},
"@babel/plugin-proposal-unicode-property-regex": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz",
@ -420,7 +417,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz",
"integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
@ -479,6 +475,15 @@
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-optional-chaining": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz",
"integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-typescript": {
"version": "7.3.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz",
@ -991,7 +996,6 @@
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
"integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.6.0",
@ -1002,7 +1006,6 @@
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz",
"integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.6.3",
@ -1019,7 +1022,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
@ -1027,8 +1029,7 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
@ -1036,7 +1037,6 @@
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz",
"integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
@ -3919,6 +3919,16 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"style-loader": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
"integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
"dev": true,
"requires": {
"loader-utils": "^1.1.0",
"schema-utils": "^1.0.0"
}
}
}
},
@ -4446,16 +4456,6 @@
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true
},
"@types/storybook__addon-knobs": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@types/storybook__addon-knobs/-/storybook__addon-knobs-5.0.3.tgz",
"integrity": "sha512-NnSOu4ajk4kL1e1eRe9zzyspIghgFu8B9ELyrAl1jF/nJE26YK2oDTi7qr+k/+X33rNaYFo6e7+lsEqeI3MLXg==",
"dev": true,
"requires": {
"@types/react": "*",
"@types/storybook__react": "*"
}
},
"@types/storybook__react": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/storybook__react/-/storybook__react-4.0.2.tgz",
@ -5005,7 +5005,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@ -5788,6 +5787,60 @@
"integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=",
"dev": true
},
"babel-plugin-transform-postcss": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-postcss/-/babel-plugin-transform-postcss-0.3.0.tgz",
"integrity": "sha512-Sn4coeHvw3PCc22KVWtrkFFTh/K3G1ZCl26O3HZyLBgna987oHqTjJui+ofVUmglaWqydmFiEQd999uXWrmQLQ==",
"dev": true,
"requires": {
"debug": "^2.6.0",
"postcss-load-config": "^1.1.0"
},
"dependencies": {
"cosmiconfig": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
"integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
"dev": true,
"requires": {
"is-directory": "^0.3.1",
"js-yaml": "^3.4.3",
"minimist": "^1.2.0",
"object-assign": "^4.1.0",
"os-homedir": "^1.0.1",
"parse-json": "^2.2.0",
"require-from-string": "^1.1.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"dev": true,
"requires": {
"error-ex": "^1.2.0"
}
},
"postcss-load-config": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
"integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
"dev": true,
"requires": {
"cosmiconfig": "^2.1.0",
"object-assign": "^4.1.0",
"postcss-load-options": "^1.2.0",
"postcss-load-plugins": "^2.3.0"
}
}
}
},
"babel-plugin-transform-property-literals": {
"version": "6.9.4",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz",
@ -6737,7 +6790,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@ -7139,7 +7191,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
@ -7147,8 +7198,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"colors": {
"version": "1.4.0",
@ -9656,8 +9706,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
"version": "1.12.0",
@ -9739,8 +9788,7 @@
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"etag": {
"version": "1.8.1",
@ -11666,8 +11714,7 @@
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
"globalthis": {
"version": "1.0.0",
@ -11846,8 +11893,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.0",
@ -12263,9 +12309,9 @@
"dev": true
},
"https-proxy-agent": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
"integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"dev": true,
"requires": {
"agent-base": "^4.3.0",
@ -13826,8 +13872,7 @@
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"js-yaml": {
"version": "3.13.1",
@ -13896,8 +13941,7 @@
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
"json-parse-better-errors": {
"version": "1.0.2",
@ -14451,8 +14495,7 @@
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"lodash-es": {
"version": "4.17.15",
@ -16960,6 +17003,90 @@
"import-cwd": "^2.0.0"
}
},
"postcss-load-options": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
"integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
"dev": true,
"requires": {
"cosmiconfig": "^2.1.0",
"object-assign": "^4.1.0"
},
"dependencies": {
"cosmiconfig": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
"integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
"dev": true,
"requires": {
"is-directory": "^0.3.1",
"js-yaml": "^3.4.3",
"minimist": "^1.2.0",
"object-assign": "^4.1.0",
"os-homedir": "^1.0.1",
"parse-json": "^2.2.0",
"require-from-string": "^1.1.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"dev": true,
"requires": {
"error-ex": "^1.2.0"
}
}
}
},
"postcss-load-plugins": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
"integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
"dev": true,
"requires": {
"cosmiconfig": "^2.1.1",
"object-assign": "^4.1.0"
},
"dependencies": {
"cosmiconfig": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
"integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
"dev": true,
"requires": {
"is-directory": "^0.3.1",
"js-yaml": "^3.4.3",
"minimist": "^1.2.0",
"object-assign": "^4.1.0",
"os-homedir": "^1.0.1",
"parse-json": "^2.2.0",
"require-from-string": "^1.1.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"dev": true,
"requires": {
"error-ex": "^1.2.0"
}
}
}
},
"postcss-loader": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
@ -17081,6 +17208,34 @@
"postcss": "^7.0.6"
}
},
"postcss-plugin": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postcss-plugin/-/postcss-plugin-1.0.0.tgz",
"integrity": "sha1-92OBRWW4e5PhNEn8+ddZQcVmsHA=",
"dev": true,
"requires": {
"postcss": "^6.0.8"
},
"dependencies": {
"postcss": {
"version": "6.0.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
"integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
"source-map": "^0.6.1",
"supports-color": "^5.4.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"postcss-reporter": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz",
@ -18591,6 +18746,12 @@
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"dev": true
},
"require-from-string": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
"integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
"dev": true
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
@ -19755,8 +19916,7 @@
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"source-map-resolve": {
"version": "0.5.2",
@ -20273,13 +20433,25 @@
}
},
"style-loader": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
"integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.0.0.tgz",
"integrity": "sha512-B0dOCFwv7/eY31a5PCieNwMgMhVGFe9w+rh7s/Bx8kfFkrth9zfTZquoYvdw8URgiqxObQKcpW51Ugz1HjfdZw==",
"dev": true,
"requires": {
"loader-utils": "^1.1.0",
"schema-utils": "^1.0.0"
"loader-utils": "^1.2.3",
"schema-utils": "^2.0.1"
},
"dependencies": {
"schema-utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz",
"integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
"ajv-keywords": "^3.4.1"
}
}
}
},
"style-search": {
@ -20634,7 +20806,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@ -21085,8 +21256,7 @@
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
"dev": true
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
},
"to-object-path": {
"version": "0.3.0",
@ -21364,9 +21534,9 @@
"dev": true
},
"typescript": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz",
"integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==",
"version": "3.7.0-dev.20191021",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.0-dev.20191021.tgz",
"integrity": "sha512-SSx/+QkyW7PMcaGQXzVmVkrRmmaLFsdOYXhP9sY9eYMiHrfmtZE9EL2hjtbihfnpyWfCmPup69VgbB4dTTEQgg==",
"dev": true
},
"ua-parser-js": {

View File

@ -1,8 +1,8 @@
{
"private": true,
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/cli": "^7.6.4",
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
@ -21,11 +21,10 @@
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/jest": "^24.0.18",
"@types/node": "^12.7.3",
"@types/storybook__addon-knobs": "^5.0.1",
"@types/storybook__react": "^4.0.2",
"@types/supercluster": "^5.0.1",
"awesome-typescript-loader": "^5.2.1",
"babel-jest": "^24.8.0",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
"babel-plugin-const-enum": "^0.0.2",
"babel-plugin-css-modules-transform": "^1.6.2",
@ -110,5 +109,8 @@
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.6.0"
}
}

View File

@ -22,9 +22,21 @@ const defaultGlobalConfig: Partial<IGlobalConfig> = {
'rgb(33,102,172)',
'rgb(5,48,97)',
],
size: 10000,
size: 10,
shape: 'circle',
scales: {},
shape2d: [
'circle',
'triangle',
'square',
'pentagon',
'hexagon',
'octogon',
'hexagram',
'rhombus',
'vesica',
],
shape3d: ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn'],
};
// @see https://github.com/epoberezkin/ajv#options

View File

@ -1,4 +1,5 @@
import { SyncBailHook, SyncHook } from 'tapable';
import { IGlobalConfigService } from '../config/IConfigService';
import { IModel } from '../renderer/IModel';
import { IMultiPassRenderer } from '../renderer/IMultiPassRenderer';
import { ISource, ISourceCFG } from '../source/ISourceService';
@ -14,6 +15,8 @@ export interface ILayerGlobalConfig {
colors: string[];
size: number;
shape: string;
shape2d: string[];
shape3d: string[];
scales: {
[key: string]: IScale;
};
@ -31,6 +34,7 @@ export interface ILayer {
name: string; // 代表 Layer 的类型
// visible: boolean;
// zIndex: number;
configService: IGlobalConfigService;
plugins: ILayerPlugin[];
hooks: {
init: SyncBailHook<void, boolean | void>;

View File

@ -33,6 +33,24 @@ export interface IScale {
domain?: any[];
}
export enum StyleScaleType {
CONSTANT = 'constant',
VARIABLE = 'variable',
}
export interface IScaleOption {
field?: string;
type: ScaleTypes;
ticks?: any[];
nice?: boolean;
format?: () => any;
domain?: any[];
}
export interface IStyleScale {
scale: any;
field: string;
type: StyleScaleType;
option: IScaleOption | undefined;
}
export enum AttributeType {
Attribute,
InstancedAttribute,
@ -45,7 +63,7 @@ export interface IEncodeFeature {
shape?: string | number;
pattern?: string;
id?: number;
coordinates: Position[][];
coordinates: Position | Position[] | Position[][];
}
export interface IVertexAttributeDescriptor
@ -62,6 +80,8 @@ export interface IVertexAttributeDescriptor
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => number[];
}
@ -78,6 +98,8 @@ export interface IStyleAttributeInitializationOptions {
scale?: {
field: StyleAttributeField;
values: unknown[];
names: string[];
type: StyleScaleType;
callback?: (...args: any[]) => [];
scalers?: Array<{
field: string;
@ -111,6 +133,7 @@ export type Triangulation = (
vertices: number[];
indices: number[];
size: number;
normals?: number[];
};
export interface IStyleAttributeUpdateOptions {

View File

@ -1,5 +1,8 @@
import { isNil } from 'lodash';
import { IStyleAttribute } from '../layer/IStyleAttributeService';
import {
IStyleAttribute,
StyleScaleType,
} from '../layer/IStyleAttributeService';
import { IAttribute } from '../renderer/IAttribute';
import { IBuffer } from '../renderer/IBuffer';
import {
@ -7,6 +10,7 @@ import {
IEncodeFeature,
IFeatureRange,
IStyleAttributeInitializationOptions,
IStyleScale,
IVertexAttributeDescriptor,
} from './IStyleAttributeService';
@ -14,6 +18,8 @@ export default class StyleAttribute implements IStyleAttribute {
public name: string;
public type: AttributeType;
public scale?: {
type: StyleScaleType.CONSTANT;
names: string[];
field: string | string[];
values: unknown[];
callback?: (...args: any[]) => [];

View File

@ -37,6 +37,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
elements: Array<{
featureIdx: number;
vertices: number[];
normals: number[];
offset: number;
}>;
} = {
@ -105,7 +106,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
const attributeToUpdate = this.attributes.find(
(attribute) => attribute.name === attributeName,
);
if (attributeToUpdate) {
if (attributeToUpdate && attributeToUpdate.descriptor) {
const { descriptor } = attributeToUpdate;
const { update, buffer, size = 0 } = descriptor;
const bytesPerElement = bytesPerElementMap[buffer.type || gl.FLOAT];
@ -122,7 +123,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
// 以 byte 为单位计算 buffer 中的偏移
const bufferOffsetInBytes = offset * size * bytesPerElement;
const updatedBufferData = featuresToUpdate
.map(({ featureIdx, vertices }) => {
.map(({ featureIdx, vertices, normals }, attributeIdx) => {
const verticesNumForCurrentFeature =
vertices.length / sizePerElement;
const featureData: number[] = [];
@ -131,6 +132,9 @@ export default class StyleAttributeService implements IStyleAttributeService {
vertexIdx < verticesNumForCurrentFeature;
vertexIdx++
) {
const normal = normals
? normals!.slice(vertexIdx * 3, vertexIdx * 3 + 3)
: [];
featureData.push(
...update(
features[featureIdx],
@ -139,6 +143,8 @@ export default class StyleAttributeService implements IStyleAttributeService {
vertexIdx * sizePerElement,
vertexIdx * sizePerElement + sizePerElement,
),
attributeIdx,
normal,
),
);
}
@ -168,10 +174,10 @@ export default class StyleAttributeService implements IStyleAttributeService {
elements: IElements;
} {
const descriptors = this.attributes.map((attr) => attr.descriptor);
let verticesNum = 0;
const vertices: number[] = [];
const indices: number[] = [];
const normals: number[] = [];
let size = 3;
features.forEach((feature, featureIdx) => {
@ -179,10 +185,14 @@ export default class StyleAttributeService implements IStyleAttributeService {
const {
indices: indicesForCurrentFeature,
vertices: verticesForCurrentFeature,
normals: normalsForCurrentFeature,
size: vertexSize,
} = triangulation(feature);
indices.push(...indicesForCurrentFeature.map((i) => i + verticesNum));
vertices.push(...verticesForCurrentFeature);
if (normalsForCurrentFeature) {
normals.push(...normalsForCurrentFeature);
}
size = vertexSize;
const verticesNumForCurrentFeature =
verticesForCurrentFeature.length / vertexSize;
@ -192,6 +202,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
this.featureLayout.elements.push({
featureIdx,
vertices: verticesForCurrentFeature,
normals: normalsForCurrentFeature as number[],
offset: verticesNum,
});
@ -204,7 +215,11 @@ export default class StyleAttributeService implements IStyleAttributeService {
vertexIdx++
) {
descriptors.forEach((descriptor, attributeIdx) => {
if (descriptor.update) {
if (descriptor && descriptor.update) {
const normal = normalsForCurrentFeature?.slice(
vertexIdx * 3,
vertexIdx * 3 + 3,
)|| [];
(descriptor.buffer.data as number[]).push(
...descriptor.update(
feature,
@ -213,14 +228,15 @@ export default class StyleAttributeService implements IStyleAttributeService {
vertexIdx * vertexSize,
vertexIdx * vertexSize + vertexSize,
),
vertexIdx, // 当前顶点所在feature索引
normal,
// TODO: 传入顶点索引 vertexIdx
),
);
}
});
}
});
} // end if
}); // end for each
} // end for
}); // end features for Each
const {
createAttribute,
createBuffer,
@ -232,6 +248,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
} = {};
descriptors.forEach((descriptor, attributeIdx) => {
if (descriptor) {
// IAttribute 参数透传
const { buffer, update, name, ...rest } = descriptor;
@ -244,6 +261,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
// 在 StyleAttribute 上保存对 VertexAttribute 的引用
this.attributes[attributeIdx].vertexAttribute = vertexAttribute;
}
});
const elements = createElements({

View File

@ -32,6 +32,7 @@
"gl-matrix": "^3.1.0",
"gl-vec2": "^1.3.0",
"lodash": "^4.17.15",
"merge-json-schemas": "1.0.0",
"polyline-miter-util": "^1.0.1",
"tapable": "^2.0.0-beta.8"
},

View File

@ -9,6 +9,7 @@ import {
ILayerPlugin,
IMapService,
IModel,
IModelInitializationOptions,
IMultiPassRenderer,
IRendererService,
IShaderModuleService,
@ -132,6 +133,9 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
@lazyInject(TYPES.IStyleAttributeService)
public styleAttributeService: IStyleAttributeService;
@lazyInject(TYPES.IGlobalConfigService)
public readonly configService: IGlobalConfigService;
@lazyInject(TYPES.IIconService)
protected readonly iconService: IIconService;
@ -151,9 +155,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
ILayerInitializationOptions & ChildLayerStyleOptions
>;
@lazyInject(TYPES.IGlobalConfigService)
private readonly configService: IGlobalConfigService;
@lazyInject(TYPES.IShaderModuleService)
private readonly shaderModuleService: IShaderModuleService;
@ -215,11 +216,51 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
return this;
}
public size(field: StyleAttributeField, values?: StyleAttributeOption) {
public size(
field: StyleAttributeField,
values?: StyleAttributeOption,
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
) {
this.styleAttributeService.updateStyleAttribute(
'size',
{
// @ts-ignore
scale: {
field,
...this.splitValuesAndCallbackInAttribute(
// @ts-ignore
values,
this.configService.getConfig().size,
),
},
},
// @ts-ignore
updateOptions,
);
return this;
}
public shape(field: StyleAttributeField, values?: StyleAttributeOption) {
public shape(
field: StyleAttributeField,
values?: StyleAttributeOption,
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
) {
this.styleAttributeService.updateStyleAttribute(
'shape',
{
// @ts-ignore
scale: {
field,
...this.splitValuesAndCallbackInAttribute(
// @ts-ignore
values,
this.configService.getConfig().shape,
),
},
},
// @ts-ignore
updateOptions,
);
return this;
}
@ -234,7 +275,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
// @ts-ignore
this.styleOptions = {
...this.styleOptions,
...options,
...(options as object),
};
return this;
}
@ -311,8 +352,17 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
this.interactionService.triggerHover({ x, y });
}
protected buildLayerModel(options: ILayerModelInitializationOptions): IModel {
const { moduleName, vertexShader, fragmentShader, triangulation } = options;
protected buildLayerModel(
options: ILayerModelInitializationOptions &
Partial<IModelInitializationOptions>,
): IModel {
const {
moduleName,
vertexShader,
fragmentShader,
triangulation,
...rest
} = options;
this.shaderModuleService.registerModule(moduleName, {
vs: vertexShader,
fs: fragmentShader,
@ -327,13 +377,13 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> implements ILayer {
this.encodedData,
triangulation,
);
return createModel({
attributes,
uniforms,
fs,
vs,
elements,
...rest,
});
}

View File

@ -1,14 +1,16 @@
import BaseLayer from './core/BaseLayer';
import Point3dLayer from './point/extrude';
// import HeatMapLayer from './heatmap';
// import Line from './line';
// import PointLayer from './point';
import PointLayer from './point/index';
// import Point from './point/point';
import PolygonLayer from './polygon';
// import ImageLayer from './raster';
export {
BaseLayer,
// PointLayer,
PointLayer,
PolygonLayer,
Point3dLayer,
// Point,
// Line,
// ImageLayer,

View File

@ -5,8 +5,10 @@ import {
ILogService,
IScale,
IStyleAttribute,
IStyleScale,
lazyInject,
ScaleTypes,
StyleScaleType,
TYPES,
} from '@l7/core';
import { IParseDataItem } from '@l7/source';
@ -38,8 +40,9 @@ export default class FeatureScalePlugin implements ILayerPlugin {
@lazyInject(TYPES.ILogService)
private readonly logger: ILogService;
// key = field_attribute name
private scaleCache: {
[field: string]: unknown;
[field: string]: IStyleScale;
} = {};
public apply(layer: ILayer) {
@ -71,30 +74,65 @@ export default class FeatureScalePlugin implements ILayerPlugin {
this.scaleCache = {};
attributes.forEach((attribute) => {
if (attribute.scale) {
attribute.scale.scalers = this.parseFields(
attribute.scale.field || '',
).map((field: string) => ({
field,
func: this.getOrCreateScale(field, attribute, dataArray),
}));
attribute.needRescale = false;
// 创建Scale
const attributeScale = attribute.scale;
attributeScale.names= this.parseFields(attribute!.scale!.field || []);
const scales: IStyleScale[] = attributeScale.names
.map((field:string) => {
return this.getOrCreateScale(field, attribute, dataArray);
})
// 为scales 设置值区间
if (scales.some((scale) => scale.type === StyleScaleType.VARIABLE)) {
attributeScale.type = StyleScaleType.VARIABLE;
scales.forEach((scale) => {
// 如果设置了回调干啥这不需要设置让range
if (!attributeScale.callback && attributeScale.values.length > 0) {
scale.scale.range(attributeScale.values);
}
});
} else {
// 设置attribute 常量值 常量直接在value取值
attributeScale.values = scales.map((scale, index) => {
return scale.scale(attributeScale.names[index]);
});
}
attributeScale.scalers = scales.map((scale: IStyleScale)=> {
return {
field: scale.field,
func: scale.scale,
}
});
attribute.needRescale = false;
}
});
}
private getOrCreateScale(
field: string,
attribute: IStyleAttribute,
dataArray: IParseDataItem[],
) {
if (this.scaleCache[field]) {
return this.scaleCache[field];
const scalekey = [field,attribute.name].join('_')
if (this.scaleCache[scalekey]) {
return this.scaleCache[scalekey];
}
this.scaleCache[field] = this.createScale(field, dataArray);
(this.scaleCache[field] as {
range: (c: unknown[]) => void;
}).range(attribute?.scale?.values || []);
return this.scaleCache[field];
const styleScale = this.createScale(field, dataArray);
this.scaleCache[scalekey] = styleScale;
if (
styleScale.type === StyleScaleType.VARIABLE &&
attribute.scale?.values &&
attribute.scale?.values.length > 0
) { // 只有变量初始化range
styleScale.scale.range(attribute.scale?.values);
}
return this.scaleCache[scalekey];
}
/**
@ -112,28 +150,44 @@ export default class FeatureScalePlugin implements ILayerPlugin {
return [field];
}
private createScale(field: string, data?: IParseDataItem[]): unknown {
private createScale(field: string, data?: IParseDataItem[]): IStyleScale {
// 首先查找全局默认配置例如 color
const scaleOption: IScale | undefined = this.configService.getConfig()?.scales?.[field];
const styleScale: IStyleScale = {
field,
scale: undefined,
type: StyleScaleType.VARIABLE,
option: scaleOption,
};
if (!data || !data.length) {
// 数据为空
return scaleOption && scaleOption.type
? this.createDefaultScale(scaleOption)
: d3.scaleOrdinal([field]);
if (scaleOption && scaleOption.type) {
styleScale.scale = this.createDefaultScale(scaleOption);
} else {
styleScale.scale = d3.scaleOrdinal([field]);
styleScale.type = StyleScaleType.CONSTANT;
}
const firstValue = data.find((d) => !isNil(d[field]))?.[field];
return styleScale;
}
const firstValue = (data!.find((d) => !isNil(d[field])))?.[field]
// 常量 Scale
if (isNumber(field) || (isNil(firstValue) && !scaleOption)) {
return d3.scaleOrdinal([field]);
styleScale.scale = d3.scaleOrdinal([field]);
styleScale.type = StyleScaleType.CONSTANT;
} else {
// 根据数据类型判断 默认等分位,时间,和枚举类型
const type =
(scaleOption && scaleOption.type) || this.getDefaultType(firstValue);
return this.createDefaultScale(
this.createDefaultScaleConfig(type, field, data),
);
const cfg = this.createDefaultScaleConfig(type, field, data);
Object.assign(cfg, scaleOption);
styleScale.scale = this.createDefaultScale(cfg);
styleScale.option = cfg;
}
return styleScale;
}
private getDefaultType(firstValue: unknown) {

View File

@ -39,7 +39,7 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin {
featureIdx: number,
vertex: number[],
) => {
return [vertex[0], vertex[1], 0];
return vertex.length === 3 ? vertex : [vertex[0], vertex[1], 0];
},
},
});

View File

@ -0,0 +1,139 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import pointExtrudeFrag from './shaders/extrude_frag.glsl';
import pointExtrudeVert from './shaders/extrude_vert.glsl';
import { PointExtrudeTriangulation } from './triangulation';
interface IPointLayerStyleOptions {
opacity: number;
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PointLayer';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const { opacity } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_Opacity: opacity || 0,
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'pointExtrude',
vertexShader: pointExtrudeVert,
fragmentShader: pointExtrudeFrag,
triangulation: PointExtrudeTriangulation,
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
if (size) {
let buffersize: number[] = [];
if (Array.isArray(size)) {
// TODO 多维size支持
buffersize =
size.length === 2 ? [size[0], size[0], size[1]] : size;
}
if (!Array.isArray(size)) {
buffersize = [size];
}
return buffersize;
} else {
return [2, 2, 2];
}
},
},
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'pos',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Pos',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (feature: IEncodeFeature, featureIdx: number) => {
const coordinates = feature.coordinates as number[];
return [coordinates[0], coordinates[1], 0];
},
},
});
}
}

View File

@ -1,216 +1,154 @@
// import {
// gl,
// ILayer,
// IRendererService,
// IShaderModuleService,
// lazyInject,
// packCircleVertex,
// TYPES,
// } from '@l7/core';
// import { featureEach } from '@turf/meta';
// import BaseLayer from '../core/BaseLayer';
// import circleFrag from './shaders/circle_frag.glsl';
// import circleVert from './shaders/circle_vert.glsl';
import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerPlugin,
ILogService,
IStyleAttributeService,
lazyInject,
TYPES,
} from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import pointFillFrag from './shaders/fill_frag.glsl';
import pointFillVert from './shaders/fill_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
}
export function PointTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
extrude: [-1, -1, 1, -1, 1, 1, -1, 1],
indices: [0, 1, 2, 2, 3, 0],
size: coordinates.length,
};
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PointLayer';
// export interface IPointLayerStyleOptions {
// pointShape: string;
// pointColor: [number, number, number];
// pointRadius: number;
// pointOpacity: number;
// strokeWidth: number;
// strokeColor: [number, number, number];
// strokeOpacity: number;
// }
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
// interface IPointFeature {
// coordinates: [number, number] | [number, number];
// [key: string]: any;
// }
protected renderModels() {
const { opacity } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_Opacity: opacity || 0,
},
}),
);
return this;
}
// /**
// * PointLayer
// */
// export default class PointLayer extends BaseLayer {
// public styleOptions: IPointLayerStyleOptions = {
// pointShape: 'circle',
// pointColor: [81, 187, 214],
// pointRadius: 10,
// pointOpacity: 1,
// strokeWidth: 2,
// strokeColor: [255, 255, 255],
// strokeOpacity: 1,
// };
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'pointfill',
vertexShader: pointFillVert,
fragmentShader: pointFillFrag,
triangulation: PointTriangulation,
depth: { enable: false },
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}
// public name: string = 'pointLayer';
private registerBuiltinAttributes(layer: ILayer) {
layer.styleAttributeService.registerStyleAttribute({
name: 'extrude',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Extrude',
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 extrude = [-1, -1, 1, -1, 1, 1, -1, 1];
const extrudeIndex = (attributeIdx % 4) * 2;
return [extrude[extrudeIndex], extrude[extrudeIndex + 1]];
},
},
});
// @lazyInject(TYPES.IShaderModuleService)
// private readonly shaderModule: IShaderModuleService;
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size = 2 } = feature;
return [size as number];
},
},
});
// @lazyInject(TYPES.IRendererService)
// private readonly renderer: IRendererService;
// private pointFeatures: IPointFeature[] = [];
// // public style(options: Partial<IPointLayerStyleOptions>) {
// // // this.layerStyleService.update(options);
// // // this.styleOptions = {
// // // ...this.styleOptions,
// // // ...options,
// // // };
// // }
// public render(): ILayer {
// this.models.forEach((model) =>
// model.draw({
// uniforms: {
// u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
// u_stroke_width: 1,
// u_blur: 0,
// u_opacity: 1,
// u_stroke_color: [1, 1, 1, 1],
// u_stroke_opacity: 1,
// },
// }),
// );
// return this;
// }
// protected buildModels() {
// this.shaderModule.registerModule('circle', {
// vs: circleVert,
// fs: circleFrag,
// });
// this.models = [];
// const { vs, fs, uniforms } = this.shaderModule.getModule('circle');
// // TODO: fix me
// const source = this.getSource();
// featureEach(
// // @ts-ignore
// source.originData,
// ({ geometry: { coordinates }, properties }) => {
// this.pointFeatures.push({
// coordinates,
// });
// },
// );
// const {
// packedBuffer,
// packedBuffer2,
// packedBuffer3,
// indexBuffer,
// positionBuffer,
// // @ts-ignore
// } = this.buildPointBuffers(this.pointFeatures);
// const {
// createAttribute,
// createBuffer,
// createElements,
// createModel,
// } = this.renderer;
// this.models.push(
// createModel({
// attributes: {
// a_Position: createAttribute({
// buffer: createBuffer({
// data: positionBuffer,
// type: gl.FLOAT,
// }),
// }),
// a_packed_data: createAttribute({
// buffer: createBuffer({
// data: packedBuffer,
// type: gl.FLOAT,
// }),
// }),
// },
// uniforms,
// fs,
// vs,
// count: indexBuffer.length,
// primitive: gl.TRIANGLES,
// elements: createElements({
// data: indexBuffer,
// type: gl.UNSIGNED_INT,
// }),
// depth: { enable: false },
// blend: {
// enable: true,
// func: {
// srcRGB: gl.SRC_ALPHA,
// srcAlpha: 1,
// dstRGB: gl.ONE_MINUS_SRC_ALPHA,
// dstAlpha: 1,
// },
// },
// }),
// );
// }
// private buildPointBuffers(pointFeatures: IPointFeature[]) {
// const packedBuffer: number[][] = [];
// const packedBuffer2: number[][] = [];
// const packedBuffer3: number[][] = [];
// const positionBuffer: number[][] = [];
// const indexBuffer: Array<[number, number, number]> = [];
// const {
// pointColor,
// pointRadius,
// pointShape,
// pointOpacity,
// strokeColor,
// strokeWidth,
// strokeOpacity,
// } = this.styleOptions;
// let i = 0;
// pointFeatures.forEach((pointFeature) => {
// // TODO: 判断是否使用瓦片坐标
// const [tileX, tileY] = pointFeature.coordinates;
// // 压缩顶点数据
// // TODO: 某些变量通过 uniform 而非 vertex attribute 传入
// const {
// packedBuffer: packed1,
// packedBuffer2: packed2,
// packedBuffer3: packed3,
// } = packCircleVertex({
// color: [...pointColor, 255],
// radius: pointRadius,
// tileX: 0,
// tileY: 0,
// shape: pointShape,
// opacity: pointOpacity,
// strokeColor: [...strokeColor, 255],
// strokeOpacity,
// strokeWidth,
// });
// packedBuffer.push(...packed1);
// packedBuffer2.push(...packed2);
// packedBuffer3.push(...packed3);
// // 经纬度坐标
// positionBuffer.push([tileX, tileY]);
// positionBuffer.push([tileX, tileY]);
// positionBuffer.push([tileX, tileY]);
// positionBuffer.push([tileX, tileY]);
// // 构造 index
// indexBuffer.push([0 + i, 1 + i, 2 + i]);
// indexBuffer.push([2 + i, 3 + i, 0 + i]);
// i += 4;
// });
// return {
// packedBuffer,
// packedBuffer2,
// packedBuffer3,
// indexBuffer,
// positionBuffer,
// };
// }
// }
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'shape',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Shape',
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 { shape = 2 } = feature;
const shape2d = layer.configService.getConfig().shape2d as string[];
const shapeIndex = shape2d.indexOf(shape as string);
return [shapeIndex];
},
},
});
}
}

View File

@ -1,19 +1,19 @@
precision highp float;
attribute vec3 a_Position;
attribute vec4 a_color;
attribute vec3 a_size;
attribute vec3 a_shape;
attribute vec3 a_normal;
attribute vec3 a_Pos;
attribute vec4 a_Color;
attribute vec3 a_Size;
attribute vec3 a_Normal;
uniform mat4 u_ModelMatrix;
varying vec4 v_color;
#pragma include "projection"
void main() {
vec3 size = a_size * a_shape;
v_color = vec4(a_normal,1.0);
vec3 size = a_Size * a_Position;
v_color = vec4(a_Normal,1.0);
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
vec4 project_pos = project_position(vec4(a_Pos.xy, 0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, size.z, 1.0));
}

View File

@ -0,0 +1,61 @@
uniform float u_blur : 0;
uniform float u_opacity : 1;
uniform float u_stroke_width : 1;
uniform vec4 u_stroke_color : [1, 1, 1, 1];
uniform float u_stroke_opacity : 1;
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
#pragma include "sdf_2d"
void main() {
int shape = int(floor(v_data.w + 0.5));
lowp float antialiasblur = v_data.z;
float antialiased_blur = -max(u_blur, antialiasblur);
float r = v_radius / (v_radius + u_stroke_width);
float outer_df;
float inner_df;
// 'circle', 'triangle', 'square', 'pentagon', 'hexagon', 'octogon', 'hexagram', 'rhombus', 'vesica'
if (shape == 0) {
outer_df = sdCircle(v_data.xy, 1.0);
inner_df = sdCircle(v_data.xy, r);
} else if (shape == 1) {
outer_df = sdEquilateralTriangle(1.1 * v_data.xy);
inner_df = sdEquilateralTriangle(1.1 / r * v_data.xy);
} else if (shape == 2) {
outer_df = sdBox(v_data.xy, vec2(1.));
inner_df = sdBox(v_data.xy, vec2(r));
} else if (shape == 3) {
outer_df = sdPentagon(v_data.xy, 0.8);
inner_df = sdPentagon(v_data.xy, r * 0.8);
} else if (shape == 4) {
outer_df = sdHexagon(v_data.xy, 0.8);
inner_df = sdHexagon(v_data.xy, r * 0.8);
} else if (shape == 5) {
outer_df = sdOctogon(v_data.xy, 1.0);
inner_df = sdOctogon(v_data.xy, r);
} else if (shape == 6) {
outer_df = sdHexagram(v_data.xy, 0.52);
inner_df = sdHexagram(v_data.xy, r * 0.52);
} else if (shape == 7) {
outer_df = sdRhombus(v_data.xy, vec2(1.0));
inner_df = sdRhombus(v_data.xy, vec2(r));
} else if (shape == 8) {
outer_df = sdVesica(v_data.xy, 1.1, 0.8);
inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8);
}
float opacity_t = smoothstep(0.0, antialiased_blur, outer_df);
float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
antialiased_blur,
0.0,
inner_df
);
gl_FragColor = opacity_t * mix(v_color * u_opacity, u_stroke_color * u_stroke_opacity, color_t);
}

View File

@ -0,0 +1,36 @@
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec2 a_Extrude;
attribute float a_Size;
attribute float a_Shape;
uniform mat4 u_ModelMatrix;
uniform float u_stroke_width : 2;
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
#pragma include "projection"
void main() {
// unpack color(vec2)
v_color = a_Color;
vec2 extrude = a_Extrude;
float shape_type = a_Shape;
// radius(16-bit)
v_radius = a_Size;
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width));
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
// TODO: billboard
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
// anti-alias
float antialiasblur = 1.0 / (a_Size + u_stroke_width);
// construct point coords
v_data = vec4(extrude, antialiasblur, shape_type);
}

View File

@ -0,0 +1,85 @@
import { IEncodeFeature } from '@l7/core';
import { vec3 } from 'gl-matrix';
import extrudePolygon, { IExtrudeGeomety } from './shape/extrude';
import { geometryShape, ShapeType2D, ShapeType3D } from './shape/Path';
interface IGeometryCache {
[key: string]: IExtrudeGeomety;
}
const GeometryCache: IGeometryCache = {};
export function PointFillTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
indices: [0, 1, 2, 2, 3, 0],
size: coordinates.length,
};
}
export function PointExtrudeTriangulation(feature: IEncodeFeature) {
const { shape } = feature;
const { positions, index } = getGeometry(shape as ShapeType3D);
return {
vertices: positions,
indices: index,
normals: Array.from(computeVertexNormals(positions, index)),
size: 3,
};
}
function getGeometry(shape: ShapeType3D): IExtrudeGeomety {
if (GeometryCache && GeometryCache[shape]) {
return GeometryCache[shape];
}
const path = geometryShape[shape]
? geometryShape[shape]()
: geometryShape.cylinder();
const geometry = extrudePolygon([path]);
GeometryCache[shape] = geometry;
return geometry;
}
function computeVertexNormals(
positions: number[],
indexArray: number[],
dim: number = 3,
) {
const normals = new Float32Array((positions.length / dim) * 3);
let vA: number;
let vB: number;
let vC: number;
const cb = vec3.create();
const ab = vec3.create();
const normal = vec3.create();
for (let i = 0, li = indexArray.length; i < li; i += 3) {
vA = indexArray[i + 0] * 3;
vB = indexArray[i + 1] * 3;
vC = indexArray[i + 2] * 3;
const [ax, ay] = [positions[vA], positions[vA + 1]];
const pA = vec3.fromValues(ax, ay, positions[vA + 2]);
const [bx, by] = [positions[vB], positions[vB + 1]];
const pB = vec3.fromValues(bx, by, positions[vB + 2]);
const [cx, cy] = [positions[vC], positions[vC + 1]];
const pC = vec3.fromValues(cx, cy, positions[vC + 2]);
vec3.sub(cb, pC, pB);
vec3.sub(ab, pA, pB);
vec3.cross(normal, cb, ab);
normals[vA] += cb[0];
normals[vA + 1] += cb[1];
normals[vA + 2] += cb[2];
normals[vB] += cb[0];
normals[vB + 1] += cb[1];
normals[vB + 2] += cb[2];
normals[vC] += cb[0];
normals[vC + 1] += cb[1];
normals[vC + 2] += cb[2];
}
normalizeNormals(normals);
return normals;
}
function normalizeNormals(normals: Float32Array) {
for (let i = 0, li = normals.length; i < li; i += 3) {
const normal = vec3.fromValues(normals[i], normals[i + 1], normals[i + 2]);
const newNormal = vec3.create();
vec3.normalize(newNormal, normal);
normals.set(newNormal, i);
}
}

View File

@ -10,7 +10,7 @@ interface IPolygonLayerStyleOptions {
export function polygonTriangulation(feature: IEncodeFeature) {
const { coordinates } = feature;
const flattengeo = earcut.flatten(coordinates);
const flattengeo = earcut.flatten(coordinates as number[][][]);
const { vertices, dimensions, holes } = flattengeo;
return {

View File

@ -1,5 +1,5 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import Polygon from './components/Polygon';
// @ts-ignore
storiesOf('动画', module).add('动态更新指定 feature(s)', () => <Polygon />);

View File

@ -0,0 +1,8 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import PointDemo from './components/Point';
import Point3D from './components/Point3D';
// @ts-ignore
storiesOf('图层', module)
.add('点图层', () => <PointDemo />)
.add('3D点', () => <Point3D />);

View File

@ -0,0 +1,76 @@
import { PointLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
import * as React from 'react';
import data from '../data/data.json';
export default class Point3D extends React.Component {
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public componentDidMount() {
const scene = new Scene({
center: [120.19382669582967, 30.258134],
id: 'map',
pitch: 0,
type: 'mapbox',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 1,
});
const pointLayer = new PointLayer({});
const p1 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [83.671875, 44.84029065139799],
},
},
],
};
pointLayer
.source(data)
.color('name', [
'#FFF5B8',
'#FFDC7D',
'#FFAB5C',
'#F27049',
'#D42F31',
'#730D1C',
])
.shape('subregion',[
'circle',
'triangle',
'square',
'pentagon',
'hexagon',
'octogon',
'hexagram',
'rhombus',
'vesica',
])
.size('scalerank', [2, 4, 6, 8, 10]);
scene.addLayer(pointLayer);
console.log(pointLayer);
scene.render();
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

View File

@ -0,0 +1,58 @@
import { Point3dLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
import * as React from 'react';
import data from '../data/data.json';
export default class Point3D extends React.Component {
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public componentDidMount() {
const scene = new Scene({
center: [120.19382669582967, 30.258134],
id: 'map',
pitch: 0,
type: 'mapbox',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 1,
});
const pointLayer = new Point3dLayer({});
const p1 = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [83.671875, 44.84029065139799],
},
},
],
};
pointLayer
.source(data)
.color('red')
.shape('cylinder')
.size([15, 10]);
scene.addLayer(pointLayer);
scene.render();
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ import Mapbox from './components/Mapbox';
// import PointImage from './components/pointImage';
// @ts-ignore
import notes from './Map.md';
// @ts-ignore
storiesOf('地图底图', module)
.add('高德地图', () => <AMap />, {
notes: { markdown: notes },

View File

@ -31,14 +31,9 @@ export default class Mapbox extends React.Component {
layer
.source(await response.json())
.size('name', [0, 10000, 50000, 30000, 100000])
.color('name', [
'#2E8AE6',
'#69D1AB',
'#DAF291',
'#FFD591',
'#FF7A45',
'#CF1D49',
])
.color('name', () => {
return 'yellow';
})
.shape('fill')
.style({
opacity: 0.8,

View File

@ -1,5 +1,5 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import Polygon from './components/Polygon';
// @ts-ignore
storiesOf('MultiPassRenderer', module).add('blur', () => <Polygon />);

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import AdvancedAPI from './components/AdvancedAPI';
import Highlight from './components/Highlight';
import Tooltip from './components/Tooltip';
// @ts-ignore
storiesOf('交互', module)
.add('拾取 & 高亮', () => <Highlight />)
.add('拾取 & Tooltip', () => <Tooltip />)

3459
yarn.lock

File diff suppressed because it is too large Load Diff