最近在做数据可视化的时候,提到了一种 GeoJSON 格式的数据,在此进行一下梳理。
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"
}
}
}
]
}
GeoJSON总是由一个单独的对象组成。这个对象(指的是下面的GeoJSON对象)表示几何、特征或者特征集合。
可以在 http://geojson.io 查看效果
几何是一种GeoJSON对象,这时type成员的值是下面字符串之一:"Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", 或者"GeometryCollection"。
除了“GeometryCollection”外的其他任何类型的GeoJSON几何对象必须由一个名字为"coordinates"的成员。coordinates成员的值总是数组。这个数组里的元素的结构由几何类型来确定。
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
{
"type": "MultiPoint",
"coordinates": [
[100, 0],
[101, 1]
]
}
{
"type": "LineString",
"coordinates": [
[100, 0],
[101, 1]
]
}
{
"type": "MultiLineString",
"coordinates": [
[ [100.0, 0.0], [101.0, 1.0] ],
[ [102.0, 2.0], [103.0, 3.0] ]
]
}
无孔的
{
"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 ]
]
]
}
不相交的多边形
{
"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]
]
]
]
}
是多种基本地理要素的集合,就是里面可以包含点、线、面要素
{
"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]
]
}]
}
{
"type":"Feature",
"properties":{},
"geometry":{ "type": "Point", "coordinates": [100.0, 0.0] }
}
{
"type": "FeatureCollection",
"features": []
}
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()相反 |
SELECT
id,
ST_AsGeoJSON ( geojson ) AS geojson
FROM
geojson
WHERE
ST_CONTAINS (
ST_GeomFromText ( 'POLYGON((100 30,120 30,120 36,100 36,100 30))' ),
geojson
)
1 支持地理空间索引
db.world.ensureIndex({"geometry" : "2dsphere"})
2 支持地理空间查询
主要支持 交集(intersection),包含(within),以及接近(nearness)
查询位置相交的文档
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 ]] } } })
1 地理空间命令