多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 仿百度地圖街景實現

仿百度地圖街景實現

來源:程序員人生   發布時間:2016-08-05 13:43:08 閱讀次數:6595次

使用過百度地圖的同學知道,它有個街景功能,可以看到許多地方的實景。這里就其街景內容的實現,進行下學習。

在百度地圖SDK的官網上可以看到,百度對開發者提供了很多相干的內容,方便我們進行學習。關于SDK的使用方法,包括jar包導入,*.so 動態庫的添加位置及AndroidManifest文件的配置不做為我們這里討論的內容,官方文檔已介紹的很詳細,不做無聊的搬運工。

效果圖

這里我們首先預覽下,今天終究要實現的效果圖

靜態圖1


靜態圖2


效果圖

如圖所示,我們這里的實現,就是兩個頁面的內容,1個是基礎的地圖MapView,1個是街景地圖PanoView。接下來,就這兩個頁面(Activity)分別展開來講。(由于GIF圖片大小限制,效果不是很理想,文章結尾有源碼地址,可以自己跑1下看1下效果先)

地圖MapView實現

地圖MapView的簡單顯示

布局文件

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" /> </LinearLayout>

Application

1般情況下,我們的利用程序都會有1個繼承自Application的類,用于實現1些初始化的方法,這里可以在Application里履行1些百度地圖初始化的工作,這也是官方提倡的方式。

public void onCreate() { super.onCreate(); mInstance = this; SDKInitializer.initialize(getApplicationContext()); }

Activity

在Activity的OnCreate方法中實現

setContentView(R.layout.activity_mapview); mMapView = (MapView) findViewById(R.id.bmapView);

上面這樣1段簡單的代碼,就能夠在Activity中顯示出1個MapView,也就是我們最熟習的地圖頁面,是否是很簡單,就像我們顯示1個TextView1樣。

這里說明寫1下,依照官方的API指點文檔,使用MapView等百度地圖SDK所提供的各種實現,是需要去申請相干的key的,申請的方法在官網有著詳細的介紹,這里就不再粘貼復制了;很多同學在使用MapView的時候發現,程序運行后地圖沒有顯示,顯示的都是1些方格子,這常常是由于key沒有申請,或申請的方式不當釀成的

MapView顯示到當前位置

每次打開百度地圖,都會自動定位到我們當前所在的位置,或是我們搜索某個特定的地方作為新的位置,全部地圖所顯現的區域都是新位置周邊的環境。這里,關于地圖的定位和搜索的相干實現內容,就不展開來講,不當作此次的重點。

假定我們已通過定位(或是搜索),定位了到了1個位置

**
 * 假定我們當前的位置在此
 */
private final double latitude = 39.963175;
private final double longitude = 116.400244;

這個位置依照新聞里常聽到的說法就是,東經116.40度,北緯39.96度,位于北京市東城區舊鼓樓大街丙1號。

接下來,我們要做的就是將MapView的視圖更新到我們“定位”的位置,這個位置周邊的地圖才是我們關心的。

mBaiduMap = mMapView.getMap(); //定義Maker坐標點 point = new LatLng(latitude, longitude); //定義地圖狀態 final MapStatus mMapStatus = new MapStatus.Builder() .target(point) .zoom(18) .build(); //定義MapStatusUpdate對象,以便描寫地圖狀態將要產生的變化 MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus); //改變地圖狀態 mBaiduMap.setMapStatus(mMapStatusUpdate);

這里的mBaiduMap 是1個BaiduMap的實例,通過MapView的getMap方法便可取得。我們對地圖的各種操作,設置屬性都是基于這個實例進行。

通過上面的代碼,我們就能夠將MapView的視圖更新到我們所想要的位置了。

添加View到MapView

添加Marker

依照百度地圖API的說法,我們添加到地圖上的小圖標統1稱為Marker。

//構建Marker圖標 bitmap = BitmapDescriptorFactory .fromResource(R.drawable.icon_markc); //構建MarkerOption,用于在地圖上添加Marker option = new MarkerOptions() .position(point) .icon(bitmap); //在地圖上添加Marker,并顯示 mBaiduMap.addOverlay(option);

通過上面的實現,我們就能夠將1個小圖標添加到地圖層,作為標記。我們平常使用地圖時,所搜周邊后顯現的1系列小圓點就是如此(以下圖)

marker示意圖

ShowInfoWindow使用

最后1步,實現顯示街景縮略圖的那個小彈框。

這里首先自定義1下我們要添加到地圖層的View。

view = LayoutInflater.from(mContext).inflate(R.layout.pano_overlay, null); pic = (ImageView) view.findViewById(R.id.panoImageView); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(mContext, PanoDemoMain.class); intent.putExtra("latitude", latitude); intent.putExtra("longitude", longitude); startActivity(intent); } });

這里pic這個ImageView用于顯示我們要展現的街景縮略圖。pano_overlay是全部彈框的布局,很簡單,這里就不貼代碼了。

同時,我們為這個自定義View設置點擊事件,方便我們跳轉到PanoView街景地圖頁面,并且將當前位置傳遞過去。

由于祖國地大物博,所以街景的覆蓋并不是百分之百,所以說,不是每一個地方都有街景可以顯示,有些鳥不拉屎的地方是看不到的。那我們怎樣知道甚么地方有街景呢?API為我們提供了很好的檢測方法

new Thread(new Runnable() { @Override public void run() { PanoramaRequest request = PanoramaRequest.getInstance(mContext); BaiduPanoData locationPanoData = request.getPanoramaInfoByLatLon(longitude, latitude); //開發者可以判斷是不是有外景(街景) if (locationPanoData.hasStreetPano()) { String url = baseUrl + locationPanoData.getPid(); Message message = new Message(); message.what = 0x01; message.obj = url; handler.sendMessage(message); } } }).start();

這樣,我們就能夠根據當前位置,先檢測1下是不是有街景可以顯示。這里,如果當前位置有街景,我們就通過Handler通知主線程去更新UI

private class myHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 0x01) { String url = (String) msg.obj; Glide.with(mContext).load(url).into(pic); InfoWindow mInfoWindow = new InfoWindow(view, point, -57); //顯示InfoWindow mBaiduMap.showInfoWindow(mInfoWindow); } } }

這里看1下,InfoWindow的說明及其構造函數

public class InfoWindow extends java.lang.Object
在地圖中顯示1個信息窗口,可以設置1個View作為該窗口的內容,也能夠設置1個 BitmapDescriptor 作為該窗口的內容。

public InfoWindow(View view, LatLng position, int yOffset) /** 通過傳入的 view 構造1個 InfoWindow, 此時只是利用該view 生成1個Bitmap繪制在地圖中,監聽事件由開發者實現。 Parameters: view - InfoWindow 展現的 view position - InfoWindow 顯示的地理位置 yOffset - InfoWindow Y 軸偏移量 */

在Handler的handleMessage方法中,我們通過返回的url加載圖片,并將自定義的彈框View顯示到之前1步添加的marker偏上1點的地方(這就是InfoWindow的構造函數中⑸7的意義)

關于這個加載圖片的URL,可以參考這里靜態圖API。

這樣,就實現了MapView頁面所有的內容。通過點擊InfoWindow,就能夠跳轉到PanoView所在的界面去查看街景地圖。

接下來,我們將介紹PanoView街景地圖的實現。

街景地圖PanoViewActivity實現

街景地圖PanoView基礎

街景地圖PanoView的顯示和基礎地圖MapView10分類似

首先是在布局文件中定義view

<com.baidu.lbsapi.panoramaview.PanoramaView android:id="@+id/panorama" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:visibility="visible" />

Activity的OnCreate方法中

PanoDemoApplication app = (PanoDemoApplication) this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(app); app.mBMapManager.init(new PanoDemoApplication.MyGeneralListener()); } mPanoView = (PanoramaView) findViewById(R.id.panorama); mPanoView.setPanorama(longitude, latitude);

這里一樣需要的是在Application類中做1些初始化工作;對我們所使用key的有效性進行檢測。

public void initEngineManager(Context context) { if (mBMapManager == null) { mBMapManager = new BMapManager(context); } if (!mBMapManager.init(new MyGeneralListener())) { Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(), "BMapManager 初始化毛病!", Toast.LENGTH_LONG).show(); } } // 經常使用事件監聽,用來處理通常的網絡毛病,授權驗證毛病等 static class MyGeneralListener implements MKGeneralListener { @Override public void onGetPermissionState(int iError) { // 非零值表示key驗證未通過 if (iError != 0) { // 授權Key毛病: Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(), "請在AndoridManifest.xml中輸入正確的授權Key,并檢查您的網絡連接是不是正常!error: " + iError, Toast.LENGTH_LONG).show(); } else { Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(), "key認證成功", Toast.LENGTH_LONG) .show(); } } }

同時在Activity里也需要做1些初始化的工作,最后就是通過PanoView的setPanorama()方法實現街景的顯示。

關于這里用到的setPanorama(),根據API我們可以看到

public void setPanorama(java.lang.String pid) //根據全景pid值切換全景場景 public void setPanorama(int x,int y) //根據百度墨卡托投影坐標切換全景場景 public void setPanorama(double longitude,double latitude) //根據百度經緯度坐標切換全景場景 public void setPanoramaByUid(java.lang.String uid, int panoType) //根據uid值切換全景場景

也就是說,不但通過經緯度,而且可以通過別的方式實現街景地圖的功能。這里我們就使用了大家最熟習的經緯度,對別的實現方式有興趣的同學,可以自己去探索1下。

將地圖MapView展現在街景PanoView上面

如圖所示,將1個MapView顯示在PanoView之上;很自然的我們會寫出下面的布局方式:

<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.baidu.lbsapi.panoramaview.PanoramaView android:id="@+id/panorama" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:visibility="visible" /> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" android:background="#00ffffff"> <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:padding="20dp" /> </LinearLayout> </RelativeLayout>

這樣,我們在全部PanoView的左下角定義1個60x60大小的view用于顯示1個MapView。

實現對街景視圖操作的監聽

街景SDK為我們提供了PanoramaViewListener這個接口,可以實現對從街景視圖開始繪制到完成繪制,對街景地圖的操作(如點擊,旋轉)的監聽。

API

這里我們重點看1下onMessage(String msgName, int msgType)這個回調方法。

public void onMessage(String msgName, int msgType) { Log.e(LTAG, "msgName--->" + msgName + ", msgType--->" + msgType); switch (msgType) { case 8213: //旋轉 Log.e(PanoViewActivity.class.getSimpleName(), "now,the heading is " + mPanoView.getPanoramaHeading()); Message message = new Message(); message.what = ACTION_DRAG; message.arg1 = (int) mPanoView.getPanoramaHeading(); handler.sendMessage(message); break; case 12302: //點擊 Log.e(PanoViewActivity.class.getSimpleName(), "clicked"); Message msg = new Message(); msg.what = ACTION_CLICK; handler.sendMessage(msg); break; default: break; } }

這里不能不吐槽1下,官方所提供的API文檔,對這個onMessage回調方法中的參數竟然沒有任何有價值的解釋。這里的8213及12302完全是通過打印日志自己總結出的規律。

這樣,我們對不同的操作,就能夠通過Handler實現不同的UI效果。我們看1下handler的實現:

private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case ACTION_CLICK: if (titleVisible) { titleVisible = false; textTitle.startAnimation(animationHide); textTitle.setVisibility(View.GONE); sv.setVisibility(View.GONE); } else { titleVisible = true; textTitle.startAnimation(animationShow); textTitle.setVisibility(View.VISIBLE); sv.setVisibility(View.VISIBLE); } break; case ACTION_DRAG: float heading = (float) msg.arg1; mBaiduMap.clear(); //構建MarkerOption,用于在地圖上添加Marker option = new MarkerOptions() .position(point) .rotate(360-heading) .icon(bitmap); //在地圖上添加Marker,并顯示 mBaiduMap.addOverlay(option); break; default: break; } } }

這里的處理就分兩種情況:

  • 點擊事件

我們仿照百度地圖的樣式,實現標題欄及MapView的隱藏,并添加動畫,這樣可以方便用戶全屏更清晰的視察街景內容。

  • 旋轉事件

上面我們說過對MapView添加Marker的方法,這里就派上用處了。隨著我們對PanoView的不斷拖拽旋轉,通過其getPanoramaHeading() 可以得到當前視角的偏航角。
在UI線程中,我們可以通過不斷移除和添加Marker,并設置不同的marker的偏轉角度,從而實現1種在左下方小地圖上顯現我們當前視角的效果。

好了,這樣就簡單模仿了1下百度地圖街景的部份實現功能,由于UI資源所限制,部份效果并不是完全1致,這里只是學習下而已。

代碼已上傳至github,點這里便可查看。


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 久久一级毛片 | 亚洲精品永久www嫩草 | 色综合久久久久久久久五月 | 成人自拍网 | 天天在线欧美精品免费看 | 亚洲精品欧美精品一区二区 | 日本高清无卡码一区二区久久 | 在线中文字幕第一页 | 一区二区三区欧美日韩国产 | 美国亚洲成年毛片 | 亚洲人成网站在线观看播放 | 精品国产人成在线 | 亚洲成aⅴ人在线观看 | 爱综合| 亚洲视频一区二区 | 欧美精品久久 | 婷婷麻豆 | 一区二区在线精品免费视频 | 日韩欧美h| 久久精品一区二区影院 | 国产亚洲精品美女久久久久 | 高清欧美性猛交xxxx黑人猛交 | 福利视频一二三在线视频免费观看 | 欧美日韩另类国产 | 国产精品免费播放 | 国产精品特黄毛片 | 久久精品成人免费网站 | 免费高清毛片在线播放视频 | 亚洲欧洲eeea在线观看 | 亚洲影视精品 | 国产高清一区 | 欧美韩日国产 | 激情五月开心婷婷 | 操人的网站 | 一级毛片www | 国产一区视频在线播放 | 成人三级精品视频在线观看 | 日本特黄特色aa大片免费 | 亚洲一区二区三区深夜天堂 | 亚洲欧美四级在线播放 | www视频在线看 |