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}