예제 #1
0
파일: Z2MPAPI.cpp 프로젝트: arksoftgit/10c
zOPER_EXPORT zSHORT OPERATION
GetDistanceRectangle( zDECIMAL *pdSouthLatitude,
                      zDECIMAL *pdEastLongitude,
                      zDECIMAL *pdNorthLatitude,
                      zDECIMAL *pdWestLongitude,
                      zDECIMAL dLatitude, zDECIMAL dLongitude,
                      zDECIMAL dDistance, zLONG lFlag )
{
   zCHAR szDecimal[ 32 ];
   ZDecimal d;
   ZDecimal d2;
   d = dDistance;

   double dDist = (double) d;
   if ( (lFlag & 0x80000000) == 0 )
      dDist /= GEO::KM2MI;   // convert to kilometers

   // A degree is approximately 112 kilometers.  So we will do a quick
   // approximation and then do "search until close enough".
   d = dLatitude;
   double dLat1 = d;
   d = dLongitude;
   double dLon1 = d;
   double dLat2 = GetLatitudeAtDistanceFromPoint( dLat1, dLon1, dDist );
   double dLon2 = GetLongitudeAtDistanceFromPoint( dLat1, dLon1, dDist );

   int nTrys = 0;
   double dPrev = dLat2;
   double dCalcDist = ApproxDistance( dLat1, dLon1, dLat2, dLon1, 0x80000000 );
   double dDelta = dDist - dCalcDist;
   double dDeltaMin = dDelta;
   double dMin = dLat2;
   while ( dDelta > 0.01 || dDelta < -0.01 )
   {
      nTrys++;
      dPrev = dLat2;
      dLat2 += dDelta / 112;
      dCalcDist = ApproxDistance( dLat1, dLon1, dLat2, dLon1, 0x80000000 );
      dDelta = dDist - dCalcDist;
      if ( dDelta < dDeltaMin && dDelta > -dDeltaMin )
      {
         dDeltaMin = dDelta;
         dMin = dLat2;
      }

      if ( nTrys > 50 )
      {
         dLat2 = dMin;
         d = dDeltaMin;
         SysConvertDecimalToString( &d, szDecimal, 6 );
         TraceLineS( "LatitudeDelta: ", szDecimal );
         break;
      }
   }

   d = dLat2;
   *pdNorthLatitude = d;
   d2 = dLat1 * 2;
   *pdSouthLatitude = d2 - d;

   nTrys = 0;
   dPrev = dLon2;
   dCalcDist = ApproxDistance( dLat1, dLon1, dLat1, dLon2, 0x80000000 );
   dDelta = dDist - dCalcDist;
   dDeltaMin = dDelta;
   dMin = dLon2;
   while ( dDelta > 0.01 || dDelta < -0.01 )
   {
      nTrys++;
      dPrev = dLon2;
      dLon2 += dDelta / 100;
      dCalcDist = ApproxDistance( dLat1, dLon1, dLat1, dLon2, 0x80000000 );
      dDelta = dDist - dCalcDist;
      if ( dDelta < dDeltaMin && dDelta > -dDeltaMin )
      {
         dDeltaMin = dDelta;
         dMin = dLon2;
      }

      if ( nTrys > 50 )
      {
         dLon2 = dMin;
         d = dDeltaMin;
         SysConvertDecimalToString( &d, szDecimal, 6 );
         TraceLineS( "LongitudeDelta: ", szDecimal );
         break;
      }
   }

   d = dLon2;
   *pdWestLongitude = d;
   d2 = dLon1 * 2;
   *pdEastLongitude = d2 - d;

   if ( (lFlag & 0x80000000) == 0 )
      dDelta *= GEO::KM2MI;   // convert to miles

   return( (zSHORT) (dDelta * 100.0) );
}
예제 #2
0
파일: currency.c 프로젝트: DeegC/10d
zSHORT
fnGetCurrencyText( LPDOMAINDATA lpDomainData )
{
   LPDOMAIN    lpDomain;
   zLPCONTEXT  lpContext;
   zSHORT      nRC;
   zCHAR       sz[ 200 ];
   zPCHAR      lpAttrValue;
   zCHAR       cAttrType;
   zULONG      uAttrLength;
   zBOOL       bWasNull = FALSE;
   zCHAR       szThou[ 10 ];
   zCHAR       szDecPt[ 10 ];
   zLONG       lPrecision;
   zDECIMAL    dDecimal;
   zDECIMAL    dNullDecimal;

   lpDomain = (LPDOMAIN) SysGetPointerFromHandle( lpDomainData->lpViewAttribute->hDomain );
   SysAssignDecimalFromNull( &dNullDecimal );

   if ( lpDomainData->lpViewAttribute->cType != zTYPE_DECIMAL )
   {
      *sz = lpDomainData->lpViewAttribute->cType;
      *(sz + 1) = 0;
      strcat_s( sz, zsizeof( sz ), ", " );
      strcat_s( sz, zsizeof( sz ), lpDomainData->lpViewEntity->szName );
      MessageSend( lpDomainData->zView, "", "Domain System Error",
                   sz, zMSGQ_DOMAIN_ERROR, 0 );
      return( zCALL_ERROR );
   }

   // determine output data type
   switch ( lpDomainData->cType )
   {
    case zTYPE_STRING:

      // Get a pointer to the attribute value.
      nRC = GetValueFromRecord( lpDomainData->zView,
                                lpDomainData->lpViewEntity,
                                lpDomainData->lpViewAttribute,
                                &lpAttrValue, &cAttrType, &uAttrLength );
      if ( nRC )
         return( zCALL_ERROR );

      // if there is no lpRecord, lpAttrValue returns a null...
      if ( lpAttrValue == 0 )
         lpAttrValue = (zPCHAR) &dNullDecimal;

      // Get the decimal characteristics.
      if ( lpDomainData->pszContextName && *lpDomainData->pszContextName )
      {
         if ( GetContext( &lpContext, lpDomain, lpDomainData->pszContextName ) )
         {
            // Get the formatting characters.
            nRC = fnGetDecimalFmtStrings( lpContext, szThou, szDecPt,
                                          &lPrecision );


         }
         else
         {
            MessageSend( lpDomainData->zView, "", "Domain System Error",
                         "Invalid Context for Currency Text",
                         zMSGQ_DOMAIN_ERROR, 0 );
            return( zCALL_ERROR );
         }
      }
      else
      {
         GetDefaultContext( &lpContext, lpDomain );
         fnGetDecimalFmtStrings( lpContext, szThou, szDecPt, &lPrecision );
      }

      // Convert the decimal to a basic string.
      if ( SysCompareDecimalToNull( (zPDECIMAL) lpAttrValue ) == 0 )
      {
         *((zPCHAR) lpDomainData->lpData) = 0;
         strcpy_s( sz, zsizeof( sz ), "0.0" );
         bWasNull = TRUE;
      }
      else
      {
         SysAssignDecimalFromDecimal( &dDecimal, (zPDECIMAL) lpAttrValue );
         SysConvertDecimalToString( &dDecimal, sz, (zSHORT) lPrecision );
      }

      // Convert the decimal string to correct precision and international
      // formatting characters.
      if ( szThou[ 0 ] == 0 )
      {
         if ( szDecPt[ 0 ] == 0 )
            fnFormatDecimalString( sz, 0, 0, lpDomain->lDecimalFormat );
         else
            fnFormatDecimalString( sz, 0, szDecPt, lPrecision );
      }
      // Convert the string decimal to the character string.
      fnFormatCurrencyText( lpDomainData->zView, sz,
                            szThou, szDecPt, lPrecision );
      // Return the formatted decimal, unless the return area is not
      // large enough, in that case fill it with '*'.
      if ( lpDomainData->uMaxStringLength && zstrlen( sz ) > lpDomainData->uMaxStringLength )
      {
         zmemset( (zPCHAR) lpDomainData->lpData, '*', lpDomainData->uMaxStringLength );
         *((zPCHAR) lpDomainData->lpData + lpDomainData->uMaxStringLength) = 0;
         nRC = zCALL_ERROR;
      }
      else
      {
         strcpy_s( (zPCHAR) lpDomainData->lpData, lpDomainData->uMaxStringLength, sz );
         nRC = bWasNull ? -1 : 0;
      }

      break;


    default:
      *sz = lpDomainData->cType;
      *(sz + 1) = 0;
      strcat_s( sz, zsizeof( sz ), ", " );
      strcat_s( sz, zsizeof( sz ), lpDomainData->lpViewEntity->szName );
      MessageSend( lpDomainData->zView, "", "Domain System Error",
                   sz, zMSGQ_DOMAIN_ERROR, 0 );
      return( zCALL_ERROR );
   }

   return( 0 );
}