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

commit d9803c09081e6a9993478bcc08a0e6f29e59cbfb
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Aug 16 13:55:16 2022 +0200

    Show data start time and elevation range in metadata summary.
---
 .../sis/gui/metadata/IdentificationInfo.java       | 86 ++++++++++++++++------
 .../apache/sis/gui/metadata/MetadataSummary.java   | 44 +++++------
 .../sis/gui/metadata/RepresentationInfo.java       | 12 +--
 .../java/org/apache/sis/gui/metadata/Section.java  |  4 +-
 .../apache/sis/gui/metadata/VerboseFormats.java    | 68 +++++++++++++++++
 .../org/apache/sis/gui/metadata/package-info.java  |  2 +-
 ...{TextFormats.java => PropertyValueFormats.java} | 19 ++---
 .../sis/internal/gui/PropertyValueFormatter.java   |  4 +-
 .../org/apache/sis/internal/gui/PropertyView.java  |  4 +-
 9 files changed, 169 insertions(+), 74 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
index 8da5616f77..0232f9490c 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
@@ -21,6 +21,7 @@ import java.util.Set;
 import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.StringJoiner;
+import javax.measure.Unit;
 import javafx.concurrent.Task;
 import javafx.geometry.HPos;
 import javafx.scene.canvas.Canvas;
@@ -49,6 +50,8 @@ import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.gui.BackgroundThreads;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
+import org.apache.sis.measure.Range;
+import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.storage.Aggregate;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.DataStoreException;
@@ -79,7 +82,7 @@ import static 
org.apache.sis.internal.util.CollectionsExt.nonNull;
  *
  * @author  Smaniotto Enzo (GSoC)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -313,6 +316,25 @@ final class IdentificationInfo extends 
Section<Identification> {
          * Topic category.
          */
         addLine(Vocabulary.Keys.TopicCategory, 
owner.string(nonNull(info.getTopicCategories())));
+        /*
+         * Type of resource: vector, grid, table, tin, video, etc. It gives a 
slight overview
+         * of the next section, "Spatial representation". For that reason we 
put it close to
+         * that next section, i.e. last in this section but just before the 
map.
+         */
+        addLine(Vocabulary.Keys.TypeOfResource, 
owner.string(nonNull(info.getSpatialRepresentationTypes())));
+        /*
+         * Resource format. Current implementation shows only the first format 
found.
+         */
+        for (final Format format : nonNull(info.getResourceFormats())) {
+            final Citation c = format.getFormatSpecificationCitation();
+            if (c != null) {
+                text = owner.string(c.getTitle());
+                if (text != null) {
+                    addLine(Vocabulary.Keys.Format, text);
+                    break;
+                }
+            }
+        }
         /*
          * Select a single, arbitrary date. We take the release or publication 
date if available.
          * If no publication date is found, fallback on the creation date. If 
no creation date is
@@ -337,37 +359,18 @@ final class IdentificationInfo extends 
Section<Identification> {
                     }
                 }
             }
-            if (date != null) {
-                addLine(label, owner.getDateFormat().format(date));
-            }
-        }
-        /*
-         * Type of resource: vector, grid, table, tin, video, etc. It gives a 
slight overview
-         * of the next section, "Spatial representation". For that reason we 
put it close to
-         * that next section, i.e. last in this section but just before the 
map.
-         */
-        addLine(Vocabulary.Keys.TypeOfResource, 
owner.string(nonNull(info.getSpatialRepresentationTypes())));
-        /*
-         * Resource format. Current implementation shows only the first format 
found.
-         */
-        for (final Format format : nonNull(info.getResourceFormats())) {
-            final Citation c = format.getFormatSpecificationCitation();
-            if (c != null) {
-                text = owner.string(c.getTitle());
-                if (text != null) {
-                    addLine(Vocabulary.Keys.Format, text);
-                    break;
-                }
-            }
+            addLine(label, owner.format(date));
         }
         /*
-         * Write the first description about the spatio-temporal extent, then 
draw all geographic bounding boxes
+         * Fetch the first description about the spatio-temporal extent, then 
draw all geographic bounding boxes
          * on a world map. If the bounding box encompasses the whole world, 
replace it by a "World" description.
          * The reason is that drawing a box over the whole world is not very 
informative; it rather looks like a
          * border around the image.
          */
         text = null;
         Identifier identifier = null;
+        Range<Date> timeRange = null;
+        Range<Double> heights = null;
         for (final Extent extent : nonNull(info.getExtents())) {
             if (extent != null) {
                 if (text == null) {
@@ -381,6 +384,10 @@ final class IdentificationInfo extends 
Section<Identification> {
                         isWorld = drawOnMap((GeographicBoundingBox) ge);
                     }
                 }
+                final MeasurementRange<Double> v = 
Extents.getVerticalRange(extent);
+                if (v != null) heights = (heights != null) ? heights.union(v) 
: v;
+                final Range<Date> t = Extents.getTimeRange(extent);
+                if (t != null) timeRange = (timeRange != null) ? 
timeRange.union(t) : t;
             }
         }
         if (text == null) {
@@ -392,7 +399,38 @@ final class IdentificationInfo extends 
Section<Identification> {
                 text = owner.vocabulary.getString(Vocabulary.Keys.World);
             }
         }
+        /*
+         * Write the temporal, vertical and geographic extents fetched above.
+         */
         addLine(Vocabulary.Keys.Extent, text);
+        if (timeRange != null) {
+            label = Vocabulary.Keys.StartDate;
+            Date t = timeRange.getMinValue();
+            if (t == null) {
+                t = timeRange.getMaxValue();
+                label = Vocabulary.Keys.EndDate;
+            }
+            addLine(label, owner.format(t));
+        }
+        if (heights != null) {
+            final Double min = heights.getMinValue();
+            final Double max = heights.getMaxValue();
+            if (min != null || max != null) {
+                StringBuffer b = new StringBuffer(20);
+                if (min != null && max != null && !min.equals(max)) {
+                    owner.formats.formatPair(min, " … ", max, b);
+                } else {
+                    owner.format(min != null ? min : max, b);
+                }
+                if (heights instanceof MeasurementRange<?>) {
+                    final Unit<?> unit = ((MeasurementRange<?>) 
heights).unit();
+                    if (unit != null) {
+                        owner.format(unit, b.append(' '));
+                    }
+                }
+                addLine(Vocabulary.Keys.Height, b.toString());
+            }
+        }
         setRowIndex(extentOnMap, nextRowIndex());
     }
 
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
index 7eb7382ae0..162c8994ac 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
@@ -17,8 +17,6 @@
 package org.apache.sis.gui.metadata;
 
 import java.util.Locale;
-import java.text.DateFormat;
-import java.text.NumberFormat;
 import java.util.Collection;
 import java.util.StringJoiner;
 import javafx.application.Platform;
@@ -55,7 +53,7 @@ import org.apache.sis.gui.Widget;
  *
  * @author  Smaniotto Enzo (GSoC)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -74,18 +72,11 @@ public class MetadataSummary extends Widget {
     final Vocabulary vocabulary;
 
     /**
-     * The format to use for writing numbers, created when first needed.
+     * The format to use for writing dates and numbers.
      *
-     * @see #getNumberFormat()
+     * @see #format(Object, StringBuffer)
      */
-    private NumberFormat numberFormat;
-
-    /**
-     * The format to use for writing dates, created when first needed.
-     *
-     * @see #getDateFormat()
-     */
-    private DateFormat dateFormat;
+    final VerboseFormats formats;
 
     /**
      * An image of size 360×180 pixels showing a map of the world.
@@ -134,6 +125,7 @@ public class MetadataSummary extends Widget {
      */
     public MetadataSummary() {
         vocabulary  = Vocabulary.getResources((Locale) null);
+        formats     = new VerboseFormats(vocabulary.getLocale());
         information = new TitledPane[] {
             // If order is modified, revisit `getIdentificationInfo()`.
             new 
TitledPane(vocabulary.getString(Vocabulary.Keys.ResourceIdentification), new 
IdentificationInfo(this)),
@@ -172,23 +164,27 @@ public class MetadataSummary extends Widget {
     }
 
     /**
-     * Returns the format to use for writing numbers.
+     * Formats the given property value.
+     * The formatter is selected from the object class.
+     *
+     * @param  value  the property value to format, or {@code null} if none.
+     * @return formatted string representation of the given value, or {@code 
null} if the given value was null.
      */
-    final NumberFormat getNumberFormat() {
-        if (numberFormat == null) {
-            numberFormat = NumberFormat.getInstance();
-        }
-        return numberFormat;
+    final String format(final Object value) {
+        return (value != null) ? formats.formatValue(value, true) : null;
     }
 
     /**
-     * Returns the format to use for writing dates.
+     * Formats the given property value in the specified buffer.
+     * The formatter is selected from the object class.
+     *
+     * @param  value       the property value to format, or {@code null} if 
none.
+     * @param  toAppendTo  where to append the property value.
      */
-    final DateFormat getDateFormat() {
-        if (dateFormat == null) {
-            dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, 
DateFormat.MEDIUM);
+    final void format(final Object value, final StringBuffer toAppendTo) {
+        if (value != null) {
+            formats.format(value, toAppendTo);
         }
-        return dateFormat;
     }
 
     /**
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/RepresentationInfo.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/RepresentationInfo.java
index 115673022e..396f115ccc 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/RepresentationInfo.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/RepresentationInfo.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.gui.metadata;
 
-import java.text.FieldPosition;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.spatial.Dimension;
 import org.opengis.metadata.spatial.SpatialRepresentation;
@@ -93,10 +92,7 @@ final class RepresentationInfo extends 
Section<SpatialRepresentation> {
      *       the resolution. Note that VectorSpatialRepresentation would also 
needs a table.
      */
     private void build(final GridSpatialRepresentation info) {
-        final Integer dimension = info.getNumberOfDimensions();
-        if (dimension != null) {
-            addLine(Vocabulary.Keys.NumberOfDimensions, 
owner.getNumberFormat().format(dimension));
-        }
+        addLine(Vocabulary.Keys.NumberOfDimensions, 
owner.format(info.getNumberOfDimensions()));
         final StringBuffer gridSize   = new StringBuffer(20);
         final StringBuffer resolution = new StringBuffer(20);
         for (final Dimension dim : nonNull(info.getAxisDimensionProperties())) 
{
@@ -106,9 +102,7 @@ final class RepresentationInfo extends 
Section<SpatialRepresentation> {
                 if (gridSize.length() != 0) {
                     gridSize.append(" × ");
                 }
-                if (size != null) {
-                    owner.getNumberFormat().format(size, gridSize, new 
FieldPosition(0));
-                }
+                owner.format(size, gridSize);
                 if (name != null) {
                     if (size != null) gridSize.append(' ');
                     gridSize.append(name);
@@ -119,7 +113,7 @@ final class RepresentationInfo extends 
Section<SpatialRepresentation> {
                 if (resolution.length() != 0) {
                     resolution.append(" × ");
                 }
-                owner.getNumberFormat().format(r, resolution, new 
FieldPosition(0));
+                owner.format(r, resolution);
             }
         }
         if (gridSize.length() != 0) {
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/Section.java 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/Section.java
index 4a0d085e2f..2f350a1647 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/Section.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/Section.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.gui.metadata;
 
-import java.text.NumberFormat;
 import java.util.Collection;
 import java.util.function.IntFunction;
 import javafx.collections.ObservableList;
@@ -175,9 +174,8 @@ abstract class Section<T> extends GridPane implements 
EventHandler<ActionEvent>
         final ObservableList<Node> pages = pagination.getChildren();
         int i = pages.size();
         if (i < n) {
-            final NumberFormat format = owner.getNumberFormat();
             do {
-                final ToggleButton b = new ToggleButton(format.format(++i));
+                final ToggleButton b = new ToggleButton(owner.format(++i));
                 b.setToggleGroup(pageGroup);
                 b.setOnAction​(this);
                 pages.add(b);
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/VerboseFormats.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/VerboseFormats.java
new file mode 100644
index 0000000000..f3114eb6e8
--- /dev/null
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/VerboseFormats.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.gui.metadata;
+
+import java.util.Date;
+import java.util.Locale;
+import java.text.Format;
+import java.text.DateFormat;
+import javax.measure.Unit;
+import org.apache.sis.measure.UnitFormat;
+import org.apache.sis.internal.gui.PropertyValueFormats;
+
+
+/**
+ * A provider for {@link java.text.NumberFormat}, {@link 
java.text.DateFormat}, <i>etc</i>.
+ * This format uses verbose patterns, for example full dates with day of weeks.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.3
+ * @since   1.3
+ * @module
+ */
+@SuppressWarnings({"serial","CloneableImplementsClone"})            // Not 
intended to be serialized.
+final class VerboseFormats extends PropertyValueFormats {
+    /**
+     * Creates a new format for the given locale.
+     *
+     * @param  locale  the locale to use for formatting objects.
+     */
+    VerboseFormats(final Locale locale) {
+        super(locale);
+    }
+
+    /**
+     * Creates a new format to use for formatting values of the given type.
+     * This method is invoked by {@link #getFormat(Class)} the first time
+     * that a format is needed for the given type.
+     *
+     * @param  valueType  the base type of values to parse or format.
+     * @return the format to use for parsing of formatting values of the given 
type.
+     */
+    @Override
+    protected Format createFormat(final Class<?> valueType) {
+        if (valueType == Date.class) {
+            return DateFormat.getDateTimeInstance(DateFormat.LONG, 
DateFormat.LONG, getLocale());
+        }
+        if (valueType == Unit.class) {
+            UnitFormat f = new UnitFormat(getLocale());
+            f.setStyle(UnitFormat.Style.NAME);
+            return f;
+        }
+        return super.createFormat(valueType);
+    }
+}
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
index 3d94a52328..5ebb4e9179 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/package-info.java
@@ -23,7 +23,7 @@
  * @author  Smaniotto Enzo (GSoC)
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/TextFormats.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormats.java
similarity index 86%
rename from 
application/sis-javafx/src/main/java/org/apache/sis/internal/gui/TextFormats.java
rename to 
application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormats.java
index 11ca1585ba..0ba33985d6 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/TextFormats.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormats.java
@@ -22,26 +22,27 @@ import java.text.Format;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
 import java.text.ParseException;
-import java.io.IOException;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.io.CompoundFormat;
 
 
 /**
  * A provider for {@link java.text.NumberFormat}, {@link 
java.text.DateFormat}, <i>etc</i>.
- * Used for formatting values in {@link PropertyValueFormatter}.
+ * Used for formatting values in {@link PropertyValueFormatter} or in metadata 
summary.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.2
  * @module
  */
 @SuppressWarnings({"serial","CloneableImplementsClone"})            // Not 
intended to be serialized.
-final class TextFormats extends CompoundFormat<Object> {
+public class PropertyValueFormats extends CompoundFormat<Object> {
     /**
      * Creates a new format for the given locale.
+     *
+     * @param  locale  the locale to use for formatting objects.
      */
-    TextFormats(final Locale locale) {
+    protected PropertyValueFormats(final Locale locale) {
         super(locale, TimeZone.getDefault());
     }
 
@@ -64,7 +65,7 @@ final class TextFormats extends CompoundFormat<Object> {
      * @throws ParseException always thrown.
      */
     @Override
-    public Object parse(CharSequence text, ParsePosition pos) throws 
ParseException {
+    public final Object parse(CharSequence text, ParsePosition pos) throws 
ParseException {
         throw new ParseException(null, 0);
     }
 
@@ -77,7 +78,7 @@ final class TextFormats extends CompoundFormat<Object> {
      * @param  toAppendTo  where to append the property value.
      */
     @Override
-    public void format(final Object value, final Appendable toAppendTo) throws 
IOException {
+    public final void format(final Object value, final Appendable toAppendTo) {
         final StringBuffer buffer = (StringBuffer) toAppendTo;
         final Format f = getFormat(value.getClass());
         if (f != null) {
@@ -96,7 +97,7 @@ final class TextFormats extends CompoundFormat<Object> {
      *         for the given object. If {@code false}, then {@code null} will 
be returned instead.
      * @return formatted string representation of the given value.
      */
-    public String formatValue(final Object value, final boolean 
toStringAllowed) {
+    public final String formatValue(final Object value, final boolean 
toStringAllowed) {
         final Format f = getFormat(value.getClass());
         if (f == null) {
             return value.toString();
@@ -116,7 +117,7 @@ final class TextFormats extends CompoundFormat<Object> {
      * @param  second      the maximum value of the range.
      * @param  toAppendTo  where to append the property value.
      */
-    public void formatPair(final double first, final String separator, final 
double second, final StringBuffer toAppendTo) {
+    public final void formatPair(final double first, final String separator, 
final double second, final StringBuffer toAppendTo) {
         final FieldPosition pos = new FieldPosition(0);
         final Format f = getFormat(Number.class);
         format(f, first,  toAppendTo, pos); toAppendTo.append(separator);
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormatter.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormatter.java
index 7d82d7961e..f84e7d06e8 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormatter.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyValueFormatter.java
@@ -36,7 +36,7 @@ public class PropertyValueFormatter extends PropertyFormat {
      * The formats to use for objects. Its locale is usually {@link 
Locale#getDefault()}.
      * The locale is also given to {@link 
InternationalString#toString(Locale)} calls.
      */
-    final TextFormats formats;
+    final PropertyValueFormats formats;
 
     /**
      * Creates a formatter for the specified locale.
@@ -47,7 +47,7 @@ public class PropertyValueFormatter extends PropertyFormat {
     public PropertyValueFormatter(final Appendable buffer, final Locale 
locale) {
         super(buffer);
         setLineSeparator(" ¶ ");
-        formats = new TextFormats(locale);
+        formats = new PropertyValueFormats(locale);
     }
 
     /**
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
index 69cdc19127..d8f8d6e105 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
@@ -59,7 +59,7 @@ public final class PropertyView implements Localized, 
ChangeListener<Number> {
     /**
      * Provider for {@link java.text.NumberFormat}, {@link 
java.text.DateFormat}, <i>etc</i>.
      */
-    private final TextFormats formats;
+    private final PropertyValueFormats formats;
 
     /**
      * The current property value. This is used for detecting changes.
@@ -147,7 +147,7 @@ public final class PropertyView implements Localized, 
ChangeListener<Number> {
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
     public PropertyView(final Locale locale, final ObjectProperty<Node> view, 
final ObjectProperty<Background> background) {
-        formats = new TextFormats(locale);
+        formats = new PropertyValueFormats(locale);
         this.view = view;
         if (background != null) {
             getImageCanvas().backgroundProperty().bind(background);

Reply via email to