@aibee/crc-bmap 0.8.43 → 0.8.45

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
@@ -524,7 +524,6 @@ var Timer = class {
524
524
  }
525
525
  setInterval(fn, wait) {
526
526
  const timer = window.setInterval(() => {
527
- this.tasks.interval.delete(timer);
528
527
  fn();
529
528
  }, wait);
530
529
  this.tasks.interval.add(timer);
@@ -7798,7 +7797,9 @@ var Control = class extends OrbitControls {
7798
7797
  }).onStart(() => {
7799
7798
  _this.enabled = false;
7800
7799
  }).start();
7801
- }), duration + 500);
7800
+ }), duration + 500).finally(() => {
7801
+ _this.enabled = true;
7802
+ });
7802
7803
  })();
7803
7804
  }
7804
7805
  setTargetByOffset(offsetY, target = this.target.clone()) {
@@ -9711,10 +9712,10 @@ var Path2 = class extends Object3D14 {
9711
9712
 
9712
9713
  // ../lib/src/plugins/navigation/navigation.js
9713
9714
  import { Tween as Tween3, Easing } from "@tweenjs/tween.js";
9714
- import { Vector3 as Vector321 } from "three";
9715
+ import { Vector2 as Vector216, Vector3 as Vector321 } from "three";
9715
9716
 
9716
9717
  // ../lib/src/plugins/navigation/position-navigation.js
9717
- import { EventDispatcher as EventDispatcher13 } from "three";
9718
+ import { EventDispatcher as EventDispatcher13, Vector2 as Vector215 } from "three";
9718
9719
  import { Tween as Tween2 } from "@tweenjs/tween.js";
9719
9720
  import { throttle } from "lodash";
9720
9721
  var defaultConfig3 = {
@@ -9828,7 +9829,6 @@ var PositionNavigation = class extends EventDispatcher13 {
9828
9829
  }
9829
9830
  toPosition(floor, pos) {
9830
9831
  const adsorbData = this.adsorb(floor, pos);
9831
- console.log("adsorbData", adsorbData);
9832
9832
  if (!adsorbData) {
9833
9833
  return;
9834
9834
  }
@@ -9970,6 +9970,8 @@ var PositionNavigation = class extends EventDispatcher13 {
9970
9970
  let dir = PathDirection.FRONT;
9971
9971
  let crossName = (curRoutePath == null ? void 0 : (_curRoutePath_pointInfos_index = curRoutePath.pointInfos[index]) == null ? void 0 : _curRoutePath_pointInfos_index.crossName) || "";
9972
9972
  let distance = 0;
9973
+ let angle = 0;
9974
+ let nextAngle = 0;
9973
9975
  while (dir === PathDirection.FRONT && index <= curRoutePathPoints.length) {
9974
9976
  const p1 = curRoutePathPoints[index];
9975
9977
  const p2 = curRoutePathPoints[index + 1];
@@ -9977,40 +9979,40 @@ var PositionNavigation = class extends EventDispatcher13 {
9977
9979
  if (!p1 || !p2) {
9978
9980
  dir = PathDirection.END;
9979
9981
  } else {
9980
- if (pointIndex === 0) {
9981
- const l = getLength(p1, position);
9982
- if (l < 5) {
9983
- dir = PathDirection.START;
9984
- } else {
9985
- dir = PathDirection.FRONT;
9986
- index += 1;
9987
- }
9982
+ distance += getLength(p1, p2);
9983
+ if (!p3) {
9984
+ dir = PathDirection.END;
9988
9985
  } else {
9989
- distance += getLength(p1, p2);
9990
- if (!p3) {
9991
- dir = PathDirection.END;
9992
- } else {
9993
- dir = calc_direction(p1, p2, p3);
9994
- var _curRoutePath_pointInfos__crossName;
9995
- crossName = (_curRoutePath_pointInfos__crossName = curRoutePath == null ? void 0 : curRoutePath.pointInfos[index + 1].crossName) != null ? _curRoutePath_pointInfos__crossName : "";
9996
- index += 1;
9997
- }
9986
+ dir = calc_direction(p1, p2, p3);
9987
+ angle = calc_angle(p1, p2, p3);
9988
+ const nextRadians = new Vector215(p3[0] - p2[0], p3[1] - p2[1]).angle();
9989
+ nextAngle = (nextRadians * 180 / Math.PI - 90 + 360) % 360;
9990
+ var _curRoutePath_pointInfos__crossName;
9991
+ crossName = (_curRoutePath_pointInfos__crossName = curRoutePath == null ? void 0 : curRoutePath.pointInfos[index + 1].crossName) != null ? _curRoutePath_pointInfos__crossName : "";
9992
+ index += 1;
9998
9993
  }
9999
9994
  }
10000
9995
  }
9996
+ if (curRoutePathPoints[index]) {
9997
+ distance = getLength(position, curRoutePathPoints[index]);
9998
+ }
10001
9999
  if (dir === PathDirection.END && distance <= this.options.directionEmitThreshold) {
10002
10000
  return {
10003
10001
  dir,
10004
10002
  distance,
10005
- crossName
10003
+ crossName,
10004
+ angle,
10005
+ nextAngle
10006
10006
  };
10007
10007
  }
10008
10008
  const distanceToStart = this.getCurRouteToStartDistance();
10009
- if (distanceToStart <= 5) {
10009
+ if (pointIndex === 0 && distanceToStart <= 5) {
10010
10010
  return {
10011
10011
  dir: PathDirection.START,
10012
10012
  distance,
10013
- crossName
10013
+ crossName,
10014
+ angle,
10015
+ nextAngle
10014
10016
  };
10015
10017
  }
10016
10018
  if (distance >= this.options.directionEmitThreshold) {
@@ -10019,7 +10021,9 @@ var PositionNavigation = class extends EventDispatcher13 {
10019
10021
  return {
10020
10022
  dir,
10021
10023
  distance,
10022
- crossName
10024
+ crossName,
10025
+ angle,
10026
+ nextAngle
10023
10027
  };
10024
10028
  }
10025
10029
  getNavigationInfo() {
@@ -10028,7 +10032,7 @@ var PositionNavigation = class extends EventDispatcher13 {
10028
10032
  if (!nextDirInfo) {
10029
10033
  return null;
10030
10034
  }
10031
- let { dir, distance: nextDirDistance, crossName } = nextDirInfo;
10035
+ let { dir, distance: nextDirDistance, crossName, angle, nextAngle } = nextDirInfo;
10032
10036
  if (curRouteRemainDistance <= 10) {
10033
10037
  dir = PathDirection.END;
10034
10038
  }
@@ -10037,6 +10041,8 @@ var PositionNavigation = class extends EventDispatcher13 {
10037
10041
  curRouteDistance: curRouteRemainDistance,
10038
10042
  nextDirDistance,
10039
10043
  dir,
10044
+ angle,
10045
+ nextAngle,
10040
10046
  pos: this.position,
10041
10047
  routeIndex: this.routeIndex,
10042
10048
  crossName,
@@ -10231,7 +10237,8 @@ var defaultConfig4 = {
10231
10237
  directionEmitThreshold: 5,
10232
10238
  disablePathAnimation: false,
10233
10239
  speed: 1,
10234
- roadData: []
10240
+ roadData: [],
10241
+ runAnimationMaxTime: 1
10235
10242
  };
10236
10243
  var Navigation = class extends Plugin {
10237
10244
  get curFloorPathLength() {
@@ -10248,6 +10255,7 @@ var Navigation = class extends Plugin {
10248
10255
  this.bmap.context.addEventListener("update", this.onUpdate);
10249
10256
  this.bmap.addEventListener(HooksName.SWITCH_FLOOR_AFTER, this.onSwitchFloor);
10250
10257
  this.positionNavigation.addEventListener("navigation-info", this.onNavigationInfo);
10258
+ this.bmap.context.addEventListener("control-change", this.onControlChangeForStartPoi);
10251
10259
  }
10252
10260
  showStartRotateHelperPoi() {
10253
10261
  var _this_bmap_context_currentFloor;
@@ -10319,6 +10327,7 @@ var Navigation = class extends Plugin {
10319
10327
  this.bmap.context.removeEventListener("update", this.onUpdate);
10320
10328
  this.bmap.removeEventListener(HooksName.SWITCH_FLOOR_AFTER, this.onSwitchFloor);
10321
10329
  this.positionNavigation.removeEventListener("navigation-info", this.onNavigationInfo);
10330
+ this.bmap.context.removeEventListener("control-change", this.onControlChangeForStartPoi);
10322
10331
  }
10323
10332
  clearPath() {
10324
10333
  if (this.path) {
@@ -10343,9 +10352,11 @@ var Navigation = class extends Plugin {
10343
10352
  if (path === null) {
10344
10353
  this.curFloorPath = null;
10345
10354
  this.currentPathPosition = null;
10355
+ this.toPointPosition = null;
10346
10356
  } else {
10347
10357
  this.curFloorPath = path;
10348
10358
  this.currentPathPosition = path.points[0];
10359
+ this.toPointPosition = path.points[0];
10349
10360
  }
10350
10361
  this.movedDistance = 0;
10351
10362
  this.clearTween();
@@ -10466,6 +10477,21 @@ var Navigation = class extends Plugin {
10466
10477
  const finalAngle = sign * angle;
10467
10478
  return finalAngle;
10468
10479
  }
10480
+ // 计算路线的方向 0 ~ 360
10481
+ getPathDirection2() {
10482
+ if (!this.curFloorPath || !this.toPointPosition) {
10483
+ return null;
10484
+ }
10485
+ if (this.curFloorPathPoints.length < 2) {
10486
+ return null;
10487
+ }
10488
+ const index = getPointEdgeIndex(this.curFloorPathPoints, this.toPointPosition);
10489
+ const l1 = this.curFloorPathPoints[index];
10490
+ const l2 = this.curFloorPathPoints[index + 1];
10491
+ const v1 = new Vector216(l2[0] - l1[0], l2[1] - l1[1]).normalize();
10492
+ const angle = v1.angle() * 180 / Math.PI;
10493
+ return (angle - 90 + 360) % 360;
10494
+ }
10469
10495
  // 把相机旋转到路线的上方向
10470
10496
  changeCameraToPathUp(duration = 100) {
10471
10497
  var _this = this;
@@ -10638,7 +10664,7 @@ var Navigation = class extends Plugin {
10638
10664
  if (!distance) {
10639
10665
  return;
10640
10666
  }
10641
- const time = Math.min(distance / speed, 1);
10667
+ const time = Math.min(distance / speed, _this.options.runAnimationMaxTime);
10642
10668
  if (_this.pathTween) {
10643
10669
  _this.clearTween();
10644
10670
  }
@@ -10686,6 +10712,7 @@ var Navigation = class extends Plugin {
10686
10712
  })();
10687
10713
  }
10688
10714
  setStartPoiRotate(rotate) {
10715
+ this.startPoiRotate = rotate;
10689
10716
  if (this.startPoi) {
10690
10717
  const azimuthalAngle = this.bmap.context.control.getAzimuthalAngle();
10691
10718
  const azimuthal = (azimuthalAngle * 180 / Math.PI + 360) % 360;
@@ -10709,7 +10736,7 @@ var Navigation = class extends Plugin {
10709
10736
  this.positionNavigation.dispose();
10710
10737
  }
10711
10738
  constructor(bmap, project = {}, options) {
10712
- super(bmap), this.path = null, this.fetchRoadStatus = false, this.paths = [], this.curPathIndex = 0, this.curFloorPath = null, this.translatePath = null, this.currentPathPosition = null, this.pathTween = null, this.startPoi = null, this.startRotateHelperPoi = null, this.needStartRotateHelperPoi = false, this.movedDistance = 0, this.pathStart = [
10739
+ super(bmap), this.path = null, this.fetchRoadStatus = false, this.paths = [], this.curPathIndex = 0, this.curFloorPath = null, this.translatePath = null, this.currentPathPosition = null, this.toPointPosition = null, this.pathTween = null, this.startPoi = null, this.startPoiRotate = 0, this.startRotateHelperPoi = null, this.needStartRotateHelperPoi = false, this.movedDistance = 0, this.pathStart = [
10713
10740
  0,
10714
10741
  0
10715
10742
  ], this.tweenUtil = new TweenUtil(), this.taskQueue = new TaskQueue(), // 处理路线动画
@@ -10724,6 +10751,7 @@ var Navigation = class extends Plugin {
10724
10751
  if (info.routeIndex !== this.curPathIndex) {
10725
10752
  return;
10726
10753
  }
10754
+ this.toPointPosition = info.pos;
10727
10755
  this.toPositionByTask(info.pos);
10728
10756
  }
10729
10757
  }, this.onUpdate = () => {
@@ -10741,6 +10769,10 @@ var Navigation = class extends Plugin {
10741
10769
  } else {
10742
10770
  this.clearPath();
10743
10771
  }
10772
+ }, this.onControlChangeForStartPoi = () => {
10773
+ if (this.startPoi) {
10774
+ this.setStartPoiRotate(this.startPoiRotate);
10775
+ }
10744
10776
  };
10745
10777
  if (!options && typeof project === "object") {
10746
10778
  options = project;
@@ -12287,7 +12319,7 @@ var PdrPosition = class extends EventDispatcher17 {
12287
12319
  };
12288
12320
 
12289
12321
  // ../lib/src/plugins/mul-floor-navigation/path.js
12290
- import { Mesh as Mesh12, Object3D as Object3D15, TextureLoader as TextureLoader3, Color as Color8, Vector2 as Vector215, Vector3 as Vector323, NormalBlending as NormalBlending2, RepeatWrapping as RepeatWrapping2 } from "three";
12322
+ import { Mesh as Mesh12, Object3D as Object3D15, TextureLoader as TextureLoader3, Color as Color8, Vector2 as Vector217, Vector3 as Vector323, NormalBlending as NormalBlending2, RepeatWrapping as RepeatWrapping2 } from "three";
12291
12323
  var defaultConfig5 = {
12292
12324
  texture_url: Arrow3,
12293
12325
  lineWidth: 8,
@@ -12318,7 +12350,7 @@ var MulPath = class extends Object3D15 {
12318
12350
  return;
12319
12351
  }
12320
12352
  const repeat = this.getRepeat();
12321
- this.material.repeat = new Vector215(repeat, 1);
12353
+ this.material.repeat = new Vector217(repeat, 1);
12322
12354
  }
12323
12355
  loadTexture(url) {
12324
12356
  return new Promise((r, j) => {
@@ -12359,13 +12391,13 @@ var MulPath = class extends Object3D15 {
12359
12391
  useMap: true,
12360
12392
  color: new Color8(_this.config.color),
12361
12393
  transparent: true,
12362
- resolution: new Vector215(_this.navigation.bmap.context.clientSize.width, _this.navigation.bmap.context.clientSize.height),
12394
+ resolution: new Vector217(_this.navigation.bmap.context.clientSize.width, _this.navigation.bmap.context.clientSize.height),
12363
12395
  depthTest: true,
12364
12396
  sizeAttenuation: false,
12365
12397
  lineWidth: _this.config.lineWidth * 2,
12366
12398
  map: _this.texture,
12367
12399
  blending: NormalBlending2,
12368
- repeat: new Vector215(_this.getRepeat(), 1)
12400
+ repeat: new Vector217(_this.getRepeat(), 1)
12369
12401
  });
12370
12402
  const mesh = _this.mesh = new Mesh12(lineGeometry, material);
12371
12403
  mesh.renderOrder = 9;
@@ -12408,7 +12440,7 @@ var MulPath = class extends Object3D15 {
12408
12440
  import { Tween as Tween4 } from "@tweenjs/tween.js";
12409
12441
 
12410
12442
  // ../lib/src/plugins/mul-floor-navigation/start-model.js
12411
- import { AnimationMixer, Box3 as Box310, Object3D as Object3D16, Box2 as Box23, Vector3 as Vector324, Vector2 as Vector216 } from "three";
12443
+ import { AnimationMixer, Box3 as Box310, Object3D as Object3D16, Box2 as Box23, Vector3 as Vector324, Vector2 as Vector218 } from "three";
12412
12444
  var StartModel = class extends Object3D16 {
12413
12445
  getBaseScale(object) {
12414
12446
  const { clientSize: { width, height }, camera } = this.bmap.context;
@@ -12423,12 +12455,12 @@ var StartModel = class extends Object3D16 {
12423
12455
  const leftBottom2d = vector3ToDevice(leftBottom, camera, width, height);
12424
12456
  const rightBottom2d = vector3ToDevice(rightBottom, camera, width, height);
12425
12457
  const boundingBox2d = new Box23().setFromPoints([
12426
- new Vector216(leftTop2d.x, leftTop2d.y),
12427
- new Vector216(rightTop2d.x, rightTop2d.y),
12428
- new Vector216(leftBottom2d.x, leftBottom2d.y),
12429
- new Vector216(rightBottom2d.x, rightBottom2d.y)
12458
+ new Vector218(leftTop2d.x, leftTop2d.y),
12459
+ new Vector218(rightTop2d.x, rightTop2d.y),
12460
+ new Vector218(leftBottom2d.x, leftBottom2d.y),
12461
+ new Vector218(rightBottom2d.x, rightBottom2d.y)
12430
12462
  ]);
12431
- const size = boundingBox2d.getSize(new Vector216());
12463
+ const size = boundingBox2d.getSize(new Vector218());
12432
12464
  const xScale = 40 / size.x;
12433
12465
  const yScale = 40 / size.y;
12434
12466
  const scale = Math.min(xScale, yScale);
@@ -12723,7 +12755,7 @@ var MulFloorNavigation = class extends Plugin {
12723
12755
  };
12724
12756
 
12725
12757
  // ../lib/src/plugins/mul-floor-select/mul-floor-select.js
12726
- import { EventDispatcher as EventDispatcher18, Raycaster as Raycaster2, Vector2 as Vector217 } from "three";
12758
+ import { EventDispatcher as EventDispatcher18, Raycaster as Raycaster2, Vector2 as Vector219 } from "three";
12727
12759
  var MulFloorSelect = class extends EventDispatcher18 {
12728
12760
  registryEvent() {
12729
12761
  this.clickHelper.addEventListener("click", this._click);
@@ -12740,7 +12772,7 @@ var MulFloorSelect = class extends EventDispatcher18 {
12740
12772
  if (!this.mulFloors.showStatus) {
12741
12773
  return;
12742
12774
  }
12743
- const point3 = new Vector217();
12775
+ const point3 = new Vector219();
12744
12776
  const { offsetX: x, offsetY: y } = e;
12745
12777
  const { clientSize } = this.bmap.context;
12746
12778
  point3.x = x / clientSize.width * 2 - 1;
@@ -12791,14 +12823,10 @@ var MulFloorSelect = class extends EventDispatcher18 {
12791
12823
  };
12792
12824
 
12793
12825
  // ../lib/src/plugins/car-inertial-position/car-inertial-position.js
12794
- import { EventDispatcher as EventDispatcher20 } from "three";
12795
-
12796
- // ../lib/src/plugins/car-inertial-position/compass.js
12797
- import { isNil as isNil5 } from "lodash";
12798
12826
  import { EventDispatcher as EventDispatcher19 } from "three";
12799
12827
 
12800
12828
  // ../lib/src/plugins/car-inertial-position/utils.js
12801
- import { Vector2 as Vector218 } from "three";
12829
+ import { Vector2 as Vector220 } from "three";
12802
12830
  function linearFit(points) {
12803
12831
  const n = points.length;
12804
12832
  let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
@@ -12847,7 +12875,7 @@ function calculateLineDirection(points) {
12847
12875
  }
12848
12876
  const { m, b } = linearFit(filteredPoints);
12849
12877
  const { start, end } = getLineEndpoints(m, b, filteredPoints);
12850
- const radians = new Vector218().subVectors(new Vector218(end[0], end[1]), new Vector218(start[0], start[1])).angle();
12878
+ const radians = new Vector220().subVectors(new Vector220(end[0], end[1]), new Vector220(start[0], start[1])).angle();
12851
12879
  const angle = 360 - (radians / Math.PI * 180 - 90 + 360) % 360;
12852
12880
  if (Number.isNaN(angle)) {
12853
12881
  return null;
@@ -12876,11 +12904,11 @@ function calculateInstantaneousSpeed(positions) {
12876
12904
  function predictFutureSpeed(positions, timeIntervalMs) {
12877
12905
  const first = positions[0];
12878
12906
  const last = positions.slice(-1)[0];
12879
- const distance = positions.slice(1).reduce((sum, cur, index) => {
12880
- const l = getLength(cur.position, positions[index].position);
12881
- return sum + l;
12882
- }, 0);
12907
+ const distance = getLength(last.position, first.position);
12883
12908
  const time = last.time - first.time;
12909
+ if (time < 100 || distance < 3) {
12910
+ return null;
12911
+ }
12884
12912
  return distance / time;
12885
12913
  }
12886
12914
  function transformSpeed(speed) {
@@ -12889,11 +12917,11 @@ function transformSpeed(speed) {
12889
12917
  function predictFuturePosition(lastPosition, speed, angle, time) {
12890
12918
  const angleInRadians = (angle + 90) % 360 * (Math.PI / 180);
12891
12919
  const distance = speed * time;
12892
- const vec = new Vector218(lastPosition[0], lastPosition[1]);
12920
+ const vec = new Vector220(lastPosition[0], lastPosition[1]);
12893
12921
  const vX = Math.cos(angleInRadians);
12894
12922
  const vY = Math.sin(angleInRadians);
12895
- const dir = new Vector218(vX, vY);
12896
- vec.add(dir.normalize().multiplyScalar(distance + 2));
12923
+ const dir = new Vector220(vX, vY);
12924
+ vec.add(dir.normalize().multiplyScalar(distance));
12897
12925
  return [
12898
12926
  vec.x,
12899
12927
  vec.y
@@ -12923,189 +12951,267 @@ function percentile(arr, p) {
12923
12951
  return arr[lower] * (1 - weight) + arr[upper] * weight;
12924
12952
  }
12925
12953
 
12926
- // ../lib/src/plugins/car-inertial-position/compass.js
12927
- var Compass = class extends EventDispatcher19 {
12928
- start() {
12929
- this.listenDeviceOrientation();
12954
+ // ../lib/src/plugins/car-inertial-position/kalman-filter.js
12955
+ var KalmanFilter = class {
12956
+ // 核心滤波方法
12957
+ filter(measurement) {
12958
+ const prediction = this.estimate;
12959
+ const predictionError = this.errorEstimate + this.processNoise;
12960
+ const kalmanGain = predictionError / (predictionError + this.measurementNoise);
12961
+ this.estimate = prediction + kalmanGain * (measurement - prediction);
12962
+ this.errorEstimate = (1 - kalmanGain) * predictionError;
12963
+ return this.estimate;
12964
+ }
12965
+ constructor(options = {}) {
12966
+ this.estimate = 0;
12967
+ this.errorEstimate = 1;
12968
+ this.processNoise = 0.1;
12969
+ this.measurementNoise = 1;
12970
+ this.measurementNoise = options.measurementNoise || 1;
12971
+ this.processNoise = options.processNoise || 0.1;
12972
+ this.errorEstimate = options.errorEstimate || 1;
12973
+ }
12974
+ };
12975
+
12976
+ // ../lib/src/plugins/car-inertial-position/car-inertial-position.js
12977
+ import { isNil as isNil5 } from "lodash";
12978
+ var CarInertialPosition = class extends EventDispatcher19 {
12979
+ setPathAngle(angle) {
12980
+ this.pathAngle = angle;
12930
12981
  this.dispatchEvent({
12931
- type: "start"
12982
+ type: "change-compass",
12983
+ value: this.pathAngle
12932
12984
  });
12933
- }
12934
- /**
12935
- * 设置一个根据视觉定位返回的绝对角度 校准delta
12936
- * @param compass
12937
- * @param time
12938
- */
12939
- setAbsoluteCompass(compass, time) {
12940
- if (!this.delta) {
12941
- this.emitCompass(compass);
12985
+ if (isNil5(this.angle)) {
12986
+ this.angle = angle;
12942
12987
  }
12943
- if (!this.compassData.length) {
12944
- return;
12945
- }
12946
- this.absoluteCompass = {
12947
- compass,
12948
- time
12949
- };
12950
- let cutTimeCompassIndex = this.compassData.findIndex((item) => item.timestamp >= time);
12951
- if (cutTimeCompassIndex === -1) {
12952
- cutTimeCompassIndex = this.compassData.length - 1;
12953
- }
12954
- const prevCompass = this.compassData[cutTimeCompassIndex - 1];
12955
- const nextCompass = this.compassData[cutTimeCompassIndex];
12956
- let curCompass;
12957
- if (!prevCompass) {
12958
- curCompass = nextCompass;
12959
- } else if (!nextCompass) {
12988
+ }
12989
+ changeSpeed() {
12990
+ const serverHistory = this.history.filter((item) => [
12991
+ "vision"
12992
+ ].includes(item.type));
12993
+ if (serverHistory.length < 2) {
12994
+ this.speedFilter.filter(0);
12995
+ this.speed = 0;
12960
12996
  return;
12961
- } else {
12962
- curCompass = nextCompass.timestamp - time > prevCompass.timestamp - time ? prevCompass : nextCompass;
12963
12997
  }
12964
- const delta = compass - curCompass.res;
12965
- this.deltas.push(delta);
12966
- const deltas = removeOutliers(this.deltas);
12967
- if (deltas.length) {
12968
- this.delta = deltas.reduce((sum, cur) => sum + cur, 0) / deltas.length;
12998
+ ;
12999
+ const first = serverHistory[0];
13000
+ const last = serverHistory.slice(-1)[0];
13001
+ const distance = getLength(last.position, first.position);
13002
+ const time = last.time - first.time;
13003
+ const speed = time > 0 ? distance / time : 0;
13004
+ const smoothedSpeed = this.speedFilter.filter(speed);
13005
+ this.speed = smoothedSpeed;
13006
+ }
13007
+ changeAngle(histories = this.visionHistory) {
13008
+ if (histories.length < 2) {
13009
+ this.angle = null;
13010
+ }
13011
+ ;
13012
+ const angle = calculateLineDirection(histories.map((item) => item.position));
13013
+ if (angle !== null) {
13014
+ this.setAngle(angle);
12969
13015
  }
12970
13016
  }
12971
- emitCompass(compass) {
12972
- console.log("compass delta", this.delta, compass);
12973
- this.dispatchEvent({
12974
- type: "compass",
12975
- value: (compass + this.delta + 360) % 360
12976
- });
13017
+ setAngle(angle, dispatch = true) {
13018
+ this.angle = angle;
13019
+ if (dispatch) {
13020
+ this.dispatchEvent({
13021
+ type: "change-position-compass",
13022
+ value: angle
13023
+ });
13024
+ }
12977
13025
  }
12978
13026
  /**
12979
- * 获取 compass 和 deviceMotion
13027
+ * 添加视觉结果
13028
+ * @param position
13029
+ * @param time
13030
+ * @param duration
13031
+ * @returns
12980
13032
  */
12981
- listenDeviceOrientation() {
12982
- if (isIphone) {
12983
- window.addEventListener("deviceorientation", this.deviceOrientationAbsHandler, false);
12984
- } else {
12985
- window.addEventListener("deviceorientationabsolute", this.deviceOrientationAbsHandler, {
12986
- absolute: true
12987
- });
13033
+ setPosition(position, time, duration) {
13034
+ const item = {
13035
+ position,
13036
+ time,
13037
+ clientTime: Date.now() - duration,
13038
+ type: "vision"
13039
+ };
13040
+ this._setVisionHistoryForAngle(item);
13041
+ if (isNil5(this.angle) || !this.speed) {
13042
+ this.addHistory(item);
13043
+ return;
12988
13044
  }
12989
- }
12990
- checkSensor() {
12991
- var _this = this;
12992
- return _async_to_generator(function* () {
12993
- const deviceOrientation = yield _this.checkDeviceOrientation();
12994
- return {
12995
- deviceOrientation
12996
- };
12997
- })();
12998
- }
12999
- checkDeviceOrientation() {
13000
- return _async_to_generator(function* () {
13001
- var _window_DeviceOrientationEvent;
13002
- if (!isIphone) {
13003
- return true;
13045
+ const lastIndex = this.history.findLastIndex((item2) => item2.type === "vision");
13046
+ const last = this.history[lastIndex];
13047
+ if (last) {
13048
+ if (last.time > time) {
13049
+ return;
13004
13050
  }
13005
- if (typeof window.DeviceOrientationEvent !== "undefined" && typeof ((_window_DeviceOrientationEvent = window.DeviceOrientationEvent) == null ? void 0 : _window_DeviceOrientationEvent.requestPermission) === "function") {
13006
- try {
13007
- var _window_DeviceOrientationEvent1;
13008
- const permission = yield (_window_DeviceOrientationEvent1 = window.DeviceOrientationEvent) == null ? void 0 : _window_DeviceOrientationEvent1.requestPermission();
13009
- return permission === "granted";
13010
- } catch (e) {
13011
- return false;
13012
- }
13051
+ const angle = calculateLineDirection([
13052
+ this.history.slice(-1)[0].position,
13053
+ position
13054
+ ]);
13055
+ if (angle && Math.abs(angle - this.angle) < 60) {
13056
+ this.addHistory(item);
13057
+ return;
13058
+ }
13059
+ const predictPos = predictFuturePosition(position, this.speed, 360 - this.pathAngle, duration);
13060
+ const distance = getLength(predictPos, this.history.slice(-1)[0].position);
13061
+ if (distance > 10) {
13062
+ this.visionExcessesCount++;
13063
+ } else {
13064
+ this.visionExcessesCount = 0;
13065
+ }
13066
+ if (this.visionExcessesCount > 3) {
13067
+ console.warn("\u8FDE\u7EED\u4E09\u6B21\u89C6\u89C9\u548Cpdr\u5DEE\u8DDD\u5927\u4E8E5\u7C73\uFF0C\u4F7F\u7528\u89C6\u89C9\u6821\u51C6");
13068
+ this.addHistory(item);
13069
+ this.visionExcessesCount = 0;
13013
13070
  }
13014
- return false;
13015
- })();
13016
- }
13017
- stop() {
13018
- if (isIphone) {
13019
- window.removeEventListener("deviceorientation", this.deviceOrientationAbsHandler, false);
13020
- } else {
13021
- window.removeEventListener("deviceorientationabsolute", this.deviceOrientationAbsHandler, {
13022
- absolute: true
13023
- });
13024
13071
  }
13025
- this.compassData = [];
13026
- this.dispatchEvent({
13027
- type: "stop"
13028
- });
13029
13072
  }
13030
- constructor() {
13031
- super(), this.compassData = [], this.absoluteCompass = null, this.delta = 0, this.deltas = [], this.deviceOrientationAbsHandler = (e) => {
13032
- const currTime = Date.now();
13033
- const { alpha, beta, gamma } = e;
13034
- if (isNil5(alpha) || isNil5(beta) || isNil5(gamma)) {
13035
- return;
13073
+ resetPdrPosition() {
13074
+ const lastVision = this.history.findLast((item) => item.type === "vision");
13075
+ if (lastVision && this.speed) {
13076
+ const predictPos = predictFuturePosition(lastVision.position, this.speed, 360 - this.pathAngle, Date.now() - lastVision.clientTime);
13077
+ if (predictPos) {
13078
+ this.history.push({
13079
+ position: predictPos,
13080
+ time: Date.now(),
13081
+ clientTime: Date.now(),
13082
+ type: "pdr"
13083
+ });
13036
13084
  }
13037
- const compass = isIphone ? e.webkitCompassHeading : 360 - alpha;
13038
- this.compassData.push({
13039
- timestamp: currTime,
13040
- res: compass
13041
- });
13042
- this.emitCompass(compass);
13043
- };
13085
+ }
13044
13086
  }
13045
- };
13046
-
13047
- // ../lib/src/plugins/car-inertial-position/car-inertial-position.js
13048
- var CarInertialPosition = class extends EventDispatcher20 {
13049
- startCompass() {
13050
- this.compass.start();
13087
+ /**
13088
+ * 获取 最后一个视觉坐标在加了pdr惯性的坐标
13089
+ */
13090
+ getLastVisionPdrPos() {
13091
+ const lastIndex = this.history.findLastIndex((item) => item.type === "vision");
13092
+ if (lastIndex !== -1) {
13093
+ var _this_history_;
13094
+ return (_this_history_ = this.history[lastIndex + 1]) != null ? _this_history_ : this.history[lastIndex];
13095
+ }
13096
+ return null;
13051
13097
  }
13052
- setPosition(position, time, duration) {
13053
- this.history.push({
13054
- position,
13055
- time,
13056
- clientTime: Date.now(),
13057
- type: "vision"
13058
- });
13059
- const MAX_DISTANCE = 5;
13060
- for (let i = 0; i < this.history.length; i++) {
13061
- const item = this.history[i];
13062
- const distance = getLength(item.position, position);
13063
- if (distance > MAX_DISTANCE) {
13064
- this.history.shift();
13065
- i--;
13098
+ _setVisionHistoryForAngle(history) {
13099
+ if (!this.visionHistory.length) {
13100
+ this.visionHistory.push(history);
13101
+ return;
13102
+ }
13103
+ const angle = calculateLineDirection([
13104
+ this.visionHistory.slice(-1)[0].position,
13105
+ history.position
13106
+ ]);
13107
+ if (angle !== null) {
13108
+ if (this.angle && Math.abs(this.angle - angle) > 60) {
13109
+ this.angleExcessesCount++;
13066
13110
  } else {
13067
- break;
13111
+ this.angleExcessesCount = 0;
13112
+ this.visionHistory.push(history);
13068
13113
  }
13069
13114
  }
13070
- const posInfo = this.getPosition("vision");
13071
- this.dispatchEvent({
13072
- type: "change-pos",
13073
- value: posInfo
13074
- });
13075
- this.startPositionTimer();
13076
- }
13077
- setBeaconPosition(position, time) {
13078
- this.history.push({
13115
+ if (this.angleExcessesCount > 3) {
13116
+ console.warn("\u8FDE\u7EED\u4E09\u6B21\u89D2\u5EA6\u6BD4\u8F83\u6B6A\uFF0C\u91CD\u65B0\u77EB\u6B63");
13117
+ this.visionHistory = [
13118
+ history
13119
+ ];
13120
+ this.angleExcessesCount = 0;
13121
+ } else {
13122
+ let distance = getLength(this.visionHistory[0].position, this.visionHistory.slice(-1)[0].position);
13123
+ while (distance > 5 && this.visionHistory.length > 15) {
13124
+ this.visionHistory.shift();
13125
+ distance = getLength(this.visionHistory[0].position, this.visionHistory.slice(-1)[0].position);
13126
+ }
13127
+ }
13128
+ this.changeAngle();
13129
+ }
13130
+ addHistory(data) {
13131
+ this.history.push(data);
13132
+ let visionHistory = this.history.filter((item) => item.type === "vision");
13133
+ const lastVisionTimeDelta = visionHistory.length ? Date.now() - visionHistory.slice(-1)[0].clientTime : 0;
13134
+ let maxDistance = getLength(this.history[0].position, this.history.slice(-1)[0].position);
13135
+ const MAX_DISTANCE = lastVisionTimeDelta > 5e3 ? 10 : 3;
13136
+ const MIN_POSITION_HISTORY = lastVisionTimeDelta > 5e3 ? 0 : 5;
13137
+ if (lastVisionTimeDelta > 5e3) {
13138
+ console.warn("\u89C6\u89C9\u7ED3\u679C\u8D85\u51FA5s\u4E0D\u53EF\u7528\uFF0C\u5168\u90E8\u6E05\u7A7A");
13139
+ }
13140
+ while (visionHistory.length > MIN_POSITION_HISTORY && maxDistance > MAX_DISTANCE) {
13141
+ this.history.shift();
13142
+ visionHistory = this.history.filter((item) => item.type === "vision");
13143
+ maxDistance = getLength(this.history[0].position, this.history.slice(-1)[0].position);
13144
+ }
13145
+ if (MIN_POSITION_HISTORY === 0) {
13146
+ this.changeSpeed();
13147
+ } else if (data.type === "vision") {
13148
+ this.changeSpeed();
13149
+ }
13150
+ this.changePosition(data.type);
13151
+ }
13152
+ setBeaconPosition(position, time, duration) {
13153
+ const clientTime = Date.now() - duration;
13154
+ const item = {
13079
13155
  position,
13080
13156
  time,
13081
- clientTime: Date.now(),
13157
+ clientTime,
13082
13158
  type: "beacon"
13083
- });
13084
- const posInfo = this.getPosition("beacon");
13085
- this.dispatchEvent({
13086
- type: "change-pos",
13087
- value: posInfo
13088
- });
13089
- this.startPositionTimer();
13159
+ };
13160
+ const lastServerIndex = this.history.findLastIndex((item2) => item2.type !== "pdr");
13161
+ const lastServerItem = this.history[lastServerIndex];
13162
+ if (!lastServerItem) {
13163
+ this.addHistory(item);
13164
+ return;
13165
+ }
13166
+ if (isNil5(this.pathAngle) || !this.speed) {
13167
+ this.addHistory(item);
13168
+ return;
13169
+ }
13170
+ if (lastServerItem && lastServerItem.time > time) {
13171
+ return;
13172
+ }
13173
+ const predictPos = predictFuturePosition(position, this.speed, 360 - this.pathAngle, duration);
13174
+ const distance = getLength(predictPos, this.history.slice(-1)[0].position);
13175
+ if (distance > 5) {
13176
+ this.beaconExcessesCount++;
13177
+ } else {
13178
+ this.beaconExcessesCount = 0;
13179
+ }
13180
+ if (this.beaconExcessesCount > 3) {
13181
+ console.warn("\u8FDE\u7EED\u4E09\u6B21beacon\u548Cpdr\u5DEE\u8DDD\u5927\u4E8E5\u7C73\uFF0C\u4F7F\u7528beacon\u6821\u51C6");
13182
+ this.addHistory(item);
13183
+ this.beaconExcessesCount = 0;
13184
+ }
13090
13185
  }
13091
13186
  startPositionTimer() {
13092
13187
  if (this.positionTimer) {
13093
13188
  this.timer.clearInterval(this.positionTimer);
13094
13189
  }
13095
- if (this.autoCleanTimer) {
13096
- this.timer.clearTimeout(this.autoCleanTimer);
13097
- }
13098
13190
  this.positionTimer = this.timer.setInterval(() => {
13099
- const posInfo = this.getPosition("pdr");
13100
- this.dispatchEvent({
13101
- type: "change-pos",
13102
- value: posInfo
13103
- });
13191
+ this.changePosition();
13104
13192
  }, 20);
13105
- this.autoCleanTimer = this.timer.setTimeout(() => {
13106
- this.positionTimer && this.timer.clearInterval(this.positionTimer);
13107
- this.positionTimer = null;
13108
- }, 1e3);
13193
+ }
13194
+ changePosition(from = "pdr") {
13195
+ const posInfo = this.getPosition(from);
13196
+ if (posInfo.success) {
13197
+ this.history.push({
13198
+ position: posInfo.pos,
13199
+ time: Date.now(),
13200
+ clientTime: Date.now(),
13201
+ type: "pdr"
13202
+ });
13203
+ if (this.speed) {
13204
+ this.dispatchEvent({
13205
+ type: "change-pos",
13206
+ value: _extends({}, posInfo)
13207
+ });
13208
+ } else {
13209
+ this.dispatchEvent({
13210
+ type: "change-pos",
13211
+ value: posInfo
13212
+ });
13213
+ }
13214
+ }
13109
13215
  }
13110
13216
  getPosition(from) {
13111
13217
  if (this.history.length === 0) {
@@ -13124,36 +13230,34 @@ var CarInertialPosition = class extends EventDispatcher20 {
13124
13230
  return {
13125
13231
  success: true,
13126
13232
  pos: lastHistory.position,
13127
- compass: null,
13128
- speed: 0
13233
+ compass: this.pathAngle,
13234
+ speed: this.speed
13129
13235
  };
13130
13236
  }
13131
- const visionHistory = this.history.filter((item) => item.type === "vision");
13132
- const angle = calculateLineDirection(visionHistory.map((history) => history.position));
13133
- if (angle !== null) {
13134
- this.compassAngle = angle;
13135
- this.dispatchEvent({
13136
- type: "change-compass",
13137
- value: angle
13138
- });
13237
+ if (isNil5(this.pathAngle) || !this.speed) {
13238
+ return {
13239
+ success: true,
13240
+ pos: lastHistory.position,
13241
+ compass: this.pathAngle,
13242
+ speed: this.speed
13243
+ };
13139
13244
  }
13140
13245
  const lastTime = lastHistory.clientTime;
13141
13246
  const deltaTime = Date.now() - lastTime;
13142
- const speed = predictFutureSpeed(this.history, deltaTime);
13143
- const pos = this.compassAngle ? predictFuturePosition(lastHistory.position, speed, 360 - this.compassAngle, deltaTime) : lastHistory.position;
13247
+ const pos = this.pathAngle ? predictFuturePosition(lastHistory.position, this.speed, 360 - this.pathAngle, deltaTime) : lastHistory.position;
13144
13248
  return {
13145
13249
  success: true,
13146
13250
  pos,
13147
- compass: this.compassAngle,
13148
- speed: transformSpeed(speed)
13251
+ compass: this.pathAngle,
13252
+ speed: transformSpeed(this.speed)
13149
13253
  };
13150
13254
  }
13151
13255
  dispose() {
13152
- this.compass.stop();
13153
13256
  this.timer.dispose();
13154
13257
  }
13155
13258
  constructor() {
13156
- super(), this.history = [], this.compass = new Compass(), this.compassAngle = 0, this.timer = new Timer(), this.positionTimer = null, this.autoCleanTimer = null;
13259
+ super(), this.history = [], this.visionHistory = [], this.speed = 0, this.angle = null, this.timer = new Timer(), this.positionTimer = null, this.speedFilter = new KalmanFilter(), this.visionExcessesCount = 0, this.beaconExcessesCount = 0, this.angleExcessesCount = 0, this.pathAngle = 0;
13260
+ this.startPositionTimer();
13157
13261
  }
13158
13262
  };
13159
13263
 
@@ -13324,7 +13428,7 @@ function closeDb(db = _db) {
13324
13428
  }
13325
13429
 
13326
13430
  // ../lib/src/loader/AibeeLoader/index.js
13327
- import { Vector3 as Vector326, EventDispatcher as EventDispatcher21 } from "three";
13431
+ import { Vector3 as Vector326, EventDispatcher as EventDispatcher20 } from "three";
13328
13432
 
13329
13433
  // ../lib/src/loader/AibeeLoader/layer.js
13330
13434
  function transformLayers(layer, floor) {
@@ -13613,7 +13717,7 @@ var FacilityVersionStoreName = "facility_version";
13613
13717
  var MapDataStoreName = "map_data";
13614
13718
  var RoadNetworkDataStoreName = "road_network_data";
13615
13719
  var FacilityDataStoreName = "facility_data";
13616
- var AibeeLoader = class extends EventDispatcher21 {
13720
+ var AibeeLoader = class extends EventDispatcher20 {
13617
13721
  initDb() {
13618
13722
  var _this = this;
13619
13723
  return _async_to_generator(function* () {