最近項目用到:在不規則多邊形的中心點加一個圖標。(e.g: xx地區發生暴雪,暴雪區域是多邊形,給多邊形中心加一個暴雪的圖標)
之前的設計是,計算不規則多邊形范圍矩形bounds的中心點。這個比較簡單,對於一些圓,矩形,凸多邊形都比較適合。但是遇到凹多邊形就會出現問題,比如一個月牙型的不規則多邊形,bounds的中心點,就落到月牙外了。就有點難以接受了。
經過討論,決定將中心改為重心。
下面上代碼,
計算不規則多邊形的中心:
- public static final double MIN_LAT = -90;
- public static final double MAX_LAT = 90;
- public static final double MIN_LNG = -180;
- public static final double MAX_LNG = 180;
- /**
- * 獲取不規則多邊形幾何中心點
- *
- * @param mPoints
- * @return
- */
- public static LatLng getCenterPoint(List<LatLng> mPoints) {
- // 1 自己計算
- // double latitude = (getMinLatitude(mPoints) + getMaxLatitude(mPoints)) / 2;
- // double longitude = (getMinLongitude(mPoints) + getMaxLongitude(mPoints)) / 2;
- // return new LatLng(latitude, longitude);
- // 2 使用Google map API提供的方法(推薦)
- LatLngBounds.Builder boundsBuilder = LatLngBounds.builder();
- for (LatLng ll : mPoints)
- boundsBuilder.include(ll);
- return boundsBuilder.build().getCenter();
- }
- // 經度最小值
- public static double getMinLongitude(List<LatLng> mPoints) {
- double minLongitude = MAX_LNG;
- if (mPoints.size() > 0) {
- minLongitude = mPoints.get(0).longitude;
- for (LatLng latlng : mPoints) {
- // 經度最小值
- if (latlng.longitude < minLongitude)
- minLongitude = latlng.longitude;
- }
- }
- return minLongitude;
- }
- // 經度最大值
- public static double getMaxLongitude(List<LatLng> mPoints) {
- double maxLongitude = MIN_LNG;
- if (mPoints.size() > 0) {
- maxLongitude = mPoints.get(0).longitude;
- for (LatLng latlng : mPoints) {
- // 經度最大值
- if (latlng.longitude > maxLongitude)
- maxLongitude = latlng.longitude;
- }
- }
- return maxLongitude;
- }
- // 緯度最小值
- public static double getMinLatitude(List<LatLng> mPoints) {
- double minLatitude = MAX_LAT;
- if (mPoints.size() > 0) {
- minLatitude = mPoints.get(0).latitude;
- for (LatLng latlng : mPoints) {
- // 緯度最小值
- if (latlng.latitude < minLatitude)
- minLatitude = latlng.latitude;
- }
- }
- return minLatitude;
- }
- // 緯度最大值
- public static double getMaxLatitude(List<LatLng> mPoints) {
- double maxLatitude = MIN_LAT;
- if (mPoints.size() > 0) {
- maxLatitude = mPoints.get(0).latitude;
- for (LatLng latlng : mPoints) {
- // 緯度最大值
- if (latlng.latitude > maxLatitude)
- maxLatitude = latlng.latitude;
- }
- }
- return maxLatitude;
- }
計算不規則多邊形的重心:
- /**
- * 獲取不規則多邊形重心點
- *
- * @param mPoints
- * @return
- */
- public static LatLng getCenterOfGravityPoint(List<LatLng> mPoints) {
- double area = 0.0;//多邊形面積
- double Gx = 0.0, Gy = 0.0;// 重心的x、y
- for (int i = 1; i <= mPoints.size(); i++) {
- double iLat = mPoints.get(i % mPoints.size()).latitude;
- double iLng = mPoints.get(i % mPoints.size()).longitude;
- double nextLat = mPoints.get(i - 1).latitude;
- double nextLng = mPoints.get(i - 1).longitude;
- double temp = (iLat * nextLng - iLng * nextLat) / 2.0;
- area += temp;
- Gx += temp * (iLat + nextLat) / 3.0;
- Gy += temp * (iLng + nextLng) / 3.0;
- }
- Gx = Gx / area;
- Gy = Gy / area;
- return new LatLng(Gx, Gy);
- }
其中LatLng類就是一個包含經緯度點的簡單類。可以自己創建一個包含 x ,y 的類代替。
- public final double latitude;
- public final double longitude;
通過這張圖,就可以發現中心和重心的區別了