public computeSimilarEdges()

in src/graph/edge/EdgeCalculator.ts [216:310]


    public computeSimilarEdges(node: Image, potentialEdges: PotentialEdge[]): NavigationEdge[] {
        if (!node.complete) {
            throw new ArgumentMapillaryError("Image has to be full.");
        }

        let nodeSpherical: boolean = isSpherical(node.cameraType);
        let sequenceGroups: { [key: string]: PotentialEdge[] } = {};

        for (let potentialEdge of potentialEdges) {
            if (potentialEdge.sequenceId == null) {
                continue;
            }

            if (potentialEdge.sameSequence) {
                continue;
            }

            if (nodeSpherical) {
                if (!potentialEdge.spherical) {
                    continue;
                }
            } else {
                if (!potentialEdge.spherical &&
                    Math.abs(potentialEdge.directionChange) > this._settings.similarMaxDirectionChange) {
                    continue;
                }
            }

            if (potentialEdge.distance > this._settings.similarMaxDistance) {
                continue;
            }

            if (potentialEdge.sameUser &&
                Math.abs(potentialEdge.capturedAt - node.capturedAt) <
                this._settings.similarMinTimeDifference) {
                continue;
            }

            if (sequenceGroups[potentialEdge.sequenceId] == null) {
                sequenceGroups[potentialEdge.sequenceId] = [];
            }

            sequenceGroups[potentialEdge.sequenceId].push(potentialEdge);

        }

        let similarEdges: PotentialEdge[] = [];

        let calculateScore =
            isSpherical(node.cameraType) ?
                (potentialEdge: PotentialEdge): number => {
                    return potentialEdge.distance;
                } :
                (potentialEdge: PotentialEdge): number => {
                    return this._coefficients.similarDistance * potentialEdge.distance +
                        this._coefficients.similarRotation * potentialEdge.rotation;
                };

        for (let sequenceId in sequenceGroups) {
            if (!sequenceGroups.hasOwnProperty(sequenceId)) {
                continue;
            }

            let lowestScore: number = Number.MAX_VALUE;
            let similarEdge: PotentialEdge = null;

            for (let potentialEdge of sequenceGroups[sequenceId]) {
                let score: number = calculateScore(potentialEdge);

                if (score < lowestScore) {
                    lowestScore = score;
                    similarEdge = potentialEdge;
                }
            }

            if (similarEdge == null) {
                continue;
            }

            similarEdges.push(similarEdge);
        }

        return similarEdges
            .map<NavigationEdge>(
                (potentialEdge: PotentialEdge): NavigationEdge => {
                    return {
                        data: {
                            direction: NavigationDirection.Similar,
                            worldMotionAzimuth: potentialEdge.worldMotionAzimuth,
                        },
                        source: node.id,
                        target: potentialEdge.id,
                    };
                });
    }