+},{"../Viewer":286,"rxjs":27,"rxjs/operators":225}],442:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var rxjs_1 = require("rxjs");
+var operators_1 = require("rxjs/operators");
+var Geo = require("../geo/Geo");
+var GeoCoords_1 = require("../geo/GeoCoords");
+var GraphCalculator_1 = require("../graph/GraphCalculator");
+var Spatial_1 = require("../geo/Spatial");
+var Transform_1 = require("../geo/Transform");
+var ViewportCoords_1 = require("../geo/ViewportCoords");
+var PanMode;
+(function (PanMode) {
+ PanMode[PanMode["Disabled"] = 0] = "Disabled";
+ PanMode[PanMode["Enabled"] = 1] = "Enabled";
+ PanMode[PanMode["Started"] = 2] = "Started";
+})(PanMode || (PanMode = {}));
+var PanService = /** @class */ (function () {
+ function PanService(graphService, stateService, enabled, geoCoords, graphCalculator, spatial, viewportCoords) {
+ this._graphService = graphService;
+ this._stateService = stateService;
+ this._geoCoords = !!geoCoords ? geoCoords : new GeoCoords_1.default();
+ this._graphCalculator = !!graphCalculator ? graphCalculator : new GraphCalculator_1.default(this._geoCoords);
+ this._spatial = !!spatial ? spatial : new Spatial_1.default();
+ this._viewportCoords = !!viewportCoords ? viewportCoords : new ViewportCoords_1.default();
+ this._mode = enabled !== false ? PanMode.Enabled : PanMode.Disabled;
+ this._panNodesSubject$ = new rxjs_1.Subject();
+ this._panNodes$ = this._panNodesSubject$.pipe(operators_1.startWith([]), operators_1.publishReplay(1), operators_1.refCount());
+ this._panNodes$.subscribe();
+ }
+ Object.defineProperty(PanService.prototype, "panNodes$", {
+ get: function () {
+ return this._panNodes$;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ PanService.prototype.enable = function () {
+ if (this._mode !== PanMode.Disabled) {
+ return;
+ }
+ this._mode = PanMode.Enabled;
+ this.start();
+ };
+ PanService.prototype.disable = function () {
+ if (this._mode === PanMode.Disabled) {
+ return;
+ }
+ this.stop();
+ this._mode = PanMode.Disabled;
+ };
+ PanService.prototype.start = function () {
+ var _this = this;
+ if (this._mode !== PanMode.Enabled) {
+ return;
+ }
+ var panNodes$ = this._stateService.currentNode$.pipe(operators_1.switchMap(function (current) {
+ if (!current.merged) {
+ return rxjs_1.of([]);
+ }
+ var current$ = rxjs_1.of(current);
+ var bounds = _this._graphCalculator.boundingBoxCorners(current.latLon, 20);
+ var adjacent$ = _this._graphService
+ .cacheBoundingBox$(bounds[0], bounds[1]).pipe(operators_1.catchError(function (error) {
+ console.error("Failed to cache periphery bounding box (" + current.key + ")", error);
+ return rxjs_1.empty();
+ }), operators_1.map(function (nodes) {
+ if (current.pano) {
+ return [];
+ }
+ var potential = [];
+ for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+ var node = nodes_1[_i];
+ if (node.key === current.key) {
+ continue;
+ }
+ if (node.mergeCC !== current.mergeCC) {
+ continue;
+ }
+ if (node.pano) {
+ continue;
+ }
+ if (_this._distance(node, current) > 4) {
+ continue;
+ }
+ potential.push(node);
+ }
+ return potential;
+ }));
+ return rxjs_1.combineLatest(current$, adjacent$).pipe(operators_1.withLatestFrom(_this._stateService.reference$), operators_1.map(function (_a) {
+ var _b = _a[0], cn = _b[0], adjacent = _b[1], reference = _a[1];
+ var currentDirection = _this._spatial.viewingDirection(cn.rotation);
+ var currentTranslation = Geo.computeTranslation({ lat: cn.latLon.lat, lon: cn.latLon.lon, alt: cn.alt }, cn.rotation, reference);
+ var currentTransform = _this._createTransform(cn, currentTranslation);
+ var currentAzimuthal = _this._spatial.wrap(_this._spatial.azimuthal(currentDirection.toArray(), currentTransform.upVector().toArray()), 0, 2 * Math.PI);
+ var currentProjectedPoints = _this._computeProjectedPoints(currentTransform);
+ var currentHFov = _this._computeHorizontalFov(currentProjectedPoints) / 180 * Math.PI;
+ var preferredOverlap = Math.PI / 8;
+ var left = undefined;
+ var right = undefined;
+ for (var _i = 0, adjacent_1 = adjacent; _i < adjacent_1.length; _i++) {
+ var a = adjacent_1[_i];
+ var translation = Geo.computeTranslation({ lat: a.latLon.lat, lon: a.latLon.lon, alt: a.alt }, a.rotation, reference);
+ var transform = _this._createTransform(a, translation);
+ var projectedPoints = _this._computeProjectedPoints(transform);
+ var hFov = _this._computeHorizontalFov(projectedPoints) / 180 * Math.PI;
+ var direction = _this._spatial.viewingDirection(a.rotation);
+ var azimuthal = _this._spatial.wrap(_this._spatial.azimuthal(direction.toArray(), transform.upVector().toArray()), 0, 2 * Math.PI);
+ var directionChange = _this._spatial.angleBetweenVector2(currentDirection.x, currentDirection.y, direction.x, direction.y);
+ var overlap = Number.NEGATIVE_INFINITY;
+ if (directionChange > 0) {
+ if (currentAzimuthal > azimuthal) {
+ overlap = currentAzimuthal - 2 * Math.PI + currentHFov / 2 - (azimuthal - hFov / 2);
+ }
+ else {
+ overlap = currentAzimuthal + currentHFov / 2 - (azimuthal - hFov / 2);
+ }
+ }
+ else {
+ if (currentAzimuthal < azimuthal) {
+ overlap = azimuthal + hFov / 2 - (currentAzimuthal + 2 * Math.PI - currentHFov / 2);
+ }
+ else {
+ overlap = azimuthal + hFov / 2 - (currentAzimuthal - currentHFov / 2);
+ }
+ }
+ var nonOverlap = Math.abs(hFov - overlap);
+ var distanceCost = _this._distance(a, cn);
+ var timeCost = Math.min(_this._timeDifference(a, cn), 4);
+ var overlapCost = 20 * Math.abs(overlap - preferredOverlap);
+ var fovCost = Math.min(5, 1 / Math.min(hFov / currentHFov, 1));
+ var nonOverlapCost = overlap > 0 ? -2 * nonOverlap : 0;
+ var cost = distanceCost + timeCost + overlapCost + fovCost + nonOverlapCost;
+ if (overlap > 0 &&
+ overlap < 0.5 * currentHFov &&
+ overlap < 0.5 * hFov &&
+ nonOverlap > 0.5 * currentHFov) {
+ if (directionChange > 0) {
+ if (!left) {
+ left = [cost, a, transform, hFov];
+ }
+ else {
+ if (cost < left[0]) {
+ left = [cost, a, transform, hFov];
+ }
+ }
+ }
+ else {
+ if (!right) {
+ right = [cost, a, transform, hFov];
+ }
+ else {
+ if (cost < right[0]) {
+ right = [cost, a, transform, hFov];
+ }
+ }
+ }
+ }
+ }
+ var panNodes = [];
+ if (!!left) {
+ panNodes.push([left[1], left[2], left[3]]);
+ }
+ if (!!right) {
+ panNodes.push([right[1], right[2], right[3]]);
+ }
+ return panNodes;
+ }), operators_1.startWith([]));
+ }));
+ this._panNodesSubscription = this._stateService.currentState$.pipe(operators_1.map(function (frame) {
+ return frame.state.nodesAhead > 0;
+ }), operators_1.distinctUntilChanged(), operators_1.switchMap(function (traversing) {
+ return traversing ? rxjs_1.of([]) : panNodes$;
+ }))
+ .subscribe(function (panNodes) {
+ _this._panNodesSubject$.next(panNodes);
+ });
+ this._mode = PanMode.Started;
+ };
+ PanService.prototype.stop = function () {
+ if (this._mode !== PanMode.Started) {
+ return;
+ }
+ this._panNodesSubscription.unsubscribe();
+ this._panNodesSubject$.next([]);
+ this._mode = PanMode.Enabled;
+ };
+ PanService.prototype._distance = function (node, reference) {
+ var _a = this._geoCoords.geodeticToEnu(node.latLon.lat, node.latLon.lon, node.alt, reference.latLon.lat, reference.latLon.lon, reference.alt), x = _a[0], y = _a[1], z = _a[2];
+ return Math.sqrt(x * x + y * y + z * z);
+ };
+ PanService.prototype._timeDifference = function (node, reference) {
+ return Math.abs(node.capturedAt - reference.capturedAt) / (1000 * 60 * 60 * 24 * 30);
+ };
+ PanService.prototype._createTransform = function (node, translation) {
+ return new Transform_1.Transform(node.orientation, node.width, node.height, node.focal, node.scale, node.gpano, node.rotation, translation, node.assetsCached ? node.image : undefined, undefined, node.ck1, node.ck2, node.cameraProjection);
+ };
+ PanService.prototype._computeProjectedPoints = function (transform) {
+ var vertices = [[1, 0]];
+ var directions = [[0, 0.5]];
+ var pointsPerLine = 20;
+ return Geo.computeProjectedPoints(transform, vertices, directions, pointsPerLine, this._viewportCoords);
+ };
+ PanService.prototype._computeHorizontalFov = function (projectedPoints) {
+ var _this = this;
+ var fovs = projectedPoints
+ .map(function (projectedPoint) {
+ return _this._coordToFov(projectedPoint[0]);
+ });
+ var fov = Math.min.apply(Math, fovs);
+ return fov;
+ };
+ PanService.prototype._coordToFov = function (x) {
+ return 2 * Math.atan(x) * 180 / Math.PI;
+ };
+ return PanService;
+}());
+exports.PanService = PanService;
+
+},{"../geo/Geo":384,"../geo/GeoCoords":385,"../geo/Spatial":387,"../geo/Transform":388,"../geo/ViewportCoords":389,"../graph/GraphCalculator":392,"rxjs":27,"rxjs/operators":225}],443:[function(require,module,exports){