This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new c7a721a Apply wraparound on geographic coordinates shown in status bar. Prepare `RenderedData` for wraparound axes (not yet completed). Convenience method for fetching DefaultMathTransformFactory. c7a721a is described below commit c7a721a4afc8bc61ad67c8f345c136d40c89b370 Author: Martin Desruisseaux AuthorDate: Wed Sep 9 16:32:07 2020 +0200 Apply wraparound on geographic coordinates shown in status bar. Prepare `RenderedData` for wraparound axes (not yet completed). Convenience method for fetching DefaultMathTransformFactory. --- .../org/apache/sis/gui/coverage/RenderingData.java | 25 ++++++++---- .../java/org/apache/sis/gui/map/StatusBar.java | 44 +++++++++++----------- .../coverage/grid/CoordinateOperationFinder.java | 4 +- .../internal/referencing/CoordinateOperations.java | 12 +++++- .../apache/sis/referencing/GeodeticCalculator.java | 5 +-- .../sis/referencing/StandardDefinitions.java | 8 ++-- .../provider/GeographicOffsetsTest.java | 8 ++-- 7 files changed, 58 insertions(+), 48 deletions(-) diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java index 000f91d..2738e2d 100644 --- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java +++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java @@ -146,7 +146,15 @@ final class RenderingData implements Cloneable { * objective CRS}. This is {@link GridGeometry#getGridToCRS(PixelInCell)} on {@link #dataGeometry} * concatenated with {@link #changeOfCRS}. May be {@code null} if not yet computed. */ - private MathTransform cornerToObjective, centerToObjective; + private MathTransform cornerToObjective; + + /** + * The conversion from {@linkplain CoverageCanvas#getObjectiveCRS() objective CRS} to {@link #data} + * pixel coordinates. This is the inverse of {@link #changeOfCRS} concatenated with the inverse of + * {@link GridGeometry#getGridToCRS(PixelInCell)} on {@link #dataGeometry}. + * May be {@code null} if not yet computed. + */ + private MathTransform objectiveToCenter; /** * The inverse of the {@linkplain CoverageCanvas#objectiveToDisplay objective to display} transform which was @@ -218,7 +226,7 @@ final class RenderingData implements Cloneable { private void clearCRS() { changeOfCRS = null; cornerToObjective = null; - centerToObjective = null; + objectiveToCenter = null; } /** @@ -293,13 +301,14 @@ final class RenderingData implements Cloneable { // Leave `changeOfCRS` to null. } } - if (cornerToObjective == null || centerToObjective == null) { + if (cornerToObjective == null || objectiveToCenter == null) { cornerToObjective = dataGeometry.getGridToCRS(PixelInCell.CELL_CORNER); - centerToObjective = dataGeometry.getGridToCRS(PixelInCell.CELL_CENTER); + objectiveToCenter = dataGeometry.getGridToCRS(PixelInCell.CELL_CENTER).inverse(); if (changeOfCRS != null) { - final MathTransform tr = changeOfCRS.getMathTransform(); - cornerToObjective = MathTransforms.concatenate(cornerToObjective, tr); - centerToObjective = MathTransforms.concatenate(centerToObjective, tr); + MathTransform forward = changeOfCRS.getMathTransform(); + MathTransform inverse = forward.inverse(); + cornerToObjective = MathTransforms.concatenate(cornerToObjective, forward); + objectiveToCenter = MathTransforms.concatenate(inverse, objectiveToCenter); } } /* @@ -313,7 +322,7 @@ final class RenderingData implements Cloneable { final LinearTransform inverse = objectiveToDisplay.inverse(); displayToObjective = AffineTransforms2D.castOrCopy(inverse); final MathTransform cornerToDisplay = MathTransforms.concatenate(cornerToObjective, objectiveToDisplay); - final MathTransform displayToCenter = MathTransforms.concatenate(inverse, centerToObjective.inverse()); + final MathTransform displayToCenter = MathTransforms.concatenate(inverse, objectiveToCenter); final Rectangle bounds = (Rectangle) Shapes2D.transform( MathTransforms.bidimensional(cornerToDisplay), ImageUtilities.getBounds(recoloredImage), new Rectangle()); diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java index 466fd19..88a821c 100644 --- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java +++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java @@ -1040,22 +1040,24 @@ public class StatusBar extends Widget implements EventHandler { if (x != lastX || y != lastY) { sourceCoordinates[0] = lastX = x; sourceCoordinates[1] = lastY = y; - boolean success = false; - String text; + String text, values = null; try { - text = formatCoordinates(); - success = true; + convertCoordinates(); + if (isSampleValuesVisible) { + values = sampleValuesProvider.get().evaluate(targetCoordinates); + } + targetCoordinates.normalize(); + text = format.format(targetCoordinates); } catch (TransformException | RuntimeException e) { - /* - * If even the fallback without derivative failed, show the error message. - */ Throwable cause = Exceptions.unwrap(e); text = cause.getLocalizedMessage(); if (text == null) { text = Classes.getShortClassName(cause); } + values = null; } position.setText(text); + sampleValues.setText(values); /* * Make sure that there is enough space for keeping the coordinates always visible. * This is the needed if there is an error message on the left which may be long. @@ -1064,25 +1066,21 @@ public class StatusBar extends Widget implements EventHandler { maximalPositionLength = text.length(); position.setMinWidth(Math.min(view.getWidth() / 2, Math.ceil(position.prefWidth(position.getHeight())))); } - /* - * Format the values under cursor if the coordinates are valid. First try to use coordinates - * in the CRS used by this status bar. If `ValuesUnderCursor` can not use those "real world" - * coordinates, fallback on pixel coordinates. - */ - if (isSampleValuesVisible) { - text = null; - if (success) { - text = sampleValuesProvider.get().evaluate(targetCoordinates); - } - sampleValues.setText(text); - } } } /** - * Converts and formats the local coordinates currently stored in {@link #sourceCoordinates} array. + * Converts the local coordinates currently stored in {@link #sourceCoordinates} array. + * The conversion result is stored in {@link #targetCoordinates} and the {@link #format} + * is configured with suggested precision. Callers can use this method as below: + * + * {@preformat java + * convertCoordinates(); + * targetCoordinates.normalize(); + * String text = format.format(targetCoordinates); + * } */ - private String formatCoordinates() throws TransformException { + private void convertCoordinates() throws TransformException { Matrix derivative; try { derivative = MathTransforms.derivativeAndTransform(localToPositionCRS, @@ -1122,7 +1120,6 @@ public class StatusBar extends Widget implements EventHandler { } } format.setPrecisions(precisions); - return format.format(targetCoordinates); } /** @@ -1137,7 +1134,8 @@ public class StatusBar extends Widget implements EventHandler { final String separator = format.getSeparator(); try { format.setSeparator("\t"); - return formatCoordinates(); + convertCoordinates(); + return format.format(targetCoordinates); } finally { format.setSeparator(separator); } diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java index ea4f59c..e2b7b4a 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/CoordinateOperationFinder.java @@ -32,7 +32,6 @@ import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; import org.apache.sis.util.collection.BackingStoreException; -import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.referencing.CoordinateOperations; import org.apache.sis.internal.referencing.WraparoundTransform; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; @@ -178,8 +177,7 @@ final class CoordinateOperationFinder implements Supplier { CoordinateOperationFinder(final GridGeometry source, final GridGeometry target) { this.source = source; this.target = target; - mtFactory = DefaultFactories.forBuildin(MathTransformFactory.class, - org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.class).caching(false); + mtFactory = CoordinateOperations.factoryMT().caching(false); } /** diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java index 4bfff39..bd4e063 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java @@ -34,8 +34,9 @@ import org.opengis.referencing.operation.OperationMethod; import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.referencing.operation.MathTransformFactory; -import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; import org.apache.sis.referencing.operation.AbstractCoordinateOperation; +import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; +import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.internal.metadata.NameToIdentifier; import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.system.Modules; @@ -147,6 +148,15 @@ public final class CoordinateOperations extends SystemListener { } /** + * Returns the SIS implementation of {@link MathTransformFactory}. + * + * @return SIS implementation of transform factory. + */ + public static DefaultMathTransformFactory factoryMT() { + return DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class); + } + + /** * Returns the coordinate operation factory to use for the given properties and math transform factory. * If the given properties are empty and the {@code mtFactory} is the system default, then this method * returns the system default {@code CoordinateOperationFactory} instead of creating a new one. diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java index 9872ee8..4226f76 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java @@ -30,7 +30,6 @@ import org.opengis.util.FactoryException; import org.opengis.referencing.datum.Ellipsoid; import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; @@ -46,13 +45,13 @@ import org.apache.sis.parameter.Parameters; import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.internal.referencing.provider.MapProjection; +import org.apache.sis.internal.referencing.CoordinateOperations; import org.apache.sis.internal.referencing.PositionTransformer; import org.apache.sis.internal.referencing.ReferencingUtilities; import org.apache.sis.internal.referencing.j2d.ShapeUtilities; import org.apache.sis.internal.referencing.j2d.Bezier; import org.apache.sis.internal.referencing.Resources; import org.apache.sis.internal.referencing.Formulas; -import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.util.Constants; import org.apache.sis.internal.util.Numerics; import org.apache.sis.util.resources.Vocabulary; @@ -1192,7 +1191,7 @@ public class GeodeticCalculator { crsUnit = ReferencingUtilities.getUnit(positionCRS.getCoordinateSystem()); toLinearUnit = ellipsoid.getAxisUnit().getConverterTo(Units.isLinear(crsUnit) ? crsUnit.asType(Length.class) : Units.METRE); toProjectionBase = CRS.findOperation(positionCRS, baseCRS, null).getMathTransform(); - projectionFactory = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class).caching(false); + projectionFactory = CoordinateOperations.factoryMT().caching(false); projectionProvider = (MapProjection) projectionFactory.getOperationMethod(getProjectionMethod()); projectionParameters = Parameters.castOrWrap(projectionProvider.getParameters().createValue()); projectionParameters.parameter(Constants.SEMI_MAJOR).setValue(toLinearUnit.convert(ellipsoid.getSemiMajorAxis())); diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java index af3a7fc..bacb506 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java @@ -35,11 +35,10 @@ import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.referencing.crs.VerticalCRS; import org.opengis.referencing.operation.OperationMethod; -import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.parameter.ParameterValueGroup; import org.opengis.util.NoSuchIdentifierException; -import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.internal.metadata.AxisNames; +import org.apache.sis.internal.referencing.CoordinateOperations; import org.apache.sis.internal.referencing.provider.TransverseMercator; import org.apache.sis.internal.referencing.provider.PolarStereographicA; import org.apache.sis.metadata.iso.extent.Extents; @@ -58,7 +57,6 @@ import org.apache.sis.referencing.crs.DefaultGeographicCRS; import org.apache.sis.referencing.crs.DefaultVerticalCRS; import org.apache.sis.referencing.crs.DefaultProjectedCRS; import org.apache.sis.referencing.operation.DefaultConversion; -import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.measure.Longitude; import org.apache.sis.measure.Latitude; import org.apache.sis.measure.Units; @@ -146,8 +144,8 @@ final class StandardDefinitions { { final OperationMethod method; try { - method = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class) - .getOperationMethod(isUTM ? TransverseMercator.NAME : PolarStereographicA.NAME); + method = CoordinateOperations.factoryMT() + .getOperationMethod(isUTM ? TransverseMercator.NAME : PolarStereographicA.NAME); } catch (NoSuchIdentifierException e) { throw new IllegalStateException(e); // Should not happen with SIS implementation. } diff --git a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java index 5f8e509..5e135de 100644 --- a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java +++ b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/GeographicOffsetsTest.java @@ -18,10 +18,9 @@ package org.apache.sis.internal.referencing.provider; import org.opengis.util.FactoryException; import org.opengis.parameter.ParameterValueGroup; -import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; import org.apache.sis.internal.referencing.Formulas; -import org.apache.sis.internal.system.DefaultFactories; +import org.apache.sis.internal.referencing.CoordinateOperations; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.measure.Units; @@ -36,7 +35,7 @@ import org.junit.Test; * Tests the {@link GeographicOffsets}, {@link GeographicOffsets2D} and {@link VerticalOffset} classes. * * @author Martin Desruisseaux (Geomatys) - * @version 0.8 + * @version 1.1 * @since 0.7 * @module */ @@ -121,8 +120,7 @@ public final strictfp class GeographicOffsetsTest extends TransformTestCase { */ @Test public void testCreateWithContext() throws FactoryException, TransformException { - final DefaultMathTransformFactory factory = DefaultFactories.forBuildin( - MathTransformFactory.class, DefaultMathTransformFactory.class); + final DefaultMathTransformFactory factory = CoordinateOperations.factoryMT(); final ParameterValueGroup pv = factory.getDefaultParameters("Vertical Offset"); pv.parameter("Vertical Offset").setValue(15.55, Units.FOOT); /*