package org.osm2world.viewer.view.debug; import static java.lang.Math.min; import static org.osm2world.core.math.VectorXZ.*; import java.awt.Color; import java.util.Arrays; import org.osm2world.core.ConversionFacade.Results; import org.osm2world.core.map_data.creation.index.MapQuadtree; import org.osm2world.core.map_data.creation.index.MapQuadtree.QuadLeaf; import org.osm2world.core.map_data.data.MapArea; import org.osm2world.core.map_data.data.MapElement; import org.osm2world.core.map_data.data.MapNode; import org.osm2world.core.map_data.data.MapWaySegment; import org.osm2world.core.math.VectorXZ; import org.osm2world.core.target.jogl.JOGLTarget; public class QuadtreeDebugView extends DebugView { private static final Color LEAF_BORDER_COLOR = Color.WHITE; private static final Color NODE_ARROW_COLOR = Color.YELLOW; private static final Color LINE_ARROW_COLOR = Color.LIGHT_GRAY; private static final Color AREA_ARROW_COLOR = new Color(0.8f, 0.8f, 1); private MapQuadtree mapQuadtree; private boolean arrowsEnabled = true; @Override public void setConversionResults(Results conversionResults) { super.setConversionResults(conversionResults); this.mapQuadtree = null; } public void setArrowsEnabled(boolean arrowsEnabled) { this.arrowsEnabled = arrowsEnabled; } @Override public boolean canBeUsed() { return map != null; } @Override public void fillTarget(JOGLTarget target) { if (mapQuadtree == null) { mapQuadtree = new MapQuadtree(map.getDataBoundary()); for (MapElement e : map.getMapElements()) { mapQuadtree.insert(e); } } for (QuadLeaf leaf : mapQuadtree.getLeaves()) { /* draw leaf boundary */ VectorXZ[] vs = new VectorXZ[5]; vs[0] = new VectorXZ(leaf.minX, leaf.minZ); vs[1] = new VectorXZ(leaf.maxX, leaf.minZ); vs[2] = new VectorXZ(leaf.maxX, leaf.maxZ); vs[3] = new VectorXZ(leaf.minX, leaf.maxZ); vs[4] = vs[0]; target.drawLineStrip(LEAF_BORDER_COLOR, 1, listXYZ(Arrays.asList(vs),0)); if (arrowsEnabled) { /* draw arrows from leaf center to elements */ VectorXZ leafCenter = new VectorXZ( (leaf.minX + leaf.maxX)/2, (leaf.minZ + leaf.maxZ)/2); for (MapElement e : leaf) { if (e instanceof MapNode) { VectorXZ nodePos = ((MapNode)e).getPos(); drawArrow(target, NODE_ARROW_COLOR, (float) min(1, distance(leafCenter, nodePos) * 0.3), leafCenter.xyz(0), nodePos.xyz(0)); } else if (e instanceof MapWaySegment) { VectorXZ lineStart = ((MapWaySegment)e).getStartNode().getPos(); VectorXZ lineEnd = ((MapWaySegment)e).getEndNode().getPos(); VectorXZ lineCenter = lineStart.add(lineEnd).mult(0.5f); float headLength = (float) min(1, distance(leafCenter, lineCenter) * 0.3); drawArrow(target, LINE_ARROW_COLOR, headLength, leafCenter.xyz(0), lineCenter.xyz(0)); } else if (e instanceof MapArea) { VectorXZ areaCenter = ((MapArea)e).getOuterPolygon().getCenter(); float headLength = (float) min(1, distance(leafCenter, areaCenter) * 0.3); drawArrow(target, AREA_ARROW_COLOR, headLength, leafCenter.xyz(0), areaCenter.xyz(0)); } } } } } }