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);