Add method to compare with precision

This commit is contained in:
Victor Shcherb 2017-09-03 17:21:28 +02:00
parent 36b8d544ee
commit bd23991297
2 changed files with 82 additions and 10 deletions

View file

@ -74,16 +74,17 @@ public class BinaryInspector {
in.inspector(new String[] {
// "-vpoi",
// "-vmap", "-vmapobjects",
"-vmapcoordinates",
"-vrouting",
"-vmap", "-vmapobjects",
// "-vmapcoordinates",
// "-vrouting",
// "-vtransport",
// "-vaddress", "-vcities","-vstreetgroups",
// "-vstreets", "-vbuildings", "-vintersections",
// "-lang=ru",
// "-bbox=30.4981,50.4424,30.5195,50.4351",
// "-osm="+System.getProperty("maps.dir")+"/map_full.obf.osm",
System.getProperty("maps.dir")+"/diff/17_08_29_22_00.diff.obf"
"-osm="+System.getProperty("maps.dir")+"/map_full_2.obf.osm",
System.getProperty("maps.dir")+"/diff/Diff.obf"
// System.getProperty("maps.dir")+"/diff/Ukraine_kiev-city_europe.obf"
// System.getProperty("maps.dir")+"../temp/kiev/Ukraine_kiev-city_europe_17_06_05.obf",
// System.getProperty("maps.dir")+"Ukraine_kiev-city_europe_2.obf",
});
@ -896,10 +897,11 @@ public class BinaryInspector {
} catch (IOException e) {
throw new RuntimeException(e);
}
// } else if(obj.getId() >> 1 == 205743436l) {
} else {
printMapDetails(obj, b, vInfo.vmapCoordinates);
} else if(obj.getId() == 50209165195l) {
println(b.toString());
} else {
// printMapDetails(obj, b, vInfo.vmapCoordinates);
// println(b.toString());
}
}
return false;

View file

@ -13,6 +13,7 @@ import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms;
public class BinaryMapDataObject {
private static final int COORDINATES_PRECISION_COMPARE = 0;
protected int[] coordinates = null;
protected int[][] polygonInnerCoordinates = null;
protected boolean area = false;
@ -200,7 +201,7 @@ public class BinaryMapDataObject {
if(this.objectType == thatObj.objectType
&& this.id == thatObj.id
&& this.area == thatObj.area
&& Arrays.equals(this.coordinates, thatObj.coordinates) ) {
&& compareCoordinates(this.coordinates, thatObj.coordinates, COORDINATES_PRECISION_COMPARE) ) {
if(mapIndex == null) {
throw new IllegalStateException("Illegal binary object: " + id);
}
@ -221,7 +222,7 @@ public class BinaryMapDataObject {
} else if(polygonInnerCoordinates[i].length != thatObj.polygonInnerCoordinates[i].length){
equals = false;
} else {
equals = Arrays.equals(polygonInnerCoordinates[i], thatObj.polygonInnerCoordinates[i]);
equals = compareCoordinates(polygonInnerCoordinates[i], thatObj.polygonInnerCoordinates[i], COORDINATES_PRECISION_COMPARE);
}
}
}
@ -289,6 +290,75 @@ public class BinaryMapDataObject {
}
private static boolean compareCoordinates(int[] coordinates, int[] coordinates2, int precision) {
if(precision == 0) {
return Arrays.equals(coordinates, coordinates2);
}
TIntArrayList cd = simplify(coordinates, precision);
TIntArrayList cd2 = simplify(coordinates2, precision);
return cd.equals(cd2);
}
private static TIntArrayList simplify(int[] c, int precision) {
int len = c.length / 2;
TIntArrayList lt = new TIntArrayList(len * 3);
for (int i = 0; i < len; i++) {
lt.add(0);
lt.add(c[i * 2]);
lt.add(c[i * 2 + 1]);
}
lt.set(0, 1);
lt.set((len - 1) * 3, 1);
simplifyLine(lt, precision, 0, len - 1);
TIntArrayList res = new TIntArrayList(len * 2);
for (int i = 0; i < len; i++) {
if (lt.get(i * 3) == 1) {
res.add(lt.get(i * 3 + 1));
res.add(lt.get(i * 3 + 2));
}
}
return res;
}
private static double orthogonalDistance(int x, int y, int x1, int y1, int x2, int y2) {
long A = (x - x1);
long B = (y - y1);
long C = (x2 - x1);
long D = (y2 - y1);
return Math.abs(A * D - C * B) / Math.sqrt(C * C + D * D);
}
private static void simplifyLine(TIntArrayList lt, int precision, int start, int end) {
if(start == end - 1) {
return;
}
int x = lt.get(start*3 + 1);
int y = lt.get(start*3 + 2);
int ex = lt.get(end*3 + 1);
int ey = lt.get(end*3 + 2);
double max = 0;
int maxK = -1;
for(int k = start + 1; k < end ; k++) {
double ld = orthogonalDistance(lt.get(k*3 + 1), lt.get(k*3 + 2), x, y, ex, ey);
if(maxK == -1 || max < ld) {
maxK = k;
max = ld;
}
}
if(max < precision) {
return;
}
lt.set(maxK*3, 1); // keep point
simplifyLine(lt, precision, start, maxK);
simplifyLine(lt, precision, maxK, end);
}
public int[] getCoordinates() {
return coordinates;
}