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

📄 vector.cpp

📁 利用vc开发gis系统有用的可以下一下哈欢迎大家使用
💻 CPP
字号:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Vector.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
//构造函数
TGisVectorLayer::TGisVectorLayer()
{
  m_lpPolygonList=NULL;
  m_nSelectID = -1;
}
//---------------------------------------------------------------------------
//析构函数
TGisVectorLayer::~TGisVectorLayer()
{
 if(m_lpPolygonList)
   {
    //释放资源
    for(int i=0;i<m_lpPolygonList->Count;i++)
      {
       delete m_lpPolygonList->Items[i];
      }
    delete m_lpPolygonList;
   }
}
//---------------------------------------------------------------------------
//读入Idris格式的矢量文件
BOOL TGisVectorLayer::OpenIdrisFile(AnsiString FileName)
{
  //首先读入文件头
  AnsiString DocFileName= ChangeFileExt(FileName,".dvc");
  TStringList *StringList1=new TStringList();
  StringList1->LoadFromFile(DocFileName);

  AnsiString type=StringList1->Strings[3].SubString(15,StringList1->Strings[4].Length()-13);
  if(type=="polygon")
    m_gisFileHeader.giType=GIS_POLYGON;
  else if(type=="point")
    m_gisFileHeader.giType=GIS_POINT;
  else
    m_gisFileHeader.giType=GIS_LINE;

  m_gisFileHeader.giMinX = StringList1->Strings[7].SubString(15,StringList1->Strings[7].Length()-13).ToDouble();
  m_gisFileHeader.giMaxX = StringList1->Strings[8].SubString(15,StringList1->Strings[8].Length()-13).ToDouble();
  m_gisFileHeader.giMinY = StringList1->Strings[9].SubString(15,StringList1->Strings[9].Length()-13).ToDouble();
  m_gisFileHeader.giMaxY = StringList1->Strings[10].SubString(15,StringList1->Strings[10].Length()-13).ToDouble();
  delete StringList1;

  TFileStream* File=new TFileStream(FileName,fmOpenRead);
  if(m_gisFileHeader.giType==GIS_POLYGON
    || m_gisFileHeader.giType==GIS_LINE)
  {
    m_lpPolygonList=new TList;
    float test[2];
    File->Read(test,8);
    do
    {
      LPGISPOLYGON polygon = new GISPOLYGON;
      polygon->point = new GISPOINT[test[1]];
      polygon->pPen = new TPen;
      polygon->pBrush = new TBrush;
      polygon->id=test[0];
      polygon->numberPoint=test[1];
      File->Read((float*)polygon->point ,4*2*test[1]);
      //计算多边形的外包围矩形
      polygon->outRect.x1=polygon->point[0].x;
      polygon->outRect.x2=polygon->point[0].x;
      polygon->outRect.y1=polygon->point[0].y;
      polygon->outRect.y2=polygon->point[0].y;
      for(int i=1;i<test[1];i++)
      {
        if(polygon->outRect.x1>polygon->point[i].x)
        polygon->outRect.x1=polygon->point[i].x;
        if(polygon->outRect.x2<polygon->point[i].x)
          polygon->outRect.x2=polygon->point[i].x;
        if(polygon->outRect.y1>polygon->point[i].y)
          polygon->outRect.y1=polygon->point[i].y;
        if(polygon->outRect.y2<polygon->point[i].y)
          polygon->outRect.y2=polygon->point[i].y;
      }
      m_lpPolygonList->Add (polygon);
      File->Read(test,8);
    }while(test[0]!=0 && test[1]!=0);
  }
  delete File;
  return TRUE;
}
//---------------------------------------------------------------------------
//绘制函数
void TGisVectorLayer::Draw(TCanvas* canvas,GISRECT SourceRect,TRect DestRect)
{
 m_DrawRect=DestRect;
 m_gisSourceRect=SourceRect;
 m_canvas=canvas;

 m_ratioX=DestRect.Width() /(SourceRect.x2-SourceRect.x1);
 m_ratioY=DestRect.Height()/(SourceRect.y2-SourceRect.y1);

 canvas->Brush->Color=clBlack;
 if(m_gisFileHeader.giType==GIS_POLYGON
    || m_gisFileHeader.giType==GIS_LINE)
 {
  for(int i=0;i<m_lpPolygonList->Count;i++)
  {
   LPGISPOLYGON polygon=(GISPOLYGON*)m_lpPolygonList->Items[i];
   DrawAPolygon(polygon,SourceRect,DestRect);
   if(i == m_nSelectID)
   {
     DrawSelectPolygon(SourceRect,DestRect);
   }
  }
 }
}
//---------------------------------------------------------------------------
//绘制一个多边形
void TGisVectorLayer::DrawAPolygon(LPGISPOLYGON polygon,GISRECT SourceRect,TRect DestRect)
{
   int pointCount=polygon->numberPoint ;
   TPoint* points = new TPoint[pointCount];
   for(int i=0; i<pointCount; i++)
   {
     points[i].x = m_ratioX*(polygon->point[i].x-SourceRect.x1);
     points[i].y = DestRect.Height()-m_ratioY*(polygon->point[i].y-SourceRect.y1);
   }

   m_canvas->Pen->Style = polygon->pPen->Style;
   m_canvas->Pen->Width = polygon->pPen->Width;
   m_canvas->Pen->Color = polygon->pPen->Color;
   m_canvas->Brush->Style = polygon->pBrush->Style;
   m_canvas->Brush->Color = polygon->pBrush->Color;
   if(polygon->pBrush->Bitmap)
   {
     m_canvas->Brush->Bitmap = polygon->pBrush->Bitmap;
   }
   m_canvas->Polygon(points, pointCount-1);
   m_canvas->Brush->Bitmap = NULL;
   delete points;
}
//---------------------------------------------------------------------------
//用于判断一个点是否在一个多边形中
//返回TRUE:表示点在多边形中,否则点不在多边形中
BOOL TGisVectorLayer::PointIsInPolygon(LPGISPOLYGON polygon,GISPOINT point)
{
 //如果点在多边形的外包围矩形外,那么肯定没有交点
 if(   point.x < polygon->outRect.x1
    || point.x > polygon->outRect.x2
    || point.y < polygon->outRect.y1
    || point.y > polygon->outRect.y2)
    return FALSE;

 int count=0;
 for(int i=0;i<polygon->numberPoint-1;i++)
 {
  GISLINE tempLine(polygon->point[i].x,
                   polygon->point[i].y,
                   polygon->point[i+1].x,
                   polygon->point[i+1].y);
  if(point.y < tempLine.Y1 && point.y < tempLine.Y2)
    continue;
  float a;
  float b;
  if(tempLine.X2==tempLine.X1)
    continue;
  a=(tempLine.Y2-tempLine.Y1)/(tempLine.X2-tempLine.X1);
  b=tempLine.Y1-a*tempLine.X1;
  float y=a*point.x+b;
  if(y<point.y
     && y<=(tempLine.Y1>tempLine.Y2 ? tempLine.Y1 : tempLine.Y2)
     && y>=(tempLine.Y1<tempLine.Y2? tempLine.Y1 : tempLine.Y2)
     && point.x<=(tempLine.X1>tempLine.X2 ? tempLine.X1 : tempLine.X2)
     && point.x>=(tempLine.X1<tempLine.X2 ? tempLine.X1 : tempLine.X2))
    count++;
 }

 if(count%2)
   return TRUE;
 else
   return FALSE;
}
//---------------------------------------------------------------------------
//将行列值的坐标变换成X、Y值坐标
GISPOINT TGisVectorLayer::TPointToGisPoint(TPoint SourcePoint)
{
 GISPOINT point;
 point.x= SourcePoint.x/m_ratioX + m_gisFileHeader.giMinX;
 point.y= (m_DrawRect.Height()-SourcePoint.y)/m_ratioY + m_gisFileHeader.giMinY;
 return point;
}
//---------------------------------------------------------------------------
//选择多边形函数
void TGisVectorLayer::SelectPolygon(TPoint SourcePoint)
{
 for(int i=0;i<m_lpPolygonList->Count;i++)
 {
  GISPOINT point=TPointToGisPoint(SourcePoint);
  if(PointIsInPolygon((GISPOLYGON*)(m_lpPolygonList->Items[i]),point))
  {
   m_nSelectID = i;
   return;
  }
 }

 m_nSelectID = -1;
}
//---------------------------------------------------------------------------
void TGisVectorLayer::DrawSelPlyWithBitmap(GISRECT SourceRect,TRect DestRect)
{/*
    Graphics::TBitmap *BrushBmp = new Graphics::TBitmap;
    try
    {
      LPGISPOLYGON polygon = (GISPOLYGON*)m_lpPolygonList->Items[m_nSelectID];
      int pointCount=polygon->numberPoint ;
      BrushBmp->LoadFromFile(m_strBitmapFileName);
      m_canvas->Brush->Bitmap = BrushBmp;
      TPoint* points = new TPoint[pointCount];
   for(int i=0; i<pointCount; i++)
   {
     points[i].x=ratioX*(polygon->point[i].x-SourceRect.x1);
     points[i].y=DestRect.Height()-ratioY*(polygon->point[i].y-SourceRect.y1);
   }
   m_canvas->Polygon(points, pointCount-1);
   delete points;
      m_canvas->Brush->Bitmap = NULL;
    }
    __finally
    {
      m_canvas->Brush->Bitmap = NULL;
      delete BrushBmp;
    }               */
}
//---------------------------------------------------------------------------
void TGisVectorLayer::DrawSelectPolygon(GISRECT SourceRect,TRect DestRect)
{
  TColor oldColor = m_canvas->Brush->Color; //保存原画刷颜色
  LPGISPOLYGON polygon = (GISPOLYGON*)m_lpPolygonList->Items[m_nSelectID];
  //在本次所选择的多边形中填充红色
  m_canvas->Brush->Color=clRed;
  int pointCount=polygon->numberPoint ;
  TPoint* points = new TPoint[pointCount];
  for(int i=0; i<pointCount; i++)
  {
    points[i].x=m_ratioX*(polygon->point[i].x-SourceRect.x1);
    points[i].y=DestRect.Height()-m_ratioY*(polygon->point[i].y-SourceRect.y1);
  }
  m_canvas->Pen->Style = polygon->pPen->Style;
  m_canvas->Pen->Width = polygon->pPen->Width;
  m_canvas->Pen->Color = polygon->pPen->Color;
  m_canvas->Polygon(points, pointCount-1);
  delete points;
  m_canvas->Brush->Color=oldColor; //恢复使用原画刷颜色
}
//---------------------------------------------------------------------------
void TGisVectorLayer::SetBitmapBrush(AnsiString strBitmapFile)
{
  LPGISPOLYGON polygon = (GISPOLYGON*)m_lpPolygonList->Items[m_nSelectID];
  Graphics::TBitmap *BrushBmp = new Graphics::TBitmap;
  BrushBmp->LoadFromFile(strBitmapFile);
  polygon->pBrush->Bitmap = BrushBmp;
}
//---------------------------------------------------------------------------
//将图形坐标的点转换成屏幕坐标
TPoint TGisVectorLayer:: GisPointToTPoint(GISPOINT SourcePoint)
{
  TPoint point;
  point.x = (SourcePoint.x - m_gisFileHeader.giMinX)*m_ratioX;
  point.y = m_DrawRect.Height() - (SourcePoint.y - m_gisFileHeader.giMinY)*m_ratioY;
  return point;
}
//---------------------------------------------------------------------------
//将图形坐标中的矩形转变为屏幕坐标
TRect  TGisVectorLayer::GisRectToTRect(GISRECT SourceRect)
{
  GISPOINT pt1, pt2;
  pt1.x = SourceRect.x1;
  pt1.y = SourceRect.y1;
  pt2.x = SourceRect.x2;
  pt2.y = SourceRect.y2;
  TPoint point1, point2;
  point1 = GisPointToTPoint(pt1);
  point2 = GisPointToTPoint(pt2);
  return TRect(point1,point2);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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