我们经常会看到台风路径这样的预测路径,这个肉色多边形范围其实叫可能路径范围或者叫预报误差范围,会随着预测时间的增加而扩大,我们用java来怎么实现呢
//根据预报时刻模拟生成最大误差半径,已知24h=70km
double avg_max_error = 70.0/24;
Geometry polygon = null;
Point prevPoint = null;
//最后一个点
List<Geometry> geometryList = new ArrayList<>();
Point lastPoint = new Point(centerCoords.get(0).getCoordinate().y,centerCoords.get(0).getCoordinate().x);
for (int i = 0; i < centerCoords.size(); i++) {
Point point = new Point(centerCoords.get(i).getCoordinate().y,centerCoords.get(i).getCoordinate().x);
if(Objects.isNull(polygon)){
//前一个点
prevPoint = point;
double error_radius = avg_max_error*Long.valueOf(centerCoords.get(i).getYbsk());
String circleGeoJson = TurfTransformation.circle(com.mapbox.geojson.Point.fromLngLat(prevPoint.getLon(),prevPoint.getLat()),error_radius,32, TurfConstants.UNIT_KILOMETERS).toJson();
polygon = GeoDataTypeConvertUtils.geoJsonToGeometry(circleGeoJson);
geometryList.add(polygon);
CheapRuler ruler = CheapRuler.fromLatitude(prevPoint.getLat(), Unit.KILOMETERS);
double bearing = ruler.bearing(lastPoint,prevPoint);
Point p1 = ruler.destination(point,error_radius,bearing+90);
Point p4 = ruler.destination(point,error_radius,bearing-90);
String polygonStr = "{\"geometry\":{\"coordinates\":[["+lastPoint.toArray()+","+p1.toArray()+","+p4.toArray()+","+lastPoint.toArray()+"]],\"type\":\"Polygon\"},\"type\":\"Feature\"}";
Geometry polygonGeometry = GeoDataTypeConvertUtils.geoJsonToGeometry(polygonStr);
geometryList.add(polygonGeometry);
polygon = polygon.union(polygonGeometry);
continue;
}
double pre_error_radius = avg_max_error * Long.valueOf(centerCoords.get(i-1).getYbsk());
double error_radius = avg_max_error * Long.valueOf(centerCoords.get(i).getYbsk());
CheapRuler ruler = CheapRuler.fromLatitude(centerCoords.get(i).getCoordinate().y, Unit.KILOMETERS);
String circleGeoJson = "";
circleGeoJson = TurfTransformation.circle(com.mapbox.geojson.Point.fromLngLat(centerCoords.get(i).getCoordinate().x,centerCoords.get(i).getCoordinate().y),error_radius,32, TurfConstants.UNIT_KILOMETERS).toJson();
Geometry circleGeometry = GeoDataTypeConvertUtils.geoJsonToGeometry(circleGeoJson);
geometryList.add(circleGeometry);
//计算当前点到第一个历史点
double bearing = ruler.bearing(prevPoint,point);
Point p1 = ruler.destination(point,error_radius,bearing+90);
Point p2 = ruler.destination(prevPoint,pre_error_radius,bearing+90);
Point p3 = ruler.destination(prevPoint,pre_error_radius,bearing-90);
Point p4 = ruler.destination(point,error_radius,bearing-90);
PrecisionModel precisionModel = new PrecisionModel(10);
GeometryFactory geometryFactory1 = new GeometryFactory(precisionModel);
String polygonStr = "{\"geometry\":{\"coordinates\":[["+p1.toArray()+","+p2.toArray()+","+p3.toArray()+","+p4.toArray()+","+p1.toArray()+"]],\"type\":\"Polygon\"},\"type\":\"Feature\"}";
System.out.println("===polygonStr==="+polygonStr);
Geometry polygonGeometry = GeoDataTypeConvertUtils.geoJsonToGeometry(polygonStr);
geometryList.add(polygonGeometry);
GeometryCollection geometryCollection = geometryFactory1.createGeometryCollection(geometryList.toArray(new Geometry[geometryList.size()]));
polygon = polygon.union(geometryCollection.union());
prevPoint = point;
}
画出来的效果