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 b0e8264 Refactor StatusBar API with some method renaming, property
definitions and javadoc completionS. No change in functionalities.
b0e8264 is described below
commit b0e82649c846ec32c630cd698ce57c46d7816443
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Apr 25 20:57:59 2020 +0200
Refactor StatusBar API with some method renaming, property definitions and
javadoc completionS.
No change in functionalities.
---
.../apache/sis/gui/coverage/CoverageControls.java | 2 +-
.../org/apache/sis/gui/coverage/ImageRequest.java | 9 +-
.../java/org/apache/sis/gui/map/StatusBar.java | 371 +++++++++++----------
3 files changed, 193 insertions(+), 189 deletions(-)
diff --git
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
index d62a0e7..5bef42d 100644
---
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
+++
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
@@ -80,7 +80,7 @@ final class CoverageControls extends Controls {
view = new CoverageCanvas();
view.setBackground(background);
final StatusBar statusBar = new StatusBar(referenceSystems);
- statusBar.setCanvas(view);
+ statusBar.canvas.set(view);
imageAndStatus = new BorderPane(view.getView());
imageAndStatus.setBottom(statusBar.getView());
/*
diff --git
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
index 7310a21..8147858 100644
---
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
+++
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
@@ -251,7 +251,7 @@ public class ImageRequest {
/**
* Configures the given status bar with the geometry of the grid coverage
we have just read.
- * This method is invoked by{@link
GridView#onImageLoaded(WorkerStateEvent)} in JavaFX thread
+ * This method is invoked by {@link
GridView#onImageLoaded(WorkerStateEvent)} in JavaFX thread
* after {@link ImageLoader} successfully loaded in background thread a
new image.
*/
final void configure(final StatusBar bar) {
@@ -261,15 +261,16 @@ public class ImageRequest {
/*
* By `GridCoverage.render(GridExtent)` contract, the `RenderedImage`
pixel coordinates are relative
* to the requested `GridExtent`. Consequently we need to translate
the image coordinates so that it
- * become the coordinates of the original `GridGeometry` before to
apply `gridToCRS`.
+ * become the coordinates of the original `GridGeometry` before to
apply `gridToCRS`. It is okay to
+ * modify `StatusBar.localToObjectiveCRS` because we do not associate
it to a `MapCanvas`.
*/
if (request != null) {
final double[] origin = new double[request.getDimension()];
for (int i=0; i<origin.length; i++) {
origin[i] = request.getLow(i);
}
- bar.setLocalToObjectiveCRS(MathTransforms.concatenate(
- MathTransforms.translation(origin),
bar.getLocalToObjectiveCRS()));
+ bar.localToObjectiveCRS.set(MathTransforms.concatenate(
+ MathTransforms.translation(origin),
bar.localToObjectiveCRS.get()));
}
}
}
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 c418b5a..36ed7ce 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
@@ -37,6 +37,9 @@ import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.beans.value.ObservableValue;
import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ObjectPropertyBase;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.ReadOnlyObjectPropertyBase;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
@@ -138,14 +141,35 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
private double lastX, lastY;
/**
+ * The canvas that this status bar is tracking. The property value is
{@code null} if this status bar is not
+ * associated to a canvas. After a non-null value has been set, this
{@code StatusBar} will show coordinates
+ * (usually geographic or projected) of mouse cursor position when the
mouse is over that canvas.
+ *
+ * <p>Note that if this property is set to a non-null value, then the
{@link #localToObjectiveCRS} property
+ * value will be overwritten at any time (for example every time that a
gesture event such as pan, zoom or
+ * rotation happens).</p>
+ *
+ * <div class="note"><b>API note:</b>
+ * We do not provide getter/setter for this property; use {@link
ObjectProperty#set(Object)}
+ * directly instead. We omit the "Property" suffix for making this
operation more natural.</div>
+ *
+ * @see MapCanvas
+ */
+ public final ObjectProperty<MapCanvas> canvas;
+
+ /**
* The manager of reference systems chosen by user, or {@code null} if
none.
* The {@link RecentReferenceSystems#areaOfInterest} property is used for
- * computing {@link #objectiveToFormatCRS}.
+ * computing {@link #objectiveToPositionCRS}.
*/
private final RecentReferenceSystems systemChooser;
/**
- * The selected reference system, or {@code null} if there is no such
property.
+ * The selected reference system, or {@code null} if there is no such
property. This property is provided
+ * by {@link RecentReferenceSystems}. It usually has the same value than
{@link #positionReferenceSystem},
+ * but the values may temporarily differ between the time a CRS is
selected and when it became applied.
+ *
+ * @see #positionReferenceSystem
*/
private final ObjectProperty<ReferenceSystem> selectedSystem;
@@ -154,8 +178,6 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* This is the "{@linkplain RecentReferenceSystems#setPreferred(boolean,
ReferenceSystem) preferred}" or native
* data CRS. It may not be the same than the CRS of coordinates actually
shown in the status bar.
*
- * @see #getObjectiveCRS()
- * @see #getFormatReferenceSystem()
* @see MapCanvas#getObjectiveCRS()
*/
private CoordinateReferenceSystem objectiveCRS;
@@ -165,35 +187,66 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* The {@linkplain CoordinateOperation#getSourceCRS() source CRS} is
{@link #objectiveCRS} and
* the {@linkplain CoordinateOperation#getTargetCRS() target CRS} is
{@link CoordinateFormat#getDefaultCRS()}.
* This coordinate operation may be null if there is no CRS change to apply
- * (in which case {@link #localToFormatCRS} is the same instance than
{@link #localToObjectiveCRS})
+ * (in which case {@link #localToPositionCRS} is the same instance than
{@link #localToObjectiveCRS})
* or if the target is not a CRS (for example it may be a Military Grid
Reference System (MGRS) code).
+ *
+ * @see #updateLocalToPositionCRS()
*/
- private CoordinateOperation objectiveToFormatCRS;
+ private CoordinateOperation objectiveToPositionCRS;
/**
* Conversion from local coordinates to geographic or projected
coordinates of rendered data.
- * This is not necessarily the conversion to the coordinates shown in this
status bar.
- * This conversion shall never be null but may be the identity transform.
- * It should have no {@linkplain
CoordinateOperation#getCoordinateOperationAccuracy() inaccuracy}
- * (ignoring rounding error). This transform is usually (but not
necessarily) affine.
+ * The local coordinates are the coordinates of the JavaFX view, as given
for example in {@link MouseEvent}
+ * The objective coordinates are geographic or projected of rendered data,
ignoring all CRS changes that may
+ * result from user selecting a different CRS in the contextual menu.
Consequently while this conversion is often
+ * the conversion from pixel coordinates to the coordinates shown in this
status bar, this is not always the case.
*
- * @see #getLocalToObjectiveCRS()
+ * <p>This transform shall never be null. It is initially an identity
transform and is modified by
+ * {@link #applyCanvasGeometry(GridGeometry)}. The transform is usually
(but not necessarily) affine
+ * and should have no {@linkplain
CoordinateOperation#getCoordinateOperationAccuracy() inaccuracy}
+ * (ignoring rounding error). This is normally the inverse of {@linkplain
#canvas}
+ * {@linkplain MapCanvas#getObjectiveToDisplay() objective to display}
transform,
+ * but temporary mismatches may exist during gesture events such as pans,
zooms and rotations.</p>
+ *
+ * <p>If this transform is set to a new value, the given transform must
have the same number of source
+ * and target dimensions than the previous value (if a change in the
number of dimension is desired,
+ * use {@link #applyCanvasGeometry(GridGeometry)} instead). The status bar
is updated as if the new
+ * conversion was applied <em>before</em> any CRS changes resulting from
user selecting a different
+ * CRS in the contextual menu. Note however that any specified transform
may be overwritten if some
+ * {@linkplain #canvas} gesture events happen later; setting an explicit
transform is more useful
+ * when this {@code StatusBar} is <em>not</em> associated to a {@link
MapCanvas}
+ * (for example it may be used with a {@link
org.apache.sis.gui.coverage.GridView} instead).</p>
+ *
+ * <div class="note"><b>API note:</b>
+ * We do not provide getter/setter for this property; use {@link
ObjectProperty#set(Object)}
+ * directly instead. We omit the "Property" suffix for making this
operation more natural.</div>
+ *
+ * @see MapCanvas#getObjectiveCRS()
* @see MapCanvas#getObjectiveToDisplay()
*/
- private MathTransform localToObjectiveCRS;
+ public final ObjectProperty<MathTransform> localToObjectiveCRS;
+
+ /**
+ * The reference systems used by the coordinates shown in this status bar.
+ * This is initially the <cite>objective CRS</cite>, but may become
different
+ * if the user selects another reference system through contextual menu.
+ *
+ * @see #position
+ */
+ public final ReadOnlyObjectProperty<ReferenceSystem>
positionReferenceSystem;
/**
* Conversion from local coordinates to geographic or projected
coordinates shown in this status bar.
- * This is the concatenation of {@link #localToObjectiveCRS} with {@link
#objectiveToFormatCRS} transform.
+ * This is the concatenation of {@link #localToObjectiveCRS} with {@link
#objectiveToPositionCRS} transform.
* The result is a transform to the user-selected CRS for coordinates
shown in the status bar.
* This conversion shall never be null but may be the identity transform.
* It is usually non-affine if the display CRS is not the same than the
objective CRS.
* This transform may have a {@linkplain
CoordinateOperation#getCoordinateOperationAccuracy() limited accuracy}.
*
* <p>The target CRS can be obtained by {@link
CoordinateOperation#getTargetCRS()} on
- * {@link #objectiveToFormatCRS} or by {@link
CoordinateFormat#getDefaultCRS()}.</p>
+ * {@link #objectiveToPositionCRS} or by {@link
CoordinateFormat#getDefaultCRS()}.</p>
*/
- private MathTransform localToFormatCRS;
+ private MathTransform localToPositionCRS;
/**
* The source local indices before conversion to geospatial coordinates.
@@ -206,19 +259,18 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
private double[] sourceCoordinates;
/**
- * Coordinates after conversion to the CRS. The number of dimensions
depends on
- * the target CRS. This object is reused during each coordinate
transformation.
- * Shall never be {@code null}.
+ * Coordinates after conversion to the CRS. The number of dimensions
depends on the target CRS.
+ * This object is reused during each coordinate transformation. Shall
never be {@code null}.
*
* @see #sourceCoordinates
* @see #position
- * @see #setTargetCRS(CoordinateReferenceSystem)
+ * @see #setPositionCRS(CoordinateReferenceSystem)
*/
private GeneralDirectPosition targetCoordinates;
/**
* The desired precisions for each dimension in the {@link
#targetCoordinates} to format.
- * It may vary for each position if the {@link #localToFormatCRS}
transform is non-linear.
+ * It may vary for each position if the {@link #localToPositionCRS}
transform is non-linear.
* This array is initially {@code null} and created when first needed.
*/
private double[] precisions;
@@ -241,10 +293,12 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
/**
* The labels where to format the cursor position, either as coordinate
values or other representations.
- * The text is usually the result of formatting {@link #targetCoordinates}
as numerical values,
+ * The text is usually the result of formatting coordinate values as
numerical values,
* but may also be other representations such as Military Grid Reference
System (MGRS) codes.
+ *
+ * @see #positionReferenceSystem
*/
- private final Label position;
+ protected final Label position;
/**
* The {@link #position} text to show when the mouse is outside the canvas
area.
@@ -255,20 +309,11 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
private String outsideText;
/**
- * The canvas that this status bar is tracking.
- * The property value is {@code null} if there is none.
- *
- * @see #getCanvas()
- * @see #setCanvas(MapCanvas)
- */
- public final ObjectProperty<MapCanvas> canvasProperty;
-
- /**
* The listener registered on {@link MapCanvas#renderingProperty()}, or
{@code null} if the
* listener has not yet been registered. This listener is remembered for
allowing removal.
*
- * @see #setCanvas(MapCanvas)
- * @see #onCanvasSpecified(ObservableValue, MapCanvas, MapCanvas)
+ * @see #canvas
+ * @see #onCanvasSpecified(MapCanvas, MapCanvas)
*/
private ChangeListener<Boolean> renderingListener;
@@ -286,14 +331,15 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* @param systemChooser the manager of reference systems chosen by user,
or {@code null} if none.
*/
public StatusBar(final RecentReferenceSystems systemChooser) {
- localToObjectiveCRS = MathTransforms.identity(BIDIMENSIONAL);
- localToFormatCRS = localToObjectiveCRS;
- targetCoordinates = new GeneralDirectPosition(BIDIMENSIONAL);
- sourceCoordinates = targetCoordinates.coordinates;
- lastX = lastY = Double.NaN;
- format = new CoordinateFormat();
- position = new Label();
- message = new Label();
+ positionReferenceSystem = new PositionSystem();
+ localToObjectiveCRS = new LocalToObjective();
+ localToPositionCRS = localToObjectiveCRS.get();
+ targetCoordinates = new GeneralDirectPosition(BIDIMENSIONAL);
+ sourceCoordinates = targetCoordinates.coordinates;
+ lastX = lastY = Double.NaN;
+ format = new CoordinateFormat();
+ position = new Label();
+ message = new Label();
message.setVisible(false); // Waiting for getting
a message to display.
message.setTextFill(Styles.ERROR_TEXT);
message.setMaxWidth(Double.POSITIVE_INFINITY);
@@ -303,8 +349,8 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
view.setAlignment(Pos.CENTER_RIGHT);
position.setAlignment(Pos.CENTER_RIGHT);
position.setTextAlignment(TextAlignment.RIGHT);
- canvasProperty = new SimpleObjectProperty<>(this, "canvas");
- canvasProperty.addListener(this::onCanvasSpecified);
+ canvas = new SimpleObjectProperty<>(this, "canvas");
+ canvas.addListener((p,o,n) -> onCanvasSpecified(o,n));
this.systemChooser = systemChooser;
if (systemChooser == null) {
selectedSystem = null;
@@ -321,7 +367,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
systemChooser.getItems().addListener((ListChangeListener.Change<?
extends ReferenceSystem> change) -> {
while (change.next()) {
if (change.wasAdded() || change.wasReplaced()) {
- setReplaceableTargetCRS(format.getDefaultCRS());
+ setReplaceablePositionCRS(format.getDefaultCRS());
break;
}
}
@@ -329,11 +375,11 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
/*
* Create a contextual menu offering to user a choice of CRS in
which to display the coordinates.
* The CRS choices are controlled by `RecentReferenceSystems`.
Selection of a new CRS causes the
- * `setTargetCRS(…)` method to be invoked. Contextual menu can be
invoked anywhere on the HBox;
+ * `setPositionCRS(…)` method to be invoked. Contextual menu can
be invoked anywhere on the HBox;
* we do not register this menu to `position` only because it is a
relatively small area.
*/
final Menu choices = systemChooser.createMenuItems((property,
oldValue, newValue) -> {
- setTargetCRS(newValue instanceof CoordinateReferenceSystem ?
(CoordinateReferenceSystem) newValue : null);
+ setPositionCRS(newValue instanceof CoordinateReferenceSystem ?
(CoordinateReferenceSystem) newValue : null);
});
selectedSystem =
RecentReferenceSystems.getSelectedProperty(choices);
final ContextMenu menu = new ContextMenu(choices);
@@ -356,38 +402,12 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
/**
- * Returns the canvas that this status bar is tracking.
- *
- * @return canvas that this status bar is tracking, or {@code null} if
none.
- *
- * @see #canvasProperty
- */
- public final MapCanvas getCanvas() {
- return canvasProperty.get();
- }
-
- /**
- * Sets the canvas that this status bar is tracking. After this method has
been invoked,
- * this {@code StatusBar} will show coordinates (usually geographic or
projected) below
- * mouse cursor when the mouse is over that canvas.
- *
- * @param canvas the canvas to track, or {@code null} if none.
- *
- * @see #canvasProperty
- */
- public final void setCanvas(final MapCanvas canvas) {
- canvasProperty.set(canvas);
- }
-
- /**
- * Invoked when a new value is set on {@link #canvasProperty}. Previous
listeners (if any) are removed
+ * Invoked when a new value is set on {@link #canvas}. Previous listeners
(if any) are removed
* but new mouse listeners may not be added immediately. Instead if the
canvas seems uninitialized, we
* will wait for the first call to {@link #apply(GridGeometry)} before to
add the listener. We do that
* for avoiding to show irrelevant coordinate values.
*/
- private void onCanvasSpecified(final ObservableValue<? extends MapCanvas>
property,
- final MapCanvas previous, final MapCanvas
value)
- {
+ private void onCanvasSpecified(final MapCanvas previous, final MapCanvas
value) {
if (previous != null) {
previous.floatingPane.removeEventHandler(MouseEvent.MOUSE_ENTERED,
this);
previous.floatingPane.removeEventHandler(MouseEvent.MOUSE_EXITED,
this);
@@ -432,7 +452,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
/**
* Listener notified when {@link MapCanvas} completed its rendering. This
listener sets
* {@link StatusBar#localToObjectiveCRS} to the inverse of {@link
MapCanvas#objectiveToDisplay}.
- * It assumes that even if the JavaFX local coordinates and {@link
#localToFormatCRS} transform
+ * It assumes that even if the JavaFX local coordinates and {@link
#localToPositionCRS} transform
* changed, the "real world" coordinates under the mouse cursor is still
the same. This assumption
* should be true if this listener is notified as a result of zoom,
translation or rotation events.
*/
@@ -441,7 +461,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
final Boolean previous, final Boolean
value)
{
if (!value) try {
- apply(getCanvas().getGridGeometry());
+ apply(canvas.get().getGridGeometry());
/*
* Do not hide `position` since we assume that "real world"
coordinates are still valid.
* Do not try to rewrite position neither since `lastX` and
`lastY` are not valid anymore.
@@ -460,13 +480,13 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* <li>{@link GridGeometry#getCoordinateReferenceSystem()} defines the
CRS of the coordinates to format.</li>
* <li>{@link GridGeometry#getGridToCRS(PixelInCell)
GridGeometry.getGridToCRS(PixelInCell.CELL_CENTER)}
* defines the conversion from coordinate values local to the canvas
to coordinate values in the CRS
- * (the {@linkplain #getLocalToObjectiveCRS() local to objective
CRS} conversion).</li>
+ * (the {@linkplain #localToObjectiveCRS local to objective CRS}
conversion).</li>
* <li>{@link GridGeometry#getExtent()} provides the view size in
pixels, used for estimating a resolution.</li>
* <li>{@link GridGeometry#getResolution(boolean)} is also used for
estimating a resolution.</li>
* </ul>
*
* All above properties are optional. The "local to objective CRS"
conversion can be updated
- * after this method call with {@link
#setLocalToObjectiveCRS(MathTransform)}.
+ * after this method call by setting the {@link #localToObjectiveCRS}
property.
*
* @param geometry geometry of the coverage shown in {@link MapCanvas},
or {@code null}.
*
@@ -537,6 +557,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
}
final boolean sameCRS = Utilities.equalsIgnoreMetadata(objectiveCRS,
crs);
+ ((LocalToObjective) localToObjectiveCRS).setNoCheck(localToCRS);
/*
* Remaining code should not fail, so we can start modifying the
`StatusBar` fields.
* The buffers for source and target coordinates are recreated because
the number of
@@ -555,18 +576,17 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
sourceCoordinates = targetCoordinates.coordinates; // Okay to
share array if same dimension.
}
objectiveCRS = crs;
- localToObjectiveCRS = localToCRS;
- localToFormatCRS = localToCRS; // May be
updated again below.
+ localToPositionCRS = localToCRS; // May be
updated again below.
inflatePrecisions = inflate;
precisions = null;
lastX = lastY = Double.NaN; // Not
valid anymove — see above block comment.
if (sameCRS) {
- updateLocalToFormatCRS();
- // Keep the format CRS unchanged since we made `localToFormatCRS`
consistent with its value.
+ updateLocalToPositionCRS();
+ // Keep the format CRS unchanged since we made
`localToPositionCRS` consistent with its value.
} else {
- objectiveToFormatCRS = null;
+ objectiveToPositionCRS = null;
setFormatCRS(crs); // Should
be invoked before to set precision.
- crs = setReplaceableTargetCRS(crs); // May
invoke later setFormatCRS(…) again.
+ crs = setReplaceablePositionCRS(crs); // May
invoke later setFormatCRS(…) again.
}
format.setGroundPrecision(Quantities.create(resolution, unit));
/*
@@ -576,7 +596,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* irrelevant coordinates.
*/
if (geometry != null && !isMouseListenerRegistered) {
- registerMouseListeners(canvasProperty.getValue());
+ registerMouseListeners(canvas.get());
}
/*
* If the CRS changed, we may need to update the selected menu item.
It happens when this method
@@ -589,19 +609,20 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
/**
- * Computes {@link #localToFormatCRS} after a change of {@link
#localToObjectiveCRS}.
- * Other properties, in particular {@link #objectiveToFormatCRS}, must be
valid.
+ * Computes {@link #localToPositionCRS} after a change of {@link
#localToObjectiveCRS}.
+ * Other properties, in particular {@link #objectiveToPositionCRS}, must
be valid.
*/
- private void updateLocalToFormatCRS() {
- if (objectiveToFormatCRS != null) {
- localToFormatCRS = MathTransforms.concatenate(localToObjectiveCRS,
objectiveToFormatCRS.getMathTransform());
+ private void updateLocalToPositionCRS() {
+ if (objectiveToPositionCRS != null) {
+ localToPositionCRS = MathTransforms.concatenate(
+ localToObjectiveCRS.get(),
objectiveToPositionCRS.getMathTransform());
}
}
/**
* Sets the CRS of the position shown in this status bar after replacement
by one of the available CRS
* if a match is found. This method compares the given CRS with the list
of choices before to delegate
- * to {@link #setTargetCRS(CoordinateReferenceSystem)} possibly with
different axis order. The typical
+ * to {@link #setPositionCRS(CoordinateReferenceSystem)} possibly with
different axis order. A typical
* scenario is {@link #apply(GridGeometry)} invoked with
(<var>longitude</var>, <var>latitude</var>)
* axis order, and this method swapping axes to standard
(<var>latitude</var>, <var>longitude</var>)
* axis order for coordinates display purpose.
@@ -611,7 +632,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* and units than the specified CRS. This is the CRS that {@link
CoordinateFormat#getDefaultCRS()}
* will return a little bit later (pending completion of a
background task).
*/
- private CoordinateReferenceSystem
setReplaceableTargetCRS(CoordinateReferenceSystem crs) {
+ private CoordinateReferenceSystem
setReplaceablePositionCRS(CoordinateReferenceSystem crs) {
if (crs != null) {
final ComparisonMode mode =
systemChooser.duplicationCriterion.get();
for (final ReferenceSystem system : systemChooser.getItems()) {
@@ -622,7 +643,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
}
if (crs != format.getDefaultCRS()) {
- setTargetCRS(crs);
+ setPositionCRS(crs);
}
return crs;
}
@@ -635,22 +656,16 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
*
* @param crs the new CRS, or {@code null} for {@link #objectiveCRS}.
*/
- private void setTargetCRS(final CoordinateReferenceSystem crs) {
+ private void setPositionCRS(final CoordinateReferenceSystem crs) {
if (crs != null && objectiveCRS != null && objectiveCRS != crs) {
position.setTextFill(Styles.OUTDATED_TEXT);
final Envelope aoi = (systemChooser != null) ?
systemChooser.areaOfInterest.get() : null;
- BackgroundThreads.execute(new Task<MathTransform>() {
- /**
- * The new {@link StatusBar#objectiveToFormatCRS} value if
successful.
- */
- private CoordinateOperation operation;
-
+ BackgroundThreads.execute(new Task<CoordinateOperation>() {
/**
* Invoked in a background thread for fetching transformation
to target CRS.
- * This operation may be long the first time that it is
executed, but should
- * be fast on subsequent invocations.
+ * The potentially costly part is {@code CRS.findOperation(…)}.
*/
- @Override protected MathTransform call() throws
FactoryException {
+ @Override protected CoordinateOperation call() throws
FactoryException {
DefaultGeographicBoundingBox bbox = null;
if (aoi != null) try {
bbox = new DefaultGeographicBoundingBox();
@@ -658,20 +673,20 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
} catch (TransformException e) {
bbox = null;
Logging.recoverableException(Logging.getLogger(Modules.APPLICATION),
- StatusBar.class, "setTargetCRS", e);
+ StatusBar.class, "setPositionCRS", e);
}
- operation = CRS.findOperation(objectiveCRS, crs, bbox);
- return MathTransforms.concatenate(localToObjectiveCRS,
operation.getMathTransform());
+ return CRS.findOperation(objectiveCRS, crs, bbox);
}
/**
- * Invoked in JavaFX thread on success. The {@link
StatusBar#localToFormatCRS} transform
+ * Invoked in JavaFX thread on success. The {@link
StatusBar#localToPositionCRS} transform
* is set to the transform that we computed in background and
the {@link CoordinateFormat}
* is configured with auxiliary information such as positional
accuracy.
*/
@Override protected void succeeded() {
+ final CoordinateOperation operation = getValue();
final CoordinateReferenceSystem targetCRS =
operation.getTargetCRS();
- setFormatCRS(targetCRS != null ? targetCRS : crs,
operation, getValue());
+ setPositionCRS(targetCRS != null ? targetCRS : crs,
operation);
}
/**
@@ -682,13 +697,13 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
final Locale locale =
format.getLocale(Locale.Category.DISPLAY);
setErrorMessage(Resources.forLocale(locale).getString(Resources.Keys.CanNotUseRefSys_1,
IdentifiedObjects.getDisplayName(crs,
locale)), getException());
- resetFormatCRS(Styles.ERROR_TEXT);
+ resetPositionCRS(Styles.ERROR_TEXT);
}
});
} else {
/*
* If the requested CRS is the objective CRS, avoid above costly
operation.
- * The work that we need to do is to cancel the effect of
`localToFormatCRS`.
+ * The work that we need to do is to cancel the effect of
`localToPositionCRS`.
* As a special case if `objectiveCRS` was unknown before this
method call,
* set it to the given value. This is needed for initializing the
format CRS
* to the first reference system listed in
`RecentReferenceSystems` choices.
@@ -700,7 +715,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
objectiveCRS = crs;
}
position.setMinWidth(0);
- resetFormatCRS(Styles.NORMAL_TEXT);
+ resetPositionCRS(Styles.NORMAL_TEXT);
}
}
@@ -711,15 +726,12 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* only the format CRS has been updated and not {@link
#localToObjectiveCRS}.
*
* @param crs the new CRS. Should not be {@code null}.
- * @param operation the new value to assign to {@link
#objectiveToFormatCRS}
- * @param complete the concatenation of {@link #localToObjectiveCRS}
with {@code operation}.
+ * @param operation the new value to assign to {@link
#objectiveToPositionCRS}
*/
- private void setFormatCRS(final CoordinateReferenceSystem crs,
- final CoordinateOperation operation, final MathTransform complete)
- {
+ private void setPositionCRS(final CoordinateReferenceSystem crs, final
CoordinateOperation operation) {
setFormatCRS(crs);
- objectiveToFormatCRS = operation;
- localToFormatCRS = complete;
+ objectiveToPositionCRS = operation;
+ updateLocalToPositionCRS();
// TODO: CRS.getLinearAccuracy(op);
position.setTextFill(Styles.NORMAL_TEXT);
position.setMinWidth(0);
@@ -736,11 +748,13 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
/**
* Sets the {@link CoordinateFormat} default CRS together with the tool
tip text.
- * Caller is responsible to setup transforms ({@link #localToFormatCRS},
<i>etc</i>).
+ * Caller is responsible to setup transforms ({@link #localToPositionCRS},
<i>etc</i>).
+ * For the method that apply required changes on transforms before to set
the format CRS,
+ * see {@link #setPositionCRS(CoordinateReferenceSystem)}.
*
* @param crs the new {@link #format} reference system.
*
- * @see #getFormatReferenceSystem()
+ * @see #positionReferenceSystem
*/
private void setFormatCRS(final CoordinateReferenceSystem crs) {
format.setDefaultCRS(crs);
@@ -786,86 +800,75 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
position.setText(text);
}
outsideText = text;
+ ((PositionSystem) positionReferenceSystem).fireValueChangedEvent();
}
/**
- * Resets {@link #localToFormatCRS} to its default value. This is invoked
either when the
- * target CRS is {@link #objectiveCRS}, or when an attempt to use another
CRS failed.
+ * Implementation of {@link #positionReferenceSystem} property.
*/
- private void resetFormatCRS(final Color textFill) {
- objectiveToFormatCRS = null;
- localToFormatCRS = localToObjectiveCRS;
- setFormatCRS(objectiveCRS);
- position.setTextFill(textFill);
+ private final class PositionSystem extends
ReadOnlyObjectPropertyBase<ReferenceSystem> {
+ @Override public Object getBean() {return
StatusBar.this;}
+ @Override public String getName() {return
"positionReferenceSystem";}
+ @Override public ReferenceSystem get() {return
format.getDefaultCRS();}
+ @Override protected void fireValueChangedEvent()
{super.fireValueChangedEvent();}
}
/**
- * Returns the reference systems used by the coordinates shown in this
status bar.
- * This is initially the same value than {@link #getObjectiveCRS()}, but
may become
- * different if the user selects another reference system through
contextual menu.
- *
- * @return reference systems used by the coordinates shown in this status
bar.
+ * Resets {@link #localToPositionCRS} to its default value. This is
invoked either when the
+ * target CRS is {@link #objectiveCRS}, or when an attempt to use another
CRS failed.
*/
- public final Optional<ReferenceSystem> getFormatReferenceSystem() {
- return Optional.ofNullable(format.getDefaultCRS());
+ private void resetPositionCRS(final Color textFill) {
+ objectiveToPositionCRS = null;
+ localToPositionCRS = localToObjectiveCRS.get();
+ setFormatCRS(objectiveCRS);
+ position.setTextFill(textFill);
}
/**
- * Returns the reference system used for rendering the data for which this
status bar is providing cursor coordinates.
- * This is the "{@linkplain RecentReferenceSystems#setPreferred(boolean,
ReferenceSystem) preferred}" or native
- * data CRS. It may not be the same than the CRS of coordinates actually
shown in the status bar.
+ * Implementation of {@link #localToObjectiveCRS} property performing
argument check before to change its value.
+ * When a new value is set, the given transform must have the same number
of source and target dimensions than
+ * the previous value. The status bar is updated as if the new conversion
was applied <em>before</em> any CRS
+ * changes resulting from user selecting a different CRS in the contextual
menu.
*
- * @return the reference system used for rendering the data for which this
status bar
- * is providing cursor coordinates, or {@code null} if unknown.
- *
- * @see MapCanvas#getObjectiveCRS()
+ * @see #localToObjectiveCRS
*/
- public final Optional<CoordinateReferenceSystem> getObjectiveCRS() {
- return Optional.ofNullable(objectiveCRS);
- }
+ private final class LocalToObjective extends
ObjectPropertyBase<MathTransform> {
+ LocalToObjective() {super(MathTransforms.identity(BIDIMENSIONAL));}
- /**
- * Returns the conversion from local coordinates to geographic or
projected coordinates of rendered data.
- * The local coordinates are the coordinates of the JavaFX view, as given
for example in {@link MouseEvent}.
- * This is initially an identity transform and can be computed by {@link
#applyCanvasGeometry(GridGeometry)}.
- * This transform ignores all CRS changes resulting from user selecting a
different CRS in the contextual menu.
- * This transform is usually (but not necessarily) affine.
- *
- * @return conversion from local coordinates to "real world" coordinates
of rendered data.
- * This is not necessarily the conversion to coordinates shown in
the status bar.
- *
- * @see MapCanvas#getObjectiveToDisplay()
- */
- public final MathTransform getLocalToObjectiveCRS() {
- return localToObjectiveCRS;
- }
+ @Override public Object getBean() {return StatusBar.this;}
+ @Override public String getName() {return "localToObjectiveCRS";}
- /**
- * Sets the conversion from local coordinates to geographic or projected
coordinates of rendered data.
- * The given transform must have the same number of source and target
dimensions than the previous value
- * (if a change in the number of dimension is desired, use {@link
#applyCanvasGeometry(GridGeometry)} instead).
- * The conversion should have no {@linkplain
CoordinateOperation#getCoordinateOperationAccuracy() inaccuracy}
- * (ignoring rounding error). The status bar is updated as if the new
conversion was applied <em>before</em>
- * any CRS changes resulting from user selecting a different CRS in the
contextual menu.
- *
- * @param conversion the new conversion from local coordinates to "real
world" coordinates of rendered data.
- * @throws MismatchedDimensionException if the number of dimensions is not
the same than previous conversion.
- */
- public final void setLocalToObjectiveCRS(final MathTransform conversion) {
- ArgumentChecks.ensureNonNull("conversion", conversion);
- int expected = localToObjectiveCRS.getSourceDimensions();
- int actual = conversion.getSourceDimensions();
- if (expected == actual) {
- expected = localToObjectiveCRS.getTargetDimensions();
- actual = conversion.getTargetDimensions();
+ /**
+ * Overwrite previous value without any check. This method is invoked
when the {@link #objectiveCRS}
+ * is changed in same time the {@link #localToObjectiveCRS} transform.
+ */
+ final void setNoCheck(final MathTransform newValue) {
+ super.set(newValue);
+ }
+
+ /**
+ * Sets the conversion from local coordinates to geographic or
projected coordinates of rendered data.
+ *
+ * @param newValue the new conversion from local coordinates to
"real world" coordinates of rendered data.
+ * @throws MismatchedDimensionException if the number of dimensions is
not the same than previous conversion.
+ */
+ @Override public void set(final MathTransform newValue) {
+ ArgumentChecks.ensureNonNull("newValue", newValue);
+ final MathTransform oldValue = get();
+ int expected = oldValue.getSourceDimensions();
+ int actual = newValue.getSourceDimensions();
if (expected == actual) {
- localToObjectiveCRS = conversion;
- updateLocalToFormatCRS();
- return;
+ expected = oldValue.getTargetDimensions();
+ actual = newValue.getTargetDimensions();
+ if (expected == actual) {
+ super.set(newValue);
+ updateLocalToPositionCRS();
+ return;
+ }
}
+ throw new MismatchedDimensionException(Errors.format(
+ Errors.Keys.MismatchedDimension_3, "newValue", expected,
actual));
}
- throw new MismatchedDimensionException(Errors.format(
- Errors.Keys.MismatchedDimension_3, "conversion", expected,
actual));
}
/**
@@ -898,7 +901,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
try {
Matrix derivative;
try {
- derivative =
MathTransforms.derivativeAndTransform(localToFormatCRS,
+ derivative =
MathTransforms.derivativeAndTransform(localToPositionCRS,
sourceCoordinates, 0,
targetCoordinates.coordinates, 0);
} catch (TransformException ignore) {
/*
@@ -906,7 +909,7 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* derivative calculation. Try again without derivative
(the precision will be set
* to the default resolution computed in
`setCanvasGeometry(…)`).
*/
- localToFormatCRS.transform(sourceCoordinates, 0,
targetCoordinates.coordinates, 0, 1);
+ localToPositionCRS.transform(sourceCoordinates, 0,
targetCoordinates.coordinates, 0, 1);
derivative = null;
}
if (derivative == null) {