计算不规则多边形的面积、中心、重心(计算地图围栏中心点

最近项目用到:在不规则多边形的中心点加一个图标。(e.g: xx地区发生暴雪,暴雪区域是多边形,给多边形中心加一个暴雪的图标)

之前的设计是,计算不规则多边形范围矩形bounds的中心点。这个比较简单,对于一些圆,矩形,凸多边形都比较适合。但是遇到凹多边形就会出现问题,比如一个月牙型的不规则多边形,bounds的中心点,就落到月牙外了。就有点难以接受了。

经过讨论,决定将中心改为重心。

下面上代码,

计算不规则多边形的中心:

[java] view plain copy

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;
}

计算不规则多边形的重心:

[java] view plain copy

/**

  • 获取不规则多边形重心点
  • @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 的类代替。 [java] view plain copy

public final double latitude;
public final double longitude;

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

转载于:https://my.oschina.net/u/2963604/blog/1620411

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#define geo_max(a,b) (((a) > (b)) ? (a) : (b)) #define geo_min(a,b) (((a) < (b)) ? (a) : (b)) GEO_EXPORT mappoint geo_trangeo2map(georect* grt, geopoint* pt, maprect* mrt); GEO_EXPORT geopoint geo_tranmap2geo(maprect* mrt, mappoint* mpt, georect* grt); /* *判断点在不在矩形里.在返回0 * 不在返回-1 */ GEO_EXPORT int geo_gptingrt(geopoint* gpt, georect* grt); GEO_EXPORT int geo_mptinmrt(mappoint* mpt, maprect* mrt); GEO_EXPORT geobool geo_gptingpolygon(geopoint* gpt, geopoints *gpts); /* *返回单位为:米 */ GEO_EXPORT double geo_distance(geopoint* gptfrom, geopoint* gptto); GEO_EXPORT double geo_distance_pt2polyline(geopoint* gpt, geopoints* gpts, geopoint* rnearestpt); GEO_EXPORT double geo_distance_pt2polygon(geopoint* gpt, geopoints* gpts, geopoint* rnearestpt); /* *返回单位为:平方米 */ //GEO_EXPORT double geo_area(geopoints* gpts); /* *返回单位为:度 *正北为0度,顺时针为正 */ GEO_EXPORT double geo_direction(geopoint* gptfrom, geopoint* gptto); /* * 矩形与矩形的关系 * a 在 b 里面, 返回 0 * a 部份在 b 里面,返回 1 * a 没和 b 相交, 返回 -1 * /\ y * | * | * | * |------------> x * o */ int geo_grtingrt(georect* rta, georect* rtb); /* * 矩形与矩形的关系 * a 在 b 里面, 返回 0 * a 部份在 b 里面,返回 1 * a 没和 b 相交, 返回 -1 * * o * |------------> x * | * | * | * | * \/ y */ int geo_mrtinmrt(maprect* rta, maprect* rtb); //判断线段是否相关 //相交返回GEO_TRUE //不相交返回GEO_FALSE geobool geo_linecrossline(geopoint* lafrom, geopoint* lato, geopoint* lbfrom, geopoint* lbto); /* * 多边形多边形的关系 * a 在 b 里面, 返回 0 * a 和 b 相交,返回 1 * a 没和 b 相交, 返回 -1 * b 在 a 里面, 返回 -2 * * /\ y * | * | * | * |------------> x * o */ int geo_gpolygoningpolygon(geopoints* gptsa, geopoints* gptsb);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值