UNPKG

9.22 kBJavaScriptView Raw
1
2var RADIUS = 6300000;
3var GEO2METER = RADIUS * (Math.PI / 180)
4
5
6function newScene(x3dJsonBlock) {
7 return {"X3D": {
8 "@profile": "Immersive",
9 "@version": 3.3,
10 "@xsd:noNamespaceSchemaLocation": "http://www.web3d.org/specifications/x3d-3.3.xsd",
11 "Scene": {
12 "-children": x3dJsonBlock
13 }
14 }
15 };
16}
17
18function newX3dJsonBldPart(minHeight, color, transparency, points, height) {
19 return {"Transform": {
20 "@translation": [0, minHeight, 0],
21 "-children": [
22 {"Group": {
23 "@class": "buildingPart",
24 "-children": [
25 {"Shape": {
26 "-appearance": [
27 {"Appearance": {
28 "-material": [
29 {"Material": {
30 "@diffuseColor": color,
31 "@transparency": transparency
32 }
33 }
34 ]
35 }
36 }
37 ],
38 "-geometry": [
39 {"Extrusion": {
40 "@convex": false,
41 "@creaseAngle": 0.785,
42 "@crossSection": points,
43 "@solid": false,
44 "@endCap": false,
45 "@spine": [0, 0, 0, 0, height, 0]
46 }
47 }
48 ]
49 }
50 }
51 ]
52 }
53 }
54 ]
55 }
56 };
57}
58function newX3dJsonBlFloordPart(minHeight, points) {
59 return {"Transform": {
60 "@translation": [0, minHeight, 0],
61 "-children": [
62 {"Group": {
63 "@class": "buildingPart",
64 "-children": [
65 {"Shape": {
66 "-appearance": [
67 {"Appearance": {
68 "-material": [
69 {"Material": {
70 "@diffuseColor": [1, 1, 1],
71 "@transparency": 0
72 }
73 }
74 ]
75 }
76 }
77 ],
78 "-geometry": [
79 {"Polyline2D": {
80 "@lineSegments": points}
81 }
82 ]
83 }
84 }
85 ]
86 }
87 }
88 ]
89 }
90 };
91}
92function getGeoJsonRoof(geoJsonBlock, id) {
93 var result;
94 for (var idx = 0; idx < geoJsonBlock.features.length; idx++) {
95 if (geoJsonBlock.features[idx].properties.type === "geoRoof" && geoJsonBlock.features[idx].properties.id === id) {
96 result = geoJsonBlock.features[idx];
97 break;
98 }
99 }
100 return result;
101}
102
103function geoToX3dColor(geoColor) {
104 var regex = /^rgb: \(([0-9]+), ([0-9]+), ([0-9]+)\)$/
105 var result = string.match(regex);
106 return [result[1], result[2], result[3]];
107}
108
109function isInside(geopoint, geobound) {
110 return !(geopoint[0] < geobound.minbound[0]
111 || geopoint[0] > geobound.maxbound[0]
112 || geopoint[1] < geobound.minbound[1]
113 || geopoint[1] > geobound.maxbound[1]);
114}
115
116function centroid(geonodes) {
117 var sumlon = 0;
118 var sumlat = 0;
119 for (var i = 0; i < geonodes.length; i++) {
120 sumlon += geonodes[i][0];
121 sumlat += geonodes[i][1];
122 }
123 return [
124 sumlon / geonodes.length,
125 sumlat / geonodes.length
126 ];
127}
128
129var myOsmGround;
130
131/**
132 * Convert GeoJSON data to x3dJson data
133 * @param geoJsonBlock Object
134 * @param my3dOutputStream Object
135 * @param onBlock function
136 */
137function convert(geoJsonBlock, my3dOutputStream, onBlock) {
138// console.log("geoJsonBlock: " + JSON.stringify(geoJsonBlock));
139 x3dJsonBlock = [];
140
141 switch (geoJsonBlock["properties"]["type"]) {
142 case "ground":
143 break;
144 case "building":
145 for (var i = 0; i < geoJsonBlock.features.length; i++) {
146 var geoJsonBldPart = geoJsonBlock.features[i];
147 var my3dBldPart = {};
148 points = [];
149 perimeter = 0;
150 if (geoJsonBldPart.geometry.coordinates[0].length > 0) {
151 var pointRef = geoJsonBldPart.geometry.coordinates[0][geoJsonBldPart.geometry.coordinates[0].length - 1];
152 for (var j = 0; j < geoJsonBldPart.geometry.coordinates[0].length; j++) {
153 var node = geoJsonBldPart.geometry.coordinates[0][j];
154 points[points.length] = [node[0], node[1]];
155 var z = (pointRef[1] - node[1]) * GEO2METER;
156 var x = (node[0] - pointRef[0]) * GEO2METER;
157 pointRef = node;
158 perimeter += Math.sqrt(z * z + x * x);
159 }
160 }
161 if (geoJsonBldPart.properties.levels) {
162 my3dBldPart.levels = +geoJsonBldPart.properties.levels;
163 }
164
165 // BldPart roof
166 var roof = getGeoJsonRoof(geoJsonBlock, geoJsonBldPart.properties.id);
167// x3dJsonBlock[x3dJsonBlock.length] = newX3dJsonBldPartRoof(
168// +geoJsonBldPart.properties.minHeight,
169// diffuseColor,
170// geoJsonBldPart.properties.levels ? 0.6 : 0,
171// points,
172// height);
173
174 my3dBldPart.roof = {};
175 my3dBldPart.roof.shape = "flat";
176 my3dBldPart.roof.shape = (roof && roof.shape) ? roof.shape : "flat";
177 my3dBldPart.roof.elevation = ((geoJsonBldPart.properties.height) ? geoJsonBldPart.properties.height : 0)
178 - ((my3dBldPart.roof && my3dBldPart.roof.elevation) ? my3dBldPart.roof.elevation : 0);
179 my3dBldPart.roof.points = my3dBldPart.points;
180 my3dBldPart.roof.height = (roof && roof.height) ? roof.height : 0;
181
182 var diffuseColor = (geoJsonBldPart.properties.colour !== undefined) ?
183 geoToX3dColor(geoJsonBldPart.properties.colour) :
184 [
185 (((13 * (1 + height)) % 100) / 100),
186 (((17 * (1 + height)) % 100) / 100),
187 (((23 * (1 + height)) % 100) / 100)];
188 var height = ((geoJsonBldPart.properties.height) ? geoJsonBldPart.properties.height : 0)
189 - ((roof && roof.height) ? (roof.height) : 0)
190 - geoJsonBldPart.properties.minHeight;
191 if (height === undefined) {
192 height = 9.99
193 }
194 x3dJsonBlock[x3dJsonBlock.length] = newX3dJsonBldPart(
195 +geoJsonBldPart.properties.minHeight,
196 diffuseColor,
197 geoJsonBldPart.properties.levels ? 0.6 : 0,
198 points,
199 height);
200
201 // Floors
202 if (geoJsonBldPart.properties.levels && my3dBldPart.height) {
203 var floorHeight = my3dBldPart.height / (geoJsonBldPart.properties.levels - geoJsonBldPart.properties.minLevel);
204 var level;
205 for (level = +geoJsonBldPart.properties.minLevel; level < geoJsonBldPart.properties.levels; level++) {
206 x3dJsonBlock[x3dJsonBlock.length] = newX3dJsonBlFloordPart(
207 +my3dBldPart.elevation + (level - geoJsonBldPart.properties.minLevel) * floorHeight,
208 points);
209 }
210 }
211 }
212 break;
213 }
214 onBlock(x3dJsonBlock);
215
216 if (my3dOutputStream !== undefined) {
217 var scene = newScene(x3dJsonBlock);
218 my3dOutputStream.write(JSON.stringify(scene));
219 my3dOutputStream.end();
220 }
221}
222
223exports.convert = convert;