package org.mapfish.print.attribute.map;
import com.google.common.collect.Ordering;
import org.mapfish.print.config.Configuration;
import org.mapfish.print.config.ConfigurationException;
import org.mapfish.print.config.ConfigurationObject;
import org.mapfish.print.map.DistanceUnit;
import org.mapfish.print.map.Scale;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
import static org.mapfish.print.Constants.PDF_DPI;
/**
* <p>Encapsulates a sorted set of scale denominators representing the allowed scales.</p>
* <p>The scales are sorted from largest to smallest and the index starts at 0,
* where 0 is the largest scale (most zoomed out).</p>
* <pre><code>
* map: !map
* zoomLevels: !zoomLevels
* scales: [5000, 10000, 25000, 50000, 100000, 500000]</code></pre>
* [[examples=datasource_many_dynamictables_legend]]
*/
public final class ZoomLevels implements ConfigurationObject {
private double[] scaleDenominators;
/**
* Constructor.
*
* @param scaleDenominators do not need to be sorted or unique.
*/
public ZoomLevels(final double... scaleDenominators) {
setScales(scaleDenominators);
}
/**
* default constructor for constructing by spring.
*/
public ZoomLevels() {
// intentionally empty
}
/**
* Set the scales (sorts from largest to smallest).
* @param newScaleDenominators The scales (may be unsorted).
*/
public void setScales(final double[] newScaleDenominators) {
TreeSet<Double> sortedSet = new TreeSet<Double>(Ordering.natural().reverse());
for (int i = 0; i < newScaleDenominators.length; i++) {
sortedSet.add(newScaleDenominators[i]);
}
this.scaleDenominators = new double[sortedSet.size()];
int i = 0;
for (Double scaleDenominator : sortedSet) {
this.scaleDenominators[i] = scaleDenominator;
i++;
}
}
/**
* The number of zoom levels.
*/
public int size() {
return this.scaleDenominators.length;
}
/**
* Get the scale at the given index.
* @param index the index of the zoom level to access.
* @param unit the unit.
*/
public Scale get(final int index, final DistanceUnit unit) {
return new Scale(this.scaleDenominators[index], unit, PDF_DPI);
}
@Override
public String toString() {
return Arrays.toString(this.scaleDenominators);
}
// CHECKSTYLE:OFF
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ZoomLevels that = (ZoomLevels) o;
if (!Arrays.equals(scaleDenominators, that.scaleDenominators)) return false;
return true;
}
@Override
public int hashCode() {
return Arrays.hashCode(scaleDenominators);
}
@Override
public void validate(final List<Throwable> validationErrors, final Configuration configuration) {
if (scaleDenominators == null || scaleDenominators.length == 0) {
validationErrors.add(new ConfigurationException("There are no scales defined in " + getClass().getName()));
}
}
/**
* Return a copy of the zoom level scale denominators. Scales are sorted greatest to least.
*/
public double[] getScaleDenominators() {
double[] dest = new double[this.scaleDenominators.length];
System.arraycopy(this.scaleDenominators, 0, dest, 0, this.scaleDenominators.length);
return dest;
}
// CHECKSTYLE:ON
}