No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MapViewDrawing.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. package org.insa.graphics.drawing.components;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.awt.Graphics2D;
  5. import java.awt.Image;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.ArrayList;
  11. import java.util.UUID;
  12. import org.insa.graph.Arc;
  13. import org.insa.graph.Graph;
  14. import org.insa.graph.Path;
  15. import org.insa.graph.Point;
  16. import org.insa.graphics.drawing.Drawing;
  17. import org.insa.graphics.drawing.DrawingClickListener;
  18. import org.insa.graphics.drawing.GraphPalette;
  19. import org.insa.graphics.drawing.overlays.MarkerAutoScaling;
  20. import org.insa.graphics.drawing.overlays.MarkerOverlay;
  21. import org.insa.graphics.drawing.overlays.MarkerUtils;
  22. import org.insa.graphics.drawing.overlays.Overlay;
  23. import org.insa.graphics.drawing.overlays.PathOverlay;
  24. import org.insa.graphics.drawing.overlays.PointSetOverlay;
  25. import org.insa.graphics.drawing.overlays.PolylineAutoScaling;
  26. import org.mapsforge.core.graphics.GraphicFactory;
  27. import org.mapsforge.core.model.BoundingBox;
  28. import org.mapsforge.core.model.LatLong;
  29. import org.mapsforge.core.model.MapPosition;
  30. import org.mapsforge.core.util.LatLongUtils;
  31. import org.mapsforge.core.util.Parameters;
  32. import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
  33. import org.mapsforge.map.awt.util.AwtUtil;
  34. import org.mapsforge.map.awt.view.MapView;
  35. import org.mapsforge.map.datastore.MapDataStore;
  36. import org.mapsforge.map.layer.Layer;
  37. import org.mapsforge.map.layer.Layers;
  38. import org.mapsforge.map.layer.cache.TileCache;
  39. import org.mapsforge.map.layer.hills.HillsRenderConfig;
  40. import org.mapsforge.map.layer.overlay.Marker;
  41. import org.mapsforge.map.layer.renderer.TileRendererLayer;
  42. import org.mapsforge.map.model.DisplayModel;
  43. import org.mapsforge.map.model.MapViewPosition;
  44. import org.mapsforge.map.model.Model;
  45. import org.mapsforge.map.reader.MapFile;
  46. import org.mapsforge.map.rendertheme.InternalRenderTheme;
  47. /**
  48. *
  49. */
  50. public class MapViewDrawing extends MapView implements Drawing {
  51. /**
  52. *
  53. */
  54. private static final long serialVersionUID = 8606967833704938092L;
  55. /**
  56. * Base Overlay for MapViewDrawing overlays.
  57. *
  58. */
  59. private abstract class MapViewOverlay implements Overlay {
  60. // Marker associated.
  61. protected Layer[] layers;
  62. // Current color
  63. protected Color color;
  64. public MapViewOverlay(Layer[] layers, Color color) {
  65. this.layers = layers;
  66. for (Layer layer: this.layers) {
  67. MapViewDrawing.this.getLayerManager().getLayers().add(layer);
  68. }
  69. this.color = color;
  70. }
  71. @Override
  72. public void setColor(Color color) {
  73. this.color = color;
  74. }
  75. @Override
  76. public Color getColor() {
  77. return this.color;
  78. }
  79. @Override
  80. public void setVisible(boolean visible) {
  81. for (Layer layer: layers) {
  82. layer.setVisible(visible);
  83. }
  84. }
  85. @Override
  86. public boolean isVisible() {
  87. if (this.layers.length == 0) {
  88. return true;
  89. }
  90. return this.layers[0].isVisible();
  91. }
  92. @Override
  93. public void delete() {
  94. Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers();
  95. for (Layer layer: layers) {
  96. mlayers.remove(layer);
  97. }
  98. }
  99. @Override
  100. public void redraw() {
  101. MapViewDrawing.this.getLayerManager().redrawLayers();
  102. }
  103. };
  104. /**
  105. * MarkerOverlay for MapViewDrawing.
  106. *
  107. */
  108. private class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay {
  109. private final AlphaMode alphaMode;
  110. private Color innerColor;
  111. public MapViewMarkerOverlay(Marker marker, Color outer, Color innerColor,
  112. AlphaMode alphaMode) {
  113. super(new Layer[] { marker }, outer);
  114. this.innerColor = innerColor;
  115. this.alphaMode = alphaMode;
  116. }
  117. @Override
  118. public Point getPoint() {
  119. Marker marker = (Marker) super.layers[0];
  120. return new Point((float) marker.getLatLong().getLongitude(),
  121. (float) marker.getLatLong().getLatitude());
  122. }
  123. @Override
  124. public void setColor(Color outer) {
  125. this.innerColor = this.innerColor.equals(this.color) ? outer : this.innerColor;
  126. super.setColor(color);
  127. MarkerAutoScaling marker = (MarkerAutoScaling) super.layers[0];
  128. marker.setImage(MarkerUtils.getMarkerForColor(color, this.innerColor, this.alphaMode));
  129. }
  130. @Override
  131. public void moveTo(Point point) {
  132. MarkerAutoScaling marker = (MarkerAutoScaling) this.layers[0];
  133. this.delete();
  134. marker = new MarkerAutoScaling(convertPoint(point), marker.getImage());
  135. this.layers[0] = marker;
  136. MapViewDrawing.this.getLayerManager().getLayers().add(marker);
  137. }
  138. };
  139. /**
  140. * PathOverlay for MapViewDrawing.
  141. *
  142. */
  143. private class MapViewPathOverlay extends MapViewOverlay implements PathOverlay {
  144. public MapViewPathOverlay(PolylineAutoScaling path, MarkerAutoScaling origin,
  145. MarkerAutoScaling destination) {
  146. super(new Layer[] { path, origin, destination }, path.getColor());
  147. }
  148. public MapViewPathOverlay(PolylineAutoScaling path) {
  149. super(new Layer[] { path }, path.getColor());
  150. }
  151. @Override
  152. public void setColor(Color color) {
  153. super.setColor(color);
  154. ((PolylineAutoScaling) this.layers[0]).setColor(color);
  155. ((MarkerAutoScaling) this.layers[1])
  156. .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT));
  157. ((MarkerAutoScaling) this.layers[2])
  158. .setImage(MarkerUtils.getMarkerForColor(color, color, AlphaMode.TRANSPARENT));
  159. }
  160. }
  161. /**
  162. * PointSetOverlay for MapViewDrawing - Not currently implemented.
  163. *
  164. */
  165. private class MapViewPointSetOverlay extends MapViewOverlay implements PointSetOverlay {
  166. public MapViewPointSetOverlay() {
  167. super(new Layer[0], Color.BLACK);
  168. }
  169. @Override
  170. public void setWidth(int width) {
  171. }
  172. @Override
  173. public void setWidthAndColor(int width, Color color) {
  174. setWidth(width);
  175. setColor(color);
  176. }
  177. @Override
  178. public void addPoint(Point point) {
  179. }
  180. @Override
  181. public void addPoint(Point point, int width) {
  182. setWidth(width);
  183. addPoint(point);
  184. }
  185. @Override
  186. public void addPoint(Point point, Color color) {
  187. setColor(color);
  188. addPoint(point);
  189. }
  190. @Override
  191. public void addPoint(Point point, int width, Color color) {
  192. setWidth(width);
  193. setColor(color);
  194. addPoint(point);
  195. }
  196. };
  197. // Default path color.
  198. public static final Color DEFAULT_PATH_COLOR = new Color(66, 134, 244);
  199. // Graphic factory.
  200. private static final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE;
  201. // Default tile size.
  202. private static final int DEFAULT_TILE_SIZE = 512;
  203. // List of listeners.
  204. private ArrayList<DrawingClickListener> drawingClickListeners = new ArrayList<>();
  205. // Tile size
  206. private int tileSize;
  207. // Zoom controls
  208. private MapZoomControls zoomControls;
  209. public MapViewDrawing() {
  210. super();
  211. Parameters.NUMBER_OF_THREADS = 2;
  212. Parameters.SQUARE_FRAME_BUFFER = false;
  213. getMapScaleBar().setVisible(true);
  214. DisplayModel model = getModel().displayModel;
  215. this.tileSize = DEFAULT_TILE_SIZE;
  216. model.setFixedTileSize(this.tileSize);
  217. this.setZoomLevelMin((byte) 0);
  218. this.setZoomLevelMax((byte) 20);
  219. // Try...
  220. try {
  221. this.zoomControls = new MapZoomControls(this, 0, 0, 20);
  222. this.zoomControls.addZoomInListener(new ActionListener() {
  223. @Override
  224. public void actionPerformed(ActionEvent e) {
  225. getModel().mapViewPosition.zoomIn();
  226. }
  227. });
  228. this.zoomControls.addZoomOutListener(new ActionListener() {
  229. @Override
  230. public void actionPerformed(ActionEvent e) {
  231. getModel().mapViewPosition.zoomOut();
  232. }
  233. });
  234. }
  235. catch (IOException e) {
  236. e.printStackTrace();
  237. }
  238. }
  239. /*
  240. * (non-Javadoc)
  241. *
  242. * @see org.mapsforge.map.awt.view.MapView#paint(java.awt.Graphics)
  243. */
  244. @Override
  245. public void paint(Graphics graphics) {
  246. super.paint(graphics);
  247. if (this.zoomControls != null) {
  248. this.zoomControls.setZoomLevel(this.getModel().mapViewPosition.getZoomLevel());
  249. this.zoomControls.draw((Graphics2D) graphics,
  250. getWidth() - this.zoomControls.getWidth() - 20,
  251. this.getHeight() - this.zoomControls.getHeight() - 10, this);
  252. }
  253. }
  254. /*
  255. * (non-Javadoc)
  256. *
  257. * @see org.insa.graphics.drawing.Drawing#clear()
  258. */
  259. @Override
  260. public void clear() {
  261. getLayerManager().getLayers().clear();
  262. repaint();
  263. }
  264. /*
  265. * (non-Javadoc)
  266. *
  267. * @see org.insa.graphics.drawing.Drawing#clearOverlays()
  268. */
  269. @Override
  270. public void clearOverlays() {
  271. Layers layers = getLayerManager().getLayers();
  272. for (Layer layer: layers) {
  273. if (layer instanceof PolylineAutoScaling || layer instanceof MarkerAutoScaling) {
  274. getLayerManager().getLayers().remove(layer, false);
  275. }
  276. }
  277. repaint();
  278. }
  279. protected LatLong convertPoint(Point point) {
  280. return new LatLong(point.getLatitude(), point.getLongitude());
  281. }
  282. private TileRendererLayer createTileRendererLayer(TileCache tileCache,
  283. MapDataStore mapDataStore, MapViewPosition mapViewPosition,
  284. HillsRenderConfig hillsRenderConfig) {
  285. TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore,
  286. mapViewPosition, false, true, false, GRAPHIC_FACTORY, hillsRenderConfig) {
  287. @Override
  288. public boolean onTap(LatLong tapLatLong, org.mapsforge.core.model.Point layerXY,
  289. org.mapsforge.core.model.Point tapXY) {
  290. if (zoomControls.contains(new java.awt.Point((int) tapXY.x, (int) tapXY.y))) {
  291. return false;
  292. }
  293. Point pt = new Point((float) tapLatLong.getLongitude(),
  294. (float) tapLatLong.getLatitude());
  295. for (DrawingClickListener listener: MapViewDrawing.this.drawingClickListeners) {
  296. listener.mouseClicked(pt);
  297. }
  298. return true;
  299. }
  300. };
  301. tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.DEFAULT);
  302. return tileRendererLayer;
  303. }
  304. @Override
  305. public void addDrawingClickListener(DrawingClickListener listener) {
  306. this.drawingClickListeners.add(listener);
  307. }
  308. @Override
  309. public void removeDrawingClickListener(DrawingClickListener listener) {
  310. this.drawingClickListeners.remove(listener);
  311. }
  312. protected MarkerAutoScaling createMarker(Point point, Color outer, Color inner,
  313. AlphaMode mode) {
  314. Image image = MarkerUtils.getMarkerForColor(outer, inner, mode);
  315. return new MarkerAutoScaling(convertPoint(point), image);
  316. }
  317. @Override
  318. public MarkerOverlay drawMarker(Point point, Color outer, Color inner, AlphaMode mode) {
  319. return new MapViewMarkerOverlay(createMarker(point, outer, inner, mode), outer, inner,
  320. mode);
  321. }
  322. @Override
  323. public PointSetOverlay createPointSetOverlay() {
  324. return new MapViewPointSetOverlay();
  325. }
  326. @Override
  327. public PointSetOverlay createPointSetOverlay(int width, Color color) {
  328. PointSetOverlay ps = new MapViewPointSetOverlay();
  329. ps.setWidthAndColor(width, color);
  330. return ps;
  331. }
  332. public void drawGraph(File file) {
  333. // Tile cache
  334. TileCache tileCache = AwtUtil.createTileCache(tileSize,
  335. getModel().frameBufferModel.getOverdrawFactor(), 1024,
  336. new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()));
  337. // Layers
  338. Layers layers = getLayerManager().getLayers();
  339. MapDataStore mapDataStore = new MapFile(file);
  340. TileRendererLayer tileRendererLayer = createTileRendererLayer(tileCache, mapDataStore,
  341. getModel().mapViewPosition, null);
  342. layers.add(tileRendererLayer);
  343. BoundingBox boundingBox = mapDataStore.boundingBox();
  344. final Model model = getModel();
  345. if (model.mapViewPosition.getZoomLevel() == 0
  346. || !boundingBox.contains(model.mapViewPosition.getCenter())) {
  347. byte zoomLevel = LatLongUtils.zoomForBounds(model.mapViewDimension.getDimension(),
  348. boundingBox, model.displayModel.getTileSize());
  349. model.mapViewPosition
  350. .setMapPosition(new MapPosition(boundingBox.getCenterPoint(), zoomLevel));
  351. zoomControls.setZoomLevel(zoomLevel);
  352. }
  353. }
  354. @Override
  355. public void drawGraph(Graph graph, GraphPalette palette) {
  356. throw new RuntimeException("Not implemented, use drawGraph(File).");
  357. }
  358. @Override
  359. public void drawGraph(Graph graph) {
  360. throw new RuntimeException("Not implemented, use drawGraph(File).");
  361. }
  362. @Override
  363. public PathOverlay drawPath(Path path, Color color, boolean markers) {
  364. PolylineAutoScaling line = new PolylineAutoScaling(1, color);
  365. ArrayList<Point> points = new ArrayList<>(path.getArcs().size() * 4);
  366. for (Arc arc: path.getArcs()) {
  367. points.addAll(arc.getPoints());
  368. }
  369. line.addAll(points);
  370. PathOverlay overlay = null;
  371. if (markers) {
  372. MarkerAutoScaling origin = createMarker(path.getOrigin().getPoint(), color, color,
  373. AlphaMode.TRANSPARENT),
  374. destination = createMarker(path.getDestination().getPoint(), color, color,
  375. AlphaMode.TRANSPARENT);
  376. overlay = new MapViewPathOverlay(line, origin, destination);
  377. }
  378. else {
  379. overlay = new MapViewPathOverlay(line);
  380. }
  381. return overlay;
  382. }
  383. @Override
  384. public PathOverlay drawPath(Path path, Color color) {
  385. return drawPath(path, color, true);
  386. }
  387. @Override
  388. public PathOverlay drawPath(Path path) {
  389. return drawPath(path, DEFAULT_PATH_COLOR, true);
  390. }
  391. @Override
  392. public PathOverlay drawPath(Path path, boolean markers) {
  393. return drawPath(path, DEFAULT_PATH_COLOR, markers);
  394. }
  395. }