001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.data.gpx;
003    
004    import java.util.ArrayList;
005    import java.util.Collection;
006    import java.util.Collections;
007    
008    import org.openstreetmap.josm.data.Bounds;
009    
010    public class ImmutableGpxTrackSegment implements GpxTrackSegment {
011    
012        private final Collection<WayPoint> wayPoints;
013        private final Bounds bounds;
014        private final double length;
015    
016        public ImmutableGpxTrackSegment(Collection<WayPoint> wayPoints) {
017            this.wayPoints = Collections.unmodifiableCollection(new ArrayList<WayPoint>(wayPoints));
018            this.bounds = calculateBounds();
019            this.length = calculateLength();
020        }
021    
022        private Bounds calculateBounds() {
023            Bounds result = null;
024            for (WayPoint wpt: wayPoints) {
025                if (result == null) {
026                    result = new Bounds(wpt.getCoor());
027                } else {
028                    result.extend(wpt.getCoor());
029                }
030            }
031            return result;
032        }
033    
034        private double calculateLength() {
035            double result = 0.0; // in meters
036            WayPoint last = null;
037            for (WayPoint tpt : wayPoints) {
038                if(last != null){
039                    Double d = last.getCoor().greatCircleDistance(tpt.getCoor());
040                    if(!d.isNaN() && !d.isInfinite()) {
041                        result += d;
042                    }
043                }
044                last = tpt;
045            }
046            return result;
047        }
048    
049        public Bounds getBounds() {
050            if (bounds == null)
051                return null;
052            else
053                return new Bounds(bounds);
054        }
055    
056        public Collection<WayPoint> getWayPoints() {
057            return wayPoints;
058        }
059    
060        public double length() {
061            return length;
062        }
063    
064        public int getUpdateCount() {
065            return 0;
066        }
067    
068    }