Changeset 19658 in josm


Ignore:
Timestamp:
2026-10-23T16:06:36+02:00 (15 hours ago)
Author:
gaben
Message:

fix #24876 - improve PowerLines test performance

The test looked up the water crossings of the whole way once for every node of the way, although the result only depends on the way.
On a large power line dataset (~500k primitives), a full run of the test goes from ~8.2s to ~0.9s, with identical results.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java

    r19629 r19658  
    66import java.awt.geom.Point2D;
    77import java.util.ArrayList;
    8 import java.util.Arrays;
    98import java.util.Collection;
    10 import java.util.Collections;
    119import java.util.EnumSet;
    1210import java.util.HashMap;
    … …  
    6664
    6765    /** Values for {@code power} key interpreted as power lines */
    68     static final Collection<String> POWER_LINE_TAGS = Arrays.asList("line", MINOR_LINE);
     66    static final Set<String> POWER_LINE_TAGS = Set.of("line", MINOR_LINE);
    6967    /** Values for {@code power} key interpreted as power towers */
    70     static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("catenary_mast", "pole", "portal", "tower");
     68    static final Set<String> POWER_TOWER_TAGS = Set.of("catenary_mast", "pole", "portal", "tower");
    7169    /** Values for {@code power} key interpreted as power stations */
    72     static final Collection<String> POWER_STATION_TAGS = Arrays.asList("generator", "plant", "substation");
     70    static final Set<String> POWER_STATION_TAGS = Set.of("generator", "plant", "substation");
    7371    /** Values for {@code building} key interpreted as power stations */
    74     static final Collection<String> BUILDING_STATION_TAGS = Collections.singletonList("transformer_tower");
     72    static final Set<String> BUILDING_STATION_TAGS = Set.of("transformer_tower");
    7573    /** Values for {@code power} key interpreted as allowed power items */
    76     static final Collection<String> POWER_INFRASTRUCTURE_TAGS = Arrays.asList("compensator", "connection", "converter",
     74    static final Set<String> POWER_INFRASTRUCTURE_TAGS = Set.of("compensator", "connection", "converter",
    7775            "generator", "insulator", "switch", "switchgear", "terminal", "transformer");
     76
     77    /** Values for {@code power} key interpreted as power lines or cables */
     78    private static final Set<String> POWER_LINE_OR_CABLE_TAGS = Set.of("line", MINOR_LINE, "cable");
    7879
    7980    private double hillyCompensation;
    … …  
    190191                    .message(tr("Possibly missing line support node within power line"))
    191192                    .primitives(s.getFirstNode(), s.getSecondNode())
    192                     .highlightWaySegments(new HashSet<>(Collections.singleton(s)))
     193                    .highlightWaySegments(Set.of(s))
    193194                    .build());
    194195        }
    … …  
    250251        final double stdDev = Utils.getStandardDeviation(w.getSegmentLengths(), mean);
    251252        final boolean isContinuesAsMinorLine = isContinuesAsMinorLine(w);
    252         boolean isCrossingWater = false;
     253        // the crossings only depend on the way, so look them up once instead of for every node
     254        final Set<Way> crossingWaterWays = new HashSet<>(8);
     255        final Set<ILatLon> crossingPositions = new HashSet<>(8);
     256        findCrossings(this.cellSegmentsWater, w, crossingWaterWays, crossingPositions);
     257        final boolean isCrossingWater = !crossingWaterWays.isEmpty();
    253258        int poleCount = 0;
    254259        int towerCount = 0;
    … …  
    278283            /// handle missing nodes
    279284            double segmentLen = n.greatCircleDistance(prevNode);
    280             final Set<Way> crossingWaterWays = new HashSet<>(8);
    281             final Set<ILatLon> crossingPositions = new HashSet<>(8);
    282             findCrossings(this.cellSegmentsWater, w, crossingWaterWays, crossingPositions);
    283 
    284             if (!crossingWaterWays.isEmpty()) {
     285            if (isCrossingWater) {
    285286                double compensation = calculateIntersectingLen(prevNode, crossingPositions);
    286287                segmentLen -= compensation;
    … …  
    294295
    295296            /// handle wrong line types
    296             if (!crossingWaterWays.isEmpty())
    297                 isCrossingWater = true;
    298 
    299297            if (n.hasTag(POWER, "pole"))
    300298                poleCount++;
    … …  
    600598            return true;
    601599        for (OsmPrimitive ref : way.getReferrers()) {
    602             if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag(POWER) || ref.hasTag(BUILDING))) {
    603                 for (RelationMember rm : ((Relation) ref).getMembers()) {
    604                     if (way == rm.getMember())
    605                         return true;
     600            if (ref instanceof Relation) {
     601                Relation r = (Relation) ref;
     602                if (r.isMultipolygon() && (r.hasTag(POWER) || r.hasTag(BUILDING))) {
     603                    for (RelationMember rm : r.getMembers()) {
     604                        if (rm.getMember() == way)
     605                            return true;
     606                    }
    606607                }
    607608            }
    … …  
    659660    protected final boolean isInPowerStation(Node n) {
    660661        for (OsmPrimitive station : powerStations) {
    661             List<List<Node>> nodesLists = new ArrayList<>();
    662662            if (station instanceof Way) {
    663                 nodesLists.add(((Way) station).getNodes());
     663                if (Geometry.nodeInsidePolygon(n, ((Way) station).getNodes())) {
     664                    return true;
     665                }
    664666            } else if (station instanceof Relation) {
    665667                Multipolygon polygon = MultipolygonCache.getInstance().get((Relation) station);
    666668                if (polygon != null) {
    667669                    for (JoinedWay outer : Multipolygon.joinWays(polygon.getOuterWays())) {
    668                         nodesLists.add(outer.getNodes());
     670                        if (Geometry.nodeInsidePolygon(n, outer.getNodes())) {
     671                            return true;
     672                        }
    669673                    }
    670                 }
    671             }
    672             for (List<Node> nodes : nodesLists) {
    673                 if (Geometry.nodeInsidePolygon(n, nodes)) {
    674                     return true;
    675674                }
    676675            }
    … …  
    694693     */
    695694    protected static boolean isPowerLineOrCable(Way w) {
    696         return isPowerIn(w, Arrays.asList("line", MINOR_LINE, "cable"));
     695        return isPowerIn(w, POWER_LINE_OR_CABLE_TAGS);
    697696    }
    698697
Note: See TracChangeset for help on using the changeset viewer.