// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.gpx;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.openstreetmap.josm.data.Bounds;
/**
* Immutable GPX track.
* @since 2907
*/
public class ImmutableGpxTrack extends WithAttributes implements GpxTrack {
private final List<GpxTrackSegment> segments;
private final double length;
private final Bounds bounds;
/**
* Constructs a new {@code ImmutableGpxTrack}.
* @param trackSegs track segments
* @param attributes track attributes
*/
public ImmutableGpxTrack(Collection<Collection<WayPoint>> trackSegs, Map<String, Object> attributes) {
List<GpxTrackSegment> newSegments = new ArrayList<>();
for (Collection<WayPoint> trackSeg: trackSegs) {
if (trackSeg != null && !trackSeg.isEmpty()) {
newSegments.add(new ImmutableGpxTrackSegment(trackSeg));
}
}
this.attr = Collections.unmodifiableMap(new HashMap<>(attributes));
this.segments = Collections.unmodifiableList(newSegments);
this.length = calculateLength();
this.bounds = calculateBounds();
}
private double calculateLength() {
double result = 0.0; // in meters
for (GpxTrackSegment trkseg : segments) {
result += trkseg.length();
}
return result;
}
private Bounds calculateBounds() {
Bounds result = null;
for (GpxTrackSegment segment: segments) {
Bounds segBounds = segment.getBounds();
if (segBounds != null) {
if (result == null) {
result = new Bounds(segBounds);
} else {
result.extend(segBounds);
}
}
}
return result;
}
@Override
public Map<String, Object> getAttributes() {
return attr;
}
@Override
public Bounds getBounds() {
return bounds == null ? null : new Bounds(bounds);
}
@Override
public double length() {
return length;
}
@Override
public Collection<GpxTrackSegment> getSegments() {
return segments;
}
@Override
public int getUpdateCount() {
return 0;
}
@Override
public int hashCode() {
return 31 * super.hashCode() + ((segments == null) ? 0 : segments.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
ImmutableGpxTrack other = (ImmutableGpxTrack) obj;
if (segments == null) {
if (other.segments != null)
return false;
} else if (!segments.equals(other.segments))
return false;
return true;
}
}