Marker多點(diǎn)聚合計(jì)算
什么是多點(diǎn)聚合呢萨蚕?所謂的多點(diǎn)聚合钞诡,就是計(jì)算地圖上一定范圍內(nèi)的點(diǎn)的個(gè)數(shù)空郊,然和講所有的點(diǎn)統(tǒng)計(jì)的數(shù)量顯示在范圍內(nèi)設(shè)置的marker上攻冷;我們需要解決的問題有:1、在地圖上劃定區(qū)域范圍;2呀狼、計(jì)算范圍內(nèi)的點(diǎn)的個(gè)數(shù)裂允;3、清楚原有的點(diǎn)赠潦,加上聚合后的點(diǎn)叫胖;4草冈、如何刷新
先說第一個(gè)問題:
在地圖上劃定區(qū)域范圍她奥,如下代碼實(shí)現(xiàn):
Point mPoint 定義一個(gè)點(diǎn),這個(gè)點(diǎn)是通過地圖上的marker點(diǎn)在屏幕上的投影的點(diǎn)
劃定區(qū)域范圍
如上圖怎棱,我們?cè)趧澏▍^(qū)域的時(shí)候以西南角和東北角(手機(jī)屏幕上表現(xiàn)為右下角和左上角)的兩個(gè)點(diǎn)直線距離為直徑劃定圓形區(qū)域哩俭,圓心為mPiont點(diǎn)所在的位置
southwestPoint的X軸上的值要小于northeastPoint的X軸上的值
northeastPoint的Y軸上的值要小于northeastPoint的Y軸上的值
southwestPoint 西南角
northeastPoint 東北角
Point mPoint = mProjection.toScreenLocation(mFirstMarkers.getPosition());
Point southwestPoint = new Point(mPoint.x - mGridSize,mPoint.y + mGridSize);
Point northeastPoint = new Point(mPoint.x + mGridSize,mPoint.y - mGridSize);
double northELat = mProjection.fromScreenLocation(northeastPoint).latitude;
double southWLat = mProjection.fromScreenLocation(southwestPoint).latitude;
double northElong = mProjection.fromScreenLocation(northeastPoint).longitude;
double southWlong = mProjection.fromScreenLocation(southwestPoint).longitude;
if(northELat > southWLat && northElong > southWlong) {
LatLng southWestLat = new LatLng(southWLat, southWlong);
LatLng northEastLat = new LatLng(northELat, northElong);
mBounds = new LatLngBounds(southWestLat, northEastLat);
}
添加聚合后的marker點(diǎn)
mMarkerOptions.anchor(0.5f,0.5f)
.position(mFirstMarkers.getPosition())
.icon(mFirstMarkers.getIcon());
mIncludeMarkers = new ArrayList<MarkerOptions>();
mIncludeMarkers.add(mFirstMarkers);
獲取聚合后Marker點(diǎn)上的數(shù)量
int num = mIncludeMarkers.size();
設(shè)置marker的style樣式和數(shù)據(jù)
int iconType = 0;
if(num < 100){
iconType = num / 10;
}else if(num >= 100){
iconType = (num / 100)/10;
}
switch (iconType) {
case 0:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 1:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 2:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 3:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 4:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 5:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 6:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 7:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 8:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
case 9:
mMarkerOptions.icon(BitmapDescriptorFactory
.fromBitmap(getViewBitmap(getView(num,
R.mipmap.map_marker_num))));
break;
}
根據(jù)地圖的移動(dòng)重置和刷新每次的聚合后的點(diǎn)和數(shù)字,因?yàn)楦叩碌貓D本身提供的地圖移動(dòng)的監(jiān)聽的方法拳恋,地圖的放大縮小凡资,移動(dòng)都?xì)w屬于地圖的移動(dòng),我們只需要在地圖移動(dòng)的時(shí)候谬运,我們需要通過Handler將Message傳到子線程隙赁,當(dāng)msg.what為0 的時(shí)候來重置地圖上的所有Marker,
Handler timeHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
// 更新markers
resetMarkers();
break;
}
}
};
補(bǔ)充(重置marker梆暖,參見代碼):
/**
* 獲取視野內(nèi)的marker 根據(jù)聚合算法合成自定義的marker 顯示視野內(nèi)的marker
*/
private void resetMarkers() {
/*
* 返回一個(gè)Projection 對(duì)象伞访。可以通過這個(gè)對(duì)象在屏幕坐標(biāo)與經(jīng)緯度坐標(biāo)之間進(jìn)行轉(zhuǎn)換轰驳。
* Projection 對(duì)象返回的是當(dāng)前可視區(qū)域的坐標(biāo)厚掷,當(dāng)可視區(qū)域變換時(shí),它不會(huì)自己更新级解。
* 返回:
* 當(dāng)前地圖位置的Projection對(duì)象冒黑。
*/
Projection projection = aMap.getProjection();
Point point = null;
markerOptionsListInView.clear();
for (MarkerOptions markerOptions : markerOptionsList) {
point = projection.toScreenLocation(markerOptions.getPosition());
if (point.x < 0 || point.y < 0 || point.x > width || point.y > height) {
} else {
markerOptionsListInView.add(markerOptions);
}
}
// 自定義的聚合類mSetMarkerIcon
ArrayList<SetMarkerIcon> mSetMarkerIcon = new ArrayList<SetMarkerIcon>();
for (MarkerOptions mp : markerOptionsListInView) {
if (mSetMarkerIcon.size() == 0) {
mSetMarkerIcon.add(new SetMarkerIcon(MapActivity.this,
mp, projection, 80));// 100根據(jù)自己需求調(diào)整
} else {
boolean isIn = false;
for (SetMarkerIcon cluster : mSetMarkerIcon) {
if (cluster.getBounds() != null) {
if (cluster.getBounds().contains(mp.getPosition())) {
cluster.addMarker(mp);
isIn = true;
break;
}
}
}
if (!isIn) {
mSetMarkerIcon.add(new SetMarkerIcon(
MapActivity.this, mp, projection, 80));
}
}
}
// 設(shè)置聚合點(diǎn)的位置和icon
for (SetMarkerIcon setMarkerIcon : mSetMarkerIcon) {
setMarkerIcon.setPositionAndIcon();
}
//清楚marker
aMap.clear(true);
// 重新添加
for (SetMarkerIcon markerIcon : mSetMarkerIcon) {
aMap.addMarker(markerIcon.getOptions());
}
}
Marker點(diǎn)擊
首先需要在初始化的時(shí)候添加Marker點(diǎn)擊的監(jiān)聽
aMap.setOnMarkerClickListener(this);// 設(shè)置點(diǎn)擊marker事件監(jiān)聽器
點(diǎn)擊事件的處理
/**
* 對(duì)marker標(biāo)注點(diǎn)點(diǎn)擊響應(yīng)事件
*/
@Override
public boolean onMarkerClick(Marker marker) {
//此處添加Marker點(diǎn)擊事件的處理
return false;
}
以前寫的文章沒有發(fā)表的,僅供參考和學(xué)習(xí)只用
謝謝惠顧勤哗,感覺有用的點(diǎn)個(gè)贊