001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.gpx;
003
004import java.util.ArrayList;
005import java.util.Collection;
006import java.util.Collections;
007
008import org.openstreetmap.josm.data.Bounds;
009
010public 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<>(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    @Override
050    public Bounds getBounds() {
051        if (bounds == null)
052            return null;
053        else
054            return new Bounds(bounds);
055    }
056
057    @Override
058    public Collection<WayPoint> getWayPoints() {
059        return wayPoints;
060    }
061
062    @Override
063    public double length() {
064        return length;
065    }
066
067    @Override
068    public int getUpdateCount() {
069        return 0;
070    }
071
072}