Initial version -- added millennium read funcionality
This commit is contained in:
@@ -0,0 +1,382 @@
|
||||
package com.google.maps.android;
|
||||
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/* JADX INFO: loaded from: classes2.dex */
|
||||
public class PolyUtil {
|
||||
public static final double DEFAULT_TOLERANCE = 0.1d;
|
||||
|
||||
private PolyUtil() {
|
||||
}
|
||||
|
||||
private static double tanLatGC(double d, double d2, double d3, double d4) {
|
||||
return ((Math.tan(d) * Math.sin(d3 - d4)) + (Math.tan(d2) * Math.sin(d4))) / Math.sin(d3);
|
||||
}
|
||||
|
||||
private static double mercatorLatRhumb(double d, double d2, double d3, double d4) {
|
||||
return ((MathUtil.mercator(d) * (d3 - d4)) + (MathUtil.mercator(d2) * d4)) / d3;
|
||||
}
|
||||
|
||||
private static boolean intersects(double d, double d2, double d3, double d4, double d5, boolean z) {
|
||||
if ((d5 >= 0.0d && d5 >= d3) || ((d5 < 0.0d && d5 < d3) || d4 <= -1.5707963267948966d || d <= -1.5707963267948966d || d2 <= -1.5707963267948966d || d >= 1.5707963267948966d || d2 >= 1.5707963267948966d || d3 <= -3.141592653589793d)) {
|
||||
return false;
|
||||
}
|
||||
double d6 = (((d3 - d5) * d) + (d2 * d5)) / d3;
|
||||
if (d >= 0.0d && d2 >= 0.0d && d4 < d6) {
|
||||
return false;
|
||||
}
|
||||
if ((d <= 0.0d && d2 <= 0.0d && d4 >= d6) || d4 >= 1.5707963267948966d) {
|
||||
return true;
|
||||
}
|
||||
if (z) {
|
||||
if (Math.tan(d4) < tanLatGC(d, d2, d3, d5)) {
|
||||
return false;
|
||||
}
|
||||
} else if (MathUtil.mercator(d4) < mercatorLatRhumb(d, d2, d3, d5)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean containsLocation(LatLng latLng, List<LatLng> list, boolean z) {
|
||||
return containsLocation(latLng.latitude, latLng.longitude, list, z);
|
||||
}
|
||||
|
||||
public static boolean containsLocation(double d, double d2, List<LatLng> list, boolean z) {
|
||||
int size = list.size();
|
||||
if (size == 0) {
|
||||
return false;
|
||||
}
|
||||
double radians = Math.toRadians(d);
|
||||
double radians2 = Math.toRadians(d2);
|
||||
LatLng latLng = list.get(size - 1);
|
||||
double radians3 = Math.toRadians(latLng.latitude);
|
||||
double radians4 = Math.toRadians(latLng.longitude);
|
||||
int i = 0;
|
||||
double d3 = radians3;
|
||||
for (LatLng latLng2 : list) {
|
||||
double dWrap = MathUtil.wrap(radians2 - radians4, -3.141592653589793d, 3.141592653589793d);
|
||||
if (radians == d3 && dWrap == 0.0d) {
|
||||
return true;
|
||||
}
|
||||
double radians5 = Math.toRadians(latLng2.latitude);
|
||||
double radians6 = Math.toRadians(latLng2.longitude);
|
||||
if (intersects(d3, radians5, MathUtil.wrap(radians6 - radians4, -3.141592653589793d, 3.141592653589793d), radians, dWrap, z)) {
|
||||
i++;
|
||||
}
|
||||
d3 = radians5;
|
||||
radians4 = radians6;
|
||||
}
|
||||
return (i & 1) != 0;
|
||||
}
|
||||
|
||||
public static boolean isLocationOnEdge(LatLng latLng, List<LatLng> list, boolean z, double d) {
|
||||
return isLocationOnEdgeOrPath(latLng, list, true, z, d);
|
||||
}
|
||||
|
||||
public static boolean isLocationOnEdge(LatLng latLng, List<LatLng> list, boolean z) {
|
||||
return isLocationOnEdge(latLng, list, z, 0.1d);
|
||||
}
|
||||
|
||||
public static boolean isLocationOnPath(LatLng latLng, List<LatLng> list, boolean z, double d) {
|
||||
return isLocationOnEdgeOrPath(latLng, list, false, z, d);
|
||||
}
|
||||
|
||||
public static boolean isLocationOnPath(LatLng latLng, List<LatLng> list, boolean z) {
|
||||
return isLocationOnPath(latLng, list, z, 0.1d);
|
||||
}
|
||||
|
||||
private static boolean isLocationOnEdgeOrPath(LatLng latLng, List<LatLng> list, boolean z, boolean z2, double d) {
|
||||
return locationIndexOnEdgeOrPath(latLng, list, z, z2, d) >= 0;
|
||||
}
|
||||
|
||||
public static int locationIndexOnPath(LatLng latLng, List<LatLng> list, boolean z, double d) {
|
||||
return locationIndexOnEdgeOrPath(latLng, list, false, z, d);
|
||||
}
|
||||
|
||||
public static int locationIndexOnPath(LatLng latLng, List<LatLng> list, boolean z) {
|
||||
return locationIndexOnPath(latLng, list, z, 0.1d);
|
||||
}
|
||||
|
||||
public static int locationIndexOnEdgeOrPath(LatLng latLng, List<LatLng> list, boolean z, boolean z2, double d) {
|
||||
List<LatLng> list2;
|
||||
int i;
|
||||
double d2;
|
||||
int size = list.size();
|
||||
int i2 = -1;
|
||||
if (size == 0) {
|
||||
return -1;
|
||||
}
|
||||
double d3 = d / 6371009.0d;
|
||||
double dHav = MathUtil.hav(d3);
|
||||
double radians = Math.toRadians(latLng.latitude);
|
||||
double radians2 = Math.toRadians(latLng.longitude);
|
||||
if (z) {
|
||||
i = size - 1;
|
||||
list2 = list;
|
||||
} else {
|
||||
list2 = list;
|
||||
i = 0;
|
||||
}
|
||||
LatLng latLng2 = list2.get(i);
|
||||
double radians3 = Math.toRadians(latLng2.latitude);
|
||||
double radians4 = Math.toRadians(latLng2.longitude);
|
||||
if (z2) {
|
||||
int i3 = 0;
|
||||
double d4 = radians3;
|
||||
double d5 = radians4;
|
||||
for (LatLng latLng3 : list) {
|
||||
double radians5 = Math.toRadians(latLng3.latitude);
|
||||
double radians6 = Math.toRadians(latLng3.longitude);
|
||||
if (isOnSegmentGC(d4, d5, radians5, radians6, radians, radians2, dHav)) {
|
||||
return Math.max(0, i3 - 1);
|
||||
}
|
||||
i3++;
|
||||
d4 = radians5;
|
||||
d5 = radians6;
|
||||
}
|
||||
} else {
|
||||
double d6 = radians - d3;
|
||||
double d7 = radians + d3;
|
||||
double dMercator = MathUtil.mercator(radians3);
|
||||
double dMercator2 = MathUtil.mercator(radians);
|
||||
Iterator<LatLng> it = list.iterator();
|
||||
int i4 = 0;
|
||||
while (it.hasNext()) {
|
||||
LatLng next = it.next();
|
||||
Iterator<LatLng> it2 = it;
|
||||
double radians7 = Math.toRadians(next.latitude);
|
||||
double dMercator3 = MathUtil.mercator(radians7);
|
||||
double d8 = dMercator2;
|
||||
double radians8 = Math.toRadians(next.longitude);
|
||||
if (Math.max(radians3, radians7) < d6 || Math.min(radians3, radians7) > d7) {
|
||||
d2 = radians7;
|
||||
} else {
|
||||
double dWrap = MathUtil.wrap(radians8 - radians4, -3.141592653589793d, 3.141592653589793d);
|
||||
double dWrap2 = MathUtil.wrap(radians2 - radians4, -3.141592653589793d, 3.141592653589793d);
|
||||
d2 = radians7;
|
||||
double[] dArr = {dWrap2, dWrap2 + 6.283185307179586d, dWrap2 - 6.283185307179586d};
|
||||
for (int i5 = 0; i5 < 3; i5++) {
|
||||
double d9 = dArr[i5];
|
||||
double d10 = dMercator3 - dMercator;
|
||||
double d11 = (dWrap * dWrap) + (d10 * d10);
|
||||
double dClamp = d11 > 0.0d ? MathUtil.clamp(((d9 * dWrap) + ((d8 - dMercator) * d10)) / d11, 0.0d, 1.0d) : 0.0d;
|
||||
if (MathUtil.havDistance(radians, MathUtil.inverseMercator(dMercator + (dClamp * d10)), d9 - (dClamp * dWrap)) < dHav) {
|
||||
return Math.max(0, i4 - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
i4++;
|
||||
radians4 = radians8;
|
||||
it = it2;
|
||||
dMercator = dMercator3;
|
||||
dMercator2 = d8;
|
||||
radians3 = d2;
|
||||
i2 = -1;
|
||||
}
|
||||
}
|
||||
return i2;
|
||||
}
|
||||
|
||||
private static double sinDeltaBearing(double d, double d2, double d3, double d4, double d5, double d6) {
|
||||
double dSin = Math.sin(d);
|
||||
double dCos = Math.cos(d3);
|
||||
double dCos2 = Math.cos(d5);
|
||||
double d7 = d6 - d2;
|
||||
double d8 = d4 - d2;
|
||||
double dSin2 = Math.sin(d7) * dCos2;
|
||||
double dSin3 = Math.sin(d8) * dCos;
|
||||
double d9 = dSin * 2.0d;
|
||||
double dSin4 = Math.sin(d5 - d) + (dCos2 * d9 * MathUtil.hav(d7));
|
||||
double dSin5 = Math.sin(d3 - d) + (d9 * dCos * MathUtil.hav(d8));
|
||||
double d10 = ((dSin2 * dSin2) + (dSin4 * dSin4)) * ((dSin3 * dSin3) + (dSin5 * dSin5));
|
||||
if (d10 <= 0.0d) {
|
||||
return 1.0d;
|
||||
}
|
||||
return ((dSin2 * dSin5) - (dSin4 * dSin3)) / Math.sqrt(d10);
|
||||
}
|
||||
|
||||
private static boolean isOnSegmentGC(double d, double d2, double d3, double d4, double d5, double d6, double d7) {
|
||||
double dHavDistance = MathUtil.havDistance(d, d5, d2 - d6);
|
||||
if (dHavDistance <= d7) {
|
||||
return true;
|
||||
}
|
||||
double dHavDistance2 = MathUtil.havDistance(d3, d5, d4 - d6);
|
||||
if (dHavDistance2 <= d7) {
|
||||
return true;
|
||||
}
|
||||
double dHavFromSin = MathUtil.havFromSin(MathUtil.sinFromHav(dHavDistance) * sinDeltaBearing(d, d2, d3, d4, d5, d6));
|
||||
if (dHavFromSin > d7) {
|
||||
return false;
|
||||
}
|
||||
double dHavDistance3 = MathUtil.havDistance(d, d3, d2 - d4);
|
||||
double d8 = ((1.0d - (dHavDistance3 * 2.0d)) * dHavFromSin) + dHavDistance3;
|
||||
if (dHavDistance > d8 || dHavDistance2 > d8) {
|
||||
return false;
|
||||
}
|
||||
if (dHavDistance3 < 0.74d) {
|
||||
return true;
|
||||
}
|
||||
double d9 = 1.0d - (2.0d * dHavFromSin);
|
||||
return MathUtil.sinSumFromHav((dHavDistance - dHavFromSin) / d9, (dHavDistance2 - dHavFromSin) / d9) > 0.0d;
|
||||
}
|
||||
|
||||
public static List<LatLng> simplify(List<LatLng> list, double d) {
|
||||
LatLng latLng;
|
||||
int size = list.size();
|
||||
if (size < 1) {
|
||||
throw new IllegalArgumentException("Polyline must have at least 1 point");
|
||||
}
|
||||
double d2 = 0.0d;
|
||||
if (d <= 0.0d) {
|
||||
throw new IllegalArgumentException("Tolerance must be greater than zero");
|
||||
}
|
||||
boolean zIsClosedPolygon = isClosedPolygon(list);
|
||||
if (zIsClosedPolygon) {
|
||||
latLng = list.get(list.size() - 1);
|
||||
list.remove(list.size() - 1);
|
||||
list.add(new LatLng(latLng.latitude + 1.0E-11d, latLng.longitude + 1.0E-11d));
|
||||
} else {
|
||||
latLng = null;
|
||||
}
|
||||
Stack stack = new Stack();
|
||||
double[] dArr = new double[size];
|
||||
int i = 0;
|
||||
dArr[0] = 1.0d;
|
||||
int i2 = size - 1;
|
||||
dArr[i2] = 1.0d;
|
||||
if (size > 2) {
|
||||
stack.push(new int[]{0, i2});
|
||||
int i3 = 0;
|
||||
while (stack.size() > 0) {
|
||||
int[] iArr = (int[]) stack.pop();
|
||||
double d3 = d2;
|
||||
for (int i4 = iArr[0] + 1; i4 < iArr[1]; i4++) {
|
||||
double dDistanceToLine = distanceToLine(list.get(i4), list.get(iArr[0]), list.get(iArr[1]));
|
||||
if (dDistanceToLine > d3) {
|
||||
d3 = dDistanceToLine;
|
||||
i3 = i4;
|
||||
}
|
||||
}
|
||||
if (d3 > d) {
|
||||
dArr[i3] = d3;
|
||||
stack.push(new int[]{iArr[0], i3});
|
||||
stack.push(new int[]{i3, iArr[1]});
|
||||
}
|
||||
d2 = 0.0d;
|
||||
}
|
||||
}
|
||||
if (zIsClosedPolygon) {
|
||||
list.remove(list.size() - 1);
|
||||
list.add(latLng);
|
||||
}
|
||||
ArrayList arrayList = new ArrayList();
|
||||
for (LatLng latLng2 : list) {
|
||||
if (dArr[i] != 0.0d) {
|
||||
arrayList.add(latLng2);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public static boolean isClosedPolygon(List<LatLng> list) {
|
||||
return list.get(0).equals(list.get(list.size() - 1));
|
||||
}
|
||||
|
||||
public static double distanceToLine(LatLng latLng, LatLng latLng2, LatLng latLng3) {
|
||||
if (latLng2.equals(latLng3)) {
|
||||
return SphericalUtil.computeDistanceBetween(latLng3, latLng);
|
||||
}
|
||||
double radians = Math.toRadians(latLng.latitude);
|
||||
double radians2 = Math.toRadians(latLng.longitude);
|
||||
double radians3 = Math.toRadians(latLng2.latitude);
|
||||
double radians4 = Math.toRadians(latLng2.longitude);
|
||||
double radians5 = Math.toRadians(latLng3.latitude);
|
||||
double radians6 = Math.toRadians(latLng3.longitude);
|
||||
double dCos = Math.cos(radians3);
|
||||
double d = radians5 - radians3;
|
||||
double d2 = (radians6 - radians4) * dCos;
|
||||
double d3 = (((radians - radians3) * d) + (((radians2 - radians4) * dCos) * d2)) / ((d * d) + (d2 * d2));
|
||||
if (d3 <= 0.0d) {
|
||||
return SphericalUtil.computeDistanceBetween(latLng, latLng2);
|
||||
}
|
||||
if (d3 >= 1.0d) {
|
||||
return SphericalUtil.computeDistanceBetween(latLng, latLng3);
|
||||
}
|
||||
return SphericalUtil.computeDistanceBetween(latLng, new LatLng(latLng2.latitude + ((latLng3.latitude - latLng2.latitude) * d3), latLng2.longitude + (d3 * (latLng3.longitude - latLng2.longitude))));
|
||||
}
|
||||
|
||||
public static List<LatLng> decode(String str) {
|
||||
int i;
|
||||
int i2;
|
||||
int length = str.length();
|
||||
ArrayList arrayList = new ArrayList();
|
||||
int i3 = 0;
|
||||
int i4 = 0;
|
||||
int i5 = 0;
|
||||
while (i3 < length) {
|
||||
int i6 = 1;
|
||||
int i7 = 0;
|
||||
int i8 = 1;
|
||||
while (true) {
|
||||
i = i3 + 1;
|
||||
int iCharAt = str.charAt(i3) - '@';
|
||||
i8 += iCharAt << i7;
|
||||
i7 += 5;
|
||||
if (iCharAt < 31) {
|
||||
break;
|
||||
}
|
||||
i3 = i;
|
||||
}
|
||||
int i9 = ((i8 & 1) != 0 ? ~(i8 >> 1) : i8 >> 1) + i4;
|
||||
int i10 = 0;
|
||||
while (true) {
|
||||
i2 = i + 1;
|
||||
int iCharAt2 = str.charAt(i) - '@';
|
||||
i6 += iCharAt2 << i10;
|
||||
i10 += 5;
|
||||
if (iCharAt2 < 31) {
|
||||
break;
|
||||
}
|
||||
i = i2;
|
||||
}
|
||||
i5 += (i6 & 1) != 0 ? ~(i6 >> 1) : i6 >> 1;
|
||||
arrayList.add(new LatLng(((double) i9) * 1.0E-5d, ((double) i5) * 1.0E-5d));
|
||||
i4 = i9;
|
||||
i3 = i2;
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public static String encode(List<LatLng> list) {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
long j = 0;
|
||||
long j2 = 0;
|
||||
for (LatLng latLng : list) {
|
||||
long jRound = Math.round(latLng.latitude * 100000.0d);
|
||||
long jRound2 = Math.round(latLng.longitude * 100000.0d);
|
||||
encode(jRound - j, stringBuffer);
|
||||
encode(jRound2 - j2, stringBuffer);
|
||||
j = jRound;
|
||||
j2 = jRound2;
|
||||
}
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
|
||||
private static void encode(long j, StringBuffer stringBuffer) {
|
||||
long j2 = j << 1;
|
||||
if (j < 0) {
|
||||
j2 = ~j2;
|
||||
}
|
||||
while (j2 >= 32) {
|
||||
stringBuffer.append(Character.toChars((int) ((32 | (31 & j2)) + 63)));
|
||||
j2 >>= 5;
|
||||
}
|
||||
stringBuffer.append(Character.toChars((int) (j2 + 63)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user