Skip to content

Commit

Permalink
Introduce TriangleTreeReader.DecodedVisitor (#89401)
Browse files Browse the repository at this point in the history
This commit introduces a DecodedVisitor that removes duplicate code for visitors that need to decode coordinates.
  • Loading branch information
iverase committed Aug 17, 2022
1 parent 27061a5 commit e2bf861
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
* A {@link TriangleTreeReader.Visitor} implementation for {@link Component2D} geometries.
* It can solve spatial relationships against a serialize triangle tree.
*/
public abstract class Component2DVisitor implements TriangleTreeReader.Visitor {
public abstract class Component2DVisitor extends TriangleTreeReader.DecodedVisitor {

protected final Component2D component2D;
private final CoordinateEncoder encoder;

private Component2DVisitor(Component2D component2D, CoordinateEncoder encoder) {
super(encoder);
this.component2D = component2D;
this.encoder = encoder;
}

/** If the relationship has been honour. */
Expand All @@ -32,67 +31,32 @@ private Component2DVisitor(Component2D component2D, CoordinateEncoder encoder) {
public abstract void reset();

@Override
public void visitPoint(int x, int y) {
doVisitPoint(encoder.decodeX(x), encoder.decodeY(y));
}

abstract void doVisitPoint(double x, double y);

@Override
public void visitLine(int aX, int aY, int bX, int bY, byte metadata) {
doVisitLine(encoder.decodeX(aX), encoder.decodeY(aY), encoder.decodeX(bX), encoder.decodeY(bY), metadata);
}

abstract void doVisitLine(double aX, double aY, double bX, double bY, byte metadata);

@Override
public void visitTriangle(int aX, int aY, int bX, int bY, int cX, int cY, byte metadata) {
doVisitTriangle(
encoder.decodeX(aX),
encoder.decodeY(aY),
encoder.decodeX(bX),
encoder.decodeY(bY),
encoder.decodeX(cX),
encoder.decodeY(cY),
metadata
);
}

abstract void doVisitTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata);

@Override
public boolean pushX(int minX) {
return component2D.getMaxX() >= encoder.decodeX(minX);
public boolean pushDecodedX(double minX) {
return component2D.getMaxX() >= minX;
}

@Override
public boolean pushY(int minY) {
return component2D.getMaxY() >= encoder.decodeY(minY);
public boolean pushDecodedY(double minY) {
return component2D.getMaxY() >= minY;
}

@Override
public boolean push(int maxX, int maxY) {
return component2D.getMinX() <= encoder.decodeX(maxX) && component2D.getMinY() <= encoder.decodeY(maxY);
public boolean pushDecoded(double maxX, double maxY) {
return component2D.getMinX() <= maxX && component2D.getMinY() <= maxY;

}

@Override
public boolean push(int minX, int minY, int maxX, int maxY) {
final PointValues.Relation relation = component2D.relate(
encoder.decodeX(minX),
encoder.decodeX(maxX),
encoder.decodeY(minY),
encoder.decodeY(maxY)
);
return doPush(relation);
public boolean pushDecoded(double minX, double minY, double maxX, double maxY) {
return pushDecoded(component2D.relate(minX, maxX, minY, maxY));
}

/** Relation between the query shape and the doc value bounding box. Depending on the query relationship,
* decide if we should traverse the tree.
*
* @return if true, the visitor keeps traversing the tree, else it stops.
* */
abstract boolean doPush(PointValues.Relation relation);
abstract boolean pushDecoded(PointValues.Relation relation);

/**
* Creates a visitor from the provided Component2D and spatial relationship. Visitors are re-usable by
Expand Down Expand Up @@ -131,17 +95,17 @@ public void reset() {
}

@Override
void doVisitPoint(double x, double y) {
void visitDecodedPoint(double x, double y) {
intersects = component2D.contains(x, y);
}

@Override
void doVisitLine(double aX, double aY, double bX, double bY, byte metadata) {
void visitDecodedLine(double aX, double aY, double bX, double bY, byte metadata) {
intersects = component2D.intersectsLine(aX, aY, bX, bY);
}

@Override
void doVisitTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
void visitDecodedTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
intersects = component2D.intersectsTriangle(aX, aY, bX, bY, cX, cY);
}

Expand All @@ -152,7 +116,7 @@ public boolean push() {
}

@Override
boolean doPush(PointValues.Relation relation) {
boolean pushDecoded(PointValues.Relation relation) {
if (relation == PointValues.Relation.CELL_OUTSIDE_QUERY) {
// shapes are disjoint, stop traversing the tree.
return false;
Expand Down Expand Up @@ -192,17 +156,17 @@ public void reset() {
}

@Override
void doVisitPoint(double x, double y) {
void visitDecodedPoint(double x, double y) {
disjoint = component2D.contains(x, y) == false;
}

@Override
void doVisitLine(double aX, double aY, double bX, double bY, byte metadata) {
void visitDecodedLine(double aX, double aY, double bX, double bY, byte metadata) {
disjoint = component2D.intersectsLine(aX, aY, bX, bY) == false;
}

@Override
void doVisitTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
void visitDecodedTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
disjoint = component2D.intersectsTriangle(aX, aY, bX, bY, cX, cY) == false;
}

Expand All @@ -213,7 +177,7 @@ public boolean push() {
}

@Override
boolean doPush(PointValues.Relation relation) {
boolean pushDecoded(PointValues.Relation relation) {
if (relation == PointValues.Relation.CELL_OUTSIDE_QUERY) {
// shapes are disjoint, stop traversing the tree.
return false;
Expand Down Expand Up @@ -253,17 +217,17 @@ public void reset() {
}

@Override
void doVisitPoint(double x, double y) {
void visitDecodedPoint(double x, double y) {
within = component2D.contains(x, y);
}

@Override
void doVisitLine(double aX, double aY, double bX, double bY, byte metadata) {
void visitDecodedLine(double aX, double aY, double bX, double bY, byte metadata) {
within = component2D.containsLine(aX, aY, bX, bY);
}

@Override
void doVisitTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
void visitDecodedTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
within = component2D.containsTriangle(aX, aY, bX, bY, cX, cY);
}

Expand Down Expand Up @@ -298,7 +262,7 @@ public boolean push(int maxX, int maxY) {
}

@Override
boolean doPush(PointValues.Relation relation) {
boolean pushDecoded(PointValues.Relation relation) {
if (relation == PointValues.Relation.CELL_OUTSIDE_QUERY) {
// shapes are disjoint, stop traversing the tree.
within = false;
Expand Down Expand Up @@ -333,7 +297,7 @@ public void reset() {
}

@Override
void doVisitPoint(double x, double y) {
void visitDecodedPoint(double x, double y) {
final Component2D.WithinRelation rel = component2D.withinPoint(x, y);
if (rel != Component2D.WithinRelation.DISJOINT) {
// Only override relationship if different to DISJOINT
Expand All @@ -342,7 +306,7 @@ void doVisitPoint(double x, double y) {
}

@Override
void doVisitLine(double aX, double aY, double bX, double bY, byte metadata) {
void visitDecodedLine(double aX, double aY, double bX, double bY, byte metadata) {
final boolean ab = (metadata & 1 << 4) == 1 << 4;
final Component2D.WithinRelation rel = component2D.withinLine(aX, aY, ab, bX, bY);
if (rel != Component2D.WithinRelation.DISJOINT) {
Expand All @@ -352,7 +316,7 @@ void doVisitLine(double aX, double aY, double bX, double bY, byte metadata) {
}

@Override
void doVisitTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
void visitDecodedTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
final boolean ab = (metadata & 1 << 4) == 1 << 4;
final boolean bc = (metadata & 1 << 5) == 1 << 5;
final boolean ca = (metadata & 1 << 6) == 1 << 6;
Expand All @@ -370,7 +334,7 @@ public boolean push() {
}

@Override
boolean doPush(PointValues.Relation relation) {
boolean pushDecoded(PointValues.Relation relation) {
// Only traverse the tree if the shapes intersects.
return relation == PointValues.Relation.CELL_CROSSES_QUERY;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,78 +15,64 @@
*
* TODO: We could instead choose the point closer to the centroid which improves unbalanced trees
*/
public class LabelPositionVisitor<T> implements TriangleTreeReader.Visitor {
public class LabelPositionVisitor<T> extends TriangleTreeReader.DecodedVisitor {

private T labelPosition;
private final CoordinateEncoder encoder;
private final BiFunction<Double, Double, T> pointMaker;

public LabelPositionVisitor(CoordinateEncoder encoder, BiFunction<Double, Double, T> pointMaker) {
this.encoder = encoder;
super(encoder);
this.pointMaker = pointMaker;
}

@Override
public void visitPoint(int xi, int yi) {
double x = encoder.decodeX(xi);
double y = encoder.decodeY(yi);
// System.out.println("Got point: (" + x + "," + y + ")");
void visitDecodedPoint(double x, double y) {
assert labelPosition == null;
labelPosition = pointMaker.apply(x, y);
}

@Override
public void visitLine(int aXi, int aYi, int bXi, int bYi, byte metadata) {
double aX = encoder.decodeX(aXi);
double aY = encoder.decodeY(aYi);
double bX = encoder.decodeX(bXi);
double bY = encoder.decodeY(bYi);
// System.out.println("Got line: (" + aX + "," + aY + ")-(" + bX + "," + bY + ")");
public void visitDecodedLine(double aX, double aY, double bX, double bY, byte metadata) {
assert labelPosition == null;
labelPosition = pointMaker.apply((aX + bX) / 2.0, (aY + bY) / 2.0);
}

@Override
public void visitTriangle(int aXi, int aYi, int bXi, int bYi, int cXi, int cYi, byte metadata) {
double aX = encoder.decodeX(aXi);
double aY = encoder.decodeY(aYi);
double bX = encoder.decodeX(bXi);
double bY = encoder.decodeY(bYi);
double cX = encoder.decodeX(cXi);
double cY = encoder.decodeY(cYi);
// System.out.println("Got triangle: (" + aX + "," + aY + ")-(" + bX + "," + bY + ")-(" + cX + "," + cY + ")");
public void visitDecodedTriangle(double aX, double aY, double bX, double bY, double cX, double cY, byte metadata) {
assert labelPosition == null;
labelPosition = pointMaker.apply((aX + bX + cX) / 3.0, (aY + bY + cY) / 3.0);
}

@Override
public boolean push() {
// Don't traverse deeper once we found a result
boolean pushDecodedX(double minX) {
return labelPosition == null;
}

@Override
public boolean pushX(int minX) {
// Don't traverse deeper once we found a result
boolean pushDecodedY(double minX) {
return labelPosition == null;
}

@Override
public boolean pushY(int minY) {
public boolean push() {
// Don't traverse deeper once we found a result
return labelPosition == null;
}

@Override
public boolean push(int maxX, int maxY) {
// Don't traverse deeper once we found a result
boolean pushDecoded(double maxX, double maxY) {
return labelPosition == null;
}

@Override
public boolean push(int minX, int minY, int maxX, int maxY) {
// Always start the traversal
return true;
return labelPosition == null;
}

@Override
boolean pushDecoded(double minX, double minY, double maxX, double maxY) {
return labelPosition == null;
}

public T labelPosition() {
Expand Down

0 comments on commit e2bf861

Please sign in to comment.