import ilog.views.maps.projection.*; import ilog.views.maps.*; class MercatorProjection extends IlvProjection
IlvProjection
.
MercatorProjection() { super(true, true, IlvProjection.CONFORMAL); }
boolean
value
specifying whether the projection supports nonspherical ellipsoids.
In our example, this argument is set to true
since
the projection supports the equations for these ellipsoids. boolean
value
indicating whether the projection supports an inverse method. In our
example, this argument is set to true
since
the projection supports an inverse method. int
value
that indicates the geometric properties of the projection. In our
example, this argument is IlvProjection.CONFORMAL
since
the Mercator projection is conformal. forward()
method
for the Mercator projection, you must be familiar with the IlvProjection.forward()
method.IlvProjection.forward()
public
method is called by the user to project data. This method prepares
data for projection computation and scales it appropriately. It then
redirects the calls to either one of the eforward
or sForward
protected
methods which are defined in the projection subclass (the Mercator
class in our example). In most cases, the forward
method should not be overridden. [-PI;PI]
,
if longitude reduction is used (the default value). sforward()
protected method
implements the projection of a sphere. IlvProjection.forward()
,
the sForward()
method always assumes that
the radius of the sphere is 1.x
coordinate
is equal to the longitude because it is assumed that the radius of
the sphere is 1, and longitude is expressed in radians. In this case,
you do not need to change the x
value of ll
. PI/2
. y
-coordinate
of the projected data. protected void sForward(IlvCoordinate ll) throws IlvToleranceConditionException { if (Math.abs(Math.abs(ll.y) - Math.PI / 2D) <= 1e-10D) throw new IlvToleranceConditionException(); ll.y = Math.log(Math.tan(Math.PI / 4D + .5D * ll.y)); }
eforward()
protected method
is called by the IlvProjection.forward()
method
if data is projected from a nonspherical ellipsoid.eForward()
method
for your projection. If you are projecting data from a nonspherical
ellipsoid and if the projection you are using does not support this
kind of ellipsoid, the forward()
method
will throw the exception IlvUnsupportedProjectionFeature. In this case, you can use any spherical ellipsoid
or create an equivalent sphere using the appropriate conversion methods
of the class IlvEllipsoid
. eForward()
method is slightly
more complex than the sForward()
method
although their formulas are equivalent if getEllipsoid().getE()
returns 0
.
protected void eForward(IlvCoordinate ll) throws IlvToleranceConditionException { if (Math.abs(Math.abs(ll.y) - Math.PI / 2D) <= 1e-10D) throw new IlvToleranceConditionException(); double e = Math.sqrt(getEllipsoid().getES()); double sinphi = e * Math.sin(ll.y); ll.y = Math.tan (.5D * (Math.PI/2D - ll.y)) / Math.pow((1D - sinphi) / (1D + sinphi), .5D * e); ll.y = -Math.log(ll.y); }
inverse()
method
for the Mercator projection, you should be familiar with the inverse method.IlvProjection.inverse()
method
prepares the data for inversion and processes it for the appropriate
offset. In most cases, you should not have to override the IlvProjection.inverse()
method.sInverse()
or eInverse()
depending
on whether the ellipsoid is a sphere or not. [-PI;PI]
if
longitude reduction is used (the default value). sInverse()
method.
If you call the IlvProjection.inverse()
method
for a projection that does not support the inverse()
method,
the exception IlvUnsupportedProjectionFeature will be thrown. sInverse()
method can
throw the exception IlvToleranceConditionException like all the forward methods. But since the inverse
equation of the Mercator projection is defined for all the possible
values, this method does not throw any exceptions. sForward()
method,
the projection does not modify the x
value,
therefore, the inverse equation is applied only to the y
value. protected void sInverse(IlvCoordinate xy) { xy.y = Math.PI/2D - 2D * Math.atan(Math.exp(-xy.y)); }
protected void eInverse(IlvCoordinate xy) throws IlvToleranceConditionException { double ts = Math.exp(- xy.y); double e = Math.sqrt(getEllipsoid().getES()); double eccnth = .5D * e; double Phi = Math.PI/2D - 2D * Math.atan(ts); int i = 15; double dphi; do { double con = e * Math.sin (Phi); dphi = Math.PI/2D - 2D * Math.atan(ts * Math.pow((1D - con) / (1D + con), eccnth)) - Phi; Phi += dphi; } while ((Math.abs(dphi) > 1e-10D) && (--i != 0)); if (i <= 0) throw new IlvToleranceConditionException("non-convergent inverse phi2"); xy.y = Phi; }