package net.sourceforge.gpstools.kml;
/* gpxconv
* Copyright (C) 2006 Moritz Ringler
* $Id: QuantityTrackWriter.java 441 2010-12-13 20:04:20Z ringler $
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Date;
import net.sourceforge.gpstools.TrackAnalyzer;
import net.sourceforge.gpstools.gpx.GpxType;
import net.sourceforge.gpstools.plot.SvgPlot;
import net.sourceforge.gpstools.utils.ColorFunction;
import net.sourceforge.gpstools.utils.ColorFunctionFactory;
import net.sourceforge.gpstools.utils.ValueFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.xml.sax.SAXException;
public class QuantityTrackWriter extends GpxTrackWriter{
private final double min;
private final double max;
private final TrackAnalyzer.Quantity q;
protected static float DEFAULT_STARTHUE = 0.66f;
protected static int DEFAULT_NUMHUES = 256;
private QuantityTrackWriter(OutputStream out, String name,
ValueFunction vf, ColorFunction cf,
double ymin, double ymax,
TrackAnalyzer.Quantity q)
throws SAXException, IOException{
super(out, name, vf, cf);
min = ymin;
max = ymax;
this.q = q;
}
public static QuantityTrackWriter getInstance(OutputStream out,
String name,
TrackAnalyzer.Quantity q,
TrackAnalyzer ta) throws SAXException, IOException{
ValueFunction vf = ColorFunctionFactory.createValueFunction(ta, q);
UnivariateRealFunction hue = null;
double ymin = Double.POSITIVE_INFINITY;
double ymax = Double.NEGATIVE_INFINITY;
if (q == TrackAnalyzer.Quantity.Bearing){
hue = new UnivariateRealFunction(){
@Override
public double value(double bearing){
return DEFAULT_STARTHUE - Math.round(bearing)/360.;
}
};
ymin = 0;
ymax = 360;
} else {
for(double[] dd : ta.getSupportPoints()){
for (double d : dd){
double val = Double.NaN;
try{
val = ta.getQuantity(new Date((long) d), q);
} catch(Exception ex){
//val = Double.NaN;
}
if(Double.isNaN(val)){
continue;
}
ymax = Math.max(ymax, val);
ymin = Math.min(ymin, val);
}
}
if(ymin == Double.POSITIVE_INFINITY){
ymin = 0;
ymax = 1;
}
hue = ColorFunctionFactory.createLinearHueFunction(ymin, ymax,
DEFAULT_NUMHUES,
DEFAULT_STARTHUE, -1);
}
ColorFunctionFactory cff = new ColorFunctionFactory();
cff.setHueFunction(hue);
cff.setAlpha(200);
ColorFunction cf = cff.createColorFunction();
return new QuantityTrackWriter(out, name, vf, cf, ymin, ymax, q);
}
@Override
public void writeGpx(GpxType gpx) throws SAXException, IOException{
writeLegend();
super.writeGpx(gpx);
}
public void writeLegend() throws SAXException, IOException{
writeLegendStyle();
xw.startElement("Folder");
xw.textElement("name", "Legend: " + q.longName());
double[] legendElements = SvgPlot.ticks(min, max);
if(legendElements[0] != min){
writeLegendEntry(min);
}
for(double d : legendElements){
writeLegendEntry(d);
}
if(legendElements[legendElements.length - 1] != max){
writeLegendEntry(max);
}
xw.textElement("open", "1");
xw.textElement("visibility", "1");
xw.endElement("Folder");
}
@Override
protected NumberFormat getValueFormat(){
double step = Math.abs(max - min)/DEFAULT_NUMHUES;
step /= 10.;
StringBuilder sb = new StringBuilder("#0.");
while(step < 1){
sb.append('#');
step *= 10;
}
DecimalFormat df = new DecimalFormat(sb.toString());
final DecimalFormatSymbols sym = df.getDecimalFormatSymbols();
sym.setDecimalSeparator('.');
df.setDecimalFormatSymbols(sym);
return df;
}
private void writeLegendStyle() throws SAXException, IOException{
xw.attribute("id", "legend");
xw.startElement("Style");
xw.startElement("IconStyle");
xw.startElement("Icon");
xw.textElement("href", "http://maps.google.com/mapfiles/kml/pal2/icon15.png");
xw.endElement("Icon");
xw.endElement("IconStyle");
xw.endElement("Style");
}
private void writeLegendEntry(double d) throws SAXException, IOException{
xw.startElement("Placemark");
writeLabel(d);
xw.textElement("styleUrl", "#legend");
xw.textElement("visibility", "1");
xw.endElement("Placemark");
}
}