/
StandardImageProvider.ts
234 lines (177 loc) · 5.78 KB
/
StandardImageProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import ImageProvider from "./ImageProvider";
import CredentialMode from "./CredentialMode";
/**
* 標準地図画像プロバイダ
*
* 汎用的な地図画像プロバイダの実装である。
* 構築子の引数に prefix, suffix, size, zmin, zmax を与えた場合、各メソッドの動作は以下のようになる。
* ここで c1, c2, c3 は opts.coord_order の指定に従った第1、第2、第3の座標である。
*
* ```
* requestTile( z, x, y ) -> URL が prefix + c1 + '/' + c2 + '/' + c3 + suffix の画像を要求
* getImageSize() -> size を返す
* getZoomLevelRange() -> new ImageProvider.Range( zmin, zmax ) を返す
* ```
*/
class StandardImageProvider extends ImageProvider {
private _prefix: string;
private _suffix: string;
private _size: number;
private _min_level: number;
private _max_level: number;
private _coords_part: OrderCoords;
private _crossOrigin: string | null;
/**
* @param prefix URL の先頭文字列
* @param suffix URL の末尾文字列
* @param size 地図タイル画像の寸法
* @param zmin 最小ズームレベル
* @param zmax 最大ズームレベル
* @param opts オプション集合
*/
constructor( prefix: string, suffix: string, size: number, zmin: number, zmax: number, opts?: StandardImageProvider.Option )
{
super();
this._prefix = prefix;
this._suffix = suffix;
this._size = size;
this._min_level = zmin;
this._max_level = zmax;
// タイル座標を並び替える関数
let orderCoords: OrderCoords | null = null;
if ( opts && opts.coord_order ) {
if ( opts.coord_order === StandardImageProvider.CoordOrder.ZYX ) {
orderCoords = function( z, x, y ) { return z + "/" + y + "/" + x; };
}
else if ( opts.coord_order === StandardImageProvider.CoordOrder.XYZ ) {
orderCoords = function( z, x, y ) { return x + "/" + y + "/" + z; };
}
}
const orderCoordsFixed = (
orderCoords ||
function( z, x, y ) { return z + "/" + x + "/" + y; } // その他の場合は既定値 COORD_ORDER_ZXY を使う
);
// XY 座標を変換する関数
let convCoords: OrderCoords | null = null;
if ( opts && opts.coord_system ) {
if ( opts.coord_system === StandardImageProvider.CoordSystem.LOWER_LEFT ) {
convCoords = function( z, x, y ) {
var size = Math.round( Math.pow( 2, z ) );
return orderCoordsFixed( z, x, size - y - 1 );
};
}
}
if ( !convCoords ) {
// その他の場合は既定値 UPPER_LEFT (無変換) を使う
convCoords = orderCoordsFixed;
}
// 座標部分の URL を取得する関数
this._coords_part = convCoords;
// crossorigin 属性の値
this._crossOrigin = "anonymous";
if ( opts && opts.credentials ) {
if ( opts.credentials === CredentialMode.OMIT ) {
this._crossOrigin = null;
}
else if ( opts.credentials === CredentialMode.INCLUDE ) {
this._crossOrigin = "use-credentials";
}
}
}
/**
*/
override requestTile( z: number, x: number, y: number, callback: ImageProvider.RequestCallback ): object
{
var image = new Image();
image.onload = function() { callback( image ); };
image.onerror = function() { callback( null ); };
if ( this._crossOrigin !== null ) {
image.crossOrigin = this._crossOrigin;
}
image.src = this._makeURL( z, x, y );
return image; // 要求 ID (実態は Image)
}
/**
*/
override cancelRequest( id: object )
{
// TODO: Image 読み込みの取り消し方法は不明
}
/**
*/
override getImageSize(): number
{
return this._size;
}
/**
*/
override getZoomLevelRange(): ImageProvider.Range
{
return new ImageProvider.Range( this._min_level, this._max_level );
}
/**
* URL を作成
*/
private _makeURL( z: number, x: number, y: number ): string
{
return this._prefix + this._coords_part( z, x, y ) + this._suffix;
}
}
namespace StandardImageProvider {
export interface Option {
/**
* URL の座標順序
*/
coord_order: StandardImageProvider.CoordOrder;
/**
* タイル XY 座標系
*/
coord_system: StandardImageProvider.CoordSystem;
/**
* クレデンシャルモード
*/
credentials: CredentialMode;
}
/**
* @summary URL 座標順序の列挙型
* @desc
* {@link mapray.StandardImageProvider} の構築子で opts.coord_order パラメータに指定する値の型である。
* @enum {object}
* @memberof mapray.StandardImageProvider
* @constant
*/
export enum CoordOrder {
/**
* 座標順序 Z/X/Y (既定値)
*/
ZXY,
/**
* 座標順序 Z/Y/X
*/
ZYX,
/**
* 座標順序 Z/X/Y
*/
XYZ,
};
/**
* @summary タイル XY 座標系の列挙型
* @desc
* {@link mapray.StandardImageProvider} の構築子で opts.coord_system パラメータに指定する値の型である。
* @enum {object}
* @memberof mapray.StandardImageProvider
* @constant
*/
export enum CoordSystem {
/**
* 原点:左上, X軸:右方向, Y軸:下方向 (既定値)
*/
UPPER_LEFT,
/**
* 原点:左下, X軸:右方向, Y軸:上方向
*/
LOWER_LEFT,
};
} // namespace StandardImageProvider
type OrderCoords = ( a: number, b: number, c: number ) => string;
export default StandardImageProvider;