Changeset 646 in josm


Ignore:
Timestamp:
09.06.2008 20:06:32 (4 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.