標籤:
當SNS產品加入LBS的技術將會讓移動互連網領域更加豐富多彩,例如:福士點評,街旁,盛大切客 這些運行在智能手機端的應用,當使用者拿出手機就可以根據你當前的所在地向你推薦一些有用的資訊,例如:附近的美食,商鋪,周邊生活資訊,等。
攻城師們,你有沒有想過這些應用背後的技術實現呢?手機端獲得當前的座標後是怎麼進行計算和查詢返回附件的結果呢?
用Java程式可以實現Dijkstra演算法獲得點與多點之間最短路徑的計算結果,但是我個人認為是一種暴力的方法,開發的簡化程度和計算的執行效率不會非常高。
參考資料:http://baike.baidu.com/view/7839.htm
接著再往下想,用到資料庫技術是必然,但不會把節點的座標資訊儲存到資料庫普通的欄位中進行查詢,如果和Dijkstra演算法相比不會簡化工作量也不會提高效能,但使用到MySQL中空間資料庫的概念就會簡化很多也會得到效能的提升,開源的MySQL Spatial空間索引機制就可以對點到多點之間的距離計算,類似的Spatial Database還有,PostGIS,SpatiaLite。
我的廢話:
在android手機上獲得當前座標後,將資料整好錄入android中的SQLite資料庫也可以獲得當前點對多點的最短路徑,也就是說在地理資料不會更新的情境下完全可以採用android手機上的資料庫完成這項工作,沒有必要非要利用伺服器端的Spatial Database完成最短路徑的計算。
MySQL空間資料幾種主要類型:
– GEOMETRY Geometry是階層的根類。它是一種非執行個體化類,但具有很多屬性,這些屬性對由任何Geometry子類建立的所有幾何值來說是共同的。
– POINT 代表座標空間中單個位置的幾何類,他的屬性包含 X-座標值,Y-座標值。
– LINESTRING 具有線段的座標,由每個連續的點對(兩點)定義。如果僅包含兩點,LineString為Line。 如果它既是簡單的也是封閉的,LineString為LinearRing。
– POLYGON 它由單個外部邊界以及0或多個內部邊界定義,其中,每個內部邊界定義為Polygon中的1個孔。例如:在地區地圖上,Polygon對象可表示森林。
– MULTIPOINT MultiPoint是一種由Point元素構成的幾何對象集合。這些點未以任何方式串連或排序。
– MULTILINESTRING MultiLineString是一種由 LineString元素構成的MultiCurve幾何對象集合,例如:河流體系或高速路系統。
– MULTIPOLYGON MultiPolygon是一種由Polygon元素構成的幾何對象集合。在地區地圖上,MultiPolygon可表示湖泊系統。
– GEOMETRYCOLLECTION 他是由1個或多個任意類幾何對象構成的幾何對象。GeometryCollection中的所有元素必須具有相同的空間參考系(即相同的座標系).
以上幾種的類型依賴關係,:
瞭解過上述一些基本知識,下面來建立一張商戶表,並且包含定義的空間資料庫的POINT欄位:
Create table shop (
shop_id int(3) primary key,
Location POINT,
Shop_na vachar(100),
Shop_info vachar(300)
);
插入幾條商家的門店資訊,其中採用GeomFromText方法將座標的資料庫插入POINT欄位中,例如:
insert into shop values (‘XXX’,’,GeomFromText(‘POINT(1 1)’),’XX店’,’ ‘其他資訊‘);
下面將根據客戶當前所在位置在MySQL中查詢,搜尋出在當前位置附近的一定範圍內的門店,並且可以做到按距離由近到遠排列顯示出來,從讓使用者而找到離他最近的門店。
把客戶當前所在位置可設成變數 ,例如:set @center=GeomFromText(‘POINT(10 10)’);
再把要找到最近門店可以縮小搜尋範圍 設半徑,添加搜尋條件
例:set @radius=30;
WHERE SQRT(POW( ABS( X(location) – X(@center)), 2) + POW( ABS(Y(location) – Y(@center)), 2 )) < @radius
最近門店搜尋,完整的SQL樣本:
SELECT shop_id,shop_na, SQRT(POW( ABS( X(Location) – X(@center)), 2) + POW(ABS(Y(Location) – Y(@center)), 2 )) AS distance
FROM shop WHERE SQRT(POW( ABS( X(location) – X(@center)), 2) + POW( ABS(Y(location) – Y(@center)), 2 )) < @radius
order by distance;
其中涉及的數學函數SQRT(x):表示求一個數x的平方根。POW(x,y):包含兩個參數表示求x的y次冪。ABS(x):表示求數X的絕對值。整個SQRT(POW( ABS( X(Location) – X(@center)), 2) + POW(ABS(Y(Location) – Y(@center)), 2 ))這個SQL語句實現的是一個算術運算式
即兩點間的直線距離。
比如說現在有兩個點座標A(x1,y1),B(x2,y2) 要求線段AB長度 就是用這個公式去計算。把A看成當前位置B看成一個門店,不就是相當於計算當前位置到門店這兩個點的距離嗎。座標點有了帶進去就行,等於現在只要能用函數把這個公式表示出來就可以了。
所以用到這三個函數:
SQRT(x):表示求一個數x的平方根。就相當於那個根號。√x
POW(x,y):包含兩個參數表示求x的y次冪
例如pow(2,3)就表示23,那麼POW((X1-X2),2)就相當於〖(x1-x2)〗^2
ABS(x):表示求數X的絕對值。|x| ABS(x1-x2)就等於|x1-x2|.
根據那個公式組合起來就行了
整個SQRT(POW( ABS( X(Location) – X(@center)), 2) + POW(ABS(Y(Location) – Y(@center)), 2))這句話就是用來表示這個公式的
,
這個公式計算得出來的值就是兩點間的直線距離。
參考資料:
http://dev.mysql.com/doc/refman/5.1/zh/spatial-extensions-in-mysql.html
http://en.wikipedia.org/wiki/Spatial_database
口水:
以上部分內容來自 NJ-AMT 實習生餘珊的分析報告。
–end–
MySQL 空間距離