source: josm/trunk/src/org/openstreetmap/josm/data/imagery/Shape.java@ 18341

Last change on this file since 18341 was 18341, checked in by Don-vip, 2 years ago

fix #21646 - Round new points in imagery.Shape (patch by taylor.smock)

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.awt.Polygon;
5import java.text.MessageFormat;
6import java.util.AbstractList;
7import java.util.List;
8import java.util.Objects;
9import java.util.stream.Collectors;
10import java.util.stream.Stream;
11
12import org.openstreetmap.gui.jmapviewer.Coordinate;
13import org.openstreetmap.josm.data.coor.LatLon;
14import org.openstreetmap.josm.tools.CheckParameterUtil;
15
16import static org.openstreetmap.josm.tools.I18n.tr;
17
18/**
19 * Data class to store the outline for background imagery coverage.
20 *
21 * Configuration data for imagery to describe the coverage area ({@link ImageryInfo.ImageryBounds}).
22 * @author Vincent
23 */
24public class Shape {
25
26 private final Polygon coords;
27
28 public Shape(String asString, String separator) {
29 CheckParameterUtil.ensureParameterNotNull(asString, "asString");
30 String[] components = asString.split(separator, -1);
31 if (components.length % 2 != 0)
32 throw new IllegalArgumentException(MessageFormat.format("Even number of doubles expected in string, got {0}: {1}",
33 components.length, asString));
34 int size = components.length / 2;
35 this.coords = new Polygon(new int[size], new int[size], 0);
36 for (int i = 0; i < components.length; i += 2) {
37 addPoint(components[i], components[i+1]);
38 }
39 }
40
41 /**
42 * Constructs a new empty {@code Shape}.
43 */
44 public Shape() {
45 coords = new Polygon();
46 // shape contents can be set later with addPoint()
47 }
48
49 /**
50 * Encodes this as a string so that it may be parsed using {@link #Shape(String, String)}
51 * @param separator The separator
52 * @return The string encoded shape
53 */
54 public String encodeAsString(String separator) {
55 return getPoints().stream()
56 .flatMap(c -> Stream.of(c.getLat(), c.getLon()))
57 .map(String::valueOf)
58 .collect(Collectors.joining(separator));
59 }
60
61 /**
62 * Encodes the shapes as a string using {@code ,} and {@code ;} as separators
63 * @param shapes The shapes to encode
64 * @return The string encoded shapes
65 */
66 public static String encodeAsString(List<Shape> shapes) {
67 return shapes.stream()
68 .map(s -> s.encodeAsString(","))
69 .collect(Collectors.joining(";"));
70 }
71
72 public List<Coordinate> getPoints() {
73 return new AbstractList<Coordinate>() {
74 @Override
75 public Coordinate get(int index) {
76 double lat = coords.ypoints[index] / LatLon.MAX_SERVER_INV_PRECISION;
77 double lon = coords.xpoints[index] / LatLon.MAX_SERVER_INV_PRECISION;
78 return new Coordinate(lat, lon);
79 }
80
81 @Override
82 public int size() {
83 return coords.npoints;
84 }
85 };
86 }
87
88 /**
89 * Check if the coordinates are inside this shape.
90 * @see Polygon#contains(int, int)
91 * @param latlon The latlon to look for
92 * @return {@code true} if the LatLon is inside the shape.
93 */
94 public boolean contains(LatLon latlon) {
95 return coords.contains(
96 latlon.getX() * LatLon.MAX_SERVER_INV_PRECISION,
97 latlon.getY() * LatLon.MAX_SERVER_INV_PRECISION);
98 }
99
100 public void addPoint(String sLat, String sLon) {
101 CheckParameterUtil.ensureParameterNotNull(sLat, "sLat");
102 CheckParameterUtil.ensureParameterNotNull(sLon, "sLon");
103
104 double lat, lon;
105
106 try {
107 lat = Double.parseDouble(sLat);
108 if (!LatLon.isValidLat(lat))
109 throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", lat));
110 } catch (NumberFormatException e) {
111 throw new IllegalArgumentException(MessageFormat.format("Illegal double value ''{0}''", sLat), e);
112 }
113
114 try {
115 lon = Double.parseDouble(sLon);
116 if (!LatLon.isValidLon(lon))
117 throw new IllegalArgumentException(tr("Illegal longitude value ''{0}''", lon));
118 } catch (NumberFormatException e) {
119 throw new IllegalArgumentException(MessageFormat.format("Illegal double value ''{0}''", sLon), e);
120 }
121
122 coords.addPoint(
123 (int) Math.round((lon * LatLon.MAX_SERVER_INV_PRECISION)),
124 (int) Math.round((lat * LatLon.MAX_SERVER_INV_PRECISION)));
125 }
126
127 @Override
128 public int hashCode() {
129 return Objects.hash(getPoints());
130 }
131
132 @Override
133 public boolean equals(Object obj) {
134 if (this == obj) return true;
135 if (obj == null || getClass() != obj.getClass()) return false;
136 Shape shape = (Shape) obj;
137 return Objects.equals(getPoints(), shape.getPoints());
138 }
139
140 @Override
141 public String toString() {
142 return "Shape{coords=" + getPoints() + '}';
143 }
144}
Note: See TracBrowser for help on using the repository browser.