Skip to content

Commit

Permalink
add target display, patch by Pauline Thiele
Browse files Browse the repository at this point in the history
  • Loading branch information
stoecker committed Sep 5, 2024
1 parent 6efef1b commit 663996a
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 23 deletions.
92 changes: 92 additions & 0 deletions livegps/src/livegps/CirclePanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// License: Public Domain. For details, see LICENSE file.
package livegps;

import javax.swing.JPanel;
import javax.swing.JLabel;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.BasicStroke;
import java.awt.Color;

import java.awt.geom.Rectangle2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Area;

import org.openstreetmap.josm.spi.preferences.Config;

/**
* Draw a target visualization
*/
public class CirclePanel extends JPanel {

JLabel label = new JLabel();
double x = 0;

public CirclePanel(double x) {
add(label);
this.x = x;
}

public void setOffset(double offs) {
this.x = offs;
}

@Override
protected void paintComponent(Graphics g) {
boolean isVisible = Config.getPref().getBoolean(LiveGPSPreferences.C_DISTANCE_VISUALISATION, false);

super.paintComponent(g);
if (isVisible == true) {
Graphics2D g2 = (Graphics2D) g;

int w = getWidth();
int h = getHeight();

double width = 0;
if (w > h) {
width = h*0.9;
} else {
width = w*0.9;
}

double y_start = (h/2.0) - (width/2); // center circle vertical
double x_start = (w - width) / 2; // center circle horizontal

// 3 rectangles
Shape rect1 = new Rectangle2D.Double(x_start, y_start, width*0.4, width);
Shape rect2 = new Rectangle2D.Double(x_start+width*0.4, y_start, width*0.2, width);
Shape rect3 = new Rectangle2D.Double(x_start+width*0.6, y_start, width*0.4, width);

// 1 circle
Shape circle = new Ellipse2D.Double(x_start, y_start, width, width);

// intersection
Area rect1Area = new Area(rect1);
Area rect2Area = new Area(rect2);
Area rect3Area = new Area(rect3);

Area circleArea1 = new Area(circle);
Area circleArea2 = new Area(circle);
Area circleArea3 = new Area(circle);

circleArea1.intersect(rect1Area);
circleArea2.intersect(rect2Area);
circleArea3.intersect(rect3Area);

g2.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));

DrawPoint drawpoint = new DrawPoint();
drawpoint.draw_point(x, g2, circleArea1, circleArea2, circleArea3, label, x_start, y_start, width);

g2.draw(circleArea1);
g2.draw(circleArea2);
g2.draw(circleArea3);

// red center line
g2.setColor(Color.red);
g2.drawLine((int) (x_start+(width/2)), (int) y_start, (int) (x_start+(width/2)), (int) (y_start+width));
}
}
}
86 changes: 86 additions & 0 deletions livegps/src/livegps/DrawPoint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// License: Public Domain. For details, see LICENSE file.
package livegps;

import javax.swing.JPanel;
import javax.swing.JLabel;

import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.geom.Area;

import org.openstreetmap.josm.spi.preferences.Config;

class DrawPoint extends JPanel {
public double threshold = Config.getPref().getDouble(LiveGPSPreferences.C_OFFSET_THRESHOLD, LiveGPSPreferences.DEFAULT_THRESHOLD);
int x_p = 0;
int w = getWidth();
int h = getHeight();

public void draw_point(double x, Graphics2D g2, Area circleArea1, Area circleArea2,
Area circleArea3, JLabel label, double x_start, double y_start, double width) {

// x-value of black point
if (x < -threshold) {
x_p = (int) (x_start + (width*0.4) + (x*(width/100)) - ((width*0.15)/2));
if (x_p < x_start) {
x_p = (int) x_start;
}
} else if (x > threshold) {
x_p = (int) (x_start + (x*(width/100)) + (width*0.6) - ((width*0.15)/2));
if (x_p > x_start + width) {
x_p = (int) (x_start + width);
}
} else if (x >= -threshold && x <= threshold) {
x_p = (int) (x_start + (width/2) - ((width*0.15)/2));
}

// fill area
fill(x, x_p, g2, circleArea1, circleArea2, circleArea3, label, x_start, y_start, width);

// black position point
g2.setColor(Color.black);
g2.fillOval(x_p, (int) (y_start+(width/2)-((width*0.15)/2)), (int) (width*0.15), (int) (width*0.15));
}

public void fill(double x, int x_p, Graphics2D g2, Area circleArea1, Area circleArea2, Area circleArea3,
JLabel label, double x_start, double y_start, double width) {

Color yellow;
Color green;
yellow = new Color(255, 210, 50, 255);
green = new Color(30, 200, 50, 255);

// Distance from point to center line, rounded to 2 decimals
double y = Math.round(x * 100.0) / 100.0;

if (x < 0 && -x > threshold) {
// left yellow + text
g2.setColor(yellow);
g2.fill(circleArea1);

if (width/3 < 60) { // if label larger than half circle, place label outside the circle
label.setBounds((int) (x_start - 60), (int) (y_start + width*0.3), 60, 10);
} else {
label.setBounds((int) (x_start + width*0.1), (int) (y_start + width*0.3), (int) (width/3), (int) (width/15));
}
label.setText(y+" m");

} else if ((-x <= threshold && x <= 0) || (x <= threshold && x >= 0)) {
// center green
g2.setColor(green);
g2.fill(circleArea2);
label.setText("");
} else if (x > 0 && x > threshold) {
// right yellow + text
g2.setColor(yellow);
g2.fill(circleArea3);

if (width/3 < 60) {
label.setBounds((int) (x_start + width*1.1), (int) (y_start + width*0.3), 60, 10);
} else {
label.setBounds((int) (x_start + width*0.7), (int) (y_start + width*0.3), (int) (width/3), (int) (width/15));
}
label.setText("+"+y+" m");
}
}
}
38 changes: 38 additions & 0 deletions livegps/src/livegps/LiveGPSPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

//import java.beans.PropertyChangeEvent;
//import java.beans.PropertyChangeListener;

import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
Expand Down Expand Up @@ -33,6 +36,10 @@ public class LiveGPSPreferences extends DefaultTabPreferenceSetting {
public static final String C_PORT = "livegps.gpsd.port";
/* option to use specify gpsd disabling */
public static final String C_DISABLED = "livegps.gpsd.disabled";
/* option to use distance visualisation and set threshold */
public static final String C_DISTANCE_VISUALISATION = "livegps.distance_visualisation";
public static final String C_OFFSET_THRESHOLD = "livegps.offset_threshold";
public static final double DEFAULT_THRESHOLD = 0.3;

public static final String C_LIVEGPS_COLOR_POSITION = "color.livegps.position";
public static final String C_LIVEGPS_COLOR_POSITION_ESTIMATE = "color.livegps.position_estimate";
Expand Down Expand Up @@ -60,6 +67,9 @@ public class LiveGPSPreferences extends DefaultTabPreferenceSetting {
private final JTextField serialDevice = new JTextField(30);
private final JCheckBox disableGPSD = new JCheckBox(tr("Disable GPSD"));
private final JCheckBox showOffset = new JCheckBox(tr("Show Distance to nearest way"));
private final JCheckBox showDistanceVisualisation = new JCheckBox(tr("Show distance visualisation"));
private final JTextField threshold = new JTextField(5);
private JLabel thresholdLabel;

public LiveGPSPreferences() {
super("dialogs/livegps", tr("LiveGPS settings"), tr("Here you can change some preferences of LiveGPS plugin"));
Expand Down Expand Up @@ -95,17 +105,45 @@ public void addGui(PreferenceTabbedPane gui) {
showOffset.setSelected(Config.getPref().getBoolean(C_WAYOFFSET, false));
panel.add(showOffset, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 5));

showDistanceVisualisation.setSelected(Config.getPref().getBoolean(C_DISTANCE_VISUALISATION, false));
panel.add(showDistanceVisualisation, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 5));

threshold.setText(String.valueOf(Config.getPref().getDouble(C_OFFSET_THRESHOLD, DEFAULT_THRESHOLD)));
threshold.setToolTipText(tr("Threshold, default is {0}", DEFAULT_THRESHOLD));
thresholdLabel = new JLabel(tr("Threshold"));
panel.add(thresholdLabel, GBC.std());
panel.add(threshold, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(5, 0, 0, 5));
threshold.setVisible(false);
thresholdLabel.setVisible(false);

updateThreshold(); // beim Start
showDistanceVisualisation.addActionListener(e -> updateThreshold()); // wenn sich was ändert

panel.add(Box.createVerticalGlue(), GBC.eol().fill(GridBagConstraints.VERTICAL));
createPreferenceTabWithScrollPane(gui, panel);
}

private void updateThreshold() {
boolean isVisible = showDistanceVisualisation.isSelected();

threshold.setVisible(isVisible);
thresholdLabel.setVisible(isVisible);
}

@Override
public boolean ok() {
Config.getPref().put(C_HOST, gpsdHost.getText());
Config.getPref().put(C_PORT, gpsdPort.getText());
Config.getPref().put(C_SERIAL, serialDevice.getText());
Config.getPref().putBoolean(C_DISABLED, disableGPSD.isSelected());
Config.getPref().putBoolean(C_WAYOFFSET, showOffset.isSelected());
boolean oldVal = Config.getPref().getBoolean(C_DISTANCE_VISUALISATION, false);
boolean newVal = showDistanceVisualisation.isSelected();
Config.getPref().putBoolean(C_DISTANCE_VISUALISATION, newVal);
Config.getPref().put(C_OFFSET_THRESHOLD, threshold.getText());
if (oldVal != newVal) {
LiveGpsDialog.updateCirclePanelVisibility();
}
return false;
}
}
13 changes: 11 additions & 2 deletions livegps/src/livegps/LiveGpsData.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class LiveGpsData {
private String wayString;
private WayPoint waypoint;
private static final DecimalFormat offsetFormat = new DecimalFormat("0.00");
private double offs = 0;

public LiveGpsData(double latitude, double longitude, float course, float speed) {
this.fix = true;
Expand Down Expand Up @@ -166,6 +167,14 @@ public String toString() {
+ ", long=" + latLon.lon() + ", speed=" + speed + ", course=" + course + ']';
}

public void setOffset(double offs) {
this.offs = offs;
}

public double getOffset() {
return this.offs;
}

/**
* Returns the name of the way that is closest to the current coordinates or an
* empty string if no way is around.
Expand Down Expand Up @@ -193,10 +202,10 @@ protected void decorateNameWithNodes(StringBuilder name, IWay way) {
wayString = tr("no name");
}
if (Config.getPref().getBoolean(LiveGPSPreferences.C_WAYOFFSET, false)) {
double offs = Geometry.getDistanceWayNode(way, n);
offs = Geometry.getDistanceWayNode(way, n);
WaySegment ws = Geometry.getClosestWaySegment(way, n);
if (!Geometry.angleIsClockwise(ws.getFirstNode(), ws.getSecondNode(), n))
offs = -offs;
setOffset(-offs);
/* I18N: side offset and way name for livegps way display with offset */
wayString = tr("{0} ({1})", offsetFormat.format(offs), wayString);
}
Expand Down
Loading

0 comments on commit 663996a

Please sign in to comment.