1
/******************************************************************************
2
* $Id: PJ.java 2092 2011-08-27 20:30:36Z desruisseaux $
5
* Purpose: Java/JNI wrappers for PROJ.4 API.
6
* Author: Martin Desruisseaux
8
******************************************************************************
9
* Copyright (c) 2011, Open Geospatial Consortium, Inc.
11
* Permission is hereby granted, free of charge, to any person obtaining a
12
* copy of this software and associated documentation files (the "Software"),
13
* to deal in the Software without restriction, including without limitation
14
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
* and/or sell copies of the Software, and to permit persons to whom the
16
* Software is furnished to do so, subject to the following conditions:
18
* The above copyright notice and this permission notice shall be included
19
* in all copies or substantial portions of the Software.
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
* DEALINGS IN THE SOFTWARE.
28
*****************************************************************************
29
* This file is a copy of a file developed in the GeoAPI "Proj.4 binding"
30
* module (http://www.geoapi.org/geoapi-proj4/index.html). If this file is
31
* modified, please consider synchronizing the changes with GeoAPI.
37
* Wraps the <a href="http://proj.osgeo.org/">Proj4</a> {@code PJ} native data structure.
38
* Almost every methods defined in this class are native methods delegating the work to the
39
* Proj.4 library. This class is the only place where such native methods are defined.
41
* In the Proj.4 library, the {@code PJ} structure aggregates in a single place information usually
42
* splitted in many different ISO 19111 interfaces: {@link org.opengis.referencing.datum.Ellipsoid},
43
* {@link org.opengis.referencing.datum.Datum}, {@link org.opengis.referencing.datum.PrimeMeridian},
44
* {@link org.opengis.referencing.cs.CoordinateSystem}, {@link org.opengis.referencing.crs.CoordinateReferenceSystem}
45
* and their sub-interfaces. The relationship with the GeoAPI methods is indicated in the
46
* "See" tags when appropriate.
48
* @author Martin Desruisseaux (Geomatys)
52
* The maximal number of dimension accepted by the {@link #transform(PJ, int, double[], int, int)}
53
* method. This upper limit is actually somewhat arbitrary. This limit exists mostly as a safety
54
* against potential misuse.
56
public static final int DIMENSION_MAX = 100;
57
// IMPLEMENTATION NOTE: if the value is modified, edit also the native C file.
60
* Loads the Proj4 library.
63
System.loadLibrary("proj");
67
* The pointer to {@code PJ} structure allocated in the C/C++ heap. This value has no
68
* meaning in Java code. <strong>Do not modify</strong>, since this value is used by Proj4.
69
* Do not rename neither, unless you update accordingly the C code in JNI wrappers.
71
private final long ptr;
74
* Creates a new {@code PJ} structure from the given Proj4 definition string.
76
* @param definition The Proj.4 definition string.
77
* @throws IllegalArgumentException If the PJ structure can not be created from the given string.
79
public PJ(final String definition) throws IllegalArgumentException {
80
ptr = allocatePJ(definition);
82
throw new IllegalArgumentException(definition);
87
* Creates a new {@code PJ} structure derived from an existing {@code PJ} object.
88
* This constructor is usually for getting the
89
* {@linkplain org.opengis.referencing.crs.ProjectedCRS#getBaseCRS() base geographic CRS}
90
* from a {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
92
* @param crs The CRS (usually projected) from which to derive a new CRS.
93
* @param type The type of the new CRS. Currently, only {@link Type#GEOGRAPHIC} is supported.
94
* @throws IllegalArgumentException If the PJ structure can not be created.
96
public PJ(final PJ crs, final Type type) throws IllegalArgumentException {
98
// TODO: Use Objects with JDK 7.
99
throw new NullPointerException("The CRS must be non-null.");
101
if (type != Type.GEOGRAPHIC) {
102
throw new IllegalArgumentException("Can not derive the " + type + " type.");
104
ptr = allocateGeoPJ(crs);
106
throw new IllegalArgumentException(crs.getLastError());
111
* Allocates a PJ native data structure and returns the pointer to it. This method should be
112
* invoked by the constructor only, and the return value <strong>must</strong> be assigned
113
* to the {@link #ptr} field. The allocated structure is released by the {@link #finalize()}
116
* @param definition The Proj4 definition string.
117
* @return A pointer to the PJ native data structure, or 0 if the operation failed.
119
private static native long allocatePJ(String definition);
122
* Allocates a PJ native data structure for the base geographic CRS of the given CRS, and
123
* returns the pointer to it. This method should be invoked by the constructor only, and
124
* the return value <strong>must</strong> be assigned to the {@link #ptr} field.
125
* The allocated structure is released by the {@link #finalize()} method.
127
* @param projected The CRS from which to derive the base geographic CRS.
128
* @return A pointer to the PJ native data structure, or 0 if the operation failed.
130
private static native long allocateGeoPJ(PJ projected);
133
* Returns the version number of the Proj4 library.
135
* @return The Proj.4 release string.
137
public static native String getVersion();
140
* Returns the Proj4 definition string. This is the string given to the constructor,
141
* expanded with as much information as possible.
143
* @return The Proj4 definition string.
145
public native String getDefinition();
148
* Returns the Coordinate Reference System type.
150
* @return The CRS type.
152
public native Type getType();
155
* The coordinate reference system (CRS) type returned by {@link PJ#getType()}.
156
* In the Proj.4 library, a CRS can only be geographic, geocentric or projected,
157
* without distinction between 2D and 3D CRS.
159
* @author Martin Desruisseaux (Geomatys)
161
public static enum Type {
163
* IMPLEMENTATION NOTE: Do not rename those fields, unless you update the
164
* native C code accordingly.
168
* The CRS is of type {@link org.opengis.referencing.crs.GeographicCRS}.
169
* The CRS can be two-dimensional or three-dimensional.
174
* The CRS is of type {@link org.opengis.referencing.crs.GeocentricCRS}.
175
* The CRS can only be three-dimensional.
180
* The CRS is of type {@link org.opengis.referencing.crs.ProjectedCRS}.
181
* The CRS can be two-dimensional or three-dimensional.
187
* Returns the value stored in the {@code a_orig} PJ field.
189
* @return The axis length stored in {@code a_orig}.
191
* @see org.opengis.referencing.datum.Ellipsoid#getSemiMajorAxis()
193
public native double getSemiMajorAxis();
196
* Returns the value computed from PJ fields by {@code √((a_orig)² × (1 - es_orig))}.
198
* @return The axis length computed by {@code √((a_orig)² × (1 - es_orig))}.
200
* @see org.opengis.referencing.datum.Ellipsoid#getSemiMinorAxis()
202
public native double getSemiMinorAxis();
205
* Returns the square of the ellipsoid eccentricity (ε²). The eccentricity
206
* is related to axis length by ε=√(1-(<var>b</var>/<var>a</var>)²). The
207
* eccentricity of a sphere is zero.
209
* @return The eccentricity.
211
* @see org.opengis.referencing.datum.Ellipsoid#isSphere()
212
* @see org.opengis.referencing.datum.Ellipsoid#getInverseFlattening()
214
public native double getEccentricitySquared();
217
* Returns an array of character indicating the direction of each axis. Directions are
218
* characters like {@code 'e'} for East, {@code 'n'} for North and {@code 'u'} for Up.
220
* @return The axis directions.
222
* @see org.opengis.referencing.cs.CoordinateSystemAxis#getDirection()
224
public native char[] getAxisDirections();
227
* Longitude of the prime meridian measured from the Greenwich meridian, positive eastward.
229
* @return The prime meridian longitude, in degrees.
231
* @see org.opengis.referencing.datum.PrimeMeridian#getGreenwichLongitude()
233
public native double getGreenwichLongitude();
236
* Returns the conversion factor from the linear units to metres.
238
* @param vertical {@code false} for the conversion factor of horizontal axes,
239
* or {@code true} for the conversion factor of the vertical axis.
240
* @return The conversion factor to metres for the given axis.
242
public native double getLinearUnitToMetre(boolean vertical);
245
* Transforms in-place the coordinates in the given array. The coordinates array shall contain
246
* (<var>x</var>,<var>y</var>,<var>z</var>,…) tuples, where the <var>z</var> and
247
* following dimensions are optional. Note that any dimension after the <var>z</var> value
250
* Input and output units:
253
* <li>Angular units (as in longitude and latitudes) are decimal degrees.</li>
254
* <li>Linear units are usually metres, but this is actually projection-dependent.</li>
257
* @param target The target CRS.
258
* @param dimension The dimension of each coordinate value. Must be in the [2-{@value #DIMENSION_MAX}] range.
259
* @param coordinates The coordinates to transform, as a sequence of
260
* (<var>x</var>,<var>y</var>,<<var>z</var>>,…) tuples.
261
* @param offset Offset of the first coordinate in the given array.
262
* @param numPts Number of points to transform.
263
* @throws NullPointerException If the {@code target} or {@code coordinates} argument is null.
264
* @throws IndexOutOfBoundsException if the {@code offset} or {@code numPts} arguments are invalid.
265
* @throws PJException If the operation failed for an other reason (provided by Proj4).
267
* @see org.opengis.referencing.operation.MathTransform#transform(double[], int, double[], int, int)
269
public native void transform(PJ target, int dimension, double[] coordinates, int offset, int numPts)
273
* Returns a description of the last error that occurred, or {@code null} if none.
275
* @return The last error that occurred, or {@code null}.
277
public native String getLastError();
280
* Returns the string representation of the PJ structure.
282
* @return The string representation.
285
public native String toString();
288
* Deallocates the native PJ data structure. This method can be invoked only by the garbage
289
* collector, and must be invoked exactly once (no more, no less).
290
* <strong>NEVER INVOKE THIS METHOD EXPLICITELY, NEVER OVERRIDE</strong>.
293
protected final native void finalize();