/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.kml;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.util.Locale;
import org.geotools.gml.producer.CoordinateWriter;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import com.vividsolutions.jts.geom.CoordinateSequence;
/**
* Essentially the same as the GML CoordinateWriter, but avoids adding
* attributes to coodinates tag and other stuff the KML code does not
* invoke.
*
* See
*
* @author Arne Kepp - OpenGeo
* @deprecated This class is a copy of CoordinateWriter in geotools, we should
* reuse that version and create any options we might need to customize.
*/
public class KMLCoordinateWriter extends CoordinateWriter {
private AttributesImpl atts;
private static final double DECIMAL_MIN = Math.pow(10, -3);
private static final double DECIMAL_MAX = Math.pow(10, 7);
private static final String coordinateDelimiter = ",";
private static final String tupleDelimiter = " ";
private final StringBuffer coordBuff = new StringBuffer();
private char[] buff = new char[200];
private final double scale;
private final NumberFormat coordFormatter = NumberFormat
.getInstance(Locale.US);
private final FieldPosition zero = new FieldPosition(0);
/** Dummy Z value (used to override coordinate.Z value) */
// private final double dummyZ;
/** Dimension of expected coordinates */
private final int D;
public KMLCoordinateWriter(int numDecimals, boolean isDummyZEnabled) {
super(numDecimals, isDummyZEnabled);
atts = new org.xml.sax.helpers.AttributesImpl();
scale = Math.pow(10, numDecimals);
D = 3;
// dummyZ = 0;
}
public void writeCoordinates(CoordinateSequence c, ContentHandler output)
throws SAXException {
output.startElement("", "coordinates", "coordinates", atts);
final int coordCount = c.size();
// used to check whether the coordseq handles a third dimension or not
final int coordSeqDimension = c.getDimension();
double x, y, z;
// write down a coordinate at a time
for (int i = 0, n = coordCount; i < n; i++) {
x = c.getOrdinate(i, 0);
y = c.getOrdinate(i, 1);
// clear the buffer
coordBuff.setLength(0);
// format x into buffer and append delimiter
formatDecimal(x, coordBuff);
coordBuff.append(coordinateDelimiter);
// format y into buffer
formatDecimal(y, coordBuff);
if (coordSeqDimension > 2 && !Double.isNaN(c.getOrdinate(i, 2))){
coordBuff.append(coordinateDelimiter);
formatDecimal(c.getOrdinate(i, 2), coordBuff);
}
// if there is another coordinate, tack on a tuple delimiter
if (i + 1 < coordCount) {
coordBuff.append(tupleDelimiter);
}
// make sure our character buffer is big enough
if (coordBuff.length() > buff.length) {
buff = new char[coordBuff.length()];
}
// copy the characters
coordBuff.getChars(0, coordBuff.length(), buff, 0);
// finally, output
output.characters(buff, 0, coordBuff.length());
}
output.endElement(null, "coordinates", "coordinates");
}
private void formatDecimal(double x, StringBuffer sb) {
if (Math.abs(x) >= DECIMAL_MIN && x < DECIMAL_MAX) {
x = Math.floor(x * scale + 0.5) / scale;
long lx = (long) x;
if (lx == x)
sb.append(lx);
else
sb.append(x);
} else {
coordFormatter.format(x, coordBuff, zero);
}
}
}