@itwin/map-layers-formats 5.0.0-dev.67 → 5.0.0-dev.69
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/lib/cjs/GoogleMaps/GoogleMapDecorator.d.ts +36 -0
- package/lib/cjs/GoogleMaps/GoogleMapDecorator.d.ts.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMapDecorator.js +83 -0
- package/lib/cjs/GoogleMaps/GoogleMapDecorator.js.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMaps.d.ts +166 -0
- package/lib/cjs/GoogleMaps/GoogleMaps.d.ts.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMaps.js +56 -0
- package/lib/cjs/GoogleMaps/GoogleMaps.js.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryFormat.d.ts +10 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryFormat.d.ts.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryFormat.js +20 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryFormat.js.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.d.ts +25 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.d.ts.map +1 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.js +232 -0
- package/lib/cjs/GoogleMaps/GoogleMapsImageryProvider.js.map +1 -0
- package/lib/cjs/internal/GoogleMapsUtils.d.ts +38 -0
- package/lib/cjs/internal/GoogleMapsUtils.d.ts.map +1 -0
- package/lib/cjs/internal/GoogleMapsUtils.js +104 -0
- package/lib/cjs/internal/GoogleMapsUtils.js.map +1 -0
- package/lib/cjs/map-layers-formats.d.ts +1 -0
- package/lib/cjs/map-layers-formats.d.ts.map +1 -1
- package/lib/cjs/map-layers-formats.js +1 -0
- package/lib/cjs/map-layers-formats.js.map +1 -1
- package/lib/cjs/mapLayersFormats.d.ts.map +1 -1
- package/lib/cjs/mapLayersFormats.js +2 -0
- package/lib/cjs/mapLayersFormats.js.map +1 -1
- package/lib/esm/GoogleMaps/GoogleMapDecorator.d.ts +36 -0
- package/lib/esm/GoogleMaps/GoogleMapDecorator.d.ts.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMapDecorator.js +78 -0
- package/lib/esm/GoogleMaps/GoogleMapDecorator.js.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMaps.d.ts +166 -0
- package/lib/esm/GoogleMaps/GoogleMaps.d.ts.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMaps.js +53 -0
- package/lib/esm/GoogleMaps/GoogleMaps.js.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryFormat.d.ts +10 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryFormat.d.ts.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryFormat.js +16 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryFormat.js.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.d.ts +25 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.d.ts.map +1 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.js +228 -0
- package/lib/esm/GoogleMaps/GoogleMapsImageryProvider.js.map +1 -0
- package/lib/esm/internal/GoogleMapsUtils.d.ts +38 -0
- package/lib/esm/internal/GoogleMapsUtils.d.ts.map +1 -0
- package/lib/esm/internal/GoogleMapsUtils.js +101 -0
- package/lib/esm/internal/GoogleMapsUtils.js.map +1 -0
- package/lib/esm/map-layers-formats.d.ts +1 -0
- package/lib/esm/map-layers-formats.d.ts.map +1 -1
- package/lib/esm/map-layers-formats.js +1 -0
- package/lib/esm/map-layers-formats.js.map +1 -1
- package/lib/esm/mapLayersFormats.d.ts.map +1 -1
- package/lib/esm/mapLayersFormats.js +2 -0
- package/lib/esm/mapLayersFormats.js.map +1 -1
- package/lib/public/images/google_on_non_white.png +0 -0
- package/lib/public/images/google_on_non_white_hdpi.png +0 -0
- package/lib/public/images/google_on_white.png +0 -0
- package/lib/public/images/google_on_white_hdpi.png +0 -0
- package/package.json +12 -12
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
/** @packageDocumentation
|
|
7
|
+
* @module MapLayersFormats
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.GoogleMapsImageryProvider = void 0;
|
|
11
|
+
const core_frontend_1 = require("@itwin/core-frontend");
|
|
12
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
13
|
+
const GoogleMapDecorator_1 = require("./GoogleMapDecorator");
|
|
14
|
+
const GoogleMapsUtils_1 = require("../internal/GoogleMapsUtils");
|
|
15
|
+
const loggerCategory = "MapLayersFormats.GoogleMaps";
|
|
16
|
+
const levelToken = "{level}";
|
|
17
|
+
const rowToken = "{row}";
|
|
18
|
+
const columnToken = "{column}";
|
|
19
|
+
const urlTemplate = `https://tile.googleapis.com/v1/2dtiles/${levelToken}/${columnToken}/${rowToken}`;
|
|
20
|
+
/*
|
|
21
|
+
* Google Maps imagery provider
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
class GoogleMapsImageryProvider extends core_frontend_1.MapLayerImageryProvider {
|
|
25
|
+
_decorator;
|
|
26
|
+
_hadUnrecoverableError = false;
|
|
27
|
+
_tileSize = 256;
|
|
28
|
+
constructor(settings) {
|
|
29
|
+
super(settings, true);
|
|
30
|
+
this._decorator = new GoogleMapDecorator_1.GoogleMapsDecorator();
|
|
31
|
+
}
|
|
32
|
+
static validateUrlTemplate(template) {
|
|
33
|
+
return { status: (template.indexOf(levelToken) > 0 && template.indexOf(columnToken) > 0 && template.indexOf(rowToken) > 0) ? core_frontend_1.MapLayerSourceStatus.Valid : core_frontend_1.MapLayerSourceStatus.InvalidUrl };
|
|
34
|
+
}
|
|
35
|
+
async createSession() {
|
|
36
|
+
const sessionOptions = this.createCreateSessionOptions();
|
|
37
|
+
if (this._settings.accessKey) {
|
|
38
|
+
// Create session and store in query parameters
|
|
39
|
+
const sessionObj = await GoogleMapsUtils_1.GoogleMapsUtils.createSession(this._settings.accessKey.value, sessionOptions);
|
|
40
|
+
this._settings.unsavedQueryParams = { session: sessionObj.session };
|
|
41
|
+
return sessionObj;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
core_bentley_1.Logger.logError(loggerCategory, `Missing GoogleMaps api key`);
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
get tileSize() { return this._tileSize; }
|
|
49
|
+
async initialize() {
|
|
50
|
+
const layerPropertyKeys = this._settings.properties ? Object.keys(this._settings.properties) : undefined;
|
|
51
|
+
if (layerPropertyKeys === undefined ||
|
|
52
|
+
!layerPropertyKeys.includes("mapType") ||
|
|
53
|
+
!layerPropertyKeys.includes("language") ||
|
|
54
|
+
!layerPropertyKeys.includes("region")) {
|
|
55
|
+
const msg = "Missing session options";
|
|
56
|
+
core_bentley_1.Logger.logError(loggerCategory, msg);
|
|
57
|
+
throw new core_bentley_1.BentleyError(core_bentley_1.BentleyStatus.ERROR, msg);
|
|
58
|
+
}
|
|
59
|
+
const session = await this.createSession();
|
|
60
|
+
if (!session) {
|
|
61
|
+
const msg = `Failed to create session`;
|
|
62
|
+
core_bentley_1.Logger.logError(loggerCategory, msg);
|
|
63
|
+
throw new core_bentley_1.BentleyError(core_bentley_1.BentleyStatus.ERROR, msg);
|
|
64
|
+
}
|
|
65
|
+
this._tileSize = session.tileWidth; // assuming here tiles are square
|
|
66
|
+
const isActivated = await this._decorator.activate(this._settings.properties.mapType);
|
|
67
|
+
if (!isActivated) {
|
|
68
|
+
const msg = `Failed to activate decorator`;
|
|
69
|
+
core_bentley_1.Logger.logError(loggerCategory, msg);
|
|
70
|
+
throw new core_bentley_1.BentleyError(core_bentley_1.BentleyStatus.ERROR, msg);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
createCreateSessionOptions() {
|
|
74
|
+
const layerPropertyKeys = this._settings.properties ? Object.keys(this._settings.properties) : undefined;
|
|
75
|
+
if (layerPropertyKeys === undefined ||
|
|
76
|
+
!layerPropertyKeys.includes("mapType") ||
|
|
77
|
+
!layerPropertyKeys.includes("language") ||
|
|
78
|
+
!layerPropertyKeys.includes("region")) {
|
|
79
|
+
const msg = "Missing session options";
|
|
80
|
+
core_bentley_1.Logger.logError(loggerCategory, msg);
|
|
81
|
+
throw new core_bentley_1.BentleyError(core_bentley_1.BentleyStatus.ERROR, msg);
|
|
82
|
+
}
|
|
83
|
+
const createSessionOptions = {
|
|
84
|
+
mapType: this._settings.properties.mapType,
|
|
85
|
+
region: this._settings.properties.region,
|
|
86
|
+
language: this._settings.properties.language,
|
|
87
|
+
};
|
|
88
|
+
if (this._settings.properties?.layerTypes !== undefined) {
|
|
89
|
+
createSessionOptions.layerTypes = this._settings.properties.layerTypes;
|
|
90
|
+
}
|
|
91
|
+
if (this._settings.properties?.scale !== undefined) {
|
|
92
|
+
createSessionOptions.scale = this._settings.properties.scale;
|
|
93
|
+
}
|
|
94
|
+
if (this._settings.properties?.overlay !== undefined) {
|
|
95
|
+
createSessionOptions.overlay = this._settings.properties.overlay;
|
|
96
|
+
}
|
|
97
|
+
if (this._settings.properties?.apiOptions !== undefined) {
|
|
98
|
+
createSessionOptions.apiOptions = this._settings.properties.apiOptions;
|
|
99
|
+
}
|
|
100
|
+
return createSessionOptions;
|
|
101
|
+
}
|
|
102
|
+
// construct the Url from the desired Tile
|
|
103
|
+
async constructUrl(row, column, level) {
|
|
104
|
+
const tmpUrl = urlTemplate.replace(levelToken, level.toString()).replace(columnToken, column.toString()).replace(rowToken, row.toString());
|
|
105
|
+
const obj = new URL(tmpUrl);
|
|
106
|
+
if (this._settings.accessKey) {
|
|
107
|
+
obj.searchParams.append("key", this._settings.accessKey.value);
|
|
108
|
+
}
|
|
109
|
+
// We assume the 'session' param to be already part of the query parameters (checked in initialize)
|
|
110
|
+
return this.appendCustomParams(obj.toString());
|
|
111
|
+
}
|
|
112
|
+
async fetchAttributions(tiles) {
|
|
113
|
+
const zooms = new Set();
|
|
114
|
+
const matchingAttributions = [];
|
|
115
|
+
// Viewport info requests must be made for a specific zoom level
|
|
116
|
+
tiles.forEach((tile) => zooms.add(tile.depth));
|
|
117
|
+
for (const zoom of zooms) {
|
|
118
|
+
let cartoRect;
|
|
119
|
+
for (const tile of tiles) {
|
|
120
|
+
if (tile.depth === zoom && tile instanceof core_frontend_1.MapTile) {
|
|
121
|
+
const extent = this.getEPSG4326Extent(tile.quadId.row, tile.quadId.column, tile.depth);
|
|
122
|
+
const rect = core_frontend_1.MapCartoRectangle.fromDegrees(extent.longitudeLeft, extent.latitudeBottom, extent.longitudeRight, extent.latitudeTop);
|
|
123
|
+
if (cartoRect)
|
|
124
|
+
cartoRect.union(rect);
|
|
125
|
+
else
|
|
126
|
+
cartoRect = rect;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (cartoRect) {
|
|
130
|
+
try {
|
|
131
|
+
const viewportInfo = await GoogleMapsUtils_1.GoogleMapsUtils.getViewportInfo({
|
|
132
|
+
rectangle: cartoRect,
|
|
133
|
+
session: this._settings.collectQueryParams().session,
|
|
134
|
+
key: this._settings.accessKey.value,
|
|
135
|
+
zoom
|
|
136
|
+
});
|
|
137
|
+
if (viewportInfo?.copyright) {
|
|
138
|
+
matchingAttributions.push(viewportInfo.copyright);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading viewport info: ${error?.message ?? "Unknown error"}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return matchingAttributions;
|
|
147
|
+
}
|
|
148
|
+
async logJsonError(tileResponse) {
|
|
149
|
+
try {
|
|
150
|
+
const error = await tileResponse.json();
|
|
151
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading tile: ${error?.message}`);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async loadTile(row, column, zoomLevel) {
|
|
158
|
+
if (this._hadUnrecoverableError)
|
|
159
|
+
return undefined;
|
|
160
|
+
try {
|
|
161
|
+
let tileUrl = await this.constructUrl(row, column, zoomLevel);
|
|
162
|
+
let tileResponse = await this.makeTileRequest(tileUrl);
|
|
163
|
+
if (!tileResponse.ok) {
|
|
164
|
+
if (tileResponse.headers.get("content-type")?.includes("application/json")) {
|
|
165
|
+
// Session might have expired, lets try to re-new it.
|
|
166
|
+
const isSessionCreated = await this.createSession();
|
|
167
|
+
if (isSessionCreated) {
|
|
168
|
+
tileUrl = await this.constructUrl(row, column, zoomLevel);
|
|
169
|
+
tileResponse = await this.makeTileRequest(tileUrl);
|
|
170
|
+
if (!tileResponse.ok) {
|
|
171
|
+
if (tileResponse.headers.get("content-type")?.includes("application/json")) {
|
|
172
|
+
await this.logJsonError(tileResponse);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);
|
|
176
|
+
}
|
|
177
|
+
this._hadUnrecoverableError = true; // Prevent from doing more invalid requests
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
await this.logJsonError(tileResponse);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return await this.getImageFromTileResponse(tileResponse, zoomLevel);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
if (error?.code === 401) {
|
|
194
|
+
core_bentley_1.Logger.logError(loggerCategory, `Authorize to load tile: ${error.message}`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading tile: ${error.message}`);
|
|
198
|
+
}
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
decorate(context) {
|
|
203
|
+
this._decorator.decorate(context);
|
|
204
|
+
}
|
|
205
|
+
getSelectedTiles(vp) {
|
|
206
|
+
return core_frontend_1.IModelApp.tileAdmin.getTilesForUser(vp)?.selected;
|
|
207
|
+
}
|
|
208
|
+
async addAttributions(cards, vp) {
|
|
209
|
+
let copyrightMsg = "";
|
|
210
|
+
const tiles = this.getSelectedTiles(vp);
|
|
211
|
+
if (tiles) {
|
|
212
|
+
try {
|
|
213
|
+
const attrList = await this.fetchAttributions(tiles);
|
|
214
|
+
for (const attr of attrList) {
|
|
215
|
+
attr.split(",").forEach((line) => {
|
|
216
|
+
copyrightMsg += `${copyrightMsg.length === 0 ? "" : "<br"}${line}`;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
core_bentley_1.Logger.logError(loggerCategory, `Error while loading attributions: ${error?.message ?? "Unknown error"}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
cards.appendChild(core_frontend_1.IModelApp.makeLogoCard({
|
|
225
|
+
iconSrc: `${core_frontend_1.IModelApp.publicPath}images/google_on_white_hdpi.png`,
|
|
226
|
+
heading: "Google Maps",
|
|
227
|
+
notice: copyrightMsg
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
exports.GoogleMapsImageryProvider = GoogleMapsImageryProvider;
|
|
232
|
+
//# sourceMappingURL=GoogleMapsImageryProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleMapsImageryProvider.js","sourceRoot":"","sources":["../../../src/GoogleMaps/GoogleMapsImageryProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module MapLayersFormats\n */\n\nimport { ImageMapLayerSettings, ImageSource } from \"@itwin/core-common\";\nimport { DecorateContext, IModelApp, MapCartoRectangle, MapLayerImageryProvider, MapLayerSourceStatus, MapLayerSourceValidation, MapTile, ScreenViewport, Tile } from \"@itwin/core-frontend\";\nimport { GoogleMapsCreateSessionOptions, GoogleMapsLayerTypes, GoogleMapsMapTypes, GoogleMapsScaleFactors, GoogleMapsSession } from \"./GoogleMaps\";\nimport { BentleyError, BentleyStatus, Logger } from \"@itwin/core-bentley\";\nimport { GoogleMapsDecorator } from \"./GoogleMapDecorator\";\nimport { GoogleMapsUtils } from \"../internal/GoogleMapsUtils\";\nconst loggerCategory = \"MapLayersFormats.GoogleMaps\";\nconst levelToken = \"{level}\";\nconst rowToken = \"{row}\";\nconst columnToken = \"{column}\";\n\nconst urlTemplate = `https://tile.googleapis.com/v1/2dtiles/${levelToken}/${columnToken}/${rowToken}`;\n\n/*\n* Google Maps imagery provider\n* @internal\n*/\nexport class GoogleMapsImageryProvider extends MapLayerImageryProvider {\n\n private _decorator: GoogleMapsDecorator;\n private _hadUnrecoverableError = false;\n private _tileSize = 256\n constructor(settings: ImageMapLayerSettings) {\n super(settings, true);\n this._decorator = new GoogleMapsDecorator();\n }\n public static validateUrlTemplate(template: string): MapLayerSourceValidation {\n return { status: (template.indexOf(levelToken) > 0 && template.indexOf(columnToken) > 0 && template.indexOf(rowToken) > 0) ? MapLayerSourceStatus.Valid : MapLayerSourceStatus.InvalidUrl };\n }\n\n protected async createSession() : Promise<GoogleMapsSession|undefined> {\n const sessionOptions = this.createCreateSessionOptions();\n if (this._settings.accessKey ) {\n // Create session and store in query parameters\n const sessionObj = await GoogleMapsUtils.createSession(this._settings.accessKey.value, sessionOptions);\n this._settings.unsavedQueryParams = {session: sessionObj.session};\n return sessionObj;\n } else {\n Logger.logError(loggerCategory, `Missing GoogleMaps api key`);\n return undefined;\n }\n }\n public override get tileSize(): number { return this._tileSize; }\n\n public override async initialize(): Promise<void> {\n\n const layerPropertyKeys = this._settings.properties ? Object.keys(this._settings.properties) : undefined;\n if (layerPropertyKeys === undefined ||\n !layerPropertyKeys.includes(\"mapType\") ||\n !layerPropertyKeys.includes(\"language\") ||\n !layerPropertyKeys.includes(\"region\")) {\n const msg = \"Missing session options\";\n Logger.logError(loggerCategory, msg);\n throw new BentleyError(BentleyStatus.ERROR, msg);\n }\n\n const session = await this.createSession();\n if (!session) {\n const msg = `Failed to create session`;\n Logger.logError(loggerCategory, msg);\n throw new BentleyError(BentleyStatus.ERROR, msg);\n }\n this._tileSize = session.tileWidth; // assuming here tiles are square\n\n const isActivated = await this._decorator.activate(this._settings.properties!.mapType as GoogleMapsMapTypes);\n if (!isActivated) {\n const msg = `Failed to activate decorator`;\n Logger.logError(loggerCategory, msg);\n throw new BentleyError(BentleyStatus.ERROR, msg);\n }\n }\n\n private createCreateSessionOptions(): GoogleMapsCreateSessionOptions {\n const layerPropertyKeys = this._settings.properties ? Object.keys(this._settings.properties) : undefined;\n if (layerPropertyKeys === undefined ||\n !layerPropertyKeys.includes(\"mapType\") ||\n !layerPropertyKeys.includes(\"language\") ||\n !layerPropertyKeys.includes(\"region\")) {\n const msg = \"Missing session options\";\n Logger.logError(loggerCategory, msg);\n throw new BentleyError(BentleyStatus.ERROR, msg);\n }\n\n const createSessionOptions: GoogleMapsCreateSessionOptions = {\n mapType: this._settings.properties!.mapType as GoogleMapsMapTypes,\n region: this._settings.properties!.region as string,\n language: this._settings.properties!.language as string,\n }\n\n if (this._settings.properties?.layerTypes !== undefined) {\n createSessionOptions.layerTypes = this._settings.properties.layerTypes as GoogleMapsLayerTypes[];\n }\n\n if (this._settings.properties?.scale !== undefined) {\n createSessionOptions.scale = this._settings.properties.scale as GoogleMapsScaleFactors;\n }\n\n if (this._settings.properties?.overlay !== undefined) {\n createSessionOptions.overlay = this._settings.properties.overlay as boolean;\n }\n\n if (this._settings.properties?.apiOptions !== undefined) {\n createSessionOptions.apiOptions = this._settings.properties.apiOptions as string[];\n }\n return createSessionOptions;\n }\n\n // construct the Url from the desired Tile\n public async constructUrl(row: number, column: number, level: number): Promise<string> {\n const tmpUrl = urlTemplate.replace(levelToken, level.toString()).replace(columnToken, column.toString()).replace(rowToken, row.toString());\n const obj = new URL(tmpUrl);\n if (this._settings.accessKey ) {\n obj.searchParams.append(\"key\", this._settings.accessKey.value);\n }\n\n // We assume the 'session' param to be already part of the query parameters (checked in initialize)\n return this.appendCustomParams(obj.toString());\n }\n\n private async fetchAttributions(tiles: Set<Tile>): Promise<string[]> {\n const zooms = new Set<number>();\n const matchingAttributions: string[] = [];\n\n // Viewport info requests must be made for a specific zoom level\n tiles.forEach((tile) => zooms.add(tile.depth));\n\n for (const zoom of zooms) {\n let cartoRect: MapCartoRectangle|undefined;\n for (const tile of tiles) {\n if (tile.depth === zoom && tile instanceof MapTile) {\n const extent = this.getEPSG4326Extent(tile.quadId.row, tile.quadId.column, tile.depth);\n const rect = MapCartoRectangle.fromDegrees(extent.longitudeLeft, extent.latitudeBottom, extent.longitudeRight, extent.latitudeTop)\n if (cartoRect)\n cartoRect.union(rect);\n else\n cartoRect = rect;\n }\n }\n if (cartoRect) {\n try {\n const viewportInfo = await GoogleMapsUtils.getViewportInfo({\n rectangle: cartoRect,\n session: this._settings.collectQueryParams().session,\n key: this._settings.accessKey!.value,\n zoom});\n if (viewportInfo?.copyright) {\n matchingAttributions.push(viewportInfo.copyright);\n }\n } catch (error:any) {\n Logger.logError(loggerCategory, `Error while loading viewport info: ${error?.message??\"Unknown error\"}`);\n }\n }\n }\n\n return matchingAttributions;\n }\n private async logJsonError(tileResponse: Response) {\n try {\n const error = await tileResponse.json();\n Logger.logError(loggerCategory, `Error while loading tile: ${error?.message}`);\n } catch {\n Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);\n }\n }\n\n public override async loadTile(row: number, column: number, zoomLevel: number): Promise<ImageSource | undefined> {\n if (this._hadUnrecoverableError)\n return undefined;\n\n try {\n let tileUrl: string = await this.constructUrl(row, column, zoomLevel);\n let tileResponse: Response = await this.makeTileRequest(tileUrl);\n if (!tileResponse.ok) {\n if (tileResponse.headers.get(\"content-type\")?.includes(\"application/json\")) {\n // Session might have expired, lets try to re-new it.\n const isSessionCreated = await this.createSession();\n if (isSessionCreated) {\n tileUrl = await this.constructUrl(row, column, zoomLevel);\n tileResponse = await this.makeTileRequest(tileUrl);\n if (!tileResponse.ok) {\n if (tileResponse.headers.get(\"content-type\")?.includes(\"application/json\")) {\n await this.logJsonError(tileResponse);\n } else {\n Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);\n }\n this._hadUnrecoverableError = true; // Prevent from doing more invalid requests\n return undefined;\n }\n } else {\n await this.logJsonError(tileResponse);\n }\n } else {\n Logger.logError(loggerCategory, `Error while loading tile: ${tileResponse.statusText}`);\n return undefined;\n }\n }\n return await this.getImageFromTileResponse(tileResponse, zoomLevel);\n } catch (error: any) {\n if (error?.code === 401) {\n Logger.logError(loggerCategory, `Authorize to load tile: ${error.message}`);\n } else {\n Logger.logError(loggerCategory, `Error while loading tile: ${error.message}`);\n }\n return undefined;\n }\n }\n\n public override decorate(context: DecorateContext): void {\n this._decorator.decorate(context);\n }\n\n private getSelectedTiles(vp: ScreenViewport) {\n return IModelApp.tileAdmin.getTilesForUser(vp)?.selected\n }\n\n public override async addAttributions (cards: HTMLTableElement, vp: ScreenViewport): Promise<void> {\n let copyrightMsg = \"\";\n const tiles = this.getSelectedTiles(vp);\n if (tiles) {\n try {\n const attrList = await this.fetchAttributions(tiles);\n for (const attr of attrList) {\n attr.split(\",\").forEach((line) => {\n copyrightMsg += `${copyrightMsg.length===0 ? \"\": \"<br\"}${line}`;\n });\n }\n }\n catch (error: any) {\n Logger.logError(loggerCategory, `Error while loading attributions: ${error?.message??\"Unknown error\"}`);\n }\n }\n\n cards.appendChild(IModelApp.makeLogoCard({\n iconSrc: `${IModelApp.publicPath}images/google_on_white_hdpi.png`,\n heading: \"Google Maps\",\n notice: copyrightMsg }));\n }\n\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ImageMapLayerProps, MapLayerProviderProperties } from "@itwin/core-common";
|
|
2
|
+
import { GoogleMapsCreateSessionOptions, GoogleMapsSession, ViewportInfo, ViewportInfoRequestParams } from "../GoogleMaps/GoogleMaps";
|
|
3
|
+
/** @internal */
|
|
4
|
+
export declare const GoogleMapsUtils: {
|
|
5
|
+
/**
|
|
6
|
+
* Creates a Google Maps session.
|
|
7
|
+
* @param apiKey Google Cloud API key
|
|
8
|
+
* @param opts Options to create the session
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
createSession: (apiKey: string, opts: GoogleMapsCreateSessionOptions) => Promise<GoogleMapsSession>;
|
|
12
|
+
/**
|
|
13
|
+
* Register the google maps format if it is not already registered.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
checkFormatRegistered: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a Google Maps layer props.
|
|
19
|
+
* @param name Name of the layer (Defaults to "GoogleMaps")
|
|
20
|
+
* @param opts Options to create the session (Defaults to satellite map type, English language, US region, and roadmap layer type)
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
createMapLayerProps: (name?: string, opts?: GoogleMapsCreateSessionOptions) => ImageMapLayerProps;
|
|
24
|
+
/**
|
|
25
|
+
* Retrieves the maximum zoom level available within a bounding rectangle.
|
|
26
|
+
* @param rectangle The bounding rectangle
|
|
27
|
+
* @returns The maximum zoom level available within the bounding rectangle.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
getViewportInfo: (params: ViewportInfoRequestParams) => Promise<ViewportInfo | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Converts the session options to provider properties
|
|
33
|
+
* @param opts Options to create the session
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
createPropertiesFromSessionOptions: (opts: GoogleMapsCreateSessionOptions) => MapLayerProviderProperties;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=GoogleMapsUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleMapsUtils.d.ts","sourceRoot":"","sources":["../../../src/internal/GoogleMapsUtils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEpF,OAAO,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAItI,gBAAgB;AAEhB,eAAO,MAAM,eAAe;IAC1B;;;;;MAKE;4BAC4B,MAAM,QAAQ,8BAA8B,KAAG,OAAO,CAAC,iBAAiB,CAAC;IAWvG;;;MAGE;;IAOF;;;;;IAKA;iCAC4B,MAAM,SAAwB,8BAA8B,KAAG,kBAAkB;IAW7G;;;;;MAKE;8BAC8B,yBAAyB,KAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAgB3F;;;;IAIA;+CACyC,8BAA8B,KAAG,0BAA0B;CAyBvG,CAAA"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.GoogleMapsUtils = void 0;
|
|
8
|
+
const core_frontend_1 = require("@itwin/core-frontend");
|
|
9
|
+
const GoogleMapsImageryFormat_1 = require("../GoogleMaps/GoogleMapsImageryFormat");
|
|
10
|
+
const core_bentley_1 = require("@itwin/core-bentley");
|
|
11
|
+
const core_geometry_1 = require("@itwin/core-geometry");
|
|
12
|
+
const loggerCategory = "MapLayersFormats.GoogleMaps";
|
|
13
|
+
/** @internal */
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
15
|
+
exports.GoogleMapsUtils = {
|
|
16
|
+
/**
|
|
17
|
+
* Creates a Google Maps session.
|
|
18
|
+
* @param apiKey Google Cloud API key
|
|
19
|
+
* @param opts Options to create the session
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
createSession: async (apiKey, opts) => {
|
|
23
|
+
const url = `https://tile.googleapis.com/v1/createSession?key=${apiKey}`;
|
|
24
|
+
const request = new Request(url, { method: "POST", body: JSON.stringify(opts) });
|
|
25
|
+
const response = await fetch(request);
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
throw new Error(`CreateSession request failed: ${response.status} - ${response.statusText}`);
|
|
28
|
+
}
|
|
29
|
+
core_bentley_1.Logger.logInfo(loggerCategory, `Session created successfully`);
|
|
30
|
+
return response.json();
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Register the google maps format if it is not already registered.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
checkFormatRegistered: () => {
|
|
37
|
+
if (!core_frontend_1.IModelApp.mapLayerFormatRegistry.isRegistered(GoogleMapsImageryFormat_1.GoogleMapsMapLayerFormat.formatId)) {
|
|
38
|
+
throw new Error(`GoogleMaps format is not registered`);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Creates a Google Maps layer props.
|
|
43
|
+
* @param name Name of the layer (Defaults to "GoogleMaps")
|
|
44
|
+
* @param opts Options to create the session (Defaults to satellite map type, English language, US region, and roadmap layer type)
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
createMapLayerProps: (name = "GoogleMaps", opts) => {
|
|
48
|
+
exports.GoogleMapsUtils.checkFormatRegistered();
|
|
49
|
+
return {
|
|
50
|
+
formatId: GoogleMapsImageryFormat_1.GoogleMapsMapLayerFormat.formatId,
|
|
51
|
+
url: "",
|
|
52
|
+
name,
|
|
53
|
+
properties: exports.GoogleMapsUtils.createPropertiesFromSessionOptions(opts ?? { mapType: "satellite", language: "en-US", region: "US:", layerTypes: ["layerRoadmap"] }),
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves the maximum zoom level available within a bounding rectangle.
|
|
58
|
+
* @param rectangle The bounding rectangle
|
|
59
|
+
* @returns The maximum zoom level available within the bounding rectangle.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
getViewportInfo: async (params) => {
|
|
63
|
+
const { rectangle, session, key, zoom } = params;
|
|
64
|
+
const north = core_geometry_1.Angle.radiansToDegrees(rectangle.north);
|
|
65
|
+
const south = core_geometry_1.Angle.radiansToDegrees(rectangle.south);
|
|
66
|
+
const east = core_geometry_1.Angle.radiansToDegrees(rectangle.east);
|
|
67
|
+
const west = core_geometry_1.Angle.radiansToDegrees(rectangle.west);
|
|
68
|
+
const url = `https://tile.googleapis.com/tile/v1/viewport?session=${session}&key=${key}&zoom=${zoom}&north=${north}&south=${south}&east=${east}&west=${west}`;
|
|
69
|
+
const request = new Request(url, { method: "GET" });
|
|
70
|
+
const response = await fetch(request);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const json = await response.json();
|
|
75
|
+
return json;
|
|
76
|
+
;
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Converts the session options to provider properties
|
|
80
|
+
* @param opts Options to create the session
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
createPropertiesFromSessionOptions: (opts) => {
|
|
84
|
+
const properties = {
|
|
85
|
+
mapType: opts.mapType,
|
|
86
|
+
language: opts.language,
|
|
87
|
+
region: opts.region,
|
|
88
|
+
};
|
|
89
|
+
if (opts.layerTypes !== undefined) {
|
|
90
|
+
properties.layerTypes = [...opts.layerTypes];
|
|
91
|
+
}
|
|
92
|
+
if (opts.scale !== undefined) {
|
|
93
|
+
properties.scale = opts.scale;
|
|
94
|
+
}
|
|
95
|
+
if (opts.overlay !== undefined) {
|
|
96
|
+
properties.overlay = opts.overlay;
|
|
97
|
+
}
|
|
98
|
+
if (opts.apiOptions !== undefined) {
|
|
99
|
+
properties.apiOptions = [...opts.apiOptions];
|
|
100
|
+
}
|
|
101
|
+
return properties;
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=GoogleMapsUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleMapsUtils.js","sourceRoot":"","sources":["../../../src/internal/GoogleMapsUtils.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,wDAAiD;AACjD,mFAAiF;AACjF,sDAA6C;AAE7C,wDAA6C;AAG7C,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAErD,gBAAgB;AAChB,gEAAgE;AACnD,QAAA,eAAe,GAAG;IAC7B;;;;;MAKE;IACF,aAAa,EAAE,KAAK,EAAE,MAAc,EAAE,IAAoC,EAA8B,EAAE;QACxG,MAAM,GAAG,GAAG,oDAAoD,MAAM,EAAE,CAAC;QACzE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAC,CAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAE,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,qBAAM,CAAC,OAAO,CAAC,cAAc,EAAE,8BAA8B,CAAC,CAAC;QAC/D,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED;;;MAGE;IACF,qBAAqB,EAAE,GAAG,EAAE;QAC1B,IAAI,CAAC,yBAAS,CAAC,sBAAsB,CAAC,YAAY,CAAC,kDAAwB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtF,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;;;;IAKA;IACA,mBAAmB,EAAE,CAAC,OAAe,YAAY,EAAE,IAAqC,EAAsB,EAAE;QAC9G,uBAAe,CAAC,qBAAqB,EAAE,CAAC;QAExC,OAAO;YACL,QAAQ,EAAE,kDAAwB,CAAC,QAAQ;YAC3C,GAAG,EAAE,EAAE;YACP,IAAI;YACJ,UAAU,EAAE,uBAAe,CAAC,kCAAkC,CAAC,IAAI,IAAI,EAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC,EAAC,CAAC;SAC/J,CAAC;IACJ,CAAC;IAED;;;;;MAKE;IACF,eAAe,EAAE,KAAK,EAAE,MAAiC,EAAoC,EAAE;QAC7F,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAC,GAAG,MAAM,CAAC;QAC/C,MAAM,KAAK,GAAG,qBAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,qBAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,qBAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,qBAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,wDAAwD,OAAO,QAAQ,GAAG,SAAS,IAAI,UAAU,KAAK,UAAU,KAAK,SAAS,IAAI,SAAS,IAAI,EAAE,CAAC;QAC9J,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAE,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,IAAoB,CAAC;QAAA,CAAC;IAC/B,CAAC;IAEC;;;;IAIA;IACF,kCAAkC,EAAE,CAAC,IAAoC,EAA8B,EAAE;QACvG,MAAM,UAAU,GAA+B;YAC7C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAA;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,UAAU,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAChC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QACpC,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,UAAU,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAA","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { GoogleMapsMapLayerFormat } from \"../GoogleMaps/GoogleMapsImageryFormat\";\nimport { Logger } from \"@itwin/core-bentley\";\nimport { ImageMapLayerProps, MapLayerProviderProperties } from \"@itwin/core-common\";\nimport { Angle } from \"@itwin/core-geometry\";\nimport { GoogleMapsCreateSessionOptions, GoogleMapsSession, ViewportInfo, ViewportInfoRequestParams } from \"../GoogleMaps/GoogleMaps\";\n\nconst loggerCategory = \"MapLayersFormats.GoogleMaps\";\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const GoogleMapsUtils = {\n /**\n * Creates a Google Maps session.\n * @param apiKey Google Cloud API key\n * @param opts Options to create the session\n * @internal\n */\n createSession: async (apiKey: string, opts: GoogleMapsCreateSessionOptions): Promise<GoogleMapsSession> => {\n const url = `https://tile.googleapis.com/v1/createSession?key=${apiKey}`;\n const request = new Request(url, {method: \"POST\", body: JSON.stringify(opts)});\n const response = await fetch (request);\n if (!response.ok) {\n throw new Error(`CreateSession request failed: ${response.status} - ${response.statusText}`);\n }\n Logger.logInfo(loggerCategory, `Session created successfully`);\n return response.json();\n },\n\n /**\n * Register the google maps format if it is not already registered.\n * @internal\n */\n checkFormatRegistered: () => {\n if (!IModelApp.mapLayerFormatRegistry.isRegistered(GoogleMapsMapLayerFormat.formatId)) {\n throw new Error(`GoogleMaps format is not registered`);\n }\n },\n\n /**\n * Creates a Google Maps layer props.\n * @param name Name of the layer (Defaults to \"GoogleMaps\")\n * @param opts Options to create the session (Defaults to satellite map type, English language, US region, and roadmap layer type)\n * @internal\n*/\n createMapLayerProps: (name: string = \"GoogleMaps\", opts?: GoogleMapsCreateSessionOptions): ImageMapLayerProps => {\n GoogleMapsUtils.checkFormatRegistered();\n\n return {\n formatId: GoogleMapsMapLayerFormat.formatId,\n url: \"\",\n name,\n properties: GoogleMapsUtils.createPropertiesFromSessionOptions(opts ?? {mapType: \"satellite\", language: \"en-US\", region: \"US:\", layerTypes: [\"layerRoadmap\"]}),\n };\n },\n\n /**\n * Retrieves the maximum zoom level available within a bounding rectangle.\n * @param rectangle The bounding rectangle\n * @returns The maximum zoom level available within the bounding rectangle.\n * @internal\n */\n getViewportInfo: async (params: ViewportInfoRequestParams): Promise<ViewportInfo | undefined>=> {\n const {rectangle, session, key, zoom} = params;\n const north = Angle.radiansToDegrees(rectangle.north);\n const south = Angle.radiansToDegrees(rectangle.south);\n const east = Angle.radiansToDegrees(rectangle.east);\n const west = Angle.radiansToDegrees(rectangle.west);\n const url = `https://tile.googleapis.com/tile/v1/viewport?session=${session}&key=${key}&zoom=${zoom}&north=${north}&south=${south}&east=${east}&west=${west}`;\n const request = new Request(url, {method: \"GET\"});\n const response = await fetch (request);\n if (!response.ok) {\n return undefined;\n }\n const json = await response.json();\n return json as ViewportInfo;;\n },\n\n /**\n * Converts the session options to provider properties\n * @param opts Options to create the session\n * @internal\n */\n createPropertiesFromSessionOptions: (opts: GoogleMapsCreateSessionOptions): MapLayerProviderProperties => {\n const properties: MapLayerProviderProperties = {\n mapType: opts.mapType,\n language: opts.language,\n region: opts.region,\n }\n\n if (opts.layerTypes !== undefined) {\n properties.layerTypes = [...opts.layerTypes];\n }\n\n if (opts.scale !== undefined) {\n properties.scale = opts.scale;\n }\n\n if (opts.overlay !== undefined) {\n properties.overlay = opts.overlay;\n }\n\n if (opts.apiOptions !== undefined) {\n properties.apiOptions = [...opts.apiOptions];\n }\n\n return properties;\n },\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./mapLayersFormats";
|
|
2
2
|
export * from "./ArcGisFeature/ArcGisFeatureProvider";
|
|
3
3
|
export * from "./Tools/MapFeatureInfoTool";
|
|
4
|
+
export * from "./GoogleMaps/GoogleMaps";
|
|
4
5
|
/** @docs-package-description
|
|
5
6
|
* This package provides support for additional map layer formats that are not included in the @itwin/core-frontend package.
|
|
6
7
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-layers-formats.d.ts","sourceRoot":"","sources":["../../src/map-layers-formats.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uCAAuC,CAAC;AACtD,cAAc,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"map-layers-formats.d.ts","sourceRoot":"","sources":["../../src/map-layers-formats.ts"],"names":[],"mappings":"AAKA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uCAAuC,CAAC;AACtD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AAExC;;GAEG;AAEH;;GAEG"}
|
|
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
__exportStar(require("./mapLayersFormats"), exports);
|
|
22
22
|
__exportStar(require("./ArcGisFeature/ArcGisFeatureProvider"), exports);
|
|
23
23
|
__exportStar(require("./Tools/MapFeatureInfoTool"), exports);
|
|
24
|
+
__exportStar(require("./GoogleMaps/GoogleMaps"), exports);
|
|
24
25
|
/** @docs-package-description
|
|
25
26
|
* This package provides support for additional map layer formats that are not included in the @itwin/core-frontend package.
|
|
26
27
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-layers-formats.js","sourceRoot":"","sources":["../../src/map-layers-formats.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;;;;;;;;;;;;;;AAE/F,qDAAmC;AACnC,wEAAsD;AACtD,6DAA2C;
|
|
1
|
+
{"version":3,"file":"map-layers-formats.js","sourceRoot":"","sources":["../../src/map-layers-formats.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;;;;;;;;;;;;;;AAE/F,qDAAmC;AACnC,wEAAsD;AACtD,6DAA2C;AAC3C,0DAAwC;AAExC;;GAEG;AAEH;;GAEG","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nexport * from \"./mapLayersFormats\";\nexport * from \"./ArcGisFeature/ArcGisFeatureProvider\";\nexport * from \"./Tools/MapFeatureInfoTool\";\nexport * from \"./GoogleMaps/GoogleMaps\";\n\n/** @docs-package-description\n * This package provides support for additional map layer formats that are not included in the @itwin/core-frontend package.\n */\n\n/** @docs-group-description MapLayersFormats\n * APIs for working with the map layer formats provided by this package.\n */\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapLayersFormats.d.ts","sourceRoot":"","sources":["../../src/mapLayersFormats.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"mapLayersFormats.d.ts","sourceRoot":"","sources":["../../src/mapLayersFormats.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAsB;IAC/C,OAAc,YAAY,EAAE,YAAY,CAAC;IAEzC;;;OAGG;WACiB,UAAU,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9E,kDAAkD;IAClD,WAAkB,qBAAqB,IAAI,MAAM,CAEhD;CAEF"}
|
|
@@ -13,6 +13,7 @@ const core_frontend_1 = require("@itwin/core-frontend");
|
|
|
13
13
|
const ArcGisFeatureFormat_1 = require("./ArcGisFeature/ArcGisFeatureFormat");
|
|
14
14
|
const MapFeatureInfoTool_1 = require("./Tools/MapFeatureInfoTool");
|
|
15
15
|
const OgcApiFeaturesFormat_1 = require("./OgcApiFeatures/OgcApiFeaturesFormat");
|
|
16
|
+
const GoogleMapsImageryFormat_1 = require("./GoogleMaps/GoogleMapsImageryFormat");
|
|
16
17
|
/** The primary API for the `@itwin/map-layers-formats` package. It allows the package's features to be [[initialize]]d.
|
|
17
18
|
* @beta
|
|
18
19
|
*/
|
|
@@ -28,6 +29,7 @@ class MapLayersFormats {
|
|
|
28
29
|
if (core_frontend_1.IModelApp.initialized) {
|
|
29
30
|
core_frontend_1.IModelApp.mapLayerFormatRegistry.register(ArcGisFeatureFormat_1.ArcGisFeatureMapLayerFormat);
|
|
30
31
|
core_frontend_1.IModelApp.mapLayerFormatRegistry.register(OgcApiFeaturesFormat_1.OgcApiFeaturesMapLayerFormat);
|
|
32
|
+
core_frontend_1.IModelApp.mapLayerFormatRegistry.register(GoogleMapsImageryFormat_1.GoogleMapsMapLayerFormat);
|
|
31
33
|
}
|
|
32
34
|
// register namespace containing localized strings for this package
|
|
33
35
|
MapLayersFormats.localization = config?.localization ?? core_frontend_1.IModelApp.localization;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapLayersFormats.js","sourceRoot":"","sources":["../../src/mapLayersFormats.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AACH,sDAA6C;AAC7C,wDAAiD;AACjD,6EAAkF;AAClF,mEAAgE;AAEhE,gFAAqF;
|
|
1
|
+
{"version":3,"file":"mapLayersFormats.js","sourceRoot":"","sources":["../../src/mapLayersFormats.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AACH,sDAA6C;AAC7C,wDAAiD;AACjD,6EAAkF;AAClF,mEAAgE;AAEhE,gFAAqF;AACrF,kFAAgF;AAShF;;GAEG;AACH,MAAa,gBAAgB;IAEnB,MAAM,CAAC,UAAU,GAAG,kBAAkB,CAAC;IACxC,MAAM,CAAC,YAAY,CAAe;IAEzC;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAA+B;QAC5D,IAAA,qBAAM,EAAC,yBAAS,CAAC,WAAW,EAAE,kGAAkG,CAAC,CAAC;QAClI,IAAI,yBAAS,CAAC,WAAW,EAAE,CAAC;YAC1B,yBAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,iDAA2B,CAAC,CAAC;YACvE,yBAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,mDAA4B,CAAC,CAAC;YACxE,yBAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,kDAAwB,CAAC,CAAC;QACtE,CAAC;QAED,mEAAmE;QACnE,gBAAgB,CAAC,YAAY,GAAG,MAAM,EAAE,YAAY,IAAI,yBAAS,CAAC,YAAY,CAAC;QAC/E,MAAM,gBAAgB,CAAC,YAAY,CAAC,iBAAiB,CACnD,gBAAgB,CAAC,qBAAqB,CACvC,CAAC;QAEF,uCAAkB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;IACtE,CAAC;IAED,kDAAkD;IAC3C,MAAM,KAAK,qBAAqB;QACrC,OAAO,gBAAgB,CAAC,UAAU,CAAC;IACrC,CAAC;;AA7BH,4CA+BC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module MapLayersFormats\n */\nimport { assert } from \"@itwin/core-bentley\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { ArcGisFeatureMapLayerFormat } from \"./ArcGisFeature/ArcGisFeatureFormat\";\nimport { MapFeatureInfoTool } from \"./Tools/MapFeatureInfoTool\";\nimport { Localization } from \"@itwin/core-common\";\nimport { OgcApiFeaturesMapLayerFormat } from \"./OgcApiFeatures/OgcApiFeaturesFormat\";\nimport { GoogleMapsMapLayerFormat } from \"./GoogleMaps/GoogleMapsImageryFormat\";\n\n/** Configuration options.\n * @beta\n */\nexport interface MapLayersFormatsConfig {\n localization?: Localization;\n}\n\n/** The primary API for the `@itwin/map-layers-formats` package. It allows the package's features to be [[initialize]]d.\n * @beta\n */\nexport class MapLayersFormats {\n\n private static _defaultNs = \"mapLayersFormats\";\n public static localization: Localization;\n\n /** Registers the [MapLayerFormat]($frontend)s provided by this package for use with [IModelApp]($frontend).\n * Typically, an application will call `MapLayersFormats.initialize` immediately after [IModelApp.startup]($frontend).\n * This function has no effect if called **before** [IModelApp.startup]($frontend) or **after** [IModelApp.shutdown]($frontend).\n */\n public static async initialize(config?: MapLayersFormatsConfig): Promise<void> {\n assert(IModelApp.initialized, \"MapLayersFormats.initialize must be called after IModelApp.startup and before IModelApp.shutdown\");\n if (IModelApp.initialized) {\n IModelApp.mapLayerFormatRegistry.register(ArcGisFeatureMapLayerFormat);\n IModelApp.mapLayerFormatRegistry.register(OgcApiFeaturesMapLayerFormat);\n IModelApp.mapLayerFormatRegistry.register(GoogleMapsMapLayerFormat);\n }\n\n // register namespace containing localized strings for this package\n MapLayersFormats.localization = config?.localization ?? IModelApp.localization;\n await MapLayersFormats.localization.registerNamespace(\n MapLayersFormats.localizationNamespace,\n );\n\n MapFeatureInfoTool.register(MapLayersFormats.localizationNamespace);\n }\n\n /** The internationalization service namespace. */\n public static get localizationNamespace(): string {\n return MapLayersFormats._defaultNs;\n }\n\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CanvasDecoration, DecorateContext, Decorator, Sprite } from "@itwin/core-frontend";
|
|
2
|
+
import { Point3d } from "@itwin/core-geometry";
|
|
3
|
+
import { GoogleMapsMapTypes } from "./GoogleMaps";
|
|
4
|
+
/** A simple decorator that show logo at the a given screen position.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare class LogoDecoration implements CanvasDecoration {
|
|
8
|
+
private _sprite?;
|
|
9
|
+
/** The current position of the logo in view coordinates. */
|
|
10
|
+
readonly position: Point3d;
|
|
11
|
+
private _offset;
|
|
12
|
+
set offset(offset: Point3d | undefined);
|
|
13
|
+
/** The logo offset in view coordinates.*/
|
|
14
|
+
get offset(): Point3d | undefined;
|
|
15
|
+
/** Move the logo to the lower left corner of the screen. */
|
|
16
|
+
moveToLowerLeftCorner(context: DecorateContext): boolean;
|
|
17
|
+
/** Indicate if the logo is loaded and ready to be drawn. */
|
|
18
|
+
get isLoaded(): boolean;
|
|
19
|
+
activate(sprite: Sprite): Promise<boolean>;
|
|
20
|
+
/** Draw this sprite onto the supplied canvas.
|
|
21
|
+
* @see [[CanvasDecoration.drawDecoration]]
|
|
22
|
+
*/
|
|
23
|
+
drawDecoration(ctx: CanvasRenderingContext2D): void;
|
|
24
|
+
decorate(context: DecorateContext): void;
|
|
25
|
+
}
|
|
26
|
+
/** A decorator that adds the Google Maps logo to the lower left corner of the screen.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export declare class GoogleMapsDecorator implements Decorator {
|
|
30
|
+
readonly logo: LogoDecoration;
|
|
31
|
+
/** Activate the logo based on the given map type. */
|
|
32
|
+
activate(mapType: GoogleMapsMapTypes): Promise<boolean>;
|
|
33
|
+
/** Decorate implementation */
|
|
34
|
+
decorate: (context: DecorateContext) => void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=GoogleMapDecorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleMapDecorator.d.ts","sourceRoot":"","sources":["../../../src/GoogleMaps/GoogleMapDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAA0B,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACpH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD;;GAEG;AACH,qBAAa,cAAe,YAAW,gBAAgB;IACrD,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,4DAA4D;IAC5D,SAAgB,QAAQ,UAAiB;IAEzC,OAAO,CAAC,OAAO,CAAoB;IAEnC,IAAW,MAAM,CAAC,MAAM,EAAE,OAAO,GAAC,SAAS,EAExC;IAEH,0CAA0C;IAC1C,IAAW,MAAM,IALS,OAAO,GAAC,SAAS,CAO1C;IAED,4DAA4D;IACrD,qBAAqB,CAAC,OAAO,EAAE,eAAe,GAAI,OAAO;IAahE,4DAA4D;IAC5D,IAAW,QAAQ,YAA8C;IAEpD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWvD;;OAEG;IACI,cAAc,CAAC,GAAG,EAAE,wBAAwB,GAAG,IAAI;IAOnD,QAAQ,CAAC,OAAO,EAAE,eAAe;CAGzC;AAED;;EAEE;AACF,qBAAa,mBAAoB,YAAW,SAAS;IACnD,SAAgB,IAAI,iBAAwB;IAE5C,qDAAqD;IACxC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAYpE,8BAA8B;IACvB,QAAQ,YAAa,eAAe,UAKzC;CACH"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { IconSprites, IModelApp } from "@itwin/core-frontend";
|
|
2
|
+
import { Point3d } from "@itwin/core-geometry";
|
|
3
|
+
/** A simple decorator that show logo at the a given screen position.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export class LogoDecoration {
|
|
7
|
+
_sprite;
|
|
8
|
+
/** The current position of the logo in view coordinates. */
|
|
9
|
+
position = new Point3d();
|
|
10
|
+
_offset;
|
|
11
|
+
set offset(offset) {
|
|
12
|
+
this._offset = offset;
|
|
13
|
+
}
|
|
14
|
+
/** The logo offset in view coordinates.*/
|
|
15
|
+
get offset() {
|
|
16
|
+
return this._offset;
|
|
17
|
+
}
|
|
18
|
+
/** Move the logo to the lower left corner of the screen. */
|
|
19
|
+
moveToLowerLeftCorner(context) {
|
|
20
|
+
if (!this._sprite || !this._sprite.isLoaded)
|
|
21
|
+
return false;
|
|
22
|
+
this.position.x = this._offset?.x ?? 0;
|
|
23
|
+
this.position.y = context.viewport.parentDiv.clientHeight - this._sprite.size.y;
|
|
24
|
+
if (this._offset?.y)
|
|
25
|
+
this.position.y -= this._offset.y;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
/* TODO: Add other move methods as needed */
|
|
29
|
+
/** Indicate if the logo is loaded and ready to be drawn. */
|
|
30
|
+
get isLoaded() { return this._sprite?.isLoaded ?? false; }
|
|
31
|
+
async activate(sprite) {
|
|
32
|
+
this._sprite = sprite;
|
|
33
|
+
return new Promise((resolve, _reject) => {
|
|
34
|
+
sprite.loadPromise.then(() => {
|
|
35
|
+
resolve(true);
|
|
36
|
+
}).catch(() => {
|
|
37
|
+
resolve(false);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/** Draw this sprite onto the supplied canvas.
|
|
42
|
+
* @see [[CanvasDecoration.drawDecoration]]
|
|
43
|
+
*/
|
|
44
|
+
drawDecoration(ctx) {
|
|
45
|
+
if (this.isLoaded) {
|
|
46
|
+
// Draw image with an origin at the top left corner
|
|
47
|
+
ctx.drawImage(this._sprite.image, 0, 0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
decorate(context) {
|
|
51
|
+
context.addCanvasDecoration(this);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** A decorator that adds the Google Maps logo to the lower left corner of the screen.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
export class GoogleMapsDecorator {
|
|
58
|
+
logo = new LogoDecoration();
|
|
59
|
+
/** Activate the logo based on the given map type. */
|
|
60
|
+
async activate(mapType) {
|
|
61
|
+
// Pick the logo that is the most visible on the background map
|
|
62
|
+
const imageName = mapType === "roadmap" ?
|
|
63
|
+
"google_on_white" :
|
|
64
|
+
"google_on_non_white";
|
|
65
|
+
// We need to move the logo right after the 'i.js' button
|
|
66
|
+
this.logo.offset = new Point3d(45, 10);
|
|
67
|
+
return this.logo.activate(IconSprites.getSpriteFromUrl(`${IModelApp.publicPath}images/${imageName}.png`));
|
|
68
|
+
}
|
|
69
|
+
;
|
|
70
|
+
/** Decorate implementation */
|
|
71
|
+
decorate = (context) => {
|
|
72
|
+
if (!this.logo.isLoaded)
|
|
73
|
+
return;
|
|
74
|
+
this.logo.moveToLowerLeftCorner(context);
|
|
75
|
+
this.logo.decorate(context);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=GoogleMapDecorator.js.map
|