package net.osmand.swing; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import net.osmand.data.DataTileManager; import net.osmand.osm.Entity; import net.osmand.osm.MapUtils; import net.osmand.osm.Node; import net.osmand.osm.Way; public class MapPointsLayer implements MapPanelLayer { private MapPanel map; // special points to draw private DataTileManager<? extends Entity> points; private Color color = Color.black; private int size = 3; private String tagToShow = null; private Map<Point, String> pointsToDraw = new LinkedHashMap<Point, String>(); private List<Line2D> linesToDraw = new ArrayList<Line2D>(); @Override public void destroyLayer() { } @Override public void initLayer(MapPanel map) { this.map = map; } public void setColor(Color color){ this.color = color; } public void setPointSize(int size){ this.size = size; } public void setTagToShow(String tag) { this.tagToShow = tag; } @Override public void paintLayer(Graphics g) { g.setColor(color); // draw user points for (Point p : pointsToDraw.keySet()) { g.drawOval(p.x, p.y, size, size); g.fillOval(p.x, p.y, size, size); if(tagToShow != null && pointsToDraw.get(p) != null){ g.drawString(pointsToDraw.get(p), p.x, p.y); } } g.setColor(color); // draw user points int[] xPoints = new int[4]; int[] yPoints = new int[4]; for (Line2D p : linesToDraw) { AffineTransform transform = new AffineTransform(); transform.translate(p.getX1(), p.getY1()); transform.rotate(p.getX2() - p.getX1(), p.getY2() - p.getY1()); xPoints[1] = xPoints[0] = 0; xPoints[2] = xPoints[3] = (int) Math.sqrt((p.getX2() - p.getX1())*(p.getX2() - p.getX1()) + (p.getY2() - p.getY1())*(p.getY2() - p.getY1())) +1; yPoints[3] = yPoints[0] = 0; yPoints[2] = yPoints[1] = 2; for(int i=0; i< 4; i++){ Point2D po = transform.transform(new Point(xPoints[i], yPoints[i]), null); xPoints[i] = (int) po.getX(); yPoints[i] = (int) po.getY(); } g.drawPolygon(xPoints, yPoints, 4); g.fillPolygon(xPoints, yPoints, 4); } } @Override public void prepareToDraw() { if (points != null) { double xTileLeft = map.getXTile() - map.getCenterPointX() / map.getTileSize(); double xTileRight = map.getXTile() + map.getCenterPointX() / map.getTileSize(); double yTileUp = map.getYTile() - map.getCenterPointY() / map.getTileSize(); double yTileDown = map.getYTile() + map.getCenterPointY() / map.getTileSize(); double latDown = MapUtils.getLatitudeFromTile(map.getZoom(), yTileDown); double longDown = MapUtils.getLongitudeFromTile(map.getZoom(), xTileRight); double latUp = MapUtils.getLatitudeFromTile(map.getZoom(), yTileUp); double longUp = MapUtils.getLongitudeFromTile(map.getZoom(), xTileLeft); List<? extends Entity> objects = points.getObjects(latUp, longUp, latDown, longDown); pointsToDraw.clear(); linesToDraw.clear(); for (Entity e : objects) { if(e instanceof Way){ List<Node> nodes = ((Way)e).getNodes(); if (nodes.size() > 1) { int prevPixX = 0; int prevPixY = 0; for (int i = 0; i < nodes.size(); i++) { Node n = nodes.get(i); int pixX = (int) (MapUtils.getPixelShiftX(map.getZoom(), n.getLongitude(), map.getLongitude(), map.getTileSize()) + map.getCenterPointX()); int pixY = (int) (MapUtils.getPixelShiftY(map.getZoom(), n.getLatitude(), map.getLatitude(), map.getTileSize()) + map.getCenterPointY()); if (i > 0) { linesToDraw.add(new Line2D.Float(pixX, pixY, prevPixX, prevPixY)); } prevPixX = pixX; prevPixY = pixY; } } } else if(e instanceof Node){ Node n = (Node) e; int pixX = (int) (MapUtils.getPixelShiftX(map.getZoom(), n.getLongitude(), map.getLongitude(), map.getTileSize()) + map.getCenterPointX()); int pixY = (int) (MapUtils.getPixelShiftY(map.getZoom(), n.getLatitude(), map.getLatitude(), map.getTileSize()) + map.getCenterPointY()); if (pixX >= 0 && pixY >= 0) { pointsToDraw.put(new Point(pixX, pixY), n.getTag(tagToShow)); } } else { } } } } public DataTileManager<? extends Entity> getPoints() { return points; } public void setPoints(DataTileManager<? extends Entity> points) { this.points = points; } }