leaflet-providers.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. (function () {
  2. 'use strict';
  3. L.TileLayer.Provider = L.TileLayer.extend({
  4. initialize: function (arg, options) {
  5. var providers = L.TileLayer.Provider.providers;
  6. var parts = arg.split('.');
  7. var providerName = parts[0];
  8. var variantName = parts[1];
  9. if (!providers[providerName]) {
  10. throw 'No such provider (' + providerName + ')';
  11. }
  12. var provider = {
  13. url: providers[providerName].url,
  14. options: providers[providerName].options
  15. };
  16. // overwrite values in provider from variant.
  17. if (variantName && 'variants' in providers[providerName]) {
  18. if (!(variantName in providers[providerName].variants)) {
  19. throw 'No such name in provider (' + variantName + ')';
  20. }
  21. var variant = providers[providerName].variants[variantName];
  22. provider = {
  23. url: variant.url || provider.url,
  24. options: L.Util.extend({}, provider.options, variant.options)
  25. };
  26. } else if (typeof provider.url === 'function') {
  27. provider.url = provider.url(parts.splice(1, parts.length - 1).join('.'));
  28. }
  29. // replace attribution placeholders with their values from toplevel provider attribution,
  30. // recursively
  31. var attributionReplacer = function (attr) {
  32. if (attr.indexOf('{attribution.') === -1) {
  33. return attr;
  34. }
  35. return attr.replace(/\{attribution.(\w*)\}/,
  36. function (match, attributionName) {
  37. return attributionReplacer(providers[attributionName].options.attribution);
  38. }
  39. );
  40. };
  41. provider.options.attribution = attributionReplacer(provider.options.attribution);
  42. // Compute final options combining provider options with any user overrides
  43. var layerOpts = L.Util.extend({}, provider.options, options);
  44. L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts);
  45. }
  46. });
  47. /**
  48. * Definition of providers.
  49. * see http://leafletjs.com/reference.html#tilelayer for options in the options map.
  50. */
  51. //jshint maxlen:220
  52. L.TileLayer.Provider.providers = {
  53. OpenStreetMap: {
  54. url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  55. options: {
  56. attribution:
  57. '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
  58. '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
  59. },
  60. variants: {
  61. Mapnik: {},
  62. BlackAndWhite: {
  63. url: 'http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png'
  64. },
  65. DE: {
  66. url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png'
  67. },
  68. HOT: {
  69. url: 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
  70. options: {
  71. attribution: '{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
  72. }
  73. }
  74. }
  75. },
  76. OpenCycleMap: {
  77. url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
  78. options: {
  79. attribution:
  80. '&copy; <a href="http://www.opencyclemap.org">OpenCycleMap</a>, {attribution.OpenStreetMap}'
  81. }
  82. },
  83. OpenSeaMap: {
  84. url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
  85. options: {
  86. attribution: 'Map data: &copy; <a href="http://www.openseamap.org">OpenSeaMap</a> contributors'
  87. }
  88. },
  89. Thunderforest: {
  90. url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
  91. options: {
  92. attribution: '{attribution.OpenCycleMap}'
  93. },
  94. variants: {
  95. OpenCycleMap: {},
  96. Transport: {
  97. url: 'http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png'
  98. },
  99. Landscape: {
  100. url: 'http://{s}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png'
  101. },
  102. Outdoors: {
  103. url: 'http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png'
  104. }
  105. }
  106. },
  107. OpenMapSurfer: {
  108. url: 'http://openmapsurfer.uni-hd.de/tiles/roads/x={x}&y={y}&z={z}',
  109. options: {
  110. attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> &mdash; Map data {attribution.OpenStreetMap}'
  111. },
  112. variants: {
  113. Roads: {},
  114. AdminBounds: {
  115. url: 'http://openmapsurfer.uni-hd.de/tiles/adminb/x={x}&y={y}&z={z}'
  116. },
  117. Grayscale: {
  118. url: 'http://openmapsurfer.uni-hd.de/tiles/roadsg/x={x}&y={y}&z={z}'
  119. }
  120. }
  121. },
  122. MapQuestOpen: {
  123. url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpeg',
  124. options: {
  125. attribution:
  126. 'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> &mdash; ' +
  127. 'Map data {attribution.OpenStreetMap}',
  128. subdomains: '1234'
  129. },
  130. variants: {
  131. OSM: {},
  132. Aerial: {
  133. url: 'http://oatile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg',
  134. options: {
  135. attribution:
  136. 'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> &mdash; ' +
  137. 'Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency'
  138. }
  139. }
  140. }
  141. },
  142. MapBox: {
  143. url: function (id) {
  144. return 'http://{s}.tiles.mapbox.com/v3/' + id + '/{z}/{x}/{y}.png';
  145. },
  146. options: {
  147. attribution:
  148. 'Imagery from <a href="http://mapbox.com/about/maps/">MapBox</a> &mdash; ' +
  149. 'Map data {attribution.OpenStreetMap}',
  150. subdomains: 'abcd'
  151. }
  152. },
  153. Stamen: {
  154. url: 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png',
  155. options: {
  156. attribution:
  157. 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, ' +
  158. '<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; ' +
  159. 'Map data {attribution.OpenStreetMap}',
  160. subdomains: 'abcd',
  161. minZoom: 0,
  162. maxZoom: 20
  163. },
  164. variants: {
  165. Toner: {},
  166. TonerBackground: {
  167. url: 'http://{s}.tile.stamen.com/toner-background/{z}/{x}/{y}.png'
  168. },
  169. TonerHybrid: {
  170. url: 'http://{s}.tile.stamen.com/toner-hybrid/{z}/{x}/{y}.png'
  171. },
  172. TonerLines: {
  173. url: 'http://{s}.tile.stamen.com/toner-lines/{z}/{x}/{y}.png'
  174. },
  175. TonerLabels: {
  176. url: 'http://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.png'
  177. },
  178. TonerLite: {
  179. url: 'http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png'
  180. },
  181. Terrain: {
  182. url: 'http://{s}.tile.stamen.com/terrain/{z}/{x}/{y}.jpg',
  183. options: {
  184. minZoom: 4,
  185. maxZoom: 18
  186. }
  187. },
  188. TerrainBackground: {
  189. url: 'http://{s}.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg',
  190. options: {
  191. minZoom: 4,
  192. maxZoom: 18
  193. }
  194. },
  195. Watercolor: {
  196. url: 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg',
  197. options: {
  198. minZoom: 3,
  199. maxZoom: 16
  200. }
  201. }
  202. }
  203. },
  204. Esri: {
  205. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
  206. options: {
  207. attribution: 'Tiles &copy; Esri'
  208. },
  209. variants: {
  210. WorldStreetMap: {
  211. options: {
  212. attribution:
  213. '{attribution.Esri} &mdash; ' +
  214. 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
  215. }
  216. },
  217. DeLorme: {
  218. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer/tile/{z}/{y}/{x}',
  219. options: {
  220. minZoom: 1,
  221. maxZoom: 11,
  222. attribution: '{attribution.Esri} &mdash; Copyright: &copy;2012 DeLorme'
  223. }
  224. },
  225. WorldTopoMap: {
  226. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
  227. options: {
  228. attribution:
  229. '{attribution.Esri} &mdash; ' +
  230. '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'
  231. }
  232. },
  233. WorldImagery: {
  234. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
  235. options: {
  236. attribution:
  237. '{attribution.Esri} &mdash; ' +
  238. 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
  239. }
  240. },
  241. WorldTerrain: {
  242. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
  243. options: {
  244. maxZoom: 13,
  245. attribution:
  246. '{attribution.Esri} &mdash; ' +
  247. 'Source: USGS, Esri, TANA, DeLorme, and NPS'
  248. }
  249. },
  250. WorldShadedRelief: {
  251. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
  252. options: {
  253. maxZoom: 13,
  254. attribution: '{attribution.Esri} &mdash; Source: Esri'
  255. }
  256. },
  257. WorldPhysical: {
  258. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
  259. options: {
  260. maxZoom: 8,
  261. attribution: '{attribution.Esri} &mdash; Source: US National Park Service'
  262. }
  263. },
  264. OceanBasemap: {
  265. url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}',
  266. options: {
  267. maxZoom: 13,
  268. attribution: '{attribution.Esri} &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'
  269. }
  270. },
  271. NatGeoWorldMap: {
  272. url: 'http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
  273. options: {
  274. maxZoom: 16,
  275. attribution: '{attribution.Esri} &mdash; National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC'
  276. }
  277. },
  278. WorldGrayCanvas: {
  279. url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
  280. options: {
  281. maxZoom: 16,
  282. attribution: '{attribution.Esri} &mdash; Esri, DeLorme, NAVTEQ'
  283. }
  284. }
  285. }
  286. },
  287. OpenWeatherMap: {
  288. options: {
  289. attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
  290. opacity: 0.5
  291. },
  292. variants: {
  293. Clouds: {
  294. url: 'http://{s}.tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png'
  295. },
  296. CloudsClassic: {
  297. url: 'http://{s}.tile.openweathermap.org/map/clouds_cls/{z}/{x}/{y}.png'
  298. },
  299. Precipitation: {
  300. url: 'http://{s}.tile.openweathermap.org/map/precipitation/{z}/{x}/{y}.png'
  301. },
  302. PrecipitationClassic: {
  303. url: 'http://{s}.tile.openweathermap.org/map/precipitation_cls/{z}/{x}/{y}.png'
  304. },
  305. Rain: {
  306. url: 'http://{s}.tile.openweathermap.org/map/rain/{z}/{x}/{y}.png'
  307. },
  308. RainClassic: {
  309. url: 'http://{s}.tile.openweathermap.org/map/rain_cls/{z}/{x}/{y}.png'
  310. },
  311. Pressure: {
  312. url: 'http://{s}.tile.openweathermap.org/map/pressure/{z}/{x}/{y}.png'
  313. },
  314. PressureContour: {
  315. url: 'http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png'
  316. },
  317. Wind: {
  318. url: 'http://{s}.tile.openweathermap.org/map/wind/{z}/{x}/{y}.png'
  319. },
  320. Temperature: {
  321. url: 'http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png'
  322. },
  323. Snow: {
  324. url: 'http://{s}.tile.openweathermap.org/map/snow/{z}/{x}/{y}.png'
  325. }
  326. }
  327. },
  328. Nokia: {
  329. options: {
  330. attribution:
  331. 'Map &copy; <a href="http://developer.here.com">Nokia</a>, Data &copy; NAVTEQ 2012',
  332. subdomains: '1234',
  333. devID: 'xyz', //These basemaps are free and you can sign up here: http://developer.here.com/plans
  334. appID: 'abc'
  335. },
  336. variants: {
  337. normalDay: {
  338. url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
  339. },
  340. normalGreyDay: {
  341. url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/normal.day.grey/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
  342. },
  343. satelliteNoLabelsDay: {
  344. url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/satellite.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
  345. },
  346. satelliteYesLabelsDay: {
  347. url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/hybrid.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
  348. },
  349. terrainDay: {
  350. url: 'http://{s}.maptile.lbs.ovi.com/maptiler/v2/maptile/newest/terrain.day/{z}/{x}/{y}/256/png8?token={devID}&app_id={appID}'
  351. }
  352. }
  353. },
  354. Acetate: {
  355. url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-hillshading/{z}/{x}/{y}.png',
  356. options: {
  357. attribution:
  358. '&copy;2012 Esri & Stamen, Data from OSM and Natural Earth',
  359. subdomains: '0123',
  360. minZoom: 2,
  361. maxZoom: 18
  362. },
  363. variants: {
  364. all: {},
  365. basemap: {
  366. url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-base/{z}/{x}/{y}.png'
  367. },
  368. terrain: {
  369. url: 'http://a{s}.acetate.geoiq.com/tiles/terrain/{z}/{x}/{y}.png'
  370. },
  371. foreground: {
  372. url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-fg/{z}/{x}/{y}.png'
  373. },
  374. roads: {
  375. url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-roads/{z}/{x}/{y}.png'
  376. },
  377. labels: {
  378. url: 'http://a{s}.acetate.geoiq.com/tiles/acetate-labels/{z}/{x}/{y}.png'
  379. },
  380. hillshading: {
  381. url: 'http://a{s}.acetate.geoiq.com/tiles/hillshading/{z}/{x}/{y}.png'
  382. }
  383. }
  384. }
  385. };
  386. L.tileLayer.provider = function (provider, options) {
  387. return new L.TileLayer.Provider(provider, options);
  388. };
  389. L.Control.Layers.Provided = L.Control.Layers.extend({
  390. initialize: function (base, overlay, options) {
  391. var first;
  392. var labelFormatter = function (label) {
  393. return label.replace(/\./g, ': ').replace(/([a-z])([A-Z])/g, '$1 $2');
  394. };
  395. if (base.length) {
  396. (function () {
  397. var out = {},
  398. len = base.length,
  399. i = 0;
  400. while (i < len) {
  401. if (typeof base[i] === 'string') {
  402. if (i === 0) {
  403. first = L.tileLayer.provider(base[0]);
  404. out[labelFormatter(base[i])] = first;
  405. } else {
  406. out[labelFormatter(base[i])] = L.tileLayer.provider(base[i]);
  407. }
  408. }
  409. i++;
  410. }
  411. base = out;
  412. }());
  413. this._first = first;
  414. }
  415. if (overlay && overlay.length) {
  416. (function () {
  417. var out = {},
  418. len = overlay.length,
  419. i = 0;
  420. while (i < len) {
  421. if (typeof overlay[i] === 'string') {
  422. out[labelFormatter(overlay[i])] = L.tileLayer.provider(overlay[i]);
  423. }
  424. i++;
  425. }
  426. overlay = out;
  427. }());
  428. }
  429. L.Control.Layers.prototype.initialize.call(this, base, overlay, options);
  430. },
  431. onAdd: function (map) {
  432. this._first.addTo(map);
  433. return L.Control.Layers.prototype.onAdd.call(this, map);
  434. }
  435. });
  436. L.control.layers.provided = function (baseLayers, overlays, options) {
  437. return new L.Control.Layers.Provided(baseLayers, overlays, options);
  438. };
  439. }());