javascript
GeoJSON初探
? ? ? ?
????????最近在做數據可視化的時候,提到了一種 GeoJSON 格式的數據,在此進行一下梳理。
1 簡介
????????GeoJSON是一種對各種地理數據結構進行編碼的格式。GeoJSON對象可以表示幾何、特征或者特征集合。GeoJSON支持下面幾何類型:點、線、面、多點、多線、多面和幾何集合。GeoJSON里的特征包含一個幾何對象和其他屬性,特征集合表示一系列特征。
????????一個完整的GeoJSON數據結構總是一個(JSON術語里的)對象。在GeoJSON里,對象由名/值對--也稱作成員的集合組成。
例:
{"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "Point","coordinates": [102.0, 0.5]},"properties": {"prop0": "value0"}},{"type": "Feature","geometry": {"type": "LineString","coordinates": [[102.0, 0.0],[103.0, 1.0],[104.0, 0.0],[105.0, 1.0]]},"properties": {"prop0": "value0","prop1": 0.0}},{"type": "Feature","geometry": {"type": "Polygon","coordinates": [[[100.0, 0.0],[101.0, 0.0],[101.0, 1.0],[100.0, 1.0],[100.0, 0.0]]]},"properties": {"prop0": "value0","prop1": {"this": "that"}}}] }?2 GeoJSON 對象
????????GeoJSON總是由一個單獨的對象組成。這個對象(指的是下面的GeoJSON對象)表示幾何、特征或者特征集合。
- GeoJSON對象可能有任何數目成員(名/值對)。
- GeoJSON對象必須由一個名字為"type"的成員。這個成員的值是由GeoJSON對象的類型所確定的字符串。
- ?type成員的值必須是下面之一:"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon",??? "MultiPolygon",?? "GeometryCollection", "Feature", 或者 "FeatureCollection"。
- GeoJSON對象可能有一個可選的"crs"成員,它的值必須是一個坐標參考系統的對象。
- GeoJSON對象可能有一個"bbox"成員,它的值必須是邊界框數組。
可以在?http://geojson.io?查看效果
2.1 幾何對象
????????幾何是一種GeoJSON對象,這時type成員的值是下面字符串之一:"Point", "MultiPoint", "LineString", "MultiLineString",? "Polygon", "MultiPolygon", 或者"GeometryCollection"。
????????除了“GeometryCollection”外的其他任何類型的GeoJSON幾何對象必須由一個名字為"coordinates"的成員。coordinates成員的值總是數組。這個數組里的元素的結構由幾何類型來確定。
2.1.1 點 Point
{"type": "Point","coordinates": [100.0, 0.0] }2.1.2 多點 MultiPoint
{"type": "MultiPoint","coordinates": [[100, 0],[101, 1]] }2.1.3 線 LineString
{"type": "LineString","coordinates": [[100, 0],[101, 1]] }2.1.4 多線 MultiLineString
{"type": "MultiLineString","coordinates": [[ [100.0, 0.0], [101.0, 1.0] ],[ [102.0, 2.0], [103.0, 3.0] ]] }2.1.5 多邊形 Polyon
無孔的
{"type": "Polygon","coordinates": [[[ 100, 0 ],[ 101, 0 ],[ 101, 1 ],[ 100, 1 ],[ 100, 0 ]]] }有孔的
{"type": "Polygon","coordinates": [[[ 100, 0 ],[ 101, 0 ],[ 101, 1 ],[ 100, 1 ],[ 100, 0 ]],[[ 100.2, 0.2 ],[ 100.8, 0.2 ],[ 100.8, 0.8 ],[ 100.2, 0.8 ],[ 100.2, 0.2 ]]] }2.1.6 復合多邊形 MultiPolyon
不相交的多邊形
{"type": "MultiPolygon","coordinates": [[[[109.2041015625, 30.088107753367257],[115.02685546875, 30.088107753367257],[115.02685546875, 32.7872745269555],[109.2041015625, 32.7872745269555],[109.2041015625, 30.088107753367257]]],[[[112.9833984375, 26.82407078047018],[116.69677734375, 26.82407078047018],[116.69677734375, 29.036960648558267],[112.9833984375, 29.036960648558267],[112.9833984375, 26.82407078047018]]]] }兩個嵌套的多邊形
{"type": "MultiPolygon","coordinates": [[[[101.6455078125, 27.68352808378776],[114.78515624999999, 27.68352808378776],[114.78515624999999, 35.209721645221386],[101.6455078125, 35.209721645221386],[101.6455078125, 27.68352808378776]]],[[[104.2822265625, 30.107117887092357],[108.896484375, 30.107117887092357],[108.896484375, 33.76088200086917],[104.2822265625, 33.76088200086917],[104.2822265625, 30.107117887092357]]]] }有孔洞的多邊形
{"type": "MultiPolygon","coordinates": [[[[101.6455078125, 27.68352808378776],[114.78515624999999, 27.68352808378776],[114.78515624999999, 35.209721645221386],[101.6455078125, 35.209721645221386],[101.6455078125, 27.68352808378776]],[[104.2822265625, 30.107117887092357],[108.896484375, 30.107117887092357],[108.896484375, 33.76088200086917],[104.2822265625, 33.76088200086917],[104.2822265625, 30.107117887092357]]]] }2.1.7 幾何集合 GeometryCollection
????????是多種基本地理要素的集合,就是里面可以包含點、線、面要素
{"type": "GeometryCollection","geometries": [{"type": "Point","coordinates": [108.62, 31.02819]}, {"type": "LineString","coordinates": [[108.896484375, 30.1071178870],[108.2184375, 30.91717870],[109.5184375, 31.2175780]]}] }2.2 特征對象
- 類型為 Feature 的 GeoJSON 對象是特征對象
- 特征對象必須由一個名字為"geometry"的成員,這個幾何成員的值是上面定義的幾何對象或者JSON的null值。
- 特征對戲那個必須有一個名字為“properties"的成員,這個屬性成員的值是一個對象(任何JSON對象或者JSON的null值)
2.3 特征集合對象
- 特征集合對象type為FeatureCollection。
- 特征集合對象必須由一個名字為"features"的成員。與“features"相對應的值是一個數組。這個數組中的每個元素都是上面定義的特征對象。
3 在各個數據庫中的應用
3.1 mysql
1 geometry 類型
????????MySQL提供了數據類型geometry用來存儲坐標信息,geometry類型支持以下三種數據存儲
| 數據結構 | 示例 | 說明 |
| POINT(點) | POINT(113.3 40.08) | 用于存儲點位信息,包含經緯度信息 |
| LINESTRING(線) | LineString(84.070 33.801,99.52 30.292) | 用來存儲路線信息 |
| POLYGON(面) | POLYGON((84.070 33.801, 84.100 33.801,84.070 33.801)) | 用來存儲面數據 |
2 格式化空間數據類型
????????數據庫存儲的空間數據通過可視化工具展示的明文結構為上面示例中所見,結構并不易于客戶端解析,所以MySQL提供了幾個空間函數用來解析及格式化空間數據,geojson是gis空間數據展示的標準格式,前端地圖框架及后端空間分析相關框架都會支持geojson格式
| 操作 | 函數 |
| geojson -> geometry | ST_GeomFromGeoJSON |
| geometry -> geojson | ST_ASGEOJSON |
| geometry字符串 -> geometry | ST_GEOMFROMTEXT |
?3 示例
新建表
CREATE TABLE `geojson` (`id` int(0) NOT NULL AUTO_INCREMENT,`geojson` geometry NULL,PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;?插入數據
insert into geojson(geojson) VALUES (ST_GeomFromGeoJSON('{"type": "Point", "coordinates": [121.0, 31.0]}'));查詢
select id,ST_AsGeoJSON(geojson) as geojson from geojson;常用的空間函數
| 名稱 | 描述 |
| ST_INTERSECTS() | 判斷兩個幾何是否相交 |
| ST_DISTANCE() | 兩個幾何的距離 |
| ST_CONTAIONS() | 幾何是否包含 |
| ST_ISVALID() | 幾何是否有效 |
| ST_WITHIN() | 幾何是否在里面,結果與ST_CONTAIONS()相反 |
3.2 mongodb
1 支持地理空間索引
- 2dsphere 索引
- 用于地球表面類型的地圖上
- 可以使用在 Legacy Coordinate Paris 保存的經緯度字段上和使用 GeoJSON 格式保存的點、線、多邊形字段上
- 2d 索引
- 對于非球面(游戲地圖,時間連續的數據等),可以使用 2d 索引代替 2dsphere
- 支持平面查詢和一些球形查詢,但是球形支持不是很好
- 只能對點進行索引
2 支持地理空間查詢
????????主要支持 交集(intersection),包含(within),以及接近(nearness)
- $geoIntersects
- 指出與查詢位置相交的文檔
- 支持操作符
- $geometry 指定 GeoJSON 格式的幾何圖形
- $geoWithin
- 指出完全包含在某個區域的文檔
- 支持操作符
- $box
- 查出矩形范圍內的所有文檔
- $center
- 查出圓形范圍內的所有文檔
- $polygon
- 查出多邊形范圍內的所有文檔
- $centerSphere
- 查詢出球面圓形范圍內的所有文檔
- $geometry
- 指定 GeoJSON 格式的幾何圖形
- $box
- $near
- 指出與查詢位置從最近到最遠的文檔
- 支持操作符
- $maxDistance
- 指定查詢結果的最大距離
- $minDistance
- 指定查詢結果的最小距離
- $geometry
- 指定 GeoJSON 格式的點
- $maxDistance
- $nearSphere
- 使用球面幾何計算近球面的距離,指出與查詢位置從最近到最遠的文檔
- 支持操作符
- $maxDistance
- 指定查詢結果的最大距離
- $minDistance
- 指定查詢結果的最小距離
- $geometry
- 指定 GeoJSON 格式的點
- $maxDistance
????????查詢位置相交的文檔
db.getCollection('GeoEntity').find({location: {$geoIntersects: {$geometry: {type: "Polygon" ,coordinates: [[ [ 30, 20 ], [ 30, 40 ], [ 40, 40 ],[ 40, 20 ],[ 30, 20 ]]]}}}})????????查詢交叉位置的文檔
db.getCollection('GeoEntity').find({ location: { $geoWithin: { $box: [ [ 30, 30 ], [ 32, 33 ]] } } })3.3 redis
1 地理空間命令
- geoadd
- geoadd key longitude latitude member [ longitude latitude member ... ]
- 將指定的空間元素添加到指定的 key 里
- geodist
- geodist key member1 member2 [ unit ]
- unit 代表單位
- 返回指定位置之間的距離
- geohash
- geohash key member [ member ... ]
- 返回一個標準的地理空間的 geohash 字符串
- geopos
- geopos key member [ member ... ]
- 返回地理空間的經緯度
- georadius
- georadius key longitude latitude radius m|km|ft|mi [ WITHCOORD ] [ WITHDIST ] [ WITHHASH ] [ COUNT count ]
- 查詢指定半徑范圍內所有地理空間元素的集合
- longitude 經度
- latitude 緯度
- radius 半徑距離數
- WITHDIST 將位置元素的中心之間的距離也一并返回
- WITHCOORD 將位置元素的經度和緯度也一并返回
- WITHHASH 以 52 位有符號整數的形式返回
- COUNT 返回所有匹配位置前 count 元素
- georadiusbymember
- georadiusbymember key member radius m|km|ft|mi [ WITHCOORD ] [ WITHDIST ] [ WITHHASH ] [ COUNT count ]
- 查詢指定半徑內匹配到的最大距離的一個地理空間元素
總結
- 上一篇: Android音视频API - Medi
- 下一篇: gradle idea java ssm