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

📄 viewtsgraph.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// NRDB Pro is part of the Natural Resources Database Project 
// 
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
// 

#include "stdafx.h"
#include <strstrea.h>
#include "nrdb.h"
#include "ViewTSGraph.h"
#include "mainfrm.h"

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

/////////////////////////////////////////////////////////////////////////////

const int MAX_DAYS_MONTH = 31;
const int MAX_STEP = 16;
const double AVERAGE_MONTH=30.4375;
const int MAX_DAYS_YEAR = 366;

/////////////////////////////////////////////////////////////////////////////
// CViewTSGraph

IMPLEMENT_DYNCREATE(CViewTSGraph, CViewGraph)

CViewTSGraph::CViewTSGraph()
{
}

CViewTSGraph::~CViewTSGraph()
{
}


BEGIN_MESSAGE_MAP(CViewTSGraph, CViewGraph)
	//{{AFX_MSG_MAP(CViewTSGraph)
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CViewTSGraph drawing

void CViewTSGraph::OnDraw(CDC* pDC)
{	
   CViewGraph::OnDraw(pDC);

}

/////////////////////////////////////////////////////////////////////////////
// CViewTSGraph diagnostics

#ifdef _DEBUG
void CViewTSGraph::AssertValid() const
{
	CViewGraph::AssertValid();
}

void CViewTSGraph::Dump(CDumpContext& dc) const
{
	CViewGraph::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

void CViewTSGraph::OnInitialUpdate() 
{
	CViewGraph::OnInitialUpdate();
	
	// Determine whether to display sticks or lines

   for (int iLine = 0; iLine < m_pDoc->GetNumLines(); iLine++)
   {
      m_prop.m_aGraphStyle[iLine] = CGraphProperties::lines;

      if (m_pDoc->GetLegend(iLine).Find(BDString(IDS_TOTAL)) >=0 ) m_prop.m_aGraphStyle[iLine] = CGraphProperties::sticks;
   };
	
}

/////////////////////////////////////////////////////////////////////////////
// CViewTSGraph message handlers

void CViewTSGraph::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
   double dValue;      
   CDateTime datetime;      

   BeginWaitCursor();

   // Retrieve document
  
   m_aXPosData.SetSize(m_pDoc->GetNumLines());
   m_aGraphData.SetSize(m_pDoc->GetNumLines());

   for (int iLine = 0; iLine < m_pDoc->GetNumLines(); iLine++)
   {      
      BOOL bFound = GetDoc()->GetFirstData(iLine, datetime, dValue);   
      
      if (!m_dtStart.IsValid() && datetime.IsValid())
      {
         m_dtStart = datetime; 
         m_dtEnd = datetime;
      };
              
      while (bFound)
      {
        // Transfer the data

         if (datetime.IsValid())
         {
            if (datetime < m_dtStart) m_dtStart = datetime;
            if (datetime > m_dtEnd) m_dtEnd = datetime;

            if (dValue != AFX_RFX_DOUBLE_PSEUDO_NULL)
            {
             // If monthly or annual data then set to middle

               if (datetime.GetMonth() == 0) datetime.Advance(182,0);
               else if (datetime.GetDay() == 0) datetime.Advance(15,0);

               m_bData = TRUE;
               m_aXPosData[iLine].Add(datetime.GetDateLong());
               m_aGraphData[iLine].Add(dValue);                               
            }
         };
                 
         // Get the next reading
         
         bFound = GetDoc()->GetNextData(iLine, datetime, dValue);
      }           
    
    
    // Set number of data sets
            
      m_prop.m_aLegendText.SetAtGrow(iLine,m_pDoc->GetLegend(iLine));      
      m_prop.m_aColour.SetAtGrow(iLine, GetColour(iLine));
      m_prop.m_aLineStyle.SetAtGrow(iLine, PS_SOLID);
      m_prop.m_aLineWidth.SetAtGrow(iLine, 2);
      m_prop.m_aGraphStyle.SetAtGrow(iLine, CGraphProperties::lines);

      // For 'total' data such as rainfall, display sticks      
   };
   
   // Update start and end dates

   if (m_dtStart == m_dtEnd)
   {
      m_dtStart = m_dtStart - 365*5;
      m_dtEnd = m_dtEnd + 365*5;
   }

   // If monthly data then set the last date to the end of the month

   if (m_dtEnd.GetMonth() == 0)
   {
      m_dtEnd.AdvanceYear();      
      m_dtEnd.Advance(0,-1);
   }
   else if (m_dtEnd.GetDay() == 0)
   {
      m_dtEnd.AdvanceMonth(); 
      m_dtEnd.Advance(0,-1);
   }


   // Update the displacement data

   for (iLine = 0; iLine < m_pDoc->GetNumLines(); iLine++)
   { 
      for (int i = 0; i < m_aXPosData[iLine].GetSize(); i++)
      {
         double dDisp = CDateTime((long)m_aXPosData[iLine][i],0) - m_dtStart;          
         m_aXPosData[iLine][i] = dDisp;
      };
   };

   m_prop.m_dXMin = 0;
   m_prop.m_dXMax = m_dtEnd - m_dtStart;

   // Set titles         
   
   m_prop.m_sTitle = m_pDoc->GetTitle();   
  
   EndWaitCursor();
  
}

///////////////////////////////////////////////////////////////////////////////

void CViewTSGraph::DrawGraph(CDC* pDC)
{     
   double dXOld = 0;
   double dYOld = 0;
   double dX, dY, dY0;

   // Draw the data on the graph

   for (int i = 0; i < m_aGraphData.GetSize(); i++)
   {
      // Create pen

      int nWidth = GetWidth(pDC, m_prop.m_aLineStyle[i], m_prop.m_aLineWidth[i]);
      CPen pen(m_prop.m_aLineStyle[i], nWidth, m_prop.m_aColour[i]);
      CPen* pPenOld = pDC->SelectObject(&pen);

      // Draw lines

      for (int j = 0; j < m_aGraphData[i].GetSize(); j++)
      {
         dX = m_rectAxis.left + 1 + (m_aXPosData[i][j] - m_prop.m_dXMin) *
                     (m_rectAxis.Width()-2) / (m_prop.m_dXMax - m_prop.m_dXMin);

         dY = m_rectAxis.bottom +1 - (m_aGraphData[i][j] - m_prop.m_dYMin) * 
                     (m_rectAxis.Height()-2) / (m_prop.m_dYMax - m_prop.m_dYMin);

         // Join lines

         if (m_prop.m_aGraphStyle[i] == CGraphProperties::lines)
         {
            if (j > 0)
            {
               pDC->MoveTo((int)dXOld, (int)dYOld);
               pDC->LineTo((int)dX,(int)dY);
            };

            // If only one point then draw a cross

            if (m_aGraphData[i].GetSize() == 1)
            {
               pDC->MoveTo((int)dX - nWidth, (int)dY - nWidth);
               pDC->LineTo((int)dX + nWidth, (int)dY + nWidth);
               pDC->MoveTo((int)dX - nWidth, (int)dY + nWidth);
               pDC->LineTo((int)dX + nWidth, (int)dY - nWidth);
            }
         } 
         // Draw sticks

         else if (m_prop.m_aGraphStyle[i] == CGraphProperties::sticks)
         {
            dY0 = m_rectAxis.bottom - (0 - m_prop.m_dYMin) * 
                        (m_rectAxis.Height()) / (m_prop.m_dYMax - m_prop.m_dYMin);
            dY0 = max(dY0, m_rectAxis.top);
            dY0 = min(dY0, m_rectAxis.bottom);
 
            pDC->MoveTo((int)dX, (int)dY);
            pDC->LineTo((int)dX, (int)dY0);
         }
         else if (m_prop.m_aGraphStyle[i] == CGraphProperties::symbols)
         {
            int nX = (int)dX;
            int nY = (int)dY;
            pDC->MoveTo(nX-nWidth, nY-nWidth);
            pDC->LineTo(nX+nWidth, nY+nWidth);
            pDC->MoveTo(nX-nWidth, nY+nWidth);
            pDC->LineTo(nX+nWidth, nY-nWidth);
         }
         dXOld = dX;
         dYOld = dY;
      }

      pDC->SelectObject(pPenOld);
   };

}

///////////////////////////////////////////////////////////////////////////////
//
// BOOL CViewTSGraph::DrawXAxis()
//

void CViewTSGraph::DrawXAxis(CDC* pDC)
{
   BOOL bOK = TRUE;
   BOOL m_bYearTicks;

   CFont font;
   CreateFont(pDC, font, 9);
   CFont* pFontOld = pDC->SelectObject(&font);

   CSize sz = pDC->GetTextExtent("ABC");
 
   m_bDays = FALSE;
   m_bMonthsFull = FALSE;  
   m_bMonths = FALSE;
   m_bDecades = FALSE;

 

  // Check that the data represents a valid range

   if (!m_dtStart.IsValid()) return;

 // Determine position of axis

   m_dTextHeight = sz.cy;      
   m_dTextWidth =  sz.cx/3;
   m_dOriginX = m_rectAxis.left;
   m_dOriginY = m_rectAxis.bottom;
   m_dLenX = m_rectAxis.Width();
   m_dTickLength = m_dTextHeight / 3;

  // Determine positioning of labels

   m_dDayY = m_dOriginY + m_dTextHeight*0.2;
   m_dMonthY = m_dOriginY + m_dTextHeight*1.0;
   m_dYearY = m_dOriginY + m_dTextHeight*1.8;

 // Retrieve details of the graph from the corresponding document      

   m_dRange = m_dtEnd-m_dtStart+1;
 
 // If x scale is negative, do not display as it is not possible to determine where
 // graphics server places y axis

   if (m_prop.m_dXMin < 0)
   {
      return;
   }
  
 // Determine whether days are shown

   if (m_dRange < 100)
   { 
      m_bDays = TRUE;
   };
  
  // Determine if there is enough space to draw months in full

   if ((m_dTextWidth * 4.0 * m_dRange) / MAX_DAYS_MONTH < m_dLenX)
   {
      m_bMonthsFull = TRUE;
   };
      
   if (m_dRange < 2000)
   {
      m_bMonths = TRUE;
   } 
   
   m_bYearTicks = m_dRange < 50000;

   if (m_dRange > 10000)
   {
      m_bDecades = TRUE;
   } 
      
 // Draw axis ticks for days
 
   if (bOK && m_bDays)             
   { 
       CDateTime datetime = m_dtStart;
       while (datetime <= m_dtEnd)

⌨️ 快捷键说明

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