use of org.apache.sis.coverage.grid.GridGeometry in project sis by apache.
the class CoverageExplorer method notifyDataChanged.
/**
* Invoked in JavaFX thread after the current view finished to load the new coverage.
* It is the responsibility of all {@link ViewAndControls} subclasses to listen to change events
* emitted by their views ({@link GridView} or {@link CoverageCanvas}) and to invoke this method.
* This method will then update the properties of this {@code CoverageExplorer} for the new data.
*
* <p>Note that view data may have been changed either by user changing directly a {@link GridView}
* or {@link CoverageCanvas} property, or indirectly by user changing {@link #resourceProperty} or
* {@link #coverageProperty}. In the later case, the {@code resource} and {@code coverage} arguments
* given to this method may be the value that the properties already have.</p>
*
* @param resource the new source of coverage, or {@code null} if none.
* @param coverage the new coverage, or {@code null} if none.
*/
final void notifyDataChanged(final GridCoverageResource resource, final GridCoverage coverage) {
if (coverage != null) {
final GridGeometry gg = coverage.getGridGeometry();
referenceSystems.areaOfInterest.set(gg.isDefined(GridGeometry.ENVELOPE) ? gg.getEnvelope() : null);
if (gg.isDefined(GridGeometry.CRS)) {
referenceSystems.setPreferred(true, gg.getCoordinateReferenceSystem());
}
}
/*
* Following calls will NOT forward the new values to the views because this `notifyDataChanged(…)`
* method is invoked as a consequence of view properties being updated. Those views should already
* have the new property values at this moment.
*/
isCoverageAdjusting = true;
try {
setResource(resource);
setCoverage(coverage);
} finally {
isCoverageAdjusting = false;
}
}
use of org.apache.sis.coverage.grid.GridGeometry in project sis by apache.
the class CoverageCanvasApp method createImage.
/**
* Creates a dummy image for testing purpose. Some tiles will
* have artificial errors in order to see the error controls.
*/
private static GridCoverage2D createImage() {
final Random random = new Random();
final int width = TILE_WIDTH * 4;
final int height = TILE_HEIGHT * 2;
final TiledImageMock image = new TiledImageMock(DataBuffer.TYPE_BYTE, 1, // minX
random.nextInt(50) - 25, // minY
random.nextInt(50) - 25, width, height, TILE_WIDTH, TILE_HEIGHT, // minTileX
random.nextInt(10) - 5, // minTileY
random.nextInt(10) - 5, false);
image.validate();
final double sc = 500d / Math.max(width, height);
final WritablePixelIterator it = WritablePixelIterator.create(image);
while (it.next()) {
final Point p = it.getPosition();
final double d = Math.hypot(p.x - width / 2, p.y - height / 2);
int value = 0;
if ((Math.round(d) & 16) == 0) {
value = Math.max(0, 255 - (int) (d * sc));
}
it.setSample(0, value);
}
image.failRandomly(random, false);
return new GridCoverage2D(new GridGeometry(null, PixelInCell.CELL_CORNER, MathTransforms.identity(2), CommonCRS.Engineering.DISPLAY.crs()), null, image);
}
use of org.apache.sis.coverage.grid.GridGeometry in project sis by apache.
the class RenderingData method setCoverageSpace.
/**
* Sets the input space (domain) and output space (ranges) of the coverage to be rendered.
* It should be followed by a call to {@link #ensureImageLoaded(GridCoverage, GridExtent)}.
*
* @param domain the two-dimensional grid geometry, or {@code null} if there is no data.
* @param ranges descriptions of bands, or {@code null} if there is no data.
*
* @see #isEmpty()
*/
@SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
public final void setCoverageSpace(final GridGeometry domain, final List<SampleDimension> ranges) {
processor.setFillValues(SampleDimensions.backgrounds(ranges));
// Not cloned because already an unmodifiable list.
dataRanges = ranges;
dataGeometry = domain;
/*
* If the grid geometry does not define a "grid to CRS" transform, set it to an identity transform.
* We do that because this class needs a complete `GridGeometry` as much as possible.
*/
if (domain != null && !domain.isDefined(GridGeometry.GRID_TO_CRS) && domain.isDefined(GridGeometry.EXTENT)) {
CoordinateReferenceSystem crs = null;
if (domain.isDefined(GridGeometry.CRS)) {
crs = domain.getCoordinateReferenceSystem();
}
final GridExtent extent = domain.getExtent();
dataGeometry = new GridGeometry(extent, PixelInCell.CELL_CENTER, MathTransforms.identity(extent.getDimension()), crs);
}
}
use of org.apache.sis.coverage.grid.GridGeometry in project sis by apache.
the class GridGeometryBuilder method build.
/**
* Creates the grid geometry and collect related metadata.
* This method shall be invoked exactly once after {@link #validateMandatoryTags()}.
* After this method call (if successful), the returned value is guaranteed non-null
* and can be used as a flag for determining that the build has been completed.
*
* @param width the image width in pixels.
* @param height the image height in pixels.
* @return the grid geometry, guaranteed non-null.
* @throws FactoryException if an error occurred while creating a CRS or a transform.
*/
@SuppressWarnings("fallthrough")
public GridGeometry build(final Reader reader, final long width, final long height) throws FactoryException {
CoordinateReferenceSystem crs = null;
if (keyDirectory != null) {
final CRSBuilder helper = new CRSBuilder(reader);
try {
crs = helper.build(this);
description = helper.description;
cellGeometry = helper.cellGeometry;
} catch (NoSuchIdentifierException | ParameterNotFoundException e) {
short key = Resources.Keys.UnsupportedProjectionMethod_1;
if (e instanceof NoSuchAuthorityCodeException) {
key = Resources.Keys.UnknownCRS_1;
}
reader.store.warning(reader.resources().getString(key, reader.store.getDisplayName()), e);
} catch (IllegalArgumentException | NoSuchElementException | ClassCastException e) {
if (!helper.alreadyReported) {
canNotCreate(reader, e);
}
}
}
/*
* If the CRS is non-null, then it is either two- or three-dimensional.
* The `affine` matrix may be for a greater number of dimensions, so it
* may need to be reduced.
*/
int n = (crs != null) ? crs.getCoordinateSystem().getDimension() : 2;
final DimensionNameType[] axisTypes = new DimensionNameType[n];
final long[] high = new long[n];
switch(n) {
// Fallthrough everywhere.
default:
axisTypes[2] = DimensionNameType.VERTICAL;
case 2:
axisTypes[1] = DimensionNameType.ROW;
high[1] = height - 1;
case 1:
axisTypes[0] = DimensionNameType.COLUMN;
high[0] = width - 1;
case 0:
break;
}
final GridExtent extent = new GridExtent(axisTypes, null, high, true);
boolean pixelIsPoint = CellGeometry.POINT.equals(cellGeometry);
final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
GridGeometry gridGeometry;
try {
MathTransform gridToCRS;
if (affine != null) {
gridToCRS = factory.createAffineTransform(Matrices.resizeAffine(affine, ++n, n));
} else {
pixelIsPoint = true;
gridToCRS = Localization.nonLinear(modelTiePoints);
gridToCRS = factory.createPassThroughTransform(0, gridToCRS, n - 2);
}
gridGeometry = new GridGeometry(extent, pixelIsPoint ? PixelInCell.CELL_CENTER : PixelInCell.CELL_CORNER, gridToCRS, crs);
} catch (TransformException e) {
GeneralEnvelope envelope = null;
if (crs != null) {
envelope = new GeneralEnvelope(crs);
envelope.setToNaN();
}
gridGeometry = new GridGeometry(extent, envelope, GridOrientation.HOMOTHETY);
canNotCreate(reader, e);
/*
* Note: we catch TransformExceptions because they may be caused by erroneous data in the GeoTIFF file,
* but let FactoryExceptions propagate because they are more likely to be a SIS configuration problem.
*/
}
// Not needed anymore, so let GC do its work.
keyDirectory = null;
numericParameters = null;
asciiParameters = null;
modelTiePoints = null;
affine = null;
return gridGeometry;
}
use of org.apache.sis.coverage.grid.GridGeometry in project sis by apache.
the class ImageFileDirectory method createMetadata.
/**
* Builds the metadata with the information stored in the fields of this IFD.
* This method is invoked only if the user requested the ISO 19115 metadata.
*
* @throws DataStoreException if an error occurred while reading metadata from the data store.
*/
@Override
protected Metadata createMetadata() throws DataStoreException {
final ImageMetadataBuilder metadata = this.metadata;
if (metadata == null) {
/*
* We enter in this block only if an exception occurred during the first attempt to build metadata.
* If the user insists for getting metadata, fallback on the default (less complete) implementation.
*/
return super.createMetadata();
}
// Clear now in case an exception happens.
this.metadata = null;
/*
* Add information about sample dimensions.
*
* Destination: metadata/contentInfo/attributeGroup/attribute
*/
final boolean isIndexValid = !isReducedResolution();
metadata.newCoverage(isIndexValid && reader.store.customizer.isElectromagneticMeasurement(index));
final List<SampleDimension> sampleDimensions = getSampleDimensions();
for (int band = 0; band < samplesPerPixel; band++) {
metadata.addNewBand(sampleDimensions.get(band));
metadata.setBitPerSample(bitsPerSample);
if (!metadata.hasSampleValueRange()) {
if (isMinSpecified)
metadata.addMinimumSampleValue(minValues.doubleValue(Math.min(band, minValues.size() - 1)));
if (isMaxSpecified)
metadata.addMaximumSampleValue(maxValues.doubleValue(Math.min(band, maxValues.size() - 1)));
}
}
/*
* Add Coordinate Reference System built from GeoTIFF tags.
* Note that the CRS may not exist.
*
* Destination: metadata/spatialRepresentationInfo and others.
*/
if (referencing != null) {
final GridGeometry gridGeometry = getGridGeometry();
if (gridGeometry.isDefined(GridGeometry.ENVELOPE))
try {
metadata.addExtent(gridGeometry.getEnvelope());
} catch (TransformException e) {
warning(e);
}
referencing.completeMetadata(gridGeometry, metadata);
}
/*
* End of metadata construction from TIFF tags.
*/
metadata.finish(this);
final DefaultMetadata md = metadata.build(false);
if (isIndexValid) {
final Metadata c = reader.store.customizer.customize(index, md);
md.transitionTo(DefaultMetadata.State.FINAL);
if (c != null)
return c;
}
return md;
}
Aggregations