安卓 百度地图 显示网络接收数据

来源:互联网 发布:linux的socket 编辑:程序博客网 时间:2024/05/17 02:31

1. 描述:

最近忙做个小项目,涉及到百度地图,其大致功能如下:

从服务器端(webService写的)获取数据,全部接收一次有2M左右,1000+数据,要把这些数据显示到地图上,点击有详细信息,思考了下怎么去写,记录下,方便以后进行查看。

2. 思路:

  1. 数据量稍大,按理说应该每次点进界面就刷新数据,但是每次接收2M流量吃不消,且根据数据源更新速度不是很快的问题进行优化,优化思路如下:

  • 数据缓存,SQLite数据库进行数据缓存;
  • 打开界面时判断是否已经存在数据,存在则根据时间去获取当前时间间隔内的服务器数据(服务器沟通写好)
  • 服务器端数据压缩,压缩后安卓端进行解析

  2. 要在界面上显示数据,1000+的话只能根据当前界面的经纬度范围去显示当前范围内的数据,百度提供现成的获取当前屏幕尺寸的方法,获取之后发现判断范围不是特别准,就把范围相应扩大,并在范围内数据过多时不显示(数据直接全部从数据库中读取)

3. 实现

    1. 根据时间不同进行刷新数据

private void getWebServiceData(String col) {// 表示第一次访问航标相关数据,需要连接webService进行更新if (getDataAccordingToTime() == -1) {                   new GetShip(webUrl, "Getcbxx", col).execute();} else if (getDataAccordingToTime() < 600000) {// 10min内没有访问,不刷新SQlShipDao sd = new SQlShipDao(NewShipMap.this);// 先查询数据库中是否有数据,没有则获取if (!sd.chechkCount(col)) {new GetShip(webUrl, "Getcbxx", col).execute();} else {tipsBD.setText("滑动地图以查看航标情况");}} else {new GetShip(webUrl, "Getcbxx", col,getDataAccordingToTime()).execute();}}
  时间和获取数据的方式需要根据自己数据的特点来分析,这里第一次访问的话数据库肯定没有数据直接刷新,若10min内第二次访问则先去判断数据库中是否有数据,有直接查看,没有则刷新,超过10min直接刷新,获取此时间内的网络数据.

参考函数:

private long getDataAccordingToTime() {SharedPreferences settings = getSharedPreferences("timeA", 0);long time = settings.getLong("timeA", 0);if (time == 0) {return -1;} else {long per = time - System.currentTimeMillis();return per;}}

    2.  获取当前屏幕的经纬度,滑动停止的时候重绘界面

private void changeMapGetRegion() {OnMapStatusChangeListener listener = new OnMapStatusChangeListener() {/** * 手势操作地图,设置地图状态等操作导致地图状态开始改变。 *  * @param status *            地图状态改变开始时的地图状态 */public void onMapStatusChangeStart(MapStatus status) {}/** * 地图状态变化中 *  * @param status *            当前地图状态 */public void onMapStatusChange(MapStatus status) {mMarkerInfoLy.setVisibility(View.GONE);tipsBD.setVisibility(View.GONE);}/** * 地图状态改变结束 *  * @param status *            地图状态改变结束后的地图状态 */public void onMapStatusChangeFinish(MapStatus status) {synchronized (this) {LatLng RTOld = status.bound.northeast;LatLng LBOld = status.bound.southwest;//此处哦按段区域范围不是特别准确,故手动加减裕量LatLng RT = new LatLng(RTOld.latitude + 0.02,RTOld.longitude + 0.02);LatLng LB = new LatLng(LBOld.latitude - 0.02,LBOld.longitude - 0.02);//数据库中获取当前范围的数据SQlShipDao sd = new SQlShipDao(NewShipMap.this);hbList = sd.queryAll(column, RT, LB);if (hbList.size() > 100) {hbList = null;}//利用Handler更新数据Message msg = new Message();msg.what = 0x01;mHandler.sendMessage(msg);}}};mMapView.getMap().setOnMapStatusChangeListener(listener);}

    3. Handler更新界面

private void changeUI() {mHandler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 0x01:// hbList中保存有当前屏幕范围内的航标数据try {if (mBaiduMap != null) {mBaiduMap.clear();}} catch (Exception e) {}if (hbList == null) {break;}for (HBShipClass hb : hbList) {LatLng latLng1 = new LatLng(Double.valueOf(hb.getFLATESTLAT()), Double.valueOf(hb.getFLATESTLON()));Bundle bundle = new Bundle();bundle.putSerializable("info", hb);if(hb.getFLATESTSPEED().length()<2){//setMarker(latLng1, blackship);marker.setExtraInfo(bundle);}else{setMarker(latLng1, redship);marker.setExtraInfo(bundle);}}break;}}};}

参考方法:

/** * 设置图标 *  * @param latLng1 * @param bd */private void setMarker(LatLng latLng1, BitmapDescriptor bd) {oo = new MarkerOptions().position(latLng1).icon(bd).zIndex(9).draggable(true);marker = (Marker) (mBaiduMap.addOverlay(oo));}

  4. 点击图标弹出相应的信息

/** * 复用弹出面板mMarkerLy的控件 *  * @author lyh */private class ViewHolder {TextView MMSID;TextView shipType;TextView cx;TextView sydw;LinearLayout ivDetail;TextView recTime;}

private void initMarkerClickEvent() {// 对Marker的点击mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(final Marker marker) {// 获得marker中的数据HBShipClass info = (HBShipClass) marker.getExtraInfo().get("info");InfoWindow mInfoWindow;Button button = new Button(getApplicationContext());button.setBackgroundResource(R.drawable.pop3);button.setPadding(30, 20, 30, 50);button.setText(info.getMMSID());button.setTextColor(Color.BLACK);final LatLng ll = marker.getPosition();Point p = mBaiduMap.getProjection().toScreenLocation(ll);p.y -= 47;LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);mMarkerInfoLy.setVisibility(View.VISIBLE);// 为弹出的InfoWindow添加点击事件mInfoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(button), llInfo, 0,new OnInfoWindowClickListener() {@Overridepublic void onInfoWindowClick() {// 隐藏InfoWindowmBaiduMap.hideInfoWindow();}});// 显示InfoWindowmBaiduMap.showInfoWindow(mInfoWindow);popupInfo(mMarkerInfoLy, info);return true;}});}

protected void popupInfo(RelativeLayout mMarkerLy, HBShipClass info) {info1=info;ViewHolder viewHolder = null;if (mMarkerLy.getTag() == null) {viewHolder = new ViewHolder();viewHolder.MMSID = (TextView) findViewById(R.id.MMSID);viewHolder.shipType = (TextView) findViewById(R.id.shipType);viewHolder.cx = (TextView) findViewById(R.id.cx);viewHolder.sydw = (TextView) findViewById(R.id.sydw);viewHolder.recTime = (TextView) findViewById(R.id.recTime);viewHolder.ivDetail = (LinearLayout) findViewById(R.id.touchJump);viewHolder.ivDetail.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {Intent intent = new Intent(NewShipMap.this, HBDetail.class);Bundle bundle = new Bundle();bundle.putSerializable("info", info1);intent.putExtras(bundle);startActivity(intent);}});mMarkerLy.setTag(viewHolder);}viewHolder = (ViewHolder) mMarkerLy.getTag();viewHolder.MMSID.setText("ID:" + info.getMMSID());viewHolder.shipType.setText(info.getCBLB());viewHolder.cx.setText(info.getCX());viewHolder.sydw.setText(info.getSYDW());viewHolder.recTime.setText(info.getFLATESTTIME());}

大致的思路就这样,后面的细节需要自己思考咯~

结果如图:


   

苦逼学生党,一面准备找工作,一面被**,美工设计服务器全包了...程序思路若是有更好的实现方式,还望各位不吝赐教。

0 0