JXMapViewer (openstreetmap) Drow Directions between 2 point - java

I have this Class That Draws a line between specified points or locations in the map And it works
!
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.jxmapviewer.JXMapKit;
import org.jxmapviewer.JXMapKit.DefaultProviders;
import org.jxmapviewer.JXMapViewer;
import org.jxmapviewer.painter.Painter;
import org.jxmapviewer.viewer.GeoPosition;
public class Starter {
public static void main(final String[] args) {
final JFrame f = new JFrame();
f.setSize(500, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JXMapKit jXMapKit1 = new JXMapKit();
jXMapKit1.setDefaultProvider(DefaultProviders.OpenStreetMaps);
jXMapKit1.setCenterPosition(new GeoPosition(5.41984, 100.33924));
jXMapKit1.setZoom(3);
final List<GeoPosition> region = new ArrayList<GeoPosition>();
region.add(new GeoPosition(5.42031, 100.34389));
region.add(new GeoPosition(5.41984, 100.33924));
region.add(new GeoPosition(5.42300, 100.33456));
final Painter<JXMapViewer> lineOverlay = new Painter<JXMapViewer>() {
#Override
public void paint(Graphics2D g, final JXMapViewer map, final int w, final int h) {
g = (Graphics2D) g.create();
// convert from viewport to world bitmap
final Rectangle rect = jXMapKit1.getMainMap().getViewportBounds();
g.translate(-rect.x, -rect.y);
// do the drawing
g.setColor(Color.RED);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(2));
int lastX = -1;
int lastY = -1;
for (final GeoPosition gp : region) {
// convert geo to world bitmap pixel
final Point2D pt = jXMapKit1.getMainMap().getTileFactory().geoToPixel(gp, jXMapKit1.getMainMap().getZoom());
if (lastX != -1 && lastY != -1) {
g.drawLine(lastX, lastY, (int) pt.getX(), (int) pt.getY());
}
lastX = (int) pt.getX();
lastY = (int) pt.getY();
}
g.dispose();
}
};
jXMapKit1.getMainMap().setOverlayPainter(lineOverlay);
f.setContentPane(jXMapKit1);
f.setVisible(true);
}
}
but I want to draw a route that can follow by car. Not just a straight line that cut across all the building !.
When I select two points on the map, I need to see a suggested path or path to reach, not just a line !
i need like this image
Any Help ?

Related

How to properly create a whole shape from a TextLayout?

How do I create a Shape that rensembles the whole Text/String rather than just the outline?
What I got currently from Shape outline = textTl.getOutline(null);
The problem is that I invoke the drawShadowedShape(outline, g2d); on the outline shape, so the shadow is drawn over the font. But I want to invoke the drawShadowedShape(outline, g2d); not on the outline but the Text-Shape as whole thing, so that the shadow is drawn around the Font not like in the example on the outline.
Prior to asking this question I read in the documentiaon about all TextLayout methods that return a Shape object, but I did not find the correct one by my self.
For this snippet to work you just need to supply a valid font here: String fName = "fonts/SugarBomb.ttf";
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.*;
#SuppressWarnings("serial")
public class GradientText extends JPanel {
private static final int PREF_W = 360;
private static final int PREF_H = 200;
private static Font font;
private static final int COLOR_COUNT = 3;
private static final Color BG = Color.ORANGE;
private Paint myPaint;
public GradientText() {
String fName = "fonts/SugarBomb.ttf";
InputStream is = FontTest.class.getResourceAsStream(fName);
try {
font = Font.createFont(Font.TRUETYPE_FONT, is);
font = font.deriveFont(20.0f);
} catch (FontFormatException | IOException e) {
e.printStackTrace();
}
setBackground(BG);
setPreferredSize(new Dimension(PREF_W, PREF_H));
float[] fractions = new float[COLOR_COUNT];
Color[] colors = new Color[COLOR_COUNT];
for (int i = 0; i < colors.length; i++) {
fractions[i] = ((float)i) / COLOR_COUNT;
if(i%2==0) {
colors[i] = new Color(248, 57, 1);
}else {
colors[i] = Color.yellow;
}
}
for (int i = 0; i < colors.length; i++) {
System.out.println(colors[i]);
System.out.println(fractions[i]);
}
myPaint = new LinearGradientPaint(0, 0, PREF_W, 0, fractions, colors);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
FontRenderContext frc = g2d.getFontRenderContext();
String s = "Look ma, I'm Stroked";
TextLayout textTl = new TextLayout(s, font, frc);
Shape outline = textTl.getOutline(null);
FontMetrics fm = g2d.getFontMetrics(getFont());
int x = (getWidth() - outline.getBounds().width) / 2;
int y = ((getHeight() - outline.getBounds().height) / 2) + fm.getAscent();
g2d.translate(x, y);
Stroke stroke = g2d.getStroke();
g2d.setPaint(myPaint);
g2d.fill(outline);
g2d.setStroke(new BasicStroke(1.2f));
g2d.setColor(Color.WHITE);
drawShadowedShape(outline, g2d);
g2d.draw(outline);
g2d.dispose();
}
private static void createAndShowGui() {
GradientText mainPanel = new GradientText();
JFrame frame = new JFrame("GradientText");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public static void drawShadowedShape(Shape shape, Graphics2D g2d) {
Color holdColor = g2d.getColor();
g2d.setColor(Color.black);
AffineTransform holdTransform = g2d.getTransform();
// want the shadow to be one line width pixel offset
float lineWidth = g2d.getStroke() instanceof BasicStroke ? ((BasicStroke) (g2d.getStroke())).getLineWidth()
: 2.0f;
//System.err.println("DrawingUtilities.drawShadowedShape(): lineWidth = "+lineWidth);
g2d.translate(lineWidth, lineWidth);
g2d.draw(shape);
g2d.setColor(holdColor);
g2d.setTransform(holdTransform);
g2d.draw(shape);
}
}

How To plot a point on defining a coordinate system?

I have a rectangle defined as coordinate system as shown below.I want to plot the point (-7.224,1002), but I am unable to create a formula with which I can plot corresponding to this value.I have provided a code for reference:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.stream.Collectors;
import javax.swing.JComponent;
class PlotComponent extends JComponent {
private ArrayList<Point> points = new ArrayList<Point>();
int sum=0,count=0,count1=0;
int val=0,val1=0;
private Color gridColor=new Color(200,200,200,200);
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x_start_point=(int)(getWidth()*0.1);
int x_end_point=(int)(getWidth()*0.8);
int y_start_point=(int)(getHeight()*0.1);
int y_end_point=(int)(getHeight()*0.8);
int y_line=y_end_point+y_start_point;
int x_line=x_end_point+x_start_point;
int div_x=(x_end_point-x_start_point)/13;
int div_y=(y_end_point-y_start_point)/13;
Rectangle shape=new Rectangle(x_start_point,y_start_point,x_end_point,y_end_point);
g2.setColor(Color.WHITE);
g2.fill(shape);
g2.setColor(Color.BLUE);
g2.drawRect(x_start_point,y_start_point,x_end_point,y_end_point);
int count=-2, count1=0;;
for(int i=0;i<15;i++)
{
g2.drawLine(x_start_point+(div_x*i),y_line,x_start_point+(div_x*i),(int)(y_line*1.02));
g2.drawString(Integer.toString(count), (int)(x_start_point+(div_x*i)-3.5),(int)(y_line*1.07));
count+=2;
g2.drawLine(x_start_point,y_line-(div_y*i),(int)(x_start_point*0.85),y_line-(div_y*i));
g2.drawString(Integer.toString(count1),7,(int)(y_line-(div_y*i)));
count1+=500;
}
}
public void addPoint(Point p) {
points.add(p);
}
}
Now here, I have defined a rectangle based on some offset values.So, in that case, the points would be plotted based on the offset and values taken from divisions, but i am unable to bring out a solution for the same.Kindly help
See the changes in your code and the comments explaining them :
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class SwingTest extends JFrame {
public SwingTest() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new PlotComponent());
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()-> new SwingTest());
}
}
class PlotComponent extends JComponent {
private final ArrayList<Point2D> points = new ArrayList<>();
//use constants for better readability
private static final int X_MARKS = 13, X_START = -8, X_INCREMENT = 2,Y_MARKS = 13,
Y_START = 0, Y_INCREMENT = 500, POINT_SIZE = 1;
public PlotComponent() {
setPreferredSize(new Dimension( 600, 500));
addPoint(new Point2D.Double(-7.224, 1002)); //add test point
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//you need to use doubles to avoid rounding error and have use non integer coordinates
double x_start_point = xStart();
double y_start_point = yStart();
double y_end_point = yEnd();
double width = xEnd() - xStart();
double hight = yEnd() - yStart();
double div_x= width/X_MARKS; //this is also the scale: number of pixles per
double div_y= hight/Y_MARKS; //mark. used to scale points when painting
double xOrigin = x_start_point - div_x *(X_START/X_INCREMENT); //location of
double yOrigin = y_end_point + div_y *(Y_START/Y_INCREMENT); // 0,0
Rectangle2D shape=new Rectangle2D.Double(x_start_point,y_start_point,width,hight);
g2.setColor(Color.WHITE);
g2.fill(shape);
g2.setColor(Color.BLUE);
g2.draw(shape);
int xMarkValue= X_START;
for(int i=0; i <= X_MARKS;i++){
Shape xMark = new Line2D.Double(x_start_point+div_x*i, y_end_point,
x_start_point+ div_x*i,y_end_point*1.02);
g2.draw(xMark);
g2.drawString(Integer.toString(xMarkValue), (float) (x_start_point+div_x*i-3.5),
(float)(y_end_point*1.07));
xMarkValue+=X_INCREMENT;
}
int yMarkValue=Y_START;
for(int i=0; i<= Y_MARKS;i++){
Shape yMark = new Line2D.Double(x_start_point,y_end_point-div_y*i,
x_start_point*0.85,y_end_point-div_y*i);
g2.draw(yMark);
g2.drawString(Integer.toString(yMarkValue),7,(float) (y_end_point-div_y*i));
yMarkValue+=Y_INCREMENT;
}
g2.translate(xOrigin, yOrigin); // move the canvas origin to 0,0
g2.setColor(Color.RED);
for( Point2D p : points){
//scale point coordinates. also change y direction
Shape point = new Ellipse2D.Double(p.getX()/div_x, - p.getY()/div_y, POINT_SIZE, POINT_SIZE);
g2.draw(point);
}
}
private double xStart() {
return (int)(getWidth()*0.1);
}
private double xEnd() {
return (int)(getWidth()*0.8);
}
private double yStart() {
return (int)(getHeight()*0.1);
}
private double yEnd() {
return (int)(getHeight()*0.8);
}
public void addPoint(Point2D p) {
points.add(p);
}
}

How can I display large coordinates within the coordinatesystem?

I would like to plot some points from a given wkt file, but because of their closeness I only can display a heap of ovals that are overlapped.
The points differ only in their decimal places:
POINT (3346349.958 5642197.806)
POINT (3346349.313 5642199.622)
POINT (3346349.237 5642201.918)
POINT (3346349.734 5642204.058)
POINT (3346351.746 5642205.777)
POINT (3346351.636 5642210.304)
POINT (3346349.335 5642216.518)
POINT (3346347.326 5642221.15)
POINT (3346347.365 5642223.671)
POINT (3346351.577 5642195.711)
etc...
First I tried to plot the points, but as I have mentioned all points are seemingly displayed at the same place.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import com.vividsolutions.jts.io.ParseException;
public class Display extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private int width;
private int height;
private WKTGrabsteine p = new WKTGrabsteine();
public Display() {
setLayout(null);
width = 0;
height = 0;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
g2.translate(height, width);
try {
for (int point = 0; point < p.geoCoordinates().size(); point++) {
Ellipse2D shape = new Ellipse2D.Double(p.geoCoordinates().get(point).getX() / 1000000 + 400,
p.geoCoordinates().get(point).getY() / 1000000 + 100, 5, 5);
g2.draw(shape);
}
} catch (IOException | ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
However I thought that the solution could lie in rescaling the coordinate system, which I tried to transform by Affinetransform and .scale()
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import com.vividsolutions.jts.io.ParseException;
public class Display extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private int width;
private int height;
private WKTGrabsteine p = new WKTGrabsteine();
public Display() {
setLayout(null);
width = 0;
height = 0;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
g2.translate(height, width);
at.scale(6000000, 6000000);
try {
for (int point = 0; point < p.geoCoordinates().size(); point++) {
Ellipse2D shape = new Ellipse2D.Double(p.geoCoordinates().get(point).getX(),
p.geoCoordinates().get(point).getY(), 10, 10);
g2.transform(at);
g2.draw(shape);
}
} catch (IOException | ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In fact I am quite new to this topic and have no clue how to make all points visible. Would be great if somebody could help me.
Many thanks
Use a combination of scaling and translating affine transforms.
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class PointPlotter {
Point2D.Double[] points = {
new Point2D.Double(3346349.958, 5642197.806),
new Point2D.Double(3346349.313, 5642199.622),
new Point2D.Double(3346349.237, 5642201.918),
new Point2D.Double(3346349.734, 5642204.058),
new Point2D.Double(3346351.746, 5642205.777),
new Point2D.Double(3346351.636, 5642210.304),
new Point2D.Double(3346349.335, 5642216.518),
new Point2D.Double(3346347.326, 5642221.15),
new Point2D.Double(3346347.365, 5642223.671),
new Point2D.Double(3346351.577, 5642195.711)
};
public static int SZ = 400;
BufferedImage image = new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
private JComponent ui = null;
PointPlotter() {
initUI();
}
private void drawImage() {
Graphics2D g = image.createGraphics();
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.WHITE);
g.fillRect(0, 0, SZ, SZ);
Area area = new Area();
double r = 0.3;
for (Point2D.Double point : points) {
Ellipse2D.Double e = new Ellipse2D.Double(
point.getX() - r, point.getY() - r, 2*r, 2*r);
area.add(new Area(e));
}
Rectangle2D rect = area.getBounds2D();
double w = rect.getWidth();
double h = rect.getHeight();
double max = w>h ? w : h;
double s = SZ/max;
AffineTransform scale = AffineTransform.getScaleInstance(s, s);
double tX = -rect.getMinX();
double tY = -rect.getMinY();
AffineTransform translate = AffineTransform.getTranslateInstance(tX, tY);
AffineTransform transform = scale;
transform.concatenate(translate);
area = new Area(transform.createTransformedShape(area));
g.setColor(Color.RED);
g.draw(area);
g.dispose();
}
public void initUI() {
if (ui != null) {
return;
}
drawImage();
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new JLabel(new ImageIcon(image)));
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
PointPlotter o = new PointPlotter();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}

How to rotate a rectangle after reaching specified position?

I would like to rotate a rectangle when e.g. y position achieve specified position. I would like to behave a rectangle as a car on a junction - just turn e.g. right. I prefer just rotate and continue.
A draft code looks like that:
Graphics2D g2d = (Graphics2D) g.create();
g2d.setPaint(new Color(150, 150, 0));
//1. when rectangle achieve 500 on y dimension just rotate left/right
if(y==500) {
_rotate = true;
g2d.rotate(Math.toRadians(90.));
}
if(_rotate) { //if rotate, continue way on x dimension
++x ;
g2d.fillRect(x, y, 20, 40);
} else { //else go to the north
--y;
g2d.fillRect(x, y, 20, 40);
}
There is a lot of information which is missing from your question.
In order to be able to rotate a shape, you need to know a few things, you need to know it's current position and it's next target position, then you can simply calculate the angle between these two points.
The question then becomes, how do you calculate these positions. There are plenty of ways you might achieve this, the following is a simple path following process.
First, we generate a path which we need to follow, we use the Shape API to calculate the points along the path. We use a simple time based animation (rather the looping through the points, we calculate the progress along the path by calculating amount of time the animation has been playing divided by the amount of time we want it to take) and picking the point which best matches our current progress.
We use a AffineTransform to rotate the player shape and the translate the resulting Shape to the required position. Ease
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PathFollow {
public static void main(String[] args) {
new PathFollow();
}
public PathFollow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Shape pathShape;
private List<Point2D> points;
private Shape car;
private double angle;
private Point2D pos;
private int index;
protected static final double PLAY_TIME = 5000; // 5 seconds...
private Long startTime;
public TestPane() {
Path2D path = new Path2D.Double();
path.moveTo(0, 200);
path.curveTo(100, 200, 0, 100, 100, 100);
path.curveTo(200, 100, 0, 0, 200, 0);
pathShape = path;
car = new Rectangle(0, 0, 10, 10);
points = new ArrayList<>(25);
PathIterator pi = pathShape.getPathIterator(null, 0.01);
while (!pi.isDone()) {
double[] coords = new double[6];
switch (pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
case PathIterator.SEG_LINETO:
points.add(new Point2D.Double(coords[0], coords[1]));
break;
}
pi.next();
}
// System.out.println(points.size());
// pos = points.get(0);
// index = 1;
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = System.currentTimeMillis();
}
long playTime = System.currentTimeMillis() - startTime;
double progress = playTime / PLAY_TIME;
if (progress >= 1.0) {
progress = 1d;
((Timer) e.getSource()).stop();
}
int index = Math.min(Math.max(0, (int) (points.size() * progress)), points.size() - 1);
pos = points.get(index);
if (index < points.size() - 1) {
angle = angleTo(pos, points.get(index + 1));
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.draw(pathShape);
AffineTransform at = new AffineTransform();
if (pos != null) {
Rectangle bounds = car.getBounds();
at.rotate(angle, (bounds.width / 2), (bounds.width / 2));
Path2D player = new Path2D.Double(car, at);
g2d.translate(pos.getX() - (bounds.width / 2), pos.getY() - (bounds.height / 2));
g2d.draw(player);
}
g2d.dispose();
}
// In radians...
protected double angleTo(Point2D from, Point2D to) {
double angle = Math.atan2(to.getY() - from.getY(), to.getX() - from.getX());
return angle;
}
}
}

JXMapKit drawing route with getGpxTrack()

I am trying to draw a route over the road using the source code below:
final List<GeoPosition> region = new ArrayList<GeoPosition>();
Painter<JXMapViewer> lineOverlay = new Painter<JXMapViewer>() {
public void paint(Graphics2D g, JXMapViewer map, int w, int h) {
region.add(new GeoPosition(5.42031,100.34389));
region.add(new GeoPosition(5.41984,100.33924));
region.add(new GeoPosition(5.42300,100.33456));
g = (Graphics2D) g.create();
//convert from viewport to world bitmap
Rectangle rect = jXMapKit1.getMainMap().getViewportBounds();
g.translate(-rect.x, -rect.y);
//do the drawing
g.setColor(Color.RED);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(2));
int lastX = -1;
int lastY = -1;
for (GeoPosition gp : region.getGpxTrack())
{
//convert geo to world bitmap pixel
Point2D pt = jXMapKit1.getMainMap().getTileFactory().geoToPixel(gp, jXMapKit1.getMainMap().getZoom());
if (lastX != -1 && lastY != -1) {
g.drawLine(lastX, lastY, (int) pt.getX(), (int) pt.getY());
}
lastX = (int) pt.getX();
lastY = (int) pt.getY();
}
System.out.println("I am here");
g.dispose();
}
};
However, I get an error at the line region.getGpxTrack().
I try to use the region only GeoPosition gp : region, it only draw a line between two points. What I want is a road route. Anyone know where I got wrong?
Ok I did the same to see if it works if you replace region.getGpxTrack() with region as I assume in comment. Yes it works. Here is full worked application with that what you are trying to do:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.jdesktop.swingx.JXMapKit;
import org.jdesktop.swingx.JXMapKit.DefaultProviders;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.painter.Painter;
public class Starter {
public static void main(final String[] args) {
final JFrame f = new JFrame();
f.setSize(500, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JXMapKit jXMapKit1 = new JXMapKit();
jXMapKit1.setDefaultProvider(DefaultProviders.OpenStreetMaps);
jXMapKit1.setCenterPosition(new GeoPosition(5.41984, 100.33924));
jXMapKit1.setZoom(3);
final List<GeoPosition> region = new ArrayList<GeoPosition>();
region.add(new GeoPosition(5.42031, 100.34389));
region.add(new GeoPosition(5.41984, 100.33924));
region.add(new GeoPosition(5.42300, 100.33456));
final Painter<JXMapViewer> lineOverlay = new Painter<JXMapViewer>() {
#Override
public void paint(Graphics2D g, final JXMapViewer map, final int w, final int h) {
g = (Graphics2D) g.create();
// convert from viewport to world bitmap
final Rectangle rect = jXMapKit1.getMainMap().getViewportBounds();
g.translate(-rect.x, -rect.y);
// do the drawing
g.setColor(Color.RED);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(2));
int lastX = -1;
int lastY = -1;
for (final GeoPosition gp : region) {
// convert geo to world bitmap pixel
final Point2D pt = jXMapKit1.getMainMap().getTileFactory().geoToPixel(gp, jXMapKit1.getMainMap().getZoom());
if (lastX != -1 && lastY != -1) {
g.drawLine(lastX, lastY, (int) pt.getX(), (int) pt.getY());
}
lastX = (int) pt.getX();
lastY = (int) pt.getY();
}
g.dispose();
}
};
jXMapKit1.getMainMap().setOverlayPainter(lineOverlay);
f.setContentPane(jXMapKit1);
f.setVisible(true);
}
}

Categories

Resources