Changeset 646 in josm


Ignore:
Timestamp:
2008-06-09T20:06:32+02:00 (16 years ago)
Author:
framm
Message:
  • patch by Henry Loenwind (ticket #720) to speed up gps rendering
Location:
trunk/src/org/openstreetmap/josm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java

    r627 r646  
    77import java.text.SimpleDateFormat;
    88import java.util.Date;
     9import java.awt.Color;
    910
    1011import org.openstreetmap.josm.Main;
     
    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) {
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r627 r646  
    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) {
     
    7880                data = d;
    7981                me = this;
     82                computeCacheInSync = false;
    8083        }
    8184
     
    285288        @Override public void mergeFrom(Layer from) {
    286289                data.mergeFrom(((GpxLayer)from).data);
     290                computeCacheInSync = false;
    287291        }
    288292
     
    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);
    305                 }
     328                        neutralColor = Color.GRAY;
     329                }
     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");
    316 
    317                 Point old = null;
     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
     343
     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;
    322                         }
     352                                if (!forceLines) { // don't draw lines between segments, unless forced to
     353                                        oldWp = null;
     354                        }
     355                        for (Collection<WayPoint> segment : trk.trackSegs) {
     356                                for (WayPoint trkPnt : segment) {
     357                                                if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon())) {
     358                                                continue;
     359                                                }
     360                                                if (oldWp != null) {
     361                                                double dist = trkPnt.latlon.greatCircleDistance(oldWp.latlon);
     362                                                double dtime = trkPnt.time - oldWp.time;
     363                                                double vel = dist/dtime;
     364
     365                                                        if (dtime <= 0 || vel < 0 || vel > 36) { // attn: bad case first
     366                                                                trkPnt.speedLineColor = colors[255];
     367                                                        } else {
     368                                                                trkPnt.speedLineColor = colors[(int) (7*vel)];
     369                                                        }
     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;
     375                                                }
     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                }
     387                                               
     388                Point old = null;
     389                for (GpxTrack trk : data.tracks) {
    323390                        for (Collection<WayPoint> segment : trk.trackSegs) {
    324391                                for (WayPoint trkPnt : segment) {
     
    326393                                                continue;
    327394                                        Point screen = mv.getPoint(trkPnt.eastNorth);
    328                                         if (lines && old != null) {
    329                                                 double dist = trkPnt.latlon.greatCircleDistance(oldWp.latlon);
    330                                                 double dtime = trkPnt.time - oldWp.time;
    331                                                 double vel = dist/dtime;
    332 
    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]);
    337                                                         } else {
    338                                                                 g.setColor(colors[(int) (7*vel)]);
     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);
    339399                                                        }
    340                                                 }
    341                                                
    342                                             // draw line, if no maxLineLength is set or the line is shorter.
    343                                             if (maxLineLength == -1 || dist <= maxLineLength){
     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                        }
Note: See TracChangeset for help on using the changeset viewer.