最近做项目时,有个需求,需要在百度地图上标注出一些项目点信息,因为这些项目没有途径获取坐标点,只知道归属于哪个乡镇,所有我的解决思路是:先找出各项目的乡镇坐标点,然后再以乡镇坐标点为中心,再设置一段距离,通过计算,获取最大和最小的经纬度坐标信心,然后再最大最小经纬度坐标内,随机生成我们要的点坐标。我当前使用的百度地图的 BD-09 坐标系,以下为做法:
一、导包
<dependency>
<groupId>org.gavaghan</groupId>
<artifactId>geodesy</artifactId>
<version>1.1.3</version>
</dependency>
二、获取指定坐标,并在指定范围内获取随机坐标点
/**
* 获取指定坐标,指定范围内随机坐标点
* @param longitude 经度
* @param latitude 纬度
* @return
*/
private Map doGetCoordinateInfo(BigDecimal longitude,BigDecimal latitude) {
String rangeStr = iSystemConfigService.selectSystemConfigValueByKey("config_screen_bulletin_map_range");
BigDecimal range = new BigDecimal(rangeStr);
Map resultMap = new HashMap();
BigDecimal[] latArr = this.getLatitudeRange(latitude, longitude, range);
BigDecimal[] lonArr = this.getLongitudeRange(latitude, longitude, range);
double minlat = latArr[0].doubleValue();
double maxlat = latArr[1].doubleValue();
double minlng = lonArr[0].doubleValue();
double maxlng = lonArr[1].doubleValue();
//获取随机的坐标点
Random rand = new Random();
double lon = minlng + (rand.nextDouble() * (maxlng - minlng));
double lat = minlat + (rand.nextDouble() * (maxlat - minlat));
resultMap.put("lon", lon);
resultMap.put("lat", lat);
return resultMap;
}
/**
* 纬度范围
* @param latitude 纬度
* @param longitude 经度
* @param range 距离
* @return
*/
private BigDecimal[] getLatitudeRange(BigDecimal latitude, BigDecimal longitude, BigDecimal range){
BigDecimal[] latitudeRange = new BigDecimal[2];
//89.85 为本人计算的经纬度两者的比例,如不设置,因为经纬度每一度代表的实际距离不同,生成的点会近似聚集在一条线上,不会上下分布
range = range.multiply(new BigDecimal(89.85));
double oneLatitudeDistance = getDistance(latitude.doubleValue(), longitude.doubleValue(), latitude.add(new BigDecimal(1)).doubleValue(), latitude.doubleValue());
BigDecimal calculateLatitude = range.divide(new BigDecimal(oneLatitudeDistance), 14, BigDecimal.ROUND_HALF_UP);
latitudeRange[0] = latitude.subtract(calculateLatitude);
latitudeRange[1] = latitude.add(calculateLatitude);
return latitudeRange;
}
/**
* 经度范围
* @param latitude 纬度
* @param longitude 经度
* @param range 距离
* @return
*/
private BigDecimal[] getLongitudeRange(BigDecimal latitude, BigDecimal longitude, BigDecimal range){
BigDecimal[] longitudeRange = new BigDecimal[2];
double longitudeEnd = longitude.add(new BigDecimal(1)).doubleValue();
//计算一精度的距离
double oneLongitudeDistance = getDistance(latitude.doubleValue(), longitude.doubleValue(), latitude.doubleValue(), longitudeEnd);
BigDecimal calculateLongitude = range.divide(new BigDecimal(oneLongitudeDistance), 14, BigDecimal.ROUND_HALF_UP);
longitudeRange[0] = longitude.subtract(calculateLongitude);
longitudeRange[1] = longitude.add(calculateLongitude);
return longitudeRange;
}
/**
* 计算两点距离
* @return
*/
public static double getDistance(double lat, double lon, double newLat, double newLon) {
GlobalCoordinates source = new GlobalCoordinates(lat, lon);
GlobalCoordinates target = new GlobalCoordinates(newLat, newLon);
//此处特别注意,Ellipsoid.Sphere 为坐标系,百度地图可直接用这个,还有其他的可进源码查看
return new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.Sphere, source, target).getEllipsoidalDistance();
}