MySQL空間數(shù)據(jù)存儲及函數(shù)
前言:
不久前開發(fā)了一個地圖相關(guān)的后端項目,需要提供一些點線面相關(guān)的存儲、查詢、分析相關(guān)的操作,于是對MySQL空間函數(shù)進行充分調(diào)研并應(yīng)用在項目中;MySQL為空間數(shù)據(jù)存儲及處理提供了專用的類型geometry(支持所有的空間結(jié)構(gòu)),還有有細分類型Point
, LineString
, Polygon
,MultiPoint
,MultiLineString
,MultiPolygon
等等,我們了解了空間函數(shù),在涉及到經(jīng)緯度存儲,路線存儲方面的業(yè)務(wù)就能夠使用此類型進行存儲,使用相關(guān)空間函數(shù)進行分析業(yè)務(wù)實現(xiàn),以下所有數(shù)據(jù)庫操作基于MySQL5.7.20
。
一、數(shù)據(jù)類型
1.什么是MySQL空間數(shù)據(jù)
- MySQL提供了數(shù)據(jù)類型
geometry
用來存儲坐標信息,geometry類型支持以下三種數(shù)據(jù)存儲

還有多點
MULTIPOINT
(多點)、MULTILINESTRING
(多線)、MULTIPOLYGON
(多面)、GEOMETRYCOLLECTION
(集合,可放入點線面)等類型
2.什么是geojson
GeoJSON
是一種對各種地理數(shù)據(jù)結(jié)構(gòu)進行編碼的格式。GeoJSON對象可以表示幾何、特征或者特征集合。GeoJSON
支持下面幾何類型:點、線、面、多點、多線、多面和幾何集合。GeoJSON
里的特征包含一個幾何對象和其他屬性,特征集合表示一系列特征。一個完整的GeoJSON數(shù)據(jù)結(jié)構(gòu)總是一個(JSON術(shù)語里的)對象。在GeoJSON里,對象由名/值對--也稱作成員的集合組成。對每個成員來說,名字總是字符串。成員的值要么是字符串、數(shù)字、對象、數(shù)組,要么是下面文本常量中的一個:"true
","false
"和"null
"。數(shù)組是由值是上面所說的元素組成
除了簡單的點、線、面,為了滿足復(fù)雜的地理環(huán)境及地圖業(yè)務(wù),還會有多點(
MultiPoint
),多線(MultiLineString
),多面(MultiPolygon
),幾何集合(GeometryCollection
)等,熟悉json就可以快速的熟悉并應(yīng)用geojson
3.格式化空間數(shù)據(jù)類型(geometry相互轉(zhuǎn)換geojson)
數(shù)據(jù)庫存儲的空間數(shù)據(jù)通過可視化工具展示的明文結(jié)構(gòu)為上面示例中所見,結(jié)構(gòu)并不易于客戶端解析,所以MySQL提供了幾個空間函數(shù)用來解析及格式化空間數(shù)據(jù),
geojson
是gis空間數(shù)據(jù)展示的標準格式,前端地圖框架及后端空間分析相關(guān)框架都會支持geojson
格式
示例:
準備示例數(shù)據(jù)
函數(shù)應(yīng)用示例
1.查詢綠藤氣象監(jiān)測點信息將geometry處理成geojson格式
執(zhí)行sql:
select id,point_name,ST_ASGEOJSON(point_geom) as geojson from meteorological_point where id = 1
查詢結(jié)果:
2.新增一個點位信息,客戶端提交的點位geometry字符串需要使用ST_GEOMFROMTEXT函數(shù)處理才能插入,否則會報錯
客戶端提交點位信息
{ "point_name":"新帥集團監(jiān)測點", "geotext":"POINT(117.420671499 40.194914201)"} }
錯誤示例:
insert into meteorological_point(point_name, point_geom) values("新帥集團監(jiān)測點", "POINT(117.420671499 40.194914201)")
報錯 1416 - Cannot get geometry object from data you send to the GEOMETRY field
正確插入sql:
insert into meteorological_point(point_name, point_geom) values("新帥集團監(jiān)測點", ST_GEOMFROMTEXT("POINT(117.420671499 40.194914201)"))
3.新增點位,客戶端提交點位格式為geojson格式,需要使用ST_GeomFromGeoJSON函數(shù)處理后進行插入
客戶端提交點位信息
{ "point_name":"民爆公司監(jiān)測點", "geojson":"{"type": "Point", "coordinates": [117.410671499, 40.1549142015]}"} }
插入SQL
insert into meteorological_point(point_name, point_geom) values("民爆公司監(jiān)測點", ST_GeomFromGeoJSON("{\"type\": \"Point\", \"coordinates\": [117.410671499, 40.1549142015]}"))
空間數(shù)據(jù)格式化小結(jié)
mysql geometry
數(shù)據(jù)存儲需要對geometry
文本或geojson
進行函數(shù)處理后才能進行存儲,否則會報錯,查詢時候使用格式化函數(shù)轉(zhuǎn)成geojson
方便服務(wù)端傳輸和客戶端框架解析
二、空間分析
在上一部分介紹了空間函數(shù)存儲,查詢格式化處理相關(guān)的操作,了解空間數(shù)據(jù)結(jié)構(gòu)及geojson,這一部分介紹空間數(shù)據(jù)處理函數(shù)的應(yīng)用
1、根據(jù)點位及半徑,生成緩沖區(qū)
在地圖功能中,緩沖區(qū)是非常常見的功能,一來可以查看點線面一定范圍類的覆蓋區(qū)域,二來在一些分析場景中,已知一個位子坐標信息及緩沖半徑,生成緩沖區(qū)作為查詢條件進行地理搜索
SELECT ST_ASGEOJSON(ST_BUFFER(ST_GeomFromGeoJSON('${geojsonStr}'),${radius}))
SQL解讀
調(diào)用方傳來一個geojson字符串及半徑(米),使用
ST_GeomFromGeoJSON
將geojson
字符串處理成數(shù)據(jù)庫中的geometry
,再使用ST_BUFFER(geometry
, 半徑)s生成緩沖區(qū)空間數(shù)據(jù),函數(shù)返回的格式也是geometry,所以在外面包一層ST_ASGEOJSON
函數(shù)將返回結(jié)果處理成geojson,便于客戶端讀取及渲染
示例:
- 有一個點位的geojson字符串為 "{"type": "Point", "coordinates": [117.410671499, 40.1549142015]}",緩沖半徑50米(注意:ST_BUFFER()的參數(shù)地理信息及返回值均使用墨卡托坐標系,如非墨卡托坐標系的geojson,需使用工具類進行轉(zhuǎn)換處理)
public class MercatorUtils { /** * 點位geojson轉(zhuǎn)墨卡托 * * @param point * @return */ public static JSONObject point2Mercator(JSONObject point) { JSONArray xy = point.getJSONArray(COORDINATES); JSONArray mercator = lngLat2Mercator(xy.getDouble(0), xy.getDouble(1)); point.put(COORDINATES, mercator); return point; } /** * 經(jīng)緯度轉(zhuǎn)墨卡托 */ public static JSONArray lngLat2Mercator(double lng, double lat) { double x = lng * 20037508.342789 / 180; double y = Math.log(Math.tan((90 + lat) * M_PI / 360)) / (M_PI / 180); y = y * 20037508.34789 / 180; JSONArray xy = new JSONArray(); xy.add(x); xy.add(y); return xy; } /** * 墨卡托坐標系數(shù)據(jù)轉(zhuǎn)普通坐標系 */ public static JSONObject mercatorPolygon2Lnglat(JSONObject polygon) { JSONArray coordinates = polygon.getJSONArray(COORDINATES); JSONArray xy = coordinates.getJSONArray(0); JSONArray ms = new JSONArray(); for (int i = 0; i < xy.size(); i++) { JSONArray p = xy.getJSONArray(i); JSONArray m = mercator2lngLat(p.getDouble(0), p.getDouble(1)); ms.add(m); } JSONArray newCoordinates = new JSONArray(); newCoordinates.add(ms); polygon.put(COORDINATES, newCoordinates); return polygon; } }
轉(zhuǎn)換后的geojson
就可以作為上面緩沖區(qū)的sql生成緩沖區(qū)空間數(shù)據(jù)了,生成的緩沖區(qū)數(shù)據(jù)也是墨卡托坐標系,需使用mercatorPolygon2Lnglat
進行處理后返回給客戶端,調(diào)用流程如下:
- 客戶端提交點位
geojson
及半徑 - 使用墨卡托工具類將點位
geojson
轉(zhuǎn)換成墨卡托坐標系的geojson
- 調(diào)用sql進行緩沖區(qū)生成
- 返回值使用墨卡托工具類轉(zhuǎn)換成
mercatorPolygon2Lnglat
返回給調(diào)用方
小結(jié):
上面介紹如何使用mysql st_buffer
函數(shù)生成緩沖區(qū),實際操作起來經(jīng)過我在研發(fā)中的應(yīng)用是可行的,實際開發(fā)中還可以使用一些工具包來實現(xiàn)緩沖區(qū)生成,如geotools...
三、判斷點位所在城市
- 判斷用戶點位所在城市-客戶端提交用戶的定位信息,判斷用戶所在城市(使用ST_INTERSECTS()判斷兩個幾何是否相交即可,返回0或1)
SELECT ST_INTERSECTS(ST_GeomFromGeoJSON('${geoJsonStrA}'), ST_GeomFromGeoJSON('${geoJsonStrB}'))
SQL解讀:
使用格式化函數(shù)將geojson
處理成函數(shù)支持的geomtry格式,使用ST_INTERSECTS
進行判斷即可
四、常用的空間函數(shù)
總結(jié):
MySQL
為空間數(shù)據(jù)的存儲及分析提供了豐富的數(shù)據(jù)類型及函數(shù),我們學習此類函數(shù)能夠幫助我們更好的處理地理信息,使用前需要對坐標系、geojson
相關(guān)知識進行了解,避免踩坑,如果有相關(guān)問題也可以在評論區(qū)交流,如有誤區(qū)請指正。
到此這篇關(guān)于MySQL空間數(shù)據(jù)存儲及函數(shù)的文章就介紹到這了,更多相關(guān)MySQL空間數(shù)據(jù)存儲及函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Win2003服務(wù)器安裝及設(shè)置教程 MySQL安全設(shè)置圖文教程
Win2003服務(wù)器安裝及設(shè)置教程,一般腳本之家為客戶都是將MySQL運行于普通用戶下,這樣才會盡量避免提權(quán),新建用戶什么的2012-05-05開源MySQL高效數(shù)據(jù)倉庫解決方案:Infobright詳細介紹
這篇文章主要介紹了開源MySQL高效數(shù)據(jù)倉庫解決方案:Infobright詳細介紹,本文講解了Infobright特征、Infobright的價值、Infobright的適用場景、與MySQL對比等內(nèi)容,需要的朋友可以參考下2015-03-03MySQL數(shù)據(jù)庫常用操作和技巧(DBA必備知識)
MySQL數(shù)據(jù)庫可以說是DBA們最常見和常用的數(shù)據(jù)庫之一,為了方便大家使用,老MySQL DBA總結(jié)了MySQL數(shù)據(jù)庫最常見和最常使用的一些經(jīng)驗和技巧,與分享大家!2011-03-03MySQL數(shù)據(jù)庫基礎(chǔ)篇SQL窗口函數(shù)示例解析教程
這篇文章主要為大家介紹了MySQL數(shù)據(jù)庫基礎(chǔ)篇之窗口函數(shù)示例解析教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2021-10-10MySQL5.1主從同步出現(xiàn)Relay log read failure錯誤解決方法
這篇文章主要介紹了MySQL5.1主從同步出現(xiàn)Relay log read failure錯誤解決方法,需要的朋友可以參考下2014-07-07在Windows環(huán)境下安裝MySQL 的教程圖解
這篇文章主要介紹了在Windows環(huán)境下安裝MySQL 的教程圖解,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07