001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data;
003
004import java.awt.geom.Area;
005import java.util.ArrayList;
006import java.util.Collection;
007import java.util.List;
008
009import org.openstreetmap.josm.tools.CheckParameterUtil;
010
011/**
012 * A data source, defined by bounds and textual description for the origin.
013 * @since 247 (creation)
014 * @since 7575 (moved package)
015 */
016public class DataSource {
017
018    /**
019     * The bounds of this data source
020     */
021    public final Bounds bounds;
022
023    /**
024     * The textual description of the origin (example: "OpenStreetMap Server")
025     */
026    public final String origin;
027
028    /**
029     * Constructs a new {@code DataSource}.
030     * @param bounds The bounds of this data source
031     * @param origin The textual description of the origin (example: "OpenStreetMap Server")
032     * @throws IllegalArgumentException if bounds is {@code null}
033     */
034    public DataSource(Bounds bounds, String origin) {
035        CheckParameterUtil.ensureParameterNotNull(bounds, "bounds");
036        this.bounds = bounds;
037        this.origin = origin;
038    }
039
040    @Override
041    public int hashCode() {
042        final int prime = 31;
043        int result = 1;
044        result = prime * result + ((bounds == null) ? 0 : bounds.hashCode());
045        result = prime * result + ((origin == null) ? 0 : origin.hashCode());
046        return result;
047    }
048
049    @Override
050    public boolean equals(Object obj) {
051        if (this == obj)
052            return true;
053        if (obj == null)
054            return false;
055        if (getClass() != obj.getClass())
056            return false;
057        DataSource other = (DataSource) obj;
058        if (bounds == null) {
059            if (other.bounds != null)
060                return false;
061        } else if (!bounds.equals(other.bounds))
062            return false;
063        if (origin == null) {
064            if (other.origin != null)
065                return false;
066        } else if (!origin.equals(other.origin))
067            return false;
068        return true;
069    }
070
071    @Override
072    public String toString() {
073        return "DataSource [bounds=" + bounds + ", origin=" + origin + "]";
074    }
075
076    /**
077     * Returns the total area of downloaded data (the "yellow rectangles").
078     * @param dataSources list of data sources
079     * @return Area object encompassing downloaded data.
080     * @see Data#getDataSourceArea()
081     */
082    public static Area getDataSourceArea(Collection<DataSource> dataSources) {
083        if (dataSources == null || dataSources.isEmpty()) {
084            return null;
085        }
086        Area a = new Area();
087        for (DataSource source : dataSources) {
088            // create area from data bounds
089            a.add(new Area(source.bounds.asRect()));
090        }
091        return a;
092    }
093
094    /**
095     * <p>Replies the list of data source bounds.</p>
096     *
097     * <p>Dataset maintains a list of data sources which have been merged into the
098     * data set. Each of these sources can optionally declare a bounding box of the
099     * data it supplied to the dataset.</p>
100     *
101     * <p>This method replies the list of defined (non {@code null}) bounding boxes.</p>
102     * @param dataSources list of data sources
103     *
104     * @return the list of data source bounds. An empty list, if no non-null data source
105     * bounds are defined.
106     * @see Data#getDataSourceBounds()
107     */
108    public static List<Bounds> getDataSourceBounds(Collection<DataSource> dataSources) {
109        if (dataSources == null) {
110            return null;
111        }
112        List<Bounds> ret = new ArrayList<>(dataSources.size());
113        for (DataSource ds : dataSources) {
114            if (ds.bounds != null) {
115                ret.add(ds.bounds);
116            }
117        }
118        return ret;
119    }
120}