Ticket #720: patch.2.diff

File patch.2.diff, 9.0 KB (added by Henry Loenwind, 16 years ago)

Patch v2

  • src/org/openstreetmap/josm/gui/layer/GpxLayer.java

     
    7272        public GpxData data;
    7373        private final GpxLayer me;
    7474        protected static final double PHI = Math.toRadians(15);
     75        private boolean computeCacheInSync;
     76        private int computeCacheMaxLineLingthUsed;
    7577
    7678        public GpxLayer(GpxData d) {
    7779                super((String) d.attr.get("name"));
    7880                data = d;
    7981                me = this;
     82                computeCacheInSync = false;
    8083        }
    8184
    8285        public GpxLayer(GpxData d, String name) {
     
    284287
    285288        @Override public void mergeFrom(Layer from) {
    286289                data.mergeFrom(((GpxLayer)from).data);
     290                computeCacheInSync = false;
    287291        }
    288292
    289293        private static Color[] colors = new Color[256];
     
    293297                }
    294298        }
    295299
     300        // lookup array to draw arrows without doing any math
     301        private static int ll0 = 9;
     302        private static int sl4 = 5;
     303        private static int sl9 = 3;
     304        private static int[][] dir = {
     305                {+sl4,+ll0,+ll0,+sl4},
     306                {-sl9,+ll0,+sl9,+ll0},
     307                {-ll0,+sl4,-sl4,+ll0},
     308                {-ll0,-sl9,-ll0,+sl9},
     309                {-sl4,-ll0,-ll0,-sl4},
     310                {+sl9,-ll0,-sl9,-ll0},
     311                {+ll0,-sl4,+sl4,-ll0},
     312                {+ll0,+sl9,+ll0,-sl9},
     313                {+sl4,+ll0,+ll0,+sl4},
     314                {-sl9,+ll0,+sl9,+ll0},
     315                {-ll0,+sl4,-sl4,+ll0},
     316                {-ll0,-sl9,-ll0,+sl9}
     317        };
     318
    296319        @Override public void paint(Graphics g, MapView mv) {
    297320                String gpsCol = Main.pref.get("color.gps point");
    298321                String gpsColSpecial = Main.pref.get("color.layer "+name);
     322                Color neutralColor;
    299323                if (!gpsColSpecial.equals("")) {
    300                         g.setColor(ColorHelper.html2color(gpsColSpecial));
     324                        neutralColor = ColorHelper.html2color(gpsColSpecial);
    301325                } else if (!gpsCol.equals("")) {
    302                         g.setColor(ColorHelper.html2color(gpsCol));
     326                        neutralColor = ColorHelper.html2color(gpsCol);
    303327                } else{
    304                         g.setColor(Color.GRAY);
     328                        neutralColor = Color.GRAY;
    305329                }
     330                g.setColor(neutralColor);
    306331
    307                 boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force");
    308                 boolean direction = Main.pref.getBoolean("draw.rawgps.direction");
    309                 int maxLineLength = Integer.parseInt(Main.pref.get("draw.rawgps.max-line-length", "-1"));
    310                 boolean lines = Main.pref.getBoolean("draw.rawgps.lines");
     332                boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force");                     // also draw lines between points belonging to different segments
     333                boolean direction = Main.pref.getBoolean("draw.rawgps.direction");                        // draw direction arrows on the lines
     334                int maxLineLength = Integer.parseInt(Main.pref.get("draw.rawgps.max-line-length", "-1")); // don't draw lines if longer than x meters
     335                boolean lines = Main.pref.getBoolean("draw.rawgps.lines");                                // draw line between points, global setting
    311336                String linesKey = "draw.rawgps.lines.layer "+name;
    312337                if (Main.pref.hasKey(linesKey))
    313                         lines = Main.pref.getBoolean(linesKey);
    314                 boolean large = Main.pref.getBoolean("draw.rawgps.large");
    315                 boolean colored = Main.pref.getBoolean("draw.rawgps.colors");
     338                        lines = Main.pref.getBoolean(linesKey);                                                 // draw lines, per-layer setting
     339                boolean large = Main.pref.getBoolean("draw.rawgps.large");                                // paint large dots for points
     340                boolean colored = Main.pref.getBoolean("draw.rawgps.colors");                             // color the lines
     341                boolean alternatedirection = Main.pref.getBoolean("draw.rawgps.alternatedirection");      // paint direction arrow with alternate math. may be faster
     342                boolean trianglelines = Main.pref.getBoolean("draw.rawgps.trianglelines");                // paint lines as 2 lines
    316343
    317                 Point old = null;
     344                if (computeCacheInSync && computeCacheMaxLineLingthUsed != maxLineLength) {
     345                        computeCacheInSync = false;
     346                }
     347
     348                if (!computeCacheInSync && lines) { // don't compute if the cache is good or if there are no lines to draw at all
     349                        //System.out.println("(re-)computing gpx line styles, reason: CCIS=" + computeCacheInSync + " L=" + lines);
    318350                WayPoint oldWp = null;
    319351                for (GpxTrack trk : data.tracks) {
    320                         if (!forceLines) {
    321                                 old = null;
     352                                if (!forceLines) { // don't draw lines between segments, unless forced to
     353                                        oldWp = null;
    322354                        }
    323355                        for (Collection<WayPoint> segment : trk.trackSegs) {
    324356                                for (WayPoint trkPnt : segment) {
    325                                         if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
     357                                                if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon())) {
    326358                                                continue;
    327                                         Point screen = mv.getPoint(trkPnt.eastNorth);
    328                                         if (lines && old != null) {
     359                                                }
     360                                                if (oldWp != null) {
    329361                                                double dist = trkPnt.latlon.greatCircleDistance(oldWp.latlon);
    330362                                                double dtime = trkPnt.time - oldWp.time;
    331363                                                double vel = dist/dtime;
    332364
    333                                                 if (colored && dtime > 0) {
    334                                                         // scale linearly until 130km/h = 36.1m/s
    335                                                         if (vel < 0 || vel > 36) {
    336                                                                 g.setColor(colors[255]);
     365                                                        if (dtime <= 0 || vel < 0 || vel > 36) { // attn: bad case first
     366                                                                trkPnt.speedLineColor = colors[255];
    337367                                                        } else {
    338                                                                 g.setColor(colors[(int) (7*vel)]);
     368                                                                trkPnt.speedLineColor = colors[(int) (7*vel)];
    339369                                                        }
     370                                                        if (maxLineLength == -1 || dist <= maxLineLength) {
     371                                                                trkPnt.drawLine = true;
     372                                                                trkPnt.dir = (int)(Math.atan2(-trkPnt.eastNorth.north()+oldWp.eastNorth.north(), trkPnt.eastNorth.east()-oldWp.eastNorth.east()) / Math.PI * 4 + 3.5); // crude but works
     373                                                        } else {
     374                                                                trkPnt.drawLine = false;
    340375                                                }
     376                                                } else { // make sure we reset outdated data
     377                                                        trkPnt.speedLineColor = colors[255];
     378                                                        trkPnt.drawLine = false;
     379                                                }
     380                                                oldWp = trkPnt;
     381                                        }
     382                                }
     383                        }
     384                        computeCacheInSync = true;
     385                        computeCacheMaxLineLingthUsed = maxLineLength;
     386                }
    341387
    342                                             // draw line, if no maxLineLength is set or the line is shorter.
    343                                             if (maxLineLength == -1 || dist <= maxLineLength){
     388                Point old = null;
     389                for (GpxTrack trk : data.tracks) {
     390                        for (Collection<WayPoint> segment : trk.trackSegs) {
     391                                for (WayPoint trkPnt : segment) {
     392                                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
     393                                                continue;
     394                                        Point screen = mv.getPoint(trkPnt.eastNorth);
     395                                        if (lines && trkPnt.drawLine) {
     396                                                if ((old.x != screen.x) || (old.y != screen.y)) { // skip points that are on the same screenposition
     397                                                        if (colored) {
     398                                                                g.setColor(trkPnt.speedLineColor);
     399                                                        }
     400                                                        if (trianglelines) { // fast
     401                                                                g.drawLine(screen.x, screen.y, old.x + dir[trkPnt.dir][0], old.y + dir[trkPnt.dir][1]);
     402                                                                g.drawLine(screen.x, screen.y, old.x + dir[trkPnt.dir][2], old.y + dir[trkPnt.dir][3]);
     403                                                        } else { // slow
    344404                                                g.drawLine(old.x, old.y, screen.x, screen.y);
    345 
     405                                                        }
    346406                                                if (direction) {
     407                                                                if (alternatedirection) { // a little bit faster
     408                                                                        g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][0], screen.y + dir[trkPnt.dir][1]);
     409                                                                        g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][2], screen.y + dir[trkPnt.dir][3]);
     410                                                                } else { // a tiny bit slower, may not make a difference at all
    347411                                                    double t = Math.atan2(screen.y-old.y, screen.x-old.x) + Math.PI;
    348412                                                    g.drawLine(screen.x,screen.y, (int)(screen.x + 10*Math.cos(t-PHI)), (int)(screen.y + 10*Math.sin(t-PHI)));
    349413                                                    g.drawLine(screen.x,screen.y, (int)(screen.x + 10*Math.cos(t+PHI)), (int)(screen.y + 10*Math.sin(t+PHI)));
    350414                                                }
     415                                                        }
     416                                                }
    351417                                            }else{
    352                                                 g.drawRect(screen.x, screen.y, 0, 0);
     418                                                if (colored) { // reset color for non-line drawing if lines are variable colored
     419                                                        g.setColor(neutralColor);
    353420                                            }
    354 
    355                                         } else if (!large) {
     421                                                if (large) {
     422                                                        g.fillRect(screen.x-1, screen.y-1, 3, 3);
     423                                                } else {
    356424                                                g.drawRect(screen.x, screen.y, 0, 0);
    357425                                        }
    358                                         if (large)
    359                                                 g.fillRect(screen.x-1, screen.y-1, 3, 3);
     426                                        }
    360427                                        old = screen;
    361                                         oldWp = trkPnt;
    362428                                }
    363429                        }
    364430                }
  • src/org/openstreetmap/josm/data/gpx/WayPoint.java

     
    66import java.text.ParsePosition;
    77import java.text.SimpleDateFormat;
    88import java.util.Date;
     9import java.awt.Color;
    910
    1011import org.openstreetmap.josm.Main;
    1112import org.openstreetmap.josm.data.coor.EastNorth;
     
    1617        public final LatLon latlon;
    1718        public final EastNorth eastNorth;
    1819        public double time;
     20        public Color speedLineColor;
     21        public boolean drawLine;
     22        public int dir;
    1923
    2024        public WayPoint(LatLon ll) {
    2125                latlon = ll;