All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.powsybl.iidm.geodata.utils.LineCoordinatesOrdering Maven / Gradle / Ivy

/**
 * Copyright (c) 2024, RTE (http://www.rte-france.com)
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * SPDX-License-Identifier: MPL-2.0
 */
package com.powsybl.iidm.geodata.utils;

import com.google.common.collect.Lists;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.iidm.network.extensions.Coordinate;
import com.powsybl.iidm.network.extensions.SubstationPosition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;

/**
 * @author Florian Dupuy {@literal }
 */
public final class LineCoordinatesOrdering {

    private static final Logger LOGGER = LoggerFactory.getLogger(LineCoordinatesOrdering.class);

    private LineCoordinatesOrdering() {

    }

    public static List order(Line line, List lineCoordinates) {

        Optional s1 = getCoordinate(line, TwoSides.ONE);
        Optional s2 = getCoordinate(line, TwoSides.TWO);
        Coordinate firstCoordinate = lineCoordinates.get(0);
        Coordinate lastCoordinate = lineCoordinates.get(lineCoordinates.size() - 1);

        if (s1.isPresent()) {
            if (s2.isPresent()) {
                return orderCoordinates(s1.get(), s2.get(), firstCoordinate, lastCoordinate, lineCoordinates, line.getId());
            } else {
                return orderCoordinates(s1.get(), firstCoordinate, lastCoordinate, lineCoordinates);
            }
        } else {
            if (s2.isPresent()) {
                return orderCoordinates(s2.get(), lastCoordinate, firstCoordinate, lineCoordinates);
            } else {
                return lineCoordinates; // no information on substations positions -> considering it's in the right order
            }
        }
    }

    private static List orderCoordinates(Coordinate s1, Coordinate s2, Coordinate firstCoordinate, Coordinate lastCoordinate,
                                                     List lineCoordinates, String lineId) {
        final double substation1lineStart = DistanceCalculator.distance(s1, firstCoordinate);
        final double substation2lineStart = DistanceCalculator.distance(s2, firstCoordinate);
        final double substation1lineEnd = DistanceCalculator.distance(s1, lastCoordinate);
        final double substation2lineEnd = DistanceCalculator.distance(s2, lastCoordinate);
        if ((substation1lineStart < substation2lineStart) == (substation1lineEnd < substation2lineEnd)) {
            LOGGER.warn("line {} has both first and last coordinate nearest to {}",
                    lineId, substation1lineStart < substation2lineStart ? TwoSides.ONE : TwoSides.TWO);
            // reverse the list if line end closer to substation1 than line start
            return substation1lineStart <= substation1lineEnd ? lineCoordinates : Lists.reverse(lineCoordinates);
        }
        // main case: the line start is closer to one substation, the line end is closer to the other substation
        // reverse the list if the start is closer to the second substation
        return substation1lineStart <= substation2lineStart ? lineCoordinates : Lists.reverse(lineCoordinates);
    }

    private static List orderCoordinates(Coordinate substation, Coordinate coordA, Coordinate coordB, List coordinates) {
        if (DistanceCalculator.distance(substation, coordA) > DistanceCalculator.distance(substation, coordB)) {
            return Lists.reverse(coordinates);
        } else {
            return coordinates;
        }
    }

    private static Optional getCoordinate(Line line, TwoSides side) {
        return line.getTerminal(side).getVoltageLevel().getSubstation()
                .map(s -> s.getExtension(SubstationPosition.class))
                .map(SubstationPosition.class::cast)
                .map(SubstationPosition::getCoordinate);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy