⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eqd.cpp

📁 使用finger协议从USGS(美国地质勘探局)获取地震数据
💻 CPP
字号:
/*
Module : EQD.CPP
Purpose: Implementation for a MFC class to retrieve earthquake data from the US 
         Geological Survey Web site.
Created: PJN / 18-10-1999
History: None

Copyright (c) 1999 by PJ Naughter.  
All rights reserved.

*/

//////////////// Includes ////////////////////////////////////////////
#include "stdafx.h"
#include "Finger.h"
#include "eqd.h"


//////////////// Macros / Locals /////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



//////////////// Implementation //////////////////////////////////////

CQuakeData::CQuakeData()
{
  ZeroMemory(&m_Time, sizeof(SYSTEMTIME));
  m_Latitude = 0;
  m_Longitude = 0;
  m_Depth = 0;
  m_MagType = Ml;
  m_Magnitude = 0;
  m_Quality = D;
};

BOOL CQuakeData::Parse(const CString& sLine)
{
  //Quick return if the string is empty
  if (sLine.IsEmpty())
    return FALSE;

  CString sLocalLine(sLine);
  LPTSTR pszLine = sLocalLine.GetBuffer(sLocalLine.GetLength());

  //1. the date of the quake
  int nDay;
  int nMonth;
  int nYear;
  LPTSTR pszSeps = _T(" ");
  LPTSTR pszToken = _tcstok(pszLine, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  _stscanf(pszToken, _T("%d/%d/%d"), &nYear, &nMonth, &nDay);
  if (nYear <= 30)
    nYear += 2000;
  else if (nYear <= 99)
    nYear += 1900;

  //2. The time of the quake
  int nHour;
  int nMinute;
  int nSecond;
  pszToken = _tcstok(NULL, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  _stscanf(pszToken, _T("%d:%d:%d"), &nHour, &nMinute, &nSecond);

  //Copy over all the date and time values to the member variable m_Time
  m_Time.wYear = (WORD) nYear;
  m_Time.wMonth = (WORD) nMonth;
  m_Time.wDay = (WORD) nDay;
  m_Time.wHour = (WORD) nHour;
  m_Time.wMinute = (WORD) nMinute;
  m_Time.wSecond = (WORD) nSecond;

  //3. The Latitude
  TCHAR LatIndicator = _T('\0');
  pszToken = _tcstok(NULL, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  int nTokenLen = _tcslen(pszToken);
  if (nTokenLen)
    LatIndicator = pszToken[nTokenLen-1];
  _stscanf(pszToken, _T("%f"), &m_Latitude);
  if (LatIndicator == _T('S'))
    m_Latitude = -m_Latitude;
  else if (LatIndicator != _T('N'))
  {
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }

  //4. The Longitude
  TCHAR LongIndicator = _T('\0');
  pszToken = _tcstok(NULL, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  nTokenLen = _tcslen(pszToken);
  if (nTokenLen)
    LongIndicator = pszToken[nTokenLen-1];
  _stscanf(pszToken, _T("%f"), &m_Longitude);
  if (LongIndicator == _T('W')) //West longitude is Negative, East is Positive
    m_Longitude = -m_Longitude;
  else if (LongIndicator != _T('E'))
  {
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }

  //5. The depth
  pszToken = _tcstok(NULL, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  _stscanf(pszToken, _T("%f"), &m_Depth);

  //6. The Magnitude and Magnitude Type
  pszToken = _tcstok(NULL, pszSeps);
  if (pszToken == NULL)
  { 
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }
  TCHAR sBuf[10];
  _stscanf(pszToken, _T("%f%s"), &m_Magnitude, sBuf); 
  if (_tcscmp(sBuf, _T("Ml")) == 0)
    m_MagType = Ml;
  else if (_tcscmp(sBuf, _T("Lg")) == 0)
    m_MagType = Lg;
  else if (_tcscmp(sBuf, _T("Md")) == 0)
    m_MagType = Md;
  else if (_tcscmp(sBuf, _T("Mb")) == 0)
    m_MagType = Mb;
  else if (_tcscmp(sBuf, _T("Ms")) == 0)
    m_MagType = Ms;
  else if (_tcscmp(sBuf, _T("Mw")) == 0)
    m_MagType = Mw;
  else
  {
    sLocalLine.ReleaseBuffer();
    return FALSE;
  }

  //7. The quake location quality and the comments
  pszToken = pszToken + _tcslen(pszToken) + 1;
  if (pszToken == NULL)
  { 
    m_sComments.Empty();
    m_Quality = U;
  }
  else 
  {
    CString sComments(pszToken);
    sComments.TrimLeft();
    if (sComments.GetLength() > 2)
    {
      if (sComments.GetAt(1) == _T(' '))
      {
        if (sComments.GetAt(0) == _T('A'))
        {
          m_Quality = A;
          sComments = sComments.Right(sComments.GetLength()-2);
          sComments.TrimLeft();
          m_sComments = sComments;
        }
        else if (sComments.GetAt(0) == _T('B'))
        {
          m_Quality = B;
          sComments = sComments.Right(sComments.GetLength()-2);
          sComments.TrimLeft();
          m_sComments = sComments;
        }
        else if (sComments.GetAt(0) == _T('C'))
        {
          m_Quality = C;
          sComments = sComments.Right(sComments.GetLength()-2);
          sComments.TrimLeft();
          m_sComments = sComments;
        }
        else if (sComments.GetAt(0) == _T('D'))
        {
          m_Quality = D;
          sComments = sComments.Right(sComments.GetLength()-2);
          sComments.TrimLeft();
          m_sComments = sComments;
        }
        else
        {
          //No quality indicator, just copy over the comments
          m_Quality = U;
          m_sComments = sComments;
        }
      }
      else
      {
        //No quality indicator, just copy over the comments
        m_Quality = U;
        m_sComments = sComments;
      }
    }
    else
    {
      //No quality indicator, just copy over the comments
      m_Quality = U;
      m_sComments = sComments;
    }
  }
  
  //Release the CString buffer we were using for parsing purposes
  sLocalLine.ReleaseBuffer();

  return TRUE;
}



BOOL CEQD::GetQuakeData(CArray<CQuakeData, CQuakeData&>& data, DWORD dwTimeout)
{
  BOOL bSuccess = FALSE;
  data.SetSize(0);

  //Use the finger class to get the information back
  CFinger f;
  CString sReply;
  if (f.Finger(_T("gldfs.cr.usgs.gov"), _T("quake"), sReply, TRUE, 79, dwTimeout))
  {
    //Parse each data line, line by line
    LPTSTR pszData = sReply.GetBuffer(sReply.GetLength());
    LPTSTR pszKM = _tcsstr(pszData, _T("km"));
    if (pszKM)
    {
      CString sLine;
      pszData = GetNextLine(pszKM, sLine);
      while (pszData)
      {
        //Add the newly parsed line to the array
        CQuakeData quake;
        if (quake.Parse(sLine))
          data.Add(quake);

        //Move onto the next line
        pszData = GetNextLine(pszData, sLine);
      }

      bSuccess = TRUE;
    }

    sReply.ReleaseBuffer();
  }

  return bSuccess;
}

LPTSTR CEQD::GetNextLine(LPTSTR pszData, CString& sLine)
{
  //search for the "\r\n" sequence in pszData and
  //if found return the following data
  LPTSTR pszStart = _tcsstr(pszData, _T("\r\n"));
  if (pszStart)
  {
    //Skip over the EOL terminators
    pszStart += 2;

    //Try to find this lines terminator
    LPTSTR pszEnd = _tcsstr(pszStart, _T("\r\n"));
    if (pszEnd)
    {
      //Copy this line to sLine
      int nSize = pszEnd - pszStart + 1;
      TCHAR* pszTemp = new TCHAR[nSize];
      _tcsncpy(pszTemp, pszStart, nSize-1);
      pszTemp[nSize-1] = _T('\0');
      sLine = pszTemp;
      delete [] pszTemp;
    }
    else
    {
      //copy the last line to sLine
      sLine = pszStart;
    }

    return pszEnd;
  }
  else
    return pszStart;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -