Create new drawing using Mapsforge.

This commit is contained in:
Mikael Capelle 2018-02-21 19:22:37 +01:00
parent 379784e2ec
commit d5af267227
32 changed files with 1239 additions and 393 deletions

View file

@ -23,5 +23,47 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-core-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-core-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-map-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-map-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-map-awt-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-map-awt-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-map-reader-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-map-reader-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-poi-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-poi-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-poi-awt-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-poi-awt-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-themes-0.9.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/mapsforge-themes-0.9.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/kxml2-2.3.0.jar"/>
<classpathentry kind="lib" path="libs/svg-salamander-1.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/svg-salamander-1.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/mapsforge-map-writer-0.9.1-jar-with-dependencies.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View file

@ -10,14 +10,8 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

BIN
libs/kxml2-2.3.0.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/svg-salamander-1.0.jar Normal file

Binary file not shown.

View file

@ -4,7 +4,6 @@ import java.awt.Color;
import java.util.ArrayList;
import org.insa.drawing.Drawing;
import org.insa.drawing.graph.GraphDrawing;
import org.insa.graph.Node;
public class WeaklyConnectedComponentGraphicObserver implements WeaklyConnectedComponentObserver {
@ -15,27 +14,22 @@ public class WeaklyConnectedComponentGraphicObserver implements WeaklyConnectedC
// Drawing + Graph drawing
private Drawing drawing;
private GraphDrawing gdrawing;
// Current index color
private int cindex = 0;
private int cindex = -1;
public WeaklyConnectedComponentGraphicObserver(Drawing drawing) {
this.drawing = drawing;
this.gdrawing = new GraphDrawing(drawing);
this.drawing.setAutoRepaint(true);
}
@Override
public void notifyStartComponent(Node curNode) {
this.drawing.setColor(COLORS[cindex]);
cindex = (cindex + 1) % COLORS.length;
}
@Override
public void notifyNewNodeInComponent(Node node) {
this.gdrawing.drawPoint(node.getPoint(), 5);
this.drawing.repaint();
this.drawing.drawMarker(node.getPoint(), COLORS[cindex]);
}
@Override

View file

@ -2,6 +2,7 @@ package org.insa.base;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -11,6 +12,8 @@ import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.NoninvertibleTransformException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
@ -47,15 +50,17 @@ import org.insa.algo.shortestpath.ShortestPathSolution;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsData;
import org.insa.drawing.BasicDrawing;
import org.insa.drawing.BlackAndWhiteGraphPalette;
import org.insa.drawing.Drawing;
import org.insa.drawing.graph.BlackAndWhiteGraphPalette;
import org.insa.drawing.graph.GraphDrawing;
import org.insa.drawing.graph.PathDrawing;
import org.insa.drawing.MapViewDrawing;
import org.insa.graph.Graph;
import org.insa.graph.Node;
import org.insa.graph.Path;
import org.insa.graph.Point;
import org.insa.graph.io.AbstractGraphReader;
import org.insa.graph.io.BinaryGraphReader;
import org.insa.graph.io.BinaryGraphReaderV2;
import org.insa.graph.io.BinaryPathReader;
import org.insa.graph.io.MapMismatchException;
import org.insa.graph.io.Openfile;
@ -132,7 +137,8 @@ public class MainWindow extends JFrame {
}
Point lonlat;
try {
lonlat = drawing.getLongitudeLatitude(evt);
// TODO: Fix
lonlat = ((BasicDrawing)drawing).getLongitudeLatitude(evt);
}
catch (NoninvertibleTransformException e) {
// Should never happens in "normal" circumstances...
@ -142,7 +148,7 @@ public class MainWindow extends JFrame {
Node node = graph.findClosestNode(lonlat);
new GraphDrawing(drawing).drawPoint(node.getPoint(), 10, Color.BLUE);
drawing.drawMarker(node.getPoint(), Color.BLUE);
points.add(node);
if (points.size() == nTargetPoints) {
callable.call(points);
@ -176,6 +182,9 @@ public class MainWindow extends JFrame {
private Drawing drawing;
private DrawingClickListener clickAdapter;
// Main panel.
private JSplitPane mainPanel;
// List of item for the top menus.
private JMenuItem openMapItem;
@ -219,13 +228,17 @@ public class MainWindow extends JFrame {
});
// Create graph area
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
drawing = new Drawing();
BasicDrawing drawing = new BasicDrawing();
// MapViewDrawing drawing = new MapViewDrawing();
Component drawingComponent = drawing;
this.drawing = drawing;
// Click adapter
this.clickAdapter = new DrawingClickListener();
drawing.addMouseListener(this.clickAdapter);
// drawing.addMouseListener(this.clickAdapter);
JTextArea infoPanel = new JTextArea();
infoPanel.setMinimumSize(new Dimension(200, 50));
@ -236,14 +249,14 @@ public class MainWindow extends JFrame {
this.logStream = new JOutputStream(infoPanel);
this.printStream = new PrintStream(this.logStream);
sp.setResizeWeight(0.8);
mainPanel.setResizeWeight(0.8);
// sp.setEnabled(false);
sp.setDividerSize(5);
mainPanel.setDividerSize(5);
sp.setBackground(Color.WHITE);
sp.add(drawing);
sp.add(new JScrollPane(infoPanel));
this.add(sp, BorderLayout.CENTER);
mainPanel.setBackground(Color.WHITE);
mainPanel.add(drawingComponent);
mainPanel.add(new JScrollPane(infoPanel));
this.add(mainPanel, BorderLayout.CENTER);
// Top Panel
this.add(createTopPanel(), BorderLayout.NORTH);
@ -299,7 +312,7 @@ public class MainWindow extends JFrame {
public void run() {
ShortestPathSolution solution = spAlgorithm.run();
if (solution != null && solution.isFeasible()) {
new PathDrawing(drawing).drawPath(solution.getPath());
drawing.drawPath(solution.getPath());
}
}
});
@ -317,30 +330,38 @@ public class MainWindow extends JFrame {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Map & compressed map files", "map", "map.gz");
"Map & compressed map files", "map", "map2", "map.gz");
chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
chooser.setFileFilter(filter);
if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
launchThread(new Runnable() {
@Override
public void run() {
BinaryGraphReader reader;
String path = chooser.getSelectedFile().getAbsolutePath();
DataInputStream stream;
try {
reader = new BinaryGraphReader(
Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
stream = Openfile.open(path);
} catch (IOException e1) {
JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
return ;
}
AbstractGraphReader reader;
if (path.endsWith(".map2")) {
reader = new BinaryGraphReaderV2(stream);
}
else {
reader = new BinaryGraphReader(stream);
}
try {
graph = reader.read();
}
catch (Exception exception) {
JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file.");
exception.printStackTrace(System.out);
return ;
}
drawing.clear();
new GraphDrawing(drawing).drawGraph(graph);
drawing.drawGraph(graph);
for (JMenuItem item: graphLockItems) {
item.setEnabled(true);
@ -384,7 +405,7 @@ public class MainWindow extends JFrame {
JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file.");
return ;
}
new PathDrawing(drawing).drawPath(currentPath);
drawing.drawPath(currentPath);
}
}
});
@ -418,9 +439,13 @@ public class MainWindow extends JFrame {
launchThread(new Runnable() {
@Override
public void run() {
if (!(drawing instanceof BasicDrawing)) {
BasicDrawing tmp = new BasicDrawing();
mainPanel.setLeftComponent(tmp);
drawing = tmp;
}
drawing.clear();
drawing.setAutoRepaint(true);
new GraphDrawing(drawing).drawGraph(graph);
drawing.drawGraph(graph);
}
});
}
@ -435,18 +460,45 @@ public class MainWindow extends JFrame {
launchThread(new Runnable() {
@Override
public void run() {
if (!(drawing instanceof BasicDrawing)) {
BasicDrawing tmp = new BasicDrawing();
mainPanel.setLeftComponent(tmp);
drawing = tmp;
}
drawing.clear();
drawing.setAutoRepaint(true);
new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph);
drawing.drawGraph(graph, new BlackAndWhiteGraphPalette());
}
});
}
});
graphLockItems.add(drawGraphBWItem);
JMenuItem drawGraphMapsforgeItem = new JMenuItem("Redraw (Map)", KeyEvent.VK_M);
drawGraphMapsforgeItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_M, ActionEvent.ALT_MASK));
drawGraphMapsforgeItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
launchThread(new Runnable() {
@Override
public void run() {
if (!(drawing instanceof MapViewDrawing)) {
MapViewDrawing tmp = new MapViewDrawing();
mainPanel.setLeftComponent(tmp);
drawing = tmp;
}
drawing.clear();
drawing.drawGraph(graph, new BlackAndWhiteGraphPalette());
}
});
}
});
graphLockItems.add(drawGraphMapsforgeItem);
JMenu graphMenu = new JMenu("Graph");
graphMenu.add(drawGraphItem);
graphMenu.add(drawGraphBWItem);
graphMenu.addSeparator();
graphMenu.add(drawGraphMapsforgeItem);
// Algo menu
JMenu algoMenu = new JMenu("Algorithms");

View file

@ -0,0 +1,285 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014 Christian Pesch
* Copyright 2014 Ludwig M Brinckmann
* Copyright 2014-2018 devemux86
* Copyright 2017 usrusr
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.insa.base;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Path;
import org.insa.graph.io.BinaryGraphReader;
import org.insa.graph.io.BinaryPathReader;
import org.insa.graph.io.Openfile;
import org.mapsforge.core.graphics.Color;
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.model.Point;
import org.mapsforge.core.util.LatLongUtils;
import org.mapsforge.core.util.Parameters;
import org.mapsforge.core.util.Utils;
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
import org.mapsforge.map.awt.util.AwtUtil;
import org.mapsforge.map.awt.util.JavaPreferences;
import org.mapsforge.map.awt.view.MapView;
import org.mapsforge.map.datastore.MapDataStore;
import org.mapsforge.map.datastore.MultiMapDataStore;
import org.mapsforge.map.layer.Layers;
import org.mapsforge.map.layer.cache.TileCache;
import org.mapsforge.map.layer.debug.TileCoordinatesLayer;
import org.mapsforge.map.layer.debug.TileGridLayer;
import org.mapsforge.map.layer.download.TileDownloadLayer;
import org.mapsforge.map.layer.download.tilesource.OpenStreetMapMapnik;
import org.mapsforge.map.layer.download.tilesource.TileSource;
import org.mapsforge.map.layer.hills.DiffuseLightShadingAlgorithm;
import org.mapsforge.map.layer.hills.HillsRenderConfig;
import org.mapsforge.map.layer.hills.MemoryCachingHgtReaderTileSource;
import org.mapsforge.map.layer.overlay.Polyline;
import org.mapsforge.map.layer.renderer.TileRendererLayer;
import org.mapsforge.map.model.MapViewPosition;
import org.mapsforge.map.model.Model;
import org.mapsforge.map.model.common.PreferencesFacade;
import org.mapsforge.map.reader.MapFile;
import org.mapsforge.map.rendertheme.InternalRenderTheme;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.prefs.Preferences;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;
public final class Samples {
private static final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE;
private static final boolean SHOW_DEBUG_LAYERS = false;
private static final boolean SHOW_RASTER_MAP = false;
private static final String MESSAGE = "Are you sure you want to exit the application?";
private static final String TITLE = "Confirm close";
/**
* Starts the {@code Samples}.
*
* @param args command line args: expects the map files as multiple parameters
* with possible SRTM hgt folder as 1st argument.
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// Multithreaded map rendering
Parameters.NUMBER_OF_THREADS = 2;
// Square frame buffer
Parameters.SQUARE_FRAME_BUFFER = false;
HillsRenderConfig hillsCfg = null;
File demFolder = getDemFolder(args);
if (demFolder != null) {
MemoryCachingHgtReaderTileSource tileSource = new MemoryCachingHgtReaderTileSource(demFolder, new DiffuseLightShadingAlgorithm(), AwtGraphicFactory.INSTANCE);
tileSource.setEnableInterpolationOverlap(true);
hillsCfg = new HillsRenderConfig(tileSource);
hillsCfg.indexOnThread();
args = Arrays.copyOfRange(args, 1, args.length);
}
List<File> mapFiles = getMapFiles(args);
final MapView mapView = createMapView();
final BoundingBox boundingBox = addLayers(mapView, mapFiles, hillsCfg);
// addAPath(mapView);
final PreferencesFacade preferencesFacade = new JavaPreferences(Preferences.userNodeForPackage(Samples.class));
final JFrame frame = new JFrame();
frame.setTitle("Mapsforge Samples");
frame.add(mapView);
frame.pack();
frame.setSize(new Dimension(800, 600));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
int result = JOptionPane.showConfirmDialog(frame, MESSAGE, TITLE, JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
mapView.getModel().save(preferencesFacade);
mapView.destroyAll();
AwtGraphicFactory.clearResourceMemoryCache();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
@Override
public void windowOpened(WindowEvent e) {
final Model model = mapView.getModel();
model.init(preferencesFacade);
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));
}
}
});
frame.setVisible(true);
}
private static void addAPath(MapView mapView) throws Exception {
Graph gr = (new BinaryGraphReader(Openfile.open("Maps/midip.map"))).read();
Path path = (new BinaryPathReader(Openfile.open("Paths/chemin_0x400_119963_96676.path"))).readPath(gr);
Paint paintStroke = AwtGraphicFactory.INSTANCE.createPaint();
paintStroke.setColor(Color.GREEN);
paintStroke.setStrokeWidth(3);
paintStroke.setStyle(Style.STROKE);
Polyline line = new Polyline(paintStroke, AwtGraphicFactory.INSTANCE);
for (Arc arc: path.getArcs()) {
ArrayList<org.insa.graph.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()));
}
}
mapView.getLayerManager().getLayers().add(line);
}
private static BoundingBox addLayers(MapView mapView, List<File> mapFiles, HillsRenderConfig hillsRenderConfig) {
Layers layers = mapView.getLayerManager().getLayers();
int tileSize = SHOW_RASTER_MAP ? 256 : 512;
// Tile cache
TileCache tileCache = AwtUtil.createTileCache(
tileSize,
mapView.getModel().frameBufferModel.getOverdrawFactor(),
1024,
new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()));
final BoundingBox boundingBox;
if (SHOW_RASTER_MAP) {
// Raster
mapView.getModel().displayModel.setFixedTileSize(tileSize);
TileSource tileSource = OpenStreetMapMapnik.INSTANCE;
TileDownloadLayer tileDownloadLayer = createTileDownloadLayer(tileCache, mapView.getModel().mapViewPosition, tileSource);
layers.add(tileDownloadLayer);
tileDownloadLayer.start();
mapView.setZoomLevelMin(tileSource.getZoomLevelMin());
mapView.setZoomLevelMax(tileSource.getZoomLevelMax());
boundingBox = new BoundingBox(LatLongUtils.LATITUDE_MIN, LatLongUtils.LONGITUDE_MIN, LatLongUtils.LATITUDE_MAX, LatLongUtils.LONGITUDE_MAX);
} else {
// Vector
mapView.getModel().displayModel.setFixedTileSize(tileSize);
MultiMapDataStore mapDataStore = new MultiMapDataStore(MultiMapDataStore.DataPolicy.RETURN_ALL);
for (File file : mapFiles) {
mapDataStore.addMapDataStore(new MapFile(file), false, false);
}
TileRendererLayer tileRendererLayer = createTileRendererLayer(tileCache, mapDataStore, mapView.getModel().mapViewPosition, hillsRenderConfig);
layers.add(tileRendererLayer);
boundingBox = mapDataStore.boundingBox();
}
// Debug
if (SHOW_DEBUG_LAYERS) {
layers.add(new TileGridLayer(GRAPHIC_FACTORY, mapView.getModel().displayModel));
layers.add(new TileCoordinatesLayer(GRAPHIC_FACTORY, mapView.getModel().displayModel));
}
return boundingBox;
}
private static MapView createMapView() {
MapView mapView = new MapView();
mapView.getMapScaleBar().setVisible(true);
if (SHOW_DEBUG_LAYERS) {
mapView.getFpsCounter().setVisible(true);
}
return mapView;
}
@SuppressWarnings("unused")
private static TileDownloadLayer createTileDownloadLayer(TileCache tileCache, MapViewPosition mapViewPosition, TileSource tileSource) {
return new TileDownloadLayer(tileCache, mapViewPosition, tileSource, GRAPHIC_FACTORY) {
@Override
public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
System.out.println("Tap on: " + tapLatLong);
return true;
}
};
}
private static 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, Point layerXY, Point tapXY) {
System.out.println("Tap on: " + tapLatLong);
return true;
}
};
tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.DEFAULT);
return tileRendererLayer;
}
private static File getDemFolder(String[] args) {
if (args.length == 0) {
throw new IllegalArgumentException("missing argument: <mapFile>");
}
File demFolder = new File(args[0]);
if (demFolder.exists() && demFolder.isDirectory() && demFolder.canRead()) {
return demFolder;
}
return null;
}
private static List<File> getMapFiles(String[] args) {
if (args.length == 0) {
throw new IllegalArgumentException("missing argument: <mapFile>");
}
List<File> result = new ArrayList<>();
for (String arg : args) {
File mapFile = new File(arg);
if (!mapFile.exists()) {
throw new IllegalArgumentException("file does not exist: " + mapFile);
} else if (!mapFile.isFile()) {
throw new IllegalArgumentException("not a file: " + mapFile);
} else if (!mapFile.canRead()) {
throw new IllegalArgumentException("cannot read file: " + mapFile);
}
result.add(mapFile);
}
return result;
}
private Samples() {
throw new IllegalStateException();
}
}

View file

@ -0,0 +1,314 @@
package org.insa.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.MouseEvent;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.image.*;
import java.util.ArrayList;
import java.util.Iterator;
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;
/**
* 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);
}
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

@ -1,4 +1,4 @@
package org.insa.drawing.graph;
package org.insa.drawing;
import java.awt.Color;

View file

@ -1,4 +1,4 @@
package org.insa.drawing.graph;
package org.insa.drawing;
import java.awt.Color;

View file

@ -1,179 +1,119 @@
package org.insa.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.MouseEvent;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.image.*;
import javax.swing.JPanel;
import org.insa.graph.Graph;
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 Drawing extends JPanel {
public interface Drawing {
/**
*
* Clear the drawing.
*/
private static final long serialVersionUID = 96779785877771827L;
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;
public boolean autoRepaint = true;
public void clear();
/**
* Cree et affiche une nouvelle fenetre de dessin.
* Draw a line between the two given points with the default color
* and width.
*
* @param from
* @param to
*/
public Drawing() {
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);
}
public void setAutoRepaint(boolean autoRepaint) {
this.autoRepaint = autoRepaint;
}
protected void doAutoPaint() {
if (autoRepaint) {
this.repaint();
}
}
public void setWidth(int width) {
this.gr.setStroke(new BasicStroke(width));
}
public void setColor(Color col) {
this.gr.setColor(col);
}
public void clear() {
this.gr.setColor(Color.WHITE);
this.gr.fillRect(0, 0, this.width, this.height);
}
public 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))) ;
}
public void drawLine(Point from, Point to);
/**
* Return the longitude and latitude corresponding to the given
* position of the MouseEvent.
* Draw a line between the two given points with the default color
* and the given width.
*
* @param event
*
* @return
* @param from
* @param to
* @param width
*/
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);
public void drawLine(Point from, Point to, int width);
// 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;
/**
* 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);
// Return a new point.
return new Point(lon, lat);
}
/**
* Draw a marker at the given point with the default color.
*
* @param point
*/
public void drawMarker(Point point);
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()) ;
/**
* Draw the given point with the given color.
*
* @param point
*/
public void drawMarker(Point point, Color color);
gr.drawLine(x1, y1, x2, y2) ;
this.doAutoPaint();
}
/**
* 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);
public void drawPoint(Point point, int width) {
int x = this.projx(point.getLongitude()) - width / 2;
int y = this.projy(point.getLatitude()) - width / 2;
gr.fillOval(x, y, width, width);
this.doAutoPaint();
}
/**
* Draw the given graph using the given palette.
*
* @param graph
* @param palette
*/
public void drawGraph(Graph graph, GraphPalette palette);
public void putText(Point point, String txt) {
int x = this.projx(point.getLongitude());
int y = this.projy(point.getLatitude());
gr.drawString(txt, x, y);
this.doAutoPaint();
}
/**
* 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

@ -1,4 +1,4 @@
package org.insa.drawing.graph;
package org.insa.drawing;
import java.awt.Color;

View file

@ -0,0 +1,237 @@
package org.insa.drawing;
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.prefs.Preferences;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Path;
import org.insa.graph.Point;
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.util.JavaPreferences;
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.model.common.Observer;
import org.mapsforge.map.model.common.PreferencesFacade;
import org.mapsforge.map.reader.MapFile;
import org.mapsforge.map.rendertheme.InternalRenderTheme;
import org.mapsforge.map.rendertheme.XmlRenderTheme;
import com.google.common.util.concurrent.SettableFuture;
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;
// Tile size.
int tileSize;
public MapViewDrawing() {
setBackground(Color.WHITE);
getMapScaleBar().setVisible(true);
this.tileSize = DEFAULT_TILE_SIZE;
DisplayModel model = getModel().displayModel;
model.setFixedTileSize(tileSize);
model.setBackgroundColor(convertColor(Color.WHITE));
}
protected int convertColor(Color color) {
return GRAPHIC_FACTORY.createColor(color.getAlpha(), color.getRed(),
color.getGreen(), color.getBlue());
}
private Paint createPaintStroke(int width, Color color) {
Paint paintStroke = AwtGraphicFactory.INSTANCE.createPaint();
paintStroke.setStyle(Style.STROKE);
if (width != 0) {
paintStroke.setStrokeWidth(width);
}
if (color != null) {
paintStroke.setColor(convertColor(color));
}
return paintStroke;
}
/**
*
* @param color
* @return
*/
private static 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(0x101, "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");
}
return file;
}
protected LatLong convertPoint(Point point) {
return new LatLong(point.getLatitude(), point.getLongitude());
}
private static 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);
return true;
}
};
XmlRenderTheme renderTheme = InternalRenderTheme.DEFAULT;
tileRendererLayer.setXmlRenderTheme(renderTheme);
return tileRendererLayer;
}
@Override
public void clear() {
getLayerManager().getLayers().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, null);
}
@Override
public void drawMarker(Point point, Color color) {
Marker marker = new Marker(convertPoint(point), GRAPHIC_FACTORY.createBitmap(10, 20), 1, 2);
getLayerManager().getLayers().add(marker);
}
@Override
public void drawPoint(Point point, int width, Color color) {
// TODO: Maybe do something?
}
@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 PreferencesFacade preferencesFacade = new JavaPreferences(Preferences.userNodeForPackage(MapViewDrawing.class));
final Model model = getModel();
model.init(preferencesFacade);
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));
}
}
@Override
public void drawGraph(Graph graph) {
drawGraph(graph, null);
}
@Override
public void drawPath(Path path, Color color, boolean markers) {
Paint paintStroke = createPaintStroke(5, 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);
if (markers) {
drawMarker(path.getOrigin().getPoint());
drawMarker(path.getDestination().getPoint());
}
}
@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

@ -1,132 +0,0 @@
package org.insa.drawing.graph;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import org.insa.drawing.Drawing;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Node;
import org.insa.graph.Point;
public class GraphDrawing {
// Drawing
private Drawing drawing;
// Palette
private GraphPalette palette;
public GraphDrawing(Drawing drawing) {
this.drawing = drawing;
this.palette = new BasicGraphPalette();
}
public GraphDrawing(Drawing drawing, GraphPalette palette) {
this.drawing = drawing;
this.palette = palette;
}
public void drawLine(Point p1, Point p2) {
drawing.drawLine(p1, p2);
}
public void drawPoint(Point p) {
drawPoint(p, palette.getDefaultPointWidth());
}
public void drawPoint(Point p, int width) {
drawing.drawPoint(p, width);
}
public void drawPoint(Point p, int width, Color c) {
drawing.setColor(c);
drawing.drawPoint(p, width);
}
/**
* Draw the given arc with automatic color and width depending
* on the road type.
*
* @param arc Arc to draw.
*/
public void drawArc(Arc arc) {
drawArc(arc, true);
}
/**
* Draw the given arc.
*
* @param arc Arc to draw.
* @param autoColorAndWidth Set to true to set color and width based
* on the road type of the arc.
*/
public void drawArc(Arc arc, boolean autoColorAndWidth) {
ArrayList<Point> pts = arc.getPoints();
if (!pts.isEmpty()) {
if (autoColorAndWidth) {
drawing.setColor(palette.getColorForType(arc.getInfo().getType()));
drawing.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);
drawing.setBB(minLon - deltaLon, maxLon + deltaLon,
minLat - deltaLat, maxLat + deltaLat);
}
/**
* Clear the drawing and draw the given graph on the drawing.
*
* @param graph Graph to draw.
*/
public void drawGraph(Graph graph) {
drawing.clear();
initialize(graph);
for (Node node: graph.getNodes()) {
for (Arc arc: node.getSuccessors()) {
drawArc(arc);
}
}
}
}

View file

@ -1,52 +0,0 @@
package org.insa.drawing.graph;
import java.awt.Color;
import org.insa.drawing.Drawing;
import org.insa.graph.Arc;
import org.insa.graph.Path;
public class PathDrawing {
// Default color
public static final Color DEFAULT_PATH_COLOR = new Color(255, 0, 255);
// Drawing
private Drawing drawing;
private GraphDrawing graphDrawing;
/**
* @param drawing
*/
public PathDrawing(Drawing drawing) {
this.drawing = drawing;
this.graphDrawing = new GraphDrawing(drawing);
}
/**
* Draw the given path with the given color.
*
* @param path
* @param color
*/
public void drawPath(Path path, Color color) {
this.graphDrawing.drawPoint(path.getFirstNode().getPoint(), 4, color);
this.drawing.setColor(color);
this.drawing.setWidth(2);
for (Arc arc: path.getArcs()) {
this.graphDrawing.drawArc(arc, false);
}
this.graphDrawing.drawPoint(path.getLastNode().getPoint(), 4, color);
}
/**
* Draw the given path with default color.
*
* @param path
*/
public void drawPath(Path path) {
drawPath(path, DEFAULT_PATH_COLOR);
drawing.repaint();
}
}

View file

@ -61,6 +61,8 @@ public class BinaryGraphReader extends BinaryReader implements AbstractGraphRead
@Override
public Graph read() throws IOException {
System.out.println(getClass());
// Read and check magic number and file version.
checkMagicNumberOrThrow(dis.readInt());
checkVersionOrThrow(dis.readInt());

View file

@ -0,0 +1,170 @@
package org.insa.graph.io;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import org.insa.graph.Arc;
import org.insa.graph.Graph;
import org.insa.graph.Node;
import org.insa.graph.Point;
import org.insa.graph.RoadInformation;
import org.insa.graph.RoadInformation.RoadType;
public class BinaryGraphReaderV2 extends BinaryReader implements AbstractGraphReader {
// Map version and magic number targeted for this reader.
private static final int VERSION = 5;
private static final int MAGIC_NUMBER = 0x208BC3B3;
/**
* Convert a character to its corresponding road type.
*
* @param ch Character to convert.
*
* @return Road type corresponding to ch.
*
* @see http://wiki.openstreetmap.org/wiki/Highway_tag_usage.
*/
public static RoadType toRoadType(char ch) {
switch (ch) {
case 'a': return RoadType.MOTORWAY;
case 'b': return RoadType.TRUNK;
case 'c': return RoadType.PRIMARY;
case 'd': return RoadType.SECONDARY;
case 'e': return RoadType.MOTORWAY_LINK;
case 'f': return RoadType.TRUNK_LINK;
case 'g': return RoadType.PRIMARY_LINK;
case 'h': return RoadType.SECONDARY_LINK;
case 'i': return RoadType.TERTIARY;
case 'j': return RoadType.RESIDENTIAL;
case 'k': return RoadType.UNCLASSIFIED;
case 'l': return RoadType.ROAD;
case 'm': return RoadType.LIVING_STREET;
case 'n': return RoadType.SERVICE;
case 'o': return RoadType.ROUNDABOUT;
case 'z': return RoadType.COASTLINE;
}
return RoadType.UNCLASSIFIED;
}
/**
* Create a new BinaryGraphReader using the given DataInputStream.
*
* @param dis
*/
public BinaryGraphReaderV2(DataInputStream dis) {
super(MAGIC_NUMBER, VERSION, dis);
}
@Override
public Graph read() throws IOException {
// Read and check magic number and file version.
checkMagicNumberOrThrow(dis.readInt());
checkVersionOrThrow(dis.readInt());
// Read map id.
int mapId = dis.readInt();
// Number of descriptors and nodes.
int nbDesc = dis.readInt();
int nbNodes = dis.readInt();
// Number of successors for each nodes.
int[] nbSuccessors = new int[nbNodes];
// Construct an array list with initial capacity of nbNodes.
ArrayList<Node> nodes = new ArrayList<Node>(nbNodes);
// Read nodes.
for (int node = 0; node < nbNodes; ++node) {
float longitude = ((float)dis.readInt ()) / 1E6f;
float latitude = ((float)dis.readInt ()) / 1E6f;
nbSuccessors[node] = dis.readUnsignedByte();
nodes.add(new Node(node, new Point(longitude, latitude)));
}
// Check format.
checkByteOrThrow(255);
// Read descriptors.
RoadInformation[] descs = new RoadInformation[nbDesc];
// Read
for (int descr = 0; descr < nbDesc; ++descr) {
descs[descr] = readRoadInformation();
}
// Check format.
checkByteOrThrow(254);
// Read successors and convert to arcs.
for (int node = 0; node < nbNodes; ++node) {
for (int succ = 0; succ < nbSuccessors[node]; ++succ) {
// Read target node number.
int destNode = this.read24bits();
// Read information number.
int descrNum = this.read24bits();
// Length of the arc.
int length = dis.readUnsignedShort();
// Number of segments.
int nbSegments = dis.readUnsignedShort();
// Chain of points corresponding to the segments.
ArrayList<Point> points = new ArrayList<Point>(nbSegments + 2);
points.add(nodes.get(node).getPoint());
for (int seg = 0; seg < nbSegments; ++seg) {
Point lastPoint = points.get(points.size() - 1);
float dlon = (dis.readShort()) / 2.0e5f;
float dlat = (dis.readShort()) / 2.0e5f;
points.add(new Point(lastPoint.getLongitude() + dlon,
lastPoint.getLatitude() + dlat));
}
points.add(nodes.get(destNode).getPoint());
RoadInformation info = descs[descrNum];
Node orig = nodes.get(node);
Node dest = nodes.get(destNode);
// Add successor to initial arc.
new Arc(orig, dest, length, info, points);
// And reverse arc if its a two-way road.
if (!info.isOneWay()) {
// Add without segments.
ArrayList<Point> rPoints = new ArrayList<Point>(points);
Collections.reverse(rPoints);
new Arc(dest, orig, length, info, rPoints);
}
}
}
// Check format.
checkByteOrThrow(253);
return new Graph(mapId, nodes);
}
/**
* Read the next road information from the stream.
*
* @throws IOException
*/
private RoadInformation readRoadInformation() throws IOException {
char type = (char)dis.readUnsignedByte();
int x = dis.readUnsignedByte() ;
return new RoadInformation(toRoadType(type), (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF());
}
}