Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 百度地圖

百度地圖

編輯:關於Android編程

顯示地圖和定位

對於一個地圖SDK來說,首先要顯示地圖,然後定位到當前城市。

這方面百度地圖和高德地圖的處理代碼差不多,下面是兩種地圖sdk顯示並定位的代碼例子:
百度地圖
//以下主要是定位用到的代碼
privateMapViewmMapView;
privateBaiduMapmMapLayer;
privateLocationClientmLocClient;
privatebooleanisFirstLoc=true;//是否首次定位

privatevoidinitLocation(){
mMapView=(MapView)findViewById(R.id.bmapView);
//先隱藏地圖,待定位到當前城市時再顯示
mMapView.setVisibility(View.INVISIBLE);
mMapLayer=mMapView.getMap();
mMapLayer.setOnMapClickListener(this);
//開啟定位圖層
mMapLayer.setMyLocationEnabled(true);
mLocClient=newLocationClient(this);
//設置定位監聽器
mLocClient.registerLocationListener(newMyLocationListenner());
LocationClientOptionoption=newLocationClientOption();
option.setOpenGps(true);//打開gps
option.setCoorType("bd09ll");//設置坐標類型
option.setScanSpan(1000);
option.setIsNeedAddress(true);//設置true才能獲得詳細的地址信息
//設置定位參數
mLocClient.setLocOption(option);
//開始定位
mLocClient.start();
//獲取最近一次的位置
//mLocClient.getLastKnownLocation();
}

publicclassMyLocationListennerimplementsBDLocationListener{

@Override
publicvoidonReceiveLocation(BDLocationlocation){
//mapview銷毀後不在處理新接收的位置
if(location==null||mMapView==null){
Log.d(TAG,"locationisnullormMapViewisnull");
return;
}
m_latitude=location.getLatitude();
m_longitude=location.getLongitude();
Stringposition=String.format("當前位置:%s|%s|%s|%s|%s|%s|%s",
location.getProvince(),location.getCity(),
location.getDistrict(),location.getStreet(),
location.getStreetNumber(),location.getAddrStr(),
location.getTime());
loc_position.setText(position);
MyLocationDatalocData=newMyLocationData.Builder()
.accuracy(location.getRadius())
//此處設置開發者獲取到的方向信息,順時針0-360
.direction(100).latitude(m_latitude)
.longitude(m_longitude).build();
mMapLayer.setMyLocationData(locData);
if(isFirstLoc){
isFirstLoc=false;
LatLngll=newLatLng(m_latitude,m_longitude);
MapStatusUpdateupdate=MapStatusUpdateFactory.newLatLngZoom(ll,14);
mMapLayer.animateMapStatus(update);
//定位到當前城市時再顯示圖層
mMapView.setVisibility(View.VISIBLE);
}
}

publicvoidonReceivePoi(BDLocationpoiLocation){
}
}

 

POI搜索

POI即地圖注點,它是“Point of Interest”的縮寫,在地圖上標注地點名稱、類別、經度、緯度等信息,是一個帶位置信息的地圖標注。POI搜索是地圖sdk的一個重要應用,根據關鍵字搜索並在地圖上顯示POI結果,這是智能出行的基礎。


下面是使用百度地圖搜索POI的截圖:
\


下面是兩種地圖sdk進行POI搜索的代碼例子:
百度地圖
//以下主要是POI搜索用到的代碼
privatePoiSearchmPoiSearch=null;
privateSuggestionSearchmSuggestionSearch=null;
privateAutoCompleteTextViewmKey=null;
privateEditTextmScope=null;
privateButtonbtn_search,btn_nextpage,btn_cleardata;
privateArrayAdaptersugAdapter=null;
privateintload_Index=0;

privatevoidinitMap(){
mPoiSearch=PoiSearch.newInstance();
mPoiSearch.setOnGetPoiSearchResultListener(this);
mSuggestionSearch=SuggestionSearch.newInstance();
mSuggestionSearch.setOnGetSuggestionResultListener(this);
mScope=(EditText)findViewById(R.id.poi_city);
mKey=(AutoCompleteTextView)findViewById(R.id.poi_searchkey);
btn_search=(Button)findViewById(R.id.search);
btn_nextpage=(Button)findViewById(R.id.map_next_data);
btn_cleardata=(Button)findViewById(R.id.map_clear_data);
btn_search.setOnClickListener(this);
btn_nextpage.setOnClickListener(this);
btn_cleardata.setOnClickListener(this);
sugAdapter=newArrayAdapter(this,R.layout.spinner_dropdown_item);
mKey.setAdapter(sugAdapter);

//當輸入關鍵字變化時,動態更新建議列表
mKey.addTextChangedListener(newTextWatcher(){

@Override
publicvoidafterTextChanged(Editablearg0){
}

@Override
publicvoidbeforeTextChanged(CharSequencearg0,intarg1,
intarg2,intarg3){
}

@Override
publicvoidonTextChanged(CharSequencecs,intarg1,intarg2,
intarg3){
if(cs.length()<=0){
return;
}
Stringcity=mScope.getText().toString();
//使用建議搜索服務獲取建議列表,結果在onGetSuggestionResult中更新
mSuggestionSearch
.requestSuggestion((newSuggestionSearchOption())
.keyword(cs.toString()).city(city));
}
});
}

@Override
publicvoidonGetSuggestionResult(SuggestionResultres){
if(res==null||res.getAllSuggestions()==null){
return;
}else{
sugAdapter.clear();
for(SuggestionResult.SuggestionInfoinfo:res.getAllSuggestions()){
if(info.key!=null){
sugAdapter.add(info.key);
}
}
sugAdapter.notifyDataSetChanged();
}
}

//影響搜索按鈕點擊事件
publicvoidsearchButtonProcess(Viewv){
Log.d(TAG,"editCity="+mScope.getText().toString()
+",editSearchKey="+mKey.getText().toString()
+",load_Index="+load_Index);
Stringkeyword=mKey.getText().toString();
if(search_method==SEARCH_CITY){
Stringcity=mScope.getText().toString();
mPoiSearch.searchInCity((newPoiCitySearchOption()).city(city)
.keyword(keyword).pageNum(load_Index));
}elseif(search_method==SEARCH_NEARBY){
LatLngposition=newLatLng(m_latitude,m_longitude);
intradius=Integer.parseInt(mScope.getText().toString());
mPoiSearch.searchNearby((newPoiNearbySearchOption())
.location(position).keyword(keyword).radius(radius)
.pageNum(load_Index));
}
}

publicvoidgoToNextPage(Viewv){
load_Index++;
searchButtonProcess(null);
}

publicvoidonGetPoiResult(PoiResultresult){
if(result==null
||result.error==SearchResult.ERRORNO.RESULT_NOT_FOUND){
Toast.makeText(this,"未找到結果",Toast.LENGTH_LONG).show();
return;
}elseif(result.error==SearchResult.ERRORNO.NO_ERROR){
mMapLayer.clear();
PoiOverlayoverlay=newMyPoiOverlay(mMapLayer);
mMapLayer.setOnMarkerClickListener(overlay);
ListpoiList=result.getAllPoi();
overlay.setData(result);
overlay.addToMap();
overlay.zoomToSpan();
//for(PoiInfopoi:poiList){
//Stringdetail=String.format(
//"uid=%s,city=%s,name=%s,phone=%s,address=%s",poi.uid,
//poi.city,poi.name,poi.phoneNum,poi.address);
//Log.d(TAG,detail);//坐標為poi.location(LatLng結構)
//}
}elseif(result.error==SearchResult.ERRORNO.AMBIGUOUS_KEYWORD){
//當輸入關鍵字在本市沒有找到,但在其他城市找到時,返回包含該關鍵字信息的城市列表
StringstrInfo="在";
for(CityInfocityInfo:result.getSuggestCityList()){
strInfo+=cityInfo.city+",";
}
strInfo+="找到結果";
Toast.makeText(this,strInfo,Toast.LENGTH_LONG).show();
}
}

publicvoidonGetPoiDetailResult(PoiDetailResultresult){
if(result.error!=SearchResult.ERRORNO.NO_ERROR){
Toast.makeText(this,"抱歉,未找到結果",Toast.LENGTH_SHORT).show();
}else{
Log.d(TAG,
"name="+result.getName()+",address="
+result.getAddress()+",detail_url="
+result.getDetailUrl()+",shop_hours="
+result.getShopHours()+",telephone="
+result.getTelephone()+",price="
+result.getPrice()+",type="+result.getType()
+",tag="+result.getTag());
Toast.makeText(this,result.getName()+":"+result.getAddress(),
Toast.LENGTH_SHORT).show();
}
}

privateclassMyPoiOverlayextendsPoiOverlay{

publicMyPoiOverlay(BaiduMapbaiduMap){
super(baiduMap);
}

@Override
publicbooleanonPoiClick(intindex){
super.onPoiClick(index);
PoiInfopoi=getPoiResult().getAllPoi().get(index);
mPoiSearch.searchPoiDetail((newPoiDetailSearchOption()).poiUid(poi.uid));
returntrue;
}
}

 

測距、測面積

測量距離和測量面積是地圖sdk的又一個應用,除了在地圖上添加標注之外,就是要用到數學的兩個公式。
其中測距用的是勾股定理(又名商高定理):勾股定理是一個基本的幾何定理:一個直角三角形,兩直角邊的平方和等於斜邊的平方。如果直角三角形兩直角邊為a和b,斜邊為c,那麼a*a+b*b=c*c
測面積用的是海倫公式(又名秦九韶公式):海倫公式是利用三角形的三個邊長直接求三角形面積的公式,表達式為:S=√p(p-a)(p-b)(p-c)。基於海倫公式,可以推導出根據多邊形各邊長求多邊形面積的公式,即S = 0.5 * ( (x0*y1-x1*y0) + (x1*y2-x2*y1) + ... + (xn*y0-x0*yn) )


兩種地圖sdk在測量上的數學原理是一樣的,只在添加地圖標注上有些小差異,下面是使用高德地圖進行測量的截圖:
\


下面是兩種地圖sdk進行測量的代碼例子:
百度地圖
//下面是在地圖上添加繪圖操作
privatestaticintlineColor=0x55FF0000;
privatestaticintarcColor=0xbb00FFFF;
privatestaticinttextColor=0x990000FF;
privatestaticintpolygonColor=0x77FFFF00;
privatestaticintradius=100;
privateArrayListposArray=newArrayList();
booleanis_polygon=false;

privatevoidaddDot(LatLngpos){
if(is_polygon==true&&posArray.size()>1
&&MapUtil.isInsidePolygon(pos,posArray)==true){
Log.d(TAG,"isInsidePolygon");
LatLngcenterPos=MapUtil.getCenterPos(posArray);
OverlayOptionsooText=newTextOptions().bgColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text("標題")//.rotate(-30)
.position(centerPos);
mMapLayer.addOverlay(ooText);
return;
}
if(is_polygon==true){
Log.d(TAG,"is_polygon==true");
posArray.clear();
is_polygon=false;
}
booleanis_first=false;
LatLngthisPos=pos;
if(posArray.size()>0){
LatLngfirstPos=posArray.get(0);
intdistance=(int)Math.round(MapUtil.getShortDistance(
thisPos.longitude,thisPos.latitude,firstPos.longitude,
firstPos.latitude));
//多次點擊起點,要忽略之
if(posArray.size()==1&&distance<=0){
return;
}elseif(posArray.size()>1){
LatLnglastPos=posArray.get(posArray.size()-1);
intlastDistance=(int)Math.round(MapUtil.getShortDistance(
thisPos.longitude,thisPos.latitude,lastPos.longitude,
lastPos.latitude));
//重復響應當前位置的點擊,要忽略之
if(lastDistance<=0){
return;
}
}
if(distance thisPos=firstPos;
is_first=true;
}
Log.d(TAG,"distance="+distance+",radius="+radius+",is_first="+is_first);

//畫直線
LatLnglastPos=posArray.get(posArray.size()-1);
Listpoints=newArrayList();
points.add(lastPos);
points.add(thisPos);
OverlayOptionsooPolyline=newPolylineOptions().width(2)
.color(lineColor).points(points);
mMapLayer.addOverlay(ooPolyline);

//下面計算兩點之間距離
distance=(int)Math.round(MapUtil.getShortDistance(
thisPos.longitude,thisPos.latitude,lastPos.longitude,
lastPos.latitude));
StringdisText="";
if(distance>1000){
disText=Math.round(distance*10/1000)/10d+"公裡";
}else{
disText=distance+"米";
}
LatLngllText=newLatLng(
(thisPos.latitude+lastPos.latitude)/2,
(thisPos.longitude+lastPos.longitude)/2);
OverlayOptionsooText=newTextOptions().bgColor(0x00ffffff)
.fontSize(24).fontColor(textColor).text(disText)//.rotate(-30)
.position(llText);
mMapLayer.addOverlay(ooText);
}
if(is_first!=true){
//畫圓圈
OverlayOptionsooCircle=newCircleOptions().fillColor(lineColor)
.center(thisPos).stroke(newStroke(2,0xAAFF0000)).radius(radius);
mMapLayer.addOverlay(ooCircle);
//畫圖片標記
BitmapDescriptorbitmapDesc=BitmapDescriptorFactory
.fromResource(R.drawable.icon_geo);
OverlayOptionsooMarker=newMarkerOptions().draggable(false)
.visible(true).icon(bitmapDesc).position(thisPos);
mMapLayer.addOverlay(ooMarker);
mMapLayer.setOnMarkerClickListener(newOnMarkerClickListener(){
@Override
publicbooleanonMarkerClick(Markermarker){
LatLngmarkPos=marker.getPosition();
addDot(markPos);
returntrue;
}
});
}else{
Log.d(TAG,"posArray.size()="+posArray.size());
//可能存在地圖與標記同時響應點擊事件的情況
if(posArray.size()<3){
posArray.clear();
is_polygon=false;
return;
}
//畫多邊形
OverlayOptionsooPolygon=newPolygonOptions().points(posArray)
.stroke(newStroke(1,0xFF00FF00))
.fillColor(polygonColor);
mMapLayer.addOverlay(ooPolygon);
is_polygon=true;

//下面計算多邊形的面積
LatLngcenterPos=MapUtil.getCenterPos(posArray);
doublearea=Math.round(MapUtil.getArea(posArray));
StringareaText="";
if(area>1000000){
areaText=Math.round(area*100/1000000)/100d+"平方公裡";
}else{
areaText=(int)area+"平方米";
}
OverlayOptionsooText=newTextOptions().bgColor(0x00ffffff)
.fontSize(26).fontColor(textColor).text(areaText)//.rotate(-30)
.position(centerPos);
mMapLayer.addOverlay(ooText);
}
posArray.add(thisPos);
if(posArray.size()>=3){
//畫弧線
OverlayOptionsooArc=newArcOptions()
.color(arcColor)
.width(2)
.points(posArray.get(posArray.size()-1),
posArray.get(posArray.size()-2),
posArray.get(posArray.size()-3));
mMapLayer.addOverlay(ooArc);
}
}

@Override
publicvoidonMapClick(LatLngarg0){
addDot(arg0);
}

@Override
publicbooleanonMapPoiClick(MapPoiarg0){
addDot(arg0.getPosition());
returnfalse;
}

 


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved