use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class ShapefileFeatureStore method createFeatureType.
// //////////////////////////////////////////////////////////////////////////
// schema manipulation /////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
/**
* Set the FeatureType of this DataStore. This method will delete any
* existing local resources or throw an IOException if the featurestore is
* remote.
*
* @param featureType The desired FeatureType.
* @throws DataStoreException If the featurestore is remote.
*
* @todo must synchronize this properly
*/
@Override
public void createFeatureType(final FeatureType featureType) throws DataStoreException {
final GenericName typeName = featureType.getName();
if (!isWritable(typeName.toString())) {
throw new DataStoreException("Read-only acces prevent type creation.");
}
if (typeName == null) {
throw new DataStoreException("Type name can not be null.");
}
if (!featureType.isSimple()) {
throw new DataStoreException("Feature type must not be null and must be a simple feature type.");
}
if (!featureType.getName().equals(typeName)) {
throw new DataStoreException("Shapefile featurestore can only hold typename same as feature type name.");
}
try {
// delete the files
shpFiles.delete();
} catch (IOException ex) {
throw new DataStoreException("Cannot reset datastore content", ex);
}
final AccessManager locker = shpFiles.createLocker();
// update schema and name
name = typeName;
schema = featureType;
AttributeType desc;
try {
desc = Features.toAttribute(FeatureExt.getDefaultGeometry(featureType)).orElse(null);
} catch (PropertyNotFoundException e) {
getLogger().log(Level.FINE, e, () -> String.format("No geometry can be found in given datatype%n%s", featureType));
desc = null;
}
CoordinateReferenceSystem crs = null;
final Class<?> geomType;
final ShapeType shapeType;
if (desc != null) {
crs = FeatureExt.getCRS(desc);
geomType = desc.getValueClass();
shapeType = ShapeType.findBestGeometryType(geomType);
} else {
geomType = null;
shapeType = ShapeType.NULL;
}
if (shapeType == ShapeType.UNDEFINED) {
throw new DataStoreException("Cannot create a shapefile whose geometry type is " + geomType);
}
try (Closeable disposeLocker = locker::disposeReaderAndWriters) {
final StorageFile shpStoragefile = locker.getStorageFile(SHP);
final StorageFile shxStoragefile = locker.getStorageFile(SHX);
final StorageFile dbfStoragefile = locker.getStorageFile(DBF);
final StorageFile prjStoragefile = locker.getStorageFile(PRJ);
final StorageFile cpgStoragefile = locker.getStorageFile(CPG);
try (FileChannel shpChannel = shpStoragefile.getWriteChannel();
FileChannel shxChannel = shxStoragefile.getWriteChannel()) {
try (ShapefileWriter writer = new ShapefileWriter(shpChannel, shxChannel)) {
// try to get the domain first
final Envelope domain = CRS.getDomainOfValidity(crs);
if (domain != null) {
writer.writeHeaders(new JTSEnvelope2D(domain), shapeType, 0, 100);
} else {
// try to reproject the single overall envelope keeping poles out of the way
final JTSEnvelope2D env = new JTSEnvelope2D(-179, 179, -89, 89, CommonCRS.WGS84.normalizedGeographic());
JTSEnvelope2D transformedBounds;
if (crs != null) {
try {
transformedBounds = env.transform(crs);
} catch (Exception t) {
getLogger().log(Level.WARNING, t.getLocalizedMessage(), t);
// It can happen for local projections :
transformedBounds = new JTSEnvelope2D(crs);
}
} else {
transformedBounds = env;
}
writer.writeHeaders(transformedBounds, shapeType, 0, 100);
}
}
}
final DbaseFileHeader dbfheader = DbaseFileHeader.createDbaseHeader(schema);
dbfheader.setNumRecords(0);
try (WritableByteChannel dbfChannel = dbfStoragefile.getWriteChannel()) {
dbfheader.writeHeader(dbfChannel);
}
if (crs != null) {
// .prj files should have no carriage returns in them, this messes up
// ESRI's ArcXXX software, so we'll be compatible
final WKTFormat format = new WKTFormat(Locale.ENGLISH, null);
format.setConvention(Convention.WKT1_COMMON_UNITS);
format.setNameAuthority(Citations.ESRI);
format.setIndentation(WKTFormat.SINGLE_LINE);
final String s = format.format(crs);
IOUtilities.writeString(s, prjStoragefile.getFile(), Charset.forName("ISO-8859-1"));
} else {
getLogger().warning("PRJ file not generated for null CoordinateReferenceSystem");
Path prjFile = prjStoragefile.getFile();
Files.deleteIfExists(prjFile);
}
// write dbf encoding .cpg
CpgFiles.write(dbfCharset, cpgStoragefile.getFile());
} catch (IOException ex) {
throw new DataStoreException(ex);
}
// Once all writings have succeeded, we can commit them
try {
locker.replaceStorageFiles();
} catch (IOException e) {
throw new DataStoreException("Failed commiting file changes", e);
}
// force reading it again since the file type may be a little different
name = null;
schema = null;
// we still preserve the original type name and attribute classes which may be more restricted
final FeatureTypeBuilder ftb = new FeatureTypeBuilder(getFeatureType());
ftb.setName(typeName);
final AttributeTypeBuilder gtb = (AttributeTypeBuilder) ftb.getProperty("the_geom");
if (Geometry.class.equals(gtb.getValueClass())) {
gtb.setValueClass(shapeType.bestJTSClass());
}
gtb.setName(desc.getName());
for (PropertyType pt : featureType.getProperties(true)) {
if (pt instanceof AttributeType) {
final AttributeType at = (AttributeType) pt;
if (!Geometry.class.isAssignableFrom(at.getValueClass())) {
try {
((AttributeTypeBuilder) ftb.getProperty(at.getName().toString())).setValueClass(at.getValueClass()).setName(at.getName());
} catch (PropertyNotFoundException ex) {
}
}
}
}
schema = ftb.build();
name = schema.getName();
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class ShapefileFeatureWriter method write.
/**
* {@inheritDoc }
*/
@Override
public void write() throws FeatureStoreRuntimeException {
if (currentFeature == null) {
throw new FeatureStoreRuntimeException("Current feature is null");
}
if (featureReader == null) {
throw new FeatureStoreRuntimeException("Writer closed");
}
// writing of Geometry
Geometry g = FeatureExt.getDefaultGeometryValue(currentFeature).filter(Geometry.class::isInstance).map(Geometry.class::cast).orElse(null);
// if this is the first Geometry, find the shapeType and handler
if (shapeType == null) {
int dims = 2;
if (g != null) {
dims = JTSUtilities.guessCoorinateDims(g.getCoordinates());
}
try {
shapeType = JTSUtilities.getShapeType(g, dims);
// we must go back and annotate this after writing
shpWriter.writeHeaders(new Envelope(), shapeType, 0, 0);
handler = shapeType.getShapeHandler(true);
} catch (Exception se) {
throw new FeatureStoreRuntimeException("Unexpected Error", se);
}
}
// convert geometry
g = JTSUtilities.convertToCollection(g, shapeType);
// bounds calculations
Envelope b = g.getEnvelopeInternal();
if (!b.isNull()) {
bounds.expandToInclude(b);
}
// file length update
shapefileLength += (handler.getLength(g) + 8);
try {
// write it
shpWriter.writeGeometry(g);
} catch (IOException ex) {
throw new FeatureStoreRuntimeException(ex);
}
// writing of attributes
int idx = 0;
List<AttributeType> attributes = parent.getAttributes(featureType, false);
for (int i = 0, ii = attributes.size(); i < ii; i++) {
// skip geometries
if (writeFlags[i] > 0) {
transferCache[idx++] = currentFeature.getPropertyValue(attributes.get(i).getName().toString());
}
}
try {
dbfWriter.write(transferCache);
} catch (IOException ex) {
throw new FeatureStoreRuntimeException(ex);
} catch (DbaseFileException ex) {
throw new FeatureStoreRuntimeException(ex);
}
// one more down...
records++;
if (originalFeature == null) {
addedIds.add(FeatureExt.getId(currentFeature));
} else if (!originalFeature.equals(currentFeature)) {
updatedIds.add(FeatureExt.getId(currentFeature));
}
// clear the currentFeature
currentFeature = null;
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class ShapefileFeatureWriter method flush.
/**
* Go back and update the headers with the required info.
*
* @throws IOException DOCUMENT ME!
*/
protected void flush() throws IOException {
// another problem.
if ((records <= 0) && (shapeType == null)) {
try {
final PropertyType geom = FeatureExt.getDefaultGeometry(featureType);
final Optional<Class> geomClass = Features.toAttribute(geom).map(AttributeType::getValueClass);
shapeType = geomClass.map(ShapeType::findBestGeometryType).orElse(ShapeType.NULL);
if (shapeType == ShapeType.UNDEFINED) {
throw new IOException("Cannot handle geometry class : " + (geomClass.isPresent() ? geomClass.get() : "null"));
}
} catch (PropertyNotFoundException e) {
shapeType = ShapeType.NULL;
}
}
shpWriter.writeHeaders(bounds, shapeType, records, shapefileLength);
dbfHeader.setNumRecords(records);
dbfChannel.position(0);
dbfHeader.writeHeader(dbfChannel);
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method getBBoxAttributesReader.
protected IndexedShapefileAttributeReader getBBoxAttributesReader(final List<AttributeType> properties, final Envelope bbox, final boolean loose, final Hints hints, final boolean read3D, final double[] res) throws DataStoreException {
final AccessManager locker = shpFiles.createLocker();
final double[] minRes = (double[]) hints.get(Hints.KEY_IGNORE_SMALL_FEATURES);
CloseableCollection<ShpData> goodCollec = null;
try {
final QuadTree quadTree = openQuadTree();
if (quadTree != null) {
final ShxReader shx;
try {
shx = locker.getSHXReader(useMemoryMappedBuffer);
} catch (IOException ex) {
throw new DataStoreException("Error opening Shx file: " + ex.getMessage(), ex);
}
final DataReader<ShpData> dr = new IndexDataReader(shx);
goodCollec = quadTree.search(dr, bbox, minRes);
}
} catch (Exception e) {
throw new DataStoreException("Error querying index: " + e.getMessage());
}
final LazySearchCollection<ShpData> col = (LazySearchCollection) goodCollec;
final LazyTyleSearchIterator.Buffered<ShpData> ite = (col != null) ? col.bboxIterator() : null;
// check if we need to open the dbf reader, no need when only geometry
final boolean readDBF = !(properties.size() == 1 && Geometry.class.isAssignableFrom(properties.get(0).getValueClass()));
final AttributeType[] atts = properties.toArray(new AttributeType[properties.size()]);
try {
return new IndexedBBoxShapefileAttributeReader(locker, atts, read3D, useMemoryMappedBuffer, res, readDBF, dbfCharset, minRes, col, ite, bbox, loose, minRes);
} catch (IOException ex) {
throw new DataStoreException(ex);
}
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class RandomStyleBuilder method createVectorStyle.
public static MutableStyle createVectorStyle(final FeatureType typ, Supplier<PolygonSymbolizer> polygonSymbol, Supplier<PointSymbolizer> pointSymbol, Supplier<LineSymbolizer> lineSymbol) {
final Symbolizer ps;
final PropertyType defAtt;
try {
defAtt = FeatureExt.getDefaultGeometry(typ);
} catch (PropertyNotFoundException | IllegalStateException ex) {
return SF.style();
}
final AttributeType type = Features.toAttribute(defAtt).orElse(null);
if (type == null)
return SF.style();
final Class cla = type.getValueClass();
if (cla.equals(Polygon.class) || cla.equals(MultiPolygon.class)) {
ps = polygonSymbol.get();
} else if (cla.equals(LineString.class) || cla.equals(MultiLineString.class)) {
ps = lineSymbol.get();
} else if (cla.equals(Point.class) || cla.equals(MultiPoint.class)) {
ps = pointSymbol.get();
} else {
// multiple types, create rules
final MutableStyle style = SF.style();
final MutableFeatureTypeStyle fts = SF.featureTypeStyle();
final MutableRule rulePoint = SF.rule(pointSymbol.get());
rulePoint.setFilter(FF.or(FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("Point")), FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("MultiPoint"))));
final MutableRule ruleLine = SF.rule(lineSymbol.get());
ruleLine.setFilter(FF.or(FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("LineString")), FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("MultiLineString"))));
final MutableRule rulePolygon = SF.rule(polygonSymbol.get());
rulePolygon.setFilter(FF.or(FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("Polygon")), FF.equal(FF.function("geometryType", FF.property(type.getName().toString())), FF.literal("MultiPolygon"))));
fts.rules().add(rulePoint);
fts.rules().add(ruleLine);
fts.rules().add(rulePolygon);
style.featureTypeStyles().add(fts);
return style;
}
final MutableStyle style = SF.style();
style.featureTypeStyles().add(SF.featureTypeStyle(ps));
return style;
}
Aggregations