Exemple #1
0
int ViewportParams::polarity() const
{
    // For mercator this just gives the extreme latitudes
    // instead of the actual poles but it works fine as well:
    GeoDataCoordinates northPole( 0.0, +currentProjection()->maxLat() );
    GeoDataCoordinates southPole( 0.0, -currentProjection()->maxLat() );

    bool globeHidesN, globeHidesS;
    qreal x;
    qreal yN, yS;

    currentProjection()->screenCoordinates( northPole, this,
                                          x, yN, globeHidesN );
    currentProjection()->screenCoordinates( southPole, this,
                                          x, yS, globeHidesS );

    int polarity = 0;

    // case of the flat map:
    if ( !globeHidesN && !globeHidesS ) {
        if ( yN < yS ) {
            polarity = +1;
        }
        if ( yS < yN ) {
            polarity = -1;
        }
    }
    else {
        if ( !globeHidesN && yN < height() / 2 ) {
            polarity = +1;
        }
        if ( !globeHidesN && yN > height() / 2 ) {
            polarity = -1;
        }
        if ( !globeHidesS && yS > height() / 2 ) {
            polarity = +1;
        }
        if ( !globeHidesS && yS < height() / 2 ) {
            polarity = -1;
        }
    }

    return polarity;
}
/**
This method calculates the bearing from this locality to the
supplied locality.

@param[in] aTargetLocality is the supplied target locality.
@param[out] aBearing upon successful completion, this is set to the bearing
from this locality to aTargetLocality, in degrees  counting clockwise
relative to true north.
@param[out] aDelta upon successful completion, this is set to an estimate of the
accuracy of the calculation, in degrees relative to aBearing.
@return a Symbian OS error code.
@return KErrArgument if any of iLatitude, iLongitude,
aTargetLocality.iLatitude or aTargetLocality.iLongitude are set to NaN.
@return KErrArgument if any of iHorizontalAccuracy
or aTargetLocality.iHorizontalAccuracy are set to NaN.
@return KErrPositionIncalculable if the error circle (horizontal accuracy)
of this locality includes a pole.
@return KErrPositionIncalculable if the two localities has overlapping 
error circles.
@return KErrPositionIncalculable if the error circle of this locality 
overlaps with the error circle of aTargetLocality when projected antipodal.
*/
EXPORT_C TInt TLocality::BearingTo(const TLocality& aTargetLocality,
                                   TReal32& aBearing,
                                   TReal32& aDelta) const
	{
    if (Math::IsNaN(iLatitude) ||
        Math::IsNaN(iLongitude) ||
        Math::IsNaN(iHorizontalAccuracy) ||
        Math::IsNaN(aTargetLocality.iLatitude) ||
        Math::IsNaN(aTargetLocality.iLongitude) ||
        Math::IsNaN(aTargetLocality.iHorizontalAccuracy))
        {
        return KErrArgument;
        }

    // Validate that this locality does not include the North Pole
    TCoordinate northPole(90, 0);
    TReal64 distance;
    RETURN_IF_ERROR(Distance64(*this, northPole, distance));

    if (distance <= iHorizontalAccuracy)
        {
        return KErrPositionIncalculable;
        }

    // Validate that this locality does not include the South Pole
    TCoordinate southPole(-90, 0);
    RETURN_IF_ERROR(Distance64(*this, southPole, distance));

    if (distance <= iHorizontalAccuracy)
        {
        return KErrPositionIncalculable;
        }

    // Validate that this locality does not overlap with the target locality 
    // when target is projected antipodal.
    TCoordinate antipodalTarget(-aTargetLocality.iLatitude, 
                                aTargetLocality.iLongitude + 180);
    RETURN_IF_ERROR(Distance64(*this, antipodalTarget, distance));
    TReal64 accuracySum = iHorizontalAccuracy + 
                          aTargetLocality.iHorizontalAccuracy;

    if (distance <= accuracySum)
        {
        return KErrPositionIncalculable;
        }

    // Validate that this locality does not overlap with the target locality.
    RETURN_IF_ERROR(Distance64(*this, aTargetLocality, distance));

    if (distance <= accuracySum)
        {
        return KErrPositionIncalculable;
        }

    // Calculate the bearing
    RETURN_IF_ERROR(BearingTo(aTargetLocality, aBearing));

    // Calculate the bearing delta
    TReal64 gammaInRad;
    TReal64 sinGamma = accuracySum / distance;
    RETURN_IF_ERROR(Math::ASin(gammaInRad, sinGamma));

    aDelta = TReal32(gammaInRad * KRadToDeg);

	return KErrNone;
	}