org.geolatte.geom.codec.BaseWktWriter Maven / Gradle / Ivy
Show all versions of geolatte-geom Show documentation
package org.geolatte.geom.codec;
import org.geolatte.geom.*;
class BaseWktWriter {
private final StringBuilder builder;
private final WktDialect dialect;
/**
* Constructs an instance.
*/
public BaseWktWriter(WktDialect variant, StringBuilder builder) {
this.dialect = variant;
this.builder = builder;
}
public String writeGeometry(Geometry
geometry) {
addSrid(geometry.getSRID());
addGeometry(geometry, true);
return result();
}
protected void addSrid(int srid) {
dialect.addSrid(builder, srid);
}
protected
void addGeometry(Geometry
geometry, boolean topLevel) {
addGeometryTag(geometry);
addGeometryZMMarker(geometry);
addGeometryText(geometry);
}
protected void addGeometryTag(Geometry> geometry) {
dialect.addGeometryTag(builder, geometry);
}
protected void addGeometryZMMarker(Geometry> geometry) {
dialect.addGeometryZMMarker(builder, geometry);
}
protected
void addGeometryText(Geometry
geometry) {
if (geometry.isEmpty()) {
addEmptyKeyword();
return;
}
GeometryType type = geometry.getGeometryType();
switch (type) {
case POINT:
case LINESTRING:
case LINEARRING:
addPointList(geometry.getPositions());
break;
case POLYGON:
addStartList();
addLinearRings((Polygon
) geometry);
addEndList();
break;
case GEOMETRYCOLLECTION:
addStartList();
addGeometries((AbstractGeometryCollection
) geometry, true);
addEndList();
break;
case MULTIPOINT:
addMultiPointText(geometry);
break;
case MULTILINESTRING:
case MULTIPOLYGON:
addStartList();
addGeometries((AbstractGeometryCollection
) geometry, false);
addEndList();
break;
default:
throw new UnsupportedConversionException(String.format("Geometry type %s not supported.", type));
}
}
protected
void addMultiPointText(Geometry
geometry) {
if(dialect.writeMultiPointAsListOfPositions()) {
addPointList(geometry.getPositions());
} else {
addStartList();
addGeometries((AbstractGeometryCollection
) geometry, false);
addEndList();
}
}
protected
> void addGeometries(AbstractGeometryCollection
collection, boolean withTag) {
for (int i = 0; i < collection.getNumGeometries(); i++) {
if (i > 0) {
addDelimiter();
}
Geometry> geom = collection.getGeometryN(i);
if (withTag) {
addGeometry(geom, false);
} else {
addGeometryText(geom);
}
}
}
protected
void addLinearRings(Polygon
geometry) {
addRing(geometry.getExteriorRing());
for (int i = 0; i < geometry.getNumInteriorRing(); i++) {
addDelimiter();
addRing(geometry.getInteriorRingN(i));
}
}
protected
void addRing(LinearRing
ring) {
addPointList(ring.getPositions());
}
protected
void addPointList(PositionSequence
points) {
addStartList();
addPositions(points);
addEndList();
}
protected
double[] createCoordinateBuffer(PositionSequence
positions) {
if(dialect.isLimitedTo2D()) {
return new double[2];
}
return new double[positions.getCoordinateDimension()];
}
protected
void setCoordinatesToWrite(PositionSequence
positions, int pos, double[] coords) {
if(dialect.isLimitedTo2D()) {
coords[0] = positions.getPositionN(pos).getCoordinate(0);
coords[1] = positions.getPositionN(pos).getCoordinate(1);
} else {
for (int i = 0; i < positions.getCoordinateDimension(); i++) {
coords[i] = positions.getPositionN(pos).getCoordinate(i);
}
}
}
private
void addPositions(PositionSequence
positions) {
double[] coords = createCoordinateBuffer(positions);
for (int i = 0; i < positions.size(); i++) {
if (i > 0) {
addDelimiter();
}
setCoordinatesToWrite(positions, i, coords);
for (int k = 0; k < coords.length; k++) {
//this is locale independent as it should be
if (k > 0) builder.append(' ');
builder.append(formatCoordinate(coords[k]));
}
}
}
private String formatCoordinate(double coord) {
if (coord == (long) coord) {
return String.valueOf((long) coord);
} else {
return String.valueOf(coord);
}
}
private void addEndList() {
builder.append(')');
}
private void addDelimiter() {
builder.append(",");
}
private void addStartList() {
builder.append("(");
}
private void addEmptyKeyword() {
builder.append(" EMPTY");
}
private String result() {
return builder.toString();
}
}