diff --git a/.classpath b/.classpath
index e6ce8ae..a2f75d1 100644
--- a/.classpath
+++ b/.classpath
@@ -23,5 +23,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
index 87c2087..9a8e431 100644
--- a/.project
+++ b/.project
@@ -10,14 +10,8 @@
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
- org.eclipse.m2e.core.maven2Nature
org.eclipse.jdt.core.javanature
diff --git a/libs/kxml2-2.3.0.jar b/libs/kxml2-2.3.0.jar
new file mode 100644
index 0000000..6470952
Binary files /dev/null and b/libs/kxml2-2.3.0.jar differ
diff --git a/libs/mapsforge-core-0.9.1-javadoc.jar b/libs/mapsforge-core-0.9.1-javadoc.jar
new file mode 100644
index 0000000..a2a3d4f
Binary files /dev/null and b/libs/mapsforge-core-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-core-0.9.1.jar b/libs/mapsforge-core-0.9.1.jar
new file mode 100644
index 0000000..23125a4
Binary files /dev/null and b/libs/mapsforge-core-0.9.1.jar differ
diff --git a/libs/mapsforge-map-0.9.1-javadoc.jar b/libs/mapsforge-map-0.9.1-javadoc.jar
new file mode 100644
index 0000000..5fe05e1
Binary files /dev/null and b/libs/mapsforge-map-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-map-0.9.1.jar b/libs/mapsforge-map-0.9.1.jar
new file mode 100644
index 0000000..abb4f89
Binary files /dev/null and b/libs/mapsforge-map-0.9.1.jar differ
diff --git a/libs/mapsforge-map-awt-0.9.1-javadoc.jar b/libs/mapsforge-map-awt-0.9.1-javadoc.jar
new file mode 100644
index 0000000..5f01eaa
Binary files /dev/null and b/libs/mapsforge-map-awt-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-map-awt-0.9.1.jar b/libs/mapsforge-map-awt-0.9.1.jar
new file mode 100644
index 0000000..169c154
Binary files /dev/null and b/libs/mapsforge-map-awt-0.9.1.jar differ
diff --git a/libs/mapsforge-map-reader-0.9.1-javadoc.jar b/libs/mapsforge-map-reader-0.9.1-javadoc.jar
new file mode 100644
index 0000000..783bb46
Binary files /dev/null and b/libs/mapsforge-map-reader-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-map-reader-0.9.1.jar b/libs/mapsforge-map-reader-0.9.1.jar
new file mode 100644
index 0000000..51ad11d
Binary files /dev/null and b/libs/mapsforge-map-reader-0.9.1.jar differ
diff --git a/libs/mapsforge-poi-0.9.1-javadoc.jar b/libs/mapsforge-poi-0.9.1-javadoc.jar
new file mode 100644
index 0000000..0d23e5d
Binary files /dev/null and b/libs/mapsforge-poi-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-poi-0.9.1.jar b/libs/mapsforge-poi-0.9.1.jar
new file mode 100644
index 0000000..d778de4
Binary files /dev/null and b/libs/mapsforge-poi-0.9.1.jar differ
diff --git a/libs/mapsforge-poi-awt-0.9.1-javadoc.jar b/libs/mapsforge-poi-awt-0.9.1-javadoc.jar
new file mode 100644
index 0000000..3c6a872
Binary files /dev/null and b/libs/mapsforge-poi-awt-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-poi-awt-0.9.1.jar b/libs/mapsforge-poi-awt-0.9.1.jar
new file mode 100644
index 0000000..14e1b89
Binary files /dev/null and b/libs/mapsforge-poi-awt-0.9.1.jar differ
diff --git a/libs/mapsforge-themes-0.9.1-javadoc.jar b/libs/mapsforge-themes-0.9.1-javadoc.jar
new file mode 100644
index 0000000..b40c7e5
Binary files /dev/null and b/libs/mapsforge-themes-0.9.1-javadoc.jar differ
diff --git a/libs/mapsforge-themes-0.9.1.jar b/libs/mapsforge-themes-0.9.1.jar
new file mode 100644
index 0000000..e91f12b
Binary files /dev/null and b/libs/mapsforge-themes-0.9.1.jar differ
diff --git a/libs/svg-salamander-1.0-javadoc.jar b/libs/svg-salamander-1.0-javadoc.jar
new file mode 100644
index 0000000..e136ad8
Binary files /dev/null and b/libs/svg-salamander-1.0-javadoc.jar differ
diff --git a/libs/svg-salamander-1.0.jar b/libs/svg-salamander-1.0.jar
new file mode 100644
index 0000000..200eeb0
Binary files /dev/null and b/libs/svg-salamander-1.0.jar differ
diff --git a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java b/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java
index 2f24dd9..c5cfa53 100644
--- a/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java
+++ b/src/main/org/insa/algo/weakconnectivity/WeaklyConnectedComponentGraphicObserver.java
@@ -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
diff --git a/src/main/org/insa/base/MainWindow.java b/src/main/org/insa/base/MainWindow.java
index 129e915..01b45dc 100644
--- a/src/main/org/insa/base/MainWindow.java
+++ b/src/main/org/insa/base/MainWindow.java
@@ -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");
diff --git a/src/main/org/insa/base/Samples.java b/src/main/org/insa/base/Samples.java
new file mode 100644
index 0000000..a08b2cf
--- /dev/null
+++ b/src/main/org/insa/base/Samples.java
@@ -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 .
+ */
+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 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 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 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: ");
+ }
+
+ File demFolder = new File(args[0]);
+ if (demFolder.exists() && demFolder.isDirectory() && demFolder.canRead()) {
+ return demFolder;
+ }
+ return null;
+ }
+
+ private static List getMapFiles(String[] args) {
+ if (args.length == 0) {
+ throw new IllegalArgumentException("missing argument: ");
+ }
+
+ List 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();
+ }
+}
\ No newline at end of file
diff --git a/src/main/org/insa/drawing/BasicDrawing.java b/src/main/org/insa/drawing/BasicDrawing.java
new file mode 100644
index 0000000..6b67e84
--- /dev/null
+++ b/src/main/org/insa/drawing/BasicDrawing.java
@@ -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 pts = arc.getPoints();
+ if (!pts.isEmpty()) {
+ if (palette != null) {
+ setColor(palette.getColorForType(arc.getInfo().getType()));
+ setWidth(palette.getWidthForType(arc.getInfo().getType()));
+ }
+ Iterator 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();
+ }
+
+}
diff --git a/src/main/org/insa/drawing/graph/BasicGraphPalette.java b/src/main/org/insa/drawing/BasicGraphPalette.java
similarity index 98%
rename from src/main/org/insa/drawing/graph/BasicGraphPalette.java
rename to src/main/org/insa/drawing/BasicGraphPalette.java
index 5bef312..2d82f04 100644
--- a/src/main/org/insa/drawing/graph/BasicGraphPalette.java
+++ b/src/main/org/insa/drawing/BasicGraphPalette.java
@@ -1,4 +1,4 @@
-package org.insa.drawing.graph;
+package org.insa.drawing;
import java.awt.Color;
diff --git a/src/main/org/insa/drawing/graph/BlackAndWhiteGraphPalette.java b/src/main/org/insa/drawing/BlackAndWhiteGraphPalette.java
similarity index 94%
rename from src/main/org/insa/drawing/graph/BlackAndWhiteGraphPalette.java
rename to src/main/org/insa/drawing/BlackAndWhiteGraphPalette.java
index d2066b6..2d095d5 100644
--- a/src/main/org/insa/drawing/graph/BlackAndWhiteGraphPalette.java
+++ b/src/main/org/insa/drawing/BlackAndWhiteGraphPalette.java
@@ -1,4 +1,4 @@
-package org.insa.drawing.graph;
+package org.insa.drawing;
import java.awt.Color;
diff --git a/src/main/org/insa/drawing/Drawing.java b/src/main/org/insa/drawing/Drawing.java
index ce6c8c9..0ab4927 100644
--- a/src/main/org/insa/drawing/Drawing.java
+++ b/src/main/org/insa/drawing/Drawing.java
@@ -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 {
-
- /**
- *
- */
- 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;
-
- /**
- * Cree et affiche une nouvelle fenetre de dessin.
- */
- 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 interface Drawing {
/**
- * Return the longitude and latitude corresponding to the given
- * position of the MouseEvent.
- *
- * @param event
- *
- * @return
+ * Clear the drawing.
*/
- 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);
- }
+ public void clear();
- 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.doAutoPaint();
- }
-
- 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();
- }
-
- 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 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);
+
}
diff --git a/src/main/org/insa/drawing/graph/GraphPalette.java b/src/main/org/insa/drawing/GraphPalette.java
similarity index 95%
rename from src/main/org/insa/drawing/graph/GraphPalette.java
rename to src/main/org/insa/drawing/GraphPalette.java
index 51d8d77..13ae445 100644
--- a/src/main/org/insa/drawing/graph/GraphPalette.java
+++ b/src/main/org/insa/drawing/GraphPalette.java
@@ -1,4 +1,4 @@
-package org.insa.drawing.graph;
+package org.insa.drawing;
import java.awt.Color;
diff --git a/src/main/org/insa/drawing/MapViewDrawing.java b/src/main/org/insa/drawing/MapViewDrawing.java
new file mode 100644
index 0000000..61438af
--- /dev/null
+++ b/src/main/org/insa/drawing/MapViewDrawing.java
@@ -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 idToNames = new HashMap();
+ 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 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);
+ }
+
+}
diff --git a/src/main/org/insa/drawing/graph/GraphDrawing.java b/src/main/org/insa/drawing/graph/GraphDrawing.java
deleted file mode 100644
index e64a001..0000000
--- a/src/main/org/insa/drawing/graph/GraphDrawing.java
+++ /dev/null
@@ -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 pts = arc.getPoints();
- if (!pts.isEmpty()) {
- if (autoColorAndWidth) {
- drawing.setColor(palette.getColorForType(arc.getInfo().getType()));
- drawing.setWidth(palette.getWidthForType(arc.getInfo().getType()));
- }
- Iterator 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);
- }
- }
- }
-
-}
diff --git a/src/main/org/insa/drawing/graph/PathDrawing.java b/src/main/org/insa/drawing/graph/PathDrawing.java
deleted file mode 100644
index 3ff6b03..0000000
--- a/src/main/org/insa/drawing/graph/PathDrawing.java
+++ /dev/null
@@ -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();
- }
-
-}
diff --git a/src/main/org/insa/graph/io/BinaryGraphReader.java b/src/main/org/insa/graph/io/BinaryGraphReader.java
index 8d4eecc..0be885b 100644
--- a/src/main/org/insa/graph/io/BinaryGraphReader.java
+++ b/src/main/org/insa/graph/io/BinaryGraphReader.java
@@ -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());
diff --git a/src/main/org/insa/graph/io/BinaryGraphReaderV2.java b/src/main/org/insa/graph/io/BinaryGraphReaderV2.java
new file mode 100644
index 0000000..597d3a7
--- /dev/null
+++ b/src/main/org/insa/graph/io/BinaryGraphReaderV2.java
@@ -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 nodes = new ArrayList(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 points = new ArrayList(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 rPoints = new ArrayList(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());
+ }
+
+}