9bae8c73bb06385ce34716558cd6caa09ad856e8.svn-base 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import 'babel-core/register'
  2. import 'babel-polyfill'
  3. import featuresToPolygon from './featuresToPolygon'
  4. import { toExtrudeGeometry, reductive } from './PolygonToGeom'
  5. import geoGrentAttribute from './geoGrentAttribute'
  6. import config from '../business/config'
  7. import grentText from './grentText'
  8. import * as management from './dataManagement'
  9. function mergeBigData(datas) {
  10. let index = 0
  11. let len = datas.reduce((p, c) => p + c.length, 0)
  12. let v3 = new Float32Array(len * 3)
  13. datas.forEach(data => {
  14. let length = data.length
  15. for (let i = 0; i < length; i++) {
  16. v3[index] = data[i].x
  17. v3[index + 1] = data[i].y
  18. v3[index + 2] = data[i].z
  19. index += 3
  20. }
  21. })
  22. return v3
  23. }
  24. function getMaxHeight(verticesBuffArrays) {
  25. let maxHeight = verticesBuffArrays[2]
  26. let len = verticesBuffArrays.length
  27. for (let i = 3; i < len; i += 3) {
  28. if (maxHeight < verticesBuffArrays[i + 2]) {
  29. maxHeight = verticesBuffArrays[i + 2]
  30. }
  31. }
  32. return maxHeight
  33. }
  34. function grentAnimationArray(verticesBuffArrays, stepTotal, maxHeight) {
  35. let len = verticesBuffArrays.length
  36. let animateBuffArrays = new Float32Array(
  37. (len / 3) * stepTotal
  38. )
  39. for (let i = 0, index = 0; i < len; i += 3, index++) {
  40. let indexes = index * stepTotal
  41. let origin = verticesBuffArrays[i + 2]
  42. let average = (maxHeight - origin) / stepTotal
  43. for (let j = 1; j < stepTotal + 1; j++) {
  44. animateBuffArrays[indexes + j - 1] = maxHeight - (j * average)
  45. }
  46. }
  47. return animateBuffArrays
  48. }
  49. function grentVerticesNormals(map, features) {
  50. let polygons = featuresToPolygon(features)
  51. let verticesArray = []
  52. let normalsArray = []
  53. let textVerticesArray = []
  54. let textNormalsArray = []
  55. polygons.forEach((polygon, index) => {
  56. let geo = toExtrudeGeometry(
  57. polygon,
  58. map,
  59. features[index].properties.height ||
  60. features[index].properties.levels * 5 || 5
  61. )
  62. if (!geo) return;
  63. let { vertices, normals } = geoGrentAttribute(geo)
  64. verticesArray.push(vertices)
  65. normalsArray.push(normals)
  66. if (features[index].properties.name) {
  67. let { textVertices, textNormals } = grentText(features[index].properties.name, vertices)
  68. textVerticesArray.push(textVertices)
  69. textNormalsArray.push(textNormals)
  70. }
  71. })
  72. return {
  73. verticesArray: mergeBigData(verticesArray),
  74. normalsArray: mergeBigData(normalsArray),
  75. textVerticesArray: mergeBigData(textVerticesArray),
  76. textNormalsArray: mergeBigData(textNormalsArray)
  77. }
  78. }
  79. function grentAttribute(map, features, stepTotal) {
  80. let {verticesArray, normalsArray} = grentVerticesNormals(map, features)
  81. let maxHeight = getMaxHeight(verticesArray)
  82. let animateBuffArrays = grentAnimationArray(
  83. verticesArray,
  84. stepTotal,
  85. maxHeight
  86. )
  87. return {
  88. verticesBuffArrays: verticesArray,
  89. normalsBuffArrays: normalsArray,
  90. maxHeight,
  91. animateBuffArrays
  92. }
  93. }
  94. function extractType(features) {
  95. let types = []
  96. let typeFeatures = [[]]
  97. features.forEach(f => {
  98. if (f.properties && f.properties.type) {
  99. let index = types.indexOf(f.properties.type)
  100. // index = 0
  101. if (~index) {
  102. typeFeatures[index + 1].push(f)
  103. } else {
  104. types.push(f.properties.type)
  105. typeFeatures[types.length] = [f]
  106. }
  107. } else {
  108. typeFeatures[0].push(f)
  109. }
  110. })
  111. return {
  112. typeFeatures,
  113. types
  114. }
  115. }
  116. function featuresGrentAttribute(map, features) {
  117. let { typeFeatures, types } = extractType(features)
  118. let geoJsonArray = []
  119. reductive(map)
  120. typeFeatures.forEach((features, index) => {
  121. if (features.length) {
  122. geoJsonArray.push({
  123. ...grentAttribute(map, features, config.stepTotal),
  124. fids: features.map(f => f.id),
  125. type: index === 0 ? 'unknown' : types[index - 1]
  126. })
  127. }
  128. })
  129. let transArray = []
  130. geoJsonArray.forEach(geo => {
  131. transArray.push(
  132. geo.verticesBuffArrays.buffer,
  133. geo.normalsBuffArrays.buffer,
  134. geo.animateBuffArrays.buffer
  135. )
  136. })
  137. return {
  138. geoJsonArray,
  139. transArray
  140. }
  141. }
  142. let _interface = {
  143. initialAttribute: data => {
  144. let map = JSON.parse(data.map)
  145. let incident = data.incident || 'grentAttribute'
  146. let features = JSON.parse(data.features)
  147. let { geoJsonArray, transArray} = featuresGrentAttribute(map, features)
  148. self.postMessage({
  149. incident,
  150. geoJsonArray
  151. }, transArray)
  152. },
  153. grentAnimationArray: data => {
  154. let verticesBuffArrays = data.verticesBuffArrays
  155. let maxHeight = getMaxHeight(verticesBuffArrays)
  156. let incident = data.incident || 'grentAnimationArray'
  157. let animationArray = grentAnimationArray(
  158. verticesBuffArrays,
  159. config.stepTotal,
  160. maxHeight
  161. )
  162. self.postMessage({
  163. animationArray,
  164. incident
  165. }, [animationArray.buffer])
  166. },
  167. getGeo: (function () {
  168. let ergodicIndex = 0
  169. return async data => {
  170. ergodicIndex++
  171. let currErgodicIndex = ergodicIndex
  172. self.postMessage({
  173. incident: 'obsAddGeo'
  174. })
  175. for (let i = 0; i < data.tiles.length; i++) {
  176. if (currErgodicIndex !== ergodicIndex) return;
  177. let tile = data.tiles[i]
  178. let { x, y, z } = tile
  179. let features = await management.getFeatures(x, y, z)
  180. if (currErgodicIndex !== ergodicIndex) return;
  181. let { geoJsonArray, transArray } = featuresGrentAttribute(data.map, features)
  182. self.postMessage({
  183. incident: 'addGeo',
  184. geoJsonArray
  185. }, transArray)
  186. }
  187. }
  188. })(),
  189. clearFids: data => {
  190. management.clearGeos(data.fids)
  191. }
  192. }
  193. self.addEventListener('message', event => {
  194. let data = event.data
  195. if (typeof event.data === 'string') {
  196. data = JSON.parse(event.data)
  197. }
  198. _interface[data.thing] && _interface[data.thing](data)
  199. })