# Differences between ISO/OGC specifications and GeoAPI

In the following discussion, "specification 2003-73" refers to the abstract specification Spatial Referencing by Coordinates (Topic 2), while "specification 2001-009" refers to the implementation specification Coordinate Transformation Services. The later was based on a older abstract specification.

- Changes in Metadata
- Changes in Spatial Referencing by Coordinates
- Changes in Feature Geometry
- Changes in Grid Coverage

## Changes in Metadata

### Addition

- Added a new type, `InternationalString` in order to distinguish between localizable and non-localizable character strings. Not all character string should be localizable; for example Well Know Text or code name should probably be language neutral. Since the UML doesn't said which character string are localizable and which one are not, we have done our own guess.

### Omission

- Omitted the reference system package, since it duplicates ISO 19111 / OGC Topic 2.

### Changes

> (None at this time)

## Changes in Spatial Referencing by Coordinates

### Addition

- Factory and operations from the legacy 2001-009 specification have been ported to the 2003-073 specification. This is because UML diagrams found in the 2003-073 specification contains only attributes or associations, no operations. Many services found in the legacy 2001-009 specification are not available in latest UML. More specifically:

  - There was nothing like a transformation method taking a point or an array in argument and returning a transformed point or array (e.g. the legacy `CT_MathTransform` interface).
  - There was no factory at all (e.g. the legacy `CT_CoordinateTransformationFactory` interface).

- Added a `Projection` interface as a special kind of `Conversion`. Subinterfaces of `Projection` make it possible to check which kind of projection is applied (planar, cylindrical, conical...).

- Added a `Matrix` interface. The legacy 2001-09 specification defined a `PT_Matrix` interface, which is required for derivative computation.

- Added the following methods into `AxisDirection`: `inverse()` and `absolute()`.

### Omission

- Omitted the `IdentifiedObjectBase` interface, since the split between `IdentifiedObject` and `IdentifiedObjectBase` in OGC specification is mostly a workaround for introducing `IdentifiedObject` in ISO 19111 without changing ISO 19115, where a base `ReferenceSystem` is already defined.

- Union structures avoided. While it is possible to mimic C's `union` in Java, the hacks are usually unconvenient. Furthermore, `union` are not type-safe even in C. Consequently, the following structures were omitted: `CD_SecondDefiningParameter` (replaced by an API similar to the legacy `CS_Ellipsoid`).

- Removed the `DerivedCRSType` code list, since a Java expression like `(baseCRS instanceof FooCRS)` provides the same capability with more flexibility.

### Changes

- Defined `CartesianCS` as a sub-interface of `AffineCS`.

- Allows `CompoundCRS` to contains other `CompoundCRS`. This is a violation of the ISO `CompoundCRS`'s contract ("A Compound CRS is a coordinate reference system that combines two or more coordinate reference systems, none of which can itself be compound"). However, the need for this constraint is not obvious. Note also that in "Coordinate Transformation Services" (OGC document 01-009), compound CRS was specified as a pair of arbitrary CRS ("head" and "tail"). Each of them can be an other compound CRS, allowing the creation of a tree.

- Renamed `ParameterOperation` and related interfaces as `ParameterDescriptor`. Discussion on the mailing list suggested that the previous naming was confusing, since many developpers expect `OperationParameter` to contains parameter values, which is not the case. The `ParameterDescriptor` name make it more obvious that this interface contains meta-data about parameters, not the parameter value itself. Furthermore, it is consistent with naming in usage by the Java Advanced Imaging library.

- Renamed `ParameterValueGroup.getGroup()` method as `getDescriptor()` and moved it in the hierarchy up into `GeneralParameterValue`. The `getDescriptor()` name was choosen because `getGroup()` seems too restrictive, misleading (it returns an abstract definition of a group of parameters, not the actual group), and for consistency with usage in other Java extensions (e.g. JAI's `ParameterList`).

- Moved the `GeneralParameterDescriptor`, `ParameterDescriptor`, `ParameterDescriptorGroup`, `GeneralParameterValue`, `ParameterValue`, `ParameterValueGroup`, `InvalidParameterNameException`, `InvalidParameterTypeException` and `InvalidParameterValueException` interfaces from `org.opengis.referencing.operation` to `org.opengis.parameter`. With this move, GeoAPI has extended the use of these parameter classes to be shared across several implementations with different needs. This is an accident of implementation (we produced these parameter classes first. They do happen to be very expressive and a good candiate for reuse). We also considered:

  - ISO 19119 - type specification in terms of ENUM, RANGE and so on. Not enough information is publically available to proceed.
  - Grid Coverage Exchange - parameter description is simple and has been superceeded by these definitions.
  - `java.beans.ParameterDescriptor` - The Java Beans specification is well known and many tools exist for UI creation based on this specification.
  - `javax.jai.ParameterList` - Java Advanced Imaging contains a ParameterDescriptor infrastructure that has served as a guideline for how we would like to extend this work.

  In the field we are using this set of parameter classes to describe connection information for WMS, WFS and Database connections - a function that ISO 19119 - Metadata Services is supposed to fulfill.

- Moved up (in the hierarchy) the "`maximumOccurs`" attribute from `ParameterDescriptorGroup` into the `GeneralParameterDescriptor` super-interface, in order to be on per with the "`minimumOccurs`" attribute.

## Changes in Feature Geometry

### Addition

> (None at this time)

### Omission

> (None at this time)

### Changes

- Renamed `GM_Object` as `Geometry` in order to avoid ambiguity with `java.lang.Object`.

- Moved `Envelope` and `DirectPosition` in the root geometry package (`org.opengis.geometry`) since they are used in many places in most packages.

## Changes in Grid Coverage

### Addition

- In `Coverage`, added an optional `getRenderableImage` method for interoperability with Java2D.

- In `SampleDimension`, added an optional `getSampleToGeophysics` method as a generalization of `scale` and `offset` attributes.

- Added `CannotEvaluateException` as a super-class of `PointOutsideCoverageException`.

### Omission

- Exceptions `MetadataNameNotFoundException` were declared only once in the CV package, not duplicated in every packages.

- Omitted `InvalidIndexException` (replaced by `IndexOutOfBoundsException`) and `ErrorExportingGridCoverageException` (replaced by `IOException`).

### Changes

- In `Coverage`, changed `evaluateAsDouble(DirectPosition)` into `evaluate(DirectPosition, double[])` for reusing optionally pre-allocated array. This is consistent with Java usage in `Raster` for example. Same apply to all `evaluateAsFoo(DirectPosition)` methods.

- In `GridCoverage`, changed `getDataBlockAsDouble(GridRange)` into `getDataBlock(GridCoverage, double[])` for reusing optionally pre-allocated array. This is consistent with Java usage in `Raster` for example. Same apply to all `getDataBlockAsFoo(GridRange)` methods.

- Return type of `Coverage.getSource(int)` was relaxed from `GridCoverage` to `Coverage`. Instead, the return type has been constrained to `GridCoverage` only in `GridCoverage.getSource(int)`. This approach (return type covariance) was already used in "Spatial Referencing by Coordinates" (ISO 19111). It avoid forward dependency of `Coverage` toward `GridCoverage` and give more flexibility for use of `Coverage` with non-gridded data.