@aibee/crc-bmap 0.0.106 → 0.0.107

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/lib/bmap.esm.js CHANGED
@@ -4047,9 +4047,7 @@ var BMap = class extends EventDispatcher7 {
4047
4047
  }
4048
4048
  rotateMap(radius = 0.1) {
4049
4049
  const azimuthal = this.context.control.getAzimuthalAngle();
4050
- this.context.control.maxAzimuthAngle = azimuthal + radius;
4051
- this.context.control.minAzimuthAngle = azimuthal + radius;
4052
- this.context.control.update();
4050
+ this.context.setAzimuthalAngle(azimuthal + radius, 500);
4053
4051
  }
4054
4052
  /**
4055
4053
  * 测量距离
@@ -5142,48 +5140,107 @@ function simplifyPath(path, ignoreFirst = false, smoothingOptimization = true, s
5142
5140
  const halfMidTailDist = tail.distanceTo(mid) / 2;
5143
5141
  const curveHead = mid.clone();
5144
5142
  const curveTail = mid.clone();
5145
- curveHead.add(head.clone().sub(mid).normalize().multiplyScalar(
5146
- halfHeadMidDist > smoothingDistance ? smoothingDistance / 2 : halfHeadMidDist
5147
- ));
5148
- curveTail.add(tail.clone().sub(mid).normalize().multiplyScalar(
5149
- halfMidTailDist > smoothingDistance ? smoothingDistance / 2 : halfMidTailDist
5150
- ));
5143
+ curveHead.add(
5144
+ head.clone().sub(mid).normalize().multiplyScalar(
5145
+ halfHeadMidDist > smoothingDistance ? smoothingDistance / 2 : halfHeadMidDist
5146
+ )
5147
+ );
5148
+ curveTail.add(
5149
+ tail.clone().sub(mid).normalize().multiplyScalar(
5150
+ halfMidTailDist > smoothingDistance ? smoothingDistance / 2 : halfMidTailDist
5151
+ )
5152
+ );
5151
5153
  const curveToSmooth = [
5152
5154
  [curveHead.x, curveHead.y],
5153
5155
  [mid.x, mid.y],
5154
5156
  [curveTail.x, curveTail.y]
5155
5157
  ];
5156
- simplifiedPath.push(
5157
- ...smoothPath(
5158
- curveToSmooth,
5159
- smoothingDistance / 25
5160
- )
5161
- );
5158
+ simplifiedPath.push(...smoothPath(curveToSmooth, smoothingDistance / 25));
5162
5159
  }
5163
5160
  simplifiedPath.push(joints[joints.length - 1]);
5161
+ return removeWeightPath(simplifiedPath);
5162
+ }
5163
+ function removeWeightPath(points) {
5164
+ if (points.length <= 1) {
5165
+ return points;
5166
+ }
5164
5167
  const checkedPath = [];
5165
5168
  let lastCheckedPoint;
5166
- simplifiedPath.forEach(([x, y]) => {
5169
+ points.forEach(([x, y]) => {
5167
5170
  if (!lastCheckedPoint) {
5168
5171
  lastCheckedPoint = [x, y];
5169
5172
  checkedPath.push([x, y]);
5170
- } else if (!(x === lastCheckedPoint[0] && y === lastCheckedPoint[0])) {
5173
+ } else if (!(x === lastCheckedPoint[0] && y === lastCheckedPoint[1])) {
5171
5174
  lastCheckedPoint = [x, y];
5172
5175
  checkedPath.push([x, y]);
5173
5176
  }
5174
5177
  });
5175
5178
  return checkedPath;
5176
5179
  }
5180
+ function distancePointToSegment(point3, start, end) {
5181
+ const segmentLength = Math.sqrt(
5182
+ (end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2
5183
+ );
5184
+ if (segmentLength === 0) {
5185
+ return {
5186
+ distance: Math.sqrt((point3[0] - start[0]) ** 2 + (point3[1] - start[1]) ** 2),
5187
+ closestPoint: start.slice(0)
5188
+ };
5189
+ }
5190
+ const t = Math.max(
5191
+ 0,
5192
+ Math.min(
5193
+ 1,
5194
+ ((point3[0] - start[0]) * (end[0] - start[0]) + (point3[1] - start[1]) * (end[1] - start[1])) / segmentLength ** 2
5195
+ )
5196
+ );
5197
+ const closestPoint = [
5198
+ start[0] + t * (end[0] - start[0]),
5199
+ start[1] + t * (end[1] - start[1])
5200
+ ];
5201
+ const distance = Math.sqrt(
5202
+ (point3[0] - closestPoint[0]) ** 2 + (point3[1] - closestPoint[1]) ** 2
5203
+ );
5204
+ return { distance, closestPoint };
5205
+ }
5206
+ function moveOnRoute(startPoint, endPoint, distance) {
5207
+ const [startX, startY] = startPoint;
5208
+ const [endX, endY] = endPoint;
5209
+ const routeLength = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
5210
+ const ratio = distance / routeLength;
5211
+ const newX = startX + (endX - startX) * ratio;
5212
+ const newY = startY + (endY - startY) * ratio;
5213
+ return [newX, newY];
5214
+ }
5177
5215
 
5178
5216
  // src/plugins/navigation/navigation.ts
5217
+ import { Group as TweenGroup2, Tween as Tween2 } from "@tweenjs/tween.js";
5218
+ var defaultConfig3 = {
5219
+ path: {},
5220
+ speed: 10,
5221
+ cheapMaximumDistance: 20,
5222
+ needStartPoi: false,
5223
+ startPoi: {}
5224
+ };
5179
5225
  var Navigation = class extends Plugin {
5180
5226
  path = null;
5181
5227
  worker = Worker2();
5182
5228
  fetchRoadStatus = false;
5183
5229
  uniqueKey = new UniqueKey();
5184
5230
  paths = [];
5185
- constructor(bmap, project) {
5231
+ options;
5232
+ pathTween = new TweenGroup2();
5233
+ startPoi = null;
5234
+ // 处理路线动画
5235
+ animationPathOptions = {
5236
+ cPathIndex: 0
5237
+ // 在平滑路线中的下标(平滑但是未做插值的数据,是做路线渲染的)
5238
+ };
5239
+ cPath = [];
5240
+ // 当前楼层的平滑后的路线
5241
+ constructor(bmap, project, options = {}) {
5186
5242
  super(bmap);
5243
+ this.options = Object.assign({}, defaultConfig3, options);
5187
5244
  const {
5188
5245
  apiDomain,
5189
5246
  apiPath: { roadNetwork },
@@ -5201,18 +5258,35 @@ var Navigation = class extends Plugin {
5201
5258
  this.dispatchEvent({ type: "fetch-road-status", status: true });
5202
5259
  }
5203
5260
  });
5261
+ this.registryEvent();
5262
+ }
5263
+ registryEvent() {
5264
+ this.bmap.context.addEventListener("update", this.onUpdate);
5204
5265
  this.bmap.addEventListener(
5205
5266
  "switch_floor_after" /* SWITCH_FLOOR_AFTER */,
5206
5267
  this.onSwitchFloor
5207
5268
  );
5208
5269
  }
5270
+ unRegistryEvent() {
5271
+ this.bmap.context.removeEventListener("update", this.onUpdate);
5272
+ this.bmap.removeEventListener(
5273
+ "switch_floor_after" /* SWITCH_FLOOR_AFTER */,
5274
+ this.onSwitchFloor
5275
+ );
5276
+ }
5277
+ onUpdate = () => {
5278
+ this.pathTween.update();
5279
+ };
5209
5280
  triggerWorker(type, data) {
5210
5281
  this.worker.postMessage({ type, data });
5211
5282
  }
5212
5283
  clearPath() {
5213
5284
  if (this.path) {
5214
5285
  this.bmap.context.scene.remove(this.path);
5286
+ this.path.dispose();
5215
5287
  this.path = null;
5288
+ this.pathTween.getAll().forEach((item) => item.stop());
5289
+ this.pathTween.removeAll();
5216
5290
  }
5217
5291
  }
5218
5292
  onSwitchFloor = ({ data: { curFloor } }) => {
@@ -5304,30 +5378,134 @@ var Navigation = class extends Plugin {
5304
5378
  });
5305
5379
  }
5306
5380
  renderPath(points) {
5307
- const cPath = this.catmullRomCurve3(points).map(([x, y]) => [
5308
- x,
5309
- y
5310
- ]);
5381
+ const cPath = this.catmullRomCurve3(points);
5382
+ this.cPath = cPath;
5383
+ this.animationPathOptions = {
5384
+ cPathIndex: 0
5385
+ };
5311
5386
  if (this.path) {
5312
5387
  this.path.updatePoints(cPath);
5313
5388
  } else {
5314
- this.path = new Path2(this, {});
5389
+ this.path = new Path2(this, this.options.path);
5315
5390
  this.path.create(cPath);
5316
5391
  this.path.position.z = this.bmap.context.currentFloor.groundMaxHeight + 0.1;
5317
5392
  this.bmap.context.scene.add(this.path);
5318
5393
  }
5394
+ if (this.startPoi) {
5395
+ this.startPoi.dispose();
5396
+ this.startPoi = null;
5397
+ }
5398
+ if (this.options.needStartPoi) {
5399
+ this.startPoi = this.bmap.context.currentFloor?.addPoi({
5400
+ ...this.options.startPoi,
5401
+ position: { x: cPath[0][0], y: cPath[0][1], z: 1e-4 },
5402
+ collision_enable: false
5403
+ }) || null;
5404
+ }
5319
5405
  }
5320
5406
  catmullRomCurve3(points) {
5321
- return simplifyPath(points, true, true, 10, 150, 3);
5407
+ return simplifyPath(points, false, true, 0.1, 150, 2.5);
5408
+ }
5409
+ /**
5410
+ * 按照指定速度移动到目标位置
5411
+ * @param point 目标位置
5412
+ * @param speed 移动速度
5413
+ */
5414
+ async animationTo(point3, speed = this.options.speed) {
5415
+ if (point3.floor !== this.bmap.context.currentFloor?.name || !this.path) {
5416
+ return;
5417
+ }
5418
+ const {
5419
+ animationPathOptions: { cPathIndex }
5420
+ } = this;
5421
+ const currentPath = [
5422
+ this.path.points[0],
5423
+ ...this.cPath.slice(cPathIndex + 1)
5424
+ ];
5425
+ const translatedPos = this.translatePoints([point3.pos])[0];
5426
+ const { distance, pos, index } = currentPath.reduce(
5427
+ (res, cur, index2, arr) => {
5428
+ if (index2 === arr.length - 1) {
5429
+ return res;
5430
+ }
5431
+ const { distance: distance2, closestPoint } = distancePointToSegment(
5432
+ translatedPos,
5433
+ cur,
5434
+ arr[index2 + 1]
5435
+ );
5436
+ if (distance2 < res.distance) {
5437
+ res.distance = distance2;
5438
+ res.pos = closestPoint;
5439
+ res.index = index2;
5440
+ }
5441
+ return res;
5442
+ },
5443
+ {
5444
+ distance: Number.MAX_SAFE_INTEGER,
5445
+ pos: point3.pos,
5446
+ index: 0
5447
+ }
5448
+ );
5449
+ if (distance > this.options.cheapMaximumDistance) {
5450
+ return;
5451
+ }
5452
+ if (this.path.points[0][0] === pos[0] && this.path.points[0][1] === pos[1]) {
5453
+ return;
5454
+ }
5455
+ let moveDistance = 0;
5456
+ let moveDistanceArray = [];
5457
+ if (index === 0) {
5458
+ moveDistance = getLength(currentPath[0], pos);
5459
+ moveDistanceArray = [moveDistance];
5460
+ } else {
5461
+ moveDistanceArray = [getLength(currentPath[0], currentPath[1])];
5462
+ for (let i = 1; i < index; i++) {
5463
+ moveDistanceArray.push(getLength(currentPath[i], currentPath[i + 1]));
5464
+ }
5465
+ moveDistanceArray.push(getLength(currentPath[index], pos));
5466
+ moveDistance = moveDistanceArray.reduce((sum, cur) => sum + cur, 0);
5467
+ }
5468
+ const speedSecond = this.kmPerHourToMetersPerSecond(speed);
5469
+ const timeSecond = moveDistance / speedSecond;
5470
+ this.pathTween.getAll().forEach((item) => item.stop());
5471
+ this.pathTween.removeAll();
5472
+ const start = { distance: 0 };
5473
+ return new Promise((resolve) => {
5474
+ const tween = new Tween2(start, this.pathTween).to({ distance: moveDistance }, timeSecond * 1e3).onUpdate(() => {
5475
+ for (let i = 0; i < moveDistanceArray.length; i++) {
5476
+ const sumDistance = moveDistanceArray.slice(0, i + 1).reduce((sum, cur) => sum + cur, 0);
5477
+ if (sumDistance >= start.distance) {
5478
+ const prevDistance = sumDistance - moveDistanceArray[i];
5479
+ const needDistance = start.distance - prevDistance;
5480
+ const startPoint = currentPath[i];
5481
+ const nextPoint = currentPath[i + 1];
5482
+ const pos2 = moveOnRoute(startPoint, nextPoint, needDistance);
5483
+ this.path?.updatePoints([pos2, ...currentPath.slice(i + 1)]);
5484
+ this.animationPathOptions.cPathIndex += i;
5485
+ if (this.startPoi) {
5486
+ this.startPoi.position.setX(pos2[0]).setY(pos2[1]);
5487
+ }
5488
+ this.dispatchEvent({ type: "path-animation" });
5489
+ return;
5490
+ }
5491
+ }
5492
+ }).onComplete(() => {
5493
+ this.pathTween.remove(tween);
5494
+ this.dispatchEvent({ type: "path-animation-end" });
5495
+ resolve(true);
5496
+ }).start();
5497
+ });
5498
+ }
5499
+ kmPerHourToMetersPerSecond(speedInKmPerHour) {
5500
+ const speedInMetersPerSecond = speedInKmPerHour * 1e3 / 3600;
5501
+ return speedInMetersPerSecond;
5322
5502
  }
5323
5503
  dispose() {
5324
5504
  this.worker.terminate();
5325
- this.bmap.removeEventListener(
5326
- "switch_floor_after" /* SWITCH_FLOOR_AFTER */,
5327
- this.onSwitchFloor
5328
- );
5505
+ this.unRegistryEvent();
5329
5506
  this.path?.dispose();
5330
5507
  this.uniqueKey.dispose();
5508
+ this.startPoi?.dispose();
5331
5509
  }
5332
5510
  };
5333
5511