Update bing imagery key and api urls. Interval limiting for tiles vintage (#9133)

update bing imagery key, template, api url
BasicMetadata for vintage
handled 429 in getMetadata
This commit is contained in:
Milos Brzakovic
2022-05-25 18:49:35 +02:00
committed by GitHub
parent 29f3693cbe
commit 66c5007fc2
3 changed files with 71 additions and 26 deletions
+2
View File
@@ -65,6 +65,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
* Allow searching presets by their tag (`key=value`) ([#8869])
#### Other
* Redact more API tokens from custom imagery sources in changeset metadata tags ([#8976], thanks [@k-yle])
* New Bing imagery API key and limit tiles vintage API requests ([#9133], thanks [@mbrzakovic])
#### :hammer: Development
* Switch build system to [esbuild](https://esbuild.github.io/) for much faster builds ([#8774], thanks [@mbrzakovic] and [@bhousel])
* Upgrade some dependencies: maki to `v7.1`, `fontawesome` to `v6.1`, `d3` to `v7.3`, `node-diff` to `v3.1`, `mocha` to `v9.2`, `svg-sprite` to `v1.5.4`, `marked` to `v4.0`
@@ -86,6 +87,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
[#9102]: https://github.com/openstreetmap/iD/issues/9102
[#9118]: https://github.com/openstreetmap/iD/issues/9118
[#9124]: https://github.com/openstreetmap/iD/pull/9124
[#9133]: https://github.com/openstreetmap/iD/pull/9133
[@wcedmisten]: https://github.com/wcedmisten
+34 -26
View File
@@ -6,7 +6,7 @@ import { t, localizer } from '../core/localizer';
import { geoExtent, geoSphericalDistance } from '../geo';
import { utilQsString, utilStringQs } from '../util';
import { utilAesDecrypt } from '../util/aes';
import { IntervalTasksQueue } from '../util/IntervalTasksQueue';
var isRetina = window.devicePixelRatio && window.devicePixelRatio >= 2;
@@ -265,12 +265,10 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
// https://docs.microsoft.com/en-us/bingmaps/rest-services/directly-accessing-the-bing-maps-tiles
//fallback url template
data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&n=z';
data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=1&pr=odbl&n=z';
var bing = rendererBackgroundSource(data);
//var key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU'; // P2, JOSM, etc
var key = 'Ak5oTE46TUbjRp08OFVcGpkARErDobfpuyNKa-W2mQ8wbt1K1KL8p1bIRwWwcF-Q'; // iD
var key = utilAesDecrypt('5c875730b09c6b422433e807e1ff060b6536c791dbfffcffc4c6b18a1bdba1f14593d151adb50e19e1be1ab19aef813bf135d0f103475e5c724dec94389e45d0');
/*
missing tile image strictness param (n=)
• n=f -> (Fail) returns a 404
@@ -279,10 +277,12 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
*/
const strictParam = 'n';
var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&uriScheme=https&key=' + key;
var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/AerialOSM?include=ImageryProviders&uriScheme=https&key=' + key;
var cache = {};
var inflight = {};
var providers = [];
var taskQueue = new IntervalTasksQueue(250);
var metadataLastZoom = -1;
d3_json(url)
.then(function(json) {
@@ -337,7 +337,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
var tileID = tileCoord.slice(0, 3).join('/');
var zoom = Math.min(tileCoord[2], 21);
var centerPoint = center[1] + ',' + center[0]; // lat,lng
var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
var url = 'https://dev.virtualearth.net/REST/v1/Imagery/BasicMetadata/AerialOSM/' + centerPoint +
'?zl=' + zoom + '&key=' + key;
if (inflight[tileID]) return;
@@ -350,26 +350,34 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
}
inflight[tileID] = true;
d3_json(url)
.then(function(result) {
delete inflight[tileID];
if (!result) {
throw new Error('Unknown Error');
}
var vintage = {
start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
};
vintage.range = vintageRange(vintage);
var metadata = { vintage: vintage };
cache[tileID].metadata = metadata;
if (callback) callback(null, metadata);
})
.catch(function(err) {
delete inflight[tileID];
if (callback) callback(err.message);
});
if (metadataLastZoom !== tileCoord[2]){
metadataLastZoom = tileCoord[2];
taskQueue.clear();
}
taskQueue.enqueue(() => {
d3_json(url)
.then(function (result) {
delete inflight[tileID];
if (!result) {
throw new Error('Unknown Error');
}
var vintage = {
start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
};
vintage.range = vintageRange(vintage);
var metadata = { vintage: vintage };
cache[tileID].metadata = metadata;
if (callback) callback(null, metadata);
})
.catch(function (err) {
delete inflight[tileID];
if (callback) callback(err.message);
});
});
};
+35
View File
@@ -0,0 +1,35 @@
/**
* IntervalTasksQueue
* Enabled task execution under interval limit
*/
export class IntervalTasksQueue {
/**
* Interval in milliseconds inside which only 1 task can execute.
* e.g. if interval is 200ms, and 5 async tasks are unqueued,
* they will complete in ~1s if not cleared
* @param {number} intervalInMs
*/
constructor(intervalInMs) {
this.intervalInMs = intervalInMs;
this.pendingHandles = [];
this.time = 0;
}
enqueue(task) {
let taskTimeout = this.time;
this.time += this.intervalInMs;
this.pendingHandles.push(setTimeout(() => {
this.time -= this.intervalInMs;
task();
}, taskTimeout));
}
clear() {
this.pendingHandles.forEach((timeoutHandle) => {
clearTimeout(timeoutHandle);
});
this.pendingHandles = [];
this.time = 0;
}
}