/** Tests axis swapping using {@link GeneralMatrix}. */ @Test public void testAxisSwapping() { AxisDirection[] srcAxis = {NORTH, EAST, UP}; AxisDirection[] dstAxis = {NORTH, EAST, UP}; GeneralMatrix matrix = new GeneralMatrix(srcAxis, dstAxis); assertTrue(matrix.isAffine()); assertTrue(matrix.isIdentity()); dstAxis = new AxisDirection[] {WEST, UP, SOUTH}; matrix = new GeneralMatrix(srcAxis, dstAxis); assertTrue(matrix.isAffine()); assertFalse(matrix.isIdentity()); assertEquals( new GeneralMatrix( new double[][] { {0, -1, 0, 0}, {0, 0, 1, 0}, {-1, 0, 0, 0}, {0, 0, 0, 1} }), matrix); dstAxis = new AxisDirection[] {DOWN, NORTH}; matrix = new GeneralMatrix(srcAxis, dstAxis); assertFalse(matrix.isIdentity()); assertEquals( new GeneralMatrix( new double[][] { {0, 0, -1, 0}, {1, 0, 0, 0}, {0, 0, 0, 1} }), matrix); dstAxis = new AxisDirection[] {DOWN, DOWN}; matrix = new GeneralMatrix(srcAxis, dstAxis); assertFalse(matrix.isIdentity()); assertEquals( new GeneralMatrix( new double[][] { {0, 0, -1, 0}, {0, 0, -1, 0}, {0, 0, 0, 1} }), matrix); dstAxis = new AxisDirection[] {DOWN, GEOCENTRIC_X}; try { matrix = new GeneralMatrix(srcAxis, dstAxis); fail(); } catch (IllegalArgumentException exception) { // This is the expected exception (axis not in source). } srcAxis = dstAxis; dstAxis = new AxisDirection[] {NORTH, EAST, UP, WEST}; try { matrix = new GeneralMatrix(srcAxis, dstAxis); fail(); } catch (IllegalArgumentException exception) { // This is the expected exception (colinear axis). } }
/** Tests matrix inversion and multiplication using {@link Matrix2}. */ @Test public void testMatrix2() { final Matrix2 m = new Matrix2(); assertTrue(m.isAffine()); assertTrue(m.isIdentity()); final Random random = new Random(8447482612423035360L); final GeneralMatrix identity = new GeneralMatrix(2); for (int i = 0; i < 100; i++) { m.setElement(0, 0, 100 * random.nextDouble()); m.setElement(0, 1, 100 * random.nextDouble()); m.setElement(1, 0, 100 * random.nextDouble()); m.setElement(1, 1, 100 * random.nextDouble()); final Matrix2 original = m.clone(); final GeneralMatrix check = new GeneralMatrix(m); m.invert(); check.invert(); assertTrue(check.equals(m, 1E-9)); m.multiply(original); assertTrue(identity.equals(m, 1E-9)); } }
/* * Copied from GeoTools GeoTiffMetadata2CRSAdapter because the given tie-point offset is * not correctly interpreted in GeoTools. The tie-point should be placed at the pixel center * if RasterPixelIsPoint is set as value for GTRasterTypeGeoKey. * See links: * http://www.remotesensing.org/geotiff/faq.html#PixelIsPoint * http://lists.osgeo.org/pipermail/gdal-dev/2007-November/015040.html * http://trac.osgeo.org/gdal/wiki/rfc33_gtiff_pixelispoint */ private static MathTransform getRasterToModel(final GeoTiffIIOMetadataDecoder metadata) throws GeoTiffException { // // Load initials // final boolean hasTiePoints = metadata.hasTiePoints(); final boolean hasPixelScales = metadata.hasPixelScales(); final boolean hasModelTransformation = metadata.hasModelTrasformation(); int rasterType = getGeoKeyAsInt(GeoTiffConstants.GTRasterTypeGeoKey, metadata); // geotiff spec says that PixelIsArea is the default if (rasterType == GeoTiffConstants.UNDEFINED) { rasterType = GeoTiffConstants.RasterPixelIsArea; } MathTransform xform; if (hasTiePoints && hasPixelScales) { // // we use tie points and pixel scales to build the grid to world // // model space final TiePoint[] tiePoints = metadata.getModelTiePoints(); final PixelScale pixScales = metadata.getModelPixelScales(); // here is the matrix we need to build final GeneralMatrix gm = new GeneralMatrix(3); final double scaleRaster2ModelLongitude = pixScales.getScaleX(); final double scaleRaster2ModelLatitude = -pixScales.getScaleY(); // "raster" space final double tiePointColumn = tiePoints[0].getValueAt(0) + (rasterType == GeoTiffConstants.RasterPixelIsPoint ? 0.5 : 0); final double tiePointRow = tiePoints[0].getValueAt(1) + (rasterType == GeoTiffConstants.RasterPixelIsPoint ? 0.5 : 0); // compute an "offset and scale" matrix gm.setElement(0, 0, scaleRaster2ModelLongitude); gm.setElement(1, 1, scaleRaster2ModelLatitude); gm.setElement(0, 1, 0); gm.setElement(1, 0, 0); gm.setElement( 0, 2, tiePoints[0].getValueAt(3) - (scaleRaster2ModelLongitude * tiePointColumn)); gm.setElement(1, 2, tiePoints[0].getValueAt(4) - (scaleRaster2ModelLatitude * tiePointRow)); // make it a LinearTransform xform = ProjectiveTransform.create(gm); } else if (hasModelTransformation) { if (rasterType == GeoTiffConstants.RasterPixelIsPoint) { final AffineTransform tempTransform = new AffineTransform(metadata.getModelTransformation()); tempTransform.concatenate(AffineTransform.getTranslateInstance(0.5, 0.5)); xform = ProjectiveTransform.create(tempTransform); } else { assert rasterType == GeoTiffConstants.RasterPixelIsArea; xform = ProjectiveTransform.create(metadata.getModelTransformation()); } } else { throw new GeoTiffException(metadata, "Unknown Raster to Model configuration.", null); } return xform; }