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.

149 lines
3.5 KiB

  1. var OverpassLayer = require('overpass-layer')
  2. var jsonMultilineStrings = require('json-multiline-strings')
  3. function OpenStreetBrowserLoader () {
  4. this.types = {}
  5. this.categories = {}
  6. this.repoCache = {}
  7. this.templates = {}
  8. this._loadClash = {} // if a category is being loaded multiple times, collect callbacks
  9. }
  10. OpenStreetBrowserLoader.prototype.setMap = function (map) {
  11. this.map = map
  12. }
  13. OpenStreetBrowserLoader.prototype.getCategory = function (id, callback) {
  14. if (id in this.categories) {
  15. callback(null, this.categories[id])
  16. return
  17. }
  18. var repo = 'default'
  19. if (repo in this.repoCache) {
  20. this.getCategoryFromData(id, this.repoCache[repo][id], function (err, category) {
  21. if (category) {
  22. category.setMap(this.map)
  23. }
  24. callback(err, category)
  25. })
  26. return
  27. }
  28. if (repo in this._loadClash) {
  29. this._loadClash[repo].push([ id, callback ])
  30. return
  31. }
  32. this._loadClash[repo] = [ [ id, callback ] ]
  33. function reqListener (req) {
  34. if (req.status !== 200) {
  35. console.log(req)
  36. return callback(req.statusText, null)
  37. }
  38. this.repoCache[repo] = JSON.parse(req.responseText)
  39. var todo = this._loadClash[repo]
  40. delete this._loadClash[repo]
  41. todo.forEach(function (c) {
  42. var id = c[0]
  43. var callback = c[1]
  44. if (id in this.categories) {
  45. callback(null, this.categories[id])
  46. } else {
  47. this.getCategoryFromData(id, this.repoCache[repo][id], function (err, category) {
  48. if (category) {
  49. category.setMap(this.map)
  50. }
  51. callback(err, category)
  52. })
  53. }
  54. }.bind(this))
  55. }
  56. var req = new XMLHttpRequest()
  57. req.addEventListener('load', reqListener.bind(this, req))
  58. req.open('GET', 'repo.php?repo=' + repo + '&' + config.categoriesRev)
  59. req.send()
  60. }
  61. OpenStreetBrowserLoader.prototype.getTemplate = function (id, callback) {
  62. if (id in this.templates) {
  63. callback.apply(this, this.templates[id])
  64. return
  65. }
  66. if (id in this._loadClash) {
  67. this._loadClash[id].push(callback)
  68. return
  69. }
  70. this._loadClash[id] = []
  71. function reqListener (req) {
  72. if (req.status !== 200) {
  73. console.log(req)
  74. this.templates[id] = [ req.statusText, null ]
  75. } else {
  76. this.templates[id] = [ null, OverpassLayer.twig.twig({ data: req.responseText, autoescape: true }) ]
  77. }
  78. callback.apply(this, this.templates[id])
  79. this._loadClash[id].forEach(function (c) {
  80. c.apply(this, this.templates[id])
  81. }.bind(this))
  82. }
  83. var req = new XMLHttpRequest()
  84. req.addEventListener('load', reqListener.bind(this, req))
  85. req.open('GET', config.categoriesDir + '/' + id + '.html?' + config.categoriesRev)
  86. req.send()
  87. }
  88. OpenStreetBrowserLoader.prototype.getCategoryFromData = function (id, data, callback) {
  89. if (id in this.categories) {
  90. callback(null, this.categories[id])
  91. return
  92. }
  93. if (!data.type) {
  94. return callback(new Error('no type defined'), null)
  95. }
  96. if (!(data.type in this.types)) {
  97. return callback(new Error('unknown type'), null)
  98. }
  99. var layer = new this.types[data.type](id, data)
  100. layer.setMap(this.map)
  101. this.categories[id] = layer
  102. if ('load' in layer) {
  103. layer.load(function (err) {
  104. callback(err, layer)
  105. })
  106. } else {
  107. callback(null, layer)
  108. }
  109. }
  110. OpenStreetBrowserLoader.prototype.forget = function (id) {
  111. this.categories[id].remove()
  112. delete this.categories[id]
  113. }
  114. OpenStreetBrowserLoader.prototype.registerType = function (type, classObject) {
  115. this.types[type] = classObject
  116. }
  117. module.exports = new OpenStreetBrowserLoader()