use of org.geotoolkit.geometry.jts.JTSEnvelope2D in project geotoolkit by Geomatys.
the class AggregatedCoverageResource method initGridGeometry.
private void initGridGeometry() throws DataStoreException {
if (cachedGridGeometry != null)
return;
tree = new Quadtree();
final Map<GridCoverageResource, GridGeometry> components = new HashMap<>();
for (VirtualBand band : bands) {
for (Source source : band.sources) {
try {
final GridGeometry gridGeometry = source.resource.getGridGeometry();
if (!(gridGeometry.isDefined(GridGeometry.CRS) && gridGeometry.isDefined(GridGeometry.ENVELOPE))) {
throw new DataStoreException("Resource has no defined CRS and Envelope.");
}
final CoordinateReferenceSystem crs = gridGeometry.getCoordinateReferenceSystem();
if (crs instanceof ImageCRS) {
throw new DataStoreException("CRS " + crs.getClass() + " can not be used in aggregation, resource will be ignored.");
} else if (crs != null && crs.getCoordinateSystem().getDimension() != 2) {
throw new DataStoreException("CRS " + crs.getName() + " can not be used in aggregation it is not 2D, resource will be ignored.");
}
components.put(source.resource, gridGeometry);
} catch (Exception ex) {
if (neverfail) {
this.cachedGridGeometry = new GridGeometry(new GridExtent(1, 1), null, GridOrientation.HOMOTHETY);
LOGGER.log(Level.INFO, "Failed to extract grid geometry crs or envelope from resource " + resourceName(source.resource) + " : " + ex.getMessage());
source.inMetaError = true;
} else {
throw ex;
}
}
}
}
if (components.isEmpty()) {
// no data yet
this.cachedGridGeometry = new GridGeometry(new GridExtent(1, 1), null, GridOrientation.HOMOTHETY);
return;
} else if (components.size() == 1) {
// copy exact definition
final Map.Entry<GridCoverageResource, GridGeometry> entry = components.entrySet().iterator().next();
final GridCoverageResource resource = entry.getKey();
final GridGeometry gridGeometry = entry.getValue();
if (outputCrs == null || Utilities.equalsIgnoreMetadata(outputCrs, gridGeometry.getCoordinateReferenceSystem())) {
this.cachedGridGeometry = gridGeometry;
final JTSEnvelope2D key = new JTSEnvelope2D(gridGeometry.getEnvelope());
tree.insert(key, new IndexedResource(key, resource));
return;
}
}
if (outputCrs == null) {
// use most common crs
// TODO find a better approach to determinate a common crs
final FrequencySortedSet<CoordinateReferenceSystem> map = new FrequencySortedSet<>();
for (Map.Entry<GridCoverageResource, GridGeometry> entry : components.entrySet()) {
map.add(entry.getValue().getCoordinateReferenceSystem());
}
outputCrs = map.last();
}
// compute envelope and check sample dimensions
GeneralEnvelope env = new GeneralEnvelope(outputCrs);
env.setToNaN();
int index = 0;
double[] estimatedResolution = new double[outputCrs.getCoordinateSystem().getDimension()];
Arrays.fill(estimatedResolution, Double.POSITIVE_INFINITY);
// if all coverage resources have the same grid geometry we can use it directly
GridGeometry sharedGrid = components.entrySet().iterator().next().getValue();
if (!Utilities.equalsIgnoreMetadata(sharedGrid.getCoordinateReferenceSystem(), outputCrs)) {
sharedGrid = null;
}
for (Map.Entry<GridCoverageResource, GridGeometry> entry : components.entrySet()) {
final GridCoverageResource resource = entry.getKey();
final GridGeometry componentGrid = entry.getValue();
if (sharedGrid != null && !sharedGrid.equals(componentGrid)) {
// this coverage has a different grid
sharedGrid = null;
}
Envelope envelope = componentGrid.getEnvelope();
try {
envelope = Envelopes.transform(envelope, outputCrs);
} catch (TransformException ex) {
if (neverfail) {
LOGGER.log(Level.INFO, "Failed to transform resource envelope" + resourceName(resource) + " : " + ex.getMessage());
continue;
} else {
throw new DataStoreException(ex.getMessage(), ex);
}
}
final JTSEnvelope2D key = new JTSEnvelope2D(envelope);
tree.insert(key, new IndexedResource(key, resource));
// try to find an estimated resolution
if (estimatedResolution != null) {
try {
final double[] est = CoverageUtilities.estimateResolution(componentGrid.getEnvelope(), componentGrid.getResolution(true), outputCrs);
for (int i = 0; i < estimatedResolution.length; i++) {
estimatedResolution[i] = Math.min(estimatedResolution[i], est[i]);
}
} catch (FactoryException | MismatchedDimensionException | TransformException | IncompleteGridGeometryException ex) {
estimatedResolution = null;
}
}
if (env.isAllNaN()) {
env.setEnvelope(envelope);
} else {
env.add(envelope);
}
}
if (sharedGrid != null) {
cachedGridGeometry = sharedGrid;
} else if (env.isAllNaN()) {
// could not extract any usefull information from datas
this.cachedGridGeometry = new GridGeometry(new GridExtent(1, 1), null, GridOrientation.HOMOTHETY);
} else if (estimatedResolution != null) {
cachedGridGeometry = new EstimatedGridGeometry(env, estimatedResolution);
} else {
cachedGridGeometry = new GridGeometry(null, env, GridOrientation.HOMOTHETY);
}
}
use of org.geotoolkit.geometry.jts.JTSEnvelope2D 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.geotoolkit.geometry.jts.JTSEnvelope2D in project geotoolkit by Geomatys.
the class IndexedShapefileFeatureStore method getEnvelope.
@Override
public org.opengis.geometry.Envelope getEnvelope(final Query query) throws DataStoreException {
if (!(query instanceof org.geotoolkit.storage.feature.query.Query))
throw new UnsupportedQueryException();
final org.geotoolkit.storage.feature.query.Query gquery = (org.geotoolkit.storage.feature.query.Query) query;
final Filter filter = gquery.getSelection();
if (filter == Filter.include() || QueryUtilities.queryAll(gquery)) {
// use the generic envelope calculation
return super.getEnvelope(gquery);
}
final Set<String> fids = new TreeSet<>();
IdCollectorFilterVisitor.ID_COLLECTOR.visit(filter, fids);
final Set records = new HashSet();
if (!fids.isEmpty()) {
Collection<ShpData> recordsFound = null;
try {
recordsFound = queryFidIndex(fids);
} catch (IOException ex) {
throw new DataStoreException(ex);
}
if (recordsFound != null) {
records.addAll(recordsFound);
}
}
if (records.isEmpty())
return null;
final AccessManager locker = shpFiles.createLocker();
ShapefileReader reader = null;
try {
reader = locker.getSHPReader(false, false, false, null);
final JTSEnvelope2D ret = new JTSEnvelope2D(FeatureExt.getCRS(getFeatureType(getNames().iterator().next().toString())));
for (final Iterator iter = records.iterator(); iter.hasNext(); ) {
final Data data = (Data) iter.next();
reader.goTo(((Long) data.getValue(1)).intValue());
final Record record = reader.nextRecord();
ret.expandToInclude(record.minX, record.minY);
ret.expandToInclude(record.maxX, record.maxY);
}
return ret;
} catch (IOException ex) {
throw new DataStoreException(ex);
} finally {
// todo replace by ARM in JDK 1.7
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
throw new DataStoreException(ex);
}
}
}
}
use of org.geotoolkit.geometry.jts.JTSEnvelope2D in project geotoolkit by Geomatys.
the class LineLazySearchCollectionTest method testGetAllFeatures.
@Test
public void testGetAllFeatures() throws Exception {
JTSEnvelope2D env = new JTSEnvelope2D(585000, 610000, 4910000, 4930000, crs);
LazySearchCollection collection = new LazySearchCollection(tree, dr, env);
assertEquals(116, collection.size());
}
use of org.geotoolkit.geometry.jts.JTSEnvelope2D in project geotoolkit by Geomatys.
the class LineLazySearchCollectionTest method testGetOneFeatures.
@Test
public void testGetOneFeatures() throws Exception {
JTSEnvelope2D env = new JTSEnvelope2D(588993, 589604, 4927443, 4927443, crs);
LazySearchCollection collection = new LazySearchCollection(tree, dr, env);
assertEquals(33, collection.size());
}
Aggregations