├── packages ├── mapbox-regl │ ├── global.d.ts │ ├── src │ │ ├── shaders │ │ │ ├── draw.frag.glsl │ │ │ └── draw.vert.glsl │ │ └── index.ts │ ├── tsconfig.json │ ├── dist │ │ ├── terrain-layer.esm.js.map │ │ ├── terrain-layer.cjs.js.map │ │ ├── types │ │ │ └── index.d.ts │ │ ├── terrain-layer.min.js │ │ ├── terrain-layer.esm.js │ │ ├── terrain-layer.cjs.js │ │ ├── terrain-layer.min.js.map │ │ ├── terrain-layer.js.map │ │ └── terrain-layer.js │ ├── jest.config.js │ ├── package.json │ ├── bili.config.ts │ ├── demo │ │ └── index.html │ └── README.md ├── maptalks-regl │ ├── global.d.ts │ ├── tsconfig.json │ ├── src │ │ ├── shaders │ │ │ ├── draw.frag.glsl │ │ │ └── draw.vert.glsl │ │ ├── utils.ts │ │ └── index.ts │ ├── dist │ │ ├── terrain-layer.esm.js.map │ │ ├── terrain-layer.cjs.js.map │ │ ├── types │ │ │ ├── utils.d.ts │ │ │ └── index.d.ts │ │ ├── terrain-layer.min.js │ │ └── terrain-layer.esm.js │ ├── jest.config.js │ ├── package.json │ ├── bili.config.ts │ ├── demo │ │ └── index.html │ └── README.md └── maptalks-regl-with-loaders.gl │ ├── global.d.ts │ ├── tsconfig.json │ ├── src │ ├── shaders │ │ ├── draw.frag.glsl │ │ └── draw.vert.glsl │ ├── utils.ts │ └── index.ts │ ├── dist │ └── types │ │ ├── utils.d.ts │ │ └── index.d.ts │ ├── jest.config.js │ ├── package.json │ ├── bili.config.ts │ ├── demo │ └── index.html │ └── README.md ├── .prettierignore ├── .eslintignore ├── .huskyrc.json ├── .prettierrc ├── lerna.json ├── .editorconfig ├── tsconfig.prod.json ├── .gitignore ├── README.md ├── tsconfig.json ├── .eslintrc.js └── package.json /packages/mapbox-regl/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.glsl'; 2 | -------------------------------------------------------------------------------- /packages/maptalks-regl/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.glsl'; 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | yarn.lock 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | examples/ 4 | bili.config.js 5 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.glsl'; 2 | -------------------------------------------------------------------------------- /.huskyrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged", 4 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "arrowParens": "avoid" 9 | } 10 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "packages": [ 5 | "packages/*" 6 | ], 7 | "version": "1.0.0", 8 | "publishConfig": { 9 | "access": "public" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /packages/mapbox-regl/src/shaders/draw.frag.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | varying vec2 v_texCoord; 3 | varying float v_height; 4 | uniform sampler2D u_tile; 5 | uniform float u_opacity; 6 | 7 | void main() { 8 | vec4 color = texture2D(u_tile, v_texCoord); 9 | 10 | gl_FragColor = vec4(floor(255.0 * color * u_opacity) / 255.0); 11 | } 12 | -------------------------------------------------------------------------------- /packages/mapbox-regl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.prod.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "declaration": true, 6 | "declarationDir": "dist/types" 7 | }, 8 | "include": [ 9 | "src", 10 | "global.d.ts" 11 | ], 12 | "exclude": [ 13 | "node_modules" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/maptalks-regl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.prod.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "declaration": true, 6 | "declarationDir": "dist/types" 7 | }, 8 | "include": [ 9 | "src", 10 | "global.d.ts" 11 | ], 12 | "exclude": [ 13 | "node_modules" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/maptalks-regl/src/shaders/draw.frag.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | varying vec2 v_texCoord; 3 | varying float v_height; 4 | uniform sampler2D u_tile; 5 | uniform float u_opacity; 6 | 7 | void main() { 8 | vec4 color = texture2D(u_tile, v_texCoord); 9 | 10 | gl_FragColor = vec4(floor(255.0 * color * u_opacity) / 255.0); 11 | } 12 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.prod.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "declaration": true, 6 | "declarationDir": "dist/types" 7 | }, 8 | "include": [ 9 | "src", 10 | "global.d.ts" 11 | ], 12 | "exclude": [ 13 | "node_modules" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/src/shaders/draw.frag.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | varying vec2 v_texCoord; 3 | varying float v_height; 4 | uniform sampler2D u_tile; 5 | uniform float u_opacity; 6 | 7 | void main() { 8 | vec4 color = texture2D(u_tile, v_texCoord); 9 | 10 | gl_FragColor = vec4(floor(255.0 * color * u_opacity) / 255.0); 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": false, 5 | "emitDeclarationOnly": false, 6 | "declaration": true, 7 | "rootDir": "./", 8 | "baseUrl": "./" 9 | }, 10 | "include": [], 11 | "exclude": [ 12 | "dist", 13 | "**/__tests__/**/*", 14 | "**/*.spec.*" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.esm.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.cjs.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | .nyc_output 4 | .DS_Store 5 | 6 | .idea/ 7 | .vscode/ 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | .npm 16 | # Yarn Integrity file 17 | .yarn-integrity 18 | # dotenv environment variables file 19 | .env 20 | 21 | node_modules/ 22 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/src/shaders/draw.vert.glsl: -------------------------------------------------------------------------------- 1 | attribute vec3 a_pos; 2 | attribute vec2 a_texCoord; 3 | 4 | uniform mat4 u_matrix; 5 | uniform float u_tile_size; 6 | uniform float u_extrude_scale; 7 | 8 | varying vec2 v_texCoord; 9 | varying float v_height; 10 | void main() { 11 | v_texCoord = a_texCoord; 12 | 13 | v_height = a_pos.z; 14 | 15 | gl_Position = u_matrix * vec4(a_pos.x * u_tile_size, (a_pos.y - 1.0) * u_tile_size, a_pos.z * u_extrude_scale, 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/terrain-layer.esm.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/terrain-layer.cjs.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /packages/mapbox-regl/src/shaders/draw.vert.glsl: -------------------------------------------------------------------------------- 1 | attribute vec2 a_pos; 2 | uniform mat4 u_matrix; 3 | uniform sampler2D u_image; 4 | uniform float u_extrude_scale; 5 | 6 | varying vec2 v_texCoord; 7 | varying float v_height; 8 | float extent = 4096.0 * 2.0; 9 | void main() { 10 | v_texCoord = a_pos; 11 | 12 | vec3 rgb = texture2D(u_image, v_texCoord).rgb; 13 | float height = -10000.0 + ((rgb.r * 255.0 * 256.0 * 256.0 + rgb.g * 255.0 * 256.0 + rgb.b * 255.0) * 0.1); 14 | 15 | v_height = height; 16 | 17 | gl_Position = u_matrix * vec4(a_pos.xy * extent, height * u_extrude_scale, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/types/utils.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * create gl context 3 | * @param canvas 4 | * @param glOptions 5 | * @returns {null|*} 6 | */ 7 | declare const createContext: (canvas: HTMLCanvasElement, glOptions?: {}) => CanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext | null; 8 | declare function getDevicePixelRatio(): number; 9 | export declare function getUrl(template: string | string[], properties: { 10 | x: number; 11 | y: number; 12 | z: number; 13 | }): string | null; 14 | export { createContext, getDevicePixelRatio }; 15 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/dist/types/utils.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * create gl context 3 | * @param canvas 4 | * @param glOptions 5 | * @returns {null|*} 6 | */ 7 | declare const createContext: (canvas: HTMLCanvasElement, glOptions?: {}) => CanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext | null; 8 | declare function getDevicePixelRatio(): number; 9 | export declare function getUrl(template: string | string[], properties: { 10 | x: number; 11 | y: number; 12 | z: number; 13 | }): string | null; 14 | export { createContext, getDevicePixelRatio }; 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 用 regl + mapbox-gl / maptalks 构建一个最简单的地形展示 2 | 3 | 文章地址:https://zhuanlan.zhihu.com/p/343757223 4 | 5 | 示例: 6 | 7 | ### mapbox-gl 8 | 9 | [mapbox](https://sakitam-gis.github.io/simple-terrain-viz/packages/mapbox-regl/demo/index.html) 10 | 11 | ![mapbox](https://pic1.zhimg.com/v2-e653bac35bafb50bd1a1b7a97208a6c8_b.png) 12 | 13 | ### maptalks 14 | 15 | [maptalks](https://sakitam-gis.github.io/simple-terrain-viz/packages/maptalks-regl/demo/index.html) 16 | 17 | ![maptalks](https://pic3.zhimg.com/80/v2-dcdf44c0a669981fd8c3e959bbdb1882_720w.jpg) 18 | 19 | ### maptalks + loaders.gl 20 | 21 | [maptalks](https://sakitam-gis.github.io/simple-terrain-viz/packages/maptalks-regl-with-loaders.gl/demo/index.html) 22 | -------------------------------------------------------------------------------- /packages/maptalks-regl/src/shaders/draw.vert.glsl: -------------------------------------------------------------------------------- 1 | attribute vec2 a_pos; 2 | attribute vec2 a_texCoord; 3 | 4 | uniform mat4 u_matrix; 5 | uniform float u_tile_size; 6 | uniform sampler2D u_image; 7 | uniform float u_extrude_scale; 8 | uniform float u_hasTerrain; 9 | 10 | varying vec2 v_texCoord; 11 | varying float v_height; 12 | void main() { 13 | v_texCoord = a_texCoord; 14 | 15 | if (u_hasTerrain > 0.0) { 16 | vec3 rgb = texture2D(u_image, v_texCoord).rgb; 17 | float height = -10000.0 + ((rgb.r * 255.0 * 256.0 * 256.0 + rgb.g * 255.0 * 256.0 + rgb.b * 255.0) * 0.1); 18 | 19 | v_height = height; 20 | 21 | gl_Position = u_matrix * vec4(a_pos.xy * u_tile_size, height * u_extrude_scale, 1.0); 22 | } else { 23 | gl_Position = u_matrix * vec4(a_pos.xy * u_tile_size, 0.0, 1.0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "baseUrl": ".", 5 | "rootDir": ".", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": ["packages/*/src"], 9 | "maptalks/*": ["maptalks/dist/*"] 10 | }, 11 | "target": "es5", 12 | "module": "esnext", 13 | "lib": ["es2015", "es2016", "es2017", "dom"], 14 | "types": ["node", "reflect-metadata", "jest"], 15 | "esModuleInterop": true, 16 | "strictPropertyInitialization": false, 17 | "strict": true, 18 | "preserveSymlinks": true, 19 | "declaration": false, 20 | "allowJs": true, 21 | "allowSyntheticDefaultImports": true, 22 | "experimentalDecorators": true, 23 | "emitDecoratorMetadata": false 24 | }, 25 | "include": [ 26 | "packages/*/src" 27 | ], 28 | "exclude": [ 29 | "node_modules", 30 | "packages/*/src/**/__tests__" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/mapbox-regl/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | transform: { 4 | "^.+\\.js$": "babel-jest", 5 | "^.+\\.(ts|tsx)$": "ts-jest" 6 | }, 7 | testEnvironment: "jsdom", 8 | testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 9 | moduleFileExtensions: [ 10 | "ts", "tsx", "js", "jsx", "json", "node" 11 | ], 12 | testPathIgnorePatterns: ["/dist/", "/node_modules/"], 13 | watchPathIgnorePatterns: ["/dist/", "/node_modules/"], 14 | collectCoverage: true, 15 | coveragePathIgnorePatterns: [ 16 | "/node_modules/", 17 | "/test/" 18 | ], 19 | // coverageThreshold: { 20 | // "global": { 21 | // "branches": 0, 22 | // "functions": 0, 23 | // "lines": 0, 24 | // "statements": 0 25 | // } 26 | // }, 27 | collectCoverageFrom: [ 28 | "src/*.{js,ts,tsx}" 29 | ], 30 | clearMocks: true, 31 | coverageDirectory: 'coverage', 32 | coverageReporters: ['html', 'text', 'clover'], 33 | modulePathIgnorePatterns: ['dist'], 34 | roots: [''], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/maptalks-regl/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | transform: { 4 | "^.+\\.js$": "babel-jest", 5 | "^.+\\.(ts|tsx)$": "ts-jest" 6 | }, 7 | testEnvironment: "jsdom", 8 | testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 9 | moduleFileExtensions: [ 10 | "ts", "tsx", "js", "jsx", "json", "node" 11 | ], 12 | testPathIgnorePatterns: ["/dist/", "/node_modules/"], 13 | watchPathIgnorePatterns: ["/dist/", "/node_modules/"], 14 | collectCoverage: true, 15 | coveragePathIgnorePatterns: [ 16 | "/node_modules/", 17 | "/test/" 18 | ], 19 | // coverageThreshold: { 20 | // "global": { 21 | // "branches": 0, 22 | // "functions": 0, 23 | // "lines": 0, 24 | // "statements": 0 25 | // } 26 | // }, 27 | collectCoverageFrom: [ 28 | "src/*.{js,ts,tsx}" 29 | ], 30 | clearMocks: true, 31 | coverageDirectory: 'coverage', 32 | coverageReporters: ['html', 'text', 'clover'], 33 | modulePathIgnorePatterns: ['dist'], 34 | roots: [''], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | transform: { 4 | "^.+\\.js$": "babel-jest", 5 | "^.+\\.(ts|tsx)$": "ts-jest" 6 | }, 7 | testEnvironment: "jsdom", 8 | testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 9 | moduleFileExtensions: [ 10 | "ts", "tsx", "js", "jsx", "json", "node" 11 | ], 12 | testPathIgnorePatterns: ["/dist/", "/node_modules/"], 13 | watchPathIgnorePatterns: ["/dist/", "/node_modules/"], 14 | collectCoverage: true, 15 | coveragePathIgnorePatterns: [ 16 | "/node_modules/", 17 | "/test/" 18 | ], 19 | // coverageThreshold: { 20 | // "global": { 21 | // "branches": 0, 22 | // "functions": 0, 23 | // "lines": 0, 24 | // "statements": 0 25 | // } 26 | // }, 27 | collectCoverageFrom: [ 28 | "src/*.{js,ts,tsx}" 29 | ], 30 | clearMocks: true, 31 | coverageDirectory: 'coverage', 32 | coverageReporters: ['html', 'text', 'clover'], 33 | modulePathIgnorePatterns: ['dist'], 34 | roots: [''], 35 | }; 36 | -------------------------------------------------------------------------------- /packages/mapbox-regl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mapbox-regl", 3 | "version": "1.0.0", 4 | "author": "sakitam-fdd ", 5 | "homepage": "https://github.com/sakitam-gis/simple-terrain-viz", 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "dist/terrain-layer.js", 10 | "module": "dist/terrain-layer.esm.js", 11 | "unpkg": "dist/terrain-layer.js", 12 | "commonjs": "dist/terrain-layer.cjs.js", 13 | "typings": "dist/types/index.d.ts", 14 | "namespace": "TerrainLayer", 15 | "scripts": { 16 | "tsc": "tsc --project tsconfig.json --declaration --declarationDir dist/types", 17 | "dev": "cross-env yarn bili --watch --env.NODE_ENV production", 18 | "build": "cross-env yarn bili --env.NODE_ENV production", 19 | "docs": "typedoc --out docs/api --theme minimal --mode file", 20 | "test": "jest" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/sakitam-gis/simple-terrain-viz/issues" 24 | }, 25 | "keywords": [ 26 | "regl", 27 | "mapbox" 28 | ], 29 | "license": "MIT", 30 | "repository": { 31 | "type": "git", 32 | "url": "git@github.com:sakitam-gis/simple-terrain-viz.git", 33 | "directory": "packages/mapbox-regl" 34 | }, 35 | "dependencies": { 36 | "regl": "^2.0.1" 37 | }, 38 | "devDependencies": { 39 | "@sakitam-gis/mapbox-gl": "^1.20.0", 40 | "bili": "^5.0.5" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/maptalks-regl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "maptalks-regl", 3 | "version": "1.0.0", 4 | "author": "sakitam-fdd ", 5 | "homepage": "https://github.com/sakitam-gis/simple-terrain-viz", 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "dist/terrain-layer.js", 10 | "module": "dist/terrain-layer.esm.js", 11 | "unpkg": "dist/terrain-layer.js", 12 | "commonjs": "dist/terrain-layer.cjs.js", 13 | "typings": "dist/types/index.d.ts", 14 | "namespace": "TerrainLayer", 15 | "scripts": { 16 | "tsc": "tsc --project tsconfig.json --declaration --declarationDir dist/types", 17 | "dev": "cross-env yarn bili --watch --env.NODE_ENV production", 18 | "build": "cross-env yarn bili --env.NODE_ENV production", 19 | "docs": "typedoc --out docs/api --theme minimal --mode file", 20 | "test": "jest" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/sakitam-gis/simple-terrain-viz/issues" 24 | }, 25 | "keywords": [ 26 | "regl", 27 | "maptalks" 28 | ], 29 | "license": "MIT", 30 | "repository": { 31 | "type": "git", 32 | "url": "git@github.com:sakitam-gis/simple-terrain-viz.git", 33 | "directory": "packages/maptalks-regl" 34 | }, 35 | "peerDependencies": { 36 | "maptalks": "^0.49.1" 37 | }, 38 | "dependencies": { 39 | "gl-matrix": "^3.3.0" 40 | }, 41 | "devDependencies": { 42 | "maptalks": "^0.49.1" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: [ 4 | 'airbnb-base', 5 | ], 6 | env: { 7 | browser: true, 8 | node: true, 9 | }, 10 | plugins: [], 11 | rules: { 12 | 'import/order': 'off', 13 | 'import/extensions': 'off', 14 | 15 | 'max-len': ['error', { 'code': 150 }], 16 | 'no-shadow': 0, 17 | 'func-names': 0, 18 | 19 | 'no-unused-expressions': ['error', { 'allowShortCircuit': true }], 20 | 'no-restricted-properties': 'off', 21 | 'array-callback-return': 'off', 22 | 'prefer-destructuring': 'off', 23 | 24 | 'import/named': 0, 25 | 'import/no-extraneous-dependencies': 0, 26 | 'import/prefer-default-export': 0, 27 | 'no-plusplus': 0, 28 | 'import/no-unresolved': 0, 29 | 'no-param-reassign': 0, 30 | 31 | 'class-methods-use-this': 0, 32 | 33 | // allow global require 34 | 'linebreak-style': 0, 35 | 'indent': 0, 36 | 'global-require': 0, 37 | // allow paren-less arrow functions 38 | 'arrow-parens': 0, 39 | // allow async-await 40 | 'generator-star-spacing': 0, 41 | 'no-prototype-builtins': 0, 42 | 'no-underscore-dangle': 0, 43 | 'implicit-arrow-linebreak': 0, 44 | 'no-console': 'off', 45 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 46 | }, 47 | overrides: [ 48 | { 49 | files: ['**/*.js?(x)'], 50 | }, 51 | ], 52 | globals: { 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "maptalks-regl-with-loaders.gl", 3 | "version": "1.0.0", 4 | "author": "sakitam-fdd ", 5 | "homepage": "https://github.com/sakitam-gis/simple-terrain-viz", 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "dist/terrain-layer.js", 10 | "module": "dist/terrain-layer.esm.js", 11 | "unpkg": "dist/terrain-layer.js", 12 | "commonjs": "dist/terrain-layer.cjs.js", 13 | "typings": "dist/types/index.d.ts", 14 | "namespace": "TerrainLayer", 15 | "scripts": { 16 | "tsc": "tsc --project tsconfig.json --declaration --declarationDir dist/types", 17 | "dev": "cross-env yarn bili --watch --env.NODE_ENV production", 18 | "build": "cross-env yarn bili --env.NODE_ENV production", 19 | "docs": "typedoc --out docs/api --theme minimal --mode file", 20 | "test": "jest" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/sakitam-gis/simple-terrain-viz/issues" 24 | }, 25 | "keywords": [ 26 | "regl", 27 | "maptalks" 28 | ], 29 | "license": "MIT", 30 | "repository": { 31 | "type": "git", 32 | "url": "git@github.com:sakitam-gis/simple-terrain-viz.git", 33 | "directory": "packages/maptalks-regl-with-loaders.gl" 34 | }, 35 | "peerDependencies": { 36 | "maptalks": "^0.49.1" 37 | }, 38 | "dependencies": { 39 | "gl-matrix": "^3.3.0", 40 | "@loaders.gl/core": "^2.3.7", 41 | "@loaders.gl/terrain": "^2.3.7", 42 | "@loaders.gl/images": "^2.3.7", 43 | "@loaders.gl/loader-utils": "^2.3.7" 44 | }, 45 | "devDependencies": { 46 | "maptalks": "^0.49.1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/maptalks-regl/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * create gl context 3 | * @param canvas 4 | * @param glOptions 5 | * @returns {null|*} 6 | */ 7 | const createContext = function (canvas: HTMLCanvasElement, glOptions = {}) { 8 | if (!canvas) return null; 9 | function onContextCreationError (error: any) { 10 | console.log(error.statusMessage); 11 | } 12 | if (canvas && canvas.addEventListener) { 13 | canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); 14 | } 15 | let gl = canvas.getContext('webgl', glOptions); 16 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 17 | if (!gl) { 18 | gl = canvas.getContext('webgl', glOptions); 19 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 20 | } 21 | 22 | if (canvas.removeEventListener) { 23 | canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); 24 | } 25 | return gl; 26 | }; 27 | 28 | let devicePixelRatio = 1; 29 | // fixed: ssr render @link https://github.com/gatsbyjs/gatsby/issues/25507 30 | if (typeof window !== 'undefined') { 31 | // @ts-ignore 32 | devicePixelRatio = window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI; 33 | } 34 | 35 | function getDevicePixelRatio () { 36 | return devicePixelRatio; 37 | } 38 | 39 | export function getUrl(template: string | string[], properties: { 40 | x: number; 41 | y: number; 42 | z: number; 43 | }) { 44 | if (!template || !template.length) { 45 | return null; 46 | } 47 | if (Array.isArray(template)) { 48 | const index = Math.abs(properties.x + properties.y) % template.length; 49 | template = template[index]; 50 | } 51 | 52 | const { x, y, z } = properties; 53 | return template 54 | .replace('{x}', String(x)) 55 | .replace('{y}', String(y)) 56 | .replace('{z}', String(z)) 57 | .replace('{-y}', String(Math.pow(2, z) - y - 1)); 58 | } 59 | 60 | export { 61 | createContext, 62 | getDevicePixelRatio 63 | }; 64 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * create gl context 3 | * @param canvas 4 | * @param glOptions 5 | * @returns {null|*} 6 | */ 7 | const createContext = function (canvas: HTMLCanvasElement, glOptions = {}) { 8 | if (!canvas) return null; 9 | function onContextCreationError (error: any) { 10 | console.log(error.statusMessage); 11 | } 12 | if (canvas && canvas.addEventListener) { 13 | canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); 14 | } 15 | let gl = canvas.getContext('webgl', glOptions); 16 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 17 | if (!gl) { 18 | gl = canvas.getContext('webgl', glOptions); 19 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 20 | } 21 | 22 | if (canvas.removeEventListener) { 23 | canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); 24 | } 25 | return gl; 26 | }; 27 | 28 | let devicePixelRatio = 1; 29 | // fixed: ssr render @link https://github.com/gatsbyjs/gatsby/issues/25507 30 | if (typeof window !== 'undefined') { 31 | // @ts-ignore 32 | devicePixelRatio = window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI; 33 | } 34 | 35 | function getDevicePixelRatio () { 36 | return devicePixelRatio; 37 | } 38 | 39 | export function getUrl(template: string | string[], properties: { 40 | x: number; 41 | y: number; 42 | z: number; 43 | }) { 44 | if (!template || !template.length) { 45 | return null; 46 | } 47 | if (Array.isArray(template)) { 48 | const index = Math.abs(properties.x + properties.y) % template.length; 49 | template = template[index]; 50 | } 51 | 52 | const { x, y, z } = properties; 53 | return template 54 | .replace('{x}', String(x)) 55 | .replace('{y}', String(y)) 56 | .replace('{z}', String(z)) 57 | .replace('{-y}', String(Math.pow(2, z) - y - 1)); 58 | } 59 | 60 | export { 61 | createContext, 62 | getDevicePixelRatio 63 | }; 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-terrain-viz", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "bootstrap": "lerna bootstrap", 7 | "cm": "git-cz", 8 | "postinstall": "yarn bootstrap", 9 | "test": "lerna run --parallel test" 10 | }, 11 | "license": "MIT", 12 | "dependencies": { 13 | "regl": "^2.0.1" 14 | }, 15 | "devDependencies": { 16 | "@babel/plugin-transform-runtime": "^7.12.10", 17 | "@babel/preset-typescript": "^7.7.4", 18 | "@babel/types": "^7.7.4", 19 | "@commitlint/cli": "^9.1.2", 20 | "@commitlint/config-conventional": "^9.1.2", 21 | "@types/jest": "^26.0.10", 22 | "@types/node": "^14.6.0", 23 | "@types/fs-extra": "^9.0.5", 24 | "@types/gl": "^4.1.0", 25 | "all-contributors-cli": "^6.19.0", 26 | "commitizen": "^4.1.5", 27 | "cz-conventional-changelog": "^3.2.0", 28 | "typedoc": "^0.19.2", 29 | "prettier": "^2.2.1", 30 | "fs-extra": "^9.0.1", 31 | "husky": "^4.2.5", 32 | "lerna": "^3.22.1", 33 | "bili": "^5.0.5", 34 | "babel-eslint": "^10.1.0", 35 | "cross-env": "^7.0.3", 36 | "yarn-or-npm": "^3.0.1", 37 | "eslint": "^5.16.0", 38 | "eslint-config-airbnb-base": "^14.1.0", 39 | "eslint-config-prettier": "^6.11.0", 40 | "eslint-friendly-formatter": "^4.0.1", 41 | "eslint-loader": "3.0.3", 42 | "eslint-plugin-import": "^2.22.1", 43 | "jest": "^26.0.1", 44 | "jest-config": "^26.4.2", 45 | "babel-jest": "^26.6.3", 46 | "rollup-plugin-glslify": "^1.2.0", 47 | "rollup-plugin-terser": "^7.0.2", 48 | "rollup-plugin-web-worker-loader": "^1.5.0", 49 | "rollup-plugin-node-polyfills": "^0.2.1", 50 | "rollup-plugin-typescript2": "^0.29.0", 51 | "tslib": "^2.0.1", 52 | "ts-jest": "^26.2.0", 53 | "ts-loader": "^8.0.2", 54 | "ts-node": "^9.0.0", 55 | "typescript": "4.0.2" 56 | }, 57 | "config": { 58 | "commitizen": { 59 | "path": "cz-conventional-changelog" 60 | } 61 | }, 62 | "commitlint": { 63 | "extends": [ 64 | "@commitlint/config-conventional" 65 | ] 66 | }, 67 | "workspaces": ["packages/*"] 68 | } 69 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | export declare type ID = string | number; 3 | export interface TileJSON { 4 | type: 'raster'; 5 | tileSize: number; 6 | terrainTiles: string[]; 7 | realTiles: string[]; 8 | attribution: string; 9 | } 10 | export interface IOptions { 11 | opacity?: number; 12 | extrudeScale?: number; 13 | widthSegments?: number; 14 | heightSegments?: number; 15 | } 16 | export interface ISource { 17 | on: (type: string, cb: (e: any) => void) => any; 18 | } 19 | declare type IMap = any; 20 | declare type ITile = any; 21 | export declare namespace DrawCommon { 22 | interface Props { 23 | a_pos: REGL.Vec2[]; 24 | elements: REGL.Elements; 25 | u_matrix: REGL.Mat4; 26 | u_image: REGL.Texture2D; 27 | u_tile: REGL.Texture2D; 28 | u_opacity: number; 29 | u_extrude_scale: number; 30 | } 31 | interface Uniforms { 32 | u_matrix: REGL.Mat4; 33 | u_image: REGL.Texture2D; 34 | u_tile: REGL.Texture2D; 35 | u_opacity: number; 36 | u_extrude_scale: number; 37 | } 38 | interface Attributes { 39 | a_pos: REGL.Vec2[]; 40 | } 41 | } 42 | export default class TerrainLayer { 43 | id: ID; 44 | map: IMap; 45 | private gl; 46 | private tileJson; 47 | private type; 48 | private readonly source; 49 | private readonly terrainSource; 50 | private tileSource; 51 | private terrainTileSource; 52 | private terrainSourceCache; 53 | private sourceCache; 54 | private regl; 55 | private command; 56 | private options; 57 | private renderingMode; 58 | constructor(id: ID, tileJson: TileJSON, options?: IOptions); 59 | createTerrain(): void; 60 | createTile(): void; 61 | onAdd(map: IMap, gl: WebGLRenderingContext | WebGL2RenderingContext): void; 62 | move(): void; 63 | onData(e: any): void; 64 | onTerrainData(e: any): void; 65 | updateTiles(key: string): void; 66 | getPlaneBuffer(tile: ITile, width: number, height: number, widthSegments: number, heightSegments: number): any; 67 | render(): void; 68 | setOptions(options: IOptions): void; 69 | onRemove(): void; 70 | } 71 | export {}; 72 | -------------------------------------------------------------------------------- /packages/mapbox-regl/bili.config.ts: -------------------------------------------------------------------------------- 1 | // bili.config.ts 2 | import { Config } from 'bili' 3 | import { RollupConfig } from 'bili/types/types'; 4 | import * as fs from 'fs-extra' 5 | import { resolve } from 'path' 6 | 7 | const json = fs.readJsonSync(resolve(__dirname, `./package.json`)); 8 | 9 | const generateBanner = (json: any): string => { 10 | const time = new Date(); 11 | const year = time.getFullYear(); 12 | const banner = `/*!\n * author: ${json.author} 13 | * ${json.name} v${json.version} 14 | * build-time: ${year}-${time.getMonth() + 1}-${time.getDate()} ${time.getHours()}:${time.getMinutes()} 15 | * LICENSE: ${json.license} 16 | * (c) 2020-${year} ${json.homepage}\n */`; 17 | return banner 18 | } 19 | 20 | const namePath = 'terrain-layer'; 21 | 22 | const config: Config = { 23 | babel: undefined, 24 | input: 'src/index.ts', 25 | output: { 26 | format: ['cjs', 'umd', 'umd-min', 'esm'], 27 | moduleName: json.namespace, 28 | sourceMap: true, 29 | }, 30 | extendConfig(config, { format }) { 31 | if (format.startsWith('umd')) { 32 | config.output.fileName = `${namePath}[min].js` 33 | } 34 | if (format === 'esm') { 35 | config.output.fileName = `${namePath}.esm.js` 36 | } 37 | if (format === 'cjs') { 38 | config.output.fileName = `${namePath}.cjs.js` 39 | } 40 | 41 | // config.externals = []; // 默认 bili 会排除外部依赖 42 | 43 | return config 44 | }, 45 | extendRollupConfig: (config: RollupConfig) => { 46 | if (config.outputConfig.format === 'umd') { 47 | /** Disable warning for default imports */ 48 | // config.outputConfig.exports = 'named' 49 | // // it seems the umd bundle can not satisfies our demand 50 | // config.outputConfig.footer = `if(typeof window !== "undefined" && window.${json.namespace}) { 51 | // window.${json.namespace} = window.${json.namespace}.default; 52 | // }`; 53 | } 54 | return config 55 | }, 56 | banner: generateBanner(json), 57 | plugins: { 58 | glslify: {}, 59 | 'typescript2': { 60 | clean: true, 61 | check: false, 62 | useTsconfigDeclarationDir: true 63 | } 64 | }, 65 | globals: { 66 | mapboxgl: 'mapbox-gl', 67 | regl: 'createREGL' 68 | }, 69 | externals: [ 70 | 'mapbox-gl' 71 | ] 72 | } 73 | 74 | export default config 75 | -------------------------------------------------------------------------------- /packages/maptalks-regl/bili.config.ts: -------------------------------------------------------------------------------- 1 | // bili.config.ts 2 | import { Config } from 'bili' 3 | import { RollupConfig } from 'bili/types/types'; 4 | import * as fs from 'fs-extra' 5 | import { resolve } from 'path' 6 | 7 | const json = fs.readJsonSync(resolve(__dirname, `./package.json`)); 8 | 9 | const generateBanner = (json: any): string => { 10 | const time = new Date(); 11 | const year = time.getFullYear(); 12 | const banner = `/*!\n * author: ${json.author} 13 | * ${json.name} v${json.version} 14 | * build-time: ${year}-${time.getMonth() + 1}-${time.getDate()} ${time.getHours()}:${time.getMinutes()} 15 | * LICENSE: ${json.license} 16 | * (c) 2020-${year} ${json.homepage}\n */`; 17 | return banner 18 | } 19 | 20 | const namePath = 'terrain-layer'; 21 | 22 | const config: Config = { 23 | babel: undefined, 24 | input: 'src/index.ts', 25 | output: { 26 | format: ['cjs', 'umd', 'umd-min', 'esm'], 27 | moduleName: json.namespace, 28 | sourceMap: false, 29 | }, 30 | extendConfig(config, { format }) { 31 | if (format.startsWith('umd')) { 32 | config.output.fileName = `${namePath}[min].js` 33 | } 34 | if (format === 'esm') { 35 | config.output.fileName = `${namePath}.esm.js` 36 | } 37 | if (format === 'cjs') { 38 | config.output.fileName = `${namePath}.cjs.js` 39 | } 40 | 41 | config.externals = config.externals.filter(item => item !== 'gl-matrix'); // 默认 bili 会排除外部依赖 42 | 43 | return config 44 | }, 45 | extendRollupConfig: (config: RollupConfig) => { 46 | if (config.outputConfig.format === 'umd') { 47 | /** Disable warning for default imports */ 48 | config.outputConfig.exports = 'named' 49 | // it seems the umd bundle can not satisfies our demand 50 | config.outputConfig.footer = `if(typeof window !== "undefined" && window.${json.namespace}) { 51 | window.${json.namespace} = window.${json.namespace}.default; 52 | }`; 53 | } 54 | return config 55 | }, 56 | banner: generateBanner(json), 57 | plugins: { 58 | glslify: {}, 59 | 'typescript2': { 60 | clean: true, 61 | check: false, 62 | useTsconfigDeclarationDir: true 63 | } 64 | }, 65 | globals: { 66 | maptalks: 'maptalks', 67 | regl: 'createREGL' 68 | }, 69 | externals: [ 70 | 'maptalks', 71 | 'regl' 72 | ] 73 | } 74 | 75 | export default config 76 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/bili.config.ts: -------------------------------------------------------------------------------- 1 | // bili.config.ts 2 | import { Config } from 'bili' 3 | import { RollupConfig } from 'bili/types/types'; 4 | import * as fs from 'fs-extra'; 5 | import { resolve } from 'path'; 6 | 7 | const json = fs.readJsonSync(resolve(__dirname, `./package.json`)); 8 | 9 | const generateBanner = (json: any): string => { 10 | const time = new Date(); 11 | const year = time.getFullYear(); 12 | const banner = `/*!\n * author: ${json.author} 13 | * ${json.name} v${json.version} 14 | * build-time: ${year}-${time.getMonth() + 1}-${time.getDate()} ${time.getHours()}:${time.getMinutes()} 15 | * LICENSE: ${json.license} 16 | * (c) 2020-${year} ${json.homepage}\n */`; 17 | return banner 18 | } 19 | 20 | const namePath = 'terrain-layer'; 21 | 22 | const config: Config = { 23 | babel: { 24 | asyncToPromises: false, 25 | }, 26 | input: 'src/index.ts', 27 | output: { 28 | format: ['cjs', 'umd', 'umd-min', 'esm'], 29 | moduleName: json.namespace, 30 | sourceMap: false, 31 | }, 32 | extendConfig(config, { format }) { 33 | if (format.startsWith('umd')) { 34 | config.output.fileName = `${namePath}[min].js` 35 | } 36 | if (format === 'esm') { 37 | config.output.fileName = `${namePath}.esm.js` 38 | } 39 | if (format === 'cjs') { 40 | config.output.fileName = `${namePath}.cjs.js` 41 | } 42 | 43 | // config.externals = config.externals.filter(item => item !== 'gl-matrix' && item !== 'fs' && item !== 'util' && item !== 'module' && item !== 'path' && item !== 'child_process'); // 默认 bili 会排除外部依赖 44 | config.externals = ['maptalks', 'regl']; 45 | 46 | return config 47 | }, 48 | extendRollupConfig: (config: RollupConfig) => { 49 | if (config.outputConfig.format === 'umd') { 50 | /** Disable warning for default imports */ 51 | config.outputConfig.exports = 'named' 52 | // it seems the umd bundle can not satisfies our demand 53 | config.outputConfig.footer = `if(typeof window !== "undefined" && window.${json.namespace}) { 54 | window.${json.namespace} = window.${json.namespace}.default; 55 | }`; 56 | } 57 | 58 | return config 59 | }, 60 | banner: generateBanner(json), 61 | plugins: { 62 | babel: false, 63 | glslify: {}, 64 | 'typescript2': { 65 | clean: true, 66 | check: false, 67 | useTsconfigDeclarationDir: true 68 | }, 69 | '@rollup/plugin-node-resolve': { 70 | browser: true, 71 | preferBuiltins: true 72 | }, 73 | // '@rollup/plugin-commonjs': {}, 74 | }, 75 | globals: { 76 | maptalks: 'maptalks', 77 | regl: 'createREGL' 78 | }, 79 | externals: [ 80 | 'maptalks', 81 | 'regl' 82 | ] 83 | } 84 | 85 | export default config 86 | -------------------------------------------------------------------------------- /packages/mapbox-regl/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mapbox-regl-tile-layer 6 | 7 | 8 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /packages/maptalks-regl/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | maptalks-regl-tile-layer 6 | 7 | 8 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | maptalks-regl-tile-layer 6 | 7 | 8 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 22 | 23 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | import { TileLayer, renderer } from 'maptalks'; 3 | export declare namespace DrawCommon { 4 | interface Props { 5 | a_pos: REGL.Vec2[]; 6 | a_texCoord: REGL.Vec2[]; 7 | elements: REGL.Elements; 8 | u_matrix: REGL.Mat4; 9 | u_image: REGL.Texture2D; 10 | u_tile: REGL.Texture2D; 11 | u_tile_size: number; 12 | u_hasTerrain: number; 13 | u_opacity: number; 14 | u_extrude_scale: number; 15 | zoom: number; 16 | canvasSize: [number, number]; 17 | } 18 | interface Uniforms { 19 | u_matrix: REGL.Mat4; 20 | u_image: REGL.Texture2D; 21 | u_tile: REGL.Texture2D; 22 | u_tile_size: number; 23 | u_hasTerrain: number; 24 | u_opacity: number; 25 | u_extrude_scale: number; 26 | } 27 | interface Attributes { 28 | a_pos: REGL.Vec2[]; 29 | a_texCoord: REGL.Vec2[]; 30 | } 31 | } 32 | interface Point { 33 | x: number; 34 | y: number; 35 | } 36 | declare type handleFunc = (...args: any[]) => void; 37 | interface MTK { 38 | projViewMatrix: REGL.Mat4; 39 | getResolution: () => number; 40 | getMaxNativeZoom: () => number; 41 | getCenter: () => Point; 42 | getPitch: () => number; 43 | getBearing: () => number; 44 | on: (type: string, func: handleFunc, ctx: any) => void; 45 | off: (type: string, func: handleFunc, ctx: any) => void; 46 | getDevicePixelRatio: () => number; 47 | getSize: () => { 48 | width: number; 49 | height: number; 50 | }; 51 | getGLScale(z: number): number; 52 | } 53 | interface ICanvasSize { 54 | width: number; 55 | height: number; 56 | } 57 | export interface IOptions { 58 | [key: string]: any; 59 | urlTemplate: string; 60 | subdomains: (string | number)[]; 61 | terrainTiles: string | string[]; 62 | doubleBuffer?: boolean; 63 | animation?: boolean; 64 | fps?: number; 65 | attribution?: string; 66 | minZoom?: number; 67 | maxZoom?: number; 68 | visible?: boolean; 69 | opacity?: number; 70 | zIndex?: number; 71 | hitDetect?: boolean; 72 | renderer?: 'canvas' | 'gl'; 73 | globalCompositeOperation?: string | null; 74 | cssFilter?: string | null; 75 | forceRenderOnMoving?: boolean; 76 | forceRenderOnZooming?: boolean; 77 | forceRenderOnRotating?: boolean; 78 | registerEvents?: boolean; 79 | renderStart?: () => void; 80 | renderEnd?: () => void; 81 | customCreateGLContext?: (canvas: HTMLCanvasElement, attrs: any) => WebGLRenderingContext | WebGL2RenderingContext; 82 | } 83 | declare class TerrainLayer extends TileLayer { 84 | id: string | number; 85 | options: Partial; 86 | constructor(id: string | number, options?: Partial); 87 | rerender(): void; 88 | getMap(): MTK; 89 | getTileSize(): any; 90 | } 91 | interface IRenderer { 92 | getMap: () => MTK | null; 93 | } 94 | export declare class Renderer extends renderer.TileLayerCanvasRenderer implements IRenderer { 95 | private canvas; 96 | private canvas2; 97 | private gl; 98 | private layer; 99 | private regl; 100 | private command; 101 | private _tileZoom; 102 | private isDrawable; 103 | private _drawTiles; 104 | private getPlaneBuffer; 105 | private loadTile; 106 | onTileLoad(tileImage: HTMLImageElement, tileInfo: any): any; 107 | drawTile(tileInfo: any, tileImage: HTMLImageElement): void; 108 | private loadTileImage; 109 | private getCanvasImage; 110 | onCanvasCreate(): void; 111 | createContext(): void; 112 | /** 113 | * when map changed, call canvas change 114 | * @param canvasSize 115 | */ 116 | resizeCanvas(canvasSize: ICanvasSize): void; 117 | /** 118 | * clear canvas 119 | */ 120 | clearCanvas(): void; 121 | getMap(): MTK; 122 | onRemove(): void; 123 | completeRender(): any; 124 | setCanvasUpdated(): any; 125 | setToRedraw(): any; 126 | private prepareCanvas; 127 | private getTileOpacity; 128 | } 129 | export default TerrainLayer; 130 | -------------------------------------------------------------------------------- /packages/mapbox-regl/README.md: -------------------------------------------------------------------------------- 1 | # maptalks.deckgl 2 | 3 | The plugin to play deck.gl with maptalks.js 4 | 5 | [![Build Status](https://travis-ci.org/sakitam-gis/maptalks.deckgl.svg?branch=master)](https://www.travis-ci.org/sakitam-gis/maptalks.deckgl) 6 | [![NPM downloads](https://img.shields.io/npm/dm/maptalks.deckgl.svg)](https://npmjs.org/package/maptalks.deckgl) 7 | [![](https://data.jsdelivr.com/v1/package/npm/maptalks.deckgl/badge)](https://www.jsdelivr.com/package/npm/maptalks.deckgl) 8 | ![JS gzip size](http://img.badgesize.io/https://unpkg.com/maptalks.deckgl/dist/maptalks-deckgl.js?compression=gzip&label=gzip%20size:%20JS) 9 | [![Npm package](https://img.shields.io/npm/v/maptalks.deckgl.svg)](https://www.npmjs.org/package/maptalks.deckgl) 10 | [![GitHub stars](https://img.shields.io/github/stars/sakitam-gis/maptalks.deckgl.svg)](https://github.com/sakitam-gis/maptalks.deckgl/stargazers) 11 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/sakitam-gis/maptalks.deckgl/master/LICENSE) 12 | 13 | ## Dev 14 | 15 | ```bash 16 | git clone https://github.com/sakitam-gis/maptalks.deckgl.git 17 | npm install / yarn 18 | npm run dev / yarn run dev 19 | npm run build / yarn run build 20 | ``` 21 | 22 | ## install 23 | 24 | > `npm i maptalks.deckgl` 25 | 26 | ## use 使用 27 | 28 | ```js 29 | import DeckGLLayer from 'maptalks.deckgl'; 30 | import {GeoJsonLayer, PolygonLayer} from '@deck.gl/layers'; 31 | import {LightingEffect, AmbientLight, _SunLight as SunLight} from '@deck.gl/core'; 32 | import {scaleThreshold} from 'd3-scale'; 33 | import * as maptalks from 'maptalks'; 34 | 35 | const map = new maptalks.Map(this.container, { 36 | center: [-74.01194070150844, 40.70708981756565], 37 | zoom: 5, 38 | pitch: 0, 39 | bearing: 0, 40 | centerCross: true, 41 | baseLayer: new maptalks.TileLayer('tile', { 42 | 'urlTemplate': 'https://api.mapbox.com/styles/v1/mapbox/dark-v10/tiles/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejh2N21nMzAxMmQzMnA5emRyN2lucW0ifQ.jSE-g2vsn48Ry928pqylcg' 43 | // 'subdomains': ['a', 'b', 'c', 'd'] 44 | }), 45 | }); 46 | // Source data GeoJSON 47 | const DATA_URL = 48 | 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/geojson/vancouver-blocks.json'; // eslint-disable-line 49 | 50 | export const COLOR_SCALE = scaleThreshold() 51 | .domain([-0.6, -0.45, -0.3, -0.15, 0, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 1.05, 1.2]) 52 | // @ts-ignore 53 | .range([[65, 182, 196], [127, 205, 187], [199, 233, 180], [237, 248, 177], [255, 255, 204], [255, 237, 160], [254, 217, 118], [254, 178, 76], [253, 141, 60], [252, 78, 42], [227, 26, 28], [189, 0, 38], [128, 0, 38]]); 54 | 55 | const ambientLight = new AmbientLight({ 56 | color: [255, 255, 255], 57 | intensity: 1.0 58 | }); 59 | 60 | const dirLight = new SunLight({ 61 | timestamp: Date.UTC(2019, 7, 1, 22), 62 | color: [255, 255, 255], 63 | intensity: 1.0, 64 | _shadow: true 65 | }); 66 | 67 | const landCover = [[[-123.0, 49.196], [-123.0, 49.324], [-123.306, 49.324], [-123.306, 49.196]]]; 68 | 69 | 70 | const lightingEffect = new LightingEffect({ambientLight, dirLight}); 71 | lightingEffect.shadowColor = [0, 0, 0, 0.5]; 72 | 73 | const props = { 74 | layers: [ 75 | // only needed when using shadows - a plane for shadows to drop on 76 | new PolygonLayer({ 77 | id: 'ground', 78 | data: landCover, 79 | stroked: false, 80 | getPolygon: (f) => f, 81 | getFillColor: [0, 0, 0, 0] 82 | }), 83 | new GeoJsonLayer({ 84 | id: 'geojson', 85 | data: DATA_URL, 86 | opacity: 0.8, 87 | stroked: false, 88 | filled: true, 89 | extruded: true, 90 | wireframe: true, 91 | getElevation: (f) => Math.sqrt(f.properties.valuePerSqm) * 10, 92 | getFillColor: (f) => COLOR_SCALE(f.properties.growth), 93 | getLineColor: [255, 255, 255], 94 | pickable: true, 95 | }) 96 | ], 97 | effects: [lightingEffect] 98 | } 99 | const deckLayer = new DeckGLLayer('deck', props, { 100 | animation: true, 101 | forceRenderOnMoving: true, 102 | forceRenderOnZooming: true, 103 | renderStart: () => { 104 | this.renderState?.update(); 105 | }, 106 | }); 107 | 108 | map.addLayer(deckLayer); 109 | 110 | ``` 111 | 112 | ## Examples 113 | 114 | [示例](https://sakitam-gis.github.io/maptalks.deckgl/) 115 | 116 | 其他示例请查看 packages/gatsby/pages 目录下源码。 117 | -------------------------------------------------------------------------------- /packages/maptalks-regl/README.md: -------------------------------------------------------------------------------- 1 | # maptalks.deckgl 2 | 3 | The plugin to play deck.gl with maptalks.js 4 | 5 | [![Build Status](https://travis-ci.org/sakitam-gis/maptalks.deckgl.svg?branch=master)](https://www.travis-ci.org/sakitam-gis/maptalks.deckgl) 6 | [![NPM downloads](https://img.shields.io/npm/dm/maptalks.deckgl.svg)](https://npmjs.org/package/maptalks.deckgl) 7 | [![](https://data.jsdelivr.com/v1/package/npm/maptalks.deckgl/badge)](https://www.jsdelivr.com/package/npm/maptalks.deckgl) 8 | ![JS gzip size](http://img.badgesize.io/https://unpkg.com/maptalks.deckgl/dist/maptalks-deckgl.js?compression=gzip&label=gzip%20size:%20JS) 9 | [![Npm package](https://img.shields.io/npm/v/maptalks.deckgl.svg)](https://www.npmjs.org/package/maptalks.deckgl) 10 | [![GitHub stars](https://img.shields.io/github/stars/sakitam-gis/maptalks.deckgl.svg)](https://github.com/sakitam-gis/maptalks.deckgl/stargazers) 11 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/sakitam-gis/maptalks.deckgl/master/LICENSE) 12 | 13 | ## Dev 14 | 15 | ```bash 16 | git clone https://github.com/sakitam-gis/maptalks.deckgl.git 17 | npm install / yarn 18 | npm run dev / yarn run dev 19 | npm run build / yarn run build 20 | ``` 21 | 22 | ## install 23 | 24 | > `npm i maptalks.deckgl` 25 | 26 | ## use 使用 27 | 28 | ```js 29 | import DeckGLLayer from 'maptalks.deckgl'; 30 | import {GeoJsonLayer, PolygonLayer} from '@deck.gl/layers'; 31 | import {LightingEffect, AmbientLight, _SunLight as SunLight} from '@deck.gl/core'; 32 | import {scaleThreshold} from 'd3-scale'; 33 | import * as maptalks from 'maptalks'; 34 | 35 | const map = new maptalks.Map(this.container, { 36 | center: [-74.01194070150844, 40.70708981756565], 37 | zoom: 5, 38 | pitch: 0, 39 | bearing: 0, 40 | centerCross: true, 41 | baseLayer: new maptalks.TileLayer('tile', { 42 | 'urlTemplate': 'https://api.mapbox.com/styles/v1/mapbox/dark-v10/tiles/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejh2N21nMzAxMmQzMnA5emRyN2lucW0ifQ.jSE-g2vsn48Ry928pqylcg' 43 | // 'subdomains': ['a', 'b', 'c', 'd'] 44 | }), 45 | }); 46 | // Source data GeoJSON 47 | const DATA_URL = 48 | 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/geojson/vancouver-blocks.json'; // eslint-disable-line 49 | 50 | export const COLOR_SCALE = scaleThreshold() 51 | .domain([-0.6, -0.45, -0.3, -0.15, 0, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 1.05, 1.2]) 52 | // @ts-ignore 53 | .range([[65, 182, 196], [127, 205, 187], [199, 233, 180], [237, 248, 177], [255, 255, 204], [255, 237, 160], [254, 217, 118], [254, 178, 76], [253, 141, 60], [252, 78, 42], [227, 26, 28], [189, 0, 38], [128, 0, 38]]); 54 | 55 | const ambientLight = new AmbientLight({ 56 | color: [255, 255, 255], 57 | intensity: 1.0 58 | }); 59 | 60 | const dirLight = new SunLight({ 61 | timestamp: Date.UTC(2019, 7, 1, 22), 62 | color: [255, 255, 255], 63 | intensity: 1.0, 64 | _shadow: true 65 | }); 66 | 67 | const landCover = [[[-123.0, 49.196], [-123.0, 49.324], [-123.306, 49.324], [-123.306, 49.196]]]; 68 | 69 | 70 | const lightingEffect = new LightingEffect({ambientLight, dirLight}); 71 | lightingEffect.shadowColor = [0, 0, 0, 0.5]; 72 | 73 | const props = { 74 | layers: [ 75 | // only needed when using shadows - a plane for shadows to drop on 76 | new PolygonLayer({ 77 | id: 'ground', 78 | data: landCover, 79 | stroked: false, 80 | getPolygon: (f) => f, 81 | getFillColor: [0, 0, 0, 0] 82 | }), 83 | new GeoJsonLayer({ 84 | id: 'geojson', 85 | data: DATA_URL, 86 | opacity: 0.8, 87 | stroked: false, 88 | filled: true, 89 | extruded: true, 90 | wireframe: true, 91 | getElevation: (f) => Math.sqrt(f.properties.valuePerSqm) * 10, 92 | getFillColor: (f) => COLOR_SCALE(f.properties.growth), 93 | getLineColor: [255, 255, 255], 94 | pickable: true, 95 | }) 96 | ], 97 | effects: [lightingEffect] 98 | } 99 | const deckLayer = new DeckGLLayer('deck', props, { 100 | animation: true, 101 | forceRenderOnMoving: true, 102 | forceRenderOnZooming: true, 103 | renderStart: () => { 104 | this.renderState?.update(); 105 | }, 106 | }); 107 | 108 | map.addLayer(deckLayer); 109 | 110 | ``` 111 | 112 | ## Examples 113 | 114 | [示例](https://sakitam-gis.github.io/maptalks.deckgl/) 115 | 116 | 其他示例请查看 packages/gatsby/pages 目录下源码。 117 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/README.md: -------------------------------------------------------------------------------- 1 | # maptalks.deckgl 2 | 3 | The plugin to play deck.gl with maptalks.js 4 | 5 | [![Build Status](https://travis-ci.org/sakitam-gis/maptalks.deckgl.svg?branch=master)](https://www.travis-ci.org/sakitam-gis/maptalks.deckgl) 6 | [![NPM downloads](https://img.shields.io/npm/dm/maptalks.deckgl.svg)](https://npmjs.org/package/maptalks.deckgl) 7 | [![](https://data.jsdelivr.com/v1/package/npm/maptalks.deckgl/badge)](https://www.jsdelivr.com/package/npm/maptalks.deckgl) 8 | ![JS gzip size](http://img.badgesize.io/https://unpkg.com/maptalks.deckgl/dist/maptalks-deckgl.js?compression=gzip&label=gzip%20size:%20JS) 9 | [![Npm package](https://img.shields.io/npm/v/maptalks.deckgl.svg)](https://www.npmjs.org/package/maptalks.deckgl) 10 | [![GitHub stars](https://img.shields.io/github/stars/sakitam-gis/maptalks.deckgl.svg)](https://github.com/sakitam-gis/maptalks.deckgl/stargazers) 11 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/sakitam-gis/maptalks.deckgl/master/LICENSE) 12 | 13 | ## Dev 14 | 15 | ```bash 16 | git clone https://github.com/sakitam-gis/maptalks.deckgl.git 17 | npm install / yarn 18 | npm run dev / yarn run dev 19 | npm run build / yarn run build 20 | ``` 21 | 22 | ## install 23 | 24 | > `npm i maptalks.deckgl` 25 | 26 | ## use 使用 27 | 28 | ```js 29 | import DeckGLLayer from 'maptalks.deckgl'; 30 | import {GeoJsonLayer, PolygonLayer} from '@deck.gl/layers'; 31 | import {LightingEffect, AmbientLight, _SunLight as SunLight} from '@deck.gl/core'; 32 | import {scaleThreshold} from 'd3-scale'; 33 | import * as maptalks from 'maptalks'; 34 | 35 | const map = new maptalks.Map(this.container, { 36 | center: [-74.01194070150844, 40.70708981756565], 37 | zoom: 5, 38 | pitch: 0, 39 | bearing: 0, 40 | centerCross: true, 41 | baseLayer: new maptalks.TileLayer('tile', { 42 | 'urlTemplate': 'https://api.mapbox.com/styles/v1/mapbox/dark-v10/tiles/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejh2N21nMzAxMmQzMnA5emRyN2lucW0ifQ.jSE-g2vsn48Ry928pqylcg' 43 | // 'subdomains': ['a', 'b', 'c', 'd'] 44 | }), 45 | }); 46 | // Source data GeoJSON 47 | const DATA_URL = 48 | 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/geojson/vancouver-blocks.json'; // eslint-disable-line 49 | 50 | export const COLOR_SCALE = scaleThreshold() 51 | .domain([-0.6, -0.45, -0.3, -0.15, 0, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 1.05, 1.2]) 52 | // @ts-ignore 53 | .range([[65, 182, 196], [127, 205, 187], [199, 233, 180], [237, 248, 177], [255, 255, 204], [255, 237, 160], [254, 217, 118], [254, 178, 76], [253, 141, 60], [252, 78, 42], [227, 26, 28], [189, 0, 38], [128, 0, 38]]); 54 | 55 | const ambientLight = new AmbientLight({ 56 | color: [255, 255, 255], 57 | intensity: 1.0 58 | }); 59 | 60 | const dirLight = new SunLight({ 61 | timestamp: Date.UTC(2019, 7, 1, 22), 62 | color: [255, 255, 255], 63 | intensity: 1.0, 64 | _shadow: true 65 | }); 66 | 67 | const landCover = [[[-123.0, 49.196], [-123.0, 49.324], [-123.306, 49.324], [-123.306, 49.196]]]; 68 | 69 | 70 | const lightingEffect = new LightingEffect({ambientLight, dirLight}); 71 | lightingEffect.shadowColor = [0, 0, 0, 0.5]; 72 | 73 | const props = { 74 | layers: [ 75 | // only needed when using shadows - a plane for shadows to drop on 76 | new PolygonLayer({ 77 | id: 'ground', 78 | data: landCover, 79 | stroked: false, 80 | getPolygon: (f) => f, 81 | getFillColor: [0, 0, 0, 0] 82 | }), 83 | new GeoJsonLayer({ 84 | id: 'geojson', 85 | data: DATA_URL, 86 | opacity: 0.8, 87 | stroked: false, 88 | filled: true, 89 | extruded: true, 90 | wireframe: true, 91 | getElevation: (f) => Math.sqrt(f.properties.valuePerSqm) * 10, 92 | getFillColor: (f) => COLOR_SCALE(f.properties.growth), 93 | getLineColor: [255, 255, 255], 94 | pickable: true, 95 | }) 96 | ], 97 | effects: [lightingEffect] 98 | } 99 | const deckLayer = new DeckGLLayer('deck', props, { 100 | animation: true, 101 | forceRenderOnMoving: true, 102 | forceRenderOnZooming: true, 103 | renderStart: () => { 104 | this.renderState?.update(); 105 | }, 106 | }); 107 | 108 | map.addLayer(deckLayer); 109 | 110 | ``` 111 | 112 | ## Examples 113 | 114 | [示例](https://sakitam-gis.github.io/maptalks.deckgl/) 115 | 116 | 其他示例请查看 packages/gatsby/pages 目录下源码。 117 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | import { renderer, TileLayer } from 'maptalks'; 3 | export declare namespace DrawCommon { 4 | interface Props { 5 | a_pos: REGL.Vec3[]; 6 | a_texCoord: REGL.Vec2[]; 7 | elements: REGL.Elements; 8 | u_matrix: REGL.Mat4; 9 | u_tile: REGL.Texture2D; 10 | u_tile_size: number; 11 | u_opacity: number; 12 | u_extrude_scale: number; 13 | zoom: number; 14 | canvasSize: [number, number]; 15 | } 16 | interface Uniforms { 17 | u_matrix: REGL.Mat4; 18 | u_tile: REGL.Texture2D; 19 | u_tile_size: number; 20 | u_opacity: number; 21 | u_extrude_scale: number; 22 | } 23 | interface Attributes { 24 | a_pos: REGL.Vec3[]; 25 | a_texCoord: REGL.Vec2[]; 26 | } 27 | } 28 | interface Point { 29 | x: number; 30 | y: number; 31 | } 32 | declare type handleFunc = (...args: any[]) => void; 33 | interface MTK { 34 | projViewMatrix: REGL.Mat4; 35 | getResolution: () => number; 36 | getMaxNativeZoom: () => number; 37 | getCenter: () => Point; 38 | getPitch: () => number; 39 | getBearing: () => number; 40 | on: (type: string, func: handleFunc, ctx: any) => void; 41 | off: (type: string, func: handleFunc, ctx: any) => void; 42 | getDevicePixelRatio: () => number; 43 | getSize: () => { 44 | width: number; 45 | height: number; 46 | }; 47 | getGLScale(z: number): number; 48 | } 49 | interface ICanvasSize { 50 | width: number; 51 | height: number; 52 | } 53 | export interface IOptions { 54 | [key: string]: any; 55 | elevationDecoder: { 56 | rScaler: number; 57 | gScaler: number; 58 | bScaler: number; 59 | offset: number; 60 | }; 61 | meshMaxError: number; 62 | workerUrl: null | string; 63 | urlTemplate: string; 64 | subdomains: (string | number)[]; 65 | terrainTiles: string | string[]; 66 | doubleBuffer?: boolean; 67 | animation?: boolean; 68 | fps?: number; 69 | attribution?: string; 70 | minZoom?: number; 71 | maxZoom?: number; 72 | visible?: boolean; 73 | opacity?: number; 74 | zIndex?: number; 75 | hitDetect?: boolean; 76 | renderer?: 'canvas' | 'gl'; 77 | globalCompositeOperation?: string | null; 78 | cssFilter?: string | null; 79 | forceRenderOnMoving?: boolean; 80 | forceRenderOnZooming?: boolean; 81 | forceRenderOnRotating?: boolean; 82 | registerEvents?: boolean; 83 | renderStart?: () => void; 84 | renderEnd?: () => void; 85 | customCreateGLContext?: (canvas: HTMLCanvasElement, attrs: any) => WebGLRenderingContext | WebGL2RenderingContext; 86 | } 87 | declare class TerrainLayer extends TileLayer { 88 | id: string | number; 89 | options: Partial; 90 | constructor(id: string | number, options?: Partial); 91 | rerender(): void; 92 | getMap(): MTK; 93 | getTileSize(): any; 94 | } 95 | interface IRenderer { 96 | getMap: () => MTK | null; 97 | } 98 | export declare class Renderer extends renderer.TileLayerCanvasRenderer implements IRenderer { 99 | private canvas; 100 | private canvas2; 101 | private gl; 102 | private layer; 103 | private regl; 104 | private command; 105 | private _tileZoom; 106 | private _childTiles; 107 | private _parentTiles; 108 | private tilesLoading; 109 | private tilesInView; 110 | private isDrawable; 111 | private _drawTiles; 112 | private loadTile; 113 | onTileLoad(tileImage: any, tileInfo: any): any; 114 | private loadTerrain; 115 | drawTile(tileInfo: any, tileImage: HTMLImageElement): void; 116 | private getCanvasImage; 117 | onCanvasCreate(): void; 118 | createContext(): void; 119 | /** 120 | * when map changed, call canvas change 121 | * @param canvasSize 122 | */ 123 | resizeCanvas(canvasSize: ICanvasSize): void; 124 | /** 125 | * clear canvas 126 | */ 127 | clearCanvas(): void; 128 | clear(): void; 129 | getMap(): MTK; 130 | onRemove(): void; 131 | completeRender(): any; 132 | setCanvasUpdated(): any; 133 | setToRedraw(): any; 134 | private prepareCanvas; 135 | private getTileOpacity; 136 | } 137 | export default TerrainLayer; 138 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * author: sakitam-fdd 3 | * mapbox-regl v1.0.0 4 | * build-time: 2021-1-13 17:42 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("regl")):"function"==typeof define&&define.amd?define(["regl"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).TerrainLayer=t(e.createREGL)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=t(e),r=function(){return(r=Object.assign||function(e){for(var t,i=1,r=arguments.length;i 3 | * mapbox-regl v1.0.0 4 | * build-time: 2021-1-13 17:42 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | import { __assign } from 'tslib'; 9 | import REGL from 'regl'; 10 | 11 | var vs = "#define GLSLIFY 1\nattribute vec2 a_pos;uniform mat4 u_matrix;uniform sampler2D u_image;uniform float u_extrude_scale;varying vec2 v_texCoord;varying float v_height;float extent=4096.0*2.0;void main(){v_texCoord=a_pos;vec3 rgb=texture2D(u_image,v_texCoord).rgb;float height=-10000.0+((rgb.r*255.0*256.0*256.0+rgb.g*255.0*256.0+rgb.b*255.0)*0.1);v_height=height;gl_Position=u_matrix*vec4(a_pos.xy*extent,height*u_extrude_scale,1.0);}"; // eslint-disable-line 12 | 13 | var fs = "precision mediump float;\n#define GLSLIFY 1\nvarying vec2 v_texCoord;varying float v_height;uniform sampler2D u_tile;uniform float u_opacity;void main(){vec4 color=texture2D(u_tile,v_texCoord);gl_FragColor=vec4(floor(255.0*color*u_opacity)/255.0);}"; // eslint-disable-line 14 | 15 | var TerrainLayer = 16 | /** @class */ 17 | function () { 18 | function TerrainLayer(id, tileJson, options) { 19 | if (options === void 0) { 20 | options = {}; 21 | } 22 | 23 | this.map = null; 24 | this.gl = null; 25 | this.id = id; 26 | this.tileSource = null; 27 | this.terrainTileSource = null; 28 | this.terrainSource = this.id + 'terrainSource'; 29 | this.source = this.id + 'Source'; 30 | this.type = 'custom'; 31 | this.renderingMode = '3d'; 32 | this.tileJson = tileJson; 33 | this.options = options; 34 | this.move = this.move.bind(this); 35 | this.onData = this.onData.bind(this); 36 | this.onTerrainData = this.onTerrainData.bind(this); 37 | } 38 | 39 | TerrainLayer.prototype.createTerrain = function () { 40 | this.map.addSource(this.terrainSource, __assign(__assign({}, this.tileJson), { 41 | tiles: this.tileJson.terrainTiles 42 | })); 43 | this.terrainTileSource = this.map.getSource(this.terrainSource); 44 | 45 | if (this.terrainTileSource) { 46 | this.terrainTileSource.on('data', this.onTerrainData); 47 | this.terrainSourceCache = this.map.style.sourceCaches[this.terrainSource]; 48 | } 49 | 50 | this.map.style._layers[this.id].source = this.terrainSource; 51 | }; 52 | 53 | TerrainLayer.prototype.createTile = function () { 54 | if (!this.map) return; 55 | this.map.addSource(this.source, __assign(__assign({}, this.tileJson), { 56 | tiles: this.tileJson.realTiles 57 | })); 58 | this.tileSource = this.map.getSource(this.source); 59 | 60 | if (this.tileSource) { 61 | this.tileSource.on('data', this.onData); 62 | this.sourceCache = this.map.style.sourceCaches[this.source]; 63 | } 64 | 65 | var layer = { 66 | id: this.id + 'inner', 67 | type: 'custom', 68 | renderingMode: '3d', 69 | onAdd: function onAdd() {}, 70 | render: function render() {}, 71 | onRemove: function onRemove() {} 72 | }; 73 | this.map.addLayer(layer); 74 | this.map.style._layers[this.id + 'inner'].source = this.source; 75 | }; 76 | 77 | TerrainLayer.prototype.onAdd = function (map, gl) { 78 | this.map = map; 79 | this.gl = gl; 80 | map.on('move', this.move); 81 | this.createTerrain(); 82 | this.createTile(); 83 | this.regl = REGL({ 84 | gl: gl, 85 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 86 | attributes: { 87 | antialias: true, 88 | preserveDrawingBuffer: false 89 | } 90 | }); 91 | this.command = this.regl({ 92 | frag: fs, 93 | vert: vs, 94 | attributes: { 95 | a_pos: function a_pos(_, _a) { 96 | var a_pos = _a.a_pos; 97 | return a_pos; 98 | } 99 | }, 100 | uniforms: { 101 | u_matrix: function u_matrix(_, _a) { 102 | var u_matrix = _a.u_matrix; 103 | return u_matrix; 104 | }, 105 | u_image: function u_image(_, _a) { 106 | var u_image = _a.u_image; 107 | return u_image; 108 | }, 109 | u_tile: function u_tile(_, _a) { 110 | var u_tile = _a.u_tile; 111 | return u_tile; 112 | }, 113 | u_opacity: function u_opacity(_, _a) { 114 | var u_opacity = _a.u_opacity; 115 | return u_opacity; 116 | }, 117 | u_extrude_scale: function u_extrude_scale(_, _a) { 118 | var u_extrude_scale = _a.u_extrude_scale; 119 | return u_extrude_scale; 120 | } 121 | }, 122 | depth: { 123 | enable: true, 124 | mask: true, 125 | func: 'less', 126 | range: [0, 1] 127 | }, 128 | blend: { 129 | enable: false, 130 | func: { 131 | src: 'src alpha', 132 | dst: 'one minus src alpha' 133 | }, 134 | color: [0, 0, 0, 0] 135 | }, 136 | elements: function elements(_, _a) { 137 | var elements = _a.elements; 138 | return elements; 139 | } 140 | }); 141 | }; 142 | 143 | TerrainLayer.prototype.move = function () { 144 | this.updateTiles('terrainSourceCache'); 145 | this.updateTiles('sourceCache'); 146 | }; 147 | 148 | TerrainLayer.prototype.onData = function (e) { 149 | if (e.sourceDataType === 'content') { 150 | this.updateTiles('sourceCache'); 151 | } 152 | }; 153 | 154 | TerrainLayer.prototype.onTerrainData = function (e) { 155 | if (e.sourceDataType === 'content') { 156 | this.updateTiles('terrainSourceCache'); 157 | } 158 | }; 159 | 160 | TerrainLayer.prototype.updateTiles = function (key) { 161 | // @ts-ignore 162 | this[key].update(this.map.painter.transform); 163 | }; 164 | 165 | TerrainLayer.prototype.getPlaneBuffer = function (tile, width, height, widthSegments, heightSegments) { 166 | if (tile._planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 167 | return tile._planeBuffer; 168 | } 169 | 170 | tile.widthSegments = widthSegments; 171 | tile.heightSegments = heightSegments; 172 | var width_half = width / 2; 173 | var height_half = height / 2; 174 | var gridX = Math.floor(widthSegments); 175 | var gridY = Math.floor(heightSegments); 176 | var gridX1 = gridX + 1; 177 | var gridY1 = gridY + 1; 178 | var segment_width = width / gridX; 179 | var segment_height = height / gridY; 180 | var indices = []; 181 | var vertices = []; 182 | var uvs = []; 183 | 184 | for (var iy = 0; iy < gridY1; iy++) { 185 | var y = iy * segment_height; 186 | 187 | for (var ix = 0; ix < gridX1; ix++) { 188 | var x = ix * segment_width; 189 | vertices.push(x / width_half / 2, y / height_half / 2); // vertices.push(ix / gridX, 1 - (iy / gridY)); 190 | 191 | uvs.push(ix / gridX, 1 - iy / gridY); 192 | } 193 | } 194 | 195 | for (var iy = 0; iy < gridY; iy++) { 196 | for (var ix = 0; ix < gridX; ix++) { 197 | var a = ix + gridX1 * iy; 198 | var b = ix + gridX1 * (iy + 1); 199 | var c = ix + 1 + gridX1 * (iy + 1); 200 | var d = ix + 1 + gridX1 * iy; 201 | indices.push(a, b, d); 202 | indices.push(b, c, d); 203 | } 204 | } 205 | 206 | tile._planeBuffer = { 207 | vertices: vertices, 208 | indices: indices, 209 | uvs: uvs, 210 | elements: this.regl.elements({ 211 | data: indices, 212 | primitive: 'triangles', 213 | // primitive: 'line strip', 214 | type: 'uint32', 215 | count: indices.length 216 | }), 217 | position: { 218 | buffer: this.regl.buffer({ 219 | data: vertices, 220 | type: 'float' 221 | }), 222 | size: 2 223 | } 224 | }; 225 | return tile._planeBuffer; 226 | }; 227 | 228 | TerrainLayer.prototype.render = function () { 229 | var _this = this; 230 | 231 | var tiles = this.terrainSourceCache.getVisibleCoordinates().map(function (tileid) { 232 | return _this.terrainSourceCache.getTile(tileid); 233 | }); 234 | 235 | if (this.command) { 236 | tiles.forEach(function (tile) { 237 | if (!tile.texture) return; 238 | 239 | if (!tile._terrainTexture) { 240 | tile._terrainTexture = _this.regl.texture({ 241 | data: tile.texture.image, 242 | wrapS: 'clamp', 243 | wrapT: 'clamp', 244 | min: 'linear', 245 | mag: 'linear', 246 | mipmap: true 247 | }); 248 | } 249 | 250 | if (!tile._reglTexture) { 251 | // const { x, y, z } = tile.tileID.canonical; 252 | var realTile = _this.sourceCache.getTile(tile.tileID); 253 | 254 | if (realTile && realTile.texture) { 255 | tile._reglTexture = _this.regl.texture({ 256 | data: realTile.texture.image, 257 | wrapS: 'clamp', 258 | wrapT: 'clamp', 259 | min: 'linear', 260 | mag: 'linear', 261 | mipmap: true 262 | }); 263 | } // const image = new Image(); 264 | // image.onload = () => { 265 | // tile._reglTexture = this.regl.texture({ 266 | // data: image, 267 | // wrapS: 'clamp', 268 | // wrapT: 'clamp', 269 | // min: 'linear', 270 | // mag: 'linear', 271 | // mipmap: true, 272 | // }); 273 | // }; 274 | // image.crossOrigin = '*'; 275 | // // image.src = `https://mt0.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x=${x}&y=${y}&z=${z}&s=G`; 276 | // image.src = `https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.webp?sku=101XzrMiclXn4&access_token=${mapboxgl.accessToken}`; 277 | 278 | } 279 | 280 | if (tile._reglTexture) { 281 | var data = _this.getPlaneBuffer(tile, 256 + 0, 256 + 0, _this.options.widthSegments !== undefined ? _this.options.widthSegments : 256, _this.options.heightSegments !== undefined ? _this.options.heightSegments : 256); // [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1] 282 | 283 | 284 | _this.command({ 285 | u_matrix: tile.tileID.posMatrix, 286 | u_image: tile._terrainTexture, 287 | u_tile: tile._reglTexture, 288 | elements: data.elements, 289 | a_pos: data.position, 290 | u_opacity: _this.options.opacity !== undefined ? _this.options.opacity : 1, 291 | u_extrude_scale: _this.options.extrudeScale !== undefined ? _this.options.extrudeScale : 1 292 | }); 293 | } 294 | }); 295 | } 296 | }; 297 | 298 | TerrainLayer.prototype.setOptions = function (options) { 299 | this.options = __assign(__assign({}, this.options), options); 300 | 301 | if (this.map) { 302 | this.map.triggerRepaint(); 303 | } 304 | }; 305 | 306 | TerrainLayer.prototype.onRemove = function () { 307 | this.regl.destroy(); 308 | this.map.off('move', this.move); 309 | }; 310 | 311 | return TerrainLayer; 312 | }(); 313 | 314 | export default TerrainLayer; 315 | //# sourceMappingURL=terrain-layer.esm.js.map 316 | -------------------------------------------------------------------------------- /packages/mapbox-regl/src/index.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | import vs from './shaders/draw.vert.glsl'; 3 | import fs from './shaders/draw.frag.glsl'; 4 | 5 | export type ID = string | number; 6 | 7 | export interface TileJSON { 8 | type: 'raster'; 9 | tileSize: number; 10 | terrainTiles: string[]; 11 | realTiles: string[]; 12 | attribution: string; 13 | } 14 | 15 | export interface IOptions { 16 | opacity?: number; 17 | extrudeScale?: number; 18 | widthSegments?: number; 19 | heightSegments?: number; 20 | } 21 | 22 | export interface ISource { 23 | on: (type: string, cb: (e: any) => void) => any; 24 | } 25 | 26 | type IMap = any; 27 | type ITile = any; 28 | type Pair = [T, T]; 29 | 30 | export namespace DrawCommon { 31 | export interface Props { 32 | a_pos: REGL.Vec2[]; 33 | elements: REGL.Elements; 34 | u_matrix: REGL.Mat4; 35 | u_image: REGL.Texture2D; 36 | u_tile: REGL.Texture2D; 37 | u_opacity: number; 38 | u_extrude_scale: number; 39 | } 40 | export interface Uniforms { 41 | u_matrix: REGL.Mat4; 42 | u_image: REGL.Texture2D; 43 | u_tile: REGL.Texture2D; 44 | u_opacity: number; 45 | u_extrude_scale: number; 46 | } 47 | export interface Attributes { 48 | a_pos: REGL.Vec2[]; 49 | } 50 | } 51 | 52 | export default class TerrainLayer { 53 | public id: ID; 54 | public map: IMap; 55 | 56 | private gl: WebGLRenderingContext | WebGL2RenderingContext | null; 57 | private tileJson: TileJSON; 58 | private type: 'custom'; 59 | private readonly source: string; 60 | private readonly terrainSource: string; 61 | private tileSource: ISource | null; 62 | private terrainTileSource: ISource | null; 63 | private terrainSourceCache: any; 64 | private sourceCache: any; 65 | private regl: REGL.Regl; 66 | private command: REGL.DrawCommand; 67 | private options: IOptions; 68 | private renderingMode: string; 69 | 70 | constructor(id: ID, tileJson: TileJSON, options: IOptions = {}) { 71 | this.map = null; 72 | this.gl = null; 73 | this.id = id; 74 | this.tileSource = null; 75 | this.terrainTileSource = null; 76 | this.terrainSource = this.id + 'terrainSource' 77 | this.source = this.id + 'Source' 78 | this.type = 'custom'; 79 | this.renderingMode = '3d'; 80 | this.tileJson = tileJson; 81 | 82 | this.options = options; 83 | 84 | this.move = this.move.bind(this); 85 | this.onData = this.onData.bind(this); 86 | this.onTerrainData = this.onTerrainData.bind(this); 87 | } 88 | 89 | createTerrain() { 90 | this.map.addSource(this.terrainSource, { 91 | ...this.tileJson, 92 | tiles: this.tileJson.terrainTiles 93 | }); 94 | this.terrainTileSource = this.map.getSource(this.terrainSource); 95 | if (this.terrainTileSource) { 96 | this.terrainTileSource.on('data', this.onTerrainData); 97 | this.terrainSourceCache = this.map.style.sourceCaches[this.terrainSource]; 98 | } 99 | 100 | this.map.style._layers[this.id].source = this.terrainSource; 101 | } 102 | 103 | createTile() { 104 | if (!this.map) return; 105 | this.map.addSource(this.source, { 106 | ...this.tileJson, 107 | tiles: this.tileJson.realTiles 108 | }); 109 | this.tileSource = this.map.getSource(this.source); 110 | if (this.tileSource) { 111 | this.tileSource.on('data', this.onData); 112 | this.sourceCache = this.map.style.sourceCaches[this.source]; 113 | } 114 | 115 | const layer = { 116 | id: this.id + 'inner', 117 | type: 'custom', 118 | renderingMode: '3d', 119 | onAdd: () => {}, 120 | render: () => {}, 121 | onRemove: () => {} 122 | } 123 | 124 | this.map.addLayer(layer); 125 | 126 | this.map.style._layers[this.id + 'inner'].source = this.source; 127 | } 128 | 129 | onAdd(map: IMap, gl: WebGLRenderingContext | WebGL2RenderingContext) { 130 | this.map = map; 131 | this.gl = gl; 132 | map.on('move', this.move); 133 | 134 | this.createTerrain(); 135 | 136 | this.createTile(); 137 | 138 | this.regl = REGL({ 139 | gl: gl, 140 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 141 | attributes: { 142 | antialias: true, 143 | preserveDrawingBuffer: false, 144 | } 145 | }); 146 | 147 | this.command = this.regl({ 148 | frag: fs, 149 | 150 | vert: vs, 151 | 152 | attributes: { 153 | a_pos: (_, { a_pos }) => a_pos, 154 | // a_texCoord: this.regl.prop('texCoord'), 155 | }, 156 | 157 | uniforms: { 158 | u_matrix: (_, { u_matrix }) => u_matrix, 159 | u_image: (_, { u_image }) => u_image, 160 | u_tile: (_, { u_tile }) => u_tile, 161 | u_opacity: (_, { u_opacity }) => u_opacity, 162 | u_extrude_scale: (_, { u_extrude_scale }) => u_extrude_scale, 163 | }, 164 | 165 | depth: { 166 | enable: true, 167 | mask: true, 168 | func: 'less', 169 | range: [0, 1] 170 | }, 171 | 172 | blend: { 173 | enable: false, 174 | func: { 175 | src: 'src alpha', 176 | dst: 'one minus src alpha', 177 | }, 178 | color: [0, 0, 0, 0] 179 | }, 180 | 181 | elements: (_, { elements }) => elements, 182 | }); 183 | } 184 | 185 | move() { 186 | this.updateTiles('terrainSourceCache'); 187 | this.updateTiles('sourceCache'); 188 | } 189 | 190 | onData(e: any) { 191 | if (e.sourceDataType === 'content') { 192 | this.updateTiles('sourceCache'); 193 | } 194 | } 195 | 196 | onTerrainData(e: any) { 197 | if (e.sourceDataType === 'content') { 198 | this.updateTiles('terrainSourceCache'); 199 | } 200 | } 201 | 202 | updateTiles(key: string) { 203 | // @ts-ignore 204 | this[key].update(this.map.painter.transform); 205 | } 206 | 207 | getPlaneBuffer(tile: ITile, width: number, height: number, widthSegments: number, heightSegments: number) { 208 | if (tile._planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 209 | return tile._planeBuffer; 210 | } 211 | 212 | tile.widthSegments = widthSegments; 213 | tile.heightSegments = heightSegments; 214 | 215 | const width_half = width / 2; 216 | const height_half = height / 2; 217 | 218 | const gridX = Math.floor(widthSegments); 219 | const gridY = Math.floor(heightSegments); 220 | 221 | const gridX1 = gridX + 1; 222 | const gridY1 = gridY + 1; 223 | 224 | const segment_width = width / gridX; 225 | const segment_height = height / gridY; 226 | 227 | const indices = []; 228 | const vertices = []; 229 | const uvs = []; 230 | 231 | for (let iy = 0; iy < gridY1; iy++) { 232 | const y = iy * segment_height; 233 | for (let ix = 0; ix < gridX1; ix++) { 234 | const x = ix * segment_width; 235 | vertices.push(x / width_half / 2, y / height_half / 2); 236 | // vertices.push(ix / gridX, 1 - (iy / gridY)); 237 | uvs.push(ix / gridX, 1 - (iy / gridY)); 238 | } 239 | } 240 | 241 | for (let iy = 0; iy < gridY; iy++) { 242 | for (let ix = 0; ix < gridX; ix++) { 243 | const a = ix + gridX1 * iy; 244 | const b = ix + gridX1 * (iy + 1); 245 | const c = (ix + 1) + gridX1 * (iy + 1); 246 | const d = (ix + 1) + gridX1 * iy; 247 | 248 | indices.push(a, b, d); 249 | indices.push(b, c, d); 250 | } 251 | } 252 | 253 | tile._planeBuffer = { 254 | vertices, 255 | indices, 256 | uvs, 257 | elements: this.regl.elements({ 258 | data: indices, 259 | primitive: 'triangles', 260 | // primitive: 'line strip', 261 | type: 'uint32', 262 | count: indices.length, 263 | }), 264 | position: { 265 | buffer: this.regl.buffer({ 266 | data: vertices, 267 | type: 'float', 268 | }), 269 | size: 2, 270 | }, 271 | }; 272 | 273 | return tile._planeBuffer; 274 | } 275 | 276 | render() { 277 | const tiles = this.terrainSourceCache.getVisibleCoordinates().map((tileid: any) => this.terrainSourceCache.getTile(tileid)); 278 | if (this.command) { 279 | tiles.forEach((tile: ITile) => { 280 | if (!tile.texture) return; 281 | 282 | if (!tile._terrainTexture) { 283 | tile._terrainTexture = this.regl.texture({ 284 | data: tile.texture.image, 285 | wrapS: 'clamp', 286 | wrapT: 'clamp', 287 | min: 'linear', 288 | mag: 'linear', 289 | mipmap: true, 290 | }); 291 | } 292 | 293 | if (!tile._reglTexture) { 294 | // const { x, y, z } = tile.tileID.canonical; 295 | const realTile = this.sourceCache.getTile(tile.tileID); 296 | if (realTile && realTile.texture) { 297 | tile._reglTexture = this.regl.texture({ 298 | data: realTile.texture.image, 299 | wrapS: 'clamp', 300 | wrapT: 'clamp', 301 | min: 'linear', 302 | mag: 'linear', 303 | mipmap: true, 304 | }); 305 | } 306 | // const image = new Image(); 307 | // image.onload = () => { 308 | // tile._reglTexture = this.regl.texture({ 309 | // data: image, 310 | // wrapS: 'clamp', 311 | // wrapT: 'clamp', 312 | // min: 'linear', 313 | // mag: 'linear', 314 | // mipmap: true, 315 | // }); 316 | // }; 317 | // image.crossOrigin = '*'; 318 | // // image.src = `https://mt0.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x=${x}&y=${y}&z=${z}&s=G`; 319 | // image.src = `https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.webp?sku=101XzrMiclXn4&access_token=${mapboxgl.accessToken}`; 320 | } 321 | 322 | if (tile._reglTexture) { 323 | const data = this.getPlaneBuffer( 324 | tile, 325 | 256 + 0, 326 | 256 + 0, 327 | this.options.widthSegments !== undefined ? this.options.widthSegments : 256, 328 | this.options.heightSegments !== undefined ? this.options.heightSegments : 256, 329 | ); 330 | // [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1] 331 | 332 | this.command({ 333 | u_matrix: tile.tileID.posMatrix, 334 | u_image: tile._terrainTexture, 335 | u_tile: tile._reglTexture, 336 | elements: data.elements, 337 | a_pos: data.position, 338 | u_opacity: this.options.opacity !== undefined ? this.options.opacity : 1, 339 | u_extrude_scale: this.options.extrudeScale !== undefined ? this.options.extrudeScale : 1, 340 | }); 341 | } 342 | }); 343 | } 344 | } 345 | 346 | setOptions(options: IOptions) { 347 | this.options = { 348 | ...this.options, 349 | ...options, 350 | }; 351 | if (this.map) { 352 | this.map.triggerRepaint(); 353 | } 354 | } 355 | 356 | onRemove() { 357 | this.regl.destroy(); 358 | 359 | this.map.off('move', this.move); 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.cjs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * author: sakitam-fdd 3 | * mapbox-regl v1.0.0 4 | * build-time: 2021-1-13 17:42 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | 'use strict'; 9 | 10 | var tslib = require('tslib'); 11 | var REGL = require('regl'); 12 | 13 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } 14 | 15 | var REGL__default = /*#__PURE__*/_interopDefaultLegacy(REGL); 16 | 17 | var vs = "#define GLSLIFY 1\nattribute vec2 a_pos;uniform mat4 u_matrix;uniform sampler2D u_image;uniform float u_extrude_scale;varying vec2 v_texCoord;varying float v_height;float extent=4096.0*2.0;void main(){v_texCoord=a_pos;vec3 rgb=texture2D(u_image,v_texCoord).rgb;float height=-10000.0+((rgb.r*255.0*256.0*256.0+rgb.g*255.0*256.0+rgb.b*255.0)*0.1);v_height=height;gl_Position=u_matrix*vec4(a_pos.xy*extent,height*u_extrude_scale,1.0);}"; // eslint-disable-line 18 | 19 | var fs = "precision mediump float;\n#define GLSLIFY 1\nvarying vec2 v_texCoord;varying float v_height;uniform sampler2D u_tile;uniform float u_opacity;void main(){vec4 color=texture2D(u_tile,v_texCoord);gl_FragColor=vec4(floor(255.0*color*u_opacity)/255.0);}"; // eslint-disable-line 20 | 21 | var TerrainLayer = 22 | /** @class */ 23 | function () { 24 | function TerrainLayer(id, tileJson, options) { 25 | if (options === void 0) { 26 | options = {}; 27 | } 28 | 29 | this.map = null; 30 | this.gl = null; 31 | this.id = id; 32 | this.tileSource = null; 33 | this.terrainTileSource = null; 34 | this.terrainSource = this.id + 'terrainSource'; 35 | this.source = this.id + 'Source'; 36 | this.type = 'custom'; 37 | this.renderingMode = '3d'; 38 | this.tileJson = tileJson; 39 | this.options = options; 40 | this.move = this.move.bind(this); 41 | this.onData = this.onData.bind(this); 42 | this.onTerrainData = this.onTerrainData.bind(this); 43 | } 44 | 45 | TerrainLayer.prototype.createTerrain = function () { 46 | this.map.addSource(this.terrainSource, tslib.__assign(tslib.__assign({}, this.tileJson), { 47 | tiles: this.tileJson.terrainTiles 48 | })); 49 | this.terrainTileSource = this.map.getSource(this.terrainSource); 50 | 51 | if (this.terrainTileSource) { 52 | this.terrainTileSource.on('data', this.onTerrainData); 53 | this.terrainSourceCache = this.map.style.sourceCaches[this.terrainSource]; 54 | } 55 | 56 | this.map.style._layers[this.id].source = this.terrainSource; 57 | }; 58 | 59 | TerrainLayer.prototype.createTile = function () { 60 | if (!this.map) return; 61 | this.map.addSource(this.source, tslib.__assign(tslib.__assign({}, this.tileJson), { 62 | tiles: this.tileJson.realTiles 63 | })); 64 | this.tileSource = this.map.getSource(this.source); 65 | 66 | if (this.tileSource) { 67 | this.tileSource.on('data', this.onData); 68 | this.sourceCache = this.map.style.sourceCaches[this.source]; 69 | } 70 | 71 | var layer = { 72 | id: this.id + 'inner', 73 | type: 'custom', 74 | renderingMode: '3d', 75 | onAdd: function onAdd() {}, 76 | render: function render() {}, 77 | onRemove: function onRemove() {} 78 | }; 79 | this.map.addLayer(layer); 80 | this.map.style._layers[this.id + 'inner'].source = this.source; 81 | }; 82 | 83 | TerrainLayer.prototype.onAdd = function (map, gl) { 84 | this.map = map; 85 | this.gl = gl; 86 | map.on('move', this.move); 87 | this.createTerrain(); 88 | this.createTile(); 89 | this.regl = REGL__default['default']({ 90 | gl: gl, 91 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 92 | attributes: { 93 | antialias: true, 94 | preserveDrawingBuffer: false 95 | } 96 | }); 97 | this.command = this.regl({ 98 | frag: fs, 99 | vert: vs, 100 | attributes: { 101 | a_pos: function a_pos(_, _a) { 102 | var a_pos = _a.a_pos; 103 | return a_pos; 104 | } 105 | }, 106 | uniforms: { 107 | u_matrix: function u_matrix(_, _a) { 108 | var u_matrix = _a.u_matrix; 109 | return u_matrix; 110 | }, 111 | u_image: function u_image(_, _a) { 112 | var u_image = _a.u_image; 113 | return u_image; 114 | }, 115 | u_tile: function u_tile(_, _a) { 116 | var u_tile = _a.u_tile; 117 | return u_tile; 118 | }, 119 | u_opacity: function u_opacity(_, _a) { 120 | var u_opacity = _a.u_opacity; 121 | return u_opacity; 122 | }, 123 | u_extrude_scale: function u_extrude_scale(_, _a) { 124 | var u_extrude_scale = _a.u_extrude_scale; 125 | return u_extrude_scale; 126 | } 127 | }, 128 | depth: { 129 | enable: true, 130 | mask: true, 131 | func: 'less', 132 | range: [0, 1] 133 | }, 134 | blend: { 135 | enable: false, 136 | func: { 137 | src: 'src alpha', 138 | dst: 'one minus src alpha' 139 | }, 140 | color: [0, 0, 0, 0] 141 | }, 142 | elements: function elements(_, _a) { 143 | var elements = _a.elements; 144 | return elements; 145 | } 146 | }); 147 | }; 148 | 149 | TerrainLayer.prototype.move = function () { 150 | this.updateTiles('terrainSourceCache'); 151 | this.updateTiles('sourceCache'); 152 | }; 153 | 154 | TerrainLayer.prototype.onData = function (e) { 155 | if (e.sourceDataType === 'content') { 156 | this.updateTiles('sourceCache'); 157 | } 158 | }; 159 | 160 | TerrainLayer.prototype.onTerrainData = function (e) { 161 | if (e.sourceDataType === 'content') { 162 | this.updateTiles('terrainSourceCache'); 163 | } 164 | }; 165 | 166 | TerrainLayer.prototype.updateTiles = function (key) { 167 | // @ts-ignore 168 | this[key].update(this.map.painter.transform); 169 | }; 170 | 171 | TerrainLayer.prototype.getPlaneBuffer = function (tile, width, height, widthSegments, heightSegments) { 172 | if (tile._planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 173 | return tile._planeBuffer; 174 | } 175 | 176 | tile.widthSegments = widthSegments; 177 | tile.heightSegments = heightSegments; 178 | var width_half = width / 2; 179 | var height_half = height / 2; 180 | var gridX = Math.floor(widthSegments); 181 | var gridY = Math.floor(heightSegments); 182 | var gridX1 = gridX + 1; 183 | var gridY1 = gridY + 1; 184 | var segment_width = width / gridX; 185 | var segment_height = height / gridY; 186 | var indices = []; 187 | var vertices = []; 188 | var uvs = []; 189 | 190 | for (var iy = 0; iy < gridY1; iy++) { 191 | var y = iy * segment_height; 192 | 193 | for (var ix = 0; ix < gridX1; ix++) { 194 | var x = ix * segment_width; 195 | vertices.push(x / width_half / 2, y / height_half / 2); // vertices.push(ix / gridX, 1 - (iy / gridY)); 196 | 197 | uvs.push(ix / gridX, 1 - iy / gridY); 198 | } 199 | } 200 | 201 | for (var iy = 0; iy < gridY; iy++) { 202 | for (var ix = 0; ix < gridX; ix++) { 203 | var a = ix + gridX1 * iy; 204 | var b = ix + gridX1 * (iy + 1); 205 | var c = ix + 1 + gridX1 * (iy + 1); 206 | var d = ix + 1 + gridX1 * iy; 207 | indices.push(a, b, d); 208 | indices.push(b, c, d); 209 | } 210 | } 211 | 212 | tile._planeBuffer = { 213 | vertices: vertices, 214 | indices: indices, 215 | uvs: uvs, 216 | elements: this.regl.elements({ 217 | data: indices, 218 | primitive: 'triangles', 219 | // primitive: 'line strip', 220 | type: 'uint32', 221 | count: indices.length 222 | }), 223 | position: { 224 | buffer: this.regl.buffer({ 225 | data: vertices, 226 | type: 'float' 227 | }), 228 | size: 2 229 | } 230 | }; 231 | return tile._planeBuffer; 232 | }; 233 | 234 | TerrainLayer.prototype.render = function () { 235 | var _this = this; 236 | 237 | var tiles = this.terrainSourceCache.getVisibleCoordinates().map(function (tileid) { 238 | return _this.terrainSourceCache.getTile(tileid); 239 | }); 240 | 241 | if (this.command) { 242 | tiles.forEach(function (tile) { 243 | if (!tile.texture) return; 244 | 245 | if (!tile._terrainTexture) { 246 | tile._terrainTexture = _this.regl.texture({ 247 | data: tile.texture.image, 248 | wrapS: 'clamp', 249 | wrapT: 'clamp', 250 | min: 'linear', 251 | mag: 'linear', 252 | mipmap: true 253 | }); 254 | } 255 | 256 | if (!tile._reglTexture) { 257 | // const { x, y, z } = tile.tileID.canonical; 258 | var realTile = _this.sourceCache.getTile(tile.tileID); 259 | 260 | if (realTile && realTile.texture) { 261 | tile._reglTexture = _this.regl.texture({ 262 | data: realTile.texture.image, 263 | wrapS: 'clamp', 264 | wrapT: 'clamp', 265 | min: 'linear', 266 | mag: 'linear', 267 | mipmap: true 268 | }); 269 | } // const image = new Image(); 270 | // image.onload = () => { 271 | // tile._reglTexture = this.regl.texture({ 272 | // data: image, 273 | // wrapS: 'clamp', 274 | // wrapT: 'clamp', 275 | // min: 'linear', 276 | // mag: 'linear', 277 | // mipmap: true, 278 | // }); 279 | // }; 280 | // image.crossOrigin = '*'; 281 | // // image.src = `https://mt0.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x=${x}&y=${y}&z=${z}&s=G`; 282 | // image.src = `https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.webp?sku=101XzrMiclXn4&access_token=${mapboxgl.accessToken}`; 283 | 284 | } 285 | 286 | if (tile._reglTexture) { 287 | var data = _this.getPlaneBuffer(tile, 256 + 0, 256 + 0, _this.options.widthSegments !== undefined ? _this.options.widthSegments : 256, _this.options.heightSegments !== undefined ? _this.options.heightSegments : 256); // [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1] 288 | 289 | 290 | _this.command({ 291 | u_matrix: tile.tileID.posMatrix, 292 | u_image: tile._terrainTexture, 293 | u_tile: tile._reglTexture, 294 | elements: data.elements, 295 | a_pos: data.position, 296 | u_opacity: _this.options.opacity !== undefined ? _this.options.opacity : 1, 297 | u_extrude_scale: _this.options.extrudeScale !== undefined ? _this.options.extrudeScale : 1 298 | }); 299 | } 300 | }); 301 | } 302 | }; 303 | 304 | TerrainLayer.prototype.setOptions = function (options) { 305 | this.options = tslib.__assign(tslib.__assign({}, this.options), options); 306 | 307 | if (this.map) { 308 | this.map.triggerRepaint(); 309 | } 310 | }; 311 | 312 | TerrainLayer.prototype.onRemove = function () { 313 | this.regl.destroy(); 314 | this.map.off('move', this.move); 315 | }; 316 | 317 | return TerrainLayer; 318 | }(); 319 | 320 | module.exports = TerrainLayer; 321 | //# sourceMappingURL=terrain-layer.cjs.js.map 322 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.min.js","sources":["../../../node_modules/tslib/tslib.es6.js"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from) {\r\n for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)\r\n to[j] = from[i];\r\n return to;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply","this"],"mappings":";;;;;;;qWA+BWA,EAAW,kBAClBA,EAAWC,OAAOC,QAAU,SAAkBC,OACrC,IAAIC,EAAGC,EAAI,EAAGC,EAAIC,UAAUC,OAAQH,EAAIC,EAAGD,QAEvC,IAAII,KADTL,EAAIG,UAAUF,GACOJ,OAAOS,UAAUC,eAAeC,KAAKR,EAAGK,KAAIN,EAAEM,GAAKL,EAAEK,WAEvEN,IAEKU,MAAMC,KAAMP"} -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/terrain-layer.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * author: sakitam-fdd 3 | * maptalks-regl v1.0.0 4 | * build-time: 2021-1-14 15:33 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("regl"),require("maptalks")):"function"==typeof define&&define.amd?define(["exports","regl","maptalks"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TerrainLayer={},e.createREGL,e.maptalks)}(this,(function(e,t,r){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=i(t),a=function(e,t){return(a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var s="undefined"!=typeof Float32Array?Float32Array:Array;function l(){var e=new s(3);return s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e}function u(e,t,r){var i=new s(3);return i[0]=e,i[1]=t,i[2]=r,i}function c(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],l=r[2];return e[0]=n*l-a*s,e[1]=a*o-i*l,e[2]=i*s-n*o,e}Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});var p,h=function(e){var t=e[0],r=e[1],i=e[2];return Math.hypot(t,r,i)};p=l();!function(){var e,t=(e=new s(4),s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0,e[3]=0),e)}();function g(){var e=new s(4);return s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e[3]=1,e}function v(e,t,r,i){var n,a,o,s,l,u=t[0],c=t[1],p=t[2],h=t[3],g=r[0],v=r[1],f=r[2],d=r[3];return(a=u*g+c*v+p*f+h*d)<0&&(a=-a,g=-g,v=-v,f=-f,d=-d),1-a>1e-6?(n=Math.acos(a),o=Math.sin(n),s=Math.sin((1-i)*n)/o,l=Math.sin(i*n)/o):(s=1-i,l=i),e[0]=s*u+l*g,e[1]=s*c+l*v,e[2]=s*p+l*f,e[3]=s*h+l*d,e}var f,d,y,m,_,w,x,T=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r*r+i*i+n*n+a*a;return o>0&&(o=1/Math.sqrt(o)),e[0]=r*o,e[1]=i*o,e[2]=n*o,e[3]=a*o,e};f=l(),d=u(1,0,0),y=u(0,1,0),m=g(),_=g(),w=new s(9),s!=Float32Array&&(w[1]=0,w[2]=0,w[3]=0,w[5]=0,w[6]=0,w[7]=0),w[0]=1,w[4]=1,w[8]=1,x=w;!function(){var e=function(){var e=new s(2);return s!=Float32Array&&(e[0]=0,e[1]=0),e}()}();var C=1;"undefined"!=typeof window&&(C=window.devicePixelRatio||window.screen.deviceXDPI/window.screen.logicalXDPI);var b={registerEvents:!0,renderer:"gl",glOptions:{alpha:!0,depth:!1,antialias:!0,stencil:!0},forceRenderOnMoving:!0,forceRenderOnZooming:!0},S=function(e){function t(t,r){return void 0===r&&(r={}),e.call(this,t,Object.assign({},b,r))||this}return o(t,e),t.prototype.rerender=function(){var e=this.getRenderer();e&&e.setToRedraw()},t.prototype.getMap=function(){return e.prototype.getMap.call(this)},t.prototype.getTileSize=function(){return e.prototype.getTileSize.call(this)},t}(r.TileLayer),z=new Float32Array([0,0,0]),M=new Float32Array(16),L=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return o(t,e),t.prototype.isDrawable=function(){return!0},t.prototype._drawTiles=function(t,r,i,n){e.prototype._drawTiles.call(this,t,r,i,n),this.regl&&this.regl._refresh()},t.prototype.getPlaneBuffer=function(e,t,r,i,n,a,o){if(e.planeBuffer&&e.widthSegments===a&&e.heightSegments===o)return e.planeBuffer;e.widthSegments=a,e.heightSegments=o;for(var s=i/2,l=n/2,u=Math.floor(a),c=Math.floor(o),p=u+1,h=c+1,g=i/u,v=n/c,f=[],d=[],y=[],m=0;m0.0){vec3 rgb=texture2D(u_image,v_texCoord).rgb;float height=-10000.0+((rgb.r*255.0*256.0*256.0+rgb.g*255.0*256.0+rgb.b*255.0)*0.1);v_height=height;gl_Position=u_matrix*vec4(a_pos.xy*u_tile_size,height*u_extrude_scale,1.0);}else{gl_Position=u_matrix*vec4(a_pos.xy*u_tile_size,0.0,1.0);}}",attributes:{a_pos:function(e,t){var r=t.a_pos;return r},a_texCoord:function(e,t){var r=t.a_texCoord;return r}},uniforms:{u_matrix:function(e,t){var r=t.u_matrix;return r},u_image:function(e,t){var r=t.u_image;return r},u_tile:function(e,t){var r=t.u_tile;return r},u_tile_size:function(e,t){var r=t.u_tile_size;return r},u_opacity:function(e,t){var r=t.u_opacity;return r},u_extrude_scale:function(e,t){var r=t.u_extrude_scale;return r},u_hasTerrain:function(e,t){var r=t.u_hasTerrain;return r}},viewport:function(e,t){var r=t.canvasSize;return{width:r[0],height:r[1]}},depth:{enable:!0,mask:!0,func:"less",range:[0,1]},stencil:{enable:!0,func:{cmp:"<=",ref:function(e,t){return t.zoom},mask:255}},blend:{enable:!0,func:{src:"src alpha",dst:"one minus src alpha"},color:[0,0,0,0]},elements:function(e,t){var r=t.elements;return r}}))}},t.prototype.resizeCanvas=function(e){if(this.canvas){var t=this.getMap(),r=(t.getDevicePixelRatio?t.getDevicePixelRatio():C)||1,i=e||t.getSize();this.canvas.width===i.width*r&&this.canvas.height===i.height*r||(this.canvas.height=r*i.height,this.canvas.width=r*i.width),this.canvas2.width===this.canvas.width&&this.canvas2.height===this.canvas.height||(this.canvas2.height=this.canvas.height,this.canvas2.width=this.canvas.width)}},t.prototype.clearCanvas=function(){this.canvas&&this.gl&&(e.prototype.clearCanvas.call(this),this.regl&&this.regl.clear({color:[0,0,0,0],depth:1,stencil:this._tileZoom}))},t.prototype.getMap=function(){return e.prototype.getMap.call(this)},t.prototype.onRemove=function(){e.prototype.onRemove.call(this)},t.prototype.completeRender=function(){return e.prototype.completeRender.call(this)},t.prototype.setCanvasUpdated=function(){return e.prototype.setCanvasUpdated.call(this)},t.prototype.setToRedraw=function(){return e.prototype.setToRedraw.call(this)},t.prototype.prepareCanvas=function(){return e.prototype.prepareCanvas.call(this)},t.prototype.getTileOpacity=function(t){return e.prototype.getTileOpacity.call(this,t)},t}(r.renderer.TileLayerCanvasRenderer);S.registerRenderer("gl",L),e.Renderer=L,e.default=S,Object.defineProperty(e,"__esModule",{value:!0})})),"undefined"!=typeof window&&window.TerrainLayer&&(window.TerrainLayer=window.TerrainLayer.default); 9 | -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"terrain-layer.js","sources":["../../../node_modules/tslib/tslib.es6.js"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from) {\r\n for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)\r\n to[j] = from[i];\r\n return to;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n"],"names":["__assign","Object","assign","t","s","i","n","arguments","length","p","prototype","hasOwnProperty","call","apply"],"mappings":";;;;;;;;;;;;;;;;;IA+BO,IAAIA,OAAQ,GAAG,oBAAW;IAC7BA,EAAAA,OAAQ,GAAGC,MAAM,CAACC,MAAP,IAAiB,SAASF,QAAT,CAAkBG,CAAlB,EAAqB;IAC7C,SAAK,IAAIC,CAAJ,EAAOC,CAAC,GAAG,CAAX,EAAcC,CAAC,GAAGC,SAAS,CAACC,MAAjC,EAAyCH,CAAC,GAAGC,CAA7C,EAAgDD,CAAC,EAAjD,EAAqD;IACjDD,MAAAA,CAAC,GAAGG,SAAS,CAACF,CAAD,CAAb;;IACA,WAAK,IAAII,CAAT,IAAcL,CAAd;IAAiB,YAAIH,MAAM,CAACS,SAAP,CAAiBC,cAAjB,CAAgCC,IAAhC,CAAqCR,CAArC,EAAwCK,CAAxC,CAAJ,EAAgDN,CAAC,CAACM,CAAD,CAAD,GAAOL,CAAC,CAACK,CAAD,CAAR;IAAjE;IACH;;IACD,WAAON,CAAP;IACH,GAND;;IAOA,SAAOH,OAAQ,CAACa,KAAT,CAAe,IAAf,EAAqBN,SAArB,CAAP;IACH,CATM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} -------------------------------------------------------------------------------- /packages/mapbox-regl/dist/terrain-layer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * author: sakitam-fdd 3 | * mapbox-regl v1.0.0 4 | * build-time: 2021-1-13 17:42 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | (function (global, factory) { 9 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('regl')) : 10 | typeof define === 'function' && define.amd ? define(['regl'], factory) : 11 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.TerrainLayer = factory(global.createREGL)); 12 | }(this, (function (REGL) { 'use strict'; 13 | 14 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } 15 | 16 | var REGL__default = /*#__PURE__*/_interopDefaultLegacy(REGL); 17 | 18 | var _assign = function __assign() { 19 | _assign = Object.assign || function __assign(t) { 20 | for (var s, i = 1, n = arguments.length; i < n; i++) { 21 | s = arguments[i]; 22 | 23 | for (var p in s) { 24 | if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 25 | } 26 | } 27 | 28 | return t; 29 | }; 30 | 31 | return _assign.apply(this, arguments); 32 | }; 33 | 34 | var vs = "#define GLSLIFY 1\nattribute vec2 a_pos;uniform mat4 u_matrix;uniform sampler2D u_image;uniform float u_extrude_scale;varying vec2 v_texCoord;varying float v_height;float extent=4096.0*2.0;void main(){v_texCoord=a_pos;vec3 rgb=texture2D(u_image,v_texCoord).rgb;float height=-10000.0+((rgb.r*255.0*256.0*256.0+rgb.g*255.0*256.0+rgb.b*255.0)*0.1);v_height=height;gl_Position=u_matrix*vec4(a_pos.xy*extent,height*u_extrude_scale,1.0);}"; // eslint-disable-line 35 | 36 | var fs = "precision mediump float;\n#define GLSLIFY 1\nvarying vec2 v_texCoord;varying float v_height;uniform sampler2D u_tile;uniform float u_opacity;void main(){vec4 color=texture2D(u_tile,v_texCoord);gl_FragColor=vec4(floor(255.0*color*u_opacity)/255.0);}"; // eslint-disable-line 37 | 38 | var TerrainLayer = 39 | /** @class */ 40 | function () { 41 | function TerrainLayer(id, tileJson, options) { 42 | if (options === void 0) { 43 | options = {}; 44 | } 45 | 46 | this.map = null; 47 | this.gl = null; 48 | this.id = id; 49 | this.tileSource = null; 50 | this.terrainTileSource = null; 51 | this.terrainSource = this.id + 'terrainSource'; 52 | this.source = this.id + 'Source'; 53 | this.type = 'custom'; 54 | this.renderingMode = '3d'; 55 | this.tileJson = tileJson; 56 | this.options = options; 57 | this.move = this.move.bind(this); 58 | this.onData = this.onData.bind(this); 59 | this.onTerrainData = this.onTerrainData.bind(this); 60 | } 61 | 62 | TerrainLayer.prototype.createTerrain = function () { 63 | this.map.addSource(this.terrainSource, _assign(_assign({}, this.tileJson), { 64 | tiles: this.tileJson.terrainTiles 65 | })); 66 | this.terrainTileSource = this.map.getSource(this.terrainSource); 67 | 68 | if (this.terrainTileSource) { 69 | this.terrainTileSource.on('data', this.onTerrainData); 70 | this.terrainSourceCache = this.map.style.sourceCaches[this.terrainSource]; 71 | } 72 | 73 | this.map.style._layers[this.id].source = this.terrainSource; 74 | }; 75 | 76 | TerrainLayer.prototype.createTile = function () { 77 | if (!this.map) return; 78 | this.map.addSource(this.source, _assign(_assign({}, this.tileJson), { 79 | tiles: this.tileJson.realTiles 80 | })); 81 | this.tileSource = this.map.getSource(this.source); 82 | 83 | if (this.tileSource) { 84 | this.tileSource.on('data', this.onData); 85 | this.sourceCache = this.map.style.sourceCaches[this.source]; 86 | } 87 | 88 | var layer = { 89 | id: this.id + 'inner', 90 | type: 'custom', 91 | renderingMode: '3d', 92 | onAdd: function onAdd() {}, 93 | render: function render() {}, 94 | onRemove: function onRemove() {} 95 | }; 96 | this.map.addLayer(layer); 97 | this.map.style._layers[this.id + 'inner'].source = this.source; 98 | }; 99 | 100 | TerrainLayer.prototype.onAdd = function (map, gl) { 101 | this.map = map; 102 | this.gl = gl; 103 | map.on('move', this.move); 104 | this.createTerrain(); 105 | this.createTile(); 106 | this.regl = REGL__default['default']({ 107 | gl: gl, 108 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 109 | attributes: { 110 | antialias: true, 111 | preserveDrawingBuffer: false 112 | } 113 | }); 114 | this.command = this.regl({ 115 | frag: fs, 116 | vert: vs, 117 | attributes: { 118 | a_pos: function a_pos(_, _a) { 119 | var a_pos = _a.a_pos; 120 | return a_pos; 121 | } 122 | }, 123 | uniforms: { 124 | u_matrix: function u_matrix(_, _a) { 125 | var u_matrix = _a.u_matrix; 126 | return u_matrix; 127 | }, 128 | u_image: function u_image(_, _a) { 129 | var u_image = _a.u_image; 130 | return u_image; 131 | }, 132 | u_tile: function u_tile(_, _a) { 133 | var u_tile = _a.u_tile; 134 | return u_tile; 135 | }, 136 | u_opacity: function u_opacity(_, _a) { 137 | var u_opacity = _a.u_opacity; 138 | return u_opacity; 139 | }, 140 | u_extrude_scale: function u_extrude_scale(_, _a) { 141 | var u_extrude_scale = _a.u_extrude_scale; 142 | return u_extrude_scale; 143 | } 144 | }, 145 | depth: { 146 | enable: true, 147 | mask: true, 148 | func: 'less', 149 | range: [0, 1] 150 | }, 151 | blend: { 152 | enable: false, 153 | func: { 154 | src: 'src alpha', 155 | dst: 'one minus src alpha' 156 | }, 157 | color: [0, 0, 0, 0] 158 | }, 159 | elements: function elements(_, _a) { 160 | var elements = _a.elements; 161 | return elements; 162 | } 163 | }); 164 | }; 165 | 166 | TerrainLayer.prototype.move = function () { 167 | this.updateTiles('terrainSourceCache'); 168 | this.updateTiles('sourceCache'); 169 | }; 170 | 171 | TerrainLayer.prototype.onData = function (e) { 172 | if (e.sourceDataType === 'content') { 173 | this.updateTiles('sourceCache'); 174 | } 175 | }; 176 | 177 | TerrainLayer.prototype.onTerrainData = function (e) { 178 | if (e.sourceDataType === 'content') { 179 | this.updateTiles('terrainSourceCache'); 180 | } 181 | }; 182 | 183 | TerrainLayer.prototype.updateTiles = function (key) { 184 | // @ts-ignore 185 | this[key].update(this.map.painter.transform); 186 | }; 187 | 188 | TerrainLayer.prototype.getPlaneBuffer = function (tile, width, height, widthSegments, heightSegments) { 189 | if (tile._planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 190 | return tile._planeBuffer; 191 | } 192 | 193 | tile.widthSegments = widthSegments; 194 | tile.heightSegments = heightSegments; 195 | var width_half = width / 2; 196 | var height_half = height / 2; 197 | var gridX = Math.floor(widthSegments); 198 | var gridY = Math.floor(heightSegments); 199 | var gridX1 = gridX + 1; 200 | var gridY1 = gridY + 1; 201 | var segment_width = width / gridX; 202 | var segment_height = height / gridY; 203 | var indices = []; 204 | var vertices = []; 205 | var uvs = []; 206 | 207 | for (var iy = 0; iy < gridY1; iy++) { 208 | var y = iy * segment_height; 209 | 210 | for (var ix = 0; ix < gridX1; ix++) { 211 | var x = ix * segment_width; 212 | vertices.push(x / width_half / 2, y / height_half / 2); // vertices.push(ix / gridX, 1 - (iy / gridY)); 213 | 214 | uvs.push(ix / gridX, 1 - iy / gridY); 215 | } 216 | } 217 | 218 | for (var iy = 0; iy < gridY; iy++) { 219 | for (var ix = 0; ix < gridX; ix++) { 220 | var a = ix + gridX1 * iy; 221 | var b = ix + gridX1 * (iy + 1); 222 | var c = ix + 1 + gridX1 * (iy + 1); 223 | var d = ix + 1 + gridX1 * iy; 224 | indices.push(a, b, d); 225 | indices.push(b, c, d); 226 | } 227 | } 228 | 229 | tile._planeBuffer = { 230 | vertices: vertices, 231 | indices: indices, 232 | uvs: uvs, 233 | elements: this.regl.elements({ 234 | data: indices, 235 | primitive: 'triangles', 236 | // primitive: 'line strip', 237 | type: 'uint32', 238 | count: indices.length 239 | }), 240 | position: { 241 | buffer: this.regl.buffer({ 242 | data: vertices, 243 | type: 'float' 244 | }), 245 | size: 2 246 | } 247 | }; 248 | return tile._planeBuffer; 249 | }; 250 | 251 | TerrainLayer.prototype.render = function () { 252 | var _this = this; 253 | 254 | var tiles = this.terrainSourceCache.getVisibleCoordinates().map(function (tileid) { 255 | return _this.terrainSourceCache.getTile(tileid); 256 | }); 257 | 258 | if (this.command) { 259 | tiles.forEach(function (tile) { 260 | if (!tile.texture) return; 261 | 262 | if (!tile._terrainTexture) { 263 | tile._terrainTexture = _this.regl.texture({ 264 | data: tile.texture.image, 265 | wrapS: 'clamp', 266 | wrapT: 'clamp', 267 | min: 'linear', 268 | mag: 'linear', 269 | mipmap: true 270 | }); 271 | } 272 | 273 | if (!tile._reglTexture) { 274 | // const { x, y, z } = tile.tileID.canonical; 275 | var realTile = _this.sourceCache.getTile(tile.tileID); 276 | 277 | if (realTile && realTile.texture) { 278 | tile._reglTexture = _this.regl.texture({ 279 | data: realTile.texture.image, 280 | wrapS: 'clamp', 281 | wrapT: 'clamp', 282 | min: 'linear', 283 | mag: 'linear', 284 | mipmap: true 285 | }); 286 | } // const image = new Image(); 287 | // image.onload = () => { 288 | // tile._reglTexture = this.regl.texture({ 289 | // data: image, 290 | // wrapS: 'clamp', 291 | // wrapT: 'clamp', 292 | // min: 'linear', 293 | // mag: 'linear', 294 | // mipmap: true, 295 | // }); 296 | // }; 297 | // image.crossOrigin = '*'; 298 | // // image.src = `https://mt0.google.cn/vt/lyrs=y&hl=zh-CN&gl=CN&src=app&x=${x}&y=${y}&z=${z}&s=G`; 299 | // image.src = `https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.webp?sku=101XzrMiclXn4&access_token=${mapboxgl.accessToken}`; 300 | 301 | } 302 | 303 | if (tile._reglTexture) { 304 | var data = _this.getPlaneBuffer(tile, 256 + 0, 256 + 0, _this.options.widthSegments !== undefined ? _this.options.widthSegments : 256, _this.options.heightSegments !== undefined ? _this.options.heightSegments : 256); // [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1] 305 | 306 | 307 | _this.command({ 308 | u_matrix: tile.tileID.posMatrix, 309 | u_image: tile._terrainTexture, 310 | u_tile: tile._reglTexture, 311 | elements: data.elements, 312 | a_pos: data.position, 313 | u_opacity: _this.options.opacity !== undefined ? _this.options.opacity : 1, 314 | u_extrude_scale: _this.options.extrudeScale !== undefined ? _this.options.extrudeScale : 1 315 | }); 316 | } 317 | }); 318 | } 319 | }; 320 | 321 | TerrainLayer.prototype.setOptions = function (options) { 322 | this.options = _assign(_assign({}, this.options), options); 323 | 324 | if (this.map) { 325 | this.map.triggerRepaint(); 326 | } 327 | }; 328 | 329 | TerrainLayer.prototype.onRemove = function () { 330 | this.regl.destroy(); 331 | this.map.off('move', this.move); 332 | }; 333 | 334 | return TerrainLayer; 335 | }(); 336 | 337 | return TerrainLayer; 338 | 339 | }))); 340 | //# sourceMappingURL=terrain-layer.js.map 341 | -------------------------------------------------------------------------------- /packages/maptalks-regl-with-loaders.gl/src/index.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | // @ts-ignore 3 | import { Canvas, renderer, TileLayer } from 'maptalks'; 4 | 5 | import { mat4 } from 'gl-matrix'; 6 | import { load, registerLoaders } from '@loaders.gl/core/dist/es5'; 7 | // @ts-ignore 8 | import { TerrainLoader } from '@loaders.gl/terrain/dist/es5'; 9 | import { ImageLoader } from '@loaders.gl/images/dist/es5'; 10 | 11 | import vs from './shaders/draw.vert.glsl'; 12 | import fs from './shaders/draw.frag.glsl'; 13 | 14 | import {createContext, getDevicePixelRatio, getUrl} from './utils'; 15 | 16 | registerLoaders([ 17 | // jsonLoader, 18 | [ 19 | // @ts-ignore 20 | ImageLoader, 21 | { 22 | imagebitmap: { 23 | premultiplyAlpha: 'none', 24 | }, 25 | }, 26 | ], 27 | ]); 28 | 29 | const _options = { 30 | registerEvents: true, // register map events default 31 | renderer: 'gl', 32 | glOptions: { 33 | alpha: true, 34 | depth: false, 35 | antialias: true, 36 | stencil: true 37 | }, 38 | forceRenderOnMoving: true, 39 | forceRenderOnZooming: true, 40 | elevationDecoder: { 41 | rScaler: 6553.6, 42 | gScaler: 25.6, 43 | bScaler: 0.1, 44 | offset: -10000 45 | }, 46 | meshMaxError: 4, 47 | workerUrl: null, 48 | }; 49 | 50 | export namespace DrawCommon { 51 | export interface Props { 52 | a_pos: REGL.Vec3[]; 53 | a_texCoord: REGL.Vec2[]; 54 | elements: REGL.Elements; 55 | u_matrix: REGL.Mat4; 56 | u_tile: REGL.Texture2D; 57 | u_tile_size: number; 58 | u_opacity: number; 59 | u_extrude_scale: number; 60 | zoom: number; 61 | canvasSize: [number, number]; 62 | } 63 | export interface Uniforms { 64 | u_matrix: REGL.Mat4; 65 | u_tile: REGL.Texture2D; 66 | u_tile_size: number; 67 | u_opacity: number; 68 | u_extrude_scale: number; 69 | } 70 | export interface Attributes { 71 | a_pos: REGL.Vec3[]; 72 | a_texCoord: REGL.Vec2[]; 73 | } 74 | } 75 | 76 | interface Point { 77 | x: number; 78 | y: number; 79 | } 80 | 81 | type handleFunc = (...args: any[]) => void; 82 | 83 | interface MTK { 84 | projViewMatrix: REGL.Mat4; 85 | getResolution: () => number; 86 | getMaxNativeZoom: () => number; 87 | getCenter: () => Point; 88 | getPitch: () => number; 89 | getBearing: () => number; 90 | on: (type: string, func: handleFunc, ctx: any) => void; 91 | off: (type: string, func: handleFunc, ctx: any) => void; 92 | getDevicePixelRatio: () => number; 93 | getSize: () => { 94 | width: number; 95 | height: number; 96 | } 97 | 98 | getGLScale(z: number): number; 99 | } 100 | 101 | interface ICanvasSize { 102 | width: number; 103 | height: number; 104 | } 105 | 106 | export interface IOptions { 107 | [key: string]: any; 108 | 109 | elevationDecoder: { 110 | rScaler: number; 111 | gScaler: number; 112 | bScaler: number; 113 | offset: number; 114 | }, 115 | meshMaxError: number, 116 | workerUrl: null | string, 117 | 118 | urlTemplate: string; 119 | subdomains: (string|number)[] 120 | terrainTiles: string | string[]; 121 | doubleBuffer?: boolean; 122 | animation?: boolean; 123 | fps?: number; 124 | attribution?: string; 125 | minZoom?: number; 126 | maxZoom?: number; 127 | visible?: boolean; 128 | opacity?: number; 129 | zIndex?: number; 130 | hitDetect?: boolean; 131 | renderer?: 'canvas' | 'gl'; 132 | globalCompositeOperation?: string | null; 133 | cssFilter?: string | null; 134 | forceRenderOnMoving?: boolean; 135 | forceRenderOnZooming?: boolean; 136 | forceRenderOnRotating?: boolean; 137 | 138 | registerEvents?: boolean; 139 | 140 | renderStart?: () => void; 141 | renderEnd?: () => void; 142 | customCreateGLContext?: (canvas: HTMLCanvasElement, attrs: any) => WebGLRenderingContext | WebGL2RenderingContext; 143 | } 144 | 145 | class TerrainLayer extends TileLayer { 146 | public id: string | number; 147 | public options: Partial; 148 | 149 | constructor (id: string | number, options: Partial = {}) { 150 | super(id, Object.assign({}, _options, options)); 151 | } 152 | 153 | public rerender() { 154 | // @ts-ignore 155 | const renderer = this.getRenderer(); 156 | if (renderer) { 157 | renderer.setToRedraw(); 158 | } 159 | } 160 | 161 | public getMap(): MTK { 162 | return super.getMap(); 163 | } 164 | 165 | public getTileSize() { 166 | return super.getTileSize(); 167 | } 168 | } 169 | 170 | interface IRenderer { 171 | getMap: () => MTK | null; 172 | } 173 | 174 | const v2 = [0, 0]; 175 | const v3: Float32Array = new Float32Array([0, 0, 0]); 176 | const arr16 = new Float32Array(16); 177 | 178 | export class Renderer extends renderer.TileLayerCanvasRenderer implements IRenderer { 179 | private canvas: HTMLCanvasElement; 180 | private canvas2: HTMLCanvasElement; 181 | private gl: WebGLRenderingContext | WebGL2RenderingContext; 182 | private layer: TerrainLayer; 183 | private regl: REGL.Regl; 184 | private command: REGL.DrawCommand; 185 | private _tileZoom: number; 186 | private _childTiles: any[]; 187 | private _parentTiles: any[]; 188 | private tilesLoading: {}; 189 | private tilesInView: {}; 190 | 191 | private isDrawable() { 192 | return true; 193 | } 194 | 195 | private _drawTiles(tiles: any[], parentTiles: any[], childTiles: any[], placeholders: any[]) { 196 | super._drawTiles(tiles, parentTiles, childTiles, placeholders); 197 | // do update 198 | this.regl && this.regl._refresh(); 199 | } 200 | 201 | private loadTile(tile: any) { 202 | const { terrainTiles, elevationDecoder, meshMaxError, workerUrl } = this.layer.options; 203 | if (!terrainTiles) { 204 | console.warn('必须指定真实渲染图层: options.terrainTiles'); 205 | return {}; 206 | } else { 207 | const urls = getUrl(terrainTiles, { 208 | x: tile.x, 209 | y: tile.y, 210 | z: tile.z, 211 | }); 212 | 213 | Promise.all([ 214 | this.loadTerrain({ 215 | elevationData: urls, 216 | bounds: [0, 0, 1, 1], 217 | elevationDecoder, 218 | meshMaxError, 219 | workerUrl, 220 | }), 221 | // @ts-ignore 222 | load(tile['url'], [ImageLoader]) 223 | ]).then(([terrain, image]) => { 224 | tile.terrainData = terrain; 225 | this.onTileLoad(image, tile); 226 | }).catch(error => { 227 | console.error(error) 228 | // @ts-ignore 229 | this.onTileError('', tile) 230 | }); 231 | return {}; 232 | } 233 | } 234 | 235 | public onTileLoad(tileImage: any, tileInfo: any) { 236 | return super.onTileLoad(tileImage, tileInfo); 237 | } 238 | 239 | private loadTerrain({ 240 | elevationData, 241 | bounds, 242 | elevationDecoder, 243 | meshMaxError, 244 | workerUrl, 245 | }: any) { 246 | if (!elevationData) { 247 | return null; 248 | } 249 | const options: any = { 250 | terrain: { 251 | bounds, 252 | meshMaxError, 253 | elevationDecoder, 254 | }, 255 | }; 256 | if (workerUrl !== null) { 257 | options.terrain.workerUrl = workerUrl; 258 | } 259 | // @ts-ignore 260 | return load(elevationData, TerrainLoader, options); 261 | } 262 | 263 | public drawTile(tileInfo: any, tileImage: HTMLImageElement) { 264 | const map = this.getMap(); 265 | if (!tileInfo || !map || !tileImage || !this.regl || !this.command) { 266 | return; 267 | } 268 | 269 | const scale = tileInfo._glScale = tileInfo._glScale || map.getGLScale(tileInfo.z); 270 | const w = tileInfo.size[0]; 271 | const h = tileInfo.size[1]; 272 | if (tileInfo.cache !== false) { 273 | // this._bindGLBuffer(tileImage, w, h); 274 | } 275 | 276 | // if (tileInfo.z <= this._tileZoom) { 277 | // console.log('show', tileInfo); 278 | // } else { 279 | // console.log('hide', tileInfo); 280 | // } 281 | 282 | if (!tileInfo.u_tile) { 283 | tileInfo.u_tile = this.regl.texture({ 284 | data: tileImage, 285 | wrapS: 'clamp', 286 | wrapT: 'clamp', 287 | min: 'linear', 288 | mag: 'linear', 289 | mipmap: true, 290 | }); 291 | } 292 | 293 | const point = tileInfo.point; 294 | const x = point.x * scale; 295 | const y = point.y * scale; 296 | v3[0] = x || 0; 297 | v3[1] = y || 0; 298 | const { extrudeScale, opacity } = this.layer.options; 299 | // @ts-ignore 300 | const lyOpacity = this.getTileOpacity(tileImage); 301 | 302 | const matrix = this.getMap().projViewMatrix; 303 | 304 | if (!tileInfo.planeBuffer) { 305 | const { attributes, indices } = tileInfo.terrainData; 306 | tileInfo.planeBuffer = { 307 | elements: this.regl.elements({ 308 | data: indices.value, 309 | primitive: 'triangles', 310 | // primitive: 'line strip', 311 | type: 'uint32', 312 | }), 313 | position: { 314 | buffer: this.regl.buffer({ 315 | data: attributes.POSITION.value, 316 | type: 'float', 317 | }), 318 | size: attributes.POSITION.size, 319 | }, 320 | uvs: { 321 | buffer: this.regl.buffer(attributes.TEXCOORD_0.value), 322 | size: attributes.TEXCOORD_0.size, 323 | } 324 | } 325 | } 326 | 327 | const uMatrix = mat4.identity(arr16); 328 | mat4.translate(uMatrix, uMatrix, v3); 329 | mat4.scale(uMatrix, uMatrix, [scale, scale, 1]); 330 | mat4.multiply(uMatrix, matrix as any, uMatrix); 331 | this.command({ 332 | // @ts-ignore 333 | u_matrix: uMatrix as REGL.Mat4, 334 | u_tile: tileInfo.u_tile, 335 | u_tile_size: w, 336 | zoom: tileInfo.z, 337 | elements: tileInfo.planeBuffer.elements, 338 | a_pos: tileInfo.planeBuffer.position, 339 | a_texCoord: tileInfo.planeBuffer.uvs, 340 | u_opacity: opacity !== undefined ? opacity : 1, 341 | u_extrude_scale: extrudeScale !== undefined ? extrudeScale : 1, 342 | canvasSize: [this.gl.canvas.width, this.gl.canvas.height] 343 | }); 344 | 345 | if (lyOpacity < 1) { 346 | this.setToRedraw(); 347 | } else { 348 | this.setCanvasUpdated(); 349 | } 350 | } 351 | 352 | private getCanvasImage() { 353 | if (!this.regl || !this.canvas2) { 354 | return super.getCanvasImage(); 355 | } 356 | const img = super.getCanvasImage(); 357 | if (img) { 358 | img.image = this.canvas2; 359 | } 360 | return img; 361 | } 362 | 363 | // prepare gl, create program, create buffers and fill unchanged data: image samplers, texture coordinates 364 | public onCanvasCreate() { 365 | // not in a GroupGLLayer 366 | // @ts-ignore 367 | if (!this.canvas?.gl || !this.canvas?.gl.wrap) { 368 | this.canvas2 = Canvas.createCanvas(this.canvas.width, this.canvas.height); 369 | } 370 | } 371 | 372 | public createContext() { 373 | super.createContext(); 374 | // @ts-ignore 375 | if (this.canvas?.gl && this.canvas?.gl.wrap) { 376 | // @ts-ignore 377 | this.gl = this.canvas?.gl.wrap(); 378 | } else { 379 | const layer = this.layer; 380 | const attributes = layer.options?.glOptions || { 381 | alpha: true, 382 | depth: true, 383 | antialias: true, 384 | stencil : true 385 | }; 386 | attributes.preserveDrawingBuffer = true; 387 | // fixed: jsdom env 388 | if (layer.options?.customCreateGLContext) { 389 | this.gl = this.gl || layer.options?.customCreateGLContext(this.canvas2, attributes); 390 | } else { 391 | this.gl = this.gl || createContext(this.canvas2, attributes); 392 | } 393 | 394 | if (!this.regl) { 395 | this.regl = REGL({ 396 | gl: this.gl, 397 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 398 | attributes: { 399 | antialias: true, 400 | preserveDrawingBuffer: false, 401 | } 402 | }); 403 | 404 | const stencil = false; 405 | 406 | this.command = this.regl({ 407 | frag: fs, 408 | 409 | vert: vs, 410 | 411 | attributes: { 412 | a_pos: (_, { a_pos }) => a_pos, 413 | a_texCoord: (_, { a_texCoord }) => a_texCoord, 414 | }, 415 | 416 | uniforms: { 417 | u_matrix: (_, { u_matrix }) => u_matrix, 418 | u_tile: (_, { u_tile }) => u_tile, 419 | u_tile_size: (_, { u_tile_size }) => u_tile_size, 420 | u_opacity: (_, { u_opacity }) => u_opacity, 421 | u_extrude_scale: (_, { u_extrude_scale }) => u_extrude_scale, 422 | }, 423 | 424 | viewport: (_, { canvasSize: [width, height] }) => ({ width, height }), 425 | 426 | depth: { 427 | enable: true, 428 | mask: true, 429 | func: 'less', 430 | range: [0, 1] 431 | }, 432 | 433 | // @link https://github.com/regl-project/regl/blob/master/API.md#stencil 434 | stencil: { 435 | enable: true, 436 | func: { 437 | cmp: stencil ? '=' : '<=', 438 | // @ts-ignore 439 | ref: (_: REGL.DefaultContext, { zoom, stencilRef }) => stencil ? stencilRef : zoom, 440 | mask: 0xff 441 | }, 442 | op: { 443 | fail: 'keep', 444 | zfail: 'keep', 445 | zpass: 'replace' 446 | } 447 | // opFront: { 448 | // fail: 'keep', 449 | // zfail: 'keep', 450 | // zpass: 'replace' 451 | // }, 452 | // opBack: { 453 | // fail: 'keep', 454 | // zfail: 'keep', 455 | // zpass: 'replace' 456 | // } 457 | }, 458 | 459 | blend: { 460 | enable: true, 461 | func: { 462 | src: 'src alpha', 463 | dst: 'one minus src alpha', 464 | }, 465 | color: [0, 0, 0, 0] 466 | }, 467 | 468 | elements: (_, { elements }) => elements, 469 | }); 470 | } 471 | } 472 | } 473 | 474 | /** 475 | * when map changed, call canvas change 476 | * @param canvasSize 477 | */ 478 | public resizeCanvas (canvasSize: ICanvasSize) { 479 | // eslint-disable-next-line no-useless-return 480 | if (!this.canvas) return; 481 | const map = this.getMap(); 482 | const retina = (map.getDevicePixelRatio ? map.getDevicePixelRatio() : getDevicePixelRatio()) || 1; 483 | const size = canvasSize || map.getSize(); 484 | if (this.canvas.width !== size.width * retina || this.canvas.height !== size.height * retina) { 485 | this.canvas.height = retina * size.height; 486 | this.canvas.width = retina * size.width; 487 | } 488 | 489 | if (this.canvas2.width !== this.canvas.width || this.canvas2.height !== this.canvas.height) { 490 | this.canvas2.height = this.canvas.height; 491 | this.canvas2.width = this.canvas.width; 492 | } 493 | } 494 | 495 | /** 496 | * clear canvas 497 | */ 498 | public clearCanvas () { 499 | if (!this.canvas || !this.gl) return; 500 | super.clearCanvas(); 501 | // eslint-disable-next-line no-bitwise 502 | if (this.regl) { 503 | this.regl.clear({ 504 | color: [0, 0, 0, 0], 505 | depth: 1, 506 | stencil: this._tileZoom 507 | }) 508 | } 509 | } 510 | 511 | public clear() { 512 | // @ts-ignore 513 | this._retireTiles(true); 514 | // @ts-ignore 515 | const keys = this.tileCache.keys(); 516 | let i = 0; 517 | let len = keys.length; 518 | for (; i < len; i++) { 519 | // @ts-ignore 520 | const item = this.tileCache.get(keys[i]); 521 | if (item.info) { 522 | if (item.info.u_tile) { 523 | item.info.u_tile.destroy(); 524 | } 525 | 526 | if (item.info.planeBuffer) { 527 | item.info.planeBuffer.elements.destroy(); 528 | item.info.planeBuffer.position.buffer.destroy(); 529 | item.info.planeBuffer.uvs.buffer.destroy(); 530 | } 531 | } 532 | } 533 | // @ts-ignore 534 | this.tileCache.reset(); 535 | this.tilesInView = {}; 536 | this.tilesLoading = {}; 537 | this._parentTiles = []; 538 | this._childTiles = []; 539 | super.clear(); 540 | } 541 | 542 | public getMap(): MTK { 543 | return super.getMap(); 544 | } 545 | 546 | public onRemove() { 547 | super.onRemove(); 548 | // this.removeGLCanvas(); 549 | } 550 | 551 | public completeRender() { 552 | return super.completeRender(); 553 | } 554 | 555 | public setCanvasUpdated() { 556 | return super.setCanvasUpdated(); 557 | } 558 | 559 | public setToRedraw() { 560 | return super.setToRedraw(); 561 | } 562 | 563 | private prepareCanvas() { 564 | return super.prepareCanvas(); 565 | } 566 | 567 | private getTileOpacity(tileImage: any) { 568 | return super.getTileOpacity(tileImage); 569 | } 570 | } 571 | 572 | // @ts-ignore 573 | TerrainLayer.registerRenderer('gl', Renderer); 574 | 575 | export default TerrainLayer; 576 | -------------------------------------------------------------------------------- /packages/maptalks-regl/src/index.ts: -------------------------------------------------------------------------------- 1 | import REGL from 'regl'; 2 | // @ts-ignore 3 | import { TileLayer, renderer, Canvas } from 'maptalks'; 4 | 5 | import { mat4 } from 'gl-matrix'; 6 | 7 | import vs from './shaders/draw.vert.glsl'; 8 | import fs from './shaders/draw.frag.glsl'; 9 | 10 | import { createContext, getDevicePixelRatio, getUrl } from './utils'; 11 | 12 | const _options = { 13 | registerEvents: true, // register map events default 14 | renderer: 'gl', 15 | glOptions: { 16 | alpha: true, 17 | depth: false, 18 | antialias: true, 19 | stencil: true 20 | }, 21 | forceRenderOnMoving: true, 22 | forceRenderOnZooming: true 23 | }; 24 | 25 | export namespace DrawCommon { 26 | export interface Props { 27 | a_pos: REGL.Vec2[]; 28 | a_texCoord: REGL.Vec2[]; 29 | elements: REGL.Elements; 30 | u_matrix: REGL.Mat4; 31 | u_image: REGL.Texture2D; 32 | u_tile: REGL.Texture2D; 33 | u_tile_size: number; 34 | u_hasTerrain: number; 35 | u_opacity: number; 36 | u_extrude_scale: number; 37 | zoom: number; 38 | canvasSize: [number, number]; 39 | } 40 | export interface Uniforms { 41 | u_matrix: REGL.Mat4; 42 | u_image: REGL.Texture2D; 43 | u_tile: REGL.Texture2D; 44 | u_tile_size: number; 45 | u_hasTerrain: number; 46 | u_opacity: number; 47 | u_extrude_scale: number; 48 | } 49 | export interface Attributes { 50 | a_pos: REGL.Vec2[]; 51 | a_texCoord: REGL.Vec2[]; 52 | } 53 | } 54 | 55 | interface Point { 56 | x: number; 57 | y: number; 58 | } 59 | 60 | type handleFunc = (...args: any[]) => void; 61 | 62 | interface MTK { 63 | projViewMatrix: REGL.Mat4; 64 | getResolution: () => number; 65 | getMaxNativeZoom: () => number; 66 | getCenter: () => Point; 67 | getPitch: () => number; 68 | getBearing: () => number; 69 | on: (type: string, func: handleFunc, ctx: any) => void; 70 | off: (type: string, func: handleFunc, ctx: any) => void; 71 | getDevicePixelRatio: () => number; 72 | getSize: () => { 73 | width: number; 74 | height: number; 75 | } 76 | 77 | getGLScale(z: number): number; 78 | } 79 | 80 | interface ICanvasSize { 81 | width: number; 82 | height: number; 83 | } 84 | 85 | export interface IOptions { 86 | [key: string]: any; 87 | urlTemplate: string; 88 | subdomains: (string|number)[] 89 | terrainTiles: string | string[]; 90 | doubleBuffer?: boolean; 91 | animation?: boolean; 92 | fps?: number; 93 | attribution?: string; 94 | minZoom?: number; 95 | maxZoom?: number; 96 | visible?: boolean; 97 | opacity?: number; 98 | zIndex?: number; 99 | hitDetect?: boolean; 100 | renderer?: 'canvas' | 'gl'; 101 | globalCompositeOperation?: string | null; 102 | cssFilter?: string | null; 103 | forceRenderOnMoving?: boolean; 104 | forceRenderOnZooming?: boolean; 105 | forceRenderOnRotating?: boolean; 106 | 107 | registerEvents?: boolean; 108 | 109 | renderStart?: () => void; 110 | renderEnd?: () => void; 111 | customCreateGLContext?: (canvas: HTMLCanvasElement, attrs: any) => WebGLRenderingContext | WebGL2RenderingContext; 112 | } 113 | 114 | class TerrainLayer extends TileLayer { 115 | public id: string | number; 116 | public options: Partial; 117 | 118 | constructor (id: string | number, options: Partial = {}) { 119 | super(id, Object.assign({}, _options, options)); 120 | } 121 | 122 | public rerender() { 123 | // @ts-ignore 124 | const renderer = this.getRenderer(); 125 | if (renderer) { 126 | renderer.setToRedraw(); 127 | } 128 | } 129 | 130 | public getMap(): MTK { 131 | return super.getMap(); 132 | } 133 | 134 | public getTileSize() { 135 | return super.getTileSize(); 136 | } 137 | } 138 | 139 | interface IRenderer { 140 | getMap: () => MTK | null; 141 | } 142 | 143 | const v2 = [0, 0]; 144 | const v3: Float32Array = new Float32Array([0, 0, 0]); 145 | const arr16 = new Float32Array(16); 146 | 147 | export class Renderer extends renderer.TileLayerCanvasRenderer implements IRenderer { 148 | private canvas: HTMLCanvasElement; 149 | private canvas2: HTMLCanvasElement; 150 | private gl: WebGLRenderingContext | WebGL2RenderingContext; 151 | private layer: TerrainLayer; 152 | private regl: REGL.Regl; 153 | private command: REGL.DrawCommand; 154 | private _tileZoom: number; 155 | 156 | private isDrawable() { 157 | return true; 158 | } 159 | 160 | private _drawTiles(tiles: any[], parentTiles: any[], childTiles: any[], placeholders: any[]) { 161 | super._drawTiles(tiles, parentTiles, childTiles, placeholders); 162 | // do update 163 | this.regl && this.regl._refresh(); 164 | } 165 | 166 | private getPlaneBuffer(tile: any, startX: number, startY: number, width: number, height: number, widthSegments: number, heightSegments: number) { 167 | if (tile.planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 168 | return tile.planeBuffer; 169 | } 170 | 171 | tile.widthSegments = widthSegments; 172 | tile.heightSegments = heightSegments; 173 | 174 | const width_half = width / 2; 175 | const height_half = height / 2; 176 | 177 | const gridX = Math.floor(widthSegments); 178 | const gridY = Math.floor(heightSegments); 179 | 180 | const gridX1 = gridX + 1; 181 | const gridY1 = gridY + 1; 182 | 183 | const segment_width = width / gridX; 184 | const segment_height = height / gridY; 185 | 186 | const indices = []; 187 | const vertices = []; 188 | const uvs = []; 189 | 190 | for (let iy = 0; iy < gridY1; iy++) { 191 | const y = iy * segment_height; 192 | for (let ix = 0; ix < gridX1; ix++) { 193 | const x = ix * segment_width; 194 | vertices.push(x / width_half / 2, -(y / height_half / 2)); 195 | uvs.push(x / width_half / 2, y / height_half / 2); 196 | } 197 | } 198 | 199 | for (let iy = 0; iy < gridY; iy++) { 200 | for (let ix = 0; ix < gridX; ix++) { 201 | const a = ix + gridX1 * iy; 202 | const b = ix + gridX1 * (iy + 1); 203 | const c = (ix + 1) + gridX1 * (iy + 1); 204 | const d = (ix + 1) + gridX1 * iy; 205 | 206 | indices.push(a, b, d); 207 | indices.push(b, c, d); 208 | } 209 | } 210 | 211 | tile.planeBuffer = { 212 | uvs, 213 | vertices, 214 | indices, 215 | elements: this.regl.elements({ 216 | data: indices, 217 | primitive: 'triangles', 218 | // primitive: 'line strip', 219 | type: 'uint32', 220 | count: indices.length, 221 | }), 222 | position: { 223 | buffer: this.regl.buffer({ 224 | data: vertices, 225 | type: 'float', 226 | }), 227 | size: 2, 228 | }, 229 | } 230 | 231 | return tile.planeBuffer; 232 | } 233 | 234 | private loadTile(tile: any) { 235 | const tileSize = this.layer.getTileSize(); 236 | const { terrainTiles, crossOrigin } = this.layer.options; 237 | if (!terrainTiles) { 238 | console.warn('必须指定真实渲染图层: options.terrainTiles'); 239 | return; 240 | } else { 241 | const urls = getUrl(terrainTiles, { 242 | x: tile.x, 243 | y: tile.y, 244 | z: tile.z, 245 | }); 246 | const terrainImage = new Image(); 247 | 248 | const displayImage = new Image(); 249 | // perf: 先去加载地图瓦片数据,默认渲染,再去加载地形数据进行贴图 250 | 251 | displayImage.width = tileSize['width']; 252 | displayImage.height = tileSize['height']; 253 | displayImage.onload = () => { 254 | this.onTileLoad(displayImage, tile); 255 | // @ts-ignore 256 | terrainImage.onload = () => { 257 | tile.terrainImage = terrainImage; 258 | this.onTileLoad(displayImage, tile); 259 | }; 260 | // @ts-ignore 261 | terrainImage.onerror = this.onTileError.bind(this, displayImage, tile); // 当地形数据加载失败后重新加载 262 | terrainImage.crossOrigin = crossOrigin !== null ? crossOrigin : '*'; 263 | if (urls) { 264 | terrainImage.src = urls; 265 | } 266 | }; 267 | 268 | // @ts-ignore 269 | displayImage.onerror = this.onTileError.bind(this, displayImage, tile); 270 | 271 | this.loadTileImage(displayImage, tile['url']); 272 | return displayImage; 273 | } 274 | } 275 | 276 | public onTileLoad(tileImage: HTMLImageElement, tileInfo: any) { 277 | return super.onTileLoad(tileImage, tileInfo); 278 | } 279 | 280 | public drawTile(tileInfo: any, tileImage: HTMLImageElement) { 281 | const map = this.getMap(); 282 | if (!tileInfo || !map || !tileImage || !this.regl || !this.command) { 283 | return; 284 | } 285 | 286 | const scale = tileInfo._glScale = tileInfo._glScale || map.getGLScale(tileInfo.z); 287 | const w = tileInfo.size[0]; 288 | const h = tileInfo.size[1]; 289 | if (tileInfo.cache !== false) { 290 | // this._bindGLBuffer(tileImage, w, h); 291 | } 292 | 293 | // if (tileInfo.z <= this._tileZoom) { 294 | // console.log('show', tileInfo); 295 | // } else { 296 | // console.log('hide', tileInfo); 297 | // } 298 | 299 | if (!tileInfo.u_tile) { 300 | tileInfo.u_tile = this.regl.texture({ 301 | data: tileImage, 302 | wrapS: 'clamp', 303 | wrapT: 'clamp', 304 | min: 'linear', 305 | mag: 'linear', 306 | mipmap: true, 307 | }); 308 | } 309 | 310 | if (!tileInfo.hasTerrain && tileInfo.terrainImage) { 311 | if (tileInfo.u_image) { 312 | tileInfo.u_image.destroy(); 313 | } 314 | tileInfo.u_image = this.regl.texture({ 315 | data: tileInfo.terrainImage, 316 | wrapS: 'clamp', 317 | wrapT: 'clamp', 318 | min: 'linear', 319 | mag: 'linear', 320 | mipmap: true, 321 | }); 322 | tileInfo.hasTerrain = true; 323 | } else if (!tileInfo.hasTerrain && !tileInfo.terrainImage) { 324 | // temp terrain 325 | tileInfo.u_image = this.regl.texture({ 326 | width: w, 327 | height: h, 328 | wrapS: 'clamp', 329 | wrapT: 'clamp', 330 | min: 'linear', 331 | mag: 'linear', 332 | }); 333 | tileInfo.hasTerrain = false; 334 | } 335 | 336 | const point = tileInfo.point; 337 | const x = point.x * scale; 338 | const y = point.y * scale; 339 | v3[0] = x || 0; 340 | v3[1] = y || 0; 341 | const { extrudeScale, widthSegments, heightSegments, opacity } = this.layer.options; 342 | // @ts-ignore 343 | const lyOpacity = this.getTileOpacity(tileImage); 344 | 345 | const matrix = this.getMap().projViewMatrix; 346 | 347 | const data = this.getPlaneBuffer( 348 | tileInfo, 349 | 0, 0, w, h, 350 | widthSegments !== undefined ? widthSegments : w / 2, 351 | heightSegments !== undefined ? heightSegments : h / 2, 352 | ); 353 | 354 | const uMatrix = mat4.identity(arr16); 355 | mat4.translate(uMatrix, uMatrix, v3); 356 | mat4.scale(uMatrix, uMatrix, [scale, scale, 1]); 357 | mat4.multiply(uMatrix, matrix as any, uMatrix); 358 | this.command({ 359 | // @ts-ignore 360 | u_matrix: uMatrix as REGL.Mat4, 361 | u_image: tileInfo.u_image, 362 | u_tile: tileInfo.u_tile, 363 | u_tile_size: w, 364 | u_hasTerrain: tileInfo.hasTerrain ? 1.0 : 0.0, 365 | zoom: tileInfo.z, 366 | elements: data.elements, 367 | a_pos: data.position, 368 | a_texCoord: data.uvs, 369 | u_opacity: opacity !== undefined ? opacity : 1, 370 | u_extrude_scale: extrudeScale !== undefined ? extrudeScale : 1, 371 | canvasSize: [this.gl.canvas.width, this.gl.canvas.height] 372 | }); 373 | 374 | if (lyOpacity < 1) { 375 | this.setToRedraw(); 376 | } else { 377 | this.setCanvasUpdated(); 378 | } 379 | } 380 | 381 | private loadTileImage(tileImage: any, url: string) { 382 | //image must set cors in webgl 383 | const crossOrigin = this.layer.options['crossOrigin']; 384 | tileImage.crossOrigin = crossOrigin !== null ? crossOrigin : ''; 385 | tileImage.src = url; 386 | return; 387 | } 388 | 389 | private getCanvasImage() { 390 | if (!this.regl || !this.canvas2) { 391 | return super.getCanvasImage(); 392 | } 393 | const img = super.getCanvasImage(); 394 | if (img) { 395 | img.image = this.canvas2; 396 | } 397 | return img; 398 | } 399 | 400 | // prepare gl, create program, create buffers and fill unchanged data: image samplers, texture coordinates 401 | public onCanvasCreate() { 402 | // not in a GroupGLLayer 403 | // @ts-ignore 404 | if (!this.canvas?.gl || !this.canvas?.gl.wrap) { 405 | this.canvas2 = Canvas.createCanvas(this.canvas.width, this.canvas.height); 406 | } 407 | } 408 | 409 | public createContext() { 410 | super.createContext(); 411 | // @ts-ignore 412 | if (this.canvas?.gl && this.canvas?.gl.wrap) { 413 | // @ts-ignore 414 | this.gl = this.canvas?.gl.wrap(); 415 | } else { 416 | const layer = this.layer; 417 | const attributes = layer.options?.glOptions || { 418 | alpha: true, 419 | depth: true, 420 | antialias: true, 421 | stencil : true 422 | }; 423 | attributes.preserveDrawingBuffer = true; 424 | // fixed: jsdom env 425 | if (layer.options?.customCreateGLContext) { 426 | this.gl = this.gl || layer.options?.customCreateGLContext(this.canvas2, attributes); 427 | } else { 428 | this.gl = this.gl || createContext(this.canvas2, attributes); 429 | } 430 | 431 | if (!this.regl) { 432 | this.regl = REGL({ 433 | gl: this.gl, 434 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 435 | attributes: { 436 | antialias: true, 437 | preserveDrawingBuffer: false, 438 | } 439 | }); 440 | 441 | this.command = this.regl({ 442 | frag: fs, 443 | 444 | vert: vs, 445 | 446 | attributes: { 447 | a_pos: (_, { a_pos }) => a_pos, 448 | a_texCoord: (_, { a_texCoord }) => a_texCoord, 449 | }, 450 | 451 | uniforms: { 452 | u_matrix: (_, { u_matrix }) => u_matrix, 453 | u_image: (_, { u_image }) => u_image, 454 | u_tile: (_, { u_tile }) => u_tile, 455 | u_tile_size: (_, { u_tile_size }) => u_tile_size, 456 | u_opacity: (_, { u_opacity }) => u_opacity, 457 | u_extrude_scale: (_, { u_extrude_scale }) => u_extrude_scale, 458 | u_hasTerrain: (_, { u_hasTerrain }) => u_hasTerrain, 459 | }, 460 | 461 | viewport: (_, { canvasSize: [width, height] }) => ({ width, height }), 462 | 463 | depth: { 464 | enable: true, 465 | mask: true, 466 | func: 'less', 467 | range: [0, 1] 468 | }, 469 | 470 | // @link https://github.com/regl-project/regl/blob/master/API.md#stencil 471 | stencil: { 472 | enable: true, 473 | func: { 474 | cmp: '<=', 475 | // @ts-ignore 476 | ref: (_: REGL.DefaultContext, { zoom }) => zoom, 477 | mask: 0xff 478 | }, 479 | // opFront: { 480 | // fail: 'keep', 481 | // zfail: 'keep', 482 | // zpass: 'replace' 483 | // }, 484 | // opBack: { 485 | // fail: 'keep', 486 | // zfail: 'keep', 487 | // zpass: 'replace' 488 | // } 489 | }, 490 | 491 | blend: { 492 | enable: true, 493 | func: { 494 | src: 'src alpha', 495 | dst: 'one minus src alpha', 496 | }, 497 | color: [0, 0, 0, 0] 498 | }, 499 | 500 | elements: (_, { elements }) => elements, 501 | }); 502 | } 503 | } 504 | } 505 | 506 | /** 507 | * when map changed, call canvas change 508 | * @param canvasSize 509 | */ 510 | public resizeCanvas (canvasSize: ICanvasSize) { 511 | // eslint-disable-next-line no-useless-return 512 | if (!this.canvas) return; 513 | const map = this.getMap(); 514 | const retina = (map.getDevicePixelRatio ? map.getDevicePixelRatio() : getDevicePixelRatio()) || 1; 515 | const size = canvasSize || map.getSize(); 516 | if (this.canvas.width !== size.width * retina || this.canvas.height !== size.height * retina) { 517 | this.canvas.height = retina * size.height; 518 | this.canvas.width = retina * size.width; 519 | } 520 | 521 | if (this.canvas2.width !== this.canvas.width || this.canvas2.height !== this.canvas.height) { 522 | this.canvas2.height = this.canvas.height; 523 | this.canvas2.width = this.canvas.width; 524 | } 525 | } 526 | 527 | /** 528 | * clear canvas 529 | */ 530 | public clearCanvas () { 531 | if (!this.canvas || !this.gl) return; 532 | super.clearCanvas(); 533 | // eslint-disable-next-line no-bitwise 534 | if (this.regl) { 535 | this.regl.clear({ 536 | color: [0, 0, 0, 0], 537 | depth: 1, 538 | stencil: this._tileZoom 539 | }) 540 | } 541 | } 542 | 543 | public getMap(): MTK { 544 | return super.getMap(); 545 | } 546 | 547 | public onRemove() { 548 | super.onRemove(); 549 | // this.removeGLCanvas(); 550 | } 551 | 552 | public completeRender() { 553 | return super.completeRender(); 554 | } 555 | 556 | public setCanvasUpdated() { 557 | return super.setCanvasUpdated(); 558 | } 559 | 560 | public setToRedraw() { 561 | return super.setToRedraw(); 562 | } 563 | 564 | private prepareCanvas() { 565 | return super.prepareCanvas(); 566 | } 567 | 568 | private getTileOpacity(tileImage: any) { 569 | return super.getTileOpacity(tileImage); 570 | } 571 | } 572 | 573 | // @ts-ignore 574 | TerrainLayer.registerRenderer('gl', Renderer); 575 | 576 | export default TerrainLayer; 577 | -------------------------------------------------------------------------------- /packages/maptalks-regl/dist/terrain-layer.esm.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * author: sakitam-fdd 3 | * maptalks-regl v1.0.0 4 | * build-time: 2021-1-14 15:33 5 | * LICENSE: MIT 6 | * (c) 2020-2021 https://github.com/sakitam-gis/simple-terrain-viz 7 | */ 8 | import { __extends } from 'tslib'; 9 | import REGL from 'regl'; 10 | import { TileLayer, Canvas, renderer } from 'maptalks'; 11 | import { mat4 } from 'gl-matrix'; 12 | 13 | var vs = "#define GLSLIFY 1\nattribute vec2 a_pos;attribute vec2 a_texCoord;uniform mat4 u_matrix;uniform float u_tile_size;uniform sampler2D u_image;uniform float u_extrude_scale;uniform float u_hasTerrain;varying vec2 v_texCoord;varying float v_height;void main(){v_texCoord=a_texCoord;if(u_hasTerrain>0.0){vec3 rgb=texture2D(u_image,v_texCoord).rgb;float height=-10000.0+((rgb.r*255.0*256.0*256.0+rgb.g*255.0*256.0+rgb.b*255.0)*0.1);v_height=height;gl_Position=u_matrix*vec4(a_pos.xy*u_tile_size,height*u_extrude_scale,1.0);}else{gl_Position=u_matrix*vec4(a_pos.xy*u_tile_size,0.0,1.0);}}"; // eslint-disable-line 14 | 15 | var fs = "precision mediump float;\n#define GLSLIFY 1\nvarying vec2 v_texCoord;varying float v_height;uniform sampler2D u_tile;uniform float u_opacity;void main(){vec4 color=texture2D(u_tile,v_texCoord);gl_FragColor=vec4(floor(255.0*color*u_opacity)/255.0);}"; // eslint-disable-line 16 | 17 | /** 18 | * create gl context 19 | * @param canvas 20 | * @param glOptions 21 | * @returns {null|*} 22 | */ 23 | var createContext = function createContext(canvas, glOptions) { 24 | if (glOptions === void 0) { 25 | glOptions = {}; 26 | } 27 | 28 | if (!canvas) return null; 29 | 30 | function onContextCreationError(error) { 31 | console.log(error.statusMessage); 32 | } 33 | 34 | if (canvas && canvas.addEventListener) { 35 | canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false); 36 | } 37 | 38 | var gl = canvas.getContext('webgl', glOptions); 39 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 40 | 41 | if (!gl) { 42 | gl = canvas.getContext('webgl', glOptions); 43 | gl = gl || canvas.getContext('experimental-webgl', glOptions); 44 | } 45 | 46 | if (canvas.removeEventListener) { 47 | canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false); 48 | } 49 | 50 | return gl; 51 | }; 52 | 53 | var devicePixelRatio = 1; // fixed: ssr render @link https://github.com/gatsbyjs/gatsby/issues/25507 54 | 55 | if (typeof window !== 'undefined') { 56 | // @ts-ignore 57 | devicePixelRatio = window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI; 58 | } 59 | 60 | function getDevicePixelRatio() { 61 | return devicePixelRatio; 62 | } 63 | 64 | function getUrl(template, properties) { 65 | if (!template || !template.length) { 66 | return null; 67 | } 68 | 69 | if (Array.isArray(template)) { 70 | var index = Math.abs(properties.x + properties.y) % template.length; 71 | template = template[index]; 72 | } 73 | 74 | var x = properties.x, 75 | y = properties.y, 76 | z = properties.z; 77 | return template.replace('{x}', String(x)).replace('{y}', String(y)).replace('{z}', String(z)).replace('{-y}', String(Math.pow(2, z) - y - 1)); 78 | } 79 | 80 | var _options = { 81 | registerEvents: true, 82 | renderer: 'gl', 83 | glOptions: { 84 | alpha: true, 85 | depth: false, 86 | antialias: true, 87 | stencil: true 88 | }, 89 | forceRenderOnMoving: true, 90 | forceRenderOnZooming: true 91 | }; 92 | 93 | var TerrainLayer = 94 | /** @class */ 95 | function (_super) { 96 | __extends(TerrainLayer, _super); 97 | 98 | function TerrainLayer(id, options) { 99 | if (options === void 0) { 100 | options = {}; 101 | } 102 | 103 | return _super.call(this, id, Object.assign({}, _options, options)) || this; 104 | } 105 | 106 | TerrainLayer.prototype.rerender = function () { 107 | // @ts-ignore 108 | var renderer = this.getRenderer(); 109 | 110 | if (renderer) { 111 | renderer.setToRedraw(); 112 | } 113 | }; 114 | 115 | TerrainLayer.prototype.getMap = function () { 116 | return _super.prototype.getMap.call(this); 117 | }; 118 | 119 | TerrainLayer.prototype.getTileSize = function () { 120 | return _super.prototype.getTileSize.call(this); 121 | }; 122 | 123 | return TerrainLayer; 124 | }(TileLayer); 125 | var v3 = new Float32Array([0, 0, 0]); 126 | var arr16 = new Float32Array(16); 127 | 128 | var Renderer = 129 | /** @class */ 130 | function (_super) { 131 | __extends(Renderer, _super); 132 | 133 | function Renderer() { 134 | return _super !== null && _super.apply(this, arguments) || this; 135 | } 136 | 137 | Renderer.prototype.isDrawable = function () { 138 | return true; 139 | }; 140 | 141 | Renderer.prototype._drawTiles = function (tiles, parentTiles, childTiles, placeholders) { 142 | _super.prototype._drawTiles.call(this, tiles, parentTiles, childTiles, placeholders); // do update 143 | 144 | 145 | this.regl && this.regl._refresh(); 146 | }; 147 | 148 | Renderer.prototype.getPlaneBuffer = function (tile, startX, startY, width, height, widthSegments, heightSegments) { 149 | if (tile.planeBuffer && tile.widthSegments === widthSegments && tile.heightSegments === heightSegments) { 150 | return tile.planeBuffer; 151 | } 152 | 153 | tile.widthSegments = widthSegments; 154 | tile.heightSegments = heightSegments; 155 | var width_half = width / 2; 156 | var height_half = height / 2; 157 | var gridX = Math.floor(widthSegments); 158 | var gridY = Math.floor(heightSegments); 159 | var gridX1 = gridX + 1; 160 | var gridY1 = gridY + 1; 161 | var segment_width = width / gridX; 162 | var segment_height = height / gridY; 163 | var indices = []; 164 | var vertices = []; 165 | var uvs = []; 166 | 167 | for (var iy = 0; iy < gridY1; iy++) { 168 | var y = iy * segment_height; 169 | 170 | for (var ix = 0; ix < gridX1; ix++) { 171 | var x = ix * segment_width; 172 | vertices.push(x / width_half / 2, -(y / height_half / 2)); 173 | uvs.push(x / width_half / 2, y / height_half / 2); 174 | } 175 | } 176 | 177 | for (var iy = 0; iy < gridY; iy++) { 178 | for (var ix = 0; ix < gridX; ix++) { 179 | var a = ix + gridX1 * iy; 180 | var b = ix + gridX1 * (iy + 1); 181 | var c = ix + 1 + gridX1 * (iy + 1); 182 | var d = ix + 1 + gridX1 * iy; 183 | indices.push(a, b, d); 184 | indices.push(b, c, d); 185 | } 186 | } 187 | 188 | tile.planeBuffer = { 189 | uvs: uvs, 190 | vertices: vertices, 191 | indices: indices, 192 | elements: this.regl.elements({ 193 | data: indices, 194 | primitive: 'triangles', 195 | // primitive: 'line strip', 196 | type: 'uint32', 197 | count: indices.length 198 | }), 199 | position: { 200 | buffer: this.regl.buffer({ 201 | data: vertices, 202 | type: 'float' 203 | }), 204 | size: 2 205 | } 206 | }; 207 | return tile.planeBuffer; 208 | }; 209 | 210 | Renderer.prototype.loadTile = function (tile) { 211 | var _this = this; 212 | 213 | var tileSize = this.layer.getTileSize(); 214 | var _a = this.layer.options, 215 | terrainTiles = _a.terrainTiles, 216 | crossOrigin = _a.crossOrigin; 217 | 218 | if (!terrainTiles) { 219 | console.warn('必须指定真实渲染图层: options.terrainTiles'); 220 | return; 221 | } else { 222 | var urls_1 = getUrl(terrainTiles, { 223 | x: tile.x, 224 | y: tile.y, 225 | z: tile.z 226 | }); 227 | var terrainImage_1 = new Image(); 228 | var displayImage_1 = new Image(); // perf: 先去加载地图瓦片数据,默认渲染,再去加载地形数据进行贴图 229 | 230 | displayImage_1.width = tileSize['width']; 231 | displayImage_1.height = tileSize['height']; 232 | 233 | displayImage_1.onload = function () { 234 | _this.onTileLoad(displayImage_1, tile); // @ts-ignore 235 | 236 | 237 | terrainImage_1.onload = function () { 238 | tile.terrainImage = terrainImage_1; 239 | 240 | _this.onTileLoad(displayImage_1, tile); 241 | }; // @ts-ignore 242 | 243 | 244 | terrainImage_1.onerror = _this.onTileError.bind(_this, displayImage_1, tile); // 当地形数据加载失败后重新加载 245 | 246 | terrainImage_1.crossOrigin = crossOrigin !== null ? crossOrigin : '*'; 247 | 248 | if (urls_1) { 249 | terrainImage_1.src = urls_1; 250 | } 251 | }; // @ts-ignore 252 | 253 | 254 | displayImage_1.onerror = this.onTileError.bind(this, displayImage_1, tile); 255 | this.loadTileImage(displayImage_1, tile['url']); 256 | return displayImage_1; 257 | } 258 | }; 259 | 260 | Renderer.prototype.onTileLoad = function (tileImage, tileInfo) { 261 | return _super.prototype.onTileLoad.call(this, tileImage, tileInfo); 262 | }; 263 | 264 | Renderer.prototype.drawTile = function (tileInfo, tileImage) { 265 | var map = this.getMap(); 266 | 267 | if (!tileInfo || !map || !tileImage || !this.regl || !this.command) { 268 | return; 269 | } 270 | 271 | var scale = tileInfo._glScale = tileInfo._glScale || map.getGLScale(tileInfo.z); 272 | var w = tileInfo.size[0]; 273 | var h = tileInfo.size[1]; 274 | 275 | if (tileInfo.cache !== false) ; // if (tileInfo.z <= this._tileZoom) { 276 | // console.log('show', tileInfo); 277 | // } else { 278 | // console.log('hide', tileInfo); 279 | // } 280 | 281 | 282 | if (!tileInfo.u_tile) { 283 | tileInfo.u_tile = this.regl.texture({ 284 | data: tileImage, 285 | wrapS: 'clamp', 286 | wrapT: 'clamp', 287 | min: 'linear', 288 | mag: 'linear', 289 | mipmap: true 290 | }); 291 | } 292 | 293 | if (!tileInfo.hasTerrain && tileInfo.terrainImage) { 294 | if (tileInfo.u_image) { 295 | tileInfo.u_image.destroy(); 296 | } 297 | 298 | tileInfo.u_image = this.regl.texture({ 299 | data: tileInfo.terrainImage, 300 | wrapS: 'clamp', 301 | wrapT: 'clamp', 302 | min: 'linear', 303 | mag: 'linear', 304 | mipmap: true 305 | }); 306 | tileInfo.hasTerrain = true; 307 | } else if (!tileInfo.hasTerrain && !tileInfo.terrainImage) { 308 | // temp terrain 309 | tileInfo.u_image = this.regl.texture({ 310 | width: w, 311 | height: h, 312 | wrapS: 'clamp', 313 | wrapT: 'clamp', 314 | min: 'linear', 315 | mag: 'linear' 316 | }); 317 | tileInfo.hasTerrain = false; 318 | } 319 | 320 | var point = tileInfo.point; 321 | var x = point.x * scale; 322 | var y = point.y * scale; 323 | v3[0] = x || 0; 324 | v3[1] = y || 0; 325 | var _a = this.layer.options, 326 | extrudeScale = _a.extrudeScale, 327 | widthSegments = _a.widthSegments, 328 | heightSegments = _a.heightSegments, 329 | opacity = _a.opacity; // @ts-ignore 330 | 331 | var lyOpacity = this.getTileOpacity(tileImage); 332 | var matrix = this.getMap().projViewMatrix; 333 | var data = this.getPlaneBuffer(tileInfo, 0, 0, w, h, widthSegments !== undefined ? widthSegments : w / 2, heightSegments !== undefined ? heightSegments : h / 2); 334 | var uMatrix = mat4.identity(arr16); 335 | mat4.translate(uMatrix, uMatrix, v3); 336 | mat4.scale(uMatrix, uMatrix, [scale, scale, 1]); 337 | mat4.multiply(uMatrix, matrix, uMatrix); 338 | this.command({ 339 | // @ts-ignore 340 | u_matrix: uMatrix, 341 | u_image: tileInfo.u_image, 342 | u_tile: tileInfo.u_tile, 343 | u_tile_size: w, 344 | u_hasTerrain: tileInfo.hasTerrain ? 1.0 : 0.0, 345 | zoom: tileInfo.z, 346 | elements: data.elements, 347 | a_pos: data.position, 348 | a_texCoord: data.uvs, 349 | u_opacity: opacity !== undefined ? opacity : 1, 350 | u_extrude_scale: extrudeScale !== undefined ? extrudeScale : 1, 351 | canvasSize: [this.gl.canvas.width, this.gl.canvas.height] 352 | }); 353 | 354 | if (lyOpacity < 1) { 355 | this.setToRedraw(); 356 | } else { 357 | this.setCanvasUpdated(); 358 | } 359 | }; 360 | 361 | Renderer.prototype.loadTileImage = function (tileImage, url) { 362 | //image must set cors in webgl 363 | var crossOrigin = this.layer.options['crossOrigin']; 364 | tileImage.crossOrigin = crossOrigin !== null ? crossOrigin : ''; 365 | tileImage.src = url; 366 | return; 367 | }; 368 | 369 | Renderer.prototype.getCanvasImage = function () { 370 | if (!this.regl || !this.canvas2) { 371 | return _super.prototype.getCanvasImage.call(this); 372 | } 373 | 374 | var img = _super.prototype.getCanvasImage.call(this); 375 | 376 | if (img) { 377 | img.image = this.canvas2; 378 | } 379 | 380 | return img; 381 | }; // prepare gl, create program, create buffers and fill unchanged data: image samplers, texture coordinates 382 | 383 | 384 | Renderer.prototype.onCanvasCreate = function () { 385 | var _a, _b; // not in a GroupGLLayer 386 | // @ts-ignore 387 | 388 | 389 | if (!((_a = this.canvas) === null || _a === void 0 ? void 0 : _a.gl) || !((_b = this.canvas) === null || _b === void 0 ? void 0 : _b.gl.wrap)) { 390 | this.canvas2 = Canvas.createCanvas(this.canvas.width, this.canvas.height); 391 | } 392 | }; 393 | 394 | Renderer.prototype.createContext = function () { 395 | var _a, _b, _c, _d, _e, _f; 396 | 397 | _super.prototype.createContext.call(this); // @ts-ignore 398 | 399 | 400 | if (((_a = this.canvas) === null || _a === void 0 ? void 0 : _a.gl) && ((_b = this.canvas) === null || _b === void 0 ? void 0 : _b.gl.wrap)) { 401 | // @ts-ignore 402 | this.gl = (_c = this.canvas) === null || _c === void 0 ? void 0 : _c.gl.wrap(); 403 | } else { 404 | var layer = this.layer; 405 | var attributes = ((_d = layer.options) === null || _d === void 0 ? void 0 : _d.glOptions) || { 406 | alpha: true, 407 | depth: true, 408 | antialias: true, 409 | stencil: true 410 | }; 411 | attributes.preserveDrawingBuffer = true; // fixed: jsdom env 412 | 413 | if ((_e = layer.options) === null || _e === void 0 ? void 0 : _e.customCreateGLContext) { 414 | this.gl = this.gl || ((_f = layer.options) === null || _f === void 0 ? void 0 : _f.customCreateGLContext(this.canvas2, attributes)); 415 | } else { 416 | this.gl = this.gl || createContext(this.canvas2, attributes); 417 | } 418 | 419 | if (!this.regl) { 420 | this.regl = REGL({ 421 | gl: this.gl, 422 | extensions: ['OES_texture_float', 'OES_element_index_uint', 'WEBGL_color_buffer_float'], 423 | attributes: { 424 | antialias: true, 425 | preserveDrawingBuffer: false 426 | } 427 | }); 428 | this.command = this.regl({ 429 | frag: fs, 430 | vert: vs, 431 | attributes: { 432 | a_pos: function a_pos(_, _a) { 433 | var a_pos = _a.a_pos; 434 | return a_pos; 435 | }, 436 | a_texCoord: function a_texCoord(_, _a) { 437 | var a_texCoord = _a.a_texCoord; 438 | return a_texCoord; 439 | } 440 | }, 441 | uniforms: { 442 | u_matrix: function u_matrix(_, _a) { 443 | var u_matrix = _a.u_matrix; 444 | return u_matrix; 445 | }, 446 | u_image: function u_image(_, _a) { 447 | var u_image = _a.u_image; 448 | return u_image; 449 | }, 450 | u_tile: function u_tile(_, _a) { 451 | var u_tile = _a.u_tile; 452 | return u_tile; 453 | }, 454 | u_tile_size: function u_tile_size(_, _a) { 455 | var u_tile_size = _a.u_tile_size; 456 | return u_tile_size; 457 | }, 458 | u_opacity: function u_opacity(_, _a) { 459 | var u_opacity = _a.u_opacity; 460 | return u_opacity; 461 | }, 462 | u_extrude_scale: function u_extrude_scale(_, _a) { 463 | var u_extrude_scale = _a.u_extrude_scale; 464 | return u_extrude_scale; 465 | }, 466 | u_hasTerrain: function u_hasTerrain(_, _a) { 467 | var u_hasTerrain = _a.u_hasTerrain; 468 | return u_hasTerrain; 469 | } 470 | }, 471 | viewport: function viewport(_, _a) { 472 | var _b = _a.canvasSize, 473 | width = _b[0], 474 | height = _b[1]; 475 | return { 476 | width: width, 477 | height: height 478 | }; 479 | }, 480 | depth: { 481 | enable: true, 482 | mask: true, 483 | func: 'less', 484 | range: [0, 1] 485 | }, 486 | // @link https://github.com/regl-project/regl/blob/master/API.md#stencil 487 | stencil: { 488 | enable: true, 489 | func: { 490 | cmp: '<=', 491 | // @ts-ignore 492 | ref: function ref(_, _a) { 493 | var zoom = _a.zoom; 494 | return zoom; 495 | }, 496 | mask: 0xff 497 | } 498 | }, 499 | blend: { 500 | enable: true, 501 | func: { 502 | src: 'src alpha', 503 | dst: 'one minus src alpha' 504 | }, 505 | color: [0, 0, 0, 0] 506 | }, 507 | elements: function elements(_, _a) { 508 | var elements = _a.elements; 509 | return elements; 510 | } 511 | }); 512 | } 513 | } 514 | }; 515 | /** 516 | * when map changed, call canvas change 517 | * @param canvasSize 518 | */ 519 | 520 | 521 | Renderer.prototype.resizeCanvas = function (canvasSize) { 522 | // eslint-disable-next-line no-useless-return 523 | if (!this.canvas) return; 524 | var map = this.getMap(); 525 | var retina = (map.getDevicePixelRatio ? map.getDevicePixelRatio() : getDevicePixelRatio()) || 1; 526 | var size = canvasSize || map.getSize(); 527 | 528 | if (this.canvas.width !== size.width * retina || this.canvas.height !== size.height * retina) { 529 | this.canvas.height = retina * size.height; 530 | this.canvas.width = retina * size.width; 531 | } 532 | 533 | if (this.canvas2.width !== this.canvas.width || this.canvas2.height !== this.canvas.height) { 534 | this.canvas2.height = this.canvas.height; 535 | this.canvas2.width = this.canvas.width; 536 | } 537 | }; 538 | /** 539 | * clear canvas 540 | */ 541 | 542 | 543 | Renderer.prototype.clearCanvas = function () { 544 | if (!this.canvas || !this.gl) return; 545 | 546 | _super.prototype.clearCanvas.call(this); // eslint-disable-next-line no-bitwise 547 | 548 | 549 | if (this.regl) { 550 | this.regl.clear({ 551 | color: [0, 0, 0, 0], 552 | depth: 1, 553 | stencil: this._tileZoom 554 | }); 555 | } 556 | }; 557 | 558 | Renderer.prototype.getMap = function () { 559 | return _super.prototype.getMap.call(this); 560 | }; 561 | 562 | Renderer.prototype.onRemove = function () { 563 | _super.prototype.onRemove.call(this); // this.removeGLCanvas(); 564 | 565 | }; 566 | 567 | Renderer.prototype.completeRender = function () { 568 | return _super.prototype.completeRender.call(this); 569 | }; 570 | 571 | Renderer.prototype.setCanvasUpdated = function () { 572 | return _super.prototype.setCanvasUpdated.call(this); 573 | }; 574 | 575 | Renderer.prototype.setToRedraw = function () { 576 | return _super.prototype.setToRedraw.call(this); 577 | }; 578 | 579 | Renderer.prototype.prepareCanvas = function () { 580 | return _super.prototype.prepareCanvas.call(this); 581 | }; 582 | 583 | Renderer.prototype.getTileOpacity = function (tileImage) { 584 | return _super.prototype.getTileOpacity.call(this, tileImage); 585 | }; 586 | 587 | return Renderer; 588 | }(renderer.TileLayerCanvasRenderer); 589 | 590 | TerrainLayer.registerRenderer('gl', Renderer); 591 | 592 | export default TerrainLayer; 593 | export { Renderer }; 594 | --------------------------------------------------------------------------------