| Programming with JViews Maps > Creating a Map Application Using the API > Handling Spatial Reference Systems > Converting Coordinates Between Coordinate Systems |
Converting Coordinates Between Coordinate Systems |
INDEX
PREVIOUS
NEXT
|
Once coordinate systems are defined, there must be some way to convert from one coordinate system to another. This is done using coordinate transformations, defined in the package ilog.views.maps.srs.coordtrans.
You will find information on the following topics:
As soon as you work with different coordinate systems and datums, you need to be able to convert from one to another. When working with coordinate systems, this can be performed using functions.
The coordinate transformations, as defined by the ilog.views.maps.srs.coordtrans.IlvCoordinateTransformation class, contain the information that allows you to manipulate them:
In addition to that, all the coordinate transformations implement the following methods:
IlvCoordinate transform(IlvCoordinate source, IlvCoordinate result)
result, or in a newly allocated coordinate if result is null. The method returns the transformed point.
IlvCoordinate[] transform(IlvCoordinate[] source, IlvCoordinate[] result)
nverse() method that returns an inverse transformation.
The following sections describe the predefined built in transformations of JViews Maps, and provide some examples of the transformation package.
To transform the coordinates from one coordinate system to another, mathematical functions are needed. These mathematical functions can be either simple straight forward functions, or more complicated transformations. The JViews Maps package includes the most elementary transformations (or transformation steps) used for coordinate conversions, and these are available in the ilog.views.maps.srs.coordtrans package.
The chaining of elementary transformations from one coordinate system to another is called a transformation path.
The static method CreateTransformation() from the class IlvCoordinateTransformation can automatically create transformation paths from coordinate systems of the ilog.views.maps.srs.coordsys package. To find the transformation paths created, refer to the following figure:
Convert from the following projected coordinate system:
to the following one:
The transformation path selected by CreateTransformation() will be:
At each step, the relevant unit conversion is added by using the affine transforms.
Note that this path is not the only existing path. It is also possible to convert from geographic coordinates to geocentric coordinates, in which case the transformation path would be:
In this section you will find information on the following topics:
The standard way to convert coordinates from one datum to another is to convert first the coordinates to geocentric coordinates, apply the datum shift and rotation parameters, and then convert them back to geographic coordinates.
As an alternative to this transform, the IlvAbridgedMoldenskyTransform class implements directly a transform derived directly from the Moldenski formulas. The Abridged form of these formulas are quite satisfactory for three-parameter transformations.
This transform can work on either 2-D (only latitude and longitude are modified), or 3-D (the ellipsoidal height of coordinates is also modified).
Affine transforms are commonly used in coordinate transformation. An affine transform is simply defined by a 4x4 double values matrix, and are applied to coordinates by multiplying them as if they were one 1x4 matrix.
Affine transforms are mainly used in JViews Maps for unit conversions in a transformation path.
Another use of affine transforms is to use them to implement Bursa Wolf transformations. The Bursa Wolf transformation is applied to geocentric coordinates to model a seven-parameter datum change. A seven-parameter datum is defined by the dX, dY, dZ axis shifts, the eX, eY, eZ rotations around the axis, and a scale factor expressed in parts per million. The matrix to use for Bursa Wolf transformation is:
There are some cases where a straightforward mathematical function cannot be found to convert from one coordinate system to another. In those cases, some elementary transformations can be chained to build the full transformation. This is typically the case when converting from a projected coordinate system P1 to another one P2, using different datums: first you need to convert coordinates from P1 to the geographic coordinate system, then apply a datum conversion on these coordinate systems, and then convert them to the final coordinate system P2.
The IlvConcatenatedTransform class allows multiple transformation steps to be chained and used as a unique transformation.
The function used to convert from geocentric to ellipsoid and the function used to convert from ellipsoid to geocentric are grouped together in the IlvGeocentricTransform class. Actually, the transformation is performed by specialized versions of this class:
The IlvProjectionTransform class implements a transformation in which an IlvProjection is used to convert coordinates from geographic coordinates to a projected coordinate system, and vice versa.
This transform encapsulates a projection, and uses the forward() method if the transformation is a forward transformation, or the inverse() method if the transformation is an inverse transformation.
This section helps you get started with coordinate transformations and coordinate systems. It is based on a simple example that illustrates the basic operations required to define the coordinate systems, and shows how to use the coordinate transformations back and forth.
This example is composed of the following steps:
The complete source code of the example on which this section is based can be found in the following file:
<installdir>/jviews-maps81/codefragments/srs/srchtml/Sample1.java
The Sample1.java file contains a very simple program that shows how to convert coordinates from geographic coordinates to a projected coordinate system, using a Mercator projection.
This class has only a static main() method, in which the coordinate systems are instantiated and the coordinate is transformed.
As our example uses coordinate systems and transformation, the relevant packages must be imported, as well as the projection package for the Mercator projection definition:
import ilog.views.maps.*; import ilog.views.maps.srs.coordsys.*; import ilog.views.maps.srs.coordtrans.*; import ilog.views.maps.projection.*; |
The first important step is to define the source and the target coordinate systems.
For the source coordinate system, some latitude and longitude coordinates expressed in degrees are needed. This is the kind of coordinate defined in a geographic coordinate system. In this example, the WGS84 coordinate is used. The WGS84 geographic coordinate system defines ellipsoidal coordinates over the standard WGS84 ellipsoid.
IlvCoordinateSystem sourceCS = IlvGeographicCoordinateSystem.WGS84; |
Now these coordinates must be changed to Mercator coordinates. Then you can create a new projected coordinate system using the Mercator projection to express coordinates. Note that the Mercator projection should use exactly the same geodetic parameters as the WGS84 geographic coordinate system. The latter is passed as the geographic coordinate system of the projected coordinate system.
In order to transform the coordinates, you need an IlvCoordinateTransformation. This is performed by calling the automatic transformation creation method:
IlvCoordinateTransformation CT = IlvCoordinateTransformation.CreateTransformation(sourceCS, targetCS); |
To convert coordinates, you just have to store the coordinates in an IlvCoordinate, and then call the transform() method of the coordinate transformation.
The transform() method takes two parameters: the first one is the source coordinate to transform, the second one is an IlvCoordinate to hold the result of the transformation. When this second parameter is null, a new IlvCoordinate is allocated and used. The method returns the result coordinate.
Of course, as in this example, it is possible to use the same IlvCoordinate as source and destination.
Note that the IlvCoordinateTransformation.transform() method may throw different kinds of exception if the transformation process leads to mathematical errors or overflows. Most of the time, when those methods are thrown, the transformation is not defined at the specified point.
The result of the transformation is now stored in the coord variable. In the following code example, the result is expressed in meters, which is the default measurement unit.
System.out.println("The Mercator coordinates of 45W 30N is "); System.out.println("x = " + (int) coord.x + " m"); System.out.println("y = " + (int) coord.y + " m"); |
| Note |
| It does not make much sense to interpret these values as distances since the center of the projection is far from the projected point, and projections do not maintain distances on a large scale |
At this point, the methodology to convert from geographic coordinates to Mercator coordinates is available.
To convert coordinates from Mercator back to geographic, use the getInverse() method, which returns the inverse transformation, if any.
To print geographic coordinates, you can use the toDMS() conversion method from the IlvAngularUnit class. This method converts an angle specified by a double value in a unit to DMS encoding.
For example, IlvAngularUnit.DEGREE.toDMS() converts an angle specified in degrees to DMS.
System.out.println("The inverse projection is " + IlvAngularUnit.DEGREE.toDMS(coord.x,false) + " " + IlvAngularUnit.DEGREE.toDMS(coord.y,true)); |
This section shows how to import an .ivl map file whose coordinate system is known into a JViews Maps manager, and how to lay graphic objects over that map. It is based on an example that loads a map of the USA projected with a Lambert Azimuthal Equal Area projection into a manager, and adds cities on top of the map. The geographic coordinates indicated by the mouse pointer as well as the name of the cities pointed to are displayed in text fields at the bottom of the window. This section also gives information about the instantiating and the parameterization of a projected coordinate system, describes how to convert data from geographic coordinates to this projected coordinate system, and how to use a view interactor.
The example is composed of the following steps:
The complete source code for this example can be found in the following file:
<installdir>/jviews-maps81/codefragments/srs/srchtml/Sample2.java
Note
The purpose of this example is to give a tutorial on how to use coordinate transformations. It does not use JViews Maps Beans such as
IlvJMouseCoordinateViewer, to integrate with a data source or for map layer management.
Since you need to convert from geographic coordinates to projected coordinates and vice versa, you need to keep an instance of these transformations. This is performed by means of the createTransformations() method.
First, initialize an instance of the projection used in the coordinate system of the imported map. In this example, the usa.ivl file is in Lambert Azimuthal Equal Area projection.
The projection parameters are:
Name of the Projection |
Lambert Azimuthal Equal Area |
Central Meridian |
100DW |
Central parallel |
40DN |
Measurement unit |
Meters (the default value) |
Offset |
0 (the default value) |
For more information on projection parameters see the section Projection Parameters.
Note that projection parameters are always specified using kernel units. In this case, the central meridian and parallel have to be specified in radians. Use the method IlvAngularUnit.RADIAN.fromDMS() to achieve this goal.
Once the Lambert Azimuthal projection has been initialized, you only have to create the corresponding projected coordinate system:
// Create the projected coordinate system. IlvProjectedCoordinateSystem projectedCS = new IlvProjectedCoordinateSystem("Lambert Azimutal Equal Area", projection); |
You also create a geographic coordinate system whose ellipsoid is a simple sphere:
// Create the geographic coordinate system. IlvGeographicCoordinateSystem geoCS = new IlvGeographicCoordinateSystem(IlvHorizontalShiftDatum.SPHERE_WGS84, IlvMeridian.GREENWICH); |
Finally, create the coordinate transformation and store also the inverse transformation for future quick reference:
// A coordinate transform. geo2projCT = IlvCoordinateTransformation.CreateTransformation(geoCS,projectedCS); // The inverse transform. proj2geoCT = geo2projCT.getInverse(); |
The addCitites() method adds a number of cities on top of the imported map of the United States:
The coordinate conversion is performed in the addCity() method.
First, this method converts the DMS coordinates specified as string to degrees, in order to have the longitude and latitude coordinates of each point:
Then, it computes the projected coordinates by applying the forward coordinate transformation. If the coordinates cannot be transformed (for example, because the tolerance conditions have been exceeded), the transformation may throw an exception. This is why the code is contained inside a try/catch block.
The IlvProjectionUtil.invertY() method is then called to invert the y-coordinate: in the JViews Maps manager coordinate system, the y-axis is oriented downwards, whereas, in the projection coordinate system, it is oriented upwards.
geo2projCT.transform(coordinate,coordinate); IlvPoint p = new IlvPoint((float)coordinate.x, (float)coordinate.y); IlvProjectionUtil.invertY(p); |
Note also that a new IlvPoint is allocated here. It will be used to create graphic objects (an IlvMarker) to represent the city. This graphic object is added to Layer #1 of the manager (Layer #0 contains the boundaries of the USA).
In order to track mouse position, a view interactor is used. This is performed by means of the setViewInteractor() method.
First, create a selection interactor that will be used to select cities on the map. This interactor is configured so that multiple selections are not allowed, and the map cannot be modified, which means that the user will not be able to move cities around the map. The interactor is associated with the view. Note also that the elements making up Layer #0 (that is, borders) cannot be selected either.
Then, add a listener to the interactor that will display the longitude and the latitude indicated by the mouse in the appropriate text field. To compute the latitude and the longitude, apply the inverse transformation computed previously. The result returned by this method is formatted with the IlvAngularUnit.DEGREE.toDMS() method.
Finally, add a listener to the manager. This listener will display the name of the selected city in the appropriate text field.
After you have compiled your sample, the map shown in Figure 3.30 should appear on the screen:
| Copyright © 1987-2007 ILOG S.A. All rights reserved. Documentation homepage. Legal terms. | PREVIOUS NEXT |