閱讀789 返回首頁    go 阿裏雲 go 技術社區[雲棲]


百度地圖之收索視野內的建築物

根據用戶移動地圖的位置,顯示在視野範圍內的建築物,簡單的思路是,添加地圖監聽,當地圖移動結束之後,計算出當前屏幕四個角的GeoPoint,根據這4個點,通過mysql的spatial中的函數,完成在此範圍內的建築物的查詢。

1.   mysql spatial介紹

  從MySQL4.0開始加入了Spatial擴展功能,實現了OpenGIS規定的幾何數據類型,在SQL中的簡單空間運算。但是MySQL對空間查詢的支持不夠完善,要進行複雜的空間運算,建議使用postgreSQL數據庫的postGIS。

    下圖是MySQL Spatial接口及類的結構(有背景顏色的框代表接口):

    有關mysql的詳細介紹,可以參考一下鏈接中的文章。

l  官方參考文檔(中文):

https://dev.mysql.com/doc/refman/5.1/zh/spatial-extensions-in-mysql.html

l  官方參考文檔(英文):

https://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

關於hibernate支持mysql-spatial

https://blog.csdn.net/b10090120/article/details/8698787

https://www.hibernatespatial.org/tutorial.html

拓展mysqlspatial函數:

1)  空間中的點是否相等

[delphi] view plaincopy
  1. DELIMITER $$  
  2.    
  3. CREATE DEFINER = 'smart'@'localhost'  
  4. FUNCTION ArePointsEqual(p1 POINT,  
  5.                         p2POINT  
  6.                         )  
  7. RETURNS TINYINT(1)  
  8. DETERMINISTIC  
  9. NO SQL  
  10. BEGIN  
  11.   RETURN IsZero(x(p1) -x(p2)) AND IsZero(y(p1) - y(p2));  
  12. END  
  13. $$  
  14.    
  15. DELIMITER ;  

2)  查找區域的中心點

  1. USE smartu;  
  2.    
  3. DELIMITER $$  
  4.    
  5. CREATE DEFINER = 'smart'@'localhost'  
  6. FUNCTION GetCenterPoint(g GEOMETRY)  
  7. RETURNS POINT  
  8. DETERMINISTIC  
  9. NO SQL  
  10. BEGIN  
  11.   DECLARE envelope  POLYGON;  
  12.   DECLARE sw, ne    POINT; #South-West and North-East points  
  13.   DECLARE lat, lng  DOUBLE;  
  14.    
  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);  
  21. END  
  22. $$  
  23.    
  24. DELIMITER ;  

3)  LineN

  1. USE smartu;  
  2.    
  3. DELIMITER $$  
  4.    
  5. CREATE DEFINER = 'smart'@'localhost'  
  6. FUNCTION LineN(ls LINESTRING,  
  7.                n  INT  
  8.                )  
  9. RETURNS LINESTRING  
  10. DETERMINISTIC  
  11. NO SQL  
  12. BEGIN  
  13.   IF n >= numpoints(ls)THEN  
  14.     RETURN NULL;  
  15.   END IF;  
  16.   RETURNLineString(pointn(ls, n), pointn(ls, n + 1));  
  17. END  
  18. $$  
  19.    
  20. DELIMITER ;  

4)  計算兩點間的空間距離

  1. USE smartu;  
  2.    
  3. DELIMITER $$  
  4.    
  5. CREATE DEFINER = 'smart'@'localhost'  
  6. FUNCTION DISTANCE(lat1 DOUBLE,  
  7.                   lon1DOUBLE,  
  8.                   lat2DOUBLE,  
  9.                   lon2DOUBLE  
  10.                   )  
  11. RETURNS DOUBLE  
  12. DETERMINISTIC  
  13. NO SQL  
  14. COMMENT 'counts distance (km) between 2 points on Earth surface'  
  15. BEGIN  
  16.   DECLARE dtor DOUBLEDEFAULT 57.295800;  
  17.    
  18.   RETURN (6371 *acos(sin(lat1 / dtor) * sin(lat2 / dtor) +  
  19.   cos(lat1 / dtor) *cos(lat2 / dtor) *  
  20.   cos(lon2 / dtor - lon1 /dtor)));  
  21. END  
  22. $$  
  23.    
  24. DELIMITER ;  

5)  是否為0

  1. USE smartu;  
  2.    
  3. DELIMITER $$  
  4.    
  5. CREATE DEFINER = 'smart'@'localhost'  
  6. FUNCTION IsZero(n DOUBLE)  
  7. RETURNS TINYINT(1)  
  8. DETERMINISTIC  
  9. NO SQL  
  10. BEGIN  
  11.   DECLARE epsilon DOUBLEDEFAULT 0.00000000001;  
  12.    
  13.   RETURN (abs(n) <=epsilon);  
  14. END  
  15. $$  
  16.    
  17. DELIMITER ;  

2.  項目前台、後台的實現

1)  項目後台實現

l  數據庫設計

  1. --創建表  
  2. createtable smart_u_convenience_item_spatial(  
  3.     item_spatial_id varchar(36) not null,  
  4.     location point not null,  
  5.     latitude varchar(20),  
  6.     longitude varchar(20),  
  7.     convenience_item_code varchar(500),  
  8.     convenience_item_name varchar(500),  
  9.     primary key (`item_spatial_id`),  
  10.     spatial key `sp_index`(location)  
  11. )ENGINE=MyISAM;  
  12. --往表中插入數據  
  13. INSERTINTO smart_u_convenience_item_spatial  
  14. SELECTt.convenience_item_id  
  15.      , PointFromText(concat('POINT(',t.item_latitude, ' ', t.item_longitude, ')'))  
  16.      , t.item_latitude  
  17.      , t.item_longitude  
  18.      , t.convenience_item_code  
  19.      , t.convenience_item_name  
  20.    from smart_u_convenience_item t;  

l  後台代碼使用到的查詢點的sql

  1. SELECT *  
  2. FROM  
  3.   (SELECT *  
  4.    FROM  
  5.     smart_u_convenience_item t  
  6.    WHERE  
  7.      t.convenience_item_idIN  
  8.     (SELECTs.item_spatial_id  
  9.        FROM  
  10.         smart_u_convenience_item_spatial s  
  11.        WHERE  
  12.         intersects(location,  
  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  
  18. ORDER BY  
  19.  item_longitude ASC  

2)  前台設計

  1. MKMapViewListener mapViewListener = new MKMapViewListener() {  
  2.    
  3.          @Override  
  4.          public void onMapMoveFinish() {  
  5.             // 此處可以實現地圖移動完成事件的狀態監聽  
  6.             Log.e(TAG,"mapMoveFinish");  
  7.            BsnsDisAllActivity.this.getBsnsDisInfo(BsnsDisAllActivity.this.getGeoPointMap());             
  8.          }  
  9.    
  10.          @Override  
  11.          public void onClickMapPoi(MapPoipoi) {  
  12.             Log.e(TAG,poi.geoPt.getLatitudeE6()+","+poi.geoPt.getLongitudeE6());           
  13.          }  
  14.    
  15.          @Override  
  16.          public void onGetCurrentMap(Bitmaparg0) {  
  17.             Log.e(TAG,"onGetCurrentMap");  
  18.              
  19.          }  
  20.    
  21.          @Override  
  22.          public void onMapAnimationFinish(){  
  23.             Log.e(TAG,"onMapAnimationFinish");  
  24.            BsnsDisAllActivity.this.getBsnsDisInfo(BsnsDisAllActivity.this.getGeoPointMap());  
  25.          }  
  26.       };  
  27.       mMapView.regMapViewListener(app.mBMapManager,mapViewListener);  
  28.    
  29. private Map<String,Double> getGeoPointMap(){  
  30.    
  31.          Projectionprojection = mMapView.getProjection();  
  32.    
  33.          Map<String,Double>polygon = newHashMap<String,Double>();  
  34.          GeoPointtop = projection.fromPixels(00);  
  35.          polygon.put("top_x",(double) top.getLatitudeE6());  
  36.          polygon.put("top_y",(double)top.getLongitudeE6());  
  37.          GeoPointright = projection.fromPixels(mMapView.getWidth(), 0);  
  38.          polygon.put("right_x",(double)right.getLatitudeE6());  
  39.          polygon.put("right_y",(double)right.getLongitudeE6());  
  40.          GeoPointdown = projection.fromPixels(mMapView.getWidth(), mMapView.getHeight());  
  41.          polygon.put("down_x",(double)down.getLatitudeE6());  
  42.          polygon.put("down_y",(double)down.getLongitudeE6());  
  43.          GeoPointleft = projection.fromPixels(0, mMapView.getHeight());  
  44.          polygon.put("left_x",(double)left.getLatitudeE6());  
  45.          polygon.put("left_y",(double)left.getLongitudeE6());  
  46.           
  47.          return polygon;  
  48.       }  
  49.    
  50.    
  51. private voidgetBsnsDisInfo(Map<String,Double>polygon){  
  52.           final Map<String,Double> tPolygon =polygon;  
  53.          new Thread(){  
  54.             public void run() {  
  55.                 try{  
  56.                    List<OrderByEntity>orderByEntity = new ArrayList();  
  57.                    OrderByEntityorder = newOrderByEntity();  
  58.                    order.setOrderCol("item_longitude");  
  59.                    order.setOrderType("asc");  
  60.                    orderByEntity.add(order);  
  61.    //              OrderByEntityorder2 = new OrderByEntity();  
  62.    //              order.setOrderCol("item_latitude");  
  63.    //              order.setOrderType("asc");  
  64.    //              orderByEntity.add(order2);  
  65.     
  66.                    ConvenienceItemAckEntityack = SUService.getInstance().getMapBsns(app.nowUser, tPolygon, orderByEntity, nullnull);  
  67.                    Log.i(TAG,ack.getAckCode().toString());  
  68.                    Log.i(TAG,ack.getAckMsg().toString());  
  69.                   Message msg = new Message();  
  70.                    if(ack.getAckCode().toString().indexOf("INFO") != -1){  
  71.                       msg.what = RESULT_BSNS_CAT;  
  72.                    }else{  
  73.                       msg.what = RESULT_ERROR;  
  74.                    }  
  75.                    msg.obj = ack;  
  76.                    myHandler.sendMessage(msg);  
  77.                 }catch(Exception e){  
  78.                     
  79.                 }  
  80.                  
  81.             };  
  82.          }.start();  
  83.       }  
  84.         
  85.        Handler myHandler = new Handler(){  
  86.          public void handleMessage(Messagemsg) {  
  87.             switch (msg.what) {  
  88.             case RESULT_BSNS_CAT:  
  89.                 ConvenienceItemAckEntityack = (ConvenienceItemAckEntity)msg.obj;  
  90.                 pinItemMark(ack.getResults());  
  91.                 break;  
  92.    
  93.             default:  
  94.                 break;  
  95.             }  
  96.          };  
  97.       };  
  98.        
  99.       private voidpinItemMark(List<ConvenienceItemEntity> itemList){  
  100.          convenieceItemList= newArrayList<ConvenienceItemEntity>();  
  101.          mGeoList.clear();  
  102.          latLoc.clear();  
  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());  
  108.              
  109.             ViewdrawableView = LayoutInflater.from(BsnsDisAllActivity.this).inflate(  
  110.                    R.layout.map_drawable_pin, null);// 獲取要轉換的View資源  
  111.             TextViewTestText = (TextView)drawableView.findViewById(R.id.map_drawable_text);  
  112.             TestText.setText(item.getTitle());//將每個點的Title在彈窗中以文本形式顯示出來       
  113.              
  114.             BitmapdrawableBitmap = convertViewToBitmap(drawableView);  
  115.              
  116.             Drawabledraw = newBitmapDrawable(drawableBitmap);  
  117.        
  118.             item.setMarker(draw);  
  119.              
  120.             convenieceItemList.add(itemEntity);  
  121.             mGeoList.add(item);  
  122.             PointlocPoint = newPoint();  
  123.             locPoint.x = i+1;  
  124.             locPoint.y = lat;  
  125.             latLoc.add(locPoint);           
  126.          }  
  127.           
  128.          addMarker(mGeoList);  
  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);  
  133.                      
  134.                    if(p1.y>p2.y){  
  135.                       Point temp = p1;  
  136.                       latLoc.set(j-1, p2);  
  137.                       latLoc.set(j, p1);  
  138.                    }  
  139.                    if(latLoc.get(j-1).x==0){  
  140.                       selectedItemLat = j-1;  
  141.                    }  
  142.                  }  
  143.          }  
  144.       } 

最後更新:2017-04-03 20:19:19

  上一篇:go 線程同步1——synchronized
  下一篇:go 獲取手機端驗證碼