Skip to content

Commit 6eabaad

Browse files
committed
OSM Viewer with pan and zoom functionality added.
1 parent 93b997f commit 6eabaad

File tree

3 files changed

+106
-16
lines changed

3 files changed

+106
-16
lines changed

aimax-osm/src/main/java/aimax/osm/gui/fx/applications/OsmViewerApp.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
import aimax.osm.data.DataResource;
44
import aimax.osm.gui.fx.viewer.MapPaneCtrl;
55
import javafx.application.Application;
6-
import javafx.geometry.Insets;
76
import javafx.scene.Scene;
8-
import javafx.scene.control.Button;
9-
import javafx.scene.layout.*;
10-
import javafx.scene.paint.Color;
7+
import javafx.scene.layout.BorderPane;
8+
import javafx.scene.layout.StackPane;
119
import javafx.stage.Stage;
1210

1311
import java.util.Locale;
1412

15-
import static javafx.scene.paint.Color.*;
16-
1713
/**
18-
* Created by rlunde on 03.11.2016.
14+
* Shows a map of the city of Ulm with pan and zoom functionality (mouse drag, mouse wheel, arrow keys,
15+
* plus and minus keys). Set markers with Mouse-Left and remove them with Mouse-Right. Symbols can be changed in size
16+
* by zooming with Ctrl-Button pressed.
17+
*
18+
* @author Ruediger Lunde
1919
*/
2020
public class OsmViewerApp extends Application {
2121
public static void main(String[] args) {
@@ -36,7 +36,6 @@ public void start(Stage primaryStage) throws Exception {
3636

3737
BorderPane root = new BorderPane();
3838
root.setCenter(mapPane);
39-
root.setBottom(new Button("XYZ"));
4039
Scene scene = new Scene(root, 800, 600);
4140

4241
primaryStage.setTitle("Osm Viewer App");

aimax-osm/src/main/java/aimax/osm/gui/fx/viewer/FXImageBuilder.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
9292

9393
@Override
9494
public void drawString(String text, int x, int y) {
95-
gc.strokeText(text, x, y);
95+
gc.fillText(text, x, y);
9696

9797
}
9898

@@ -107,7 +107,6 @@ public void setColor(UColor color) {
107107
color.getBlue(), color.getAlpha() / 255.0));
108108
gc.setFill(Color.rgb(color.getRed(), color.getGreen(),
109109
color.getBlue(), color.getAlpha() / 255.0));
110-
111110
}
112111

113112
@Override
@@ -117,7 +116,7 @@ public void setLineStyle(boolean dashed, float width) {
117116
dash = new float[] { width * 2f };
118117
}
119118
gc.setLineWidth(width);
120-
gc.setLineDashes(new double[] {5, 5});
119+
gc.setLineDashes(new double[] {10, 10});
121120
gc.setLineJoin(StrokeLineJoin.ROUND);
122121
}
123122

aimax-osm/src/main/java/aimax/osm/gui/fx/viewer/MapPaneCtrl.java

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import aimax.osm.viewer.CoordTransformer;
77
import aimax.osm.viewer.UnifiedMapDrawer;
88
import javafx.scene.canvas.Canvas;
9+
import javafx.scene.input.*;
910
import javafx.scene.layout.StackPane;
1011

1112
import java.io.InputStream;
@@ -20,12 +21,20 @@ public class MapPaneCtrl {
2021
private Canvas osCanvas;
2122

2223
private UnifiedMapDrawer<Canvas> mapDrawer;
24+
private boolean scaleToFit = true;
2325

2426
public MapPaneCtrl(StackPane pane) {
2527
this.pane = pane;
2628
mapDrawer = new UnifiedMapDrawer<Canvas>(new FXImageBuilder(), createMap());
27-
pane.widthProperty().addListener((obs, o, n) -> update());
28-
pane.heightProperty().addListener((obs, o, n) -> update());
29+
mapDrawer.getMap().addMapDataEventListener(ev -> update());
30+
pane.widthProperty().addListener((obs, o, n) -> { scaleToFit = true; update(); });
31+
pane.heightProperty().addListener((obs, o, n) -> { scaleToFit = true; update(); });
32+
pane.setOnMouseEntered(ev -> {if (currCanvas != null) currCanvas.requestFocus();});
33+
pane.setOnMousePressed(ev -> handleMouseEvent(ev));
34+
pane.setOnMouseDragged(ev -> handleMouseEvent(ev));
35+
pane.setOnMouseClicked(ev -> handleMouseEvent(ev));
36+
pane.setOnScroll(ev -> handleScrollEvent(ev));
37+
pane.setOnKeyPressed(ev -> handleKeyEvent(ev));
2938
pane.setMinSize(0, 0);
3039
}
3140

@@ -37,6 +46,7 @@ public OsmMap getMap() {
3746

3847
public void loadMap(InputStream stream) {
3948
mapDrawer.loadMap(stream);
49+
scaleToFit = true;
4050
}
4151

4252
public AbstractEntityRenderer getRenderer() {
@@ -50,19 +60,101 @@ public AbstractEntityRenderer getRenderer() {
5060
public void update() {
5161
Canvas canvas = osCanvas;
5262
if (canvas == null
53-
|| Math.round(canvas.getWidth()) != pane.getWidth()
54-
|| Math.round(canvas.getHeight()) != pane.getWidth()) {
63+
|| Math.abs(canvas.getWidth() - pane.getWidth()) > 0.01
64+
|| Math.abs(canvas.getHeight() - pane.getHeight()) > 0.1) {
5565
canvas = new Canvas(pane.getWidth(), pane.getHeight());
66+
canvas.setFocusTraversable(true);
5667
}
57-
mapDrawer.drawMap(canvas, true);
68+
mapDrawer.drawMap(canvas, scaleToFit);
5869
pane.getChildren().add(canvas);
5970
if (pane.getChildren().size() > 1)
6071
pane.getChildren().remove(0);
6172
osCanvas = currCanvas;
6273
currCanvas = canvas;
74+
scaleToFit = false;
6375
}
6476

77+
/**
78+
* Multiples the current scale with the specified factor and adjusts the
79+
* view so that the objects shown at the specified view focus keep at their
80+
* position.
81+
*/
82+
public void zoom(float factor, int focusX, int focusY) {
83+
getTransformer().zoom(factor, focusX, focusY);
84+
// paintPreview((int) ((1 - factor) * focusX),
85+
// (int) ((1 - factor) * focusY), factor);
86+
update();
87+
}
6588

89+
public void multiplyDisplayFactorWith(float fac) {
90+
getRenderer().setDisplayFactor(getRenderer().getDisplayFactor() * fac);
91+
update();
92+
}
6693

94+
/**
95+
* Adjusts the view.
96+
*
97+
* @param dx
98+
* Number of pixels for horizontal shift.
99+
* @param dy
100+
* Number of pixels for vertical shift.
101+
*/
102+
public void adjust(double dx, double dy) {
103+
getTransformer().adjust((int) dx, (int) dy);
104+
//paintPreview(dx, dy, 1f);
105+
update();
106+
}
67107

108+
private double xDrag;
109+
private double yDrag;
110+
private boolean dragActive;
111+
112+
protected void handleMouseEvent(MouseEvent event) {
113+
if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
114+
xDrag = event.getX();
115+
yDrag = event.getY();
116+
dragActive = false;
117+
} else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
118+
adjust(event.getX() - xDrag, event.getY() - yDrag);
119+
xDrag = event.getX();
120+
yDrag = event.getY();
121+
dragActive = true;
122+
} else if (event.getEventType() == MouseEvent.MOUSE_CLICKED && !dragActive) {
123+
if (event.getButton() == MouseButton.PRIMARY) {
124+
CoordTransformer tr = getTransformer();
125+
getMap().addMarker(tr.lat((int) event.getY()), tr.lon((int) event.getX()));
126+
} else if (event.getButton() == MouseButton.SECONDARY) {
127+
getMap().clearMarkersAndTracks();
128+
}
129+
}
130+
}
131+
132+
protected void handleScrollEvent(ScrollEvent event) {
133+
float fac = event.getDeltaY() > 0 ? 1.2f : 1.0f / 1.2f;
134+
if (event.isControlDown())
135+
multiplyDisplayFactorWith(fac);
136+
else
137+
zoom(fac, (int) event.getX(), (int) event.getY());
138+
}
139+
140+
protected void handleKeyEvent(KeyEvent event) {
141+
if (event.getCode() == KeyCode.LEFT)
142+
adjust(30, 0);
143+
else if (event.getCode() == KeyCode.RIGHT)
144+
adjust(-30, 0);
145+
else if (event.getCode() == KeyCode.UP)
146+
adjust(0, 30);
147+
else if (event.getCode() == KeyCode.DOWN)
148+
adjust(0, -30);
149+
else if (event.getCode() == KeyCode.PLUS)
150+
if (event.isControlDown())
151+
multiplyDisplayFactorWith(1.5f);
152+
else
153+
zoom(1.5f, (int) pane.getWidth() / 2, (int) pane.getHeight() / 2);
154+
else if (event.getCode() == KeyCode.MINUS)
155+
if (event.isControlDown())
156+
multiplyDisplayFactorWith(1.0f/1.5f);
157+
else
158+
zoom(0.7f, (int) pane.getWidth() / 2, (int) pane.getHeight() / 2);
159+
}
68160
}

0 commit comments

Comments
 (0)