venue-js 1.2.0-next.14 → 1.2.0-next.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -81,7 +81,8 @@ var defaultFeatureQueryOptionsMap = {
81
81
  // refresh every 5 min
82
82
  },
83
83
  element: {},
84
- page: {}
84
+ page: {},
85
+ model3d: {}
85
86
  };
86
87
 
87
88
  // src/data/api/delivery-project.ts
@@ -97,6 +98,14 @@ async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAUL
97
98
  const items = await res.json();
98
99
  return items;
99
100
  }
101
+ case "model3d": {
102
+ const res = await fetch(
103
+ `${baseUrl}/delivery/projects/${projectId}/${featureType}.geojson?api-key=${apiKey}`
104
+ );
105
+ if (res.status !== 200) return [];
106
+ const items = await res.json();
107
+ return items.features;
108
+ }
100
109
  case "sponsored-content": {
101
110
  const res = await fetch(
102
111
  `${baseUrl}/delivery/projects/${projectId}/sponsored-content.json?api-key=${apiKey}`
@@ -789,6 +798,13 @@ function featureCollection(features, options = {}) {
789
798
  fc.features = features;
790
799
  return fc;
791
800
  }
801
+ function multiPoint(coordinates, properties, options = {}) {
802
+ const geom = {
803
+ type: "MultiPoint",
804
+ coordinates
805
+ };
806
+ return feature(geom, properties, options);
807
+ }
792
808
  function isNumber(num) {
793
809
  return !isNaN(num) && num !== null && !Array.isArray(num);
794
810
  }
@@ -2726,6 +2742,7 @@ var CameraManager = class {
2726
2742
  };
2727
2743
 
2728
2744
  // src/IndoorMap/renderer/RendererManager.ts
2745
+ import _compact2 from "lodash/compact";
2729
2746
  import _isFunction from "lodash/isFunction";
2730
2747
  import _min from "lodash/min";
2731
2748
  import { center as turfCenter2 } from "@turf/center";
@@ -2736,6 +2753,12 @@ import * as maptalks4 from "maptalks-gl";
2736
2753
  import * as THREE from "three";
2737
2754
  import { BaseObject as BaseObject5 } from "maptalks.three";
2738
2755
  import turfBuffer2 from "@turf/buffer";
2756
+ import { cleanCoords } from "@turf/clean-coords";
2757
+ import { polygonToLine } from "@turf/polygon-to-line";
2758
+ import { nearestPointOnLine } from "@turf/nearest-point-on-line";
2759
+ import { length } from "@turf/length";
2760
+ import { along } from "@turf/along";
2761
+ import { pointToLineDistance } from "@turf/point-to-line-distance";
2739
2762
 
2740
2763
  // src/IndoorMap/renderer/3d/objects/GroundLabel.ts
2741
2764
  import * as maptalks3 from "maptalks-gl";
@@ -3042,15 +3065,15 @@ var GroundLabel = class extends BaseObject4 {
3042
3065
  // src/IndoorMap/renderer/3d/element3DRendererOptions.ts
3043
3066
  var element3DRendererOptions = {
3044
3067
  unit: {
3045
- default: { color: "#ffffff", height: 4 },
3068
+ default: { color: "#ffffff", height: 0.2 },
3046
3069
  byCategory: {
3047
3070
  walkway: { color: "#cccccc", height: 0.1 },
3048
3071
  terrace: { color: "#cccccc", height: 0.1 },
3049
3072
  unenclosedarea: { color: "#cccccc", height: 0.2 },
3050
3073
  nonpublic: { color: "#999999", height: 0.3 },
3051
3074
  escalator: { height: 0.2 },
3052
- parking: { height: 0.1 },
3053
- room: { color: "#ffffff", height: 2, bottomHeight: 0.12 }
3075
+ parking: { color: "#999999", height: 0.1 },
3076
+ room: { color: "#ffffff", height: 0.5, bottomHeight: 0.12 }
3054
3077
  }
3055
3078
  },
3056
3079
  kiosk: {
@@ -3082,6 +3105,7 @@ var get3DRendererOption = (featureType, category, options) => {
3082
3105
  };
3083
3106
 
3084
3107
  // src/IndoorMap/renderer/3d/Element3DRenderer.ts
3108
+ import lineSplit from "@turf/line-split";
3085
3109
  var HEIGHT_METER = 4;
3086
3110
  var MULTIORDINAL_HEIGHT_METER = 9;
3087
3111
  var Element3DRenderer = class extends EventTarget {
@@ -3213,6 +3237,68 @@ var Element3DRenderer = class extends EventTarget {
3213
3237
  console.log(`error createGeometry`, err, { feature: feature2, options });
3214
3238
  }
3215
3239
  };
3240
+ createRoomWall(unit, openings = []) {
3241
+ const polygons = unit.geometry.type === "Polygon" ? [unit.geometry.coordinates] : unit.geometry.coordinates;
3242
+ return polygons.map((plg) => {
3243
+ return plg.map((ring) => {
3244
+ const roomWall = cleanCoords(polygonToLine(polygon([ring])));
3245
+ if (openings.length === 0) {
3246
+ const color = "#ababab";
3247
+ const material = this.getOrCreateMaterialByColor(color);
3248
+ const extrudedWall = this.threeLayer.toExtrudeLine(
3249
+ new maptalks4.LineString(roomWall.geometry.coordinates),
3250
+ { height: 4, width: 1 },
3251
+ material
3252
+ );
3253
+ return extrudedWall;
3254
+ }
3255
+ let openingPoints = [];
3256
+ openings.forEach((opening) => {
3257
+ const doorCoords = opening?.geometry?.coordinates;
3258
+ const p0 = point(doorCoords[0]);
3259
+ const p1 = point(doorCoords[doorCoords.length - 1]);
3260
+ const s0 = nearestPointOnLine(roomWall, p0, { units: "meters" });
3261
+ const s1 = nearestPointOnLine(roomWall, p1, { units: "meters" });
3262
+ const d0 = s0.properties.dist;
3263
+ const d1 = s1.properties.dist;
3264
+ if (d0 > 1 || d1 > 1) {
3265
+ } else {
3266
+ openingPoints = openingPoints.concat([s0.geometry.coordinates, s1.geometry.coordinates]);
3267
+ }
3268
+ });
3269
+ try {
3270
+ const split = lineSplit(roomWall, multiPoint(openingPoints));
3271
+ const wallsOnly = split.features.filter((seg) => {
3272
+ const mid = along(seg, length(seg, { units: "meters" }) / 2, { units: "meters" });
3273
+ for (const opening of openings) {
3274
+ const dist = pointToLineDistance(mid, opening, { units: "meters" });
3275
+ if (dist < 0.05) return false;
3276
+ }
3277
+ return true;
3278
+ });
3279
+ const wallMeshes = wallsOnly.map((feature2, i) => {
3280
+ const color = "#ababab";
3281
+ const material = this.getOrCreateMaterialByColor(color);
3282
+ const extrudedLine = this.threeLayer.toExtrudeLine(
3283
+ new maptalks4.LineString(feature2.geometry.coordinates),
3284
+ { height: 3, width: 0.4, id: unit.id },
3285
+ material
3286
+ );
3287
+ extrudedLine.getObject3d().userData = {
3288
+ unitId: unit.id,
3289
+ coords: feature2.geometry.coordinates
3290
+ };
3291
+ return extrudedLine;
3292
+ }).flat();
3293
+ this.threeLayer.addMesh(wallMeshes);
3294
+ return wallMeshes;
3295
+ } catch (e) {
3296
+ console.log(e.message, { unit, roomWall });
3297
+ return [];
3298
+ }
3299
+ }).flat();
3300
+ }).flat();
3301
+ }
3216
3302
  async createEscalator(f, coordinate, options) {
3217
3303
  const model = {
3218
3304
  url: "https://cdn.venue.in.th/static/glb/escalator.glb",
@@ -3242,14 +3328,14 @@ var Element3DRenderer = class extends EventTarget {
3242
3328
  this.threeLayer.addMesh(groundLabel);
3243
3329
  return groundLabel;
3244
3330
  }
3245
- async createTree(coordinate, ordinal) {
3246
- const treeMarker = new maptalks4.GLTFMarker(coordinate, {
3331
+ async createModel3d(f) {
3332
+ const marker = new maptalks4.GLTFMarker(f.properties.center, {
3247
3333
  symbol: {
3248
- url: "https://dashboard.situm.com/uploads/3dmodels/demoaccount/new_escalator.glb"
3334
+ url: f.properties.model
3249
3335
  }
3250
3336
  });
3251
- treeMarker.addTo(this.gltfLayer);
3252
- return treeMarker;
3337
+ marker.addTo(this.gltfLayer);
3338
+ return marker;
3253
3339
  }
3254
3340
  async createBuilding(coordinate, ordinal) {
3255
3341
  return Promise.resolve(null);
@@ -3408,6 +3494,9 @@ var Element2DRenderer = class extends EventTarget {
3408
3494
  return geometry;
3409
3495
  }
3410
3496
  };
3497
+ createRoomWall(unit, openings) {
3498
+ return null;
3499
+ }
3411
3500
  async createEscalator(f, coordinates) {
3412
3501
  return Promise.resolve(null);
3413
3502
  }
@@ -3416,9 +3505,6 @@ var Element2DRenderer = class extends EventTarget {
3416
3505
  const bound = f.geometry.coordinates[0];
3417
3506
  return null;
3418
3507
  }
3419
- async createTree(coordinates) {
3420
- return Promise.resolve(null);
3421
- }
3422
3508
  async createBuilding(coordinate, ordinal) {
3423
3509
  return Promise.resolve(null);
3424
3510
  }
@@ -4290,6 +4376,38 @@ var RendererManager = class extends EventTarget {
4290
4376
  const groupLayer = this.map.getLayer("group");
4291
4377
  const threeLayer = groupLayer.getLayer("three");
4292
4378
  threeLayer.prepareToDraw = function(gl, scene, camera) {
4379
+ function findBadMeshes(scene2) {
4380
+ const bad = [];
4381
+ scene2.traverse((obj) => {
4382
+ if (!obj?.isMesh) return;
4383
+ const geom = obj.geometry;
4384
+ const pos = geom?.attributes?.position?.array;
4385
+ if (!pos || pos.length === 0) return;
4386
+ for (let i = 0; i < pos.length; i++) {
4387
+ const v2 = pos[i];
4388
+ if (!Number.isFinite(v2)) {
4389
+ bad.push({ mesh: obj, index: i, value: v2 });
4390
+ break;
4391
+ }
4392
+ }
4393
+ });
4394
+ if (bad.length) {
4395
+ console.group(`\u274C Found ${bad.length} meshes with invalid positions`);
4396
+ for (const b of bad) {
4397
+ console.log({
4398
+ name: b.mesh.name,
4399
+ userData: b.mesh.userData,
4400
+ uuid: b.mesh.uuid,
4401
+ badIndex: b.index,
4402
+ badValue: b.value
4403
+ });
4404
+ }
4405
+ console.groupEnd();
4406
+ } else {
4407
+ console.log("\u2705 No invalid meshes found");
4408
+ }
4409
+ return bad;
4410
+ }
4293
4411
  const ambientLight = new THREE3.AmbientLight(16777215, 0.3);
4294
4412
  scene.add(ambientLight);
4295
4413
  const dirColor = 16777215;
@@ -4304,6 +4422,9 @@ var RendererManager = class extends EventTarget {
4304
4422
  options.onRendererReady();
4305
4423
  }
4306
4424
  _this.#createElements();
4425
+ setTimeout(() => {
4426
+ findBadMeshes(scene);
4427
+ }, 3e3);
4307
4428
  };
4308
4429
  } else {
4309
4430
  this.elementRenderer = new Element2DRenderer(map, options.elements);
@@ -4345,6 +4466,9 @@ var RendererManager = class extends EventTarget {
4345
4466
  const levels = await this.#dataClient.filterByType("level", {
4346
4467
  populate: true
4347
4468
  });
4469
+ const openings = await this.#dataClient.filterByType("opening", {
4470
+ populate: true
4471
+ });
4348
4472
  const relationships = await this.#dataClient.filterByType("relationship");
4349
4473
  const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
4350
4474
  fixtures.forEach((fixture) => {
@@ -4358,7 +4482,7 @@ var RendererManager = class extends EventTarget {
4358
4482
  populate: true
4359
4483
  });
4360
4484
  units.filter(
4361
- (u4) => !["opentobelow", "escalator"].includes(u4.properties.category)
4485
+ (u4) => !["opentobelow", "escalator", "room"].includes(u4.properties.category)
4362
4486
  ).forEach((unit) => {
4363
4487
  const element = this.elementRenderer.createGeometry(unit);
4364
4488
  if (element) {
@@ -4366,6 +4490,22 @@ var RendererManager = class extends EventTarget {
4366
4490
  this.addElementsToManager(unit.id, _elements, unit.properties.level.properties.ordinal);
4367
4491
  }
4368
4492
  });
4493
+ units.filter((u4) => u4.properties.category === "room").forEach((unit) => {
4494
+ const openingRelationships = relationships.filter((r) => r.properties.origin?.id === unit.id || r.properties.destination?.id === unit.id);
4495
+ const roomOpenings = _compact2(openingRelationships.map((rel) => {
4496
+ const openingId = rel?.properties.intermediary[0].id;
4497
+ return openings.find((o) => o.id === openingId);
4498
+ }));
4499
+ const innerElements = this.elementRenderer.createGeometry(unit);
4500
+ const wallElements = this.elementRenderer.createRoomWall(unit, roomOpenings);
4501
+ if (innerElements || wallElements) {
4502
+ const _innerElements = Array.isArray(innerElements) ? innerElements : [innerElements];
4503
+ const _wallElements = Array.isArray(wallElements) ? wallElements : [wallElements];
4504
+ const _elements = [..._innerElements, ..._wallElements];
4505
+ const ordinal = unit.properties.level.properties.ordinal;
4506
+ this.addElementsToManager(unit.id, _elements, ordinal);
4507
+ }
4508
+ });
4369
4509
  const kiosks = await this.#dataClient.filterByType("kiosk", {
4370
4510
  populate: true
4371
4511
  });
@@ -4413,12 +4553,17 @@ var RendererManager = class extends EventTarget {
4413
4553
  const center2 = turfCenter2(polygon(label.geometry.coordinates)).geometry.coordinates;
4414
4554
  const unit = findUnitOnPoint(units, center2);
4415
4555
  const element = this.elementRenderer.createGroundLabel(label, unit);
4416
- console.log({ element });
4417
4556
  if (element) {
4418
4557
  const _elements = Array.isArray(element) ? element : [element];
4419
4558
  this.addElementsToManager(label.id, _elements, label.properties.ordinal);
4420
4559
  }
4421
4560
  }
4561
+ if (this.options.type === "3D") {
4562
+ const model3ds = await this.#dataClient.filterByType("model3d");
4563
+ for (const model3d of model3ds) {
4564
+ this.elementRenderer.createModel3d(model3d);
4565
+ }
4566
+ }
4422
4567
  this.changeLevelByOrdinal(this.currentOrdinals);
4423
4568
  this.dispatchEvent(new CustomEvent("renderermanager:elements_created"));
4424
4569
  }