1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| public static List<LatLong> narrowTest(List<LatLong> oldLatLongs, List<Float> dis){ //计算地块的顺逆时针 boolean wise = isClockwise(oldLatLongs); //原始边界点 List<LatLong> originalLatLongs = new ArrayList<>(oldLatLongs); for (int i = 0; i < dis.size(); i++) { originalLatLongs = narrowSingle(oldLatLongs,originalLatLongs, i, dis.get(i), wise); } return originalLatLongs; }
/** * * @param oldLatLongs 内缩边界点 * @param originalLatLongs 原始边界点 * @param index 内缩边序号 * @param dis 内缩距离 * @param clockwise 顺逆时针 * @return */ private static List<LatLong> narrowSingle(List<LatLong> oldLatLongs,List<LatLong> originalLatLongs, int index, float dis, boolean clockwise) { LatLong origin = oldLatLongs.get(0); List<Point2D> point2DS = loc2Point2D(origin, oldLatLongs); List<Line2D> line2DS = point2Line(point2DS);
Line2D midLine = line2DS.get(index);
Vector2D vector = new Vector2D(midLine.endPoint.x - midLine.startPoint.x, midLine.endPoint.y - midLine.startPoint.y); //平行线 Line2D ParallelLine;
if (vector.getRadian() == Math.PI / 2 || vector.getRadian() == -Math.PI / 2) { double space = dis * 100.0f;//对应的Y轴截距 ParallelLine = new Line2D(midLine.a, midLine.b, midLine.c - midLine.a * space); } else { double cos = Math.abs(Math.cos(vector.getRadian())); double space = dis * 100.0f / cos;//对应的Y轴截距 ParallelLine = new Line2D(midLine.a, midLine.b, midLine.c - midLine.b * space); }
Point2D pointT= ParallelLine.getIntersectPoint2(new Line2D(1,0,-(midLine.endPoint.x+midLine.startPoint.x)/2)); Vector2D vectorT = new Vector2D(pointT.x-midLine.startPoint.x,pointT.y-midLine.startPoint.y); double T = vector.crossProduct(vectorT);//T != 0 if ((clockwise && T > 0) || (!clockwise && T < 0)) {//顺逆不相同 if (vector.getRadian() == Math.PI / 2 || vector.getRadian() == -Math.PI / 2) { double space = -dis * 100.0f;//对应的Y轴截距 ParallelLine = new Line2D(midLine.a, midLine.b, midLine.c - midLine.a * space); } else { double cos = Math.abs(Math.cos(vector.getRadian())); double space = -dis * 100.0f / cos;//对应的Y轴截距 ParallelLine = new Line2D(midLine.a, midLine.b, midLine.c - midLine.b * space); } } Pair<Point2D, Integer> pointLeftPair = null; Pair<Point2D, Integer> pointRightPair = null;
List<Point2D> pointActual = loc2Point2D(origin, originalLatLongs); List<Line2D> lineActual = point2Line(pointActual);
//用于计算原始边界与内缩边界的差值 int temp = oldLatLongs.size() - originalLatLongs.size();
for (int i = 1; i < originalLatLongs.size() - 1; i++) { //左侧邻边序号,递减 int leftIndex = (index + originalLatLongs.size() - i - temp) % originalLatLongs.size(); //右邻边序号,递增 int rightIndex = (index + i - temp) % originalLatLongs.size(); if (pointLeftPair == null){ Point2D point1 = ParallelLine.getIntersectPoint2(line2DS.get(leftIndex)); //判断point1是否在多边形内部 if (point1 != null && isInPolygon(point2D2Latlong(origin, point1), oldLatLongs)){ pointLeftPair = new Pair<>(point1, leftIndex); } } if (pointRightPair == null){ Point2D point2 = ParallelLine.getIntersectPoint2(line2DS.get(rightIndex)); //判断point2是否在多边形内部 if (point2 != null && isInPolygon(point2D2Latlong(origin, point2), oldLatLongs)){ pointRightPair = new Pair<>(point2, rightIndex); } } //遍历所有边后还是无交点 if (pointLeftPair != null && pointRightPair != null){ break; } //左侧边与右侧边重合,结束遍历 if (Math.abs(leftIndex - rightIndex) <= 1) { break; } }
if (pointLeftPair == null || pointRightPair == null) { //如果无交点则返回上一次的边界点 return originalLatLongs; } else { int leftPairIndex = pointLeftPair.second; int rightPairIndex = pointRightPair.second;
int max = Math.max(leftPairIndex, rightPairIndex); int min = Math.min(leftPairIndex, rightPairIndex); //内缩边与其他边的两个交点正好在当前边的左右邻边上 if ((max - 1) % originalLatLongs.size() == (min + 1) % originalLatLongs.size()) { pointActual.set((pointLeftPair.second + 1) % originalLatLongs.size(), pointLeftPair.first); pointActual.set(pointRightPair.second, pointRightPair.first); } else { pointActual.set((pointLeftPair.second + 1) % originalLatLongs.size(), pointLeftPair.first); pointActual.set(pointRightPair.second, pointRightPair.first); if (rightPairIndex < leftPairIndex) { rightPairIndex = rightPairIndex + originalLatLongs.size(); } for (int i = rightPairIndex - 1; i > leftPairIndex + 1; i--) { pointActual.remove((i - 1) % originalLatLongs.size() + 1); } } } return point2D2Latlong(origin, pointActual); }
|