123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- import 'babel-core/register'
- import 'babel-polyfill'
- import featuresToPolygon from './featuresToPolygon'
- import { toExtrudeGeometry, reductive } from './PolygonToGeom'
- import geoGrentAttribute from './geoGrentAttribute'
- import config from '../business/config'
- import grentText from './grentText'
- import * as management from './dataManagement'
- function mergeBigData(datas) {
- let index = 0
- let len = datas.reduce((p, c) => p + c.length, 0)
- let v3 = new Float32Array(len * 3)
- datas.forEach(data => {
- let length = data.length
- for (let i = 0; i < length; i++) {
- v3[index] = data[i].x
- v3[index + 1] = data[i].y
- v3[index + 2] = data[i].z
- index += 3
- }
- })
- return v3
- }
- function getMaxHeight(verticesBuffArrays) {
- let maxHeight = verticesBuffArrays[2]
- let len = verticesBuffArrays.length
- for (let i = 3; i < len; i += 3) {
- if (maxHeight < verticesBuffArrays[i + 2]) {
- maxHeight = verticesBuffArrays[i + 2]
- }
- }
- return maxHeight
- }
- function grentAnimationArray(verticesBuffArrays, stepTotal, maxHeight) {
- let len = verticesBuffArrays.length
- let animateBuffArrays = new Float32Array(
- (len / 3) * stepTotal
- )
- for (let i = 0, index = 0; i < len; i += 3, index++) {
- let indexes = index * stepTotal
- let origin = verticesBuffArrays[i + 2]
- let average = (maxHeight - origin) / stepTotal
- for (let j = 1; j < stepTotal + 1; j++) {
- animateBuffArrays[indexes + j - 1] = maxHeight - (j * average)
- }
- }
- return animateBuffArrays
- }
- function grentVerticesNormals(map, features) {
- let polygons = featuresToPolygon(features)
- let verticesArray = []
- let normalsArray = []
- let textVerticesArray = []
- let textNormalsArray = []
- polygons.forEach((polygon, index) => {
- let geo = toExtrudeGeometry(
- polygon,
- map,
- features[index].properties.height ||
- features[index].properties.levels * 5 || 5
- )
- if (!geo) return;
- let { vertices, normals } = geoGrentAttribute(geo)
- verticesArray.push(vertices)
- normalsArray.push(normals)
-
- if (features[index].properties.name) {
- let { textVertices, textNormals } = grentText(features[index].properties.name, vertices)
- textVerticesArray.push(textVertices)
- textNormalsArray.push(textNormals)
- }
- })
- return {
- verticesArray: mergeBigData(verticesArray),
- normalsArray: mergeBigData(normalsArray),
- textVerticesArray: mergeBigData(textVerticesArray),
- textNormalsArray: mergeBigData(textNormalsArray)
- }
- }
- function grentAttribute(map, features, stepTotal) {
- let {verticesArray, normalsArray} = grentVerticesNormals(map, features)
- let maxHeight = getMaxHeight(verticesArray)
- let animateBuffArrays = grentAnimationArray(
- verticesArray,
- stepTotal,
- maxHeight
- )
-
- return {
- verticesBuffArrays: verticesArray,
- normalsBuffArrays: normalsArray,
- maxHeight,
- animateBuffArrays
- }
- }
- function extractType(features) {
- let types = []
- let typeFeatures = [[]]
- features.forEach(f => {
- if (f.properties && f.properties.type) {
- let index = types.indexOf(f.properties.type)
- // index = 0
- if (~index) {
- typeFeatures[index + 1].push(f)
- } else {
- types.push(f.properties.type)
- typeFeatures[types.length] = [f]
- }
- } else {
- typeFeatures[0].push(f)
- }
- })
- return {
- typeFeatures,
- types
- }
- }
- function featuresGrentAttribute(map, features) {
- let { typeFeatures, types } = extractType(features)
- let geoJsonArray = []
- reductive(map)
- typeFeatures.forEach((features, index) => {
- if (features.length) {
- geoJsonArray.push({
- ...grentAttribute(map, features, config.stepTotal),
- fids: features.map(f => f.id),
- type: index === 0 ? 'unknown' : types[index - 1]
- })
- }
- })
-
- let transArray = []
- geoJsonArray.forEach(geo => {
- transArray.push(
- geo.verticesBuffArrays.buffer,
- geo.normalsBuffArrays.buffer,
- geo.animateBuffArrays.buffer
- )
- })
- return {
- geoJsonArray,
- transArray
- }
- }
- let _interface = {
- initialAttribute: data => {
- let map = JSON.parse(data.map)
- let incident = data.incident || 'grentAttribute'
- let features = JSON.parse(data.features)
- let { geoJsonArray, transArray} = featuresGrentAttribute(map, features)
- self.postMessage({
- incident,
- geoJsonArray
- }, transArray)
- },
- grentAnimationArray: data => {
- let verticesBuffArrays = data.verticesBuffArrays
- let maxHeight = getMaxHeight(verticesBuffArrays)
- let incident = data.incident || 'grentAnimationArray'
- let animationArray = grentAnimationArray(
- verticesBuffArrays,
- config.stepTotal,
- maxHeight
- )
- self.postMessage({
- animationArray,
- incident
- }, [animationArray.buffer])
- },
- getGeo: (function () {
- let ergodicIndex = 0
- return async data => {
- ergodicIndex++
- let currErgodicIndex = ergodicIndex
- self.postMessage({
- incident: 'obsAddGeo'
- })
- for (let i = 0; i < data.tiles.length; i++) {
- if (currErgodicIndex !== ergodicIndex) return;
- let tile = data.tiles[i]
- let { x, y, z } = tile
- let features = await management.getFeatures(x, y, z)
- if (currErgodicIndex !== ergodicIndex) return;
- let { geoJsonArray, transArray } = featuresGrentAttribute(data.map, features)
- self.postMessage({
- incident: 'addGeo',
- geoJsonArray
- }, transArray)
- }
- }
- })(),
- clearFids: data => {
- management.clearGeos(data.fids)
- }
- }
- self.addEventListener('message', event => {
- let data = event.data
- if (typeof event.data === 'string') {
- data = JSON.parse(event.data)
- }
- _interface[data.thing] && _interface[data.thing](data)
- })
|