package com.example.demo.findwindeye;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 找风眼
* 总体思路,在撒点范围内画框,框框不停往右移动
* 移动的过程中做计算:只要四边的方向在画圆(上下边的点方向相对,左右边的点方向相对,且相邻边顺行)说明中心点是风眼
*/
public class Main {
private static JSONArray data = null;
private static List<Point> allPoints = null;
private static List<Double> sortedX = null;
private static List<Double> sortedY = null;
private static int calPointTotalNum = 4;
private static int calAddPointNum = calPointTotalNum - 1;
/**
* 台风速度大于1720cm。来自百度百科
*/
private static double TYPHOON_SPEED = 17.20;
static {
try{
JSONObject jsonObject = readFile();
data = jsonObject.getJSONArray("data");
allPoints = JSONArray.parseArray(data.toString(),Point.class);
sortedX = data.stream().map(o->{
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x");
}).distinct().sorted().collect(Collectors.toList());
sortedY = data.stream().map(o->{
JSONObject o1 = (JSONObject) o;
return o1.getDouble("y");
}).distinct().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
} catch (Exception e){
e.printStackTrace();
}
}
private static JSONObject readFile()throws Exception {
RandomAccessFile ra = new RandomAccessFile(
"C:\\study\\workspace\\demo\\src\\main\\java\\com\\example\\demo\\xml2json\\json" +
"\\LoDo_160913_0040_7.860M_Current.json","r");
byte[] bytes = new byte[1024 * 1024 * 10];
int read = ra.read(bytes);
String data = new String(bytes,0,read);
return JSONObject.parseObject(data);
}
public static void main(String[] args)throws Exception {
/*
1、找到最边点,上左,上右,下左,下右
2、从左上角开始往右移动(先找到步长)
*/
int xnum = 0, ynum = 0;
OUT:while (true) {
while(true){
Double startX = sortedX.get(xnum), startY = sortedY.get(ynum);
Double endX = sortedX.get(xnum+ calAddPointNum), endY = sortedY.get(ynum+ calAddPointNum);
// System.out.println("startX:"+startX+", startY:"+startY+", endX:"+endX+", endY:"+endY);
// System.out.println("endX:"+endX+", endY:"+endY);
// MyPolygon myPolygon = getMyPolygen(
// //原始点 - 0.000004,用于数据偏差
// new BigDecimal(startX.toString()).subtract(new BigDecimal("0.000004")).doubleValue(),
// new BigDecimal(startY.toString()).add(new BigDecimal("0.000004")).doubleValue(),
// new BigDecimal(endX.toString()).add(new BigDecimal("0.000004")).doubleValue(),
// new BigDecimal(endY.toString()).subtract(new BigDecimal("0.000004")).doubleValue()
// );
JSONArray pointInPolygon = findPointInPolygon(startX,startY,endX,endY);
if(pointInPolygon.size() > 0 ){
boolean isWindEye = checkIsWindEye(pointInPolygon);
if(isWindEye){
System.out.println("+++++++++++++++++++++++++\r\n"+pointInPolygon);
double midX = new BigDecimal(startX.toString())
.add(new BigDecimal(endX.toString()))
.divide(new BigDecimal("2")).doubleValue();
double midY = new BigDecimal(startY.toString())
.add(new BigDecimal(endY.toString()))
.divide(new BigDecimal("2")).doubleValue();
System.out.println("XY:"+midX+","+midY);
if(isTyphoonSpeed(pointInPolygon)){
// 超过一半的点为台风速度才是台风
System.out.println("是台风速度");
} else {
System.out.println("不是台风速度风眼");
}
}
}
xnum ++;
if(xnum + calAddPointNum == sortedX.size()){
xnum = 0;
break;
}
}
ynum ++;
if(ynum + calAddPointNum == sortedY.size()){
break;
}
}
System.out.println("执行结束");
}
/**
* 超过一半的点为台风速度,则为true
* @param pointInPolygon
* @return
*/
private static boolean isTyphoonSpeed(JSONArray pointInPolygon) {
JSONArray upPoints = findUpPoints(pointInPolygon);
JSONArray downPoints = findDownPoints(pointInPolygon);
JSONArray leftPoints = findLeftPoints(pointInPolygon);
JSONArray rightPoints = findRightPoints(pointInPolygon);
JSONArray all = new JSONArray();
all.addAll(upPoints);
all.addAll(downPoints);
all.addAll(leftPoints);
all.addAll(rightPoints);
int count = 0;
for (Object o : all) {
JSONObject o1 = (JSONObject) o;
Double v = o1.getDouble("v");
if (v >= TYPHOON_SPEED) {
count ++;
}
}
if(count > all.size()/2){
return true;
}
return false;
}
/**
* 判断是否有风眼
*
* 首先,判断
*
* @param pointInPolygon
* @return
*/
private static boolean checkIsWindEye(JSONArray pointInPolygon) {
// 必须包含16个点
// if(pointInPolygon.size() < 16){
// return false;
// }
// 找出最边边的中间点的方向,只要是成环就是风眼
Direction upDirection = findUpDirection(pointInPolygon);
// printDirection(upDirection);
if(upDirection == Direction.UNKNOWN) return false;
Direction downDirection = findDownDirection(pointInPolygon);
// printDirection(downDirection);
if(downDirection == Direction.UNKNOWN) return false;
if(upDirection == downDirection) return false;
Direction leftDirection = findLeftDirection(pointInPolygon);
// printDirection(leftDirection);
if(leftDirection == Direction.UNKNOWN) return false;
Direction rightDirection = findRightDirection(pointInPolygon);
// printDirection(rightDirection);
if(rightDirection == Direction.UNKNOWN) return false;
if(leftDirection == rightDirection) return false;
System.out.println();
if(upDirection == Direction.LEFT && leftDirection == Direction.DOWN
&& downDirection == Direction.RIGHT && rightDirection == Direction.UP
||
upDirection == Direction.RIGHT && rightDirection == Direction.DOWN
&& downDirection == Direction.LEFT && leftDirection == Direction.UP
){
return true;
}
return false;
}
private static void printDirection(Direction dir){
if(dir == Direction.UNKNOWN){
System.out.print("o");
} else if(dir == Direction.UP){
System.out.print("^");
} else if(dir == Direction.DOWN){
System.out.print("v");
} else if(dir == Direction.LEFT){
System.out.print("<");
} else if(dir == Direction.RIGHT){
System.out.print(">");
}
}
private static Direction findRightDirection(JSONArray pointInPolygon) {
JSONArray rightPoints = findRightPoints(pointInPolygon);
// if(rightPoints.size() < 4) return Direction.UNKNOWN;
Direction rightDirection = Direction.UNKNOWN;
// 所有的点都必须有同一方向
for(Object o : rightPoints){
JSONObject o1 = (JSONObject) o;
Double d = o1.getDouble("d");
// 直上直下的过滤掉
if(d == 90 || d == -90){
return Direction.UNKNOWN;
}
// 当前点的方向
Direction pointDir;
if(d > -90 && d < 90){
pointDir = Direction.UP;
} else {
pointDir = Direction.DOWN;
}
if(rightDirection == Direction.UNKNOWN){
// 上的方向未定义时与当前点一致
rightDirection = pointDir;
} else if(pointDir != rightDirection){
// 如果上方向已经定义,且当前点与上方向点不一至,说明该点不是风眼 <- ->
return Direction.UNKNOWN;
}
}
return rightDirection;
}
private static Direction findLeftDirection(JSONArray pointInPolygon) {
JSONArray leftPoints = findLeftPoints(pointInPolygon);
// if(leftPoints.size() < 4) return Direction.UNKNOWN;
Direction leftDirection = Direction.UNKNOWN;
// 所有的点都必须有同一方向
for(Object o : leftPoints){
JSONObject o1 = (JSONObject) o;
Double d = o1.getDouble("d");
// 直上直下的过滤掉
if(d == 90 || d == -90){
return Direction.UNKNOWN;
}
// 当前点的方向
Direction pointDir;
if(d > -90 && d < 90){
pointDir = Direction.UP;
} else {
pointDir = Direction.DOWN;
}
if(leftDirection == Direction.UNKNOWN){
// 上的方向未定义时与当前点一致
leftDirection = pointDir;
} else if(pointDir != leftDirection){
// 如果上方向已经定义,且当前点与上方向点不一至,说明该点不是风眼 <- ->
return Direction.UNKNOWN;
}
}
return leftDirection;
}
private static JSONArray findLeftPoints(JSONArray pointInPolygon) {
Optional<Double> x1 = pointInPolygon.stream().map(o -> {
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x");
}).min(Comparator.comparing(Double::doubleValue));
Double minx = x1.get();
JSONArray array = new JSONArray();
pointInPolygon.stream().filter(o->{
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x").equals(minx);
}).forEach(o->array.add(o));
return array;
}
private static JSONArray findRightPoints(JSONArray pointInPolygon) {
Optional<Double> x1 = pointInPolygon.stream().map(o -> {
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x");
}).max(Comparator.comparing(Double::doubleValue));
Double maxx = x1.get();
JSONArray array = new JSONArray();
pointInPolygon.stream().filter(o->{
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x").equals(maxx);
}).forEach(o->array.add(o));
return array;
}
private static Direction findDownDirection(JSONArray pointInPolygon) {
JSONArray downPoints = findDownPoints(pointInPolygon);
// if(downPoints.size() < 4) return Direction.UNKNOWN;
Direction downDirection = Direction.UNKNOWN;
// 所有的点都必须有同一方向
for(Object o : downPoints){
JSONObject o1 = (JSONObject) o;
Double d = o1.getDouble("d");
// 直上直下的过滤掉
if(d == 0 || d == 180){
return Direction.UNKNOWN;
}
// 当前点的方向
Direction pointDir;
if(d > 0){
pointDir = Direction.RIGHT;
} else {
pointDir = Direction.LEFT;
}
if(downDirection == Direction.UNKNOWN){
// 上的方向未定义时与当前点一致
downDirection = pointDir;
} else if(pointDir != downDirection){
// 如果上方向已经定义,且当前点与上方向点不一至,说明该点不是风眼 <- ->
return Direction.UNKNOWN;
}
}
return downDirection;
}
private static Direction findUpDirection(JSONArray pointInPolygon) {
// 找上方的点
JSONArray upPoints = findUpPoints(pointInPolygon);
// if(upPoints.size() < 4) return Direction.UNKNOWN;
Direction upDirection = Direction.UNKNOWN;
// 所有的点都必须有同一方向
for(Object o : upPoints){
JSONObject o1 = (JSONObject) o;
Double d = o1.getDouble("d");
// 直上直下的过滤掉
if(d == 0 || d == 180){
return Direction.UNKNOWN;
}
// 当前点的方向
Direction pointDir;
if(d > 0){
pointDir = Direction.RIGHT;
} else {
pointDir = Direction.LEFT;
}
if(upDirection == Direction.UNKNOWN){
// 上的方向未定义时与当前点一致
upDirection = pointDir;
} else if(pointDir != upDirection){
// 如果上方向已经定义,且当前点与上方向点不一至,说明该点不是风眼 <- ->
return Direction.UNKNOWN;
}
}
return upDirection;
}
private static JSONArray findDownPoints(JSONArray pointInPolygon) {
List<Double> xall = pointInPolygon.stream().map(o -> {
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x");
}).distinct().collect(Collectors.toList());
JSONArray array = new JSONArray();
xall.forEach(x->{
Optional<Object> min = pointInPolygon.stream().filter(o -> {
// 找到同一列的点
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x").equals(x);
}).min(Comparator.comparing(o -> {
// 找到同一列最y值是小的点
JSONObject o1 = (JSONObject) o;
return o1.getDouble("y");
}));
Object o = min.get();
array.add(o);
});
return array;
}
private static JSONArray findUpPoints(JSONArray pointInPolygon) {
List<Double> xall = pointInPolygon.stream().map(o -> {
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x");
}).distinct().collect(Collectors.toList());
JSONArray array = new JSONArray();
xall.forEach(x->{
Optional<Object> max = pointInPolygon.stream().filter(o -> {
// 找到同一列的点
JSONObject o1 = (JSONObject) o;
return o1.getDouble("x").equals(x);
}).max(Comparator.comparing(o -> {
// 找到同一列最y值是小的点
JSONObject o1 = (JSONObject) o;
return o1.getDouble("y");
}));
Object o = max.get();
array.add(o);
});
return array;
}
private static JSONArray findPointInPolygon(Double startX, Double startY, Double endX, Double endY) {
JSONArray objects = new JSONArray();
for (Object o : data) {
JSONObject o1 = (JSONObject) o;
Double x = o1.getDouble("x");
Double y = o1.getDouble("y");
if(x < startX || y > startY || x > endX || y < endY) {
continue;
} else {
objects.add(o);
if(objects.size() >= calPointTotalNum*calPointTotalNum){
break;
}
}
// if(myPolygon.contains(x, y)){
//
// }
}
return objects;
}
private static MyPolygon getMyPolygen(Double startx, Double starty,Double endX,Double endY) {
MyPolygon myPolygon = new MyPolygon();
myPolygon.addPoint(startx, starty);//左下
myPolygon.addPoint(startx, endY);//左上
myPolygon.addPoint(endX,endY);//右上
myPolygon.addPoint(endX, starty);//右下
return myPolygon;
}
public enum Direction {
UP,
DOWN,
LEFT,
RIGHT,
UNKNOWN;
}
}
找风眼程序
猜你喜欢
转载自blog.csdn.net/u011498478/article/details/124378990
今日推荐
周排行