Changeset 14521 in josm


Ignore:
Timestamp:
2018-12-08T14:19:23+01:00 (4 months ago)
Author:
Don-vip
Message:

see #16073 - handle entries where centroid does not lie in shape (like Canadian 'British Columbia Mosaic')

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/Bounds.java

    r14095 r14521  
    500500     */
    501501    public Rectangle2D.Double asRect() {
    502         double w = getWidth();
    503         return new Rectangle2D.Double(minLon, minLat, w, maxLat-minLat);
    504     }
    505 
    506     private double getWidth() {
     502        return new Rectangle2D.Double(minLon, minLat, getWidth(), getHeight());
     503    }
     504
     505    /**
     506     * Returns the bounds width.
     507     * @return the bounds width
     508     * @since 14521
     509     */
     510    public double getHeight() {
     511        return maxLat-minLat;
     512    }
     513
     514    /**
     515     * Returns the bounds width.
     516     * @return the bounds width
     517     * @since 14521
     518     */
     519    public double getWidth() {
    507520        return maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0);
    508521    }
     
    513526     */
    514527    public double getArea() {
    515         return getWidth() * (maxLat - minLat);
     528        return getWidth() * getHeight();
    516529    }
    517530
  • trunk/src/org/openstreetmap/josm/tools/Geometry.java

    r14273 r14521  
    840840        BigDecimal east = BigDecimal.ZERO;
    841841
    842         // See https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon for the equation used here
     842        // See https://en.wikipedia.org/wiki/Centroid#Of_a_polygon for the equation used here
    843843        for (int i = 0; i < size; i++) {
    844844            EastNorth n0 = nodes.get(i);
  • trunk/test/unit/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreferenceTestIT.java

    r14519 r14521  
    1313import java.util.Set;
    1414import java.util.TreeMap;
    15 import java.util.stream.Collectors;
    1615
    1716import org.junit.Rule;
    1817import org.junit.Test;
     18import org.openstreetmap.gui.jmapviewer.Coordinate;
    1919import org.openstreetmap.gui.jmapviewer.TileXY;
    2020import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
     
    2323import org.openstreetmap.gui.jmapviewer.tilesources.ScanexTileSource;
    2424import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
     25import org.openstreetmap.josm.data.Bounds;
    2526import org.openstreetmap.josm.data.coor.LatLon;
    2627import org.openstreetmap.josm.data.imagery.CoordinateConversion;
     
    3334import org.openstreetmap.josm.data.imagery.WMTSTileSource;
    3435import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
    35 import org.openstreetmap.josm.data.projection.Projection;
    3636import org.openstreetmap.josm.data.projection.ProjectionRegistry;
    3737import org.openstreetmap.josm.testutils.JOSMTestRules;
    38 import org.openstreetmap.josm.tools.Geometry;
    3938import org.openstreetmap.josm.tools.HttpClient;
    4039import org.openstreetmap.josm.tools.HttpClient.Response;
     
    106105    }
    107106
     107    private static LatLon getPointInShape(Shape shape) {
     108        final Coordinate p1 = shape.getPoints().get(0);
     109        final Bounds bounds = new Bounds(p1.getLat(), p1.getLon(), p1.getLat(), p1.getLon());
     110        shape.getPoints().forEach(p -> bounds.extend(p.getLat(), p.getLon()));
     111
     112        final double w = bounds.getWidth();
     113        final double h = bounds.getHeight();
     114
     115        final double x2 = bounds.getMinLon() + (w / 2.0);
     116        final double y2 = bounds.getMinLat() + (h / 2.0);
     117
     118        final LatLon center = new LatLon(y2, x2);
     119
     120        // check to see if center is inside shape
     121        if (shape.contains(center)) {
     122            return center;
     123        }
     124
     125        // if center position (C) is not inside shape, try naively some other positions as follows:
     126        final double x1 = bounds.getMinLon() + (.25 * w);
     127        final double x3 = bounds.getMinLon() + (.75 * w);
     128        final double y1 = bounds.getMinLat() + (.25 * h);
     129        final double y3 = bounds.getMinLat() + (.75 * h);
     130        // +-----------+
     131        // |  5  1  6  |
     132        // |  4  C  2  |
     133        // |  8  3  7  |
     134        // +-----------+
     135        for (LatLon candidate : new LatLon[] {
     136                new LatLon(y1, x2),
     137                new LatLon(y2, x3),
     138                new LatLon(y3, x2),
     139                new LatLon(y2, x1),
     140                new LatLon(y1, x1),
     141                new LatLon(y1, x3),
     142                new LatLon(y3, x3),
     143                new LatLon(y3, x1)
     144        }) {
     145            if (shape.contains(candidate)) {
     146                return candidate;
     147            }
     148        }
     149        return center;
     150    }
     151
    108152    private static LatLon getCenter(ImageryBounds bounds) {
    109153        List<Shape> shapes = bounds.getShapes();
    110         Projection proj = ProjectionRegistry.getProjection();
    111         return shapes != null && shapes.size() > 1
    112                 ? proj.eastNorth2latlon(
    113                         Geometry.getCentroidEN(shapes.get(0).getPoints().stream()
    114                                 .map(CoordinateConversion::coorToLL)
    115                                 .map(proj::latlon2eastNorth)
    116                                 .collect(Collectors.toList())))
    117                 : bounds.getCenter();
     154        return shapes != null && !shapes.isEmpty() ? getPointInShape(shapes.get(0)) : bounds.getCenter();
    118155    }
    119156
Note: See TracChangeset for help on using the changeset viewer.