<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=iso-8859-1 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7600.16535"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px" 
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true" 
name="Compose message area">
<DIV><FONT color=#a70401 size=2>Martin,</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Now I need some help with the inverse 
projection.</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>After many days messing with the Albers I have 
found where the problems are but they do not make any sense.&nbsp; In the 
projection for the ellipsoids, the following line caused the returned longitude 
to always be either +/-90 which is what it is supposed to do.&nbsp; My problem 
is: why is it there at all?</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>// line 1 lpphi = lpphi &lt; 0. ? 
-ProjectionMath.HALFPI : ProjectionMath.HALFPI;</FONT><BR></DIV>
<DIV><FONT color=#a70401 size=2>When I commented it out the elliptical code gave 
me very good results over all 64K tests.</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Just to keep things interesting, when working 
with the sphere, the following line of code returned a NaN for all latitudes 
between -89 and 16 degrees.&nbsp; From 17 thru 89 degrees it returned values 
from 1.4964... through 0.2351....</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpphi 
= Math.asin(lpphi); // line 2 returns&nbsp;NaN<BR></FONT></DIV>
<DIV><FONT color=#a70401 size=2>When I replaced that line with the code used for 
the ellipsoids:</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;&nbsp;&nbsp;lpphi = (c - lpphi * 
lpphi) / n;<BR>&nbsp;&nbsp; &nbsp;lpphi = phi1_(lpphi, e, one_es));</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>the code for the sphere returned very accurate 
results.</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Although I am getting good results, this does 
not seem to be the way to do it.&nbsp; This just not make any sense.&nbsp; Over 
to you for resolution.</FONT></DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Fred</DIV></FONT>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>/*<BR>Copyright 2006 Jerry Huxtable</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Licensed under the Apache License, Version 2.0 
(the "License");<BR>you may not use this file except in compliance with the 
License.<BR>You may obtain a copy of the License at</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp; <A 
title="http://www.apache.org/licenses/LICENSE-2.0&#10;CTRL + Click to follow link" 
href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A></FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>Unless required by applicable law or agreed to 
in writing, software<BR>distributed under the License is distributed on an "AS 
IS" BASIS,<BR>WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
implied.<BR>See the License for the specific language governing permissions 
and<BR>limitations under the License.<BR>*/</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>/*<BR>&nbsp;* This file was semi-automatically 
converted from the public-domain USGS PROJ source.<BR>&nbsp;*/<BR>package 
org.osgeo.proj4j.proj;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>import java.awt.geom.*;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>import 
org.osgeo.proj4j.ProjectionMath;<BR>import 
org.osgeo.proj4j.Projection;<BR>import 
org.osgeo.proj4j.ProjectionException;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>public class AlbersProjection extends Projection 
{</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;private final static double EPS10 = 
1.e-10;<BR>&nbsp;private final static double TOL7 = 1.e-7;<BR>&nbsp;private 
double ec;<BR>&nbsp;private double n;<BR>&nbsp;private double 
c;<BR>&nbsp;private double dd;<BR>&nbsp;private double n2;<BR>&nbsp;private 
double rho0;<BR>&nbsp;private double phi1;<BR>&nbsp;private double 
phi2;<BR>&nbsp;private double[] en;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;private final static int N_ITER = 
15;<BR>&nbsp;private final static double EPSILON = 1.0e-7;<BR>&nbsp;private 
final static double TOL = 1.0e-10;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;//protected double projectionLatitude1 = 
MapMath.degToRad(45.5);<BR>&nbsp;//protected double projectionLatitude2 = 
MapMath.degToRad(29.5);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public AlbersProjection() 
{<BR>&nbsp;&nbsp;minLatitude = Math.toRadians(0);<BR>&nbsp;&nbsp;maxLatitude = 
Math.toRadians(80);<BR>&nbsp;&nbsp;projectionLatitude1 = 
ProjectionMath.degToRad(45.5);<BR>&nbsp;&nbsp;projectionLatitude2 = 
ProjectionMath.degToRad(29.5);<BR>&nbsp;&nbsp;initialize();<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;private static double phi1_(double qs, 
double Te, double Tone_es) {<BR>&nbsp;&nbsp;int i;<BR>&nbsp;&nbsp;double Phi, 
sinpi, cospi, con, com, dphi;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;Phi = Math.asin (.5 * 
qs);<BR>&nbsp;&nbsp;if (Te &lt; EPSILON)<BR>&nbsp;&nbsp;&nbsp;return( Phi 
);<BR>&nbsp;&nbsp;i = N_ITER;<BR>&nbsp;&nbsp;do {<BR>&nbsp;&nbsp;&nbsp;sinpi = 
Math.sin (Phi);<BR>&nbsp;&nbsp;&nbsp;cospi = Math.cos 
(Phi);<BR>&nbsp;&nbsp;&nbsp;con = Te * sinpi;<BR>&nbsp;&nbsp;&nbsp;com = 1. - 
con * con;<BR>&nbsp;&nbsp;&nbsp;dphi = .5 * com * com / cospi * (qs / Tone_es 
-<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sinpi / com + .5 / Te * Math.log ((1. - con) 
/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1. + con)));<BR>&nbsp;&nbsp;&nbsp;Phi += 
dphi;<BR>&nbsp;&nbsp;} while (Math.abs(dphi) &gt; TOL &amp;&amp; --i != 
0);<BR>&nbsp;&nbsp;return( i != 0 ? Phi : Double.MAX_VALUE 
);<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public Point2D.Double project(double 
lplam, double lpphi, Point2D.Double out) {<BR>&nbsp;&nbsp;double 
rho;<BR>&nbsp;&nbsp;if ((rho = c - (!spherical ? n * 
ProjectionMath.qsfn(Math.sin(lpphi), e, one_es) : n2 * Math.sin(lpphi))) &lt; 
0.)<BR>&nbsp;&nbsp;&nbsp;throw new ProjectionException("F");<BR>&nbsp;&nbsp;rho 
= dd * Math.sqrt(rho);<BR>&nbsp;&nbsp;out.x = rho * Math.sin( lplam *= n 
);<BR>&nbsp;&nbsp;out.y = rho0 - rho * Math.cos(lplam);<BR>&nbsp;&nbsp;return 
out;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public Point2D.Double 
projectInverse(double xyx, double xyy, Point2D.Double out)<BR>&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;double rho;<BR>&nbsp;&nbsp;if ((rho = 
ProjectionMath.distance(xyx, xyy = rho0 - xyy)) != 
0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;double lpphi, 
lplam;<BR>&nbsp;&nbsp;&nbsp;if (n &lt; 
0.)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;rho = -rho;<BR>&nbsp;&nbsp;&nbsp;&nbsp;xyx = 
-xyx;<BR>&nbsp;&nbsp;&nbsp;&nbsp;xyy = -xyy;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
}<BR>&nbsp;&nbsp;&nbsp;lpphi =&nbsp; rho / dd;<BR>&nbsp;&nbsp;&nbsp;if 
(!spherical)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;lpphi = (c - lpphi * lpphi) / 
n;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (Math.abs(ec - Math.abs(lpphi)) &gt; 
TOL7)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((lpphi = phi1_(lpphi, e, one_es)) == 
Double.MAX_VALUE)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new 
ProjectionException("I");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpphi = lpphi &lt; 0. ? 
-ProjectionMath.HALFPI : ProjectionMath.HALFPI;<BR>&nbsp;&nbsp;&nbsp;&nbsp; } // 
end if (!spherical)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (Math.abs(out.y = 
(c - lpphi * lpphi) / n2) &lt;= 1.)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;lpphi = Math.asin(lpphi); // line 2 
returns&nbsp;NaN<BR>&nbsp;&nbsp;&nbsp;else<BR>// line 1 lpphi = lpphi &lt; 0. ? 
-ProjectionMath.HALFPI : ProjectionMath.HALFPI;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
lplam = Math.atan2(xyx, xyy) / n;<BR>&nbsp;&nbsp;&nbsp;&nbsp; out.x = 
lplam;<BR>&nbsp;&nbsp;&nbsp;&nbsp; out.y = lpphi;<BR>&nbsp;&nbsp;&nbsp; } // end 
if ((rho = ProjectionMath<BR>&nbsp;&nbsp;&nbsp; 
else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;out.x = 
0.;<BR>&nbsp;&nbsp;&nbsp;out.y = n &gt; 0. ? ProjectionMath.HALFPI : - 
ProjectionMath.HALFPI;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;return 
out;<BR>&nbsp;&nbsp; } // end projectInverse</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public void initialize() 
{<BR>&nbsp;&nbsp;super.initialize();<BR>&nbsp;&nbsp;double cosphi, 
sinphi;<BR>&nbsp;&nbsp;boolean secant;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;phi1 = 
projectionLatitude1;<BR>&nbsp;&nbsp;phi2 = projectionLatitude2;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;if (Math.abs(phi1 + phi2) &lt; 
EPS10)<BR>&nbsp;&nbsp;&nbsp;throw new 
IllegalArgumentException("-21");<BR>&nbsp;&nbsp;n = sinphi = 
Math.sin(phi1);<BR>&nbsp;&nbsp;cosphi = Math.cos(phi1);<BR>&nbsp;&nbsp;secant = 
Math.abs(phi1 - phi2) &gt;= EPS10;<BR>&nbsp;&nbsp;//spherical = es &gt; 
0.0;<BR>&nbsp;&nbsp;if (!spherical) {<BR>&nbsp;&nbsp;&nbsp;double ml1, 
m1;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;&nbsp;if ((en = 
ProjectionMath.enfn(es)) == null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;throw new 
IllegalArgumentException("0");<BR>&nbsp;&nbsp;&nbsp;m1 = 
ProjectionMath.msfn(sinphi, cosphi, es);<BR>&nbsp;&nbsp;&nbsp;ml1 = 
ProjectionMath.qsfn(sinphi, e, one_es);<BR>&nbsp;&nbsp;&nbsp;if (secant) { /* 
secant cone */<BR>&nbsp;&nbsp;&nbsp;&nbsp;double ml2, m2;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;&nbsp;&nbsp;&nbsp;sinphi = 
Math.sin(phi2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;cosphi = 
Math.cos(phi2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;m2 = ProjectionMath.msfn(sinphi, 
cosphi, es);<BR>&nbsp;&nbsp;&nbsp;&nbsp;ml2 = ProjectionMath.qsfn(sinphi, e, 
one_es);<BR>&nbsp;&nbsp;&nbsp;&nbsp;n = (m1 * m1 - m2 * m2) / (ml2 - 
ml1);<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;ec = 1. - .5 * one_es * 
Math.log((1. - e) /<BR>&nbsp;&nbsp;&nbsp;&nbsp;(1. + e)) / 
e;<BR>&nbsp;&nbsp;&nbsp;c = m1 * m1 + n * ml1;<BR>&nbsp;&nbsp;&nbsp;dd = 1. / 
n;<BR>&nbsp;&nbsp;&nbsp;rho0 = dd * Math.sqrt(c - n * 
ProjectionMath.qsfn(Math.sin(projectionLatitude),<BR>&nbsp;&nbsp;&nbsp;&nbsp;e, 
one_es));<BR>&nbsp;&nbsp;} else {<BR>&nbsp;&nbsp;&nbsp;if (secant) n = .5 * (n + 
Math.sin(phi2));<BR>&nbsp;&nbsp;&nbsp;n2 = n + n;<BR>&nbsp;&nbsp;&nbsp;c = 
cosphi * cosphi + n2 * sinphi;<BR>&nbsp;&nbsp;&nbsp;dd = 1. / 
n;<BR>&nbsp;&nbsp;&nbsp;rho0 = dd * Math.sqrt(c - n2 * 
Math.sin(projectionLatitude));<BR>&nbsp;&nbsp;}<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;/**<BR>&nbsp; * Returns true if this 
projection is equal area<BR>&nbsp; */<BR>&nbsp;public boolean isEqualArea() 
{<BR>&nbsp;&nbsp;return true;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public boolean hasInverse() 
{<BR>&nbsp;&nbsp;return true;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;/**<BR>&nbsp; * Returns the ESPG code for 
this projection, or 0 if unknown.<BR>&nbsp; */<BR>&nbsp;public int getEPSGCode() 
{<BR>&nbsp;&nbsp;return 9822;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>&nbsp;public String toString() 
{<BR>&nbsp;&nbsp;return "Albers Equal Area";<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2>/*<BR>&nbsp;public String toString() 
{<BR>&nbsp;&nbsp;return "Lambert Equal Area 
Conic";<BR>&nbsp;}<BR>*/<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=#a70401 size=2></FONT>&nbsp;</DIV></BODY></HTML>