public computeStepEdges()

in src/graph/edge/EdgeCalculator.ts [324:413]


    public computeStepEdges(
        node: Image,
        potentialEdges: PotentialEdge[],
        prevId: string,
        nextId: string): NavigationEdge[] {

        if (!node.complete) {
            throw new ArgumentMapillaryError("Image has to be full.");
        }

        let edges: NavigationEdge[] = [];

        if (isSpherical(node.cameraType)) {
            return edges;
        }

        for (let k in this._directions.steps) {
            if (!this._directions.steps.hasOwnProperty(k)) {
                continue;
            }

            let step: StepDirection = this._directions.steps[k];

            let lowestScore: number = Number.MAX_VALUE;
            let edge: PotentialEdge = null;
            let fallback: PotentialEdge = null;

            for (let potential of potentialEdges) {
                if (potential.spherical) {
                    continue;
                }

                if (Math.abs(potential.directionChange) > this._settings.stepMaxDirectionChange) {
                    continue;
                }

                let motionDifference: number =
                    this._spatial.angleDifference(step.motionChange, potential.motionChange);
                let directionMotionDifference: number =
                    this._spatial.angleDifference(potential.directionChange, motionDifference);
                let drift: number =
                    Math.max(Math.abs(motionDifference), Math.abs(directionMotionDifference));

                if (Math.abs(drift) > this._settings.stepMaxDrift) {
                    continue;
                }

                let potentialId: string = potential.id;
                if (step.useFallback && (potentialId === prevId || potentialId === nextId)) {
                    fallback = potential;
                }

                if (potential.distance > this._settings.stepMaxDistance) {
                    continue;
                }

                motionDifference = Math.sqrt(
                    motionDifference * motionDifference +
                    potential.verticalMotion * potential.verticalMotion);

                let score: number =
                    this._coefficients.stepPreferredDistance *
                    Math.abs(potential.distance - this._settings.stepPreferredDistance) /
                    this._settings.stepMaxDistance +
                    this._coefficients.stepMotion * motionDifference / this._settings.stepMaxDrift +
                    this._coefficients.stepRotation * potential.rotation / this._settings.stepMaxDirectionChange +
                    this._coefficients.stepSequencePenalty * (potential.sameSequence ? 0 : 1) +
                    this._coefficients.stepMergeCCPenalty * (potential.sameMergeCC ? 0 : 1);

                if (score < lowestScore) {
                    lowestScore = score;
                    edge = potential;
                }
            }

            edge = edge == null ? fallback : edge;
            if (edge != null) {
                edges.push({
                    data: {
                        direction: step.direction,
                        worldMotionAzimuth: edge.worldMotionAzimuth,
                    },
                    source: node.id,
                    target: edge.id,
                });
            }
        }

        return edges;
    }