EXPORT_C void MTe_LbsPsyStaticData::PrintPosInfo(const TPositionInfo& aPosInfo) const
	{	
	_LIT(KTimeFormat, "%H:%T:%S.%C");
	TBuf<100> cTimeStr;
	
	INFO_PRINTF2(_L("classSize=%d"), aPosInfo.PositionClassSize());
	INFO_PRINTF2(_L("classType=0x%x"), aPosInfo.PositionClassType());
	INFO_PRINTF2(_L("moduleId=0x%x"), aPosInfo.ModuleId());
	INFO_PRINTF2(_L("updateType=%d"), aPosInfo.UpdateType());
	INFO_PRINTF2(_L("positionMode=%d"), aPosInfo.PositionMode());
	INFO_PRINTF2(_L("positionModeReason=%d"), aPosInfo.PositionModeReason());
	
	TPosition pos;
	aPosInfo.GetPosition(pos);
	INFO_PRINTF2(_L("pos altitude=%f"), pos.Altitude());
	INFO_PRINTF2(_L("pos latitude=%f"), pos.Latitude());
	INFO_PRINTF2(_L("pos longitude=%f"), pos.Longitude());
	INFO_PRINTF2(_L("pos datum=0x%x"), pos.Datum());
	INFO_PRINTF2(_L("pos horAccuracy=%f"), pos.HorizontalAccuracy());
	INFO_PRINTF2(_L("pos verAccuracy=%f"), pos.VerticalAccuracy());
						
	TRAP_IGNORE(pos.Time().FormatL(cTimeStr, KTimeFormat);)
TInt CPositionRequest::PackPositionData()
    {
    TPositionInfo& info = PositionInfo(iPositionBuffer);

    // Verify that ModuleId, set by PSY, is correct if using specific PSY.
    // If a proxy PSY is used, the proxy is responsible for verifying UID.
    if (!iHasProxyPositioner &&
        info.ModuleId() != iPositionerParams.iImplementationUid)
        {
        return KErrGeneral;
        }

    // Check that datum type still is WGS84
    TPosition position;
    info.GetPosition(position);
    if (position.Datum() != KPositionDatumWgs84)
        {
        return KErrNotSupported;
        }

    TPtr8 ptrToBuffer = iPositionBuffer->Des();
    return Global::Write(iMessage, KParamPositionInfo, ptrToBuffer);
    }
Ejemplo n.º 3
0
EXPORT_C TBool T_LbsUtils::Compare_PosInfo(const TPositionInfoBase& aPosInfoSideA, const TPositionInfoBase& aPosInfoSideB, TComparisonAccuracyType aCmpAccuracy)
	{
	// TODO compare base class items, such as module id, position mode, etc.

	TUint32 typeA = aPosInfoSideA.PositionClassType();
	TUint32 typeB = aPosInfoSideB.PositionClassType();
	
	// Compare TPositionInfo type items.
	if(typeA & typeB & EPositionInfoClass)
		{
		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionInfoClass");
		const TPositionInfo& posInfoSideA = reinterpret_cast<const TPositionInfo&>(aPosInfoSideA);
		const TPositionInfo& posInfoSideB = reinterpret_cast<const TPositionInfo&>(aPosInfoSideB);
		
		TPosition posSideA;
		TPosition posSideB;
		posInfoSideA.GetPosition(posSideA);
		posInfoSideB.GetPosition(posSideB);

		// Carry out an exact check when comparing items.
		if (EExactAccuracy == aCmpAccuracy)
			{
			TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Comparing positions for exact match");
			// Compare latitude. 
			if (Math::IsNaN(posSideA.Latitude()) && Math::IsNaN(posSideB.Latitude()))
				;
			else if (posSideA.Latitude() != posSideB.Latitude())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Latitudes %d and %d respectively", posSideA.Latitude(), posSideB.Latitude());
				return EFalse;
				}
			
			// Compare longitude.
			if (Math::IsNaN(posSideA.Longitude()) && Math::IsNaN(posSideB.Longitude()))
				;
			else if (posSideA.Longitude() != posSideB.Longitude())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Longitudes %d and %d respectively", posSideA.Longitude(), posSideB.Longitude());
				return EFalse;
				}		
			
			// Compare altitude.
			if (Math::IsNaN(posSideA.Altitude()) && Math::IsNaN(posSideB.Altitude()))
				;
			else if (posSideA.Altitude() != posSideB.Altitude())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Altitudes %d and %d respectively", posSideA.Altitude(), posSideB.Altitude());				
				return EFalse;
				}
			
			// Compare datum.
			if (posSideA.Datum() != posSideB.Datum())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Datums %d and %d respectively", posSideA.Datum(), posSideB.Datum());				
				return EFalse;
				}				
			
			// Compare horizontal accuracy.
			if (Math::IsNaN(posSideA.HorizontalAccuracy()) && Math::IsNaN(posSideB.HorizontalAccuracy()))
				;
			else if (posSideA.HorizontalAccuracy() != posSideB.HorizontalAccuracy())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Horizontal Accuracies %d and %d respectively", posSideA.HorizontalAccuracy(), posSideB.HorizontalAccuracy());				
				return EFalse;
				}		
			
			// Compare vertical accuracy.
			if (Math::IsNaN(posSideA.VerticalAccuracy()) && Math::IsNaN(posSideB.VerticalAccuracy()))
				;
			else if (posSideA.VerticalAccuracy() != posSideB.VerticalAccuracy())
				{
				TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match!");
				TESTLOG3(ELogP1, "Vertical Accuracies %d and %d respectively", posSideA.VerticalAccuracy(), posSideB.VerticalAccuracy());				
				return EFalse;
				}		
			}
		else
			{
			// Check latitude + longitude using horz accuracy.
			TReal horzAct = posSideA.HorizontalAccuracy(); // Use the verify accuracy value (which is side A).
			TReal distance ;			
	
			TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Comparing positions for 'rough' match");			
		//	if(NAN != horzAct)
				{
				// The following is a temporary patch until TPositionInfo.Distance() is implemented:				
/* 
	from http://www.movable-type.co.uk/scripts/GIS-FAQ-5.1.html
	
	presuming a spherical Earth with radius R (see below), and the locations of the two points in spherical coordinates (longitude and latitude) are lon1,lat1 and lon2,lat2 then the

	Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159):

	dlon = lon2 - lon1
	dlat = lat2 - lat1
	a = sin^2(dlat/2) + cos(lat1) * cos(lat2) * sin^2(dlon/2)
	c = 2 * arcsin(min(1,sqrt(a)))
	d = R * c

	will give mathematically and computationally exact results. 
	
*/				
				const TReal pi = 3.141592653589793;
				const TReal earthRadius = 6367 * 1000;	// earth radius in metres
				
				TReal32 latA = posSideA.Latitude() * (pi/180);
				TReal32 latB = posSideB.Latitude() * (pi/180);
				TReal32 lonA = posSideA.Longitude() * (pi/180);
				TReal32 lonB = posSideB.Longitude() * (pi/180);
				
				TReal dlon = (lonB - lonA);	
				TReal dlat = (latB - latA);
				TReal sin_half_dlat, sin_half_dlon, coslatA, coslatB;
				
				Math::Sin(sin_half_dlat, dlat/2);
				Math::Sin(sin_half_dlon, dlon/2);
				Math::Cos(coslatA, latA);
				Math::Cos(coslatB, latB);
				
				TReal a = (sin_half_dlat * sin_half_dlat) + (coslatA * coslatB * (sin_half_dlon * sin_half_dlon));
				TReal sqrt_a;
				Math::Sqrt(sqrt_a, a);
				TReal arcsinmin;
				
				TReal min = Min(static_cast<TReal>(1), sqrt_a);
				Math::ASin(arcsinmin, min);
				
				distance = earthRadius * (2 * arcsinmin);
				
				//__ASSERT_ALWAYS(!Math::IsNaN(distance), User::Panic(_L("Lbs Test Utils"), KErrGeneral));
				if(Math::IsNaN(latA) || Math::IsNaN(lonA) || Math::IsNaN(horzAct))
					{	
					TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match because contains NaNs!");	
					return EFalse;			
					}
				else if(distance > horzAct + 30)	// lrm allow for 30m discrepency for now TO DO figure out whether we should be able to check finer accuracy
					{
					TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Positions don't match because distance greater than reported accuracy + margin!");
					return EFalse;
					}
				}
				
			/*	put back later:	
			TReal32 horzAct = posSideA.HorizontalAccuracy(); // Use the verify accuracy value (which is side A).
			TReal32 distance ;			
			
			posSideA.Distance(posSideB, distance);
			if (distance > horzAct)
				return EFalse;
		
			// Check altitude using vert accuracy.
			TReal32 vertAct = posSideA.VerticalAccuracy(); // Use the verify accuracy value (which is side A).
			TReal32 height = Abs(posSideA.Altitude() - posSideB.Altitude());
			if (height > vertAct)
				return EFalse;
			*/
			
			}
			
		// TODO, we don't compare times, not sure if this is something we would do later on
//		if (posSideA.Time() != posSideB.Time())
//			return EFalse;
		
		return ETrue;
		}

	// Compare TPositionCourseInfo type items.		
	if (typeA & typeB & EPositionCourseInfoClass)
		{
		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionCourseInfoClass");
		// TODO
		}

	// Compare TPositionSatelliteInfo type items.
	if (typeA & typeB & EPositionSatelliteInfoClass)
		{
		TESTLOG(ELogP1, "T_LbsUtils::Compare_PosInfo() Both positions are of type EPositionSatelliteInfoClass");
		// TODO
		}

/* For extended tests when we have them.
	if (infoBase.PositionClassType() & EPositionClassTestExtension)
		{
		}
*/
	return EFalse;
	}