Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Integer/Double by BigInteger/BigDecimal in metadata #87

Open
desruisseaux opened this issue Jul 18, 2023 · 6 comments
Open

Replace Integer/Double by BigInteger/BigDecimal in metadata #87

desruisseaux opened this issue Jul 18, 2023 · 6 comments
Labels
Java Specific to the Java language.

Comments

@desruisseaux
Copy link
Contributor

The ISO 19115-1 standard defines each attribute as optional, mandatory or conditional. The GeoAPI interfaces in the org.opengis.metadata packages reflects the ISO specification by allowing values to be null. Since Java primitive types such as int or double cannot be null, GeoAPI workarounds this limitation by using their wrapper classes instead, which are java.lang.Integer and java.lang.Double respectively. But those numeric values could have been made more flexible by using BigInteger and BigDecimal instead. It would avoid limitations in the magnitude of the number and in precision. It would also allows floating point values to better capture the precision intended by the data producer, which is usually in base 10 with a fixed number of fraction digits (that number can be specified to BigDecimal).. BigInteger and BigDecimal are the types used by default by some tools that generate Java code from XML schemas.

This proposal to replace java.lang.Integer and java.lang.Double by java.math.BigInteger and java.math.BigDecimal is for metadata only, because performance is usually not an issue in metadata (contrarily to referencing, features or coverages) and wrapper classes were already used in metadata anyway (we are not proposing to replace primitive type usages).

@desruisseaux desruisseaux added the Java Specific to the Java language. label Jul 18, 2023
@desruisseaux
Copy link
Contributor Author

Duplicates #46. A possible compromise may be BigInteger for counts, Quantity<?> for real numbers with units of measurement, Number for the rest.

@paulushub
Copy link

Well the reference is MD_FeatureTypeInfo.featureInstanceCount using 32-bit integer.
BigInteger is, however, unlimited. Do you really need that for a feature count?
Where it cannot be 32-bit integer, normally the 64-bit integer (long) is used.
Is long also insufficient in this case?

@desruisseaux
Copy link
Contributor Author

Indeed, I'm not aware of dataset with a feature count greater than 2⁶³. But the amount of geospatial data collected daily by remote sensors is so large (some Tb per day if I remember correctly), that the need for larger numbers may not be so unlikely. Keeping in mind that this is only metadata and may be describing data that are not actually on the machine.

As another reason, the use of BigInteger would be a lot for symmetry with BigDecimal.

Another reason not mentioned is that BigInteger is non-final, therefore libraries can create their own subclasses with additional information. A use-case is the support of GML nilReason, which said why a value is missing (one of: inapplicable, missing, template, unknown, withheld, other). We have no mechanism in GeoAPI for describing that, as nilReason is not defined by abstract standards (I think that it is GML-specific). For an implementation wanting to carry this information, one possible way is to create a subclass of BitInteger representing the value 0 but with additional implementation-specific attributes saying that the information is missing. I'm advocating for this approach as it also has drawbacks (users can confuse the value with a real zero). But it is an example of case where using a non-final class may be helpful for some implementations.

@paulushub
Copy link

paulushub commented Feb 22, 2025

Another reason not mentioned is that BigInteger is non-final, therefore libraries can create their own subclasses with additional information.

I do not know, but it reads like rather using Number, which is also extended by BigInteger and BigDecimal. This leaves it to the implementations to decide what to return.
Extending BigInteger to create a missing value does not sound like a good idea to me.

Also, the fields of BigInteger are final with the exception of the cacheable fields, which are now depreciated in a move to immutable type (with the actual mutable form of BigInteger, the MutableBigInteger class, available for internal uses only and does not extend BigInteger).

@desruisseaux
Copy link
Contributor Author

Yes, I agree that extending BigInteger would be a very questionable practice, which is why I do not really take it as an argument.

On the other side, Number is more generic than desired, as it can be both integers and real numbers. The ideal would have been an abstract base class for all integers, distinct from real numbers, but we don't have that in Java.

@paulushub
Copy link

The ideal would have been an abstract base class for all integers, distinct from real numbers, but we don't have that in Java.

Thanks for the tip. .NET does not have an equivalent of Number, and I am providing an interface, INumber for that.
Adding Integer and Decimal or Float, abstract classes might be a good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java Specific to the Java language.
Projects
None yet
Development

No branches or pull requests

2 participants