/* Copyright 2013 The jeo project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jeo.proj.wkt;
import org.osgeo.proj4j.CoordinateReferenceSystem;
import org.osgeo.proj4j.datum.Datum;
import org.osgeo.proj4j.datum.Ellipsoid;
import org.osgeo.proj4j.proj.LongLatProjection;
import org.osgeo.proj4j.proj.Projection;
import org.osgeo.proj4j.units.Unit;
import org.osgeo.proj4j.units.Units;
public class ProjWKTEncoder {
private static String q = "\"";
public String encode(CoordinateReferenceSystem crs) {
return encode(crs, true);
}
public String encode(CoordinateReferenceSystem crs, boolean format) {
return encodeCRS(crs, new StringBuilder(), format ? 0 : -1);
}
String encodeCRS(CoordinateReferenceSystem crs, StringBuilder buf, int indent) {
return crs.getProjection() instanceof LongLatProjection ?
encodeGeoCRS(crs, buf, indent) : encodeProjCS(crs, buf, indent);
}
String encodeGeoCRS(CoordinateReferenceSystem crs, StringBuilder buf, int indent) {
doIndent(buf, indent).append("GEOGCS[").append(q).append(crs.getName()).append(q).append(",");
encodeDatum(crs.getDatum(), buf, addIndent(indent)).append(",");
encodePrimeMeridian(crs, buf, addIndent(indent)).append(",");
encodeUnit(crs.getProjection(), Units.RADIANS, buf, addIndent(indent)).append(",");
encodeAxis("Geodetic longitude", "EAST", buf, addIndent(indent)).append(",");
encodeAxis("Geodetic latitude", "NORTH", buf, addIndent(indent));
buf.append("]");
return buf.toString();
}
StringBuilder encodeDatum(Datum datum, StringBuilder buf, int indent) {
doIndent(buf, indent).append("DATUM[").append(q).append(datum.getName()).append(q).append(",");
encodeEllipsoid(datum.getEllipsoid(), buf, addIndent(indent));
double[] toWgs84 = datum.getTransformToWGS84();
if (toWgs84 != null) {
buf.append(",");
encodeTOWGS84(toWgs84, buf, addIndent(indent));
}
return buf.append("]");
}
StringBuilder encodeEllipsoid(Ellipsoid e, StringBuilder buf, int indent) {
double invFlat = e.getA() / (e.getA() - e.getB());
return doIndent(buf, indent).append("SPHEROID[")
.append(q).append(e.getName()).append(q).append(", ")
.append(e.getEquatorRadius()).append(", ").append(invFlat)
.append("]");
}
StringBuilder encodeTOWGS84(double[] toWgs84, StringBuilder buf, int indent) {
doIndent(buf, indent).append("TOWGS84[");
for (double d : toWgs84) {
buf.append(d).append(", ");
}
buf.setLength(buf.length()-2);
return buf.append("]");
}
StringBuilder encodePrimeMeridian(CoordinateReferenceSystem crs, StringBuilder buf, int indent) {
doIndent(buf, indent).append("PRIMEM[").append(q).append("Greenwich").append(q)
.append(", 0.0]");
return buf;
}
StringBuilder encodeUnit(Projection p, Unit base, StringBuilder buf, int indent) {
Unit unit = p.getUnits();
if (unit != null) {
double scale = Units.convert(1, unit, base);
doIndent(buf, indent).append("UNIT[").append(q).append(unit.name).append(q)
.append(", ").append(scale).append("]");
}
return buf;
}
StringBuilder encodeAxis(String name, String dir, StringBuilder buf, int indent) {
doIndent(buf, indent).append("AXIS[").append(q).append(name).append(q)
.append(", ").append(dir).append("]");
return buf;
}
String encodeProjCS(CoordinateReferenceSystem crs, StringBuilder buf, int indent) {
doIndent(buf, indent).append("PROJCS[").append(q).append(crs.getName()).append(q).append(",");
encodeGeoCRS(crs.createGeographic(), buf, addIndent(indent));
buf.append(",");
Projection p = crs.getProjection();
encodeProjection(p, buf, addIndent(indent)).append(",");
encodeParameter("central_meridian", p.getProjectionLongitudeDegrees(), buf, addIndent(indent)).append(",");
encodeParameter("latitude_of_origin", p.getProjectionLatitudeDegrees(), buf, addIndent(indent)).append(",");
encodeParameter("scale_factor", p.getScaleFactor(), buf, addIndent(indent)).append(",");
encodeParameter("false_easting", p.getFalseEasting(), buf, addIndent(indent)).append(",");
encodeParameter("false_northing", p.getFalseNorthing(), buf, addIndent(indent)).append(",");
encodeUnit(crs.getProjection(), Units.METRES, buf, addIndent(indent)).append(",");
encodeAxis("Easting", "EAST", buf, addIndent(indent)).append(",");
encodeAxis("Northing", "NORTH", buf, addIndent(indent));
buf.append("]");
return buf.toString();
}
StringBuilder encodeProjection(Projection p, StringBuilder buf, int indent) {
String name = null;/*p.getWktName();*/
if (name == null) {
name = p.getName();
}
doIndent(buf, indent).append("PROJECTION[").append(q).append(name).append(q).append("]");
return buf;
}
StringBuilder encodeParameter(String key, double val, StringBuilder buf, int indent) {
return doIndent(buf, indent).append("PARAMETER[")
.append(q).append(key).append(q).append(", ")
.append(val).append("]");
}
StringBuilder doIndent(StringBuilder buf, int indent) {
if (indent > -1) {
if (indent > 0) {
buf.append("\n");
}
for (int i = 0; i < indent; i++) {
buf.append(" ");
}
}
return buf;
}
int addIndent(int indent) {
return indent > -1 ? indent + 2 : indent;
}
}