順投影を書く
メルカトル図法の順関数を書く前に、IlvProjection::forward 関数について理解しておく必要があります。
IlvProjection::forward 関数
IlvProjection::forward パブリック関数は、データの投影を行うユーザーが呼び出します。この関数は投影計算のためにデータを用意し、適切に調整します。その後、呼び出しを投影サブクラス (この例ではメルカトル図法クラス) に定義された、eForward または sForward のいずれかの保護された関数に振り替えます。
IlvProjection::forward 関数:
座標が地心の場合、緯度を調整します。
経度を投影図法の中央経線に合わせます。
経度換算を使っている場合に (デフォルト値)、経度を範囲
[-PI;PI] に合わせます。
地球を球体で表すか、楕円で表すかによって、
sForward 関数か、または
eForward 関数を呼び出します。次に、
投影済みデータを楕円の寸法とデカルト座標オフセットに調整して、指定した測定単位に変換します。
球形からデータを投影する
sForward 保護関数は、球形の投影図法を実装します。
IlvProjection::forward 関数によって適切なスケーリングが行われるため、sForward 関数では、常に球体の半径を 1 とします。
この例の場合、メルカトル図法は赤道に接する円筒上の球体の投影図法です。球体の半径を 1 と仮定するため、x 座標は経度 (ラジアンで表す) に等しくなります。この場合、x 値の ll は変更不要です。
メルカトル図法では、極地付近の領域を表示できないため、緯度が PI/2 に近すぎる場合は、エラー・コードを返します。
次の方程式を使って、投影済みデータの y 座標を計算します。
IlvMapsError
Mercator::sForward(IlvCoordinate& ll) const
{
// Return an error if the point is close to a pole.
if (fabs(fabs(ll.y()) - IlvMaps::Pi() / 2.)<= 1e-10)
return ToleranceConditionError();
ll.setY(log(tan(IlvMaps::Pi() / 4. + 0.5 * ll.y())));
return IlvMaps::NoError();
楕円からデータを投影する
eForward 保護関数は、データが非球形の楕円から投影されている場合に、IlvProjection::forward 関数で呼び出します。
投影図法に
eForward 関数を実装する必要はありません。非球形の楕円からデータを投影する場合で、使用する投影図法がこの種の楕円をサポートしない場合は、
forward 関数が、
IlvProjection::UnsupportedFeatureError() で与えられるエラー・コードを返します。この場合、球体の楕円を使うか、または
IlvEllipsoid クラスの、適切な変換関数を使って相当する球形を作成することができます。
getEllipsoid()->getE() が 0 を返す場合、式の結果は同じですが、eForward 関数は sForward 関数よりも若干複雑になります。
IlvMapsError
Mercator::eForward(IlvCoordinate& ll) const
{
// Return an error if the point is close to a pole.
if (fabs(fabs(ll.y()) - IlvMaps::Pi() / 2.)<= 1e-10)
return ToleranceConditionError();
IlvDoublee = sqrt(getEllipsoid()->getES());
IlvDouble sinphi = e * sin(ll.y());
ll.setY(tan(.5 * (IlvMaps::Pi() / 2. -
ll.y())) /
pow((1. - sinphi) / (1. + sinphi),
0.5 * e));
ll.setY(-log(ll.y()));
return IlvMaps::NoError();
}
Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.