package com.revolsys.record.io.format.kml; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.Collections; import java.util.Set; import com.revolsys.geometry.cs.CoordinateSystem; import com.revolsys.geometry.cs.GeographicCoordinateSystem; import com.revolsys.geometry.cs.epsg.EpsgCoordinateSystems; import com.revolsys.geometry.io.GeometryReader; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.io.FileUtil; import com.revolsys.io.map.MapWriter; import com.revolsys.io.map.MapWriterFactory; import com.revolsys.record.io.GeometryRecordReaderFactory; import com.revolsys.record.io.RecordWriter; import com.revolsys.record.io.RecordWriterFactory; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.spring.resource.Resource; public class Kml extends GeometryRecordReaderFactory implements RecordWriterFactory, MapWriterFactory { public static final Set<CoordinateSystem> COORDINATE_SYSTEMS = Collections .singleton(EpsgCoordinateSystems.wgs84()); public static long getLookAtRange(final BoundingBox boundingBox) { if (boundingBox.isEmpty() || boundingBox.getWidth() == 0 && boundingBox.getHeight() == 0) { return 1000; } else { final double minX = boundingBox.getMinX(); final double maxX = boundingBox.getMaxX(); final double centreX = boundingBox.getCentreX(); final double minY = boundingBox.getMinY(); final double maxY = boundingBox.getMaxY(); final double centreY = boundingBox.getCentreY(); double maxMetres = 0; for (final double y : new double[] { minY, centreY, maxY }) { final double widthMetres = GeographicCoordinateSystem.distanceMetres(minX, y, maxX, y); if (widthMetres > maxMetres) { maxMetres = widthMetres; } } for (final double x : new double[] { minX, centreX, maxX }) { final double heightMetres = GeographicCoordinateSystem.distanceMetres(x, minY, x, maxY); if (heightMetres > maxMetres) { maxMetres = heightMetres; } } if (maxMetres == 0) { return 1000; } else { final double lookAtScale = 1.2; final double lookAtRange = maxMetres / 2 / Math.tan(Math.toRadians(25)) * lookAtScale; return (long)Math.ceil(lookAtRange); } } } public Kml() { super(Kml22Constants.KML_FORMAT_DESCRIPTION); addMediaTypeAndFileExtension(Kml22Constants.KML_MEDIA_TYPE, Kml22Constants.KML_FILE_EXTENSION); } @Override public Set<CoordinateSystem> getCoordinateSystems() { return COORDINATE_SYSTEMS; } @Override public GeometryReader newGeometryReader(final Resource resource) { final KmlGeometryReader iterator = new KmlGeometryReader(resource); return iterator; } @Override public MapWriter newMapWriter(final java.io.Writer out) { return new KmlMapWriter(out); } @Override public MapWriter newMapWriter(final OutputStream out, final Charset charset) { return newMapWriter(out); } @Override public RecordWriter newRecordWriter(final String baseName, final RecordDefinition recordDefinition, final OutputStream outputStream, final Charset charset) { final OutputStreamWriter writer = FileUtil.newUtf8Writer(outputStream); return new KmlRecordWriter(writer); } }