园林绿化
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.

309 lines
8.6 KiB

  1. /* MVT加载类 作者: 木遥(微信: http://marsgis.cn/weixin.html ) */
  2. // import * as mars3d from "mars3d"
  3. ;(function (window) {
  4. function MvtImageryProvider(options) {
  5. options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT)
  6. this.options = options
  7. this._tileWidth = Cesium.defaultValue(options.tileWidth, 512)
  8. this._tileHeight = Cesium.defaultValue(options.tileHeight, 512)
  9. this._minimumLevel = Cesium.defaultValue(options.minimumLevel, 0)
  10. this._maximumLevel = Cesium.defaultValue(options.maximumLevel, 18)
  11. if (options.rectangle && options.rectangle.xmin && options.rectangle.xmax && options.rectangle.ymin && options.rectangle.ymax) {
  12. var xmin = options.rectangle.xmin
  13. var xmax = options.rectangle.xmax
  14. var ymin = options.rectangle.ymin
  15. var ymax = options.rectangle.ymax
  16. options.rectangle = Cesium.Rectangle.fromDegrees(xmin, ymin, xmax, ymax)
  17. }
  18. this._tilingScheme = Cesium.defaultValue(options.tilingScheme, new Cesium.WebMercatorTilingScheme({ ellipsoid: options.ellipsoid }))
  19. this._rectangle = Cesium.defaultValue(options.rectangle, this._tilingScheme.rectangle)
  20. this._rectangle = Cesium.Rectangle.intersection(this._rectangle, this._tilingScheme.rectangle)
  21. this._hasAlphaChannel = Cesium.defaultValue(options.hasAlphaChannel, true)
  22. this._errorEvent = new Cesium.Event()
  23. this._readyPromise = Cesium.defer()
  24. this._credit = undefined
  25. this._ready = true
  26. //mvt相关的处理
  27. if (!window.ol) {
  28. throw new DeveloperError("请引入Openlayers类库!")
  29. }
  30. this._ol = window.ol
  31. this._mvtParser = new this._ol.format.MVT()
  32. this._key = Cesium.defaultValue(options.key, "")
  33. this._url = Cesium.defaultValue(options.url, "")
  34. if (options.styleConfig) {
  35. //(glStyle, sources, resolutions = defaultResolutions, spriteData, spriteImageUrl, getFonts)
  36. this._styleClass = window.olms.stylefunction(options.styleConfig, options.styleConfig.sources, "", null, null)
  37. // this._url = options.styleConfig.tiles[0]
  38. } else if (options.style) {
  39. switch (options.style) {
  40. case "mapbox-streets-v6":
  41. this._styleClass = new mars3d.MapboxStreetsV6()
  42. break
  43. default:
  44. this._styleClass = options.style
  45. break
  46. }
  47. }
  48. var sw = this._tilingScheme._rectangleSouthwestInMeters
  49. var ne = this._tilingScheme._rectangleNortheastInMeters
  50. var mapExtent = [sw.x, sw.y, ne.x, ne.y]
  51. this._resolutions = ol.tilegrid.resolutionsFromExtent(mapExtent, this._maximumLevel, this._tileWidth)
  52. this._pixelRatio = 1
  53. this._transform = [0.125, 0, 0, 0.125, 0, 0]
  54. this._replays = ["Default", "Image", "Polygon", "LineString", "Text"]
  55. this._tileQueue = new Cesium.TileReplacementQueue()
  56. this._cacheSize = 1000
  57. }
  58. Object.defineProperties(MvtImageryProvider.prototype, {
  59. proxy: {
  60. get: function () {
  61. return undefined
  62. }
  63. },
  64. tileWidth: {
  65. get: function () {
  66. return this._tileWidth
  67. }
  68. },
  69. tileHeight: {
  70. get: function () {
  71. return this._tileHeight
  72. }
  73. },
  74. maximumLevel: {
  75. get: function () {
  76. return undefined
  77. }
  78. },
  79. minimumLevel: {
  80. get: function () {
  81. return undefined
  82. }
  83. },
  84. tilingScheme: {
  85. get: function () {
  86. return this._tilingScheme
  87. }
  88. },
  89. rectangle: {
  90. get: function () {
  91. return this._tilingScheme.rectangle
  92. }
  93. },
  94. tileDiscardPolicy: {
  95. get: function () {
  96. return undefined
  97. }
  98. },
  99. errorEvent: {
  100. get: function () {
  101. return this._errorEvent
  102. }
  103. },
  104. ready: {
  105. get: function () {
  106. return true
  107. }
  108. },
  109. readyPromise: {
  110. get: function () {
  111. return this._readyPromise
  112. }
  113. },
  114. credit: {
  115. get: function () {
  116. return undefined
  117. }
  118. },
  119. hasAlphaChannel: {
  120. get: function () {
  121. return true
  122. }
  123. }
  124. })
  125. MvtImageryProvider.prototype.getTileCredits = function (x, y, level) {
  126. return undefined
  127. }
  128. MvtImageryProvider.prototype.pickFeatures = function (x, y, level, longitude, latitude) {
  129. return undefined
  130. }
  131. MvtImageryProvider.prototype.requestImage = function (x, y, level, request) {
  132. var cacheTile = findTileInQueue(x, y, level, this._tileQueue)
  133. if (cacheTile != undefined) {
  134. return new Promise((resolve, reject) => {
  135. resolve(cacheTile)
  136. })
  137. } else {
  138. var that = this
  139. var url = this._url
  140. var reverseY = this._tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1
  141. url = url.replace("{x}", x).replace("{y}", y).replace("{reverseY}", reverseY).replace("{z}", level).replace("{k}", this._key)
  142. var resource = Cesium.Resource.createIfNeeded(url)
  143. return resource.fetchArrayBuffer().then(function (arrayBuffer) {
  144. var canvas = document.createElement("canvas")
  145. canvas.width = that._tileWidth
  146. canvas.height = that._tileHeight
  147. var vectorContext = canvas.getContext("2d")
  148. var features = that._mvtParser.readFeatures(arrayBuffer)
  149. var styleFun = that._styleClass.getStyle()
  150. var extent = [0, 0, 4096, 4096]
  151. var _replayGroup = new ol.render.canvas.ReplayGroup(0, extent, 8, true, 100)
  152. for (var i = 0; i < features.length; i++) {
  153. var feature = features[i]
  154. var styles = styleFun(features[i], that._resolutions[level])
  155. for (var j = 0; j < styles.length; j++) {
  156. ol.renderer.vector.renderFeature_(_replayGroup, feature, styles[j], 16)
  157. }
  158. }
  159. _replayGroup.finish()
  160. _replayGroup.replay(vectorContext, that._pixelRatio, that._transform, 0, {}, that._replays, true)
  161. if (that._tileQueue.count > that._cacheSize) {
  162. trimTiles(that._tileQueue, that._cacheSize / 2)
  163. }
  164. canvas.xMvt = x
  165. canvas.yMvt = y
  166. canvas.zMvt = level
  167. that._tileQueue.markTileRendered(canvas)
  168. delete _replayGroup
  169. _replayGroup = null
  170. return canvas
  171. })
  172. }
  173. }
  174. function findTileInQueue(x, y, level, tileQueue) {
  175. var item = tileQueue.head
  176. while (item != undefined && !(item.xMvt == x && item.yMvt == y && item.zMvt == level)) {
  177. item = item.replacementNext
  178. }
  179. return item
  180. }
  181. function removeQueue(tileReplacementQueue, item) {
  182. var previous = item.replacementPrevious
  183. var next = item.replacementNext
  184. if (item === tileReplacementQueue._lastBeforeStartOfFrame) {
  185. tileReplacementQueue._lastBeforeStartOfFrame = next
  186. }
  187. if (item === tileReplacementQueue.head) {
  188. tileReplacementQueue.head = next
  189. } else {
  190. previous.replacementNext = next
  191. }
  192. if (item === tileReplacementQueue.tail) {
  193. tileReplacementQueue.tail = previous
  194. } else {
  195. next.replacementPrevious = previous
  196. }
  197. item.replacementPrevious = undefined
  198. item.replacementNext = undefined
  199. --tileReplacementQueue.count
  200. }
  201. function trimTiles(tileQueue, maximumTiles) {
  202. var tileToTrim = tileQueue.tail
  203. while (tileQueue.count > maximumTiles && Cesium.defined(tileToTrim)) {
  204. var previous = tileToTrim.replacementPrevious
  205. removeQueue(tileQueue, tileToTrim)
  206. delete tileToTrim
  207. tileToTrim = null
  208. tileToTrim = previous
  209. }
  210. }
  211. class PbfolLayer extends mars3d.layer.BaseTileLayer {
  212. _addedHook() {
  213. let styleUrl = this.options.style
  214. if (mars3d.Util.isString(styleUrl) && styleUrl.endsWith(".json")) {
  215. this.getPbfStyle(styleUrl).then((data) => {
  216. if (this.isAdded) {
  217. super._addedHook()
  218. }
  219. })
  220. } else {
  221. super._addedHook()
  222. }
  223. }
  224. //构建ImageryProvider
  225. _createImageryProvider(options) {
  226. return createImageryProvider(options)
  227. }
  228. //取样式数据
  229. getPbfStyle(styleUrl) {
  230. return mars3d.Util.fetchJson({
  231. url: styleUrl,
  232. queryParameters: {
  233. access_token: this.options.key || "mars3d"
  234. }
  235. })
  236. .then((json) => {
  237. this.options.styleConfig = json
  238. })
  239. .catch(function (error) {
  240. console.log("加载样式出错", error)
  241. })
  242. }
  243. }
  244. function createImageryProvider(options) {
  245. return new MvtImageryProvider(options)
  246. }
  247. PbfolLayer.createImageryProvider = createImageryProvider
  248. //注册下
  249. const layerType = "mvt" //图层类型
  250. mars3d.LayerUtil.register(layerType, PbfolLayer)
  251. mars3d.LayerUtil.registerImageryProvider(layerType, createImageryProvider)
  252. //对外接口
  253. mars3d.provider.MvtImageryProvider = MvtImageryProvider
  254. mars3d.layer.PbfolLayer = PbfolLayer
  255. })(window)
  256. // export { PbfolLayer }