Skip to content

Commit 93b997f

Browse files
committed
First simple FX-based map viewers added.
1 parent e8a4862 commit 93b997f

25 files changed

+3020
-2646
lines changed

aimax-osm/README.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The framework provides interfaces for central parts of the system and additional
1212
example implementations. In the current version, the fundamental data structures
1313
for nodes, ways, and the map itself can be replaced. The framework supports experiments
1414
with different implementations to optimize routing and also to integrate a database
15-
version of the map representation. The application <code>aimax.osm.applications.MiniNaviApp</code>
15+
version of the map representation. The application <code>aimax.osm.gui.swing.applications.MiniNaviApp</code>
1616
demonstrates how to plug the components together and provides means to integrate and test
1717
own versions of the needed components.
1818

@@ -42,7 +42,7 @@ cities like Berlin can be loaded and displayed without any problem if enough
4242
heap space is provided (VM argument -Xmx500M).
4343

4444
Getting started: Run one of the applications in the
45-
<code>aimax.osm.applications</code> package. If no map is displayed
45+
<code>aimax.osm.gui.swing.applications</code> package. If no map is displayed
4646
by default, make sure that the main/resource folder is included
4747
in the build path of your project, recompile and start again.
4848
Then, place the mouse inside the map viewer pane. Try mouse-left, mouse-right,
@@ -128,17 +128,17 @@ Under the release/ directory you should find three jar files, aima-core.jar, aim
128128
Ensure these are on your CLASSPATH, the different GUI programs that can be run using these are:
129129
* java -jar aimax-osm.jar
130130
+ this will run the default OsmAimaDemoApp, this allows you to run applications and demos from the aima-gui project as well as some of the applications provided in this project.
131-
* java -classpath aimax-osm.jar aimax.osm.applications.OsmViewerApp
131+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.OsmViewerApp
132132
+ just the plain viewer (not dependent on AIMA)
133-
* java -classpath aimax-osm.jar aimax.osm.applications.OsmViewerPlusApp
133+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.OsmViewerPlusApp
134134
+ demonstrates, how to configure and extend the viewer
135-
* java -classpath aimax-osm.jar aimax.osm.applications.RoutePlannerApp
135+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.RoutePlannerApp
136136
+ uses aima-core search functionality for routing in OSM maps
137-
* java -classpath aimax-osm.jar aimax.osm.applications.OsmAgentApp
137+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.OsmAgentApp
138138
+ lets map agents from aima-core act in map environments which are defined by OSM data
139-
* java -classpath aimax-osm.jar aimax.osm.applications.SearchDemoOsmAgentApp
139+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.SearchDemoOsmAgentApp
140140
+ visualizes simulated search space exploration of different search strategies
141-
* java -classpath aimax-osm.jar aimax.osm.applications.MiniNaviApp
141+
* java -classpath aimax-osm.jar aimax.osm.gui.swing.applications.MiniNaviApp
142142
+ provides a base for car navigation system development
143143

144144
It is recommended to start the applications with VM argument -Xmx500m (or higher value) and

aimax-osm/build.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<import file="${path.to.aima-gui.project}/build.xml"/>
88

9-
<property name="aimax-osm.run" value="aimax.osm.applications.OsmAimaDemoApp" />
9+
<property name="aimax-osm.run" value="aimax.osm.gui.swing.applications.OsmAimaDemoApp" />
1010

1111
<path id="aimax-osm.classpath">
1212
<path refid="aima-gui.classpath" />
@@ -53,7 +53,7 @@
5353
<jar destfile="${aimax-osm.dir.build.release}/aimax-osm.jar">
5454
<manifest>
5555
<attribute name="Class-Path" value="aima-gui.jar commons-compress-1.1.jar" />
56-
<attribute name="Main-Class" value="aimax.osm.applications.OsmViewerApp" />
56+
<attribute name="Main-Class" value="aimax.osm.gui.swing.applications.OsmViewerApp" />
5757
<attribute name="Implementation-Title" value="AIMAX-OSM" />
5858
<attribute name="Implementation-Version" value="${aimax-osm.version}" />
5959
<attribute name="AIMAX-OSM-Version" value="${aimax-osm.version}" />
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package aimax.osm.gui.fx.applications;
2+
3+
import aimax.osm.data.DataResource;
4+
import aimax.osm.gui.fx.viewer.MapPaneCtrl;
5+
import javafx.application.Application;
6+
import javafx.geometry.Insets;
7+
import javafx.scene.Scene;
8+
import javafx.scene.control.Button;
9+
import javafx.scene.layout.*;
10+
import javafx.scene.paint.Color;
11+
import javafx.stage.Stage;
12+
13+
import java.util.Locale;
14+
15+
import static javafx.scene.paint.Color.*;
16+
17+
/**
18+
* Created by rlunde on 03.11.2016.
19+
*/
20+
public class OsmViewerApp extends Application {
21+
public static void main(String[] args) {
22+
launch(args);
23+
}
24+
25+
@Override
26+
public void start(Stage primaryStage) throws Exception {
27+
// indicates progress when reading large maps (for testing only)
28+
// Logger.getLogger("aimax.osm").setLevel(Level.FINEST);
29+
// Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);
30+
31+
Locale.setDefault(Locale.US);
32+
33+
StackPane mapPane = new StackPane();
34+
MapPaneCtrl mapPaneCtrl = new MapPaneCtrl(mapPane);
35+
mapPaneCtrl.loadMap(DataResource.getULMFileResource());
36+
37+
BorderPane root = new BorderPane();
38+
root.setCenter(mapPane);
39+
root.setBottom(new Button("XYZ"));
40+
Scene scene = new Scene(root, 800, 600);
41+
42+
primaryStage.setTitle("Osm Viewer App");
43+
primaryStage.setScene(scene);
44+
primaryStage.show();
45+
}
46+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package aimax.osm.gui.fx.applications;
2+
3+
import aimax.osm.data.DataResource;
4+
import aimax.osm.data.MapBuilder;
5+
import aimax.osm.data.OsmMap;
6+
import aimax.osm.data.impl.DefaultMap;
7+
import aimax.osm.gui.fx.viewer.FXImageBuilder;
8+
import aimax.osm.reader.Bz2OsmReader;
9+
import aimax.osm.reader.MapReader;
10+
import aimax.osm.viewer.MapStyleFactory;
11+
import aimax.osm.viewer.UnifiedMapDrawer;
12+
import javafx.application.Application;
13+
import javafx.scene.Group;
14+
import javafx.scene.Scene;
15+
import javafx.scene.canvas.Canvas;
16+
import javafx.scene.paint.Color;
17+
import javafx.stage.Stage;
18+
19+
import java.util.Locale;
20+
21+
/**
22+
* Simple demo application which shows a stage with the
23+
* map of Ulm, provided that a file with name ulm.osm is found
24+
* in the resource/maps path. No interactions supported here.
25+
*
26+
* @author Ruediger Lunde
27+
*/
28+
public class SimpleOsmViewerApp extends Application {
29+
30+
public static void main(String[] args) {
31+
launch(args);
32+
}
33+
34+
@Override
35+
public void start(Stage primaryStage) throws Exception {
36+
// indicates progress when reading large maps (for testing only)
37+
// Logger.getLogger("aimax.osm").setLevel(Level.FINEST);
38+
// Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);
39+
40+
Locale.setDefault(Locale.US);
41+
42+
UnifiedMapDrawer<Canvas> mapDrawer = new UnifiedMapDrawer<Canvas>(new FXImageBuilder());
43+
mapDrawer.loadMap(DataResource.getULMFileResource());
44+
45+
Canvas canvas = new Canvas(600, 400);
46+
mapDrawer.drawMap(canvas, true);
47+
Group root = new Group();
48+
root.getChildren().add(canvas);
49+
Scene scene = new Scene(root, Color.BLACK);
50+
51+
primaryStage.setTitle("Simple Osm Viewer App");
52+
primaryStage.setScene(scene);
53+
primaryStage.show();
54+
}
55+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package aimax.osm.gui.fx.viewer;
2+
3+
import aimax.osm.viewer.UColor;
4+
import aimax.osm.viewer.UnifiedImageBuilder;
5+
import javafx.scene.canvas.Canvas;
6+
import javafx.scene.canvas.GraphicsContext;
7+
import javafx.scene.paint.Color;
8+
import javafx.scene.shape.StrokeLineJoin;
9+
import javafx.scene.text.Font;
10+
11+
/**
12+
* Specialized image builder for the FX canvas.
13+
*
14+
* @author Ruediger Lunde
15+
*/
16+
public class FXImageBuilder implements UnifiedImageBuilder<Canvas> {
17+
18+
private Canvas result;
19+
private GraphicsContext gc;
20+
boolean areaFillMode;
21+
22+
@Override
23+
public void initialize(Canvas canvas) {
24+
result = canvas;
25+
gc = canvas.getGraphicsContext2D();
26+
initStroke();
27+
}
28+
29+
/** Returns the width of the image under construction. */
30+
@Override
31+
public int getWidth() { return (int) result.getWidth(); }
32+
33+
/** Returns the height of the image under construction. */
34+
@Override
35+
public int getHeight() {
36+
return (int) result.getHeight();
37+
}
38+
39+
@Override
40+
public void drawLine(int x1, int y1, int x2, int y2) {
41+
gc.strokeLine(x1, y1, x2, y2);
42+
}
43+
44+
@Override
45+
public void drawRect(int x, int y, int width, int height) {
46+
initStroke();
47+
if (areaFillMode)
48+
gc.fillRect(x, y, width, height);
49+
else
50+
gc.strokeRect(x, y, width, height);
51+
52+
}
53+
54+
@Override
55+
public void drawOval(int x, int y, int width, int height) {
56+
initStroke();
57+
if (areaFillMode)
58+
gc.fillOval(x, y, width, height);
59+
else
60+
gc.strokeOval(x, y, width, height);
61+
62+
}
63+
64+
@Override
65+
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
66+
double[] xPts = new double[nPoints];
67+
double[] yPts = new double[nPoints];
68+
for (int i = 0; i < nPoints; i++) {
69+
xPts[i] = xPoints[i];
70+
yPts[i] = yPoints[i];
71+
}
72+
initStroke();
73+
gc.strokePolyline(xPts, yPts, nPoints);
74+
75+
}
76+
77+
@Override
78+
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
79+
double[] xPts = new double[nPoints];
80+
double[] yPts = new double[nPoints];
81+
for (int i = 0; i < nPoints; i++) {
82+
xPts[i] = xPoints[i];
83+
yPts[i] = yPoints[i];
84+
}
85+
initStroke();
86+
if (areaFillMode)
87+
gc.fillPolygon(xPts, yPts, nPoints);
88+
else
89+
gc.strokePolygon(xPts, yPts, nPoints);
90+
91+
}
92+
93+
@Override
94+
public void drawString(String text, int x, int y) {
95+
gc.strokeText(text, x, y);
96+
97+
}
98+
99+
@Override
100+
public Canvas getResult() {
101+
return result;
102+
}
103+
104+
@Override
105+
public void setColor(UColor color) {
106+
gc.setStroke(Color.rgb(color.getRed(), color.getGreen(),
107+
color.getBlue(), color.getAlpha() / 255.0));
108+
gc.setFill(Color.rgb(color.getRed(), color.getGreen(),
109+
color.getBlue(), color.getAlpha() / 255.0));
110+
111+
}
112+
113+
@Override
114+
public void setLineStyle(boolean dashed, float width) {
115+
float dash[] = null;
116+
if (dashed) {
117+
dash = new float[] { width * 2f };
118+
}
119+
gc.setLineWidth(width);
120+
gc.setLineDashes(new double[] {5, 5});
121+
gc.setLineJoin(StrokeLineJoin.ROUND);
122+
}
123+
124+
@Override
125+
public void setAreaFilled(boolean value) {
126+
areaFillMode = value;
127+
128+
}
129+
130+
@Override
131+
public void setFontSize(float size) {
132+
gc.setFont(new Font(gc.getFont().getName(), size));
133+
}
134+
135+
@Override
136+
public float getFontSize() { return (float) gc.getFont().getSize();
137+
}
138+
139+
private void initStroke() {
140+
gc.setLineWidth(1);
141+
gc.setLineDashes(null);
142+
gc.setLineJoin(StrokeLineJoin.ROUND);
143+
}
144+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package aimax.osm.gui.fx.viewer;
2+
3+
import aimax.osm.data.OsmMap;
4+
import aimax.osm.data.impl.DefaultMap;
5+
import aimax.osm.viewer.AbstractEntityRenderer;
6+
import aimax.osm.viewer.CoordTransformer;
7+
import aimax.osm.viewer.UnifiedMapDrawer;
8+
import javafx.scene.canvas.Canvas;
9+
import javafx.scene.layout.StackPane;
10+
11+
import java.io.InputStream;
12+
13+
/**
14+
* Created by rlunde on 28.10.2016.
15+
*/
16+
public class MapPaneCtrl {
17+
18+
private StackPane pane;
19+
private Canvas currCanvas;
20+
private Canvas osCanvas;
21+
22+
private UnifiedMapDrawer<Canvas> mapDrawer;
23+
24+
public MapPaneCtrl(StackPane pane) {
25+
this.pane = pane;
26+
mapDrawer = new UnifiedMapDrawer<Canvas>(new FXImageBuilder(), createMap());
27+
pane.widthProperty().addListener((obs, o, n) -> update());
28+
pane.heightProperty().addListener((obs, o, n) -> update());
29+
pane.setMinSize(0, 0);
30+
}
31+
32+
protected OsmMap createMap() { return new DefaultMap(); }
33+
34+
public OsmMap getMap() {
35+
return mapDrawer.getMap();
36+
}
37+
38+
public void loadMap(InputStream stream) {
39+
mapDrawer.loadMap(stream);
40+
}
41+
42+
public AbstractEntityRenderer getRenderer() {
43+
return mapDrawer.getRenderer();
44+
}
45+
46+
public void setRenderer(AbstractEntityRenderer renderer) { mapDrawer.setRenderer(renderer); }
47+
48+
public CoordTransformer getTransformer() { return mapDrawer.getTransformer(); }
49+
50+
public void update() {
51+
Canvas canvas = osCanvas;
52+
if (canvas == null
53+
|| Math.round(canvas.getWidth()) != pane.getWidth()
54+
|| Math.round(canvas.getHeight()) != pane.getWidth()) {
55+
canvas = new Canvas(pane.getWidth(), pane.getHeight());
56+
}
57+
mapDrawer.drawMap(canvas, true);
58+
pane.getChildren().add(canvas);
59+
if (pane.getChildren().size() > 1)
60+
pane.getChildren().remove(0);
61+
osCanvas = currCanvas;
62+
currCanvas = canvas;
63+
}
64+
65+
66+
67+
68+
}

0 commit comments

Comments
 (0)