百度地圖之收索視野內的建築物
根據用戶移動地圖的位置,顯示在視野範圍內的建築物,簡單的思路是,添加地圖監聽,當地圖移動結束之後,計算出當前屏幕四個角的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
https://blog.csdn.net/b10090120/article/details/8698787
https://www.hibernatespatial.org/tutorial.html
拓展mysqlspatial函數:
1) 空間中的點是否相等
[delphi]
view plaincopy
- DELIMITER $$
- CREATE DEFINER = 'smart'@'localhost'
- FUNCTION ArePointsEqual(p1 POINT,
- p2POINT
- )
- RETURNS TINYINT(1)
- DETERMINISTIC
- NO SQL
- BEGIN
- RETURN IsZero(x(p1) -x(p2)) AND IsZero(y(p1) - y(p2));
- END
- $$
- DELIMITER ;
2) 查找區域的中心點
[sql]
view plaincopy
- USE smartu;
- DELIMITER $$
- CREATE DEFINER = 'smart'@'localhost'
- FUNCTION GetCenterPoint(g GEOMETRY)
- RETURNS POINT
- DETERMINISTIC
- NO SQL
- BEGIN
- DECLARE envelope POLYGON;
- DECLARE sw, ne POINT; #South-West and North-East points
- DECLARE lat, lng DOUBLE;
- SET envelope =exteriorring(Envelope(g));
- SET sw =pointn(envelope, 1);
- SET ne =pointn(envelope, 3);
- SET lat = x(sw) + (x(ne)- x(sw)) / 2;
- SET lng = y(sw) + (y(ne)- y(sw)) / 2;
- RETURN POINT(lat, lng);
- END
- $$
- DELIMITER ;
3) LineN
[sql]
view plaincopy
- USE smartu;
- DELIMITER $$
- CREATE DEFINER = 'smart'@'localhost'
- FUNCTION LineN(ls LINESTRING,
- n INT
- )
- RETURNS LINESTRING
- DETERMINISTIC
- NO SQL
- BEGIN
- IF n >= numpoints(ls)THEN
- RETURN NULL;
- END IF;
- RETURNLineString(pointn(ls, n), pointn(ls, n + 1));
- END
- $$
- DELIMITER ;
4) 計算兩點間的空間距離
[sql]
view plaincopy
- USE smartu;
- DELIMITER $$
- CREATE DEFINER = 'smart'@'localhost'
- FUNCTION DISTANCE(lat1 DOUBLE,
- lon1DOUBLE,
- lat2DOUBLE,
- lon2DOUBLE
- )
- RETURNS DOUBLE
- DETERMINISTIC
- NO SQL
- COMMENT 'counts distance (km) between 2 points on Earth surface'
- BEGIN
- DECLARE dtor DOUBLEDEFAULT 57.295800;
- RETURN (6371 *acos(sin(lat1 / dtor) * sin(lat2 / dtor) +
- cos(lat1 / dtor) *cos(lat2 / dtor) *
- cos(lon2 / dtor - lon1 /dtor)));
- END
- $$
- DELIMITER ;
5) 是否為0
[sql]
view plaincopy
- USE smartu;
- DELIMITER $$
- CREATE DEFINER = 'smart'@'localhost'
- FUNCTION IsZero(n DOUBLE)
- RETURNS TINYINT(1)
- DETERMINISTIC
- NO SQL
- BEGIN
- DECLARE epsilon DOUBLEDEFAULT 0.00000000001;
- RETURN (abs(n) <=epsilon);
- END
- $$
- DELIMITER ;
2. 項目前台、後台的實現
1) 項目後台實現
l 數據庫設計
[sql]
view plaincopy
- --創建表
- createtable smart_u_convenience_item_spatial(
- item_spatial_id varchar(36) not null,
- location point not null,
- latitude varchar(20),
- longitude varchar(20),
- convenience_item_code varchar(500),
- convenience_item_name varchar(500),
- primary key (`item_spatial_id`),
- spatial key `sp_index`(location)
- )ENGINE=MyISAM;
- --往表中插入數據
- INSERTINTO smart_u_convenience_item_spatial
- SELECTt.convenience_item_id
- , PointFromText(concat('POINT(',t.item_latitude, ' ', t.item_longitude, ')'))
- , t.item_latitude
- , t.item_longitude
- , t.convenience_item_code
- , t.convenience_item_name
- from smart_u_convenience_item t;
l 後台代碼使用到的查詢點的sql
[sql]
view plaincopy
- SELECT *
- FROM
- (SELECT *
- FROM
- smart_u_convenience_item t
- WHERE
- t.convenience_item_idIN
- (SELECTs.item_spatial_id
- FROM
- smart_u_convenience_item_spatial s
- WHERE
- intersects(location,
- geomfromtext(concat('POLYGON((', 3.9921123E7, ' ', 1.16365462E8,
- ',', 3.9921123E7, ' ', 1.16441881E8,
- ',', 3.9879484E7, ' ', 1.16441881E8,
- ',', 3.9879484E7, ' ', 1.16365462E8,
- ',', 3.9921123E7, ' ', 1.16365462E8,'))'))))) t
- ORDER BY
- item_longitude ASC
2) 前台設計
[java]
view plaincopy
- MKMapViewListener mapViewListener = new MKMapViewListener() {
- @Override
- public void onMapMoveFinish() {
- // 此處可以實現地圖移動完成事件的狀態監聽
- Log.e(TAG,"mapMoveFinish");
- BsnsDisAllActivity.this.getBsnsDisInfo(BsnsDisAllActivity.this.getGeoPointMap());
- }
- @Override
- public void onClickMapPoi(MapPoipoi) {
- Log.e(TAG,poi.geoPt.getLatitudeE6()+","+poi.geoPt.getLongitudeE6());
- }
- @Override
- public void onGetCurrentMap(Bitmaparg0) {
- Log.e(TAG,"onGetCurrentMap");
- }
- @Override
- public void onMapAnimationFinish(){
- Log.e(TAG,"onMapAnimationFinish");
- BsnsDisAllActivity.this.getBsnsDisInfo(BsnsDisAllActivity.this.getGeoPointMap());
- }
- };
- mMapView.regMapViewListener(app.mBMapManager,mapViewListener);
- private Map<String,Double> getGeoPointMap(){
- Projectionprojection = mMapView.getProjection();
- Map<String,Double>polygon = newHashMap<String,Double>();
- GeoPointtop = projection.fromPixels(0, 0);
- polygon.put("top_x",(double) top.getLatitudeE6());
- polygon.put("top_y",(double)top.getLongitudeE6());
- GeoPointright = projection.fromPixels(mMapView.getWidth(), 0);
- polygon.put("right_x",(double)right.getLatitudeE6());
- polygon.put("right_y",(double)right.getLongitudeE6());
- GeoPointdown = projection.fromPixels(mMapView.getWidth(), mMapView.getHeight());
- polygon.put("down_x",(double)down.getLatitudeE6());
- polygon.put("down_y",(double)down.getLongitudeE6());
- GeoPointleft = projection.fromPixels(0, mMapView.getHeight());
- polygon.put("left_x",(double)left.getLatitudeE6());
- polygon.put("left_y",(double)left.getLongitudeE6());
- return polygon;
- }
- private voidgetBsnsDisInfo(Map<String,Double>polygon){
- final Map<String,Double> tPolygon =polygon;
- new Thread(){
- public void run() {
- try{
- List<OrderByEntity>orderByEntity = new ArrayList();
- OrderByEntityorder = newOrderByEntity();
- order.setOrderCol("item_longitude");
- order.setOrderType("asc");
- orderByEntity.add(order);
- // OrderByEntityorder2 = new OrderByEntity();
- // order.setOrderCol("item_latitude");
- // order.setOrderType("asc");
- // orderByEntity.add(order2);
- ConvenienceItemAckEntityack = SUService.getInstance().getMapBsns(app.nowUser, tPolygon, orderByEntity, null, null);
- Log.i(TAG,ack.getAckCode().toString());
- Log.i(TAG,ack.getAckMsg().toString());
- Message msg = new Message();
- if(ack.getAckCode().toString().indexOf("INFO") != -1){
- msg.what = RESULT_BSNS_CAT;
- }else{
- msg.what = RESULT_ERROR;
- }
- msg.obj = ack;
- myHandler.sendMessage(msg);
- }catch(Exception e){
- }
- };
- }.start();
- }
- Handler myHandler = new Handler(){
- public void handleMessage(Messagemsg) {
- switch (msg.what) {
- case RESULT_BSNS_CAT:
- ConvenienceItemAckEntityack = (ConvenienceItemAckEntity)msg.obj;
- pinItemMark(ack.getResults());
- break;
- default:
- break;
- }
- };
- };
- private voidpinItemMark(List<ConvenienceItemEntity> itemList){
- convenieceItemList= newArrayList<ConvenienceItemEntity>();
- mGeoList.clear();
- latLoc.clear();
- for(inti=0;i<itemList.size();i++){
- ConvenienceItemEntityitemEntity = itemList.get(i);
- int lat = Integer.parseInt(itemEntity.getItemLatitude());
- int loc = Integer.parseInt(itemEntity.getItemLongtude());
- OverlayItemitem = newOverlayItem(newGeoPoint(lat, loc),itemEntity.getConvenienceItemName() ,itemEntity.getConvenienceItemId());
- ViewdrawableView = LayoutInflater.from(BsnsDisAllActivity.this).inflate(
- R.layout.map_drawable_pin, null);// 獲取要轉換的View資源
- TextViewTestText = (TextView)drawableView.findViewById(R.id.map_drawable_text);
- TestText.setText(item.getTitle());//將每個點的Title在彈窗中以文本形式顯示出來
- BitmapdrawableBitmap = convertViewToBitmap(drawableView);
- Drawabledraw = newBitmapDrawable(drawableBitmap);
- item.setMarker(draw);
- convenieceItemList.add(itemEntity);
- mGeoList.add(item);
- PointlocPoint = newPoint();
- locPoint.x = i+1;
- locPoint.y = lat;
- latLoc.add(locPoint);
- }
- addMarker(mGeoList);
- for (int i = 0; i < latLoc.size(); i++){
- for (int j = 1; j < latLoc.size() - i; j++) {
- Point p1 = latLoc.get((j-1));
- Point p2 = latLoc.get(j);
- if(p1.y>p2.y){
- Point temp = p1;
- latLoc.set(j-1, p2);
- latLoc.set(j, p1);
- }
- if(latLoc.get(j-1).x==0){
- selectedItemLat = j-1;
- }
- }
- }
- }
最後更新:2017-04-03 20:19:19
上一篇:
線程同步1——synchronized
下一篇:
獲取手機端驗證碼
Yii2單元測試生成的測試類方法中,引入外部非模型類報錯,如何解決?
一種LTE天線的去耦合分析
標準的力量:讓新型智慧城市建設有章可循
關於p->next=p;和p=p->next;的刨根問底(也有轉的內容)
Oracle 12c多租戶特性詳解:全局用戶與本地用戶的原理與維護
PgSQL · 內核開發 · 如何管理你的 PostgreSQL 插件
C# 常用函數集錦
《Spark 官方文檔》Spark SQL, DataFrames 以及 Datasets 編程指南(四)
Strategy Analytics:問卷調查揭示物聯網支出低於企業IT預算的10%
百度地圖顯示多個標注點