-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathImageTileLoader.ts
117 lines (100 loc) · 4 KB
/
ImageTileLoader.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
import {Observable, Subscriber} from "rxjs";
/**
* @class ImageTileLoader
*
* @classdesc Represents a loader of image tiles.
*/
export class ImageTileLoader {
private _origin: string;
private _scheme: string;
private _host: string;
/**
* Create a new node image tile loader instance.
*
* @param {string} scheme - The URI scheme.
* @param {string} host - The URI host.
* @param {string} [origin] - The origin query param.
*/
constructor(scheme: string, host: string, origin?: string) {
this._scheme = scheme;
this._host = host;
this._origin = origin != null ? `?origin=${origin}` : "";
}
/**
* Retrieve an image tile.
*
* @description Retrieve an image tile by specifying the area
* as well as the scaled size.
*
* @param {string} identifier - The identifier of the image.
* @param {number} x - The top left x pixel coordinate for the tile
* in the original image.
* @param {number} y - The top left y pixel coordinate for the tile
* in the original image.
* @param {number} w - The pixel width of the tile in the original image.
* @param {number} h - The pixel height of the tile in the original image.
* @param {number} scaledW - The scaled width of the returned tile.
* @param {number} scaledH - The scaled height of the returned tile.
*/
public getTile(
identifier: string,
x: number,
y: number,
w: number,
h: number,
scaledW: number,
scaledH: number): [Observable<HTMLImageElement>, Function] {
let characteristics: string = `/${identifier}/${x},${y},${w},${h}/${scaledW},${scaledH}/0/default.jpg`;
let url: string =
this._scheme +
"://" +
this._host +
characteristics +
this._origin;
let xmlHTTP: XMLHttpRequest = null;
return [Observable.create(
(subscriber: Subscriber<HTMLImageElement>): void => {
xmlHTTP = new XMLHttpRequest();
xmlHTTP.open("GET", url, true);
xmlHTTP.responseType = "arraybuffer";
xmlHTTP.timeout = 15000;
xmlHTTP.onload = (event: Event) => {
if (xmlHTTP.status !== 200) {
subscriber.error(
new Error(
`Failed to fetch tile (${identifier}: ${x},${y},${w},${h}). ` +
`Status: ${xmlHTTP.status}, ${xmlHTTP.statusText}`));
return;
}
let image: HTMLImageElement = new Image();
image.crossOrigin = "Anonymous";
image.onload = (e: Event) => {
subscriber.next(image);
subscriber.complete();
};
image.onerror = (error: ErrorEvent) => {
subscriber.error(new Error(`Failed to load tile image (${identifier}: ${x},${y},${w},${h})`));
};
let blob: Blob = new Blob([xmlHTTP.response]);
image.src = window.URL.createObjectURL(blob);
};
xmlHTTP.onerror = (error: Event) => {
subscriber.error(new Error(`Failed to fetch tile (${identifier}: ${x},${y},${w},${h})`));
};
xmlHTTP.ontimeout = (error: Event) => {
subscriber.error(new Error(`Tile request timed out (${identifier}: ${x},${y},${w},${h})`));
};
xmlHTTP.onabort = (event: Event) => {
subscriber.error(new Error(`Tile request was aborted (${identifier}: ${x},${y},${w},${h})`));
};
xmlHTTP.send(null);
}),
(): void => {
if (xmlHTTP != null) {
xmlHTTP.abort();
}
},
];
}
}
export default ImageTileLoader;