矢量空間數據格式


空間數據格式是空間數據的基礎,定義了如何在計算機中表達空間數據。各個GIS軟件都定義了自己的空間數據格式。OGC定義了空間數據的交換格式,來實現各類GIS軟件之間的空間數據交互。主要有WKT、WKB、GML幾類,隨着Google Earth的普及,KML也成為OGC的規范。

 

1. 常用的矢量數據格式主要包括以下六類:

  • 點(Point)
  • 多點(MultiPoint)
  • 線(LineString)
  • 多線(MultiLineString)
  • 面(Polygon)
  • 多面(MultiPolygon)

1) 點(Point)

    單獨一個坐標點構成的空間實體。

 

2) 多點(MultiPoint)

    由多個坐標點構成的一個空間實體。

3) 線(LineString)

    由一條線構成的空間實體。

4) 多線(MultiLineString)

   有多條線構成的一個空間實體。

5) 面(Polygon)

    Polygon和MultiPolygon的結構較為復雜,概念相也容易混淆。Polygon和MultiPolygon都由多個環(Ring)構成的封閉的面狀實體。

    Polygon具有1個外環和0個或n個內環構成。

    MultiPoylgon由多個Plygon構成,Plygon之間的空間關系是相離,因此MultiPolygon並沒有外環。

6) 多面(MultiPolygon)

   由多個相離的Polygon構成,並沒有一個外環。

    

 

 

2. WKT

WKT用文本的方式來表達Geometry,便於人的閱讀。

WKT的格式為:Geometry類型(坐標數據)

1) 點(Point)

    格式:POINT(x y)

    下面是一個Point類型的Geometry的WKT

    § POINT(1 1)

  • Point:Geometry類型
  • (1 1):幾何坐標(x y),x和y之間用空格隔開,不是用逗號。

2) 多點(MultiPoint)

    格式:MULTIPOINT(x1 y1,x2 y2,…,xn yn)

3) 線(LineString)

    格式:LINESTRING(x1 y1,x2 y2,…,xn yn)

4) 多線(MultiLineString)

   格式:MULTILINESTRING((x1 y1,x2 y2,…,xn yn),(x1 y1,x2 y2,…,xm ym),......)

5) 面(Polygon)

    格式:POLYGON((x1 y1,x2 y2,…,xn yn),(x1 y1,x2 y2,…,xm ym),......)

    其中每一個括號為一個環,其中(x1 y1,x2 y2,…,xn yn)為外環。

6) 多面(MultiPolygon)

    格式:MULTIPOLYGON(((x1 y1,x2 y2,…,xn yn),(x1 y1,x2 y2,…,xm ym),......)),(...));

    第一層括號為第一個Polygon,每個Polygon之間用逗號隔開。

  

3. WKB

WKB采用二進制的方式來表達Geometry數據。WKB是一種自描述的數據結構,本身帶有Geometry的元數據信息。這里還是介紹常用的6種Geometry。

3.1 WKB的基本結構
下面以Point的來介紹WKB的基本結構,其他類型的Geometry的結構與Point的結構類似。

Point的WKB結構定義如下所示:

1 struct WKBPoint{
2     unsigned char    byteOrder;
3     int              wkbType;
4     Point            point;
5 };

 與之相對應的WKBPoint的內存結構如下圖所示:

1) byteOrder(字節序)
    字節序描述了數據結構在計算機里面的內存排布。例如,32位系統上int類型數據由4個字節構成,這4個字節可以可以由高地址位向低地址位排列,也可以由低地址位向高地址位排列,由此引出Big Endian和Little Endian兩種字節序。
    WKBPoint的第1個字節是字節序,描述了WKBPoint內存的排列是Big Endian還是Little Endian。當WKB的字節序與主機字節序不同時,需要將WKB的字節序進行逆序變換,轉換為主機字節序,否則WKB無法被正確解析。
2) wkbType
    第2~5的四個字節為一個int型變量,描述了WKB的幾何類型。
    系統根據wkbType描述的幾何類型來調用不同的程序來解析WKB結構。
3) Point結構體
    對於WKBPoint,從第6個字節開始是一個struct Point類型數據結構,定義了點的坐標結構。
    struct Point的定義如下所示:

1 struct Point{
2     double x;
3     double y;
4 };

    可以看出,struct Point定義了一個x,y坐標對,描述了一個平台面上的點的坐標。

 WKB的前5個字節,即byteOrder和wkbType是所有WKB擁有的共同結構,用以判斷WKB的基本信息。因此,可以定義為通用的結構體,由於WKB的預處理。

1 struct WKBGeometryInfo{
2     unsigned char    byteOrder;
3     int              wkbType; 
4 };

 

通過WKBGeometryInfo,可以判斷wkb的類型,然后調用不同的處理函數進行處理。

 1 unsigned char* wkb;
 2 WKBGeometryInfo *info = (WKBGeometryInfo *)wkb;
 3 
 4 switch(info->wkbType)
 5 {
 6 case wkbPoint:
 7     ...
 8     break;
 9 case wkbLineString:
10     ...
11     break;
12 case wkbPolygon:
13     ...
14     break;
15 ....
16 }

 

 3.2 WKB數據結構的完整定義(C語言)

 1) 定義字節序對齊

     編譯器優化結構體,采用4字節對齊方式。對於不滿足4字節對齊的結構體,編譯器會填充一些空字節,補足為4字節,來保持對齊方式。WKB的結構體不滿足4字節對齊,為了讓編譯器不進行結構體對齊處理,需要顯式地設置為1字節對齊。

1 #pragma pack(1)

 

2) 定義字節序枚舉

1 enum WKBByteOrder {
2     wkbXDR,     // Big Endian
3     wkbNDR = 1  // Little Endian
4 };

 

定義默認字節序

1 #define coDefaultByteOrder wkbNDR

 

3) 定義幾何數據類型枚舉

 1 enum WKBGeometryType {
 2      wkbNull                ,
 3      wkbPoint                = 1,
 4      wkbLineString           = 2,
 5      wkbPolygon              = 3,
 6      wkbMultiPoint           = 4,
 7      wkbMultiLineString      = 5,
 8      wkbMultiPolygon         = 6,
 9      wkbGeometryCollection   = 7
10 };

 

4) 定義坐標點數據結構

1  struct Point{
2      double x;
3      double y;
4  };

 

5) 定義環(Ring)數據結構

1  struct LinearRing {
2      int     numPoints;
3      Point   points[1];
4  };

 

至此,完成WKB的基本數據結構及枚舉的定義,下面定義6類幾何數據結構

6) WKBPoint

1  struct WKBPoint{
2      unsigned char    byteOrder;
3      int              wkbType;    // = 1;
4      Point            point;
5  };

 

7) WKBLineString

1  struct WKBLineString {
2      unsigned char    byteOrder;
3      int              wkbType;    // = 2;
4      int              numPoints;
5      Point            points[1];
6  };

 

LineString實際上是一個Point序列。由於C語言里面不能定義變長數據,所以WKBLineString里面定義了只有一個元素的數組points。
實際上points指向了一個由numPoints個元素構成的points數組。
前面定義的LinearRing結構與此類似。

8) WKBPolygon
1  struct WKBPolygon {
2      unsigned char    byteOrder;
3      int              wkbType;    // = 3;
4      int              numRings;
5      LinearRing       rings[1];
6  };
7  
 
        

 

9) WKBMultiPoint
1  struct WKBMultiPoint {
2      unsigned char    byteOrder;
3      int              wkbType;    //=4;
4      int              numPoints;
5      WKBPoint         points[1];
6  };
10) WKBMultiLineString
1  struct WKBMultiLineString {
2      unsigned char    byteOrder;
3      int              wkbType;    // = 5;
4      int              numLineStrings;
5      WKBLineString    lineStrings[1];
6  };
 
        

 

11) WKBMultiPolygon
1  struct WKBMultiPolygon {
2      unsigned char    byteOrder;
3      int              wkbType;    // = 6;
4      int              numPolygons;
5      WKBPolygon       polygons[1];
6  };
 
        

 WKB的完整數據結構如下所示

View Code
  1 #pragma pack(1)
  2   
  3   /*
  4    * 定義字節序枚舉
  5    */
  6   enum WKBByteOrder {
  7       wkbXDR,        // Big Endian    
  8       wkbNDR = 1     // Little Endian
  9   };
 10 
 11   /*
 12    * 定義默認字節序
 13    */
 14   #define coDefaultByteOrder wkbNDR  
 15 
 16   /*
 17    * 定義幾何數據類型枚舉
 18    */
 19   enum WKBGeometryType {
 20       wkbNull                ,
 21       wkbPoint                = 1,
 22       wkbLineString           = 2,
 23       wkbPolygon              = 3,
 24       wkbMultiPoint           = 4,
 25       wkbMultiLineString      = 5,
 26       wkbMultiPolygon         = 6,
 27       wkbGeometryCollection   = 7
 28   };
 29   
 30   /*
 31    * 定義點數據結構
 32    */
 33   struct Point{
 34       double x;
 35       double y;
 36   };
 37     
 38   /*
 39    * 定義環數據結構
 40    */
 41   struct LinearRing {
 42       int     numPoints;
 43       Point   points[1];
 44   };
 45   
 46   /*
 47    * 定義幾何信息枚舉,這個數據結構是所有WKB格式的頭部
 48    */
 49   struct WKBGeometryInfo{
 50       unsigned char    byteOrder;
 51       int              wkbType; 
 52   };
 53   
 54   /*
 55    * 定義Point類型WKB數據結構
 56    */
 57   struct WKBPoint{
 58       unsigned char    byteOrder;
 59       int              wkbType;    // = 1;
 60       Point            point;
 61   };
 62     
 63   /*
 64    * 定義LineString類型WKB數據結構
 65    */
 66   struct WKBLineString {
 67       unsigned char    byteOrder;
 68       int              wkbType;    // = 2;
 69       int              numPoints;
 70       Point            points[1];
 71   };
 72   
 73   /*
 74    * 定義Polygon類型WKB數據結構
 75    */
 76   struct WKBPolygon {
 77       unsigned char    byteOrder;
 78       int              wkbType;    // = 3;
 79       int              numRings;
 80       LinearRing       rings[1];
 81   };
 82   
 83   /*
 84    * 定義MultiPoint類型WKB數據結構
 85    */
 86   struct WKBMultiPoint {
 87       unsigned char    byteOrder;
 88       int              wkbType;    //=4;
 89       int              numPoints;
 90       WKBPoint         points[1];
 91   };
 92   
 93   /*
 94    * 定義MultiLineString類型WKB數據結構
 95    */
 96   struct WKBMultiLineString {
 97       unsigned char    byteOrder;
 98       int              wkbType;    // = 5;
 99       int              numLineStrings;
100       WKBLineString    lineStrings[1];
101   };
102     
103   /*
104    * 定義BMultiPolygon 類型WKB數據結構
105    */
106   struct WKBMultiPolygon {
107       unsigned char    byteOrder;
108       int              wkbType;    // = 6;
109       int              numPolygons;
110       WKBPolygon       polygons[1];
111   };
112  
113   #pragma pack()
 
        

 3.3 WKB數據訪問

1) WKBPoint

1 unsigned char* wkb;
2 WKBPoint* pWKBPoint = (WKBPoint*)wkb;
3 printf("%f,%f\n", pWKBPoint->point.x pWKBPoint->point.y);

 

2) WKBMultiPoint

 1 unsigned int numPoints = 0;
 2 WKBPoint* pWKBPoint = NULL;
 3 
 4 //Point個數
 5 numPoints = pWKBMultiPoint->numPoints;
 6 //獲得points數組的指針
 7 pWKBPoint = (WKBPoint*)(&(pWKBMultiPoint->points[0]));
 8 //遍歷points數組
 9 for(unsigned int i=0; i<numPoints; i++, pWKBPoint++)
10 {
11     printf("%f,%f\n", pWKBPoint->point.x pWKBPoint->point.y);
12 }
3) WKBLineString
 1 Point* pt=NULL;
 2 unsigned int numPoints = 0;
 3 
 4 //Point個數
 5 numPoints = pWKBLineString->numPoints;
 6 //獲得points數組的指針
 7 pt = (Point*)(&(pWKBLineString->points[0]));
 8 //遍歷points數組
 9 for(unsigned int i = 0; i<numPoints; i++,pt++, gdiPt++)
10 {
11     printf("%f,%f\n", pt->x pt->y);
12 }
4) WKBMultiLineString 
 1 Point *pt = NULL;
 2 WKBLineString* pWKBLineString = NULL;
 3 unsigned int numLineStrings = 0;
 4 
 5 //獲得LineString個數
 6 numLineStrings = pWKBMultiLineString->numLineStrings;
 7 
 8 //獲得LineString數組指針
 9 pWKBLineString = &(pWKBMultiLineString->lineStrings[0]);
10 for(unsigned int i=0; i<numLineStrings; i++)
11 {
12     //指向pWKBLineString的points數組首個元素的指針
13     pt = &(pWKBLineString->points[0]);
14     //訪問pWKBLineString數據
15     //......
16 
17     //pt指向pWKBLineString的points數組的末尾
18     //即pWKBMultiLineString的下一個pWKBLineString的頭部
19     pt += pWKBLineString->numPoints;
20     pWKBLineString = (auge::WKBLineString*)pt;
21 }
5) WKBPolygon
 1 unsigned int i=0,j=0;
 2 unsigned int numPoints = 0;
 3 unsigned int numRings = pWKBPolygon->numRings;
 4 Point *pt=NULL;
 5 LinearRing *pLinearRing = NULL;
 6 
 7 numRings = pWKBPolygon->numRings;
 8 pLinearRing = (auge::LinearRing*)(&(pWKBPolygon->rings[0]));    
 9 
10 for(i=0; i<numRings; i++)
11 {
12     numPoints = pLinearRing->numPoints;
13     //指向pLinearRing的points數組的首個元素
14     pt = (Point*)(&(pLinearRing->points[0]));
15     
16     //遍歷points數組
17     for(j = 0; j<numPoints; j++,pt++)
18     {
19         printf("%f,%f\n", point->x point->y);
20     }
21     
22     //遍歷完成后pt指向points數組的末尾,即pLinearRing的末尾,也就是下一個LinearRing的開始
23     pLinearRing = (LinearRing*)pt;
24 }

 

 6) MultiPolygon
 1 int numPoints = 0;
 2 int numLinearRing = 0;
 3 int numPolygons = 0;
 4 int i=0, j=0, k=0;
 5 
 6 Point         *pt=NULL;
 7 LinearRing    *pLinearRing = NULL;
 8 WKBPolygon    *pWKBPolygon = NULL;
 9 
10 
11 numPolygons = pWKBMultiPolygon->numPolygons;
12 pWKBPolygon = (WKBPolygon*)(&(pWKBMultiPolygon->polygons[0]));
13 
14 for(i=0; i<numPolygons; i++)
15 {    
16     numLinearRing = pWKBPolygon->numRings;
17     pLinearRing = (auge::LinearRing*)(&(pWKBPolygon->rings[0]));    
18     
19     for(j=0; j<numLinearRing; j++)
20     {
21         numPoints = pLinearRing->numPoints;
22         pt = (Point*)(&(pLinearRing->points[0]));
23         
24         for(k = 0; k<numPoints; k++,pt++)
25         {
26             printf("%f,%f\n", pt->x pt->y);
27         }
28         
29         pLinearRing = (auge::LinearRing*)pt;
30     }
31 
32     pWKBPolygon = (auge::WKBPolygon*)pLinearRing;
33 }
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM