You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2023/11/21 14:19:46 UTC
(sis-site) branch main updated (729e122b -> 6c4b10ac)
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/sis-site.git
from 729e122b Reorganize and develop the discussion about metadata and nil values.
new e4965644 Rename de "GeoAPI" style as "API" for convenience. It is frequently used, and having the same length as "SIS" and "OGC" make easier to format some HTML code as table.
new 6c4b10ac Better documentation about the handling of NilReason and the view as TreeTableMap.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../annexes/geoapi/DefinitionProcess.html | 26 ++--
.../annexes/geoapi/ReduceDependency.html | 8 +-
.../annexes/tests/GeoApiConformance.html | 26 ++--
.../developer-guide/introduction/Conventions.html | 8 +-
.../developer-guide/introduction/DataAccess.html | 3 +-
.../developer-guide/metadata/NavigateMetadata.html | 168 ++++++++++++++++++---
content/developer-guide/metadata/NilReason.html | 60 +++++++-
content/developer-guide/metadata/index.html | 3 +-
.../referencing/ComponentsOfCRS.html | 8 +-
.../utility/Internationalization.html | 2 +-
content/developer-guide/xml/ISO-19115.html | 2 +-
static/book/book.css | 16 +-
12 files changed, 263 insertions(+), 67 deletions(-)
(sis-site) 01/02: Rename de "GeoAPI" style as "API" for convenience. It is frequently used, and having the same length as "SIS" and "OGC" make easier to format some HTML code as table.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sis-site.git
commit e496564493da51bb6c3acf5271b670f7ba07f137
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Nov 21 10:21:27 2023 +0100
Rename de "GeoAPI" style as "API" for convenience.
It is frequently used, and having the same length as "SIS" and "OGC" make easier to format some HTML code as table.
---
.../annexes/geoapi/DefinitionProcess.html | 26 +++++++++++-----------
.../annexes/geoapi/ReduceDependency.html | 8 +++----
.../annexes/tests/GeoApiConformance.html | 26 +++++++++++-----------
.../developer-guide/introduction/Conventions.html | 4 ++--
.../referencing/ComponentsOfCRS.html | 8 +++----
.../utility/Internationalization.html | 2 +-
content/developer-guide/xml/ISO-19115.html | 2 +-
static/book/book.css | 2 +-
8 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/content/developer-guide/annexes/geoapi/DefinitionProcess.html b/content/developer-guide/annexes/geoapi/DefinitionProcess.html
index 1dfed58f..f2ada6c7 100644
--- a/content/developer-guide/annexes/geoapi/DefinitionProcess.html
+++ b/content/developer-guide/annexes/geoapi/DefinitionProcess.html
@@ -82,7 +82,7 @@
The <abbr>OGC</abbr> class <code>MD_Identifier</code> becomes the
<code>Identifier</code> interface in the <code>org.opengis.metadata</code> package.
The <abbr>OGC</abbr> class <code>SC_CRS</code> becomes the <code>CoordinateReferenceSystem</code> interface,
- and the <code class="OGC">usesDatum</code> association becomes a <code class="GeoAPI">getDatum()</code> method,
+ and the <code class="OGC">usesDatum</code> association becomes a <code class="API">getDatum()</code> method,
rather than the “<code>getUsesDatum()</code>” that would result from an automatic conversion tool.
We do not allow programs to blindly apply rules that ignore the conventions of the community whose schemas we translate.
</p></div>
@@ -156,12 +156,12 @@
the name of the element in that standard, and also its obligation.
For example, in the following code snippet, the first <code>@UML</code> code indicates that the Java interface that follows
(<code>ProjectedCRS</code>) is defined using the <code>SC_ProjectedCRS</code> type of <abbr>ISO</abbr> 19111 standard.
- The second <code>@UML</code> annotation, this time applied to the <code class="GeoAPI">getCoordinateSystem()</code> method,
+ The second <code>@UML</code> annotation, this time applied to the <code class="API">getCoordinateSystem()</code> method,
indicates that this method is defined using the <code class="OGC">coordinateSystem</code> association of <abbr>ISO</abbr> 19111 standard,
and that this association is mandatory — meaning, in Java, that the method is not allowed to return a <code>null</code> value.
</p>
-<pre><code>package <code class="GeoAPI">org.opengis.referencing.crs</code>;
+<pre><code>package <code class="API">org.opengis.referencing.crs</code>;
/**
* A 2D coordinate reference system used to approximate the shape of the earth on a planar surface.
@@ -172,7 +172,7 @@ public interface ProjectedCRS extends GeneralDerivedCRS {
* Returns the coordinate system, which must be Cartesian.
*/
@UML(obligation=MANDATORY, specification=ISO_19111, identifier="<code class="OGC">coordinateSystem</code>")
- CartesianCS <code class="GeoAPI">getCoordinateSystem()</code>;
+ CartesianCS <code class="API">getCoordinateSystem()</code>;
}</code></pre>
<p>
@@ -198,7 +198,7 @@ System.out.println("Standard name of type " + type.getName() + " is " + Types.ge
<h4 id="MappingToJDK">Implicit mapping to standard <abbr>JDK</abbr></h4>
<p>
- Some classes and methods have neither an <code>@UML</code> annotation, nor an entry in the <code class="GeoAPI">class-index.properties</code> file.
+ Some classes and methods have neither an <code>@UML</code> annotation, nor an entry in the <code class="API">class-index.properties</code> file.
They are either extensions of GeoAPI, or else types defined in other libraries, such as standard <abbr title="Java Development Kit">JDK</abbr>.
In this last case, the mapping to <abbr>ISO</abbr> standards is implicit.
The following table describes this mapping for <abbr>ISO</abbr> 19103 types.
@@ -248,12 +248,12 @@ System.out.println("Standard name of type " + type.getName() + " is " + Types.ge
<tr>
<td><code class="OGC">FreeText</code></td>
<td>(no equivalent)</td>
- <td class="leftBorder">See <code class="GeoAPI">org.opengis.util.InternationalString</code> below.</td>
+ <td class="leftBorder">See <code class="API">org.opengis.util.InternationalString</code> below.</td>
</tr>
<tr>
<td><code class="OGC">CharacterString</code></td>
<td><code>java.lang.String</code></td>
- <td class="leftBorder">Often <code class="GeoAPI">org.opengis.util.InternationalString</code> (see below).</td>
+ <td class="leftBorder">Often <code class="API">org.opengis.util.InternationalString</code> (see below).</td>
</tr>
<tr>
<td><code class="OGC">LocalisedCharacterString</code></td>
@@ -369,15 +369,15 @@ System.out.println("Standard name of type " + type.getName() + " is " + Types.ge
Both define all authorized values, without allowing the user to add any.
A <code class="OGC">CodeList</code> is similar to an enumeration, except that users may add their own items.
Standard <abbr>JDK</abbr> does not offer this possibility.
- GeoAPI defines an abstract <code class="GeoAPI">CodeList</code> class that reproduces some of the functionality of <code>Enum</code> while being extensible.
- Extensions are made available by the <code class="GeoAPI">valueOf(String)</code> static method, which, in contrast to <code>Enum</code>,
+ GeoAPI defines an abstract <code class="API">CodeList</code> class that reproduces some of the functionality of <code>Enum</code> while being extensible.
+ Extensions are made available by the <code class="API">valueOf(String)</code> static method, which, in contrast to <code>Enum</code>,
creates new instances if the name provided does not correspond to the name of an existing instance.
</p>
-<pre><code>MediumName cdRom = MediumName.<code class="GeoAPI">CD_ROM;</code>
-MediumName usbKey = MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">USB_KEY</code>"); // There is no constraint on this value.
-assert MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">CD_ROM</code>") == cdRom : "valueOf must return existing constants.";
-assert MediumName.<code class="GeoAPI">valueOf</code>("<code class="GeoAPI">USB_KEY</code>") == usbKey : "valueOf must cache the previously requested values.";</code></pre>
+<pre><code>MediumName cdRom = MediumName.<code class="API">CD_ROM;</code>
+MediumName usbKey = MediumName.<code class="API">valueOf</code>("<code class="API">USB_KEY</code>"); // There is no constraint on this value.
+assert MediumName.<code class="API">valueOf</code>("<code class="API">CD_ROM</code>") == cdRom : "valueOf must return existing constants.";
+assert MediumName.<code class="API">valueOf</code>("<code class="API">USB_KEY</code>") == usbKey : "valueOf must cache the previously requested values.";</code></pre>
</section>
</body>
</html>
diff --git a/content/developer-guide/annexes/geoapi/ReduceDependency.html b/content/developer-guide/annexes/geoapi/ReduceDependency.html
index 8d86b75c..ed14fe8d 100644
--- a/content/developer-guide/annexes/geoapi/ReduceDependency.html
+++ b/content/developer-guide/annexes/geoapi/ReduceDependency.html
@@ -52,24 +52,24 @@
Java reflection methods allow access to this information during the execution of an application.
Class <code>org.apache.sis.util.iso.Types</code> provides static convenience methods like
<code class="SIS">getStandardName(Class)</code>, but one can avoid those methods.
- The following example displays the standard name for the method <code class="GeoAPI">getTitle()</code> from the <code>Citation</code> interface:
+ The following example displays the standard name for the method <code class="API">getTitle()</code> from the <code>Citation</code> interface:
</p>
<pre><code>Class<?> type = Citation.class;
-Method method = type.getMethod("<code class="GeoAPI">getTitle</code>", (Class<?>[]) null);
+Method method = type.getMethod("<code class="API">getTitle</code>", (Class<?>[]) null);
UML annot = method.getAnnotation(UML.class);
String id = annot.identifier();
System.out.println("The standard name for the " + method.getName() + " method is " + id);</code></pre>
<p>
The reverse operation — getting the Java class and method from a standard name — is a bit more complicated.
- It requires reading the <code class="GeoAPI">class-index.properties</code> file provided in the <code>org.opengis.annotation</code> package.
+ It requires reading the <code class="API">class-index.properties</code> file provided in the <code>org.opengis.annotation</code> package.
The following example reads the files just before searching for the name of the interface corresponding to <code>CI_Citation</code>.
Users are always encouraged to only read this file once and then save its contents in their application’s cache.
</p>
<pre><code>Properties isoToGeoAPI = new Properties();
-try (InputStream in = UML.class.getResourceAsStream("<code class="GeoAPI">class-index.properties</code>")) {
+try (InputStream in = UML.class.getResourceAsStream("<code class="API">class-index.properties</code>")) {
isoToGeoAPI.load(in);
}
String isoName = "<code class="OGC">CI_Citation</code>";
diff --git a/content/developer-guide/annexes/tests/GeoApiConformance.html b/content/developer-guide/annexes/tests/GeoApiConformance.html
index da4ba71b..671bf59e 100644
--- a/content/developer-guide/annexes/tests/GeoApiConformance.html
+++ b/content/developer-guide/annexes/tests/GeoApiConformance.html
@@ -65,15 +65,15 @@
</p></div>
<p>
- The easiest way to perform these verifications is to call the static methods <code class="GeoAPI">validate(…)</code>
+ The easiest way to perform these verifications is to call the static methods <code class="API">validate(…)</code>
of the <code>org.opengis.test.Validators</code> class.
As all of <code>Validators</code> methods bear the same name, it is enough to write “<code>validate(<var>value</var>)</code>”
and then let the compiler choose the most appropriate method for the type of object given in argument.
If the object type is not known at the time of compilation,
- the <code class="GeoAPI">dispatch(Object)</code> method can be invoked for redirecting the work to the most appropriate <code class="GeoAPI">validate(…)</code> method.
+ the <code class="API">dispatch(Object)</code> method can be invoked for redirecting the work to the most appropriate <code class="API">validate(…)</code> method.
</p>
<p>
- All <code class="GeoAPI">validate(…)</code> functions follow a chain of dependencies,
+ All <code class="API">validate(…)</code> functions follow a chain of dependencies,
meaning that they will also validate each component of the object to be validated.
For example, the validation of a <code>GeographicCRS</code> implies the validation of its component
<code>GeodeticDatum</code>, which itself implies the validation of its component <code>Ellipsoid</code>, and so on.
@@ -98,14 +98,14 @@ public class MyTest {
* in a parent class to all test classes.
*/
static {
- Validators.<code class="GeoAPI">DEFAULT.metadata.requireMandatoryAttributes</code> = false;
- Validators.<code class="GeoAPI">DEFAULT.citation.requireMandatoryAttributes</code> = false;
+ Validators.<code class="API">DEFAULT.metadata.requireMandatoryAttributes</code> = false;
+ Validators.<code class="API">DEFAULT.citation.requireMandatoryAttributes</code> = false;
}
@Test
public void testMyMetadata() {
Metadata myObject = …; // Create an object here.
- Validators.<code class="GeoAPI">validate</code>(myObject);
+ Validators.<code class="API">validate</code>(myObject);
}
}</code></pre>
@@ -123,14 +123,14 @@ public class MyTest {
public MyTest() {
validators = new ValidatorContainer();
- validators.<code class="GeoAPI">metadata.requireMandatoryAttributes</code> = false;
- validators.<code class="GeoAPI">citation.requireMandatoryAttributes</code> = false;
+ validators.<code class="API">metadata.requireMandatoryAttributes</code> = false;
+ validators.<code class="API">citation.requireMandatoryAttributes</code> = false;
}
@Test
public void testMyMetadata() {
Metadata myObject = …; // Create an object here.
- validators.<code class="GeoAPI">validate</code>(myObject);
+ validators.<code class="API">validate</code>(myObject);
}
}</code></pre>
@@ -142,7 +142,7 @@ public class MyTest {
All test classes bear a name ending in "<code>Test</code>".
GeoAPI also provides an <code>org.opengis.test.TestSuite</code> class including all test classes defined in the
<code>geoapi-conformance</code> module, but Apache <abbr>SIS</abbr> does not use it.
- Instead, Apache <abbr>SIS</abbr> inherits GeoAPI’s <code class="GeoAPI">*Test</code> classes on a case-by-case basis,
+ Instead, Apache <abbr>SIS</abbr> inherits GeoAPI’s <code class="API">*Test</code> classes on a case-by-case basis,
in the appropriate modules.
The example below gives an example of a customized GeoAPI test:
The <a href="http://www.geoapi.org/geoapi-conformance/apidocs/org/opengis/test/referencing/ParameterizedTransformTest.html">parent test javadoc</a>
@@ -175,8 +175,8 @@ public class MyTest extends ParameterizedTransformTest {
@Test
@Override
public void testLambertAzimuthalEqualArea() throws FactoryException, TransformException {
- <code class="GeoAPI">tolerance</code> = 0.1; // 10 cm tolerance.
- super.<code class="GeoAPI">testLambertAzimuthalEqualArea()</code>;
+ <code class="API">tolerance</code> = 0.1; // 10 cm tolerance.
+ super.<code class="API">testLambertAzimuthalEqualArea()</code>;
}
/**
@@ -186,7 +186,7 @@ public class MyTest extends ParameterizedTransformTest {
*/
@After
public void ensureAllTransformAreMath2D() {
- assertTrue(<code class="GeoAPI">transform</code> instanceof MathTransform2D);
+ assertTrue(<code class="API">transform</code> instanceof MathTransform2D);
}
}</code></pre>
</section>
diff --git a/content/developer-guide/introduction/Conventions.html b/content/developer-guide/introduction/Conventions.html
index aa0a3716..9202e257 100644
--- a/content/developer-guide/introduction/Conventions.html
+++ b/content/developer-guide/introduction/Conventions.html
@@ -60,7 +60,7 @@
<p>
For example to represent a projected coordinate reference system (Mercator, Lambert, <i>etc</i>),
<code class="OGC">SC_ProjectedCRS</code> is an <abbr>UML</abbr> and <abbr>XML</abbr> element defined by the <abbr>ISO</abbr> 19111 standard.
- Then <code class="GeoAPI">org.opengis.referencing.crs.<b>ProjectedCRS</b></code> is the implementation-neutral GeoAPI interface derived from that standard,
+ Then <code class="API">org.opengis.referencing.crs.<b>ProjectedCRS</b></code> is the implementation-neutral GeoAPI interface derived from that standard,
and <code class="SIS">org.apache.sis.referencing.crs.<b>DefaultProjectedCRS</b></code> is the implementation class provided by Apache SIS.
</p>
</section>
@@ -73,7 +73,7 @@
but prefixed by <code>Abstract</code>, <code>Default</code> or <code>General</code> word.
The <code>General</code> prefix is sometimes used instead of <code>Default</code>
to indicate that alternative implementations are available for some specific cases.
- For example the <code class="GeoAPI">Envelope</code> interface is implemented by at least two Apache SIS classes:
+ For example the <code class="API">Envelope</code> interface is implemented by at least two Apache SIS classes:
<code class="SIS">GeneralEnvelope</code> and <code class="SIS">Envelope2D</code>.
The first implementation can represent envelopes with any number of dimensions
while the second implementation is specialized for two-dimensional envelopes.
diff --git a/content/developer-guide/referencing/ComponentsOfCRS.html b/content/developer-guide/referencing/ComponentsOfCRS.html
index 733193ba..e9141f01 100644
--- a/content/developer-guide/referencing/ComponentsOfCRS.html
+++ b/content/developer-guide/referencing/ComponentsOfCRS.html
@@ -190,10 +190,10 @@ RangeMeaning atEnds = secondAxis.getRangeMeaning(); // For a longitude a
but many ellipsoid definitions provide this factor instead of semi-minor axis length.
</p>
-<pre><code>Unit<Length> units = ellipsoid.<code class="GeoAPI">getAxisUnit()</code>;
-double semiMajor = ellipsoid.<code class="GeoAPI">getSemiMajorAxis()</code>; // In units of measurement given above.
-double semiMinor = ellipsoid.<code class="GeoAPI">getSemiMinorAxis()</code>; // In units of measurement given above.
-double ivf = ellipsoid.<code class="GeoAPI">getInverseFlattening()</code>; // = semiMajor / (semiMajor - semiMinor).
+<pre><code>Unit<Length> units = ellipsoid.<code class="API">getAxisUnit()</code>;
+double semiMajor = ellipsoid.<code class="API">getSemiMajorAxis()</code>; // In units of measurement given above.
+double semiMinor = ellipsoid.<code class="API">getSemiMinorAxis()</code>; // In units of measurement given above.
+double ivf = ellipsoid.<code class="API">getInverseFlattening()</code>; // = semiMajor / (semiMajor - semiMinor).
</code></pre>
<p>
diff --git a/content/developer-guide/utility/Internationalization.html b/content/developer-guide/utility/Internationalization.html
index 093f3807..d4d5bd7b 100644
--- a/content/developer-guide/utility/Internationalization.html
+++ b/content/developer-guide/utility/Internationalization.html
@@ -99,7 +99,7 @@
<div class="example"><p><b>Example:</b>
<abbr>SIS</abbr> includes only one instance of the <code>OperationMethod</code>
type representing the Mercator projection, regardless of the client’s language.
- But its <code class="GeoAPI">getName()</code> method (indirectly) provides an instance of
+ But its <code class="API">getName()</code> method (indirectly) provides an instance of
<code>InternationalString</code>, so that <code>toString(Locale.ENGLISH)</code> returns <cite>Mercator projection</cite>
while <code>toString(Locale.FRENCH)</code> returns <cite>Projection de Mercator</cite>.
</p></div>
diff --git a/content/developer-guide/xml/ISO-19115.html b/content/developer-guide/xml/ISO-19115.html
index 7c194ae7..3068fd78 100644
--- a/content/developer-guide/xml/ISO-19115.html
+++ b/content/developer-guide/xml/ISO-19115.html
@@ -183,7 +183,7 @@ public class MyClass {
Although this mechanism has been defined in order to better support the representation of <abbr>XML</abbr> attributes
of the <code>gco:ObjectIdentification</code> group,
it also conveniently allows other types of identifiers to be manipulated.
- For example, the <code class="GeoAPI">ISBN</code> and <code class="GeoAPI">ISSN</code> attributes of
+ For example, the <code class="API">ISBN</code> and <code class="API">ISSN</code> attributes of
<code>Citation</code> may be manipulated in this way.
The methods of the <code class="SIS">IdentifiedObject</code> interface therefore provides a specific location
where all types of identifiers (not only <abbr>XML</abbr>) associated with an object may be manipulated.
diff --git a/static/book/book.css b/static/book/book.css
index effe5d85..09751e9c 100644
--- a/static/book/book.css
+++ b/static/book/book.css
@@ -300,7 +300,7 @@ code.OGC {
color: MediumBlue;
}
-code.GeoAPI {
+code.API {
color: Green;
}
(sis-site) 02/02: Better documentation about the handling of NilReason and the view as TreeTableMap.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/sis-site.git
commit 6c4b10acff054f46d21caf4bd7e115061664aa82
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Nov 21 14:25:06 2023 +0100
Better documentation about the handling of NilReason and the view as TreeTableMap.
---
.../developer-guide/introduction/Conventions.html | 4 +-
.../developer-guide/introduction/DataAccess.html | 3 +-
.../developer-guide/metadata/NavigateMetadata.html | 168 ++++++++++++++++++---
content/developer-guide/metadata/NilReason.html | 60 +++++++-
content/developer-guide/metadata/index.html | 3 +-
static/book/book.css | 14 ++
6 files changed, 224 insertions(+), 28 deletions(-)
diff --git a/content/developer-guide/introduction/Conventions.html b/content/developer-guide/introduction/Conventions.html
index 9202e257..420016e8 100644
--- a/content/developer-guide/introduction/Conventions.html
+++ b/content/developer-guide/introduction/Conventions.html
@@ -33,7 +33,7 @@
-->
<section>
<header>
- <h2 id="TypographicConventions">Typographic conventions</h2>
+ <h2 id="TypographicConventions">Typographic conventions in this document</h2>
</header>
<p>
The elements defined in a computer language, such as classes and methods in Java or elements in an <abbr>XML</abbr> document,
@@ -66,7 +66,7 @@
</section>
<section>
<header>
- <h2 id="CodingConventions">Coding conventions</h2>
+ <h2 id="CodingConventions">Coding conventions in Apache <abbr>SIS</abbr></h2>
</header>
<p>
Apache SIS implements most GeoAPI interfaces by a classes of the same name than the interface
diff --git a/content/developer-guide/introduction/DataAccess.html b/content/developer-guide/introduction/DataAccess.html
index f7039a12..fc9ce044 100644
--- a/content/developer-guide/introduction/DataAccess.html
+++ b/content/developer-guide/introduction/DataAccess.html
@@ -70,8 +70,7 @@
For example, the following code read a metadata file from a Landsat-8 image and prints the declared geographic bounding box:
</p>
-<pre><code>
-import org.opengis.metadata.Metadata;
+<pre><code>import org.opengis.metadata.Metadata;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStores;
diff --git a/content/developer-guide/metadata/NavigateMetadata.html b/content/developer-guide/metadata/NavigateMetadata.html
index a8883b06..578ccdfe 100644
--- a/content/developer-guide/metadata/NavigateMetadata.html
+++ b/content/developer-guide/metadata/NavigateMetadata.html
@@ -44,7 +44,7 @@
</p>
<ul>
<li>As key-value pairs in a <code>Map</code> (from <code>java.util</code>).</li>
- <li>As a <code>TreeTable</code> (from <code>org.apache.sis.util.collection</code>).</li>
+ <li>As a <code class="SIS">TreeTable</code> (from <code>org.apache.sis.util.collection</code>).</li>
<li>As a table record in a database (using <code>org.apache.sis.metadata.sql</code>).</li>
<li>As an <abbr>XML</abbr> document conforms to <abbr>ISO</abbr> standard schema.</li>
</ul>
@@ -56,13 +56,22 @@
<h3 id="GetMetadataElement">Direct access via getter methods</h3>
<p>
All metadata classes provide getter, and sometime setter, methods for their properties.
- Some properties accept many values, in which case the property type is a collection.
- The following example prints the range of latitudes of all data descriptions
- found in a given root <code>Metadata</code> object:
+ The following example prints all ranges of latitudes found in a metadata.
+ It may be, for example, a metadata describing the extent of a raster file.
+ Fetching that information requires navigating through the following steps:
+ </p><p style="text-align:center">
+ <code class="API">Metadata</code>
+ ⟶ <code class="OGC">identificationInfo</code>
+ ⟶ <code class="OGC">extent</code>
+ ⟶ <code class="OGC">geographicElement</code>
+ ⟶ (<code class="OGC">southBoundLatitude</code>, <code class="OGC">northBoundLatitude</code>)
+ </p><p>
+ Some properties accept many values, in which case the code must iterate over the elements of a collection.
+ Furthermore, some properties are available only in a sub-interface, in which case <code>instanceof</code>
+ checks are required. The resulting code is as below:
</p>
-<pre><code>
-import org.opengis.metadata.metadata;
+<pre><code>import org.opengis.metadata.metadata;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.extent.GeographicExtent;
import org.opengis.metadata.extent.GeographicBoundingBox;
@@ -95,14 +104,16 @@ void main() {
For example the following method navigates through different branches where North, South, East and West data bounds may be found:
</p>
-<pre><code>
-import org.opengis.metadata.metadata;
+<pre><code>import org.opengis.metadata.metadata;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.apache.sis.metadata.iso.extent.Extents;
void main() {
Metadata metadata = ...; // For example, metadata read from a data store.
GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(extent);
+ if (box != null) {
+ // Same as in the previous example.
+ }
}</code></pre>
<p>
@@ -111,6 +122,88 @@ void main() {
<code>Citations</code>, <code>Envelopes</code>, <code>Matrices</code> and <code>MathTransforms</code>.
</p>
+
+
+
+ <h3 id="SetMetadataElement">Direct construction via setter methods</h3>
+ <p>
+ For every getter method, there is a corresponding setter method.
+ However the setter methods are not defined in the GeoAPI interfaces, which are read-only.
+ For invoking setter methods, it is necessary to use the Apache <abbr>SIS</abbr> implementation classes directly.
+ It is straightforward when the metadata objects are created and populated in the same code, as there is nothing special to do.
+ The following example creates a citation using three different ways to specify a value:
+ at construction time using convenience constructors,
+ using setter methods,
+ and by adding elements directly in the collections, which are modifiable.
+ </p>
+<pre><code>import org.apache.sis.metadata.iso.DefaultIdentifier;
+import org.apache.sis.metadata.iso.citation.DefaultCitation;
+import org.opengis.metadata.citation.PresentationForm; // A code list.
+
+void main() {
+ // Following constructor is a convenience for setting the `title` property at construction time.
+ var citation = new DefaultCitation("Climate Change 2022: Impacts, Adaptation, and Vulnerability");
+ citation.getPresentationForms().add(PresentationForm.DOCUMENT_DIGITAL);
+
+ var identifier = new DefaultIdentifier();
+ identifier.setCode("10.1017/9781009325844");
+ identifier.setCodeSpace("DOI");
+ citation.getIdentifiers().add(identifier);
+
+ // Do not allow the citation to be modified after this point (optional).
+ citation.transitionTo(DefaultCitation.State.FINAL);
+ System.out.println(citation);
+}</code></pre>
+
+ <p>
+ Output is as below:
+ </p>
+
+<pre><samp>Citation……………………………………… Climate Change 2022: Impacts, Adaptation, and Vulnerability
+ ├─Identifier……………………… 10.1017/9781009325844
+ │ └─Code space…………… DOI
+ └─Presentation form…… Document digital</samp></pre>
+
+ <p>
+ Often, the newly created metadata will be reused many times.
+ It may be for example a static final constant, or a cached value.
+ In such case, it may be desirable to declare the metadata as unmodifiable after its construction.
+ This is the purpose of the call to <code class="SIS">transitionTo(State.FINAL)</code> in above example.
+ After that call, any attempt to modify the metadata will cause an <code class="SIS">UnmodifiableMetadataException</code> to be thrown.
+ </p><p>
+ Setting the values of a metadata object may be more tricky when the implementation class is unknown.
+ Since there is no setter methods in the GeoAPI interfaces, the metadata may need to be converted to
+ an Apache <abbr>SIS</abbr> implementation class first, and that instance needs to be modifiable.
+ This is a two steps process.
+ The first step can be done by invoking the static <code class="SIS">castOrCopy(…)</code> method
+ which is defined in every Apache <abbr>SIS</abbr> implementation classes.
+ For example there is
+ a <code class="SIS">DefaultCitation.castOrCopy(<code class="OGC">Citation</code>)</code> method,
+ a <code class="SIS">DefaultExtent.castOrCopy(<code class="OGC">Extent</code>)</code> method, <i>etc.</i>
+ Those methods will either return the given instance directly when possible,
+ or otherwise create a <em>shallow</em> copy of that instance (i.e., without recursive copy of children).
+ The second step can be done in different ways. An easy way (while not the most efficient)
+ is to make an unconditional <em>deep</em> copy of the metadata,
+ in case that metadata was unmodifiable (<code class="SIS">State.FINAL</code>),
+ and also (if desired) for avoiding to change the original metadata.
+ Example:
+ </p>
+
+<pre><code>import org.opengis.metadata.citation.Citation;
+import org.apache.sis.metadata.iso.citation.DefaultCitation;
+import org.apache.sis.util.SimpleInternationalString;
+
+void main() {
+ Citation original = ...; // Some pre-existing citation.
+
+ // Get a modifiable copy and change its title.
+ DefaultCitation edit = DefaultCitation.castOrCopy(original);
+ edit = (DefaultCitation) copy.deepCopy(DefaultCitation.State.EDITABLE);
+ edit.setTitle(new SimpleInternationalString("A new title"));
+}</code></pre>
+
+
+
<h3 id="MetadataAsMap">View as key-value pairs</h3>
<p>
Above static methods explore fragments of metadata tree in search for requested information,
@@ -119,13 +212,13 @@ void main() {
In such cases, one can view the metadata as a <code>java.util.Map</code> like below:
</p>
-<pre><code>
-import java.util.Map;
+<pre><code>import java.util.Map;
import org.apache.sis.metadata.MetadataStandard;
import org.apache.sis.metadata.KeyNamePolicy;
import org.apache.sis.metadata.ValueExistencePolicy;
void main() {
+ Object metadata = ...;
Map<String,Object> elements = MetadataStandard.ISO_19115.asValueMap(
metadata, // Any instance from the org.opengis.metadata package or a sub-package.
null, // Used for resolving ambiguities. We can ignore for this example.
@@ -154,6 +247,9 @@ void main() {
package javadoc.
</p>
+
+
+
<h3 id="MetadataAsTreeTable">View as tree table</h3>
<p>
A richer alternative to the view as a map is the view as a tree table.
@@ -162,19 +258,53 @@ void main() {
</p>
<table>
<caption>Columns of a tree table view of a metadata</caption>
- <tr><th>Column</th> <th>Description</th></tr>
- <tr><td><code class="SIS">IDENTIFIER</code></td> <td>The UML identifier if any, or otherwise the Java Beans name, of the metadata property.</td></tr>
- <tr><td><code class="SIS">INDEX</code></td> <td>If the property is a collection, then the zero-based index of the element in that collection.</td></tr>
- <tr><td><code class="SIS">NAME</code></td> <td>A human-readable name for the node, derived from above identifier and index.</td></tr>
- <tr><td><code class="SIS">TYPE</code></td> <td>The base type of the value (usually a GeoAPI interface).</td></tr>
- <tr><td><code class="SIS">VALUE</code></td> <td>The metadata value for the node. This column may be writable.</td></tr>
- <tr><td><code class="SIS">NIL_REASON</code></td> <td>If the value is mandatory and nevertheless absent, the reason why.</td></tr>
- <tr><td><code class="SIS">REMARKS</code></td> <td>Remarks or warning on the property value.</td></tr>
+ <tr><th>Column</th> <th>Description</th> <th>Writable</th></tr>
+ <tr><td><code class="SIS">IDENTIFIER</code></td> <td>The UML identifier if any, or otherwise the Java Beans name, of the metadata property.</td><td></td></tr>
+ <tr><td><code class="SIS">INDEX</code></td> <td>If the property is a collection, then the zero-based index of the element in that collection.</td><td></td></tr>
+ <tr><td><code class="SIS">NAME</code></td> <td>A human-readable name for the node, derived from above identifier and index.</td><td></td></tr>
+ <tr><td><code class="SIS">TYPE</code></td> <td>The base type of the value (usually a GeoAPI interface).</td><td></td></tr>
+<!-- SIS 1.5
+ <tr><td><code class="SIS">OBLIGATION</code></td> <td>Whether the property is mandatory, optional or conditional.</td><td></td></tr>
+-->
+ <tr><td><code class="SIS">VALUE</code></td> <td>The metadata value for the node. This column may be writable.</td><td>✓</td></tr>
+<!-- SIS 1.5
+ <tr><td><code class="SIS">NIL_REASON</code></td> <td>If the value is mandatory and nevertheless absent, the reason why.</td><td>✓</td></tr>
+-->
+ <tr><td><code class="SIS">REMARKS</code></td> <td>Remarks or warning on the property value.</td><td></td></tr>
</table>
<p>
Tree table views are obtained in a way similar to <a href="#MetadataAsMap">map views</a>,
- but using the <code class="SIS">asTreeTable(Object)</code> method instead of <code class="SIS">asValueMap(Object)</code>.
+ but using the <code class="SIS">asTreeTable(…)</code> method instead of <code class="SIS">asValueMap(…)</code>.
+ Values can be obtained for each column, and can be set for the <code class="SIS">VALUE</code> column
+ if the underlying metadata object is modifiable.
+ The following example prints the values of the <code class="SIS">NAME</code> and <code class="SIS">TYPE</code>
+ columns for a given metadata and all its children:
</p>
+
+<pre><code>import org.apache.sis.metadata.MetadataStandard;
+import org.apache.sis.metadata.ValueExistencePolicy;
+import org.apache.sis.util.collection.TreeTable;
+import org.apache.sis.util.collection.TableColumn;
+
+class Explorer {
+ void main() {
+ Object metadata = ...;
+ TreeTable table = MetadataStandard.ISO_19115.asTreeTable(
+ metadata, // Any instance from the org.opengis.metadata package or a sub-package.
+ null, // Used for resolving ambiguities. We can ignore for this example.
+ ValueExistencePolicy.NON_EMPTY); // Entries with null or empty values will be omitted.
+
+ // Print the names and types of all metadata elements having a value.
+ printRecursively(table.getRoot());
+ }
+
+ private static void printRecursively(TreeTable.Node node) {
+ String name = node.getValue(TableColumn.NAME);
+ Class<?> type = node.getValue(TableColumn.TYPE);
+ System.out.println(name + " : " + type.getSimpleName());
+ node.getChildren().forEach(Explorer::printRecursively);
+ }
+}</code></pre>
</section>
</body>
</html>
diff --git a/content/developer-guide/metadata/NilReason.html b/content/developer-guide/metadata/NilReason.html
index 274da300..e910a6f7 100644
--- a/content/developer-guide/metadata/NilReason.html
+++ b/content/developer-guide/metadata/NilReason.html
@@ -53,16 +53,70 @@
<tr><td><code class="OGC">missing</code></td> <td>The value cannot exist.</td></tr>
<tr><td><code class="OGC">withheld</code></td> <td>The value cannot be revealed.</td></tr>
<tr><td><code class="OGC">template</code></td> <td>The value will be available later.</td></tr>
+ <tr><td><code class="OGC">other</code></td> <td>None of the above. Can be completed by user-suplied strings.</td></tr>
</table>
<p>
The transmission of this information requires the use of a non-null object, even when the value is missing.
- In such case, <abbr>SIS</abbr> will return an object that, besides implementing the desired GeoAPI interface,
- also implements the <code>org.apache.sis.xml.NilObject</code> interface.
+ In such case, Apache <abbr>SIS</abbr> will return an object that, besides implementing the desired GeoAPI interface,
+ also implements the <code class="SIS">NilObject</code> interface.
This interface flags the instances where all methods return an empty collection, an empty table, <code>null</code>,
<code>NaN</code>, <code>0</code> or <code>false</code>, in this preference order, as permitted by the return types of the methods.
- Each instance that implements <code>NilObject</code> provides a <code class="SIS">getNilReason()</code> method
+ Each instance that implements <code class="SIS">NilObject</code> provides a <code class="SIS">getNilReason()</code> method
indicating why the object is nil.
+ For example, the following code specifies that a citation title is missing
+ because this metadata is only a template to be completed by the user:
</p>
+
+<pre><code>import org.opengis.util.InternationalString;
+import org.apache.sis.metadata.iso.citation.DefaultCitation;
+import org.apache.sis.xml.NilReason;
+
+void main() {
+ InternationalString nil = NilReason.TEMPLATE.createNilObject(InternationalString.class);
+ var citation = new DefaultCitation(nil);
+
+ // Verify the reason that we have just set.
+ System.out.println("Title: " + citation.getTitle());
+ NilReason reason = NilReason.forObject(citation.getTitle());
+ System.out.println("Reason why the title is missing: " + reason);
+}</code></pre>
+
+ <p>
+ Output is as below (note that the title is empty, not null):
+ </p>
+
+<pre><samp>Title:
+Reason why the title is missing: template</samp></pre>
+
+<!-- SIS 1.5
+ <p>
+ Alternatively, if the metadata instance is known to be a subclass of <code class="SIS">AbstractMetadata</code>,
+ then the following substitutions can be done in the above example.
+ The advantage is that the <code class="SIS">nilReasons()</code> map works for a few more types
+ than what <code class="SIS">NilReason.createNilObject(Class)</code> can support, for example <code>Boolean</code>.
+ The inconvenient is that there is less compile-time checks, because properties are identified by character strings.
+ </p>
+ <div class="table">
+ <div class="row">
+ <div class="cell"><code><code class="SIS">NilReason.forObject</code>(citation.<code class="API">getTitle()</code>)</code></div>
+ <div class="cell">⟶</div>
+ <div class="cell"><code>citation.<code class="SIS">nilReasons()</code>.get(<code class="OGC">"title"</code>)</code></div>
+ </div>
+ <div class="row">
+ <div class="cell"><code>citation.<code class="SIS">setTitle</code>(nilReason.<code class="SIS">createNilObject</code>(<code class="OGC">InternationalString</code>.class))</code></div>
+ <div class="cell">⟶</div>
+ <div class="cell"><code>citation.<code class="SIS">nilReasons()</code>.put(<code class="OGC">"title"</code>, nilReason)</code></div>
+ </div>
+ </div>
+ <p>
+ The <code class="SIS">nilReasons()</code> is also useful for checking if there is any mandatory property without value.
+ That map will alway contain an entry for such cases, even if the associated nil reason is <code>null</code>.
+ By contrast, optional properties are contained in the map only if they are associated to a non-null nil reason.
+ Consequently, <code>metadata.<code class="SIS">nilReasons()</code>.contains(null)</code> is true if the metadata
+ contains at least one mandatory property with no value and no nil reason.
+ </p>
+-->
+
</section>
</body>
</html>
diff --git a/content/developer-guide/metadata/index.html b/content/developer-guide/metadata/index.html
index a6e811b0..16d559d5 100644
--- a/content/developer-guide/metadata/index.html
+++ b/content/developer-guide/metadata/index.html
@@ -103,8 +103,7 @@
A metadata may be created programmatically like below:
</p>
-<pre><code>
-import org.apache.sis.metadata.iso.citation.DefaultCitation;
+<pre><code>import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.opengis.metadata.citation.PresentationForm;
void main() {
diff --git a/static/book/book.css b/static/book/book.css
index 09751e9c..4b9f6e45 100644
--- a/static/book/book.css
+++ b/static/book/book.css
@@ -281,6 +281,20 @@ div.row-of-boxes > div {
padding: 6px 30px;
}
+div.table {
+ display: table;
+}
+
+div.row {
+ display: table-row;
+}
+
+div.cell {
+ display: table-cell;
+ padding-left: 21px;
+ padding-right: 21px;
+}
+
pre {
margin-top: 21px;
margin-bottom: 21px;