|
// |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}),global.d3)); |
|
}(this, function (exports) { 'use strict'; |
|
|
|
|
|
function geoTile() { |
|
|
|
// Basic Constants |
|
const tau = Math.PI * 2; |
|
const lim = 85.05113; |
|
|
|
// Map Properties: |
|
var w = 960; |
|
var h = 500; |
|
|
|
// Projection Values: |
|
var pk = w/tau; // projection scale k |
|
var px = w/2; // projection translate x |
|
var py = h/2; // projection translate y |
|
var pc = [0,0] // projection geographic center |
|
|
|
// Zoom Transform Values: |
|
var tk = 1; // zoom transform scale k |
|
var tx = 0; // zoom transform translate x |
|
var ty = 0; // zoom transform translate y |
|
|
|
// The Projection: |
|
var p = d3.geoMercator() |
|
.scale(pk) |
|
.translate([px,py]) |
|
.center(pc); |
|
|
|
// Tile wrapping: |
|
var W = true; |
|
|
|
// Tile source & attribution |
|
var source = function(d) { |
|
return "http://" + "abc"[d.y % 3] + ".tile.openstreetmap.org/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
var a = "Tiles © OpenStreetMap contributors"; |
|
|
|
function geoTile(_) { |
|
return p(_); |
|
} |
|
|
|
// General Methods |
|
geoTile.width = function(_) { |
|
return arguments.length ? (w = _, geoTile) : w; |
|
} |
|
geoTile.height = function(_) { |
|
return arguments.length ? (h = _, geoTile) : h; |
|
} |
|
geoTile.size = function(_) { |
|
if(arguments.length) { |
|
(_ instanceof d3.selection) ? (w = _.attr("width"), h = _.attr("height")) : (w = _[0], h = _[1]); |
|
return geoTile; |
|
} |
|
else return [w,h] |
|
} |
|
geoTile.source = function(_) { |
|
return arguments.length ? (source = _, geoTile) : source; |
|
} |
|
geoTile.projection = function() { |
|
return p; |
|
} |
|
geoTile.attribution = function(_) { |
|
return arguments.length ? (a = _, geoTile) : a; |
|
} |
|
geoTile.wrap = function(_) { |
|
return arguments.length ? (W = _, geoTile) : W; |
|
} |
|
|
|
|
|
// Standard Projection methods: |
|
geoTile.invert = function(_) { |
|
return p.invert(_); |
|
} |
|
geoTile.center = function(_) { |
|
return arguments.length ? (pc = _, p.center(pc), geoTile): pc; |
|
} |
|
geoTile.scale = function(_) { |
|
return arguments.length ? (pk = _, p.scale(pk), geoTile) : pk; |
|
} |
|
geoTile.translate = function(_) { |
|
return arguments.length ? (px = _[0], py = _[1], p.translate([px,py]), geoTile) : [px,py] |
|
} |
|
geoTile.fit = function(_) { |
|
return arguments.length ? (p.fitSize([w,h],_),px = p.translate()[0],py = p.translate()[1],pk = p.scale(), geoTile) : "n/a"; |
|
} |
|
geoTile.fitExtent = function(e,f) { |
|
return arguments.length > 1 ? (p.fitExtent(e,f),px = p.translate()[0],py = p.translate()[1],pk = p.scale(), geoTile) : "n/a"; |
|
} |
|
geoTile.fitMargin = function(m,f) { |
|
return arguments.length > 1 ? (p.fitExtent([[m,m],[w-m,h-m]],f), px = p.translate()[0],py = p.translate()[1],pk = p.scale(), geoTile) : "n/a"; |
|
} |
|
|
|
// Zoom Methods: |
|
geoTile.zoomScale = function(_) { |
|
return arguments.length ? (tk = _, p.scale(pk*tk), geoTile) : tk; |
|
} |
|
geoTile.zoomTranslate = function(_) { |
|
return arguments.length ? (tx = _[0], ty = _[1], p.translate([tx, ty]), geoTile): [tx,ty] |
|
} |
|
geoTile.zoomIdentity = function() { |
|
return d3.zoomIdentity.translate(px,py).scale(tk).translate(0,0); |
|
} |
|
geoTile.zoomTransform = function(t) { |
|
tx = t.x, ty = t.y, tk = t.k; p.translate([tx,ty]); p.scale(pk*tk); return geoTile; |
|
} |
|
|
|
// Tile Methods: |
|
// Calculate Tiles: |
|
geoTile.tiles = function() { |
|
var size = pk * tk * tau; |
|
var z = Math.max(Math.log(size) / Math.LN2 - 8, 0); // z, assuming image size of 256. |
|
var s = Math.pow(2, z - Math.round(z) + 8); |
|
|
|
var y0 = p([-180,lim])[1]; |
|
var x0 = p([-180,lim])[0]; |
|
|
|
var set = []; |
|
var cStart = Math.max(0, Math.floor((0 - x0) / s)); |
|
var cEnd = Math.max(0, Math.ceil((w - x0) / s)); |
|
var rStart = Math.max(0,Math.floor((0 - y0) / s)); |
|
var rEnd = Math.max(0, Math.ceil((h - y0) / s)); |
|
|
|
for(var i = cStart; i < cEnd; i++) { |
|
for(var j = rStart; j < rEnd; j++) { |
|
set.push({x:i,y:j,z:Math.round(z),id:i+"-"+j+"-"+z}) |
|
} |
|
} |
|
|
|
set.translate = [x0 / s, y0 / s]; |
|
set.scale = s; |
|
|
|
return set; |
|
|
|
} |
|
// Assign Tiles to a Selection: |
|
geoTile.tile = function(g) { |
|
|
|
var set = geoTile.tiles(); |
|
var images = g.attr("transform", stringify(set.scale, set.translate)) |
|
.selectAll("image") |
|
.data(set, function(d) { return d.id; }) |
|
|
|
images.exit().remove(); |
|
images.enter().append("image").merge(images) |
|
.attr("xlink:href", source ) |
|
.attr("x", function(d) { return d.x * 256; }) |
|
.attr("y", function(d) { return d.y * 256; }) |
|
.attr("width", 256) |
|
.attr("height", 256); |
|
} |
|
|
|
// Helper stringify |
|
function stringify(scale, translate) { |
|
var k = scale / 256, r = scale % 1 ? Number : Math.round; |
|
return "translate(" + r(translate[0] * scale) + "," + r(translate[1] * scale) + ") scale(" + k + ")"; |
|
} |
|
|
|
// To break out in the future, at least use switch ?: |
|
geoTile.tileSet = function(_) { |
|
// CartoDB: |
|
if(_ == "CartoDB_Positron") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/light_all/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_PositronNoLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/light_nolabels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_PositronOnlyLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/light_only_labels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_DarkMatter") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/dark_all/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_DarkMatterNoLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/dark_nolabels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_DarkMatterOnlyLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/dark_only_labels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_Voyager") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/rastertiles/voyager/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
/* else if(_ == "CartoDB_VoyagerNoLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/rastertiles/voyager-nolabels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if(_ == "CartoDB_VoyagerOnlyLabels") { |
|
a = "© OpenStreetMap © CartoDB"; |
|
source = function(d) { |
|
return "https://cartodb-basemaps-b.global.ssl.fastly.net/rastertiles/voyager-only_labels/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} */ |
|
|
|
// ESRI |
|
else if(_ == "ESRI_WorldTerrain") { |
|
a = "Tiles © Esri - Source: USGS, Esri, TANA, DeLorme, and NPS" |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_WorldShadedRelief") { |
|
a = "Tiles © Esri - Source: Esri"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_WorldPhysical") { |
|
a = "Tiles © Esri - Source: US National Park Service"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_WorldStreetMap") { |
|
a = "Tiles © Esri - Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_WorldTopoMap") { |
|
a = "Tiles © Esri - Source: Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_WorldImagery") { |
|
a = "Tiles © Esri - Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_OceanBasemap") { |
|
a = "Tiles © Esri - Source: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_NGWorld") { |
|
a = "Tiles © Esri - Source: National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
else if (_ == "ESRI_Gray") { |
|
a = "Tiles © Esri - Source: Esri, DeLorme, NAVTEQ"; |
|
source = function(d) { |
|
return "https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/"+d.z+"/"+d.y+"/"+d.x+".png"; |
|
} |
|
} |
|
|
|
// OSM |
|
else if (_ == "OSM_Topo") { |
|
a = "Tiles © OpenStreetMap contributors"; |
|
source = function(d) { |
|
return "https://tile.opentopomap.org/"+d.z+"/"+d.x+"/"+d.y+".png"; |
|
} |
|
} |
|
else if (_ == "OSM") { |
|
a = "Tiles © OpenStreetMap contributors"; |
|
source = function(d) { |
|
return "https://" + "abc"[d.y % 3] + ".tile.openstreetmap.org/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
|
|
|
|
// STAMEN |
|
else if (_ == "Stamen_Toner") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/toner/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_TonerBackground") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/toner-background/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_TonerLines") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/toner-lines/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_TonerLite") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/toner-lite/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_Terrain") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/terrain/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_TerrainBackground") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/terrain-background/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_TerrainLines") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/terrain-lines/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
else if (_ == "Stamen_Watercolor") { |
|
a = "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA." |
|
source = function(d) { |
|
return "https://stamen-tiles.a.ssl.fastly.net/watercolor/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
|
|
else { |
|
// Default: |
|
console.log("Unknown Tileset, using OSM"); |
|
a = "Tiles © OpenStreetMap contributors"; |
|
source = function(d) { |
|
return "http://" + "abc"[d.y % 3] + ".tile.openstreetmap.org/" + d.z + "/" + d.x + "/" + d.y + ".png"; |
|
} |
|
} |
|
|
|
return geoTile; |
|
} |
|
|
|
return geoTile; |
|
|
|
} |
|
|
|
exports.geoTile = geoTile; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
})); |