Regoranized package.

This commit is contained in:
Holt59
2018-02-24 13:46:47 +01:00
parent 4a5ac5ad58
commit c624fd9dfd
11 changed files with 19 additions and 30 deletions

View File

@@ -0,0 +1,345 @@
package org.insa.graphics.drawing;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JPanel;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Node;
import org.insa.graph.Path;
import org.insa.graph.Point;
/**
* Cette implementation de la classe Dessin produit vraiment un affichage (au
* contraire de la classe DessinInvisible).
*/
public class BasicDrawing extends JPanel implements Drawing {
/**
*
*/
private static final long serialVersionUID = 96779785877771827L;
// Default path color.
public static final Color DEFAULT_PATH_COLOR = new Color(255, 0, 255);
// Default palette.
public static final GraphPalette DEFAULT_PALETTE = new BasicGraphPalette();
// Default marker width
private static final int DEFAULT_MARKER_WIDTH = 10;
//
private final Graphics2D gr;
private double long1, long2, lat1, lat2;
// Width and height of the image
private final int width, height;
//
private Image image;
private ZoomAndPanListener zoomAndPanListener;
// Mapping DrawingClickListener -> MouseEventListener
private Map<DrawingClickListener, MouseListener> listenerMapping = new IdentityHashMap<>();
/**
* Create a new BasicDrawing.
*
*/
public BasicDrawing() {
this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
this.addMouseListener(zoomAndPanListener);
this.addMouseMotionListener(zoomAndPanListener);
this.addMouseWheelListener(zoomAndPanListener);
this.width = 2000;
this.height = 1600;
BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
this.image = img;
this.gr = img.createGraphics();
this.zoomAndPanListener.setCoordTransform(this.gr.getTransform());
this.long1 = -180;
this.long2 = 180;
this.lat1 = -90;
this.lat2 = 90;
this.clear();
this.repaint();
}
@Override
public void paintComponent(Graphics g1) {
Graphics2D g = (Graphics2D) g1;
g.clearRect(0, 0, getWidth(), getHeight());
g.setTransform(zoomAndPanListener.getCoordTransform());
g.drawImage(image, 0, 0, this);
}
protected void setBB(double long1, double long2, double lat1, double lat2) {
if (long1 > long2 || lat1 > lat2) {
throw new Error("DessinVisible.setBB : mauvaises coordonnees.");
}
this.long1 = long1;
this.long2 = long2;
this.lat1 = lat1;
this.lat2 = lat2;
double scale = 1 / Math.max(this.width / (double) this.getWidth(), this.height / (double) this.getHeight());
this.zoomAndPanListener.getCoordTransform().setToIdentity();
this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2,
(this.getHeight() - this.height * scale) / 2);
this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
this.zoomAndPanListener.setZoomLevel(0);
this.repaint();
}
private int projx(double lon) {
return (int) (width * (lon - this.long1) / (this.long2 - this.long1));
}
private int projy(double lat) {
return (int) (height * (1 - (lat - this.lat1) / (this.lat2 - this.lat1)));
}
/**
* Return the longitude and latitude corresponding to the given position of the
* MouseEvent.
*
* @param event
*
* @return
*/
public Point getLongitudeLatitude(MouseEvent event) throws NoninvertibleTransformException {
// Get the point using the inverse transform of the Zoom/Pan object, this gives
// us
// a point within the drawing box (between [0, 0] and [width, height]).
Point2D ptDst = this.zoomAndPanListener.getCoordTransform().inverseTransform(event.getPoint(), null);
// Inverse the "projection" on x/y to get longitude and latitude.
double lon = ptDst.getX();
double lat = ptDst.getY();
lon = (lon / this.width) * (this.long2 - this.long1) + this.long1;
lat = (1 - lat / this.height) * (this.lat2 - this.lat1) + this.lat1;
// Return a new point.
return new Point(lon, lat);
}
@Override
public void addDrawingClickListener(DrawingClickListener listener) {
MouseListener mListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent evt) {
System.out.println(evt);
try {
listener.mouseClicked(getLongitudeLatitude(evt));
}
catch (NoninvertibleTransformException e) {
e.printStackTrace();
}
}
};
this.addMouseListener(mListener);
this.listenerMapping.put(listener, mListener);
}
@Override
public void removeDrawingClickListener(DrawingClickListener listener) {
this.removeMouseListener(this.listenerMapping.get(listener));
}
protected void setWidth(int width) {
this.gr.setStroke(new BasicStroke(width));
}
protected void setColor(Color col) {
this.gr.setColor(col);
}
@Override
public void clear() {
this.gr.setColor(Color.WHITE);
this.gr.fillRect(0, 0, this.width, this.height);
}
@Override
public void drawLine(Point from, Point to) {
int x1 = this.projx(from.getLongitude());
int x2 = this.projx(to.getLongitude());
int y1 = this.projy(from.getLatitude());
int y2 = this.projy(to.getLatitude());
gr.drawLine(x1, y1, x2, y2);
this.repaint();
}
@Override
public void drawLine(Point from, Point to, int width) {
setWidth(width);
drawLine(from, to);
}
@Override
public void drawLine(Point from, Point to, int width, Color color) {
setWidth(width);
setColor(color);
drawLine(from, to);
}
@Override
public void drawMarker(Point point) {
drawPoint(point, DEFAULT_MARKER_WIDTH, this.gr.getColor());
}
@Override
public void drawMarker(Point point, Color color) {
setColor(color);
drawMarker(point);
}
@Override
public void drawPoint(Point point, int width, Color color) {
setWidth(width);
setColor(color);
int x = this.projx(point.getLongitude()) - DEFAULT_MARKER_WIDTH / 2;
int y = this.projy(point.getLatitude()) - DEFAULT_MARKER_WIDTH / 2;
gr.fillOval(x, y, DEFAULT_MARKER_WIDTH, DEFAULT_MARKER_WIDTH);
this.repaint();
}
/**
* Draw the given arc.
*
* @param arc
* Arc to draw.
* @param palette
* Palette to use to retrieve color and width for arc, or null to use
* current settings.
*/
public void drawArc(Arc arc, GraphPalette palette) {
ArrayList<Point> pts = arc.getPoints();
if (!pts.isEmpty()) {
if (palette != null) {
setColor(palette.getColorForType(arc.getInfo().getType()));
setWidth(palette.getWidthForType(arc.getInfo().getType()));
}
Iterator<Point> it1 = pts.iterator();
Point prev = it1.next();
while (it1.hasNext()) {
Point curr = it1.next();
drawLine(prev, curr);
prev = curr;
}
}
}
/**
* Initialize the drawing for the given graph.
*
* @param graph
*/
public void initialize(Graph graph) {
double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, maxLon = Double.NEGATIVE_INFINITY,
maxLat = Double.NEGATIVE_INFINITY;
for (Node node: graph.getNodes()) {
Point pt = node.getPoint();
if (pt.getLatitude() < minLat) {
minLat = pt.getLatitude();
}
if (pt.getLatitude() > maxLat) {
maxLat = pt.getLatitude();
}
if (pt.getLongitude() < minLon) {
minLon = pt.getLongitude();
}
if (pt.getLongitude() > maxLon) {
maxLon = pt.getLongitude();
}
}
double deltaLon = 0.02 * (maxLon - minLon), deltaLat = 0.02 * (maxLat - minLat);
setBB(minLon - deltaLon, maxLon + deltaLon, minLat - deltaLat, maxLat + deltaLat);
}
@Override
public void drawGraph(Graph graph, GraphPalette palette) {
clear();
initialize(graph);
for (Node node: graph.getNodes()) {
for (Arc arc: node.getSuccessors()) {
drawArc(arc, palette);
}
}
}
@Override
public void drawGraph(Graph graph) {
drawGraph(graph, DEFAULT_PALETTE);
}
@Override
public void drawPath(Path path, Color color, boolean markers) {
setColor(color);
setWidth(2);
for (Arc arc: path.getArcs()) {
drawArc(arc, null);
}
if (markers) {
drawMarker(path.getOrigin().getPoint(), color);
drawMarker(path.getDestination().getPoint(), color);
}
}
@Override
public void drawPath(Path path, Color color) {
drawPath(path, color, true);
}
@Override
public void drawPath(Path path) {
drawPath(path, DEFAULT_PATH_COLOR);
}
@Override
public void drawPath(Path path, boolean markers) {
drawPath(path, DEFAULT_PATH_COLOR, markers);
}
@SuppressWarnings("unused")
private void putText(Point point, String txt) {
int x = this.projx(point.getLongitude());
int y = this.projy(point.getLatitude());
gr.drawString(txt, x, y);
this.repaint();
}
}

View File

@@ -0,0 +1,97 @@
package org.insa.graphics.drawing;
import java.awt.Color;
import org.insa.graph.RoadInformation.RoadType;
public class BasicGraphPalette implements GraphPalette {
// Color types for arc.
static final Color motorway = Color.RED;
static final Color bigroad = new Color(255, 105, 0);
static final Color smallroad = new Color(255, 234, 0);
static final Color coastline = Color.BLUE;
// Default point width
static final int DEFAULT_POINT_WIDTH = 1;
/**
*
*/
public BasicGraphPalette() { }
@Override
public int getDefaultPointWidth() {
return 2;
}
@Override
public Color getDefaultPointColor() {
return Color.GREEN;
}
@Override
public Color getColorForType(RoadType type) {
Color color = Color.BLACK;
switch (type) {
case MOTORWAY:
color = motorway;
break;
case TRUNK:
case PRIMARY:
case SECONDARY:
case MOTORWAY_LINK:
case TRUNK_LINK:
case PRIMARY_LINK:
color = bigroad;
break;
case SECONDARY_LINK:
case TERTIARY:
case RESIDENTIAL:
case UNCLASSIFIED:
case ROAD:
case LIVING_STREET:
case SERVICE:
case ROUNDABOUT:
color = smallroad;
break;
case COASTLINE:
color = coastline;
break;
}
return color;
}
@Override
public int getWidthForType(RoadType type) {
int width = 1;
switch (type) {
case MOTORWAY:
width = 2;
break;
case TRUNK:
case PRIMARY:
case SECONDARY:
case MOTORWAY_LINK:
case TRUNK_LINK:
case PRIMARY_LINK:
width = 1;
break;
case SECONDARY_LINK:
case TERTIARY:
case RESIDENTIAL:
case UNCLASSIFIED:
case ROAD:
case LIVING_STREET:
case SERVICE:
case ROUNDABOUT:
width = 1;
break;
case COASTLINE:
width = 4;
break;
}
return width;
}
}

View File

@@ -0,0 +1,25 @@
package org.insa.graphics.drawing;
import java.awt.Color;
import org.insa.graph.RoadInformation.RoadType;
public class BlackAndWhiteGraphPalette extends BasicGraphPalette {
// Road colors (index
private final static Color[] ROAD_COLOR_FROM_WIDTH = {
null, new Color(140, 140, 140), new Color(80, 80, 80), new Color(40, 40, 40), new Color(30, 30, 30)
};
@Override
public Color getDefaultPointColor() {
return Color.BLACK;
}
@Override
public Color getColorForType(RoadType type) {
int width = getWidthForType(type);
return ROAD_COLOR_FROM_WIDTH[width];
}
}

View File

@@ -0,0 +1,134 @@
package org.insa.graphics.drawing;
import java.awt.Color;
import org.insa.graph.Graph;
import org.insa.graph.Path;
import org.insa.graph.Point;
public interface Drawing {
/**
* Add a listener to click to this drawing.
*
* @param listener
*/
public void addDrawingClickListener(DrawingClickListener listener);
/**
* Remove the given listener from the drawing.
*
* @param listener
*/
public void removeDrawingClickListener(DrawingClickListener listener);
/**
* Clear the drawing.
*/
public void clear();
/**
* Draw a line between the two given points with the default color and width.
*
* @param from
* @param to
*/
public void drawLine(Point from, Point to);
/**
* Draw a line between the two given points with the default color and the given
* width.
*
* @param from
* @param to
* @param width
*/
public void drawLine(Point from, Point to, int width);
/**
* Draw a line between the two given points with the given color and the given
* width.
*
* @param from
* @param to
* @param width
* @param color
*/
public void drawLine(Point from, Point to, int width, Color color);
/**
* Draw a marker at the given point with the default color.
*
* @param point
*/
public void drawMarker(Point point);
/**
* Draw the given point with the given color.
*
* @param point
*/
public void drawMarker(Point point, Color color);
/**
* Draw a point width the given width and color. Do not use this to mark
* location, use drawMarker.
*
* @param point
* @param width
* @param color
*/
public void drawPoint(Point point, int width, Color color);
/**
* Draw the given graph using the given palette.
*
* @param graph
* @param palette
*/
public void drawGraph(Graph graph, GraphPalette palette);
/**
* Draw the given graph using a default palette specific to the implementation.
*
* @param graph
*/
public void drawGraph(Graph graph);
/**
* Draw a path using the given color.
*
* @param path
* @param color
* @param markers
* Show origin and destination markers.
*/
public void drawPath(Path path, Color color, boolean markers);
/**
* Draw a path using the given color with markers.
*
* @param path
* @param color
*/
public void drawPath(Path path, Color color);
/**
* Draw a path using a default color specific to the implementation
*
*
* @param path
* @param markers
* Show origin and destination markers.
*/
public void drawPath(Path path, boolean markers);
/**
* Draw a path using a default color specific to the implementation
*
*
* @param path
*/
public void drawPath(Path path);
}

View File

@@ -0,0 +1,14 @@
package org.insa.graphics.drawing;
import org.insa.graph.Point;
public interface DrawingClickListener {
/**
* Event triggered when a click is made on the map.
*
* @param point
*/
public void mouseClicked(Point point);
}

View File

@@ -0,0 +1,33 @@
package org.insa.graphics.drawing;
import java.awt.Color;
import org.insa.graph.RoadInformation.RoadType;
public interface GraphPalette {
/**
* @return The default point width for this palette.
*/
public int getDefaultPointWidth();
/**
* @return The default point color for this palette.
*/
public Color getDefaultPointColor();
/**
* @param type Type of the road.
*
* @return Color associated to the given type of road.
*/
public Color getColorForType(RoadType type);
/**
* @param type Type of the road.
*
* @return Width associated to the given type of road.
*/
public int getWidthForType(RoadType type);
}

View File

@@ -0,0 +1,315 @@
package org.insa.graphics.drawing;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Path;
import org.insa.graph.Point;
import org.insa.graphics.drawing.utils.MarkerUtils;
import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.core.graphics.GraphicFactory;
import org.mapsforge.core.graphics.Paint;
import org.mapsforge.core.graphics.Style;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.MapPosition;
import org.mapsforge.core.util.LatLongUtils;
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
import org.mapsforge.map.awt.util.AwtUtil;
import org.mapsforge.map.awt.view.MapView;
import org.mapsforge.map.datastore.MapDataStore;
import org.mapsforge.map.layer.Layers;
import org.mapsforge.map.layer.cache.TileCache;
import org.mapsforge.map.layer.hills.HillsRenderConfig;
import org.mapsforge.map.layer.overlay.Marker;
import org.mapsforge.map.layer.overlay.Polyline;
import org.mapsforge.map.layer.renderer.TileRendererLayer;
import org.mapsforge.map.model.DisplayModel;
import org.mapsforge.map.model.MapViewPosition;
import org.mapsforge.map.model.Model;
import org.mapsforge.map.reader.MapFile;
import org.mapsforge.map.rendertheme.InternalRenderTheme;
public class MapViewDrawing extends MapView implements Drawing {
/**
*
*/
private static final long serialVersionUID = 8606967833704938092L;
// Default path color.
public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244);
// Graphic factory.
private static final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE;
// Default tile size.
private static final int DEFAULT_TILE_SIZE = 512;
// List of listeners.
private ArrayList<DrawingClickListener> drawingClickListeners = new ArrayList<>();
// Tile size.
int tileSize;
// Extra layers...
private static class FixedStrokeWidthLayer {
public Paint paint;
public int width;
public FixedStrokeWidthLayer(Paint paint, int width) {
this.paint = paint;
this.width = width;
}
};
ArrayList<FixedStrokeWidthLayer> extraLayers = new ArrayList<>();
public MapViewDrawing() {
getMapScaleBar().setVisible(true);
this.tileSize = DEFAULT_TILE_SIZE;
DisplayModel model = getModel().displayModel;
model.setFixedTileSize(tileSize);
addMouseWheelListener(new MouseAdapter() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
for (FixedStrokeWidthLayer f: extraLayers) {
f.paint.setStrokeWidth(getStrokeWidth(f.width));
}
}
});
}
/**
* @param color
* @return
*/
protected int convertColor(Color color) {
return GRAPHIC_FACTORY.createColor(color.getAlpha(), color.getRed(), color.getGreen(), color.getBlue());
}
/**
* @param width
* @return
*/
private int getStrokeWidth(int width) {
byte zoomLevel = getModel().mapViewPosition.getZoomLevel();
int mul = 2;
if (zoomLevel < 8) {
mul = 1;
}
else {
mul += 2 * (zoomLevel - 8) / 3;
}
return width * mul;
}
/**
* @param width
* @param color
* @return
*/
private Paint createPaintStroke(int width, Color color) {
Paint paintStroke = AwtGraphicFactory.INSTANCE.createPaint();
paintStroke.setStyle(Style.STROKE);
if (width != 0) {
paintStroke.setStrokeWidth(getStrokeWidth(width));
}
if (color != null) {
paintStroke.setColor(convertColor(color));
}
return paintStroke;
}
/**
*
* @param color
* @return
*/
private File getMapsforgeFileFromGraph(Graph graph) {
// TODO: Find a way to change this...
Map<Integer, String> idToNames = new HashMap<Integer, String>();
idToNames.put(0x100, "insa");
idToNames.put(0x110, "paris");
idToNames.put(0x200, "mayotte");
idToNames.put(0x250, "newzealand");
idToNames.put(0x300, "reunion");
idToNames.put(0x400, "midip");
idToNames.put(0x410, "morbihan");
File file = null;
if (idToNames.containsKey(graph.getMapId())) {
file = new File("Maps/" + idToNames.get(graph.getMapId()) + ".mapfg");
if (!file.exists()) {
file = new File("Maps/new/" + idToNames.get(graph.getMapId()) + ".mapfg");
}
}
if (file == null || !file.exists()) {
JFileChooser fileChooser = new JFileChooser("Maps/");
fileChooser.setFileFilter(new FileNameExtensionFilter("mapsforge files", "" + "mapfg"));
if (fileChooser.showOpenDialog(this.getParent()) == JFileChooser.APPROVE_OPTION) {
file = fileChooser.getSelectedFile();
}
}
return file;
}
protected LatLong convertPoint(Point point) {
return new LatLong(point.getLatitude(), point.getLongitude());
}
private TileRendererLayer createTileRendererLayer(TileCache tileCache, MapDataStore mapDataStore,
MapViewPosition mapViewPosition, HillsRenderConfig hillsRenderConfig) {
TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore, mapViewPosition, false,
true, false, GRAPHIC_FACTORY, hillsRenderConfig) {
@Override
public boolean onTap(LatLong tapLatLong, org.mapsforge.core.model.Point layerXY,
org.mapsforge.core.model.Point tapXY) {
System.out.println("Tap on: " + tapLatLong);
Point pt = new Point(tapLatLong.getLongitude(), tapLatLong.getLatitude());
for (DrawingClickListener listener: MapViewDrawing.this.drawingClickListeners) {
listener.mouseClicked(pt);
}
return true;
}
};
tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.DEFAULT);
return tileRendererLayer;
}
@Override
public void addDrawingClickListener(DrawingClickListener listener) {
this.drawingClickListeners.add(listener);
}
@Override
public void removeDrawingClickListener(DrawingClickListener listener) {
this.drawingClickListeners.remove(listener);
}
@Override
public void clear() {
getLayerManager().getLayers().clear();
extraLayers.clear();
repaint();
}
@Override
public void drawLine(Point from, Point to) {
drawLine(from, to, 0, null);
}
@Override
public void drawLine(Point from, Point to, int width) {
drawLine(from, to, width, null);
}
@Override
public void drawLine(Point from, Point to, int width, Color color) {
Paint paintStroke = createPaintStroke(width, color);
Polyline line = new Polyline(paintStroke, AwtGraphicFactory.INSTANCE);
line.getLatLongs().add(convertPoint(from));
line.getLatLongs().add(convertPoint(to));
getLayerManager().getLayers().add(line);
}
@Override
public void drawMarker(Point point) {
drawMarker(point, Color.GREEN);
}
@Override
public void drawMarker(Point point, Color color) {
Bitmap bitmap = MarkerUtils.getMarkerForColor(color);
Marker marker = new Marker(convertPoint(point), bitmap, 0, -bitmap.getHeight() / 2);
getLayerManager().getLayers().add(marker);
}
@Override
public void drawPoint(Point point, int width, Color color) {
// TODO:
}
@Override
public void drawGraph(Graph graph, GraphPalette palette) {
File graphFile = getMapsforgeFileFromGraph(graph);
// Tile cache
TileCache tileCache = AwtUtil.createTileCache(tileSize, getModel().frameBufferModel.getOverdrawFactor(), 1024,
new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()));
// Layers
Layers layers = getLayerManager().getLayers();
MapDataStore mapDataStore = new MapFile(graphFile);
TileRendererLayer tileRendererLayer = createTileRendererLayer(tileCache, mapDataStore,
getModel().mapViewPosition, null);
layers.add(tileRendererLayer);
BoundingBox boundingBox = mapDataStore.boundingBox();
final Model model = getModel();
if (model.mapViewPosition.getZoomLevel() == 0 || !boundingBox.contains(model.mapViewPosition.getCenter())) {
byte zoomLevel = LatLongUtils.zoomForBounds(model.mapViewDimension.getDimension(), boundingBox,
model.displayModel.getTileSize());
model.mapViewPosition.setMapPosition(new MapPosition(boundingBox.getCenterPoint(), zoomLevel));
model.mapViewPosition.setZoomLevelMin(zoomLevel);
}
}
@Override
public void drawGraph(Graph graph) {
drawGraph(graph, null);
}
@Override
public void drawPath(Path path, Color color, boolean markers) {
Paint paintStroke = createPaintStroke(1, DEFAULT_PATH_COLOR);
Polyline line = new Polyline(paintStroke, AwtGraphicFactory.INSTANCE);
for (Arc arc: path.getArcs()) {
ArrayList<Point> points = arc.getPoints();
for (int i = 0; i < points.size(); ++i) {
line.getLatLongs().add(new LatLong(points.get(i).getLatitude(), points.get(i).getLongitude()));
}
}
getLayerManager().getLayers().add(line);
extraLayers.add(new FixedStrokeWidthLayer(paintStroke, 1));
if (markers) {
drawMarker(path.getOrigin().getPoint(), DEFAULT_PATH_COLOR);
drawMarker(path.getDestination().getPoint(), DEFAULT_PATH_COLOR);
}
}
@Override
public void drawPath(Path path, Color color) {
drawPath(path, color, true);
}
@Override
public void drawPath(Path path) {
drawPath(path, DEFAULT_PATH_COLOR, true);
}
@Override
public void drawPath(Path path, boolean markers) {
drawPath(path, DEFAULT_PATH_COLOR, markers);
}
}

View File

@@ -0,0 +1,141 @@
package org.insa.graphics.drawing;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
public class ZoomAndPanListener implements MouseListener, MouseMotionListener, MouseWheelListener {
public static final int DEFAULT_MIN_ZOOM_LEVEL = -20;
public static final int DEFAULT_MAX_ZOOM_LEVEL = 10;
public static final double DEFAULT_ZOOM_MULTIPLICATION_FACTOR = 1.2;
private Component targetComponent;
private int zoomLevel = 0;
private int minZoomLevel = DEFAULT_MIN_ZOOM_LEVEL;
private int maxZoomLevel = DEFAULT_MAX_ZOOM_LEVEL;
private double zoomMultiplicationFactor = DEFAULT_ZOOM_MULTIPLICATION_FACTOR;
private Point dragStartScreen;
private Point dragEndScreen;
private AffineTransform coordTransform = new AffineTransform();
public ZoomAndPanListener(Component targetComponent) {
this.targetComponent = targetComponent;
}
public ZoomAndPanListener(Component targetComponent, int minZoomLevel, int maxZoomLevel, double zoomMultiplicationFactor) {
this.targetComponent = targetComponent;
this.minZoomLevel = minZoomLevel;
this.maxZoomLevel = maxZoomLevel;
this.zoomMultiplicationFactor = zoomMultiplicationFactor;
}
public void translate(double dx, double dy) {
coordTransform.translate(dx, dy);
targetComponent.repaint();
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
dragStartScreen = e.getPoint();
dragEndScreen = null;
}
public void mouseReleased(MouseEvent e) {
// moveCamera(e);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
moveCamera(e);
}
public void mouseWheelMoved(MouseWheelEvent e) {
zoomCamera(e);
}
private void moveCamera(MouseEvent e) {
try {
dragEndScreen = e.getPoint();
Point2D.Float dragStart = transformPoint(dragStartScreen);
Point2D.Float dragEnd = transformPoint(dragEndScreen);
double dx = dragEnd.getX() - dragStart.getX();
double dy = dragEnd.getY() - dragStart.getY();
coordTransform.translate(dx, dy);
dragStartScreen = dragEndScreen;
dragEndScreen = null;
targetComponent.repaint();
} catch (NoninvertibleTransformException ex) {
ex.printStackTrace();
}
}
private void zoomCamera(MouseWheelEvent e) {
try {
int wheelRotation = e.getWheelRotation();
Point p = e.getPoint();
if (wheelRotation > 0) {
if (zoomLevel < maxZoomLevel) {
zoomLevel++;
Point2D p1 = transformPoint(p);
coordTransform.scale(1 / zoomMultiplicationFactor, 1 / zoomMultiplicationFactor);
Point2D p2 = transformPoint(p);
coordTransform.translate(p2.getX() - p1.getX(), p2.getY() - p1.getY());
targetComponent.repaint();
}
} else {
if (zoomLevel > minZoomLevel) {
zoomLevel--;
Point2D p1 = transformPoint(p);
coordTransform.scale(zoomMultiplicationFactor, zoomMultiplicationFactor);
Point2D p2 = transformPoint(p);
coordTransform.translate(p2.getX() - p1.getX(), p2.getY() - p1.getY());
targetComponent.repaint();
}
}
} catch (NoninvertibleTransformException ex) {
ex.printStackTrace();
}
}
private Point2D.Float transformPoint(Point p1) throws NoninvertibleTransformException {
AffineTransform inverse = coordTransform.createInverse();
Point2D.Float p2 = new Point2D.Float();
inverse.transform(p1, p2);
return p2;
}
public int getZoomLevel() {
return zoomLevel;
}
public void setZoomLevel(int zoomLevel) {
this.zoomLevel = zoomLevel;
}
public AffineTransform getCoordTransform() {
return coordTransform;
}
public void setCoordTransform(AffineTransform coordTransform) {
this.coordTransform = coordTransform;
}
}

View File

@@ -0,0 +1,107 @@
package org.insa.graphics.drawing.utils;
import java.awt.Color;
import java.awt.image.BufferedImage;
import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.map.awt.graphics.AwtBitmap;
public class MarkerUtils {
/**
* Return a color mapping with the given color as the main color.
*
* @param color
* @return
*/
protected static Color[] getColorMapping(Color color) {
return new Color[] { new Color(0, 0, 0, 0), color, Color.BLACK };
}
/**
* Create a Bitmap representing a marker of the given color.
*
* @param color
* @return
*/
public static Bitmap getMarkerForColor(Color color) {
// create image
BufferedImage image = new BufferedImage(MARKER_MASK[0].length, MARKER_MASK.length, BufferedImage.TYPE_INT_ARGB);
Color[] map = getColorMapping(color);
for (int i = 0; i < image.getHeight(); ++i) {
for (int j = 0; j < image.getWidth(); ++j) {
image.setRGB(j, i, map[MARKER_MASK[i][j]].getRGB());
}
}
// Create Bitmap and return it.
return new AwtBitmap(image);
}
// Mask
private static byte[][] MARKER_MASK = new byte[][] {
// @formatter:off
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
}