根據(jù)用戶移動(dòng)地圖的位置,顯示在視野范圍內(nèi)的建筑物,簡(jiǎn)單的思路是,添加地圖監(jiān)聽(tīng),當(dāng)?shù)貓D移動(dòng)結(jié)束之后,計(jì)算出當(dāng)前屏幕四個(gè)角的GeoPoint,根據(jù)這4個(gè)點(diǎn),通過(guò)mysql的spatial中的函數(shù),完成在此范圍內(nèi)的建筑物的查詢。
1. mysql spatial介紹
從MySQL4.0開(kāi)始加入了Spatial擴(kuò)展功能,實(shí)現(xiàn)了OpenGIS規(guī)定的幾何數(shù)據(jù)類型,在SQL中的簡(jiǎn)單空間運(yùn)算。但是MySQL對(duì)空間查詢的支持不夠完善,要進(jìn)行復(fù)雜的空間運(yùn)算,建議使用postgreSQL數(shù)據(jù)庫(kù)的postGIS。
下圖是MySQL Spatial接口及類的結(jié)構(gòu)(有背景顏色的框代表接口):
有關(guān)mysql的詳細(xì)介紹,可以參考一下鏈接中的文章。
l 官方參考文檔(中文):
http://dev./doc/refman/5.1/zh/spatial-extensions-in-mysql.html#mysql-spatial-datatypes
l 官方參考文檔(英文):
http://dev./doc/refman/5.0/en/spatial-extensions.html
l 關(guān)于hibernate支持mysql-spatial:
http://blog.csdn.net/b10090120/article/details/8698787
http://www./tutorial.html
拓展mysqlspatial函數(shù):
1) 空間中的點(diǎn)是否相等
03 |
CREATE DEFINER = 'smart' @ 'localhost' |
04 |
FUNCTION ArePointsEqual(p1 POINT, |
11 |
RETURN IsZero(x(p1) -x(p2)) AND IsZero(y(p1) - y(p2)); |
2) 查找區(qū)域的中心點(diǎn)
05 |
CREATE DEFINER = 'smart' @ 'localhost' |
06 |
FUNCTION GetCenterPoint(g GEOMETRY) |
11 |
DECLARE envelope POLYGON; |
12 |
DECLARE sw, ne POINT; #South-West and North-East points |
13 |
DECLARE lat, lng DOUBLE ; |
15 |
SET envelope =exteriorring(Envelope(g)); |
16 |
SET sw =pointn(envelope, 1); |
17 |
SET ne =pointn(envelope, 3); |
18 |
SET lat = x(sw) + (x(ne)- x(sw)) / 2; |
19 |
SET lng = y(sw) + (y(ne)- y(sw)) / 2; |
20 |
RETURN POINT(lat, lng); |
3) LineN
05 |
CREATE DEFINER = 'smart' @ 'localhost' |
06 |
FUNCTION LineN(ls LINESTRING, |
13 |
IF n >= numpoints(ls) THEN |
16 |
RETURNLineString(pointn(ls, n), pointn(ls, n + 1)); |
4) 計(jì)算兩點(diǎn)間的空間距離
05 |
CREATE DEFINER = 'smart' @ 'localhost' |
06 |
FUNCTION DISTANCE(lat1 DOUBLE , |
14 |
COMMENT 'counts distance (km) between 2 points on Earth surface' |
16 |
DECLARE dtor DOUBLEDEFAULT 57.295800; |
18 |
RETURN (6371 *acos(sin(lat1 / dtor) * sin(lat2 / dtor) + |
19 |
cos(lat1 / dtor) *cos(lat2 / dtor) * |
20 |
cos(lon2 / dtor - lon1 /dtor))); |
5) 是否為0
05 |
CREATE DEFINER = 'smart' @ 'localhost' |
06 |
FUNCTION IsZero(n DOUBLE ) |
11 |
DECLARE epsilon DOUBLEDEFAULT 0.00000000001; |
13 |
RETURN ( abs (n) <=epsilon); |
2. 項(xiàng)目前臺(tái)、后臺(tái)的實(shí)現(xiàn)
1) 項(xiàng)目后臺(tái)實(shí)現(xiàn)
l 數(shù)據(jù)庫(kù)設(shè)計(jì)
02 |
createtable smart_u_convenience_item_spatial( |
03 |
item_spatial_id varchar (36) not null , |
04 |
location point not null , |
06 |
longitude varchar (20), |
07 |
convenience_item_code varchar (500), |
08 |
convenience_item_name varchar (500), |
09 |
primary key (`item_spatial_id`), |
10 |
spatial key `sp_index`(location) |
13 |
INSERTINTO smart_u_convenience_item_spatial |
14 |
SELECTt.convenience_item_id |
15 |
, PointFromText(concat( 'POINT(' ,t.item_latitude, ' ' , t.item_longitude, ')' )) |
18 |
, t.convenience_item_code |
19 |
, t.convenience_item_name |
20 |
from smart_u_convenience_item t; |
l 后臺(tái)代碼使用到的查詢點(diǎn)的sql
05 |
smart_u_convenience_item t |
07 |
t.convenience_item_idIN |
08 |
(SELECTs.item_spatial_id |
10 |
smart_u_convenience_item_spatial s |
13 |
geomfromtext(concat( 'POLYGON((' , 3.9921123E7, ' ' , 1.16365462E8, |
14 |
',' , 3.9921123E7, ' ' , 1.16441881E8, |
15 |
',' , 3.9879484E7, ' ' , 1.16441881E8, |
16 |
',' , 3.9879484E7, ' ' , 1.16365462E8, |
17 |
',' , 3.9921123E7, ' ' , 1.16365462E8, '))' ))))) t |
2) 前臺(tái)設(shè)計(jì)
001 |
MKMapViewListener mapViewListener = new MKMapViewListener() { |
004 |
public void onMapMoveFinish() { |
005 |
// 此處可以實(shí)現(xiàn)地圖移動(dòng)完成事件的狀態(tài)監(jiān)聽(tīng) |
006 |
Log.e(TAG, "mapMoveFinish" ); |
007 |
BsnsDisAllActivity. this .getBsnsDisInfo(BsnsDisAllActivity. this .getGeoPointMap()); |
011 |
public void onClickMapPoi(MapPoipoi) { |
012 |
Log.e(TAG,poi.geoPt.getLatitudeE6()+ "," +poi.geoPt.getLongitudeE6()); |
016 |
public void onGetCurrentMap(Bitmaparg0) { |
017 |
Log.e(TAG, "onGetCurrentMap" ); |
022 |
public void onMapAnimationFinish(){ |
023 |
Log.e(TAG, "onMapAnimationFinish" ); |
024 |
BsnsDisAllActivity. this .getBsnsDisInfo(BsnsDisAllActivity. this .getGeoPointMap()); |
027 |
mMapView.regMapViewListener(app.mBMapManager,mapViewListener); |
029 |
private Map<String,Double> getGeoPointMap(){ |
031 |
Projectionprojection = mMapView.getProjection(); |
033 |
Map<String,Double>polygon = newHashMap<String,Double>(); |
034 |
GeoPointtop = projection.fromPixels( 0 , 0 ); |
035 |
polygon.put( "top_x" ,( double ) top.getLatitudeE6()); |
036 |
polygon.put( "top_y" ,( double )top.getLongitudeE6()); |
037 |
GeoPointright = projection.fromPixels(mMapView.getWidth(), 0 ); |
038 |
polygon.put( "right_x" ,( double )right.getLatitudeE6()); |
039 |
polygon.put( "right_y" ,( double )right.getLongitudeE6()); |
040 |
GeoPointdown = projection.fromPixels(mMapView.getWidth(), mMapView.getHeight()); |
041 |
polygon.put( "down_x" ,( double )down.getLatitudeE6()); |
042 |
polygon.put( "down_y" ,( double )down.getLongitudeE6()); |
043 |
GeoPointleft = projection.fromPixels( 0 , mMapView.getHeight()); |
044 |
polygon.put( "left_x" ,( double )left.getLatitudeE6()); |
045 |
polygon.put( "left_y" ,( double )left.getLongitudeE6()); |
051 |
private voidgetBsnsDisInfo(Map<String,Double>polygon){ |
052 |
final Map<String,Double> tPolygon =polygon; |
056 |
List<OrderByEntity>orderByEntity = new ArrayList(); |
057 |
OrderByEntityorder = newOrderByEntity(); |
058 |
order.setOrderCol( "item_longitude" ); |
059 |
order.setOrderType( "asc" ); |
060 |
orderByEntity.add(order); |
061 |
// OrderByEntityorder2 = new OrderByEntity(); |
062 |
// order.setOrderCol("item_latitude"); |
063 |
// order.setOrderType("asc"); |
064 |
// orderByEntity.add(order2); |
066 |
ConvenienceItemAckEntityack = SUService.getInstance().getMapBsns(app.nowUser, tPolygon, orderByEntity, null , null ); |
067 |
Log.i(TAG,ack.getAckCode().toString()); |
068 |
Log.i(TAG,ack.getAckMsg().toString()); |
069 |
Message msg = new Message(); |
070 |
if (ack.getAckCode().toString().indexOf( "INFO" ) != - 1 ){ |
071 |
msg.what = RESULT_BSNS_CAT; |
073 |
msg.what = RESULT_ERROR; |
076 |
myHandler.sendMessage(msg); |
085 |
Handler myHandler = new Handler(){ |
086 |
public void handleMessage(Messagemsg) { |
088 |
case RESULT_BSNS_CAT: |
089 |
ConvenienceItemAckEntityack = (ConvenienceItemAckEntity)msg.obj; |
090 |
pinItemMark(ack.getResults()); |
099 |
private voidpinItemMark(List<ConvenienceItemEntity> itemList){ |
100 |
convenieceItemList= newArrayList<ConvenienceItemEntity>(); |
103 |
for (inti= 0 ;i<itemList.size();i++){ |
104 |
ConvenienceItemEntityitemEntity = itemList.get(i); |
105 |
int lat = Integer.parseInt(itemEntity.getItemLatitude()); |
106 |
int loc = Integer.parseInt(itemEntity.getItemLongtude()); |
107 |
OverlayItemitem = newOverlayItem(newGeoPoint(lat, loc),itemEntity.getConvenienceItemName() ,itemEntity.getConvenienceItemId()); |
109 |
ViewdrawableView = LayoutInflater.from(BsnsDisAllActivity. this ).inflate( |
110 |
R.layout.map_drawable_pin, null ); // 獲取要轉(zhuǎn)換的View資源 |
111 |
TextViewTestText = (TextView)drawableView.findViewById(R.id.map_drawable_text); |
112 |
TestText.setText(item.getTitle()); //將每個(gè)點(diǎn)的Title在彈窗中以文本形式顯示出來(lái) |
114 |
BitmapdrawableBitmap = convertViewToBitmap(drawableView); |
116 |
Drawabledraw = newBitmapDrawable(drawableBitmap); |
118 |
item.setMarker(draw); |
120 |
convenieceItemList.add(itemEntity); |
122 |
PointlocPoint = newPoint(); |
125 |
latLoc.add(locPoint); |
129 |
for ( int i = 0 ; i < latLoc.size(); i++){ |
130 |
for ( int j = 1 ; j < latLoc.size() - i; j++) { |
131 |
Point p1 = latLoc.get((j- 1 )); |
132 |
Point p2 = latLoc.get(j); |
139 |
if (latLoc.get(j- 1 ).x== 0 ){ |
140 |
selectedItemLat = j- 1 ; |
來(lái)自:http://blog.csdn.net/fengshuiyue/article/details/9155463
|