package com.revolsys.record.io.format.saif.util; import java.io.IOException; import java.util.Map; import java.util.TreeMap; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.impl.LineStringDoubleBuilder; import com.revolsys.geometry.model.impl.LineStringDoubleGf; import com.revolsys.record.io.format.saif.SaifConstants; import com.revolsys.record.io.format.saif.geometry.ArcLineString; import com.revolsys.util.Property; public class ArcConverter implements OsnConverter { private final GeometryFactory geometryFactory; private final GeometryFactory geometryFactory3d; private String geometryType = SaifConstants.ARC; public ArcConverter(final GeometryFactory geometryFactory) { this.geometryFactory = geometryFactory; this.geometryFactory3d = geometryFactory.convertAxisCount(3); } public ArcConverter(final GeometryFactory geometryFactory, final String geometryType) { this(geometryFactory); this.geometryType = geometryType; } public void attributeEnum(final OsnSerializer serializer, final String name, final String value) throws IOException { if (value != null) { serializer.endLine(); serializer.attributeEnum(name, value, false); } } public LineString newLineString(final GeometryFactory geometryFactory, final LineStringDoubleBuilder line) { final int axisCount = geometryFactory.getAxisCount(); final int vertexCount = line.getVertexCount(); final double[] coordinates = LineStringDoubleGf.getNewCoordinates(geometryFactory, line); return new ArcLineString(geometryFactory, axisCount, vertexCount, coordinates); } @Override public Object read(final OsnIterator iterator) { final Map<String, Object> values = new TreeMap<>(); values.put(SaifConstants.TYPE, this.geometryType); String field = iterator.nextFieldName(); LineString geometry = null; while (field != null) { if (field.equals("LineString")) { int axisCount = 2; final LineStringDoubleBuilder line = new LineStringDoubleBuilder(this.geometryFactory); while (iterator.next() != OsnIterator.END_LIST) { final String pointName = iterator.nextObjectName(); if (!pointName.equals("/Point")) { iterator.throwParseError("Expecting Point object"); } final String coordsName = iterator.nextFieldName(); if (!coordsName.equals("coords")) { iterator.throwParseError("Expecting coords attribute"); } final String coordTypeName = iterator.nextObjectName(); if (coordTypeName.equals("/Coord3D")) { final double x = iterator.nextDoubleAttribute("c1"); final double y = iterator.nextDoubleAttribute("c2"); final double z = iterator.nextDoubleAttribute("c3"); axisCount = 3; line.appendVertex(x, y, z); } else if (coordTypeName.equals("/Coord2D")) { final double x = iterator.nextDoubleAttribute("c1"); final double y = iterator.nextDoubleAttribute("c2"); line.appendVertex(x, y); } else { iterator.throwParseError("Expecting Coord2D or Coord3D"); } iterator.nextEndObject(); iterator.nextEndObject(); } final int axisCount1 = axisCount; final GeometryFactory geometryFactory1 = this.geometryFactory.convertAxisCount(axisCount1); geometry = newLineString(geometryFactory1, line); } else { readAttribute(iterator, field, values); } field = iterator.nextFieldName(); } Property.set(geometry, values); return geometry; } protected void readAttribute(final OsnIterator iterator, final String fieldName, final Map<String, Object> values) { final Object value = iterator.nextValue(); values.put(fieldName, value); } @Override public void write(final OsnSerializer serializer, final Object object) throws IOException { final boolean writeAttributes = true; write(serializer, object, writeAttributes); } protected void write(final OsnSerializer serializer, final Object object, final boolean writeAttributes) throws IOException { if (object instanceof LineString) { final LineString line = (LineString)object; serializer.startObject(this.geometryType); serializer.fieldName("LineString"); serializer.startCollection("List"); final LineString points = line; final int axisCount = points.getAxisCount(); for (int i = 0; i < points.getVertexCount(); i++) { serializer.startObject(SaifConstants.POINT); serializer.fieldName("coords"); final double x = points.getX(i); final double y = points.getY(i); final double z = points.getZ(i); if (axisCount == 2) { serializer.startObject("/Coord2D"); serializer.attribute("c1", x, true); serializer.attribute("c2", y, false); } else { serializer.startObject("/Coord3D"); serializer.attribute("c1", x, true); serializer.attribute("c2", y, true); if (Double.isNaN(z)) { serializer.attribute("c3", 0, false); } else { serializer.attribute("c3", z, false); } } serializer.endObject(); serializer.endAttribute(); serializer.endObject(); } serializer.endCollection(); serializer.endAttribute(); if (writeAttributes && line instanceof ArcLineString) { writeAttributes(serializer, (ArcLineString)line); } serializer.endObject(); } } protected void writeAttribute(final OsnSerializer serializer, final Map<String, Object> values, final String name) throws IOException { final Object value = values.get(name); if (value != null) { serializer.endLine(); serializer.attribute(name, value, false); } } @Override public void writeAttribute(final OsnSerializer serializer, final Object object, final String name) throws IOException { } protected void writeAttributes(final OsnSerializer serializer, final ArcLineString line) throws IOException { final String qualifier = line.getQualifier(); attributeEnum(serializer, "qualifier", qualifier); } }