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.

344 lines
8.4 KiB

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