@naivemap/mapbox-gl-image-layer 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -7
- package/dist/es/index.js +189 -91
- package/dist/es/shaders/image.fragment.glsl.js +1 -0
- package/dist/es/shaders/image.vertex.glsl.js +1 -0
- package/dist/es/shaders/mask.fragment.glsl.js +1 -0
- package/dist/es/shaders/mask.vertex.glsl.js +1 -0
- package/dist/js/index.d.ts +32 -16
- package/dist/js/index.js +215 -91
- package/dist/js/shaders/image.fragment.glsl.d.ts +2 -0
- package/dist/js/shaders/image.fragment.glsl.js +3 -0
- package/dist/js/shaders/image.vertex.glsl.d.ts +2 -0
- package/dist/js/shaders/image.vertex.glsl.js +3 -0
- package/dist/js/shaders/mask.fragment.glsl.d.ts +2 -0
- package/dist/js/shaders/mask.fragment.glsl.js +3 -0
- package/dist/js/shaders/mask.vertex.glsl.d.ts +2 -0
- package/dist/js/shaders/mask.vertex.glsl.js +3 -0
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -26,18 +26,31 @@ export default class ImageLayer implements mapboxgl.CustomLayerInterface
|
|
|
26
26
|
|
|
27
27
|
| Name | Description |
|
|
28
28
|
| --- | --- |
|
|
29
|
-
| **option.url** <br
|
|
30
|
-
| **option.projection** <br
|
|
31
|
-
| **option.coordinates** <br
|
|
29
|
+
| **option.url** <br />(`string`) | URL that points to an image. |
|
|
30
|
+
| **option.projection** <br />(`string`) | Projection with EPSG code that points to the image. |
|
|
31
|
+
| **option.coordinates** <br />(`Array<Array<number>>`) | Corners of image specified in longitude, latitude pairs: top left, top right, bottom right, bottom left. ref: [coordinates](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#image-coordinates) |
|
|
32
32
|
| **option.resampling** <br />(Optional `enum`. One of `"linear"`, `"nearest"`. Defaults to `"linear"`) | The resampling/interpolation method to use for overscaling, also known as texture magnification filter. ref: [raster-resampling](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-raster-raster-resampling) |
|
|
33
|
-
| **
|
|
33
|
+
| **option.opacity** <br />(Optional `number` between 0 and 1 inclusive. Defaults to 1. | The opacity at which the image will be drawn. |
|
|
34
|
+
| **option.crossOrigin** <br />(`string`) | The crossOrigin attribute is a string which specifies the Cross-Origin Resource Sharing ([CORS](https://developer.mozilla.org/en-US/docs/Glossary/CORS)) setting to use when retrieving the image. |
|
|
35
|
+
| **option.mask** <br />(`MaskProperty`) | The polygonal mask or multipolygonal mask for the image. |
|
|
34
36
|
|
|
35
37
|
```ts
|
|
36
38
|
export type ImageOption = {
|
|
37
39
|
url: string
|
|
38
40
|
projection: string
|
|
39
41
|
coordinates: Coordinates
|
|
40
|
-
resampling
|
|
42
|
+
resampling?: 'linear' | 'nearest'
|
|
43
|
+
opacity?: number
|
|
44
|
+
crossOrigin?: string
|
|
45
|
+
mask?: MaskProperty
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// top left, top right, bottom right, bottom left.
|
|
49
|
+
export type Coordinates = [[number, number], [number, number], [number, number], [number, number]]
|
|
50
|
+
|
|
51
|
+
export type MaskProperty = {
|
|
52
|
+
type?: 'in' | 'out' // default: in
|
|
53
|
+
data: GeoJSON.Polygon | GeoJSON.MultiPolygon
|
|
41
54
|
}
|
|
42
55
|
```
|
|
43
56
|
|
|
@@ -45,17 +58,26 @@ export type ImageOption = {
|
|
|
45
58
|
|
|
46
59
|
#### updateImage
|
|
47
60
|
|
|
48
|
-
Updates the
|
|
61
|
+
Updates the URL, the projection, the coordinates, the opacity or the resampling of the image.
|
|
49
62
|
|
|
50
63
|
```ts
|
|
51
64
|
updateImage(option: {
|
|
52
|
-
url
|
|
65
|
+
url?: string
|
|
53
66
|
projection?: string
|
|
54
67
|
coordinates?: Coordinates
|
|
68
|
+
opacity?: number
|
|
55
69
|
resampling?: 'linear' | 'nearest'
|
|
56
70
|
}): this
|
|
57
71
|
```
|
|
58
72
|
|
|
73
|
+
#### updateMask
|
|
74
|
+
|
|
75
|
+
Updates the mask property.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
updateMask(mask: Partial<MaskProperty>): this
|
|
79
|
+
```
|
|
80
|
+
|
|
59
81
|
## Example
|
|
60
82
|
|
|
61
83
|
```ts
|
package/dist/es/index.js
CHANGED
|
@@ -1,130 +1,228 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { satisfies } from 'compare-versions';
|
|
2
|
+
import earcut from 'earcut';
|
|
3
|
+
import mapboxgl from 'mapbox-gl';
|
|
4
|
+
import * as twgl from 'twgl.js';
|
|
5
|
+
import fs from './shaders/image.fragment.glsl';
|
|
6
|
+
import vs from './shaders/image.vertex.glsl';
|
|
7
|
+
import maskfs from './shaders/mask.fragment.glsl';
|
|
8
|
+
import maskvs from './shaders/mask.vertex.glsl';
|
|
3
9
|
import { initArrugator } from './utils/arrugator';
|
|
4
10
|
var ImageLayer = /** @class */ (function () {
|
|
5
11
|
function ImageLayer(id, option) {
|
|
6
|
-
this.id = id;
|
|
7
12
|
this.type = 'custom';
|
|
8
13
|
this.renderingMode = '2d';
|
|
9
|
-
|
|
10
|
-
this.
|
|
14
|
+
// mask
|
|
15
|
+
this.stencilChecked = true; // resetStencilClippingMasks 版本检查
|
|
16
|
+
this.id = id;
|
|
17
|
+
this.option = option;
|
|
18
|
+
this.loaded = false;
|
|
19
|
+
this.maskProperty = Object.assign({ type: 'in' }, option.mask);
|
|
20
|
+
// 检查 stencil 是否可用
|
|
21
|
+
this.stencilChecked = satisfies(mapboxgl.version, '>=2.7.0');
|
|
22
|
+
// 如果传了 mask 边界数据,且版本不符
|
|
23
|
+
if (this.maskProperty.data && !this.stencilChecked) {
|
|
24
|
+
throw new Error("\u5982\u679C\u9700\u8981\u906E\u7F69\uFF08\u63A9\u819C\uFF09\uFF0Cmapbox-gl \u7248\u672C\u5FC5\u987B\uFF1A>=2.7.0");
|
|
25
|
+
}
|
|
11
26
|
// 初始化 Arrugator
|
|
12
27
|
var projection = option.projection, coordinates = option.coordinates;
|
|
13
|
-
this.
|
|
14
|
-
this._map = null
|
|
15
|
-
this._gl = null
|
|
16
|
-
this._program = null
|
|
17
|
-
this._texture = null
|
|
18
|
-
this._positionBuffer = null
|
|
19
|
-
this._uvBuffer = null
|
|
20
|
-
this._verticesIndexBuffer = null
|
|
28
|
+
this.arrugado = initArrugator(projection, coordinates);
|
|
29
|
+
// this._map = null
|
|
30
|
+
// this._gl = null
|
|
31
|
+
// this._program = null
|
|
32
|
+
// this._texture = null
|
|
33
|
+
// this._positionBuffer = null
|
|
34
|
+
// this._uvBuffer = null
|
|
35
|
+
// this._verticesIndexBuffer = null
|
|
21
36
|
}
|
|
22
37
|
ImageLayer.prototype.onAdd = function (map, gl) {
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.
|
|
29
|
-
|
|
30
|
-
this.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
gl.vertexAttribPointer(a_uv, 2, gl.FLOAT, false, 0, 0);
|
|
41
|
-
gl.enableVertexAttribArray(a_uv);
|
|
42
|
-
this._verticesIndexBuffer = gl.createBuffer();
|
|
43
|
-
// gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._verticesIndexBuffer)
|
|
44
|
-
// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this._arrugado.trigs), gl.STATIC_DRAW)
|
|
45
|
-
this._bindData(gl, this._arrugado);
|
|
38
|
+
this.map = map;
|
|
39
|
+
this.gl = gl;
|
|
40
|
+
// 主程序
|
|
41
|
+
this.programInfo = twgl.createProgramInfo(gl, [vs, fs]);
|
|
42
|
+
this.loadTexture(map, gl);
|
|
43
|
+
this.bufferInfo = twgl.createBufferInfoFromArrays(gl, {
|
|
44
|
+
a_pos: { numComponents: 2, data: this.arrugado.pos },
|
|
45
|
+
a_uv: { numComponents: 2, data: this.arrugado.uv },
|
|
46
|
+
indices: this.arrugado.trigs,
|
|
47
|
+
});
|
|
48
|
+
// 掩膜程序
|
|
49
|
+
if (this.maskProperty.data) {
|
|
50
|
+
var data = this.maskProperty.data;
|
|
51
|
+
if (data) {
|
|
52
|
+
this.maskProgramInfo = twgl.createProgramInfo(gl, [maskvs, maskfs]);
|
|
53
|
+
this.maskBufferInfo = this.getMaskBufferInfo(gl, data);
|
|
54
|
+
}
|
|
46
55
|
}
|
|
47
56
|
};
|
|
48
57
|
ImageLayer.prototype.onRemove = function (map, gl) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
if (this.programInfo) {
|
|
59
|
+
gl.deleteProgram(this.programInfo.program);
|
|
60
|
+
}
|
|
61
|
+
if (this.maskProgramInfo) {
|
|
62
|
+
gl.deleteProgram(this.maskProgramInfo.program);
|
|
63
|
+
}
|
|
64
|
+
if (this.texture) {
|
|
65
|
+
gl.deleteTexture(this.texture);
|
|
66
|
+
}
|
|
52
67
|
};
|
|
53
68
|
ImageLayer.prototype.render = function (gl, matrix) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// texture
|
|
67
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
68
|
-
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
69
|
-
gl.uniform1i(gl.getUniformLocation(this._program, 'u_sampler'), 0);
|
|
70
|
-
// aplha
|
|
69
|
+
/**
|
|
70
|
+
* 线图层在启用 stencil 会消失,参考: https://github.com/mapbox/mapbox-gl-js/issues/12213
|
|
71
|
+
* 临时解决方案: map.painter.resetStencilClippingMasks()
|
|
72
|
+
* 该方法在 mapboxgl version >=2.7.0 才能用
|
|
73
|
+
*/
|
|
74
|
+
var _a;
|
|
75
|
+
if (this.stencilChecked) {
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
this.map.painter.resetStencilClippingMasks();
|
|
78
|
+
}
|
|
79
|
+
if (this.loaded && this.programInfo && this.bufferInfo) {
|
|
80
|
+
// blend
|
|
71
81
|
gl.enable(gl.BLEND);
|
|
72
82
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
if (this.maskProgramInfo && this.maskBufferInfo) {
|
|
84
|
+
// mask program
|
|
85
|
+
gl.useProgram(this.maskProgramInfo.program);
|
|
86
|
+
// stencil test
|
|
87
|
+
gl.enable(gl.STENCIL_TEST);
|
|
88
|
+
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
|
|
89
|
+
gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
|
|
90
|
+
gl.stencilMask(0xff);
|
|
91
|
+
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
92
|
+
// matrix
|
|
93
|
+
twgl.setUniforms(this.maskProgramInfo, { u_matrix: matrix });
|
|
94
|
+
// pos & indices
|
|
95
|
+
twgl.setBuffersAndAttributes(gl, this.maskProgramInfo, this.maskBufferInfo);
|
|
96
|
+
// draw
|
|
97
|
+
var elementType = gl.UNSIGNED_SHORT;
|
|
98
|
+
if (this.maskBufferInfo.numElements / 3 > 65535) {
|
|
99
|
+
// 使 drawElements 支持 UNSIGNED_INT 类型
|
|
100
|
+
gl.getExtension('OES_element_index_uint');
|
|
101
|
+
elementType = gl.UNSIGNED_INT;
|
|
102
|
+
}
|
|
103
|
+
gl.drawElements(gl.TRIANGLES, this.maskBufferInfo.numElements, elementType, 0);
|
|
104
|
+
}
|
|
105
|
+
// texture program
|
|
106
|
+
gl.useProgram(this.programInfo.program);
|
|
107
|
+
if ((_a = this.maskProgramInfo) === null || _a === void 0 ? void 0 : _a.program) {
|
|
108
|
+
// stencil test
|
|
109
|
+
var ref = this.maskProperty.type === 'out' ? 0 : 1;
|
|
110
|
+
gl.stencilFunc(gl.EQUAL, ref, 0xff);
|
|
111
|
+
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
112
|
+
}
|
|
113
|
+
// uniforms
|
|
114
|
+
twgl.setUniforms(this.programInfo, {
|
|
115
|
+
u_matrix: matrix,
|
|
116
|
+
u_opacity: this.option.opacity || 1,
|
|
117
|
+
u_sampler: this.texture,
|
|
118
|
+
});
|
|
119
|
+
// pos, uv & indices
|
|
120
|
+
twgl.setBuffersAndAttributes(gl, this.programInfo, this.bufferInfo);
|
|
121
|
+
// draw
|
|
122
|
+
gl.drawElements(gl.TRIANGLES, this.arrugado.trigs.length, gl.UNSIGNED_SHORT, 0);
|
|
123
|
+
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
124
|
+
gl.disable(gl.STENCIL_TEST);
|
|
76
125
|
}
|
|
77
126
|
};
|
|
78
127
|
/**
|
|
79
|
-
* Updates the
|
|
128
|
+
* Updates the URL, the projection, the coordinates, the opacity or the resampling of the image.
|
|
80
129
|
* @param {Object} option Options object.
|
|
81
|
-
* @param {string} [option.url]
|
|
130
|
+
* @param {string} [option.url] Image URL.
|
|
82
131
|
* @param {string} [option.projection] Projection with EPSG code that points to the image..
|
|
83
132
|
* @param {Array<Array<number>>} [option.coordinates] Four geographical coordinates,
|
|
133
|
+
* @param {number} [option.opacity] opacity of the image.
|
|
84
134
|
* @param {string} [option.resampling] The resampling/interpolation method to use for overscaling.
|
|
85
135
|
*/
|
|
86
136
|
ImageLayer.prototype.updateImage = function (option) {
|
|
87
|
-
var _a, _b, _c;
|
|
88
|
-
this.
|
|
89
|
-
|
|
90
|
-
if (this._gl && this._map) {
|
|
137
|
+
var _a, _b, _c, _d, _e;
|
|
138
|
+
if (this.gl && this.map) {
|
|
139
|
+
this.option.opacity = (_a = option.opacity) !== null && _a !== void 0 ? _a : this.option.opacity;
|
|
91
140
|
if (option.projection || option.coordinates) {
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
141
|
+
this.option.projection = (_b = option.projection) !== null && _b !== void 0 ? _b : this.option.projection;
|
|
142
|
+
this.option.coordinates = (_c = option.coordinates) !== null && _c !== void 0 ? _c : this.option.coordinates;
|
|
94
143
|
// reinit arrugator
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
144
|
+
this.arrugado = initArrugator(this.option.projection, this.option.coordinates);
|
|
145
|
+
this.bufferInfo = twgl.createBufferInfoFromArrays(this.gl, {
|
|
146
|
+
a_pos: { numComponents: 2, data: this.arrugado.pos },
|
|
147
|
+
a_uv: { numComponents: 2, data: this.arrugado.uv },
|
|
148
|
+
indices: this.arrugado.trigs,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (option.url || option.resampling) {
|
|
152
|
+
this.loaded = false;
|
|
153
|
+
this.option.url = (_d = option.url) !== null && _d !== void 0 ? _d : this.option.url;
|
|
154
|
+
this.option.resampling = (_e = option.resampling) !== null && _e !== void 0 ? _e : this.option.resampling;
|
|
155
|
+
// reload image
|
|
156
|
+
this.loadTexture(this.map, this.gl);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
this.map.triggerRepaint();
|
|
97
160
|
}
|
|
98
|
-
this._option.resampling = (_c = option.resampling) !== null && _c !== void 0 ? _c : this._option.resampling;
|
|
99
|
-
// reload image
|
|
100
|
-
this._loadImage(this._map, this._gl);
|
|
101
161
|
}
|
|
102
162
|
return this;
|
|
103
163
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Updates the mask property
|
|
166
|
+
* @param {MaskProperty} mask The mask property.
|
|
167
|
+
*/
|
|
168
|
+
ImageLayer.prototype.updateMask = function (mask) {
|
|
169
|
+
if (this.gl && this.map && this.maskProgramInfo) {
|
|
170
|
+
this.maskProperty = Object.assign(this.maskProperty, mask);
|
|
171
|
+
this.maskBufferInfo = this.getMaskBufferInfo(this.gl, this.maskProperty.data);
|
|
172
|
+
this.map.triggerRepaint();
|
|
173
|
+
}
|
|
174
|
+
return this;
|
|
111
175
|
};
|
|
112
|
-
ImageLayer.prototype.
|
|
176
|
+
ImageLayer.prototype.loadTexture = function (map, gl) {
|
|
113
177
|
var _this = this;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
124
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
|
|
178
|
+
// 创建纹理
|
|
179
|
+
var filter = this.option.resampling === 'nearest' ? gl.NEAREST : gl.LINEAR;
|
|
180
|
+
this.texture = twgl.createTexture(gl, {
|
|
181
|
+
src: this.option.url,
|
|
182
|
+
crossOrigin: this.option.crossOrigin,
|
|
183
|
+
minMag: filter,
|
|
184
|
+
flipY: 0,
|
|
185
|
+
}, function () {
|
|
186
|
+
_this.loaded = true;
|
|
125
187
|
map.triggerRepaint();
|
|
126
188
|
});
|
|
127
189
|
};
|
|
190
|
+
ImageLayer.prototype.getMaskBufferInfo = function (gl, data) {
|
|
191
|
+
var positions = [];
|
|
192
|
+
var triangles = [];
|
|
193
|
+
if (data.type === 'MultiPolygon') {
|
|
194
|
+
// type: 'MultiPolygon'
|
|
195
|
+
var polyCount = data.coordinates.length;
|
|
196
|
+
var triangleStartIndex_1 = 0;
|
|
197
|
+
for (var i = 0; i < polyCount; i++) {
|
|
198
|
+
var coordinates = data.coordinates[i];
|
|
199
|
+
var flatten = earcut.flatten(coordinates);
|
|
200
|
+
var vertices = flatten.vertices, holes = flatten.holes, dimensions = flatten.dimensions;
|
|
201
|
+
var triangle = earcut(vertices, holes, dimensions);
|
|
202
|
+
var triangleNew = triangle.map(function (item) { return item + triangleStartIndex_1; });
|
|
203
|
+
triangleStartIndex_1 += vertices.length / 2;
|
|
204
|
+
// positions.push(...vertices)
|
|
205
|
+
// triangles.push(...triangleNew)
|
|
206
|
+
for (var m = 0; m < vertices.length; m++) {
|
|
207
|
+
positions.push(vertices[m]);
|
|
208
|
+
}
|
|
209
|
+
for (var n = 0; n < triangleNew.length; n++) {
|
|
210
|
+
triangles.push(triangleNew[n]);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// type: 'Polygon'
|
|
216
|
+
var flatten = earcut.flatten(data.coordinates);
|
|
217
|
+
var vertices = flatten.vertices, holes = flatten.holes, dimensions = flatten.dimensions;
|
|
218
|
+
positions = vertices;
|
|
219
|
+
triangles = earcut(vertices, holes, dimensions);
|
|
220
|
+
}
|
|
221
|
+
return twgl.createBufferInfoFromArrays(gl, {
|
|
222
|
+
a_pos: { numComponents: 2, data: positions },
|
|
223
|
+
indices: triangles.length / 3 > 65535 ? new Uint32Array(triangles) : new Uint16Array(triangles),
|
|
224
|
+
});
|
|
225
|
+
};
|
|
128
226
|
return ImageLayer;
|
|
129
227
|
}());
|
|
130
228
|
export default ImageLayer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "\n#ifdef GL_ES\n precision highp int;\n precision mediump float;\n#endif\nuniform sampler2D u_sampler;\nuniform float u_opacity;\nvarying vec2 v_uv;\nvoid main() {\n vec4 color = texture2D(u_sampler, v_uv);\n gl_FragColor = color * u_opacity;\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "\nuniform mat4 u_matrix;\nattribute vec2 a_pos;\nattribute vec2 a_uv;\nvarying vec2 v_uv;\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n v_uv = a_uv;\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "\n#ifdef GL_ES\nprecision highp int;\nprecision mediump float;\n#endif\n\nvoid main() {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "\nuniform mat4 u_matrix;\nuniform float u_alt;\nattribute vec2 a_pos;\n\nconst float PI = 3.1415926536;\nconst float earthRadius = 6371008.8;\nconst float earthCircumference = 2.0 * PI * earthRadius; // meters\n\nfloat circumferenceAtLatitude(float latitude) {\n return earthCircumference * cos(latitude * PI / 180.0);\n}\n\nfloat mercatorXfromLng(float lng) {\n return (180.0 + lng) / 360.0;\n}\n\nfloat mercatorYfromLat(float lat) {\n return (180.0 - (180.0 / PI * log(tan(PI / 4.0 + lat * PI / 360.0)))) / 360.0;\n}\n\nfloat mercatorZfromAltitude(float altitude, float lat) {\n return altitude / circumferenceAtLatitude(lat);\n}\n\nvec3 mercatorfromLngLat(vec2 lnglat, float alt) {\n return vec3(mercatorXfromLng(lnglat.x), mercatorYfromLat(lnglat.y), mercatorZfromAltitude(alt, lnglat.y));\n}\n\nvoid main() {\n vec3 mercator = mercatorfromLngLat(a_pos, 0.0);\n gl_Position = u_matrix * vec4(mercator, 1.0);\n // gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n}\n";
|
package/dist/js/index.d.ts
CHANGED
|
@@ -1,44 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
import mapboxgl from 'mapbox-gl';
|
|
2
2
|
import type { Coordinates } from './utils/arrugator';
|
|
3
|
+
export type { Coordinates } from './utils/arrugator';
|
|
4
|
+
export declare type MaskProperty = {
|
|
5
|
+
type?: 'in' | 'out';
|
|
6
|
+
data: GeoJSON.Polygon | GeoJSON.MultiPolygon;
|
|
7
|
+
};
|
|
3
8
|
export declare type ImageOption = {
|
|
4
9
|
url: string;
|
|
5
10
|
projection: string;
|
|
6
11
|
coordinates: Coordinates;
|
|
7
12
|
resampling?: 'linear' | 'nearest';
|
|
13
|
+
opacity?: number;
|
|
8
14
|
crossOrigin?: string;
|
|
15
|
+
mask?: MaskProperty;
|
|
9
16
|
};
|
|
10
17
|
export default class ImageLayer implements mapboxgl.CustomLayerInterface {
|
|
11
18
|
id: string;
|
|
12
19
|
type: 'custom';
|
|
13
20
|
renderingMode?: '2d' | '3d' | undefined;
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
private
|
|
18
|
-
private
|
|
19
|
-
private
|
|
20
|
-
private
|
|
21
|
-
private
|
|
22
|
-
private
|
|
23
|
-
private
|
|
21
|
+
private option;
|
|
22
|
+
private map?;
|
|
23
|
+
private gl?;
|
|
24
|
+
private loaded;
|
|
25
|
+
private arrugado;
|
|
26
|
+
private programInfo?;
|
|
27
|
+
private bufferInfo?;
|
|
28
|
+
private texture?;
|
|
29
|
+
private stencilChecked;
|
|
30
|
+
private maskProperty;
|
|
31
|
+
private maskProgramInfo?;
|
|
32
|
+
private maskBufferInfo?;
|
|
24
33
|
constructor(id: string, option: ImageOption);
|
|
25
34
|
onAdd(map: mapboxgl.Map, gl: WebGLRenderingContext): void;
|
|
26
35
|
onRemove(map: mapboxgl.Map, gl: WebGLRenderingContext): void;
|
|
27
36
|
render(gl: WebGLRenderingContext, matrix: number[]): void;
|
|
28
37
|
/**
|
|
29
|
-
* Updates the
|
|
38
|
+
* Updates the URL, the projection, the coordinates, the opacity or the resampling of the image.
|
|
30
39
|
* @param {Object} option Options object.
|
|
31
|
-
* @param {string} [option.url]
|
|
40
|
+
* @param {string} [option.url] Image URL.
|
|
32
41
|
* @param {string} [option.projection] Projection with EPSG code that points to the image..
|
|
33
42
|
* @param {Array<Array<number>>} [option.coordinates] Four geographical coordinates,
|
|
43
|
+
* @param {number} [option.opacity] opacity of the image.
|
|
34
44
|
* @param {string} [option.resampling] The resampling/interpolation method to use for overscaling.
|
|
35
45
|
*/
|
|
36
46
|
updateImage(option: {
|
|
37
|
-
url
|
|
47
|
+
url?: string;
|
|
38
48
|
projection?: string;
|
|
39
49
|
coordinates?: Coordinates;
|
|
50
|
+
opacity?: number;
|
|
40
51
|
resampling?: 'linear' | 'nearest';
|
|
41
52
|
}): this;
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Updates the mask property
|
|
55
|
+
* @param {MaskProperty} mask The mask property.
|
|
56
|
+
*/
|
|
57
|
+
updateMask(mask: Partial<MaskProperty>): this;
|
|
58
|
+
private loadTexture;
|
|
59
|
+
private getMaskBufferInfo;
|
|
44
60
|
}
|
package/dist/js/index.js
CHANGED
|
@@ -1,132 +1,256 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
2
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var
|
|
4
|
-
var
|
|
29
|
+
var compare_versions_1 = require("compare-versions");
|
|
30
|
+
var earcut_1 = __importDefault(require("earcut"));
|
|
31
|
+
var mapbox_gl_1 = __importDefault(require("mapbox-gl"));
|
|
32
|
+
var twgl = __importStar(require("twgl.js"));
|
|
33
|
+
var image_fragment_glsl_1 = __importDefault(require("./shaders/image.fragment.glsl"));
|
|
34
|
+
var image_vertex_glsl_1 = __importDefault(require("./shaders/image.vertex.glsl"));
|
|
35
|
+
var mask_fragment_glsl_1 = __importDefault(require("./shaders/mask.fragment.glsl"));
|
|
36
|
+
var mask_vertex_glsl_1 = __importDefault(require("./shaders/mask.vertex.glsl"));
|
|
5
37
|
var arrugator_1 = require("./utils/arrugator");
|
|
6
38
|
var ImageLayer = /** @class */ (function () {
|
|
7
39
|
function ImageLayer(id, option) {
|
|
8
|
-
this.id = id;
|
|
9
40
|
this.type = 'custom';
|
|
10
41
|
this.renderingMode = '2d';
|
|
11
|
-
|
|
12
|
-
this.
|
|
42
|
+
// mask
|
|
43
|
+
this.stencilChecked = true; // resetStencilClippingMasks 版本检查
|
|
44
|
+
this.id = id;
|
|
45
|
+
this.option = option;
|
|
46
|
+
this.loaded = false;
|
|
47
|
+
this.maskProperty = Object.assign({ type: 'in' }, option.mask);
|
|
48
|
+
// 检查 stencil 是否可用
|
|
49
|
+
this.stencilChecked = (0, compare_versions_1.satisfies)(mapbox_gl_1.default.version, '>=2.7.0');
|
|
50
|
+
// 如果传了 mask 边界数据,且版本不符
|
|
51
|
+
if (this.maskProperty.data && !this.stencilChecked) {
|
|
52
|
+
throw new Error("\u5982\u679C\u9700\u8981\u906E\u7F69\uFF08\u63A9\u819C\uFF09\uFF0Cmapbox-gl \u7248\u672C\u5FC5\u987B\uFF1A>=2.7.0");
|
|
53
|
+
}
|
|
13
54
|
// 初始化 Arrugator
|
|
14
55
|
var projection = option.projection, coordinates = option.coordinates;
|
|
15
|
-
this.
|
|
16
|
-
this._map = null
|
|
17
|
-
this._gl = null
|
|
18
|
-
this._program = null
|
|
19
|
-
this._texture = null
|
|
20
|
-
this._positionBuffer = null
|
|
21
|
-
this._uvBuffer = null
|
|
22
|
-
this._verticesIndexBuffer = null
|
|
56
|
+
this.arrugado = (0, arrugator_1.initArrugator)(projection, coordinates);
|
|
57
|
+
// this._map = null
|
|
58
|
+
// this._gl = null
|
|
59
|
+
// this._program = null
|
|
60
|
+
// this._texture = null
|
|
61
|
+
// this._positionBuffer = null
|
|
62
|
+
// this._uvBuffer = null
|
|
63
|
+
// this._verticesIndexBuffer = null
|
|
23
64
|
}
|
|
24
65
|
ImageLayer.prototype.onAdd = function (map, gl) {
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.
|
|
31
|
-
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
gl.vertexAttribPointer(a_uv, 2, gl.FLOAT, false, 0, 0);
|
|
43
|
-
gl.enableVertexAttribArray(a_uv);
|
|
44
|
-
this._verticesIndexBuffer = gl.createBuffer();
|
|
45
|
-
// gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._verticesIndexBuffer)
|
|
46
|
-
// gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this._arrugado.trigs), gl.STATIC_DRAW)
|
|
47
|
-
this._bindData(gl, this._arrugado);
|
|
66
|
+
this.map = map;
|
|
67
|
+
this.gl = gl;
|
|
68
|
+
// 主程序
|
|
69
|
+
this.programInfo = twgl.createProgramInfo(gl, [image_vertex_glsl_1.default, image_fragment_glsl_1.default]);
|
|
70
|
+
this.loadTexture(map, gl);
|
|
71
|
+
this.bufferInfo = twgl.createBufferInfoFromArrays(gl, {
|
|
72
|
+
a_pos: { numComponents: 2, data: this.arrugado.pos },
|
|
73
|
+
a_uv: { numComponents: 2, data: this.arrugado.uv },
|
|
74
|
+
indices: this.arrugado.trigs,
|
|
75
|
+
});
|
|
76
|
+
// 掩膜程序
|
|
77
|
+
if (this.maskProperty.data) {
|
|
78
|
+
var data = this.maskProperty.data;
|
|
79
|
+
if (data) {
|
|
80
|
+
this.maskProgramInfo = twgl.createProgramInfo(gl, [mask_vertex_glsl_1.default, mask_fragment_glsl_1.default]);
|
|
81
|
+
this.maskBufferInfo = this.getMaskBufferInfo(gl, data);
|
|
82
|
+
}
|
|
48
83
|
}
|
|
49
84
|
};
|
|
50
85
|
ImageLayer.prototype.onRemove = function (map, gl) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
86
|
+
if (this.programInfo) {
|
|
87
|
+
gl.deleteProgram(this.programInfo.program);
|
|
88
|
+
}
|
|
89
|
+
if (this.maskProgramInfo) {
|
|
90
|
+
gl.deleteProgram(this.maskProgramInfo.program);
|
|
91
|
+
}
|
|
92
|
+
if (this.texture) {
|
|
93
|
+
gl.deleteTexture(this.texture);
|
|
94
|
+
}
|
|
54
95
|
};
|
|
55
96
|
ImageLayer.prototype.render = function (gl, matrix) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// texture
|
|
69
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
70
|
-
gl.bindTexture(gl.TEXTURE_2D, this._texture);
|
|
71
|
-
gl.uniform1i(gl.getUniformLocation(this._program, 'u_sampler'), 0);
|
|
72
|
-
// aplha
|
|
97
|
+
/**
|
|
98
|
+
* 线图层在启用 stencil 会消失,参考: https://github.com/mapbox/mapbox-gl-js/issues/12213
|
|
99
|
+
* 临时解决方案: map.painter.resetStencilClippingMasks()
|
|
100
|
+
* 该方法在 mapboxgl version >=2.7.0 才能用
|
|
101
|
+
*/
|
|
102
|
+
var _a;
|
|
103
|
+
if (this.stencilChecked) {
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
this.map.painter.resetStencilClippingMasks();
|
|
106
|
+
}
|
|
107
|
+
if (this.loaded && this.programInfo && this.bufferInfo) {
|
|
108
|
+
// blend
|
|
73
109
|
gl.enable(gl.BLEND);
|
|
74
110
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
111
|
+
if (this.maskProgramInfo && this.maskBufferInfo) {
|
|
112
|
+
// mask program
|
|
113
|
+
gl.useProgram(this.maskProgramInfo.program);
|
|
114
|
+
// stencil test
|
|
115
|
+
gl.enable(gl.STENCIL_TEST);
|
|
116
|
+
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
|
|
117
|
+
gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
|
|
118
|
+
gl.stencilMask(0xff);
|
|
119
|
+
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
120
|
+
// matrix
|
|
121
|
+
twgl.setUniforms(this.maskProgramInfo, { u_matrix: matrix });
|
|
122
|
+
// pos & indices
|
|
123
|
+
twgl.setBuffersAndAttributes(gl, this.maskProgramInfo, this.maskBufferInfo);
|
|
124
|
+
// draw
|
|
125
|
+
var elementType = gl.UNSIGNED_SHORT;
|
|
126
|
+
if (this.maskBufferInfo.numElements / 3 > 65535) {
|
|
127
|
+
// 使 drawElements 支持 UNSIGNED_INT 类型
|
|
128
|
+
gl.getExtension('OES_element_index_uint');
|
|
129
|
+
elementType = gl.UNSIGNED_INT;
|
|
130
|
+
}
|
|
131
|
+
gl.drawElements(gl.TRIANGLES, this.maskBufferInfo.numElements, elementType, 0);
|
|
132
|
+
}
|
|
133
|
+
// texture program
|
|
134
|
+
gl.useProgram(this.programInfo.program);
|
|
135
|
+
if ((_a = this.maskProgramInfo) === null || _a === void 0 ? void 0 : _a.program) {
|
|
136
|
+
// stencil test
|
|
137
|
+
var ref = this.maskProperty.type === 'out' ? 0 : 1;
|
|
138
|
+
gl.stencilFunc(gl.EQUAL, ref, 0xff);
|
|
139
|
+
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
|
140
|
+
}
|
|
141
|
+
// uniforms
|
|
142
|
+
twgl.setUniforms(this.programInfo, {
|
|
143
|
+
u_matrix: matrix,
|
|
144
|
+
u_opacity: this.option.opacity || 1,
|
|
145
|
+
u_sampler: this.texture,
|
|
146
|
+
});
|
|
147
|
+
// pos, uv & indices
|
|
148
|
+
twgl.setBuffersAndAttributes(gl, this.programInfo, this.bufferInfo);
|
|
149
|
+
// draw
|
|
150
|
+
gl.drawElements(gl.TRIANGLES, this.arrugado.trigs.length, gl.UNSIGNED_SHORT, 0);
|
|
151
|
+
gl.clear(gl.STENCIL_BUFFER_BIT);
|
|
152
|
+
gl.disable(gl.STENCIL_TEST);
|
|
78
153
|
}
|
|
79
154
|
};
|
|
80
155
|
/**
|
|
81
|
-
* Updates the
|
|
156
|
+
* Updates the URL, the projection, the coordinates, the opacity or the resampling of the image.
|
|
82
157
|
* @param {Object} option Options object.
|
|
83
|
-
* @param {string} [option.url]
|
|
158
|
+
* @param {string} [option.url] Image URL.
|
|
84
159
|
* @param {string} [option.projection] Projection with EPSG code that points to the image..
|
|
85
160
|
* @param {Array<Array<number>>} [option.coordinates] Four geographical coordinates,
|
|
161
|
+
* @param {number} [option.opacity] opacity of the image.
|
|
86
162
|
* @param {string} [option.resampling] The resampling/interpolation method to use for overscaling.
|
|
87
163
|
*/
|
|
88
164
|
ImageLayer.prototype.updateImage = function (option) {
|
|
89
|
-
var _a, _b, _c;
|
|
90
|
-
this.
|
|
91
|
-
|
|
92
|
-
if (this._gl && this._map) {
|
|
165
|
+
var _a, _b, _c, _d, _e;
|
|
166
|
+
if (this.gl && this.map) {
|
|
167
|
+
this.option.opacity = (_a = option.opacity) !== null && _a !== void 0 ? _a : this.option.opacity;
|
|
93
168
|
if (option.projection || option.coordinates) {
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
169
|
+
this.option.projection = (_b = option.projection) !== null && _b !== void 0 ? _b : this.option.projection;
|
|
170
|
+
this.option.coordinates = (_c = option.coordinates) !== null && _c !== void 0 ? _c : this.option.coordinates;
|
|
96
171
|
// reinit arrugator
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
172
|
+
this.arrugado = (0, arrugator_1.initArrugator)(this.option.projection, this.option.coordinates);
|
|
173
|
+
this.bufferInfo = twgl.createBufferInfoFromArrays(this.gl, {
|
|
174
|
+
a_pos: { numComponents: 2, data: this.arrugado.pos },
|
|
175
|
+
a_uv: { numComponents: 2, data: this.arrugado.uv },
|
|
176
|
+
indices: this.arrugado.trigs,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (option.url || option.resampling) {
|
|
180
|
+
this.loaded = false;
|
|
181
|
+
this.option.url = (_d = option.url) !== null && _d !== void 0 ? _d : this.option.url;
|
|
182
|
+
this.option.resampling = (_e = option.resampling) !== null && _e !== void 0 ? _e : this.option.resampling;
|
|
183
|
+
// reload image
|
|
184
|
+
this.loadTexture(this.map, this.gl);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.map.triggerRepaint();
|
|
99
188
|
}
|
|
100
|
-
this._option.resampling = (_c = option.resampling) !== null && _c !== void 0 ? _c : this._option.resampling;
|
|
101
|
-
// reload image
|
|
102
|
-
this._loadImage(this._map, this._gl);
|
|
103
189
|
}
|
|
104
190
|
return this;
|
|
105
191
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Updates the mask property
|
|
194
|
+
* @param {MaskProperty} mask The mask property.
|
|
195
|
+
*/
|
|
196
|
+
ImageLayer.prototype.updateMask = function (mask) {
|
|
197
|
+
if (this.gl && this.map && this.maskProgramInfo) {
|
|
198
|
+
this.maskProperty = Object.assign(this.maskProperty, mask);
|
|
199
|
+
this.maskBufferInfo = this.getMaskBufferInfo(this.gl, this.maskProperty.data);
|
|
200
|
+
this.map.triggerRepaint();
|
|
201
|
+
}
|
|
202
|
+
return this;
|
|
113
203
|
};
|
|
114
|
-
ImageLayer.prototype.
|
|
204
|
+
ImageLayer.prototype.loadTexture = function (map, gl) {
|
|
115
205
|
var _this = this;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
126
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
|
|
206
|
+
// 创建纹理
|
|
207
|
+
var filter = this.option.resampling === 'nearest' ? gl.NEAREST : gl.LINEAR;
|
|
208
|
+
this.texture = twgl.createTexture(gl, {
|
|
209
|
+
src: this.option.url,
|
|
210
|
+
crossOrigin: this.option.crossOrigin,
|
|
211
|
+
minMag: filter,
|
|
212
|
+
flipY: 0,
|
|
213
|
+
}, function () {
|
|
214
|
+
_this.loaded = true;
|
|
127
215
|
map.triggerRepaint();
|
|
128
216
|
});
|
|
129
217
|
};
|
|
218
|
+
ImageLayer.prototype.getMaskBufferInfo = function (gl, data) {
|
|
219
|
+
var positions = [];
|
|
220
|
+
var triangles = [];
|
|
221
|
+
if (data.type === 'MultiPolygon') {
|
|
222
|
+
// type: 'MultiPolygon'
|
|
223
|
+
var polyCount = data.coordinates.length;
|
|
224
|
+
var triangleStartIndex_1 = 0;
|
|
225
|
+
for (var i = 0; i < polyCount; i++) {
|
|
226
|
+
var coordinates = data.coordinates[i];
|
|
227
|
+
var flatten = earcut_1.default.flatten(coordinates);
|
|
228
|
+
var vertices = flatten.vertices, holes = flatten.holes, dimensions = flatten.dimensions;
|
|
229
|
+
var triangle = (0, earcut_1.default)(vertices, holes, dimensions);
|
|
230
|
+
var triangleNew = triangle.map(function (item) { return item + triangleStartIndex_1; });
|
|
231
|
+
triangleStartIndex_1 += vertices.length / 2;
|
|
232
|
+
// positions.push(...vertices)
|
|
233
|
+
// triangles.push(...triangleNew)
|
|
234
|
+
for (var m = 0; m < vertices.length; m++) {
|
|
235
|
+
positions.push(vertices[m]);
|
|
236
|
+
}
|
|
237
|
+
for (var n = 0; n < triangleNew.length; n++) {
|
|
238
|
+
triangles.push(triangleNew[n]);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// type: 'Polygon'
|
|
244
|
+
var flatten = earcut_1.default.flatten(data.coordinates);
|
|
245
|
+
var vertices = flatten.vertices, holes = flatten.holes, dimensions = flatten.dimensions;
|
|
246
|
+
positions = vertices;
|
|
247
|
+
triangles = (0, earcut_1.default)(vertices, holes, dimensions);
|
|
248
|
+
}
|
|
249
|
+
return twgl.createBufferInfoFromArrays(gl, {
|
|
250
|
+
a_pos: { numComponents: 2, data: positions },
|
|
251
|
+
indices: triangles.length / 3 > 65535 ? new Uint32Array(triangles) : new Uint16Array(triangles),
|
|
252
|
+
});
|
|
253
|
+
};
|
|
130
254
|
return ImageLayer;
|
|
131
255
|
}());
|
|
132
256
|
exports.default = ImageLayer;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: "\n#ifdef GL_ES\n precision highp int;\n precision mediump float;\n#endif\nuniform sampler2D u_sampler;\nuniform float u_opacity;\nvarying vec2 v_uv;\nvoid main() {\n vec4 color = texture2D(u_sampler, v_uv);\n gl_FragColor = color * u_opacity;\n}\n";
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = "\n#ifdef GL_ES\n precision highp int;\n precision mediump float;\n#endif\nuniform sampler2D u_sampler;\nuniform float u_opacity;\nvarying vec2 v_uv;\nvoid main() {\n vec4 color = texture2D(u_sampler, v_uv);\n gl_FragColor = color * u_opacity;\n}\n";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = "\nuniform mat4 u_matrix;\nattribute vec2 a_pos;\nattribute vec2 a_uv;\nvarying vec2 v_uv;\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n v_uv = a_uv;\n}\n";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: "\nuniform mat4 u_matrix;\nuniform float u_alt;\nattribute vec2 a_pos;\n\nconst float PI = 3.1415926536;\nconst float earthRadius = 6371008.8;\nconst float earthCircumference = 2.0 * PI * earthRadius; // meters\n\nfloat circumferenceAtLatitude(float latitude) {\n return earthCircumference * cos(latitude * PI / 180.0);\n}\n\nfloat mercatorXfromLng(float lng) {\n return (180.0 + lng) / 360.0;\n}\n\nfloat mercatorYfromLat(float lat) {\n return (180.0 - (180.0 / PI * log(tan(PI / 4.0 + lat * PI / 360.0)))) / 360.0;\n}\n\nfloat mercatorZfromAltitude(float altitude, float lat) {\n return altitude / circumferenceAtLatitude(lat);\n}\n\nvec3 mercatorfromLngLat(vec2 lnglat, float alt) {\n return vec3(mercatorXfromLng(lnglat.x), mercatorYfromLat(lnglat.y), mercatorZfromAltitude(alt, lnglat.y));\n}\n\nvoid main() {\n vec3 mercator = mercatorfromLngLat(a_pos, 0.0);\n gl_Position = u_matrix * vec4(mercator, 1.0);\n // gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n}\n";
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = "\nuniform mat4 u_matrix;\nuniform float u_alt;\nattribute vec2 a_pos;\n\nconst float PI = 3.1415926536;\nconst float earthRadius = 6371008.8;\nconst float earthCircumference = 2.0 * PI * earthRadius; // meters\n\nfloat circumferenceAtLatitude(float latitude) {\n return earthCircumference * cos(latitude * PI / 180.0);\n}\n\nfloat mercatorXfromLng(float lng) {\n return (180.0 + lng) / 360.0;\n}\n\nfloat mercatorYfromLat(float lat) {\n return (180.0 - (180.0 / PI * log(tan(PI / 4.0 + lat * PI / 360.0)))) / 360.0;\n}\n\nfloat mercatorZfromAltitude(float altitude, float lat) {\n return altitude / circumferenceAtLatitude(lat);\n}\n\nvec3 mercatorfromLngLat(vec2 lnglat, float alt) {\n return vec3(mercatorXfromLng(lnglat.x), mercatorYfromLat(lnglat.y), mercatorZfromAltitude(alt, lnglat.y));\n}\n\nvoid main() {\n vec3 mercator = mercatorfromLngLat(a_pos, 0.0);\n gl_Position = u_matrix * vec4(mercator, 1.0);\n // gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n}\n";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naivemap/mapbox-gl-image-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Load a static image of any projection via Arrugator and Proj4js.",
|
|
5
5
|
"author": "huanglii <li.huangli@qq.com>",
|
|
6
6
|
"homepage": "https://github.com/naivemap/mapbox-gl-layers#readme",
|
|
@@ -45,13 +45,17 @@
|
|
|
45
45
|
"proj4": "^2.8.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"arrugator": "^1.0.1"
|
|
48
|
+
"arrugator": "^1.0.1",
|
|
49
|
+
"compare-versions": "^6.0.0-rc.1",
|
|
50
|
+
"earcut": "^2.2.4",
|
|
51
|
+
"twgl.js": "^5.3.1"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
54
|
+
"@types/earcut": "^2.1.1",
|
|
51
55
|
"@types/mapbox-gl": "^2.7.2",
|
|
52
56
|
"@types/node": "^17.0.36",
|
|
53
57
|
"@types/proj4": "^2.5.2",
|
|
54
58
|
"npm-run-all": "^4.1.5"
|
|
55
59
|
},
|
|
56
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "3a2fa3bab4a8e676df592ea4f674fbf9b9e9b221"
|
|
57
61
|
}
|