mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 09:12:52 +00:00
Merge branch 'jgravois-tilemap'
This commit is contained in:
@@ -26,6 +26,15 @@ export function rendererBackground(context) {
|
||||
|
||||
|
||||
function background(selection) {
|
||||
// If we are displaying an Esri basemap at high zoom,
|
||||
// check its tilemap to see how high the zoom can go
|
||||
if (context.map().zoom() > 18) {
|
||||
var basemap = baseLayer.source();
|
||||
if (basemap && /^EsriWorldImagery/.test(basemap.id)) {
|
||||
var center = context.map().center();
|
||||
basemap.fetchTilemap(center);
|
||||
}
|
||||
}
|
||||
|
||||
var baseFilter = '';
|
||||
if (detected.cssfilters) {
|
||||
@@ -114,16 +123,17 @@ export function rendererBackground(context) {
|
||||
background.updateImagery = function() {
|
||||
if (context.inIntro()) return;
|
||||
|
||||
var b = background.baseLayerSource(),
|
||||
o = _overlayLayers
|
||||
.filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
|
||||
.map(function (d) { return d.source().id; })
|
||||
.join(','),
|
||||
meters = geoOffsetToMeters(b.offset()),
|
||||
epsilon = 0.01,
|
||||
x = +meters[0].toFixed(2),
|
||||
y = +meters[1].toFixed(2),
|
||||
q = utilStringQs(window.location.hash.substring(1));
|
||||
var b = background.baseLayerSource();
|
||||
var o = _overlayLayers
|
||||
.filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
|
||||
.map(function (d) { return d.source().id; })
|
||||
.join(',');
|
||||
|
||||
var meters = geoOffsetToMeters(b.offset());
|
||||
var epsilon = 0.01;
|
||||
var x = +meters[0].toFixed(2);
|
||||
var y = +meters[1].toFixed(2);
|
||||
var q = utilStringQs(window.location.hash.substring(1));
|
||||
|
||||
var id = b.id;
|
||||
if (id === 'custom') {
|
||||
@@ -215,13 +225,12 @@ export function rendererBackground(context) {
|
||||
if (!osm) return background;
|
||||
|
||||
var blacklists = context.connection().imageryBlacklists();
|
||||
var template = d.template();
|
||||
var fail = false;
|
||||
var tested = 0;
|
||||
var regex;
|
||||
|
||||
var template = d.template(),
|
||||
fail = false,
|
||||
tested = 0,
|
||||
regex, i;
|
||||
|
||||
for (i = 0; i < blacklists.length; i++) {
|
||||
for (var i = 0; i < blacklists.length; i++) {
|
||||
try {
|
||||
regex = new RegExp(blacklists[i]);
|
||||
fail = regex.test(template);
|
||||
@@ -270,7 +279,6 @@ export function rendererBackground(context) {
|
||||
|
||||
background.toggleOverlayLayer = function(d) {
|
||||
var layer;
|
||||
|
||||
for (var i = 0; i < _overlayLayers.length; i++) {
|
||||
layer = _overlayLayers[i];
|
||||
if (layer.source() === d) {
|
||||
@@ -350,12 +358,12 @@ export function rendererBackground(context) {
|
||||
return geoExtent([args[2], args[1]]);
|
||||
}
|
||||
|
||||
var dataImagery = data.imagery || [],
|
||||
q = utilStringQs(window.location.hash.substring(1)),
|
||||
requested = q.background || q.layer,
|
||||
extent = parseMap(q.map),
|
||||
first,
|
||||
best;
|
||||
var dataImagery = data.imagery || [];
|
||||
var q = utilStringQs(window.location.hash.substring(1));
|
||||
var requested = q.background || q.layer;
|
||||
var extent = parseMap(q.map);
|
||||
var first;
|
||||
var best;
|
||||
|
||||
// Add all the available imagery sources
|
||||
_backgroundSources = dataImagery.map(function(source) {
|
||||
|
||||
@@ -6,8 +6,16 @@ import {
|
||||
geoMercatorRaw as d3_geoMercatorRaw
|
||||
} from 'd3-geo';
|
||||
|
||||
import { json as d3_json } from 'd3-request';
|
||||
|
||||
import { t } from '../util/locale';
|
||||
import { geoExtent, geoPolygonIntersectsPolygon } from '../geo';
|
||||
|
||||
import {
|
||||
geoExtent,
|
||||
geoPolygonIntersectsPolygon,
|
||||
geoSphericalDistance
|
||||
} from '../geo';
|
||||
|
||||
import { jsonpRequest } from '../util/jsonp_request';
|
||||
import { utilDetect } from '../util/detect';
|
||||
|
||||
@@ -109,19 +117,20 @@ export function rendererBackgroundSource(data) {
|
||||
var lat = Math.atan(sinh(Math.PI * (1 - 2 * y / zoomSize)));
|
||||
|
||||
switch (this.projection) {
|
||||
case 'EPSG:4326': // todo: alternative codes of WGS 84?
|
||||
return {
|
||||
x: lon * 180 / Math.PI,
|
||||
y: lat * 180 / Math.PI
|
||||
};
|
||||
default: // EPSG:3857 and synonyms
|
||||
var mercCoords = d3_geoMercatorRaw(lon, lat);
|
||||
return {
|
||||
x: 20037508.34 / Math.PI * mercCoords[0],
|
||||
y: 20037508.34 / Math.PI * mercCoords[1]
|
||||
};
|
||||
case 'EPSG:4326': // todo: alternative codes of WGS 84?
|
||||
return {
|
||||
x: lon * 180 / Math.PI,
|
||||
y: lat * 180 / Math.PI
|
||||
};
|
||||
default: // EPSG:3857 and synonyms
|
||||
var mercCoords = d3_geoMercatorRaw(lon, lat);
|
||||
return {
|
||||
x: 20037508.34 / Math.PI * mercCoords[0],
|
||||
y: 20037508.34 / Math.PI * mercCoords[1]
|
||||
};
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
var minXmaxY = tileToProjectedCoords(coord[0], coord[1], coord[2]);
|
||||
var maxXminY = tileToProjectedCoords(coord[0]+1, coord[1]+1, coord[2]);
|
||||
return template
|
||||
@@ -205,13 +214,13 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
|
||||
data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
|
||||
|
||||
var bing = rendererBackgroundSource(data),
|
||||
key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
|
||||
url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
|
||||
key + '&jsonp={callback}',
|
||||
cache = {},
|
||||
inflight = {},
|
||||
providers = [];
|
||||
var bing = rendererBackgroundSource(data);
|
||||
var key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU'; // Same as P2 and JOSM
|
||||
var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
|
||||
key + '&jsonp={callback}';
|
||||
var cache = {};
|
||||
var inflight = {};
|
||||
var providers = [];
|
||||
|
||||
jsonpRequest(url, function(json) {
|
||||
providers = json.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
|
||||
@@ -244,10 +253,10 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
|
||||
|
||||
bing.getMetadata = function(center, tileCoord, callback) {
|
||||
var tileId = tileCoord.slice(0, 3).join('/'),
|
||||
zoom = Math.min(tileCoord[2], 21),
|
||||
centerPoint = center[1] + ',' + center[0], // lat,lng
|
||||
url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
|
||||
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 +
|
||||
'?zl=' + zoom + '&key=' + key + '&jsonp={callback}';
|
||||
|
||||
if (inflight[tileId]) return;
|
||||
@@ -290,25 +299,57 @@ rendererBackgroundSource.Bing = function(data, dispatch) {
|
||||
|
||||
|
||||
rendererBackgroundSource.Esri = function(data) {
|
||||
var esri = rendererBackgroundSource(data);
|
||||
var cache = {};
|
||||
var inflight = {};
|
||||
var _prevCenter;
|
||||
|
||||
// don't request blank tiles, instead overzoom real tiles - #4327
|
||||
// deprecated technique, but it works (for now)
|
||||
if (data.template.match(/blankTile/) === null) {
|
||||
data.template = data.template + '?blankTile=false';
|
||||
}
|
||||
// use a tilemap service to set maximum zoom for esri tiles dynamically
|
||||
// https://developers.arcgis.com/documentation/tiled-elevation-service/
|
||||
esri.fetchTilemap = function(center) {
|
||||
// skip if we have already fetched a tilemap within 5km
|
||||
if (_prevCenter && geoSphericalDistance(center, _prevCenter) < 5000) return;
|
||||
_prevCenter = center;
|
||||
|
||||
var esri = rendererBackgroundSource(data),
|
||||
cache = {},
|
||||
inflight = {};
|
||||
// tiles are available globally to zoom level 19, afterward they may or may not be present
|
||||
var z = 20;
|
||||
|
||||
// first generate a random url using the template
|
||||
var dummyUrl = esri.url([1,2,3]);
|
||||
|
||||
// calculate url z/y/x from the lat/long of the center of the map
|
||||
var x = (Math.floor((center[0] + 180) / 360 * Math.pow(2, z)));
|
||||
var y = (Math.floor((1 - Math.log(Math.tan(center[1] * Math.PI / 180) + 1 / Math.cos(center[1] * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, z)));
|
||||
|
||||
// fetch an 8x8 grid because responses to leverage cache
|
||||
var tilemapUrl = dummyUrl.replace(/tile\/[0-9]+\/[0-9]+\/[0-9]+/, 'tilemap') + '/' + z + '/' + y + ' /' + x + '/8/8';
|
||||
|
||||
// make the request and introspect the response from the tilemap server
|
||||
d3_json(tilemapUrl, function (err, tilemap) {
|
||||
if (err || !tilemap) return;
|
||||
|
||||
var hasTiles = true;
|
||||
for (var i = 0; i < tilemap.data.length; i++) {
|
||||
// 0 means an individual tile in the grid doesn't exist
|
||||
if (!tilemap.data[i]) {
|
||||
hasTiles = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if any tiles are missing at level 20 we restrict maxZoom to 19
|
||||
esri.scaleExtent[1] = (hasTiles ? 20 : 19);
|
||||
});
|
||||
};
|
||||
|
||||
esri.getMetadata = function(center, tileCoord, callback) {
|
||||
var tileId = tileCoord.slice(0, 3).join('/'),
|
||||
zoom = Math.min(tileCoord[2], esri.scaleExtent[1]),
|
||||
centerPoint = center[0] + ',' + center[1], // long, lat (as it should be)
|
||||
unknown = t('info_panels.background.unknown'),
|
||||
metadataLayer,
|
||||
vintage = {},
|
||||
metadata = {};
|
||||
var tileId = tileCoord.slice(0, 3).join('/');
|
||||
var zoom = Math.min(tileCoord[2], esri.scaleExtent[1]);
|
||||
var centerPoint = center[0] + ',' + center[1]; // long, lat (as it should be)
|
||||
var unknown = t('info_panels.background.unknown');
|
||||
var metadataLayer;
|
||||
var vintage = {};
|
||||
var metadata = {};
|
||||
|
||||
if (inflight[tileId]) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user