今天,我就接着来浅谈一下关于百度地图的内景,外景的展示功能。今天具体要实现的功能就是输入该地点的名称然后就展示该地点的内景图片,有内景就展示内景,没有则显示该地点的街景,该功能是参考百度地图官方的API来实现。

实现街景展示的地点的搜索,需要涉及到几个方面的知识:HttpClient网络请求封装,解析JSON数据,封装解析后JSON数据。其实展示内景或者外景很简单,只需要获取到内景的uid(POI的id),外景的经纬度即可,然后通过相应的API即可设置。关键点就是如何去获得我输入地点的uid或者经纬度呢??这时候百度地图开放平台提供一个接口,就是输入一地点它就会返回该地点的uid和经纬度等信息的JSON数据,而我们只需要去解析这些JSON数据,就可以得到我们想要的uid和经纬度信息。大致的思路是这样的。

一、熟悉百度地图官方接口API数据的使用。

1、首先进入百度地图API官网,点击进入一个web服务API,然后选择PlaceAPI

通过以上介绍你应该就可以得到一个可以测试的URL,只要传入我们申请的APPKEY,根据传入不同的地点名称就会返回一个JSON数据。到底可不可以呢,其实我们可以测试一下,如果可以的话,我只要按要求拼接好URL,并把该URL粘贴到浏览器地址栏会返回一大串的JSON数据,如果返回了,那么我们成功拿到了数据,就可以进行下一步了。

http://api.map.baidu.com/place/v2/search?ak=3QIYhSeKPK770bpwzepo9GI1&output=json&query=北京大学&page_size=10&page_num=0&scope=1&region=全国

看来我们这样的拼接的URL还是存在着问题,它说少了一个参数,其实仔细思考一下,发现也很正常,因为我们的APPKEY是申请的类型Android手机类型,而这里的接口是提供web服务的,如果申请的APPKEY的类型是JavaScript类型的话,那么就无需mcode参数。而如果是android或者IOS则需要在URL后面再增添一个mcode参数,那么我们知道mcode是必需的,那么这mcode参数值是什么呢??其实的它的值就是你的Eclipse中的SHA1 fingerprint值和你的项目的包名组合中间用“;"连接具体如下:

最终得到如下的URL:

http://api.map.baidu.com/place/v2/search?ak=nylibTfKmZw9mGe3juhT3U9x&output=json&query=北京大学&page_size=10&page_num=0&scope=1&region=全国&mcode=F5:3E:06:3E:FC:E8:ED:19:60:2E:99:63:D8:78:85:2E:EB:12:9D:BE;com.mikyou.maptest

可以使用如下的URL粘贴浏览器测试一下,看是否可以返回JSON数据。最终发现可以返回JSON数据,那么到这里我们就知道了如何从百度官方拿到我们想要的数据。

并且从返回的JSON数据可以得到lat(经度),lng(纬度),streetId(街景id),uid(内景Id)等一系列的数据。那么接下来我们只需要利用的android的HttpClient中的get或post请求网络数据,得到返回的JSON数据,然后我们解析这些JSON数据得到经纬度,streetid,uid,然后把这些设置给百度全景展示的API即能实现全景和内景功能。

二、要实现全景功能需要在AndroidManifest.xml中配置一下BaseAppcation,用于对全景显示的初始化

package com.mikyou.tools;import android.app.Application;
import android.content.Context;
import android.widget.Toast;import com.baidu.lbsapi.BMapManager;
import com.baidu.lbsapi.MKGeneralListener;import com.baidu.mapapi.SDKInitializer;public class BaseApplication extends Application {private static Context mContext;public static float sScale;public static int sWidthDp;public static int sWidthPix;public BMapManager mBMapManager = null;private static BaseApplication mInstance;public static BaseApplication getInstance() {return mInstance;}@Overridepublic void onCreate() {super.onCreate();SDKInitializer.initialize(this);initEngineManager(this);mContext = this;mInstance = this;sScale = getResources().getDisplayMetrics().density;sWidthPix = getResources().getDisplayMetrics().widthPixels;sWidthDp = (int) (sWidthPix / sScale);}public void initEngineManager(Context context) {if (mBMapManager == null) {mBMapManager = new BMapManager(context);}if (!mBMapManager.init(new MyGeneralListener())) {Toast.makeText(BaseApplication.getInstance().getApplicationContext(),"BMapManager!", Toast.LENGTH_LONG).show();}}public static class MyGeneralListener implements MKGeneralListener {@Overridepublic void onGetPermissionState(int iError) {if (iError != 0) {} else {}}}
}
 <applicationandroid:name="com.mikyou.tools.BaseApplication"<!-- 配置在此处 -->android:allowBackup="true"android:icon="@drawable/icon"android:label="@string/app_name"android:theme="@style/AppTheme" ><meta-dataandroid:name="com.baidu.lbsapi.API_KEY"android:value="nylibTfKmZw9mGe3juhT3U9x" /><activityandroid:name="com.mikyou.maptest.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><serviceandroid:name="com.baidu.location.f"android:enabled="true"android:process=":remote" ><intent-filter><action android:name="com.baidu.location.service_v2.2" ></action></intent-filter></service><activityandroid:name="com.mikyou.maptest.OtherPnoramaActivity"android:label="@string/title_activity_other_pnorama" ></activity></application>

三、实现HttpClient中的网络数据请求,自己个人封装一个HttpUtil类,里面有个方法它能直接返回一个JSON对象。

package com.mikyou.tools;import java.io.IOException;
import java.util.List;import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;/*** @author mikyou* 封装get和post方式请求* HttpClient 维护session* 一个HttpClient对象代表一个浏览器* 高度封装了客户端与服务端交互的,可以直接返回一个JSONObject对象* */
public class HttpUtils {private static  JSONObject jsonObjects;private static String entityString;private static HttpResponse res=null;private static String APPKEY="nylibTfKmZw9mGe3juhT3U9x";//APPKEYprivate static String outputForm="json";//返回网络数据的格式private static String Head="http://api.map.baidu.com/place/v2/search?ak=";//URL接口地址首部private static String IP=null;private static int pageSize=20;//一次返回数据总条数private static String mcode="F5:3E:06:3E:FC:E8:ED:19:60:2E:99:63:D8:78:85:2E:EB:12:9D:BE;com.mikyou.maptest";//mcode参数private static HttpClient clients=new DefaultHttpClient();@SuppressWarnings("unused")public static JSONObject send(String destination,List<NameValuePair> params) throws ClientProtocolException, IOException, JSONException{if (params==null) {//表示发送get方式请求,否则就发送Post发送请求(因为get方式不需要params)IP=Head+APPKEY+"&output="+outputForm+"&query="+destination+"&page_size="+pageSize+"&page_num=0&scope=1&region=全国&mcode="+mcode;System.out.println("IP_Address:--------->"+IP);HttpGet get=new HttpGet(IP);res=clients.execute(get);}else{HttpPost post=new HttpPost(IP);post.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));res=clients.execute(post);}if (res.getStatusLine().getStatusCode()==200) {HttpEntity entity=res.getEntity();entityString=EntityUtils.toString(entity,HTTP.UTF_8);System.out.println("httpUtils--------------->"+entityString);jsonObjects=new JSONObject(entityString);}return jsonObjects;}public static String getEntityString() {return entityString;}public static void setEntityString(String entityString) {HttpUtils.entityString = entityString;}
}

接着就是使用HttpUtil去进行Http请求,我们在进行网络请求数据,一般都是耗时的操作,所以需要去开启一个子线程来专门进行网络请求,从而可以避免阻塞主线程不至于真个应用直接崩溃。子线程得到JSON对象后,还得需要通过Handler对象去把该对象传递给主线程,然后再到主线程中去解析JSON数据,最后让这些数据更新我们的UI,因为子线程是无法更新UI的。为了数据的读取的方便性,先将解析后的数据每一条数据保存成一个SearchInfo对象,整个数据就可以保存在SearchInfoList集合中,需要的时候就可以随时去取。

 /*** @author mikyou* 根据输入搜索的信息,从网络获得的JSON数据* 开启一个线程去获取网络数据* getSearchDataFromNetWork* */private void getSearchDataFromNetWork() {new Thread(new Runnable() {@Overridepublic void run() {try {JSONObject jsonObject=HttpUtils.send(searchEdit.getText().toString(), null);Message msg=new Message();msg.obj=jsonObject;msg.what=0x1234;handler.sendMessage(msg);} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}}}).start();              }});}
//搜索网络请求API得到的JSON数据/*** @author zhongqihong* 利用子线程请求中得到的网络数据,利用Handler来更新* 主线程(即UI线程)* */private Handler handler=new Handler(){public void handleMessage(android.os.Message msg) {if (msg.what==0x1234) {JSONObject object=(JSONObject) msg.obj;//toast("json:----->"+object.toString());//解析开始:然后把每一个地点信息封装到SearchInfo类中try {JSONArray array=object.getJSONArray("results");for (int i = 0; i < array.length(); i++) {JSONObject joObject=array.getJSONObject(i);String name=joObject.getString("name");JSONObject  object2=joObject.getJSONObject("location");double lat=object2.getDouble("lat");double lng=object2.getDouble("lng");String address=joObject.getString("address");String streetIds=joObject.getString("street_id");String uids=joObject.getString("uid");SearchInfo mInfo=new SearchInfo(name, lat, lng, address, streetIds, uids);searchInfoLists.add(mInfo);}} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}displayInDialog();}

然后通过displayInDialog方法将解析后的数据,显示在一个列表对话框中。,并且给每个列表项设置点击事件,当点击其中一项,就会把该项的SearchInfo存入的信息读取出经纬度信息,然后通过经纬度信息就可以创建一个经纬度对象,最后把该对象设置给地图,然后该地图就可以定位到该点在地图上的位置,并用一个全景的图标标识,最后点击该图标就会开启一个新的Activity来显示该点的全景或者内容,所以需要将该项的SearchInfo通过Intent对象传递过去。

     /*** @author mikyou* 显示搜索后信息的自定义列表项对话框,以及对话框点击事件的处理* */private void displayInDialog() {if (searchInfoLists!=null) {AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);builder.setIcon(R.drawable.calibration_arrow).setTitle("请选择你查询到的地点").setAdapter(new myDialogListAdapter(), new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {final SearchInfo mInfos=searchInfoLists.get(which);uid=mInfos.getUid();myBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker PnoramaMark) {Intent intent=new Intent(MainActivity.this, OtherPnoramaActivity.class);intent.putExtra("info", mInfos);startActivity(intent);return true;}});addPnoramaLayout(mInfos);//}}).show();}else{toast("未查询到相关地点");}}};

接着通过addPnoramaLayout(mInfos);方法将全景的覆盖物的图标添加到相对应地图的位置

 /*** @author mikyou* 添加全景覆盖物,即全景的图标,迅速定位到该地点在地图上的位置* */public void addPnoramaLayout(SearchInfo mInfos) {myBaiduMap.clear();  LatLng latLng=new LatLng(mInfos.getLatitude(), mInfos.getLongtiude());Marker pnoramaMarker=null;OverlayOptions options;BitmapDescriptor mPnoramaIcon=BitmapDescriptorFactory.fromResource(R.drawable.icon_card_streetscape_blue);options=new MarkerOptions().position(latLng).icon(mPnoramaIcon).zIndex(6);pnoramaMarker=(Marker) myBaiduMap.addOverlay(options);MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);myBaiduMap.animateMapStatus(msu);}

最后通过全景覆盖物的点击事件就可以开起一个新Activity来显示内景和全景,通过Intent传递一个当前点击的Item项SearchInfo对象

         myBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker PnoramaMark) {Intent intent=new Intent(MainActivity.this, OtherPnoramaActivity.class);intent.putExtra("info", mInfos);startActivity(intent);return true;}});

四、那么接下来就是对设置街景、内景API操作了,因为通过上一步传来的SearchInfo对象中保存了我们实现内景的所需的数据信息。

/*** @author mikyou* 显示全景* */private void initPanoramaView() {SearchInfo info=(SearchInfo) getIntent().getSerializableExtra("info");//获取从MainActivity中传来的SearchInfo对象String uid=info.getUid();//得到设置内景必需的uidpanoramaView=(PanoramaView) findViewById(R.id.panorama);//判断是否有内外景PanoramaRequest request=PanoramaRequest.getInstance(OtherPnoramaActivity.this);BaiduPoiPanoData poiPanoData=request.getPanoramaInfoByUid(uid);//将该uid设置给内景APIpanoramaView.setPanoramaImageLevel(ImageDefinition.ImageDefinitionMiddle);//表示展示的内景是中等分辨率,(ImageDefinitionHigh)高分辨率,(ImageDefinitionLow)低分辨率if (poiPanoData.hasInnerPano()) {//判断该POI是否有内景panoramaView.setPanoramaByUid(uid, PanoramaView.PANOTYPE_INTERIOR);panoramaView.setIndoorAlbumGone();//除去内景相册panoramaView.setIndoorAlbumVisible();//将内景相册显示}else if (poiPanoData.hasStreetPano()) {//判断该POI是否有外景,就只能通过经纬度来显示外景panoramaView.setPanorama(info.getLongtiude(), info.getLatitude());//没有内景就通过经纬度来展示街景//Toast.makeText(OtherPnoramaActivity.this, "有该地方的外景,wait", Toast.LENGTH_SHORT).show();}else{Toast.makeText(OtherPnoramaActivity.this, "sorry,网络不给力无法加载全景", Toast.LENGTH_SHORT).show();}}

五、全景功能明显也是高耗的功能,展示那么多高清大图需要很多网络流量那么则需要管理全景的生命周期,还是老方法将它的生命周期与该Activity的生命周期进行绑定即可。

 @Overrideprotected void onPause() {panoramaView.onPause();super.onPause();}@Overrideprotected void onResume() {panoramaView.onResume();super.onResume();}@Overrideprotected void onDestroy() {panoramaView.destroy();super.onDestroy();}

里全景功能就介绍完毕,最后附上两个Activity的源码:

MainActivity.java:

package com.mikyou.maptest;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import org.apache.http.client.ClientProtocolException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.mikyou.beans.MarkInfo;
import com.mikyou.beans.SearchInfo;
import com.mikyou.sensor.MyOrientationListener;
import com.mikyou.sensor.MyOrientationListener.onOrientationListener;
import com.mikyou.tools.HttpUtils;
public class MainActivity extends Activity implements OnClickListener,OnMapClickListener,OnMarkerClickListener{private MapView mapView=null;private BaiduMap myBaiduMap=null;//修改默认View相关private View defaultBaiduMapScaleButton,defaultBaiduMapLogo,defaultBaiduMapScaleUnit;//基本地图类型,实时交通,及覆盖物相关private ImageView mapRoad;private ImageView mapType;private String[] types={"普通地图","卫星地图","热力地图(已关闭)"};private float current;//放大或缩小的比例系数private ImageView expandMap;//放大地图控件private ImageView narrowMap;//缩小地图private ImageView addMarks;//添加覆盖物控件private BitmapDescriptor myMarks;private List<MarkInfo> markInfoList;private LinearLayout markLayout;//定位相关private LocationClient myLocationClient;//专门用于监听位置的客户端对象private MyLocationListener myListener;//定位监听器对象private double latitude,longtitude;//经纬度private BitmapDescriptor myBitmapLocation;//定位的自定义图标private boolean isFirstIn=true;//设置一个标记,查看是否是第一次private String locationTextString;//定义的位置的信息private TextView locationText;//显示定位信息的TextView控件private MyOrientationListener myOrientationListener;private float myCurrentX;private ImageView selectLocationMode;private ImageView myLocation;private String[] LocationModeString={"罗盘模式","普通模式","跟随模式","3D俯视模式(已关闭)"};//全景相关private EditText searchEdit;private ImageView okToSearch;private List<SearchInfo> searchInfoLists;private String uid;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);SDKInitializer.initialize(getApplicationContext());setContentView(R.layout.activity_main);mapView=(MapView) findViewById(R.id.map_view_test);initMapView();changeDefaultBaiduMapView();initMapLocation();initSearchDestination();}/*** @author mikyou* 搜索相关* */private void initSearchDestination() {searchEdit=(EditText) findViewById(R.id.search_panorama);okToSearch=(ImageView) findViewById(R.id.ok_to_search);okToSearch.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {searchInfoLists=new ArrayList<SearchInfo>();getSearchDataFromNetWork();}/*** @author mikyou* 根据输入搜索的信息,从网络获得的JSON数据* 开启一个线程去获取网络数据* getSearchDataFromNetWork* */private void getSearchDataFromNetWork() {new Thread(new Runnable() {@Overridepublic void run() {try {JSONObject jsonObject=HttpUtils.send(searchEdit.getText().toString(), null);Message msg=new Message();msg.obj=jsonObject;msg.what=0x1234;handler.sendMessage(msg);} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JSONException e) {e.printStackTrace();}}}).start();               }});}//搜索网络请求API得到的JSON数据/*** @author mikyou* 利用子线程请求中得到的网络数据,利用Handler来更新* 主线程(即UI线程)* */private Handler handler=new Handler(){public void handleMessage(android.os.Message msg) {if (msg.what==0x1234) {JSONObject object=(JSONObject) msg.obj;//toast("json:----->"+object.toString());//解析开始:然后把每一个地点信息封装到SearchInfo类中try {JSONArray array=object.getJSONArray("results");for (int i = 0; i < array.length(); i++) {JSONObject joObject=array.getJSONObject(i);String name=joObject.getString("name");JSONObject  object2=joObject.getJSONObject("location");double lat=object2.getDouble("lat");double lng=object2.getDouble("lng");String address=joObject.getString("address");String streetIds=joObject.getString("street_id");String uids=joObject.getString("uid");SearchInfo mInfo=new SearchInfo(name, lat, lng, address, streetIds, uids);searchInfoLists.add(mInfo);}} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}displayInDialog();}/*** @author mikyou* 显示搜索后信息的自定义列表项对话框,以及对话框点击事件的处理* */private void displayInDialog() {if (searchInfoLists!=null) {AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);builder.setIcon(R.drawable.calibration_arrow).setTitle("请选择你查询到的地点").setAdapter(new myDialogListAdapter(), new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {final SearchInfo mInfos=searchInfoLists.get(which);uid=mInfos.getUid();myBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker PnoramaMark) {Intent intent=new Intent(MainActivity.this, OtherPnoramaActivity.class);intent.putExtra("info", mInfos);startActivity(intent);return true;}});addPnoramaLayout(mInfos);//}}).show();}else{toast("未查询到相关地点");}}};/*** @author mikyou* 添加全景覆盖物,即全景的图标,迅速定位到该地点在地图上的位置* */public void addPnoramaLayout(SearchInfo mInfos) {myBaiduMap.clear();  LatLng latLng=new LatLng(mInfos.getLatitude(), mInfos.getLongtiude());Marker pnoramaMarker=null;OverlayOptions options;BitmapDescriptor mPnoramaIcon=BitmapDescriptorFactory.fromResource(R.drawable.icon_card_streetscape_blue);options=new MarkerOptions().position(latLng).icon(mPnoramaIcon).zIndex(6);pnoramaMarker=(Marker) myBaiduMap.addOverlay(options);MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);myBaiduMap.animateMapStatus(msu);}/*** @author mikyou* 将我们搜索的信息来自网络的JSON数据解析后,封装在一个SearchInfo类中* 然后将这些数据展示在一个自定义的列表项的对话框中,以下就为定义列表项的适配器* ListAdapter* */class myDialogListAdapter extends BaseAdapter{@Overridepublic int getCount() {return searchInfoLists.size();}@Overridepublic Object getItem(int position) {return getItem(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {SearchInfo mSearchInfo=searchInfoLists.get(position);View view=View.inflate(MainActivity.this, R.layout.dialog_list_item, null);TextView desnameTv=(TextView) view.findViewById(R.id.desname);TextView addressTv=(TextView) view.findViewById(R.id.address);desnameTv.setText(mSearchInfo.getDesname());addressTv.setText(mSearchInfo.getAddress());return view;}}/*** @author Mikyou* 初始化定位功能* */private void initMapLocation() {myLocationClient=new LocationClient(this);//创建一个定位客户端对象myListener=new MyLocationListener();//创建一个定位事件监听对象myLocationClient.registerLocationListener(myListener);//并给该定位客户端对象注册监听事件//对LocaitonClient进行一些必要的设置LocationClientOption option=new LocationClientOption();option.setCoorType("bd09ll");//设置坐标的类型option.setIsNeedAddress(true);//返回当前的位置信息,如果不设置为true,默认就为false,就无法获得位置的信息option.setOpenGps(true);//打开GPSoption.setScanSpan(1000);//表示1s中进行一次定位请求myLocationClient.setLocOption(option);useLocationOrientationListener();//调用方向传感器}/*** @author Mikyou* 定位结合方向传感器,从而可以实时监测到X轴坐标的变化,从而就可以检测到* 定位图标方向变化,只需要将这个动态变化的X轴的坐标更新myCurrentX值,* 最后在MyLocationData data.driection(myCurrentX);* */private void useLocationOrientationListener() {myOrientationListener=new MyOrientationListener(MainActivity.this);myOrientationListener.setMyOrientationListener(new onOrientationListener() {@Overridepublic void onOrientationChanged(float x) {//监听方向的改变,方向改变时,需要得到地图上方向图标的位置myCurrentX=x;System.out.println("方向:x---->"+x);}});        }/*** @author mikyou* 获取位置信息的客户端对象的监听器类MyLocationListener* */class MyLocationListener implements BDLocationListener{@Overridepublic void onReceiveLocation(BDLocation location) {//得到一个MyLocationData对象,需要将BDLocation对象转换成MyLocationData对象MyLocationData data=new MyLocationData.Builder().accuracy(location.getRadius())//精度半径.direction(myCurrentX)//方向.latitude(location.getLatitude())//经度.longitude(location.getLongitude())//纬度.build();myBaiduMap.setMyLocationData(data);//配置自定义的定位图标,需要在紧接着setMyLocationData后面设置//调用自定义定位图标changeLocationIcon();latitude=location.getLatitude();//得到当前的经度longtitude=location.getLongitude();//得到当前的纬度//toast("经度:"+latitude+"     纬度:"+longtitude);if (isFirstIn) {//表示用户第一次打开,就定位到用户当前位置,即此时只要将地图的中心点设置为用户此时的位置即可getMyLatestLocation(latitude,longtitude);//获得最新定位的位置,并且地图的中心点设置为我的位置isFirstIn=false;//表示第一次才会去定位到中心点locationTextString=""+location.getAddrStr();//这里得到地址必须需要在设置LocationOption的时候需要设置isNeedAddress为true;toast(locationTextString);locationText.setText(locationTextString);}}}/*** @author zhongqihong* 获得最新定位的位置,并且地图的中心点设置为我的位置* */private void getMyLatestLocation(double lat,double lng) {LatLng latLng=new LatLng(lat, lng);//创建一个经纬度对象,需要传入当前的经度和纬度两个整型值参数MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);//创建一个地图最新更新的状态对象,需要传入一个最新经纬度对象myBaiduMap.animateMapStatus(msu);//表示使用动画的效果传入,通过传入一个地图更新状态对象,然后利用百度地图对象来展现和还原那个地图更新状态,即此时的地图显示就为你现在的位置}/*** @author zhongqihong* 自定义定位图标* */private void changeLocationIcon() {myBitmapLocation=BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher);//引入自己的图标if (isFirstIn) {//表示第一次定位显示普通模式MyLocationConfiguration config=new MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config);}           }/*** @author zhongqihong* 初始化地图的View* */private void initMapView() {registerAllIds();registerAllEvents();}private void registerAllIds() {mapRoad=(ImageView) findViewById(R.id.road_condition);mapType=(ImageView) findViewById(R.id.map_type);expandMap=(ImageView) findViewById(R.id.add_scale);narrowMap=(ImageView) findViewById(R.id.low_scale);addMarks=(ImageView) findViewById(R.id.map_marker);markLayout=(LinearLayout) findViewById(R.id.mark_layout);locationText=(TextView) findViewById(R.id.mylocation_text);selectLocationMode=(ImageView) findViewById(R.id.map_location);myLocation=(ImageView) findViewById(R.id.my_location);}private void registerAllEvents() {mapRoad.setOnClickListener(this);mapType.setOnClickListener(this);expandMap.setOnClickListener(this);narrowMap.setOnClickListener(this);addMarks.setOnClickListener(this);selectLocationMode.setOnClickListener(this);myLocation.setOnClickListener(this);}/*** @author mikyou* 除去百度地图上的默认控件* */private void changeDefaultBaiduMapView() {changeInitialzeScaleView();//改变默认百度地图初始加载的地图比例//设置隐藏缩放和扩大的百度地图的默认的比例按钮for (int i = 0; i < mapView.getChildCount(); i++) {//遍历百度地图中的所有子View,找到这个扩大和缩放的按钮控件View,然后设置隐藏View即可View child=mapView.getChildAt(i);if (child instanceof ZoomControls) {defaultBaiduMapScaleButton=child;//该defaultBaiduMapScaleButton子View是指百度地图默认产生的放大和缩小的按钮,得到这个Viewbreak;}}defaultBaiduMapScaleButton.setVisibility(View.GONE);//然后将该View的Visiblity设为不存在和不可见,即隐藏defaultBaiduMapLogo =mapView.getChildAt(1);//该View是指百度地图中默认的百度地图的Logo,得到这个ViewdefaultBaiduMapLogo.setPadding(300, -10, 100, 100);//设置该默认Logo View的位置,因为这个该View的位置会影响下面的刻度尺单位View显示的位置mapView.removeViewAt(1);//最后移除默认百度地图的logo ViewdefaultBaiduMapScaleUnit=mapView.getChildAt(2);//得到百度地图的默认单位刻度的ViewdefaultBaiduMapScaleUnit.setPadding(100, 0, 115,200);//最后设置调整百度地图的默认单位刻度View的位置        }/*** @author mikyou* 改变默认初始化的地图的比例* */private void changeInitialzeScaleView() {myBaiduMap=mapView.getMap();//改变百度地图的放大比例,让首次加载地图就开始扩大到500米的距离,获得百度地图对象MapStatusUpdate factory=MapStatusUpdateFactory.zoomTo(15.0f);myBaiduMap.animateMapStatus(factory);        }/*** @author mikyou* 管理地图的生命周期* */protected void onDestroy() {super.onDestroy();//在Activity执行onDestory时执行mapView(地图)生命周期管理mapView.onDestroy();}@Overrideprotected void onStart() {//当Activity调用onStart方法,开启定位以及开启方向传感器,即将定位的服务、方向传感器和Activity生命周期绑定在一起myBaiduMap.setMyLocationEnabled(true);//开启允许定位if (!myLocationClient.isStarted()) {myLocationClient.start();//开启定位}//开启方向传感器myOrientationListener.start();super.onStart();}@Overrideprotected void onStop() {//当Activity调用onStop方法,关闭定位以及关闭方向传感器myBaiduMap.setMyLocationEnabled(false);myLocationClient.stop();//关闭定位myOrientationListener.stop();//关闭方向传感器super.onStop();}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();//在Activity执行onResume是执行MapView(地图)生命周期管理mapView.onResume();}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();mapView.onPause();}//点击事件相关@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.road_condition://是否打开实时交通switchRoadCondition();break;case R.id.map_type://选择地图的类型selectMapType();break;case R.id.add_scale://放大地图比例expandMapScale();break;case R.id.low_scale://缩小地图比例narrowMapScale();break;case R.id.map_marker://添加覆盖物addMapMarks();break;case R.id.my_location://定位功能,需要用到LocationClient进行定位//BDLocationListenergetMyLatestLocation(latitude,longtitude);break;case R.id.map_location://选择定位模式selectLocation();break;default:break;}}/*** @author mikyou* 选择定位的模式* */private void selectLocation() {AlertDialog.Builder builder2=new AlertDialog.Builder(this);builder2.setIcon(R.drawable.track_collect_running).setTitle("请选择定位的模式").setItems(LocationModeString, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String mode=LocationModeString[which];if (mode.equals("罗盘模式")) {MyLocationConfiguration config=new MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config);}else if (mode.equals("跟随模式")) {MyLocationConfiguration config=new MyLocationConfiguration(LocationMode.FOLLOWING, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config);}else if (mode.equals("普通模式")) {MyLocationConfiguration config=new MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config);}else if (mode.equals("3D俯视模式(已关闭)")||mode.equals("3D俯视模式(已打开)")) {if (mode.equals("3D俯视模式(已打开)")) {UiSettings     mUiSettings = myBaiduMap.getUiSettings();mUiSettings.setCompassEnabled(true);LocationModeString[which]="3D俯视模式(已关闭)";toast("3D模式已关闭");}else{MyLocationConfiguration config=new MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config);MyLocationConfiguration config2=new MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);myBaiduMap.setMyLocationConfigeration(config2);LocationModeString[which]="3D俯视模式(已打开)";toast("3D模式已打开");}}}}).show();     }/*** @author Mikyou* 添加覆盖物* */private void addMapMarks() {initMarksData();myBaiduMap.clear();//先清除一下图层LatLng latLng=null;Marker marker=null;OverlayOptions options;myMarks=BitmapDescriptorFactory.fromResource(R.drawable.mark);//引入自定义的覆盖物图标,将其转化成一个BitmapDescriptor对象//遍历MarkInfo的List一个MarkInfo就是一个Markfor (int i = 0; i < markInfoList.size(); i++) {//经纬度对象latLng=new LatLng(markInfoList.get(i).getLatitude(), markInfoList.get(i).getLongitude());//需要创建一个经纬对象,通过该对象就可以定位到处于地图上的某个具体点//图标options=new MarkerOptions().position(latLng).icon(myMarks).zIndex(6);marker=(Marker) myBaiduMap.addOverlay(options);//将覆盖物添加到地图上Bundle bundle=new Bundle();//创建一个Bundle对象将每个mark具体信息传过去,当点击该覆盖物图标的时候就会显示该覆盖物的详细信息bundle.putSerializable("mark", markInfoList.get(i));marker.setExtraInfo(bundle);}MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);//通过这个经纬度对象,地图就可以定位到该点myBaiduMap.animateMapStatus(msu);}/*** @author mikyou* 初始化覆盖物信息数据* */private void initMarksData() {markInfoList=new ArrayList<MarkInfo>();markInfoList.add(new MarkInfo(32.079254, 118.787623, R.drawable.pic1, "英伦贵族小旅馆", "距离209米", 1888));markInfoList.add(new MarkInfo(32.064355, 118.787624, R.drawable.pic2, "沙井国际高级会所", "距离459米", 388));markInfoList.add(new MarkInfo(28.7487420000, 115.8748860000, R.drawable.pic4, "华东交通大学南区", "距离5米", 888));markInfoList.add(new MarkInfo(28.7534890000, 115.8767960000, R.drawable.pic3, "华东交通大学北区", "距离10米", 188));myBaiduMap.setOnMarkerClickListener(this);myBaiduMap.setOnMapClickListener(this);   }/*** @author mikyou* 放大地图的比例* */private void narrowMapScale() {current-=0.5f;MapStatusUpdate msu=MapStatusUpdateFactory.zoomTo(15.0f+current);myBaiduMap.animateMapStatus(msu);}/***@author mikyou*缩小地图的比例 * */private void expandMapScale() {current+=0.5f;MapStatusUpdate msu2=MapStatusUpdateFactory.zoomTo(15.0f+current);myBaiduMap.animateMapStatus(msu2);}/*** @author mikyou* 选择地图的类型* */private void selectMapType() {AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);builder.setIcon(R.drawable.icon).setTitle("请选择地图的类型").setItems(types, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String select=types[which];if (select.equals("普通地图")) {myBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);}else if (select.equals("卫星地图")) {myBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);}else if (select.equals("热力地图(已关闭)")||select.equals("热力地图(已打开)")) {if(myBaiduMap.isBaiduHeatMapEnabled()) {myBaiduMap.setBaiduHeatMapEnabled(false);Toast.makeText(MainActivity.this, "热力地图已关闭", 0).show();types[which]="热力地图(已关闭)";}else {myBaiduMap.setBaiduHeatMapEnabled(true);Toast.makeText(MainActivity.this, "热力地图已打开", 0).show();types[which]="热力地图(已打开)";}}}}).show();}/*** @author mikyou* 是否打开实时交通* */private void switchRoadCondition() {if (myBaiduMap.isTrafficEnabled()) {//如果是开着的状态,当点击后,就会出关闭状态myBaiduMap.setTrafficEnabled(false);mapRoad.setImageResource(R.drawable.main_icon_roadcondition_off);}else{//如果是的关闭的状态,当点击后,就会处于开启的状态myBaiduMap.setTrafficEnabled(true);mapRoad.setImageResource(R.drawable.main_icon_roadcondition_on);}}/*** @author mikyou* 覆盖物的点击事件* */@Overridepublic boolean onMarkerClick(Marker marker) {Bundle bundle=  marker.getExtraInfo();MarkInfo MyMarker=(MarkInfo) bundle.getSerializable("mark");ImageView iv=(ImageView) markLayout.findViewById(R.id.mark_image);TextView distanceTv=(TextView) markLayout.findViewById(R.id.distance);TextView nameTv=(TextView) markLayout.findViewById(R.id.name);TextView zanNumsTv=(TextView) markLayout.findViewById(R.id.zan_nums);iv.setImageResource(MyMarker.getImageId());distanceTv.setText(MyMarker.getDistance()+"");nameTv.setText(MyMarker.getName());zanNumsTv.setText(MyMarker.getZanNum()+"");//初始化一个InfoWindowinitInfoWindow(MyMarker,marker);markLayout.setVisibility(View.VISIBLE);return true;}/***@author mikyou*初始化出一个InfoWindow* * */private void initInfoWindow(MarkInfo MyMarker,Marker marker) {// TODO Auto-generated method stubInfoWindow infoWindow;//InfoWindow中显示的View内容样式,显示一个TextViewTextView infoWindowTv=new TextView(MainActivity.this);infoWindowTv.setBackgroundResource(R.drawable.location_tips);infoWindowTv.setPadding(30, 20, 30, 50);infoWindowTv.setText(MyMarker.getName());infoWindowTv.setTextColor(Color.parseColor("#FFFFFF"));final LatLng latLng=marker.getPosition();Point p=myBaiduMap.getProjection().toScreenLocation(latLng);//将地图上的经纬度转换成屏幕中实际的点p.y-=47;//设置屏幕中点的Y轴坐标的偏移量LatLng ll=myBaiduMap.getProjection().fromScreenLocation(p);//把修改后的屏幕的点有转换成地图上的经纬度对象/*** @author mikyou* 实例化一个InfoWindow的对象* public InfoWindow(View view,LatLng position, int yOffset)通过传入的 view 构造一个 InfoWindow, 此时只是利用该view生成一个Bitmap绘制在地图中,监听事件由开发者实现。*  参数:* view - InfoWindow 展示的 view* position - InfoWindow 显示的地理位置* yOffset - InfoWindow Y 轴偏移量* */infoWindow=new InfoWindow(infoWindowTv, ll, 10);myBaiduMap.showInfoWindow(infoWindow);//显示InfoWindow}/*** @author mikyou* 给整个地图添加的点击事件* */@Overridepublic void onMapClick(LatLng arg0) {//表示点击地图其他的地方使得覆盖物的详情介绍的布局隐藏,但是点击已显示的覆盖物详情布局上,则不会消失,因为在详情布局上添加了Clickable=true//由于事件的传播机制,因为点击事件首先会在覆盖物布局的父布局(map)中,由于map是可以点击的,map则会把点击事件给消费掉,如果加上Clickable=true表示点击事件由详情布局自己处理,不由map来消费markLayout.setVisibility(View.GONE);myBaiduMap.hideInfoWindow();//隐藏InfoWindow}@Overridepublic boolean onMapPoiClick(MapPoi arg0) {return false;}public void toast(String str){Toast.makeText(MainActivity.this, str, 0).show();}
}

OtherPnoramaActivity.java:

package com.mikyou.maptest;import com.baidu.lbsapi.BMapManager;
import com.baidu.lbsapi.model.BaiduPoiPanoData;
import com.baidu.lbsapi.panoramaview.PanoramaRequest;
import com.baidu.lbsapi.panoramaview.PanoramaView;
import com.baidu.lbsapi.panoramaview.PanoramaView.ImageDefinition;
import com.mikyou.beans.SearchInfo;
import com.mikyou.tools.SystemStatusManager;import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;public class OtherPnoramaActivity extends Activity {private double latitude,longtiude;private PanoramaView panoramaView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setTranslucentStatus();setContentView(R.layout.activity_other_pnorama);initPanoramaView();}@Overrideprotected void onPause() {panoramaView.onPause();super.onPause();}@Overrideprotected void onResume() {panoramaView.onResume();super.onResume();}@Overrideprotected void onDestroy() {panoramaView.destroy();super.onDestroy();}/*** @author mikyou* 显示全景* */private void initPanoramaView() {SearchInfo info=(SearchInfo) getIntent().getSerializableExtra("info");//获取从MainActivity中传来的SearchInfo对象String uid=info.getUid();//得到设置内景必需的uidpanoramaView=(PanoramaView) findViewById(R.id.panorama2);//判断是否有内外景PanoramaRequest request=PanoramaRequest.getInstance(OtherPnoramaActivity.this);BaiduPoiPanoData poiPanoData=request.getPanoramaInfoByUid(uid);//将该uid设置给内景APIpanoramaView.setPanoramaImageLevel(ImageDefinition.ImageDefinitionMiddle);//表示展示的内景是中等分辨率,(ImageDefinitionHigh)高分辨率,(ImageDefinitionLow)低分辨率if (poiPanoData.hasInnerPano()) {//判断该POI是否有内景panoramaView.setPanoramaByUid(uid, PanoramaView.PANOTYPE_INTERIOR);panoramaView.setIndoorAlbumGone();//除去内景相册panoramaView.setIndoorAlbumVisible();//将内景相册显示}else if (poiPanoData.hasStreetPano()) {//判断该POI是否有外景,就只能通过经纬度来显示外景panoramaView.setPanorama(info.getLongtiude(), info.getLatitude());//没有内景就通过经纬度来展示街景//Toast.makeText(OtherPnoramaActivity.this, "有该地方的外景,wait", Toast.LENGTH_SHORT).show();}else{Toast.makeText(OtherPnoramaActivity.this, "sorry,网络不给力无法加载全景", Toast.LENGTH_SHORT).show();}}private void setTranslucentStatus() {if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT){Window win=getWindow();WindowManager.LayoutParams winParams=win.getAttributes();final int bits=WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;winParams.flags |=bits;win.setAttributes(winParams);}SystemStatusManager tintManager = new SystemStatusManager(this);tintManager.setStatusBarTintEnabled(true);tintManager.setStatusBarTintResource(0);tintManager.setNavigationBarTintEnabled(true);}
}

运行效果:

 

 Demo下载链接

浅谈百度地图的简单开发之实现地图全景,内景展示功能(四)相关推荐

  1. 浅谈百度地图的简单开发再续前缘之公交,地铁路线检索查询(六)

    关于百度地图的简单开发前段时间,写过一个小系列的博客关于百度地图的基本地图,定位,全景,导航等功能做了简单的介绍.从今天开始又将准备一期有关百度地图的POI检索的等一列查询功能,如城市检索,周边检索, ...

  2. 浅谈百度地图的简单开发最后收官之实现导航功能(五)

    这篇是高仿百度地图的最后一篇了,今天主要来实现百度地图的导航的功能,并且该导航还自带语音播报功能,然后最后对整个百度地图开发过程遇到的问题进行一些列举,并给出一些解决的办法,可能总结的不是很齐全,希望 ...

  3. 浅谈百度地图的简单开发之引入基本地图以及修改地图样式(一)

    今天,想给大家带来一个基于百度地图官方开放的API开发的高仿百度地图的Demo(还称不上是一个APP),基本实现了百度地图的几大核心功能,百度地图中的基本地图,百度地图的定位,百度地图的全景显示,百度 ...

  4. 浅谈百度地图的简单开发之结合方向传感器实现定位功能(三)

    今天我们来谈下百度地图的定位功能,在此之前我已经将百度地图的基本地图大概说了下,其实百度地图的基本功能还有很多的内容.感兴趣的可以到百度地图的开发者的官网看看.今天就开始来讲下百度地图中的定位功能. ...

  5. 浅谈百度地图的简单开发之实现基本地图的类型及覆盖物的添加(二)

    今天,我们接着上一讲,上一讲我们把地图上界面自定义了一番,加上了按钮等一系列的控件,但是还没有给这些加上具体的功能,今天这一讲,主要是实现几种地图的切换,是否开启实时交通,通过自定义的按钮去控制地图的 ...

  6. 百度地图的简单开发之方向传感器实现定位功能

    今天我们来谈下百度地图的定位功能,在此之前我已经将百度地图的基本地图大概说了下,其实百度地图的基本功能还有很多的内容.感兴趣的可以到百度地图的开发者的官网看看.今天就开始来讲下百度地图中的定位功能. ...

  7. java百度地图路线规划_浅谈百度地图WEB开发中的四种路线规划

    百度地图在3.0的Javascript api中增加了四种路径规划,分别是:步行.骑行.自驾.公交. 关于路线规划的引用也相当简单,我们以步行为例://实例化地图 var map = new BMap ...

  8. iOS开发之百度地图的简单集成——标注POI检索

    iOS开发之百度地图的简单集成--标注&POI检索 .h文件 // Created by XK_Recollection on 16/6/15. // Copyright © 2016年 GN ...

  9. catia三维轴承_浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文

    浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文 一.概述 单排四点接触球转盘轴承是一种能够同时承受较大轴向负荷.径向负荷和倾覆力矩等综合载荷,集支承.旋转.传动.固定等多种功能于一身的特殊 ...

最新文章

  1. SpringMVC(三):使用 POJO 对象绑定请求参数值
  2. 先庆祝一下,冠军的心博客园诞生了!!
  3. CCNP自学之路——eigrp--1
  4. pytorch教程龙曲良46-55
  5. 为什么嵌入式工程师会对8位MCU有误解?
  6. 基于C#.NET的--Windows进程管理工具
  7. Probe:Android线上OOM问题定位组件
  8. Java+包裹类型_java中的包裹类型
  9. android 编译模块
  10. Selenium学习笔记||三、BeautifulSoup
  11. 40道C语言大学经典例题及代码(免费 全)
  12. 编程获取中国股市行业分类并作图--使用python、tushare、pyecharts实现
  13. 如何把 .mobi 格式的电子书转换成 PDF
  14. sublime-text-3-build-3207 破解+注册码
  15. DNT精英论坛(暨.NET北京俱乐部)第3期沙龙:区块链跨链技术的设计与实践
  16. 安庆师范大学c语言程序设计,安庆师范大学计算机与信息学院欢迎你!
  17. telnet -测试端口号
  18. OpenSSL心脏出血漏洞
  19. Android 音量控制流程分析
  20. python开发mbus程序_基于MBUS标准协议采集水、热、气表的方法与流程

热门文章

  1. 【软考中级】多媒体应用设计师复习笔记第六章
  2. Gibonacci number【斐波拉契】
  3. Codeforces Round #143 (Div. 2)-D. Magic Box
  4. 球半篮球分析,NBA总决赛第四场:顿凯尔特人VS勇士
  5. 《我编程,我快乐》 摘抄
  6. 使用CSS写一个三角形
  7. Windows Server 2008 R2 安装Oracle 10g 提示“程序异常终止”问题
  8. adminLTE 教程
  9. kmeans算法_KMeans聚类算法详解
  10. DELL 1520 笔记本拆机