Wechat: yu389741| Email: gisdqy@163.com

Shop:https://www.giserdqy.com/shop

计算不规则多边形的面积、中心、重心java、c#实现


计算不规则多边形的面积、中心、重心

最近项目用到:在不规则多边形的中心点加一个图标。(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;
    }
//其中LatLng类就是一个包含经纬度点的简单类。可以自己创建一个包含 x ,y 的类代替。
计算不规则多边形的重心:
     /**
     * 获取不规则多边形重心点
     *
     * @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;

通过这张图,就可以发现中心和重心的区别了


求多边形重心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);
        }
资源来自网络,如有侵权,请联系我删除。

Have any Question or Comment?

发表评论

您的电子邮箱地址不会被公开。

CAPTCHAis initialing...