package org.geotoolkit.data.geojson;
import com.fasterxml.jackson.core.JsonEncoding;
import com.vividsolutions.jts.geom.Geometry;
import org.apache.sis.storage.DataStoreException;
import org.geotoolkit.data.FeatureStoreRuntimeException;
import org.geotoolkit.data.FeatureWriter;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.sis.feature.FeatureExt;
import org.apache.sis.internal.feature.AttributeConvention;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
/**
* @author Quentin Boileau (Geomatys)
*/
public class GeoJSONStreamWriter implements FeatureWriter {
private final GeoJSONWriter writer;
private final FeatureType featureType;
private Feature edited = null;
private Feature lastWritten = null;
private int currentFeatureIdx = 0;
/**
*
* @param outputStream stream were GeoJSON will be written
* @param featureType {@link FeatureType} of features to write.
* @param doubleAccuracy number of coordinates fraction digits
* @throws DataStoreException
*/
public GeoJSONStreamWriter(OutputStream outputStream, FeatureType featureType, final int doubleAccuracy)
throws DataStoreException {
this(outputStream, featureType, JsonEncoding.UTF8, doubleAccuracy);
}
/**
*
* @param outputStream stream were GeoJSON will be written
* @param featureType {@link FeatureType} of features to write.
* @param encoding character encoding
* @param doubleAccuracy number of coordinates fraction digits
* @throws DataStoreException
*/
public GeoJSONStreamWriter(OutputStream outputStream, FeatureType featureType, final JsonEncoding encoding, final int doubleAccuracy)
throws DataStoreException {
this(outputStream, featureType, encoding, doubleAccuracy, false);
}
public GeoJSONStreamWriter(OutputStream outputStream, FeatureType featureType, final JsonEncoding encoding, final int doubleAccuracy, boolean prettyPrint)
throws DataStoreException {
this.featureType= featureType;
try {
writer = new GeoJSONWriter(outputStream, encoding, doubleAccuracy, prettyPrint);
//start write feature collection.
writer.writeStartFeatureCollection(FeatureExt.getCRS(featureType), null);
writer.flush();
} catch (IOException ex) {
throw new DataStoreException(ex.getMessage(), ex);
}
}
/**
* Utility method to write a single Feature into an OutputStream
*
* @param outputStream
* @param feature to write
* @param encoding
* @param doubleAccuracy
* @param prettyPrint
*/
public static void writeSingleFeature(OutputStream outputStream, Feature feature, final JsonEncoding encoding,
final int doubleAccuracy, boolean prettyPrint) throws IOException {
try (final GeoJSONWriter writer = new GeoJSONWriter(outputStream, encoding, doubleAccuracy, prettyPrint)) {
writer.writeSingleFeature(feature);
}
}
/**
* Utility method to write a single Geometry into an OutputStream
*
* @param outputStream
* @param geometry to write
* @param encoding
* @param doubleAccuracy
* @param prettyPrint
*/
public static void writeSingleGeometry(OutputStream outputStream, Geometry geometry, final JsonEncoding encoding,
final int doubleAccuracy, boolean prettyPrint) throws IOException {
try (final GeoJSONWriter writer = new GeoJSONWriter(outputStream, encoding, doubleAccuracy, prettyPrint)) {
writer.writeSingleGeometry(geometry);
}
}
@Override
public FeatureType getFeatureType() {
return featureType;
}
@Override
public Feature next() throws FeatureStoreRuntimeException {
edited = featureType.newInstance();
edited.setPropertyValue(AttributeConvention.IDENTIFIER_PROPERTY.toString(), "id-" + currentFeatureIdx++);
return edited;
}
@Override
public void remove() throws FeatureStoreRuntimeException {
throw new FeatureStoreRuntimeException("Not supported on reader.");
}
@Override
public void write() throws FeatureStoreRuntimeException {
if(edited == null || edited.equals(lastWritten)) return;
lastWritten = edited;
try {
writer.writeFeature(edited);
writer.flush();
} catch (IOException | IllegalArgumentException e) {
throw new FeatureStoreRuntimeException(e.getMessage(), e);
}
}
@Override
public boolean hasNext() throws FeatureStoreRuntimeException {
return true;
}
@Override
public void close() {
try {
writer.writeEndFeatureCollection();
writer.flush();
writer.close();
} catch (IOException ex) {
throw new FeatureStoreRuntimeException(ex);
}
}
}