All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotoolkit.geometry.AbstractDirectPosition Maven / Gradle / Ivy

/*
 *    Geotoolkit.org - An Open Source Java GIS Toolkit
 *    http://www.geotoolkit.org
 *
 *    (C) 2001-2012, Open Source Geospatial Foundation (OSGeo)
 *    (C) 2009-2012, Geomatys
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotoolkit.geometry;

import java.util.Arrays;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import org.geotoolkit.util.XArrays;
import org.geotoolkit.util.Utilities;
import org.geotoolkit.referencing.CRS;
import org.geotoolkit.resources.Errors;

import static org.geotoolkit.util.Strings.trimFractionalPart;


/**
 * Base class for {@linkplain DirectPosition direct position} implementations. This base class
 * provides default implementations for {@link #toString}, {@link #equals} and {@link #hashCode}
 * methods.
 * 

* This class do not holds any state. The decision to implement {@link java.io.Serializable} * or {@link org.geotoolkit.util.Cloneable} interfaces is left to implementors. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.16 * * @since 2.4 * @module */ public abstract class AbstractDirectPosition implements DirectPosition { /** * Constructs a direct position. */ protected AbstractDirectPosition() { } /** * Returns always {@code this}, the direct position for this * {@linkplain org.opengis.geometry.coordinate.Position position}. * * @since 2.5 */ @Override public DirectPosition getDirectPosition() { return this; } /** * Sets this direct position to the given position. If the given position is * {@code null}, then all ordinate values are set to {@linkplain Double#NaN NaN}. *

* If this position and the given position have a non-null CRS, then the default implementation * requires the CRS to be {@linkplain CRS#equalsIgnoreMetadata equals (ignoring metadata)} * otherwise a {@link MismatchedReferenceSystemException} is thrown. However subclass may * choose to assign the CRS of this position to the CRS of the given position. * * @param position The new position, or {@code null}. * @throws MismatchedDimensionException If the given position doesn't have the expected dimension. * @throws MismatchedReferenceSystemException If the given position doesn't use the expected CRS. * * @since 3.16 (derived from 2.5) */ public void setLocation(final DirectPosition position) throws MismatchedDimensionException { final int dimension = getDimension(); if (position != null) { ensureDimensionMatch("position", position.getDimension(), dimension); final CoordinateReferenceSystem crs = getCoordinateReferenceSystem(); if (crs != null) { final CoordinateReferenceSystem other = position.getCoordinateReferenceSystem(); if (other != null && !CRS.equalsIgnoreMetadata(crs, other)) { throw new IllegalArgumentException(Errors.format( Errors.Keys.MISMATCHED_COORDINATE_REFERENCE_SYSTEM)); } } for (int i=0; iWell Known Text (WKT) format. * The output is like below: * *

{@code POINT(}{@linkplain #getCoordinate() ordinates}{@code )}
* * The output of this method can be * {@linkplain GeneralDirectPosition#GeneralDirectPosition(String) parsed} by the * {@link GeneralDirectPosition} constructor. */ @Override public String toString() { return toString(this); } /** * Formats a {@code POINT} element from a direct position. This method formats the given * position in the Well Known Text (WKT) format. The output is like below: * *
{@code POINT(}{@linkplain DirectPosition#getCoordinate() ordinates}{@code )}
* * The output of this method can be * {@linkplain GeneralDirectPosition#GeneralDirectPosition(String) parsed} by the * {@link GeneralDirectPosition} constructor. * * @param position The position to format. * @return The position as a {@code POINT} in WKT format. * * @see GeneralDirectPosition#GeneralDirectPosition(String) * @see org.geotoolkit.measure.CoordinateFormat * @see org.geotoolkit.io.wkt * * @since 3.09 */ public static String toString(final DirectPosition position) { final StringBuilder buffer = new StringBuilder("POINT("); final int dimension = position.getDimension(); for (int i=0; i= length) return null; if (Character.isJavaIdentifierStart(c = wkt.charAt(i))) { do if (++i >= length) return null; while (Character.isJavaIdentifierPart(c = wkt.charAt(i))); } } while (Character.isWhitespace(c)); /* * Skip the opening parenthesis, and the following whitespaces if any. * We remember the matching parenthesis since we will look for it later. * Note: we use character ' ' for "end of string". */ char close = ' '; if (c == '(' || c == '[') { close = (c == '(') ? ')' : ']'; do if (++i >= length) { c = ' '; break; } while (Character.isWhitespace(c = wkt.charAt(i))); } /* * Index i is either at the beginning of a number, at the closing parenthesis or at the end * of string (in any cases we are not at a whitespace). Now process every space-separated * ordinates until we reach the closing parenthesis or the end of string. */ double[] ordinates = new double[2]; int dimension = 0; scan: while (true) { if (c == close) { /* * We have reached the closing parenthesis. Having any non-whitespace * character after this one is an error. Otherwise we are done. */ while (++i < length) { if (!Character.isWhitespace(c = wkt.charAt(i))) { throw new IllegalArgumentException(Errors.format( Errors.Keys.UNPARSABLE_STRING_$2, wkt, wkt.substring(i))); } } break scan; } /* * We are at the beginning of a number. Find where the number ends (at * the first whitespace or closing parenthesis), parse it and store it. */ final int start = i; do if (++i >= length) { i = length; c = ' '; break; } while (!Character.isWhitespace(c = wkt.charAt(i)) && c != close); if (dimension == ordinates.length) { ordinates = Arrays.copyOf(ordinates, dimension*2); } ordinates[dimension++] = Double.parseDouble(wkt.substring(start, i)); /* * Skip whitespaces. If we reach the end of string without finding * the closing parenthesis, check if we were suppose to have any. */ while (Character.isWhitespace(c)) { if (++i >= length) { if (close != ' ') { throw new IllegalArgumentException(Errors.format( Errors.Keys.NON_EQUILIBRATED_PARENTHESIS_$2, wkt, close)); } break scan; } c = wkt.charAt(i); } } return XArrays.resize(ordinates, dimension); } /** * Returns a hash value for this coordinate. * * @return A hash code value for this position. */ @Override public int hashCode() { return hashCode(this); } /** * Returns a hash value for the given coordinate. */ static int hashCode(final DirectPosition position) { final int dimension = position.getDimension(); int code = 1; for (int i=0; i>> 32)); } final CoordinateReferenceSystem crs = position.getCoordinateReferenceSystem(); if (crs != null) { code += crs.hashCode(); } return code; } /** * Returns {@code true} if the specified object is also a {@linkplain DirectPosition * direct position} with equals {@linkplain #getCoordinate coordinate} and * {@linkplain #getCoordinateReferenceSystem CRS}. * * @param object The object to compare with this position. * @return {@code true} if the given object is equal to this position. */ @Override public boolean equals(final Object object) { if (object instanceof DirectPosition) { final DirectPosition that = (DirectPosition) object; final int dimension = getDimension(); if (dimension == that.getDimension()) { for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy