/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/
package org.geomajas.gwt.client.widget;
import com.google.gwt.i18n.client.NumberFormat;
/**
* Utility class for converting scales to string and the reverse.
*
* @author Joachim Van der Auwera
*/
public final class ScaleConverter {
public static final String ERROR_SCALE = "Negative or zero scale not allowed, did you use a correct pixel length?";
private ScaleConverter() {
// do not allow instantiation
}
/**
* Convert a scale to a string representation.
*
* @param scale scale to convert
* @param precision precision for the scale, or 0
* @param significantDigits maximum number of significant digits
* @return string representation for the scale
*/
public static String scaleToString(double scale, int precision, int significantDigits) {
NumberFormat numberFormat = NumberFormat.getFormat("###,###");
if (scale > 0 && scale < 1.0) {
int denominator = round((int) Math.round(1.0 / scale), precision, significantDigits);
return "1 : " + numberFormat.format(denominator);
} else if (scale >= 1.0) {
int nominator = round((int) Math.round(scale), precision, significantDigits);
return numberFormat.format(nominator) + " : 1";
} else {
return ERROR_SCALE;
}
}
/**
* Parse scale from string representation.
*
* @param value to parse
* @return scale value
*/
public static Double stringToScale(String value) {
NumberFormat numberFormat = NumberFormat.getFormat("###,###");
String[] scale2 = value.split(":");
if (scale2.length == 1) {
return 1.0 / numberFormat.parse(scale2[0].trim());
} else {
return numberFormat.parse(scale2[0].trim()) / numberFormat.parse(scale2[1].trim());
}
}
/**
* Round integer number by applying precision and maximum significant digits.
*
* @param value value to round
* @param precision precision
* @param significantDigits significant digits
* @return rounded value
*/
static int round(int value, int precision, int significantDigits) {
if (precision > 0) {
value = (value + precision / 2) / precision * precision;
}
if (significantDigits > 0) {
int forRounding = value;
int precisionMax = (int) Math.pow(10, significantDigits);
int multiplier = 1;
while (value > precisionMax) {
forRounding = value;
multiplier *= 10;
value /= 10;
}
if (forRounding % 10 >= 5) {
value++;
}
value *= multiplier;
}
return value;
}
}