MySQL中地理位置數據擴展geometry的使用心得

最近學習了些MySQL geometry數據存儲和計算,在這裏記錄下。html

1. 環境git

  geometry推薦在5.6版本以上使用,儘管大部分功能在5.5已經可用,除了距離計算函數st_distance等新增函數。函數

2. Geometry主要相關類學習

2.1 Geometry優化

  Geometry是全部此擴展中類型得基類,其餘類型如Point,LineString,Polygon都是Geometry的子類。Geometry有一些屬性,這些屬性是全部其餘幾何類的共有屬性:spa

  type: 類型(Point, LineString,...)htm

  SRID: 該值肯定了用於描述定義幾何對象的座標空間的空間座標系統,參考連接:https://www.cnblogs.com/Joetao/articles/2086846.html對象

  coordinates: 座標值blog

  interior, boundary, exterior: interior是幾何對象所展空間的部分,boundary是幾何對象的邊界,exterior是幾何對象未佔有的空間。索引

  MBR: 可以覆蓋幾何對象的最小矩形,能夠想象成信封,它由幾何對象中最大最小的座標值組合而成:

    ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

  simple/nonsimple: 幾何對象是否簡單

  closed/not closed: 幾何對象是否封閉

  dimension: 維度數(Point: 0, LineString: 1, Polygon: 2)

2.2 Point

  顧名思義就是點,有一個座標值,沒有長度、面積、邊界。

2.3 LineString

  顧名思義就是線,由一系列點鏈接而成。

  若是線從頭到尾沒有交叉,那就是簡單的(simple)

  若是起點和終點重疊,那就是封閉的(closed)

2.4 Polygon

  多邊形。能夠是一個實心平面形,即沒有內部邊界,也能夠有空洞,相似鈕釦。

2.5 MultiPoint, MultiLineString, MultiPolygon, GeometryCollection

  這4種類型都是集合類,是多個Point、LineString或Polygon組合在一塊兒而成。

3. 幾何對象在MySQL中的數據格式

  在MySQL中有3種表達幾何對象的格式:

  -->WKT(文本格式)

  -->WKB(二進制格式)

  -->MySQL內部存儲格式

  其中WKT格式簡單易讀,在這裏着重介紹:

3.1 WKT

3.1.1 Point

  POINT(121.213342 31.234532)

  經度(longitude)在前,維度(latitude)在後,用空格分隔

3.1.2 LineString

  LINESTRING(121.342423 31.542423,121.345664 31.246790,121.453178 31.456862)

  點與點之間用逗號分隔;一個點中的經緯度用空格分隔,與POINT格式一致

3.1.3 Polygon

  POLYGON((121.342423 31.542423,121.345664 31.246790,121.453178 31.456862),(121.563633 31.566652,121.233565 31.234565,121.568756 31.454367))

  由一個表示外部邊界的LineString和0個或多個表示內部邊界的LineString組成,最簡單的就是隻有一個外邊界的狀況:POLYGON((0 0,10,0 10 10, 0 10))

3.1.4 集合類格式

  MULTIPOINT(0 0, 20 20, 60 60)

  MULTILINESTRING((10 10, 20 20), (15 15, 30 15))

  MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))

  GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))

4. 幾何對象建立函數

  MySQL表中的幾何對象有它本身的內部格式,咱們須要將幾何對象從方便輸入的WKT格式轉換爲其內部格式,才能進行進一步的存儲,計算等。

  這裏主要講解使用WKT格式的函數,對於集合類對象的建立函數因爲較少使用也再也不列舉

  GeomFromText(wkt): 建立一個任何類型的幾何對象Geometry

  PointFromText(wkt): 建立一個Point對象

  LineStringFromText(wkt): 建立一個LineString對象

  PolygonFromText(wkt): 建立一個Polygon對象

5. 建立支持空間幾何對象的表

5.1 建立表

  如下是我建立的一個樣例:

  CREATE TABLE `t_geo_test` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `NAME` varchar(64) NOT NULL,
    `SHAPE` geometry NOT NULL,
    PRIMARY KEY (`ID`)
  ) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

  這裏的字段SHAPE就是存儲幾何對象的,類型爲geometry,能夠支持point,linestring,polygon等任意幾何對象。

  引擎須要使用MyISAM。

  表結構:

  

5.2 插入數據

5.2.1 插入點數據

  INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (1, 'P1', geomFromText('POINT(121.474103 31.232862)'));

5.2.2 插入線數據

  INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (2, 'L1', geomFromText('LINESTRING(121.474103 31.232862,121.472462 31.231339,121.471984 31.232821)'));

5.2.3 插入多邊形數據

  INSERT INTO `t_geo_test` (ID,NAME,SHAPE) VALUES (5, 'POLYGON_1', geomfromtext('POLYGON((121.474243 31.234504, 121.471775 31.233348, 121.470724 31.23155, 121.471603 31.230229, 121.472655 31.230357, 121.475777 31.232045, 121.474243 31.234504))'));

5.3 獲取數據

  AsText(): 此函數能將幾何對象的內部存儲格式轉換爲WKT格式

6. 經常使用函數

6.1 獲取幾何對象屬性的函數

  6.1.1 Geometry

    -->Dimension(g)

      返回對象g的維數

    -->Envelope(g)

      返回對象g的最小邊界矩形(MBR)。結類型爲Polygon值。

    -->GeometryType(g)

      以字符串形式返回幾何類型的名稱,如POINT,LINESTRING

    -->IsClosed(g)

      返回對象g是否封閉

    -->IsSimple(g)

      返回對象g是否簡單

  6.1.2 Point

    -->X(p)

      以雙精度數值返回點p的X座標值(經度)。

    -->Y(p)

      以雙精度數值返回點p的Y座標值(緯度)。

  6.1.3 LineString

    -->EndPoint(line)

      返回對象line的最後一個點Point

    -->StartPoint(line)

      返回對象line的第一個點Point

    -->PointN(line, N)

      返回對象line中第N個點,N從1開始

  6.1.4 Polygon

    -->ExteriorRing(poly)

      返回對象poly的外環,類型爲LineString

    -->InteriorRingN(poly, N)

      返回對象poly的第N個內環,N從1開始

    -->NumInteriorRings(poly)

      返回對象poly的neihuan個數

6.2 從現成幾何對象建立新的對象

6.2.1 st_union(g1, g2)

  將g1和g2合併爲一個集合類對象

  SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
  SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');

  SELECT st_union(@g1, @g2);

  結果:

  POLYGON((121.472655 31.230157, 121.471903 31.230229, 121.471898134093 31.2302649098516, 121.471603 31.230229, 121.470724 31.23155, 121.471761757556 31.2333253454665, 121.471775 31.233948, 121.474243 31.234804, 121.474597 31.2339365384615, 121.475777 31.232045, 121.475442678789 31.2318642395248, 121.475777 31.231045, 121.472655 31.230157))

6.2.2 st_difference(g1, g2)

  返回幾何對象,該對象表示了幾何值g1與g2的點集合差別

  SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
  SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');
  SELECT st_difference(@g1,@g2);

  結果:

  MULTIPOLYGON(((121.471603 31.230229, 121.470724 31.23155, 121.471761757556 31.2333253454665, 121.471724 31.23155, 121.471898134093 31.2302649098516, 121.471603 31.230229)), ((121.475442678789 31.2318642395248, 121.474597 31.2339365384615, 121.475777 31.232045, 121.475442678789 31.2318642395248)))

 

6.2.3 st_intersection(g1,g2)

  返回幾何對象,該對象表示了幾何值g1與g2的點集合交集

  SET @g1 = geomFromText('POLYGON((121.474243 31.234504,121.471775 31.233348,121.470724 31.23155,121.471603 31.230229,121.472655 31.230357,121.475777 31.232045,121.474243 31.234504))');
  SET @g2 = geomFromText('POLYGON((121.474243 31.234804,121.471775 31.233948,121.471724 31.23155,121.471903 31.230229,121.472655 31.230157,121.475777 31.231045,121.474243 31.234804))');

  SELECT st_intersection(@g1,@g2);

  結果:

  POLYGON((121.471898134093 31.2302649098516, 121.471724 31.23155, 121.471761757556 31.2333253454665, 121.471775 31.233348, 121.474243 31.234504, 121.474597 31.2339365384615, 121.475442678789 31.2318642395248, 121.472655 31.230357, 121.471898134093 31.2302649098516))

6.3 幾何對象之間空間關係的函數

6.3.1 st_contains(g1, g2)

  返回1: g1徹底包含g2;返回0: g1未包含g2

6.3.2 st_crosses(g1, g2), st_intersects(g1, g2)

  返回1: g1與g2相交;返回0:g1與g2未相交

6.3.3 st_disjoint(g1, g2)

  是st_crosses的反函數

6.3.4 st_within(g1, g2)

  g1在g2內則返回1,不然返回0

7. 空間索引

對錶中的geometry類型的字段進行索引能夠優化搜索,MySQL中經過對Geometry對象的MBR建立索引

建立:

CREATE SPATIAL INDEX i_shape ON `t_geo_test`(SHAPE);

刪除:

DROP INDEX i_shape ON `t_geo_test`;

8.一些注意事項

8.1 目前MySQL中支持的空間座標系統沒有gcj02,bd09等國內座標系,默認使用WGS84地球座標系,因此在建立幾何對象時輸入的座標值儘可能使用WGS84座標,以免偏差。

8.2 MySQL中的計算距離,長度,面積等絕對數值的空間計算函數(area(), GLength(), st_distance())存在必定的偏差,儘可能不要使用。

相關文章
相關標籤/搜索