001    /*
002     *    GeoAPI - Java interfaces for OGC/ISO standards
003     *    http://www.geoapi.org
004     *
005     *    Copyright (C) 2007-2012 Open Geospatial Consortium, Inc.
006     *    All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007     *
008     *    Permission to use, copy, and modify this software and its documentation, with
009     *    or without modification, for any purpose and without fee or royalty is hereby
010     *    granted, provided that you include the following on ALL copies of the software
011     *    and documentation or portions thereof, including modifications, that you make:
012     *
013     *    1. The full text of this NOTICE in a location viewable to users of the
014     *       redistributed or derivative work.
015     *    2. Notice of any changes or modifications to the OGC files, including the
016     *       date changes were made.
017     *
018     *    THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019     *    NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020     *    TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021     *    THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022     *    PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023     *
024     *    COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025     *    CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026     *
027     *    The name and trademarks of copyright holders may NOT be used in advertising or
028     *    publicity pertaining to the software without specific, written prior permission.
029     *    Title to copyright in this software and any associated documentation will at all
030     *    times remain with copyright holders.
031     */
032    package org.opengis.geometry;
033    
034    
035    /**
036     * Specifies the precision model of the {@linkplain DirectPosition direct positions}
037     * in a {@linkplain Geometry geometry}.
038     * <p>
039     * A precision model defines a grid of allowable points. The {@link #round} method
040     * allows to round a direct position to the nearest allowed point. The {@link #getType}
041     * method describes the collapsing behavior of a direct position.
042     * <p>
043     * {@code Precision} instances can be sorted by their {@linkplain #getScale scale}.
044     * </p>
045     *
046     * @author Jody Garnett
047     * @since GeoAPI 2.1
048     */
049    public interface Precision extends Comparable<Precision> {
050        /**
051         * Compares this precision model with the specified one. Returns -1 is this model is
052         * less accurate than the other one, +1 if it is more accurate, or 0 if they have the
053         * same accuracy.
054         *
055         * @param other Other precision model to compare against.
056         * @return a negative integer, zero, or a positive integer as this object
057         *      is less than, equal to, or greater than the other.
058         */
059        int compareTo(Precision other);
060    
061        /**
062         * Returns the maximum number of significant digits provided by this precision model..
063         * <p>
064         * Apparently this is usually used for output, note GML generation usually has its own concept
065         * of significant digits. You may be able to capture this in terms of the getScale().
066         * </p>
067         *
068         * @return number of significant digits
069         * @see #getScale()
070         *
071         * @deprecated This is redundant with {@link #getScale}.
072         */
073        @Deprecated
074        int getMaximumSignificantDigits();
075    
076        /**
077         * Multiplying factor used to obtain a precise ordinate.
078         * <p>
079         * Multiply by this value and then divide by this value to round correctly:
080         *
081         * <blockquote><pre>
082         * double scale = pm.getScale();
083         * return Math.round(value * scale) / scale;
084         * </pre></blockquote>
085         *
086         * So to round to {@code 3} significant digits we would have a scale of {@code 1000}.
087         * Tip: the number of significant digits can be computed as below:
088         *
089         * <blockquote><pre>
090         * int significantDigits = (int) Math.ceil(Math.log10(pm.getScale()));
091         * </pre></blockquote>
092         *
093         * @return Multiplying factor used before rounding.
094         */
095        double getScale();
096    
097        /**
098         * Returns the type of this precision model.
099         */
100        PrecisionType getType();
101    
102        /**
103         * Rounds a direct position to this precision model in place.
104         * <p>
105         * It is likely that a {@code Precision} instance will keep different rounding rules for different
106         * axis (example <var>x</var> & <var>y</var> ordinates may be handled differently then height),
107         * by always rounding a direct position as a whole we will enable this functionality.
108         */
109        void round(DirectPosition position);
110    }