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    import java.util.HashMap;
008    import java.util.List;
009    import java.util.Map;
010    
011    import org.openstreetmap.josm.data.Bounds;
012    
013    public class ImmutableGpxTrack implements GpxTrack {
014    
015        private final Map<String, Object> attributes;
016        private final Collection<GpxTrackSegment> segments;
017        private final double length;
018        private final Bounds bounds;
019    
020        public ImmutableGpxTrack(Collection<Collection<WayPoint>> trackSegs, Map<String, Object> attributes) {
021            List<GpxTrackSegment> newSegments = new ArrayList<GpxTrackSegment>();
022            for (Collection<WayPoint> trackSeg: trackSegs) {
023                if (trackSeg != null && !trackSeg.isEmpty()) {
024                    newSegments.add(new ImmutableGpxTrackSegment(trackSeg));
025                }
026            }
027            this.attributes = Collections.unmodifiableMap(new HashMap<String, Object>(attributes));
028            this.segments = Collections.unmodifiableCollection(newSegments);
029            this.length = calculateLength();
030            this.bounds = calculateBounds();
031        }
032    
033        private double calculateLength(){
034            double result = 0.0; // in meters
035    
036            for (GpxTrackSegment trkseg : segments) {
037                result += trkseg.length();
038            }
039            return result;
040        }
041    
042        private Bounds calculateBounds() {
043            Bounds result = null;
044            for (GpxTrackSegment segment: segments) {
045                Bounds segBounds = segment.getBounds();
046                if (segBounds != null) {
047                    if (result == null) {
048                        result = new Bounds(segBounds);
049                    } else {
050                        result.extend(segBounds);
051                    }
052                }
053            }
054            return result;
055        }
056    
057        public Map<String, Object> getAttributes() {
058            return attributes;
059        }
060    
061        public Bounds getBounds() {
062            if (bounds == null)
063                return null;
064            else
065                return new Bounds(bounds);
066        }
067    
068        public double length() {
069            return length;
070        }
071    
072        public Collection<GpxTrackSegment> getSegments() {
073            return segments;
074        }
075    
076        public int getUpdateCount() {
077            return 0;
078        }
079    }