Add path overlays functionality.

This commit is contained in:
Holt59 2018-02-25 19:17:26 +01:00
parent 71202409b8
commit 96ca2b3a8a
5 changed files with 179 additions and 67 deletions

View File

@ -218,8 +218,10 @@ public class MainWindow extends JFrame {
threadTimer.stop(); threadTimer.stop();
threadPanel.setVisible(false); threadPanel.setVisible(false);
currentThread.setThread(null); currentThread.setThread(null);
if (spPanel != null) {
spPanel.setEnabled(true); spPanel.setEnabled(true);
} }
}
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) { private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing)); spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));

View File

@ -27,6 +27,7 @@ import org.insa.graph.Point;
import org.insa.graphics.drawing.overlays.MarkerOverlay; import org.insa.graphics.drawing.overlays.MarkerOverlay;
import org.insa.graphics.drawing.overlays.MarkerUtils; import org.insa.graphics.drawing.overlays.MarkerUtils;
import org.insa.graphics.drawing.overlays.Overlay; import org.insa.graphics.drawing.overlays.Overlay;
import org.insa.graphics.drawing.overlays.PathOverlay;
/** /**
* Cette implementation de la classe Dessin produit vraiment un affichage (au * Cette implementation de la classe Dessin produit vraiment un affichage (au
@ -64,11 +65,17 @@ public class BasicDrawing extends JPanel implements Drawing {
/** /**
* Draw the given overlay. * Draw the given overlay.
*/ */
public abstract void draw(Graphics2D g); public void draw(Graphics2D g) {
if (this.visible) {
drawImpl(g);
}
}
public abstract void drawImpl(Graphics2D g);
}; };
public class BasicMarker extends BasicOverlay implements MarkerOverlay { public class BasicMarkerOverlay extends BasicOverlay implements MarkerOverlay {
// Point of the marker. // Point of the marker.
private Point point; private Point point;
@ -76,7 +83,7 @@ public class BasicDrawing extends JPanel implements Drawing {
// Color of the marker. // Color of the marker.
private Color color; private Color color;
public BasicMarker(Point point, Color color) { public BasicMarkerOverlay(Point point, Color color) {
super(); super();
this.point = point; this.point = point;
this.color = color; this.color = color;
@ -94,7 +101,7 @@ public class BasicDrawing extends JPanel implements Drawing {
} }
@Override @Override
public void draw(Graphics2D graphics) { public void drawImpl(Graphics2D graphics) {
int px = BasicDrawing.this.projx(getPoint().getLongitude()); int px = BasicDrawing.this.projx(getPoint().getLongitude());
int py = BasicDrawing.this.projy(getPoint().getLatitude()); int py = BasicDrawing.this.projy(getPoint().getLatitude());
@ -109,6 +116,64 @@ public class BasicDrawing extends JPanel implements Drawing {
}; };
public class BasicPathOverlay extends BasicOverlay implements PathOverlay {
// List of points
List<Point> points;
// Color for the path
Color color;
// Origin / Destination markers.
BasicMarkerOverlay origin, destination;
public BasicPathOverlay(List<Point> points, Color color) {
this(points, color, null, null);
}
public BasicPathOverlay(List<Point> points, Color color, BasicMarkerOverlay origin,
BasicMarkerOverlay destination) {
this.points = points;
this.origin = origin;
this.destination = destination;
}
@Override
public void drawImpl(Graphics2D graphics) {
if (!points.isEmpty()) {
graphics.setStroke(new BasicStroke(2));
graphics.setColor(color);
Iterator<Point> itPoint = points.iterator();
Point prev = itPoint.next();
while (itPoint.hasNext()) {
Point curr = itPoint.next();
int x1 = BasicDrawing.this.projx(prev.getLongitude());
int x2 = BasicDrawing.this.projx(curr.getLongitude());
int y1 = BasicDrawing.this.projy(prev.getLatitude());
int y2 = BasicDrawing.this.projy(curr.getLatitude());
graphics.drawLine(x1, y1, x2, y2);
prev = curr;
}
}
if (this.origin != null) {
this.origin.draw(graphics);
}
if (this.destination != null) {
this.destination.draw(graphics);
}
}
};
// Default path color. // Default path color.
public static final Color DEFAULT_PATH_COLOR = new Color(255, 0, 255); public static final Color DEFAULT_PATH_COLOR = new Color(255, 0, 255);
@ -285,14 +350,8 @@ public class BasicDrawing extends JPanel implements Drawing {
this.overlays.clear(); this.overlays.clear();
} }
public void drawLine(Point from, Point to) { public BasicMarkerOverlay createMarker(Point point, Color color) {
int x1 = this.projx(from.getLongitude()); return new BasicMarkerOverlay(point, color);
int x2 = this.projx(to.getLongitude());
int y1 = this.projy(from.getLatitude());
int y2 = this.projy(to.getLatitude());
overlayGraphics.drawLine(x1, y1, x2, y2);
this.repaint();
} }
@Override @Override
@ -302,7 +361,7 @@ public class BasicDrawing extends JPanel implements Drawing {
@Override @Override
public MarkerOverlay drawMarker(Point point, Color color) { public MarkerOverlay drawMarker(Point point, Color color) {
BasicMarker marker = new BasicMarker(point, color); BasicMarkerOverlay marker = createMarker(point, color);
this.overlays.add(marker); this.overlays.add(marker);
this.repaint(); this.repaint();
return marker; return marker;
@ -325,21 +384,28 @@ public class BasicDrawing extends JPanel implements Drawing {
* @param palette Palette to use to retrieve color and width for arc, or null to * @param palette Palette to use to retrieve color and width for arc, or null to
* use current settings. * use current settings.
*/ */
public void drawArc(Arc arc, GraphPalette palette) { protected void drawArc(Arc arc, GraphPalette palette) {
List<Point> pts = arc.getPoints(); List<Point> pts = arc.getPoints();
if (!pts.isEmpty()) { if (!pts.isEmpty()) {
if (palette != null) { if (palette != null) {
setColor(palette.getColorForType(arc.getInfo().getType())); this.graphGraphics.setColor(palette.getColorForType(arc.getInfo().getType()));
setWidth(palette.getWidthForType(arc.getInfo().getType())); this.graphGraphics.setStroke(new BasicStroke(palette.getWidthForType(arc.getInfo().getType())));
} }
Iterator<Point> it1 = pts.iterator(); Iterator<Point> it1 = pts.iterator();
Point prev = it1.next(); Point prev = it1.next();
while (it1.hasNext()) { while (it1.hasNext()) {
Point curr = it1.next(); Point curr = it1.next();
drawLine(prev, curr);
int x1 = this.projx(prev.getLongitude());
int x2 = this.projx(curr.getLongitude());
int y1 = this.projy(prev.getLatitude());
int y2 = this.projy(curr.getLatitude());
graphGraphics.drawLine(x1, y1, x2, y2);
prev = curr; prev = curr;
} }
} }
this.repaint();
} }
/** /**
@ -347,7 +413,7 @@ public class BasicDrawing extends JPanel implements Drawing {
* *
* @param graph * @param graph
*/ */
public void initialize(Graph graph) { protected void initialize(Graph graph) {
double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, maxLon = Double.NEGATIVE_INFINITY, double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, maxLon = Double.NEGATIVE_INFINITY,
maxLat = Double.NEGATIVE_INFINITY; maxLat = Double.NEGATIVE_INFINITY;
for (Node node: graph.getNodes()) { for (Node node: graph.getNodes()) {
@ -374,15 +440,12 @@ public class BasicDrawing extends JPanel implements Drawing {
@Override @Override
public void drawGraph(Graph graph, GraphPalette palette) { public void drawGraph(Graph graph, GraphPalette palette) {
clear(); clear();
Graphics2D oldOverlayGraphics = this.overlayGraphics;
this.overlayGraphics = this.graphGraphics;
initialize(graph); initialize(graph);
for (Node node: graph.getNodes()) { for (Node node: graph.getNodes()) {
for (Arc arc: node.getSuccessors()) { for (Arc arc: node.getSuccessors()) {
drawArc(arc, palette); drawArc(arc, palette);
} }
} }
this.overlayGraphics = oldOverlayGraphics;
} }
@Override @Override
@ -391,31 +454,43 @@ public class BasicDrawing extends JPanel implements Drawing {
} }
@Override @Override
public void drawPath(Path path, Color color, boolean markers) { public PathOverlay drawPath(Path path, Color color, boolean markers) {
setColor(color); List<Point> points = new ArrayList<Point>();
setWidth(2); if (!path.isEmpty()) {
points.add(path.getOrigin().getPoint());
for (Arc arc: path.getArcs()) { for (Arc arc: path.getArcs()) {
drawArc(arc, null); Iterator<Point> itPoint = arc.getPoints().iterator();
// Discard origin each time
itPoint.next();
while (itPoint.hasNext()) {
points.add(itPoint.next());
} }
if (markers) {
drawMarker(path.getOrigin().getPoint(), color);
drawMarker(path.getDestination().getPoint(), color);
} }
} }
BasicMarkerOverlay origin = null, destination = null;
if (markers && !path.isEmpty()) {
origin = createMarker(path.getOrigin().getPoint(), color);
destination = createMarker(path.getDestination().getPoint(), color);
}
BasicPathOverlay overlay = new BasicPathOverlay(points, color, origin, destination);
this.overlays.add(overlay);
this.repaint();
return overlay;
}
@Override @Override
public void drawPath(Path path, Color color) { public PathOverlay drawPath(Path path, Color color) {
drawPath(path, color, true); return drawPath(path, color, true);
} }
@Override @Override
public void drawPath(Path path) { public PathOverlay drawPath(Path path) {
drawPath(path, DEFAULT_PATH_COLOR); return drawPath(path, DEFAULT_PATH_COLOR);
} }
@Override @Override
public void drawPath(Path path, boolean markers) { public PathOverlay drawPath(Path path, boolean markers) {
drawPath(path, DEFAULT_PATH_COLOR, markers); return drawPath(path, DEFAULT_PATH_COLOR, markers);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -6,6 +6,7 @@ import org.insa.graph.Graph;
import org.insa.graph.Path; import org.insa.graph.Path;
import org.insa.graph.Point; import org.insa.graph.Point;
import org.insa.graphics.drawing.overlays.MarkerOverlay; import org.insa.graphics.drawing.overlays.MarkerOverlay;
import org.insa.graphics.drawing.overlays.PathOverlay;
public interface Drawing { public interface Drawing {
@ -73,8 +74,9 @@ public interface Drawing {
* @param path * @param path
* @param color * @param color
* @param markers Show origin and destination markers. * @param markers Show origin and destination markers.
* @return
*/ */
public void drawPath(Path path, Color color, boolean markers); public PathOverlay drawPath(Path path, Color color, boolean markers);
/** /**
* Draw a path using the given color with markers. * Draw a path using the given color with markers.
@ -82,7 +84,7 @@ public interface Drawing {
* @param path * @param path
* @param color * @param color
*/ */
public void drawPath(Path path, Color color); public PathOverlay drawPath(Path path, Color color);
/** /**
* Draw a path using a default color specific to the implementation * Draw a path using a default color specific to the implementation
@ -91,7 +93,7 @@ public interface Drawing {
* @param path * @param path
* @param markers Show origin and destination markers. * @param markers Show origin and destination markers.
*/ */
public void drawPath(Path path, boolean markers); public PathOverlay drawPath(Path path, boolean markers);
/** /**
* Draw a path using a default color specific to the implementation * Draw a path using a default color specific to the implementation
@ -99,6 +101,6 @@ public interface Drawing {
* *
* @param path * @param path
*/ */
public void drawPath(Path path); public PathOverlay drawPath(Path path);
} }

View File

@ -17,6 +17,7 @@ import org.insa.graph.Point;
import org.insa.graphics.drawing.overlays.MarkerOverlay; import org.insa.graphics.drawing.overlays.MarkerOverlay;
import org.insa.graphics.drawing.overlays.MarkerUtils; import org.insa.graphics.drawing.overlays.MarkerUtils;
import org.insa.graphics.drawing.overlays.Overlay; import org.insa.graphics.drawing.overlays.Overlay;
import org.insa.graphics.drawing.overlays.PathOverlay;
import org.insa.graphics.drawing.overlays.PolylineAutoScaling; import org.insa.graphics.drawing.overlays.PolylineAutoScaling;
import org.mapsforge.core.graphics.Bitmap; import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.core.graphics.GraphicFactory; import org.mapsforge.core.graphics.GraphicFactory;
@ -48,51 +49,71 @@ public class MapViewDrawing extends MapView implements Drawing {
*/ */
private static final long serialVersionUID = 8606967833704938092L; private static final long serialVersionUID = 8606967833704938092L;
public class MapViewOverlayTracker implements Overlay { public class MapViewOverlay implements Overlay {
// Marker associated. // Marker associated.
protected Layer layer; protected Layer[] layers;
public MapViewOverlayTracker(Layer marker) { public MapViewOverlay(Layer[] layers) {
this.layer = marker; this.layers = layers;
for (Layer layer: this.layers) {
MapViewDrawing.this.getLayerManager().getLayers().add(layer);
}
} }
@Override @Override
public void setVisible(boolean visible) { public void setVisible(boolean visible) {
this.layer.setVisible(visible); for (Layer layer: layers) {
layer.setVisible(visible);
}
} }
@Override @Override
public void delete() { public void delete() {
MapViewDrawing.this.getLayerManager().getLayers().remove(layer); Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers();
for (Layer layer: layers) {
mlayers.remove(layer);
}
} }
}; };
public class MapViewMarkerTracker extends MapViewOverlayTracker implements MarkerOverlay { public class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay {
public MapViewMarkerTracker(Marker marker) { public MapViewMarkerOverlay(Marker marker) {
super(marker); super(new Layer[] { marker });
} }
@Override @Override
public Point getPoint() { public Point getPoint() {
Marker marker = (Marker) super.layer; Marker marker = (Marker) super.layers[0];
return new Point(marker.getLatLong().getLongitude(), marker.getLatLong().getLatitude()); return new Point(marker.getLatLong().getLongitude(), marker.getLatLong().getLatitude());
} }
@Override @Override
public void moveTo(Point point) { public void moveTo(Point point) {
Marker marker = (Marker) this.layer; Marker marker = (Marker) this.layers[0];
this.delete(); this.delete();
marker = new Marker(convertPoint(point), marker.getBitmap(), marker.getHorizontalOffset(), marker = new Marker(convertPoint(point), marker.getBitmap(), marker.getHorizontalOffset(),
marker.getVerticalOffset()); marker.getVerticalOffset());
this.layer = marker; this.layers[0] = marker;
MapViewDrawing.this.getLayerManager().getLayers().add(this.layer); MapViewDrawing.this.getLayerManager().getLayers().add(marker);
} }
}; };
public class MapViewPathOverlay extends MapViewOverlay implements PathOverlay {
public MapViewPathOverlay(PolylineAutoScaling path, Marker origin, Marker destination) {
super(new Layer[] { path, origin, destination });
}
public MapViewPathOverlay(PolylineAutoScaling path) {
super(new Layer[] { path });
}
}
// Default path color. // Default path color.
public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244); public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244);
@ -189,6 +210,11 @@ public class MapViewDrawing extends MapView implements Drawing {
repaint(); repaint();
} }
protected Marker createMarker(Point point, Color color) {
Bitmap bitmap = new AwtBitmap(MarkerUtils.getMarkerForColor(color));
return new Marker(convertPoint(point), bitmap, 0, -bitmap.getHeight() / 2);
}
@Override @Override
public MarkerOverlay drawMarker(Point point) { public MarkerOverlay drawMarker(Point point) {
return drawMarker(point, Color.GREEN); return drawMarker(point, Color.GREEN);
@ -196,10 +222,7 @@ public class MapViewDrawing extends MapView implements Drawing {
@Override @Override
public MarkerOverlay drawMarker(Point point, Color color) { public MarkerOverlay drawMarker(Point point, Color color) {
Bitmap bitmap = new AwtBitmap(MarkerUtils.getMarkerForColor(color)); return new MapViewMarkerOverlay(createMarker(point, color));
Marker marker = new Marker(convertPoint(point), bitmap, 0, -bitmap.getHeight() / 2);
getLayerManager().getLayers().add(marker);
return new MapViewMarkerTracker(marker);
} }
@Override @Override
@ -239,31 +262,36 @@ public class MapViewDrawing extends MapView implements Drawing {
} }
@Override @Override
public void drawPath(Path path, Color color, boolean markers) { public PathOverlay drawPath(Path path, Color color, boolean markers) {
PolylineAutoScaling line = new PolylineAutoScaling(1, DEFAULT_PATH_COLOR); PolylineAutoScaling line = new PolylineAutoScaling(1, DEFAULT_PATH_COLOR);
for (Arc arc: path.getArcs()) { for (Arc arc: path.getArcs()) {
line.add(arc.getPoints()); line.add(arc.getPoints());
} }
getLayerManager().getLayers().add(line); PathOverlay overlay = null;
if (markers) { if (markers) {
drawMarker(path.getOrigin().getPoint(), DEFAULT_PATH_COLOR); Marker origin = createMarker(path.getOrigin().getPoint(), DEFAULT_PATH_COLOR),
drawMarker(path.getDestination().getPoint(), DEFAULT_PATH_COLOR); destination = createMarker(path.getDestination().getPoint(), DEFAULT_PATH_COLOR);
overlay = new MapViewPathOverlay(line, origin, destination);
} }
else {
overlay = new MapViewPathOverlay(line);
}
return overlay;
} }
@Override @Override
public void drawPath(Path path, Color color) { public PathOverlay drawPath(Path path, Color color) {
drawPath(path, color, true); return drawPath(path, color, true);
} }
@Override @Override
public void drawPath(Path path) { public PathOverlay drawPath(Path path) {
drawPath(path, DEFAULT_PATH_COLOR, true); return drawPath(path, DEFAULT_PATH_COLOR, true);
} }
@Override @Override
public void drawPath(Path path, boolean markers) { public PathOverlay drawPath(Path path, boolean markers) {
drawPath(path, DEFAULT_PATH_COLOR, markers); return drawPath(path, DEFAULT_PATH_COLOR, markers);
} }
} }

View File

@ -0,0 +1,5 @@
package org.insa.graphics.drawing.overlays;
public interface PathOverlay extends Overlay {
}