转载地址:http://blog.youkuaiyun.com/shao941122/article/details/53671643
最近项目用到:在不规则多边形的中心点加一个图标。(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;
-
-
-
-
-
-
-
- public static LatLng getCenterPoint(List<LatLng> mPoints) {
-
-
-
-
-
- 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;
- }
计算不规则多边形的重心:
-
-
-
-
-
-
- public static LatLng getCenterOfGravityPoint(List<LatLng> mPoints) {
- double area = 0.0;
- double Gx = 0.0, Gy = 0.0;
- 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;
通过这张图,就可以发现中心和重心的区别了

求多边形重心C#版代码:
public PointF getCenterOfGravityPoint(List<PointF> mPoints)
{
float area = 0.0f;//多边形面积
float Gx = 0.0f, Gy = 0.0f;// 重心的x、y
for (int i = 1; i <= mPoints.Count; i++)
{
float iLat = mPoints[(i % mPoints.Count())].X;
float iLng = mPoints[(i % mPoints.Count())].Y;
float nextLat = mPoints[(i - 1)].X;
float nextLng = mPoints[(i - 1)].Y;
float temp = (iLat * nextLng - iLng * nextLat) / 2.0f;
area += temp;
Gx += temp * (iLat + nextLat) / 3.0f;
Gy += temp * (iLng + nextLng) / 3.0f;
}
Gx = Gx / area;
Gy = Gy / area;
return new PointF(Gx, Gy);
}