You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
8.9 KiB

6 years ago
6 years ago
7 years ago
7 years ago
6 years ago
7 years ago
6 years ago
7 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. /* globals map:true, overpassFrontend:true, currentPath:true, options:true, baseCategory:true, overpassUrl:true showDetails */
  2. const tabs = require('modulekit-tabs')
  3. var OverpassFrontend = require('overpass-frontend')
  4. var OpenStreetBrowserLoader = require('./OpenStreetBrowserLoader')
  5. var state = require('./state')
  6. var hash = require('sheet-router/hash')
  7. global.OpenStreetBrowserLoader = OpenStreetBrowserLoader
  8. require('./CategoryIndex')
  9. require('./CategoryOverpass')
  10. require('./category.css')
  11. const mapMetersPerPixel = require('./map-getMetersPerPixel')
  12. global.map = null
  13. global.baseCategory = null
  14. global.overpassUrl = null
  15. global.overpassFrontend = null
  16. global.currentPath = null
  17. global.mainRepo = ''
  18. global.tabs = null
  19. var lastPopupClose = 0
  20. // Optional modules
  21. require('./options')
  22. require('./language')
  23. require('./overpassChooser')
  24. require('./fullscreen')
  25. require('./mapLayers')
  26. require('./twigFunctions')
  27. require('./markers')
  28. require('./categories')
  29. require('./wikipedia')
  30. require('./image')
  31. require('./addCategories')
  32. require('./permalink')
  33. //require('./leaflet-geo-search')
  34. require('./nominatim-search')
  35. require('./CategoryOverpassFilter')
  36. require('./GeoInfo')
  37. require('./PluginMeasure')
  38. require('./PluginGeoLocate')
  39. let exportAll = require('./exportAll')
  40. const tagsDisplay = require('./tagsDisplay').display
  41. require('./tagsDisplay-tag2link')
  42. window.onload = function () {
  43. var initState = config.defaultView
  44. map = L.map('map')
  45. map.getMetersPerPixel = mapMetersPerPixel.bind(map)
  46. map.attributionControl.setPrefix('<a target="_blank" href="https://wiki.openstreetmap.org/wiki/OpenStreetBrowser">OpenStreetBrowser</a>')
  47. // due to php export, options may be an array -> fix
  48. if (Array.isArray(options)) {
  49. options = {}
  50. }
  51. global.tabs = new tabs.Tabs(document.getElementById('globalTabs'))
  52. call_hooks('init')
  53. call_hooks_callback('init_callback', initState, onload2.bind(this, initState))
  54. map.createPane('selected')
  55. map.getPane('selected').style.zIndex = 498
  56. map.createPane('casing')
  57. map.getPane('casing').style.zIndex = 399
  58. }
  59. function onload2 (initState) {
  60. // Scale bar
  61. L.control.scale().addTo(map)
  62. if (!overpassUrl) {
  63. overpassUrl = config.overpassUrl
  64. if (Array.isArray(overpassUrl) && overpassUrl.length) {
  65. overpassUrl = overpassUrl[0]
  66. }
  67. }
  68. overpassFrontend = new OverpassFrontend(overpassUrl, {
  69. timeGap: 10,
  70. effortPerRequest: 512
  71. })
  72. OpenStreetBrowserLoader.setMap(map)
  73. var newState
  74. if (location.hash && location.hash.length > 1) {
  75. newState = state.parse(location.hash.substr(1))
  76. } else {
  77. newState = initState
  78. }
  79. // make sure the map has an initial location
  80. if (!('zoom' in newState) && !('lat' in newState) && !('lon' in newState)) {
  81. state.apply(initState)
  82. }
  83. state.apply(newState)
  84. if ('repo' in newState) {
  85. global.mainRepo = newState.repo
  86. }
  87. loadBaseCategory()
  88. map.on('popupopen', function (e) {
  89. if (e.popup.object) {
  90. var url = e.popup.object.layer_id + '/' + (e.popup.object.sublayer_id === 'main' ? '' : e.popup.object.sublayer_id + ':') + e.popup.object.id
  91. if (location.hash.substr(1) !== url && location.hash.substr(1, url.length + 1) !== url + '/') {
  92. currentPath = url
  93. // only push state, when last popup close happened >1sec earlier
  94. state.update(null, Date.now() - lastPopupClose > 1000)
  95. }
  96. OpenStreetBrowserLoader.getCategory(e.popup.object.layer_id, function (err, category) {
  97. if (err) {
  98. alert(err)
  99. return
  100. }
  101. category.notifyPopupOpen(e.popup.object, e.popup)
  102. })
  103. }
  104. })
  105. map.on('popupclose', function (e) {
  106. if (e.popup.object) {
  107. OpenStreetBrowserLoader.getCategory(e.popup.object.layer_id, function (err, category) {
  108. if (err) {
  109. alert(err)
  110. return
  111. }
  112. category.notifyPopupClose(e.popup.object, e.popup)
  113. })
  114. }
  115. lastPopupClose = Date.now()
  116. currentPath = null
  117. state.update(null, true)
  118. hide()
  119. })
  120. map.on('moveend', function (e) {
  121. state.update()
  122. })
  123. hash(function (loc) {
  124. state.apply(state.parse(loc.substr(1)))
  125. })
  126. state.update()
  127. call_hooks('initFinish')
  128. }
  129. function loadBaseCategory () {
  130. let repo = global.mainRepo + (global.mainRepo === '' ? '' : '/')
  131. OpenStreetBrowserLoader.getCategory(repo + 'index', function (err, category) {
  132. if (err) {
  133. alert(err)
  134. return
  135. }
  136. baseCategory = category
  137. category.setParentDom(document.getElementById('contentListBaseCategory'))
  138. category.open()
  139. category.dom.classList.add('baseCategory')
  140. })
  141. }
  142. global.allMapFeatures = function (callback) {
  143. global.baseCategory.allMapFeatures(callback)
  144. }
  145. window.setPath = function (path, state) {
  146. currentPath = path
  147. if ('repo' in state && state.repo !== global.mainRepo && baseCategory) {
  148. baseCategory.remove()
  149. global.mainRepo = state.repo
  150. loadBaseCategory()
  151. }
  152. if (!path) {
  153. map.closePopup()
  154. return
  155. }
  156. var param = {
  157. showDetails: !!path.match(/\/details$/),
  158. hasLocation: 'lat' in state && 'lon' in state && 'zoom' in state
  159. }
  160. show(path, param, function (err) {
  161. if (err) {
  162. alert(err)
  163. return
  164. }
  165. call_hooks('show', path, param)
  166. })
  167. }
  168. function show (id, options, callback) {
  169. if (options.showDetails) {
  170. call_hooks('hide-' + document.getElementById('content').className)
  171. document.getElementById('content').className = 'details'
  172. document.getElementById('contentDetails').innerHTML = lang('loading')
  173. }
  174. var m = id.match(/^(.*)\/((?:[\w\d-]+:)?[nwr]\d+)(\/details)?$/)
  175. if (!m) {
  176. return callback(new Error('unknown request'))
  177. }
  178. var categoryId = m[1]
  179. var featureId = m[2]
  180. OpenStreetBrowserLoader.getCategory(categoryId, function (err, category) {
  181. if (err) {
  182. return callback(new Error('error loading category "' + categoryId + '": ' + err))
  183. }
  184. if (!category.parentDom) {
  185. category.setParentDom(document.getElementById('contentListAddCategories'))
  186. }
  187. category.show(
  188. featureId,
  189. options,
  190. function (err, data) {
  191. if (err) {
  192. return callback(new Error('error loading object "' + categoryId + '/' + featureId + '": ' + err))
  193. }
  194. if (!map._popup || map._popup !== data.popup) {
  195. data.feature.openPopup()
  196. }
  197. if (options.showDetails) {
  198. showDetails(data, category)
  199. }
  200. callback(err)
  201. }
  202. )
  203. category.open()
  204. })
  205. }
  206. window.showDetails = function (data, category) {
  207. var div, h, dt, dd, li, a
  208. var k
  209. var dom = document.getElementById('contentDetails')
  210. dom.innerHTML = ''
  211. div = document.createElement('h1')
  212. div.className = 'title'
  213. div.innerHTML = data.data.title || ''
  214. dom.appendChild(div)
  215. data.sublayer.updateAssets(div, data)
  216. div = document.createElement('div')
  217. div.className = 'description'
  218. div.innerHTML = data.data.popupDescription || data.data.description || ''
  219. dom.appendChild(div)
  220. data.sublayer.updateAssets(div, data)
  221. div = document.createElement('div')
  222. div.className = 'body'
  223. dom.appendChild(div)
  224. function updateBody (div) {
  225. div.innerHTML = data.data.detailBody || data.data.body || ''
  226. data.sublayer.updateAssets(div, data)
  227. }
  228. data.object.on('update', updateBody.bind(this, div))
  229. updateBody(div)
  230. div = document.createElement('div')
  231. div.className = 'body'
  232. dom.appendChild(div)
  233. category.renderTemplate(data, 'detailsBody', function (div, err, result) {
  234. div.innerHTML = result
  235. data.sublayer.updateAssets(div, data)
  236. }.bind(this, div))
  237. call_hooks_callback('show-details', data, category, dom,
  238. function (err) {
  239. if (err.length) {
  240. console.log('show-details produced errors:', err)
  241. }
  242. }
  243. )
  244. h = document.createElement('h3')
  245. h.innerHTML = lang('header:export')
  246. dom.appendChild(h)
  247. div = document.createElement('div')
  248. dom.appendChild(div)
  249. exportAll(data, div)
  250. h = document.createElement('h3')
  251. h.innerHTML = lang('header:attributes')
  252. dom.appendChild(h)
  253. dom.appendChild(tagsDisplay(data.object.tags))
  254. h = document.createElement('h3')
  255. h.innerHTML = lang('header:osm_meta')
  256. dom.appendChild(h)
  257. div = document.createElement('dl')
  258. div.className = 'meta'
  259. dt = document.createElement('dt')
  260. dt.appendChild(document.createTextNode('id'))
  261. div.appendChild(dt)
  262. dd = document.createElement('dd')
  263. a = document.createElement('a')
  264. a.appendChild(document.createTextNode(data.object.type + '/' + data.object.osm_id))
  265. a.href = config.urlOpenStreetMap + '/' + data.object.type + '/' + data.object.osm_id
  266. a.target = '_blank'
  267. dd.appendChild(a)
  268. div.appendChild(dd)
  269. for (k in data.object.meta) {
  270. dt = document.createElement('dt')
  271. dt.appendChild(document.createTextNode(k))
  272. div.appendChild(dt)
  273. dd = document.createElement('dd')
  274. dd.appendChild(document.createTextNode(data.object.meta[k]))
  275. div.appendChild(dd)
  276. }
  277. dom.appendChild(div)
  278. }
  279. function hide () {
  280. call_hooks('hide-' + document.getElementById('content').className)
  281. document.getElementById('content').className = 'list'
  282. }
  283. window.showRootContent = hide