MySQL 4.1+ 內置 Spatial Extensions,遵循 OGC OpenGIS 標準,使用 WKT (Well-Known Text) / WKB (Well-Known Binary) 格式存儲。
Geometry (抽象基類)
├── Point -- 已支持
├── Curve
│ └── LineString -- 已支持
│ ├── Line
│ └── LinearRing
├── Surface
│ └── Polygon -- 已支持
├── GeometryCollection -- 已支持
│ ├── MultiPoint -- 已支持
│ ├── MultiCurve
│ │ └── MultiLineString -- 已支持
│ └── MultiSurface
│ └── MultiPolygon -- 已支持
注意:僅 MyISAM 表支持空間索引 (SPATIAL INDEX),InnoDB 5.7.5+ 開始支持。
CREATE TABLE geo_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
geo GEOMETRY NOT NULL,
SPATIAL INDEX idx_geo (geo)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- 插入點
INSERT INTO geo_table (geo) VALUES (GeomFromText('POINT(116.39 39.91)'));
-- 插入線串 (折線)
INSERT INTO geo_table (geo) VALUES (GeomFromText('LINESTRING(0 0, 1 1, 2 2)'));
-- 插入多邊形 (外環 + 可選內環/孔)
INSERT INTO geo_table (geo) VALUES (GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'));
-- 插入多點/多線/多面
INSERT INTO geo_table (geo) VALUES (GeomFromText('MULTIPOINT((0 0), (1 1))'));
INSERT INTO geo_table (geo) VALUES (GeomFromText('MULTILINESTRING((0 0, 1 1), (2 2, 3 3))'));
INSERT INTO geo_table (geo) VALUES (GeomFromText('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)), ((20 20, 30 20, 30 30, 20 30, 20 20)))'));
| 函數 | 用途 | 示例 |
|---|---|---|
AsText(geo) / AsWKB(geo) | 轉為可讀文本/二進制 | SELECT id, AsText(geo) FROM geo_table; |
MBRIntersects(g1, g2) | 最小外接矩形相交判斷 (利用空間索引) | SELECT * FROM geo_table WHERE MBRIntersects(geo, GeomFromText('POLYGON((...))')); |
MBRWithin(g1, g2) | g1 的 MBR 完全在 g2 內 | 同上 |
MBRContains(g1, g2) | g1 的 MBR 包含 g2 | 同上 |
Distance(g1, g2) | 兩幾何對象最小距離 | SELECT Distance(GeomFromText('POINT(0 0)'), GeomFromText('POINT(3 4)')); → 5 |
Area(poly) | 多邊形面積 | SELECT Area(geo) FROM geo_table WHERE id=3; |
Centroid(poly) | 幾何中心點 | SELECT AsText(Centroid(geo)) FROM geo_table WHERE id=3; |
Buffer(g, d) | 緩衝區 (MySQL 5.6+) | SELECT AsText(Buffer(GeomFromText('POINT(0 0)'), 1)); |
GEOMETRY 或具體子類型 (POINT 等)NOT NULLSPATIAL INDEXMBR... 系列函數-- 定義查詢窗口 (西經, 南緯, 東經, 北緯)
SET @bbox = GeomFromText('POLYGON((116.3 39.8, 116.5 39.8, 116.5 40.0, 116.3 40.0, 116.3 39.8))');
SELECT id, AsText(geo),
MBRWithin(geo, @bbox) AS fully_inside,
MBRIntersects(geo, @bbox) AS intersects
FROM geo_table
WHERE MBRIntersects(geo, @bbox);
MySQLGeometryLayer.java 為完整 WebGIS 集成參考