001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.imagery; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.text.MessageFormat; 007import java.util.ArrayList; 008import java.util.List; 009import java.util.Objects; 010 011import org.openstreetmap.gui.jmapviewer.Coordinate; 012import org.openstreetmap.josm.data.coor.LatLon; 013import org.openstreetmap.josm.data.osm.Node; 014import org.openstreetmap.josm.tools.CheckParameterUtil; 015import org.openstreetmap.josm.tools.Geometry; 016 017/** 018 * @author Vincent 019 * 020 */ 021public class Shape { 022 023 private List<Coordinate> coords = new ArrayList<>(); 024 025 public Shape(String asString, String separator) throws IllegalArgumentException { 026 CheckParameterUtil.ensureParameterNotNull(asString, "asString"); 027 String[] components = asString.split(separator); 028 if (components.length % 2 != 0) 029 throw new IllegalArgumentException(MessageFormat.format("Even number of doubles expected in string, got {0}: {1}", components.length, asString)); 030 for (int i=0; i<components.length; i+=2) { 031 addPoint(components[i], components[i+1]); 032 } 033 } 034 035 public Shape() { 036 } 037 038 public String encodeAsString(String separator) { 039 StringBuilder sb = new StringBuilder(); 040 for (Coordinate c : coords) { 041 if (sb.length() != 0) { 042 sb.append(separator); 043 } 044 sb.append(c.getLat()).append(separator).append(c.getLon()); 045 } 046 return sb.toString(); 047 } 048 049 public List<Coordinate> getPoints() { 050 return coords; 051 } 052 053 public boolean contains(LatLon latlon) { 054 if (latlon == null) 055 return false; 056 List<Node> nodes = new ArrayList<>(coords.size()); 057 for (Coordinate c : coords) { 058 nodes.add(new Node(new LatLon(c.getLat(), c.getLon()))); 059 } 060 return Geometry.nodeInsidePolygon(new Node(latlon), nodes); 061 } 062 063 public void addPoint(String sLat, String sLon) throws IllegalArgumentException { 064 CheckParameterUtil.ensureParameterNotNull(sLat, "sLat"); 065 CheckParameterUtil.ensureParameterNotNull(sLon, "sLon"); 066 067 double lat, lon; 068 069 try { 070 lat = Double.parseDouble(sLat); 071 if (!LatLon.isValidLat(lat)) 072 throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", lat)); 073 } catch (NumberFormatException e) { 074 throw new IllegalArgumentException(MessageFormat.format("Illegal double value ''{0}''", sLat)); 075 } 076 077 try { 078 lon = Double.parseDouble(sLon); 079 if (!LatLon.isValidLon(lon)) 080 throw new IllegalArgumentException(tr("Illegal longitude value ''{0}''", lon)); 081 } catch (NumberFormatException e) { 082 throw new IllegalArgumentException(MessageFormat.format("Illegal double value ''{0}''", sLon)); 083 } 084 085 coords.add(new Coordinate(LatLon.roundToOsmPrecision(lat), LatLon.roundToOsmPrecision(lon))); 086 } 087 088 @Override 089 public int hashCode() { 090 int hash = 5; 091 hash = 47 * hash + Objects.hashCode(this.coords); 092 return hash; 093 } 094 095 @Override 096 public boolean equals(Object obj) { 097 if (obj == null) { 098 return false; 099 } 100 if (getClass() != obj.getClass()) { 101 return false; 102 } 103 final Shape other = (Shape) obj; 104 if (!Objects.equals(this.coords, other.coords)) { 105 return false; 106 } 107 return true; 108 } 109 110 111}