参考资料:
http://www.jb51.cc/article/p-zzxlypsm-bks.html
http://www.eoeandroid.com/thread-322074-1-1.html
这两个都是实现了百度地图标注物聚合的功能,用到的基本思想基本上一致的。代码可以下载下来直接使用。
在它们的基础上,我将图中的点换成了照片本地的照片,而且数据库中照片存储的信息不仅包括照片的名称还包括照片拍摄的地理位置(包括经纬度和地区),随着缩放比例的变化,聚合物的数量在变化,聚合物的内容也在发生,照片的数量与内容也在发生变化。
Cluster类是聚合器,ClusterMarker是聚合标注物的功能。在编码过程中遇到的问题是如何来判断一个点处于聚合物中以及如何根据聚合物找到聚合物中的点,根据点找到对应的照片,并将第一张照片显示在地图上,以便在点击地图上显示的照片时,可以只查看该聚合物内坐标点处拍的照片。
---------------程序的入口类---------------
List<OverlayItem> clusters=mCluster.createCluster(mMarkers); itemOverlay.removeAll(); for(int i=0;i<clusters.size();i++){//以聚合物的总数量作为最外层循环 int z=0,num_photo=0; Cursor cursorFirstPhoto; String location="",first_photo=""; GeoPoint markGeo=clusters.get(i).getPoint();//聚合物的中心点 ArrayList <GeoPoint> geoP=new ArrayList<GeoPoint>(); Bounds bound = new Bounds(markGeo.getLatitudeE6(),markGeo.getLongitudeE6(),markGeo.getLatitudeE6(),markGeo.getLongitudeE6()); bound=MapUtils.getExtendedBounds(mMapView,bound,mGridSize); for(int j=0;j<mMarkers.size();j++){//以点的总个数作为内层循环 if(mCluster.isMarkersInCluster(mMarkers.get(j).getPoint(),bound)){//判断一个点是否处于该聚合物中 geoP.add(mMarkers.get(j).getPoint()); ArrayList<String>name=new ArrayList<String>(); double longitude=(mMarkers.get(j).getPoint().getLongitudeE6())/10E5; double latitude=(mMarkers.get(j).getPoint().getLatitudeE6())/10E5; Cursor cursor=dbM.queryByLocation(longitude,latitude); cursor.moveToFirst(); String photos=cursor.getString(cursor.getColumnIndex("photo_id")); cursorFirstPhoto=dbM.query(photos); String lo=cursorFirstPhoto.getString(cursorFirstPhoto.getColumnIndex("location")); for(cursor.moveToFirst();!(cursor.isAfterLast());cursor.moveToNext()){ String photo_name=cursor.getString(cursor.getColumnIndex("photo_id")); name.add(photo_name); num_photo++; } z++; } } }
---------------Cluster类中的createCluster(List<OverlayItem> markerList)函数和setClusterDrawable(ClusterMarker clusterMarker)函数修改---------------
public ArrayList<OverlayItem> createCluster(List<OverlayItem> markerList){ this.mClusterMarkers.clear(); ArrayList<OverlayItem> itemList = new ArrayList<OverlayItem>(); for(int i=0;i<markerList.size();i++){ addCluster(markerList.get(i)); } for(int i=0;i<mClusterMarkers.size();i++){ ClusterMarker cm=mClusterMarkers.get(i); double longitude=cm.getPoint().getLongitudeE6()/10E5; double latitude=cm.getPoint().getLatitudeE6()/10E5; DBManager dbM=new DBManager(); Cursor cursor=dbM.queryByFirstPhoto(longitude,latitude); cursor.moveToFirst(); String first_photo=cursor.getString(cursor.getColumnIndex("photo_id")); setClusterDrawable(cm,first_photo); OverlayItem oi = new OverlayItem(cm.getmCenter(),cm.getTitle(),cm.getSnippet()); oi.setMarker(cm.getMarker()); itemList.add(oi); } return itemList; }
注明:
queryByFirstPhoto(double longitude,double latitude)函数为根据经纬度查询第一张照片的名称。
private void setClusterDrawable(ClusterMarker clusterMarker,String image){ View drawableView=LayoutInflater.from(context).inflate(R.layout.drawable_mark,null); TextView text=(TextView)drawableView.findViewById(R.id.drawble_mark); DBManager dbM=new DBManager(); Cursor cursorFirstPhoto=dbM.query(image); String lo=cursorFirstPhoto.getString(cursorFirstPhoto.getColumnIndex("location")); System.out.println("2020002020202"+lo); String image_path=Environment.getExternalStorageDirectory().getPath()+ "/"+"traveljournal/"+lo+"/"+image; ImageSpan imgSpan = new ImageSpan(getFirstImage(image_path)); SpannableString spanString = new SpannableString("icon"); spanString.setSpan(imgSpan,4,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); text.setText(spanString); Bitmap bitmap = MapUtils.convertViewToBitmap(drawableView); clusterMarker.setMarker(new BitmapDrawable(bitmap)); }
ImageSpan imgSpan = new ImageSpan(getFirstImage(image_path));
SpannableString spanString = new SpannableString("icon");
spanString.setSpan(imgSpan,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setText(spanString);
public Bitmap getFirstImage(String path){ Bitmap b=null; try { InputStream is = new FileInputStream(path); BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Config.ARGB_8888; options.inJustDecodeBounds = false; options.inSampleSize = 2; b = BitmapFactory.decodeStream(is,null,options); int width = b.getWidth(); int height = b.getHeight(); // 根据自己的需要设置照片的大小 int newWidth = 200; int newHeight = 200; // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth,scaleHeight); // 得到新的图片 b = Bitmap.createBitmap(b,width,height,matrix,true); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return b; }
这个函数可以实现根据路径获得照片。
根据自己的项目修改小细节的部分就不说啦。