package org.opentrafficsim.draw.graphs; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djunits.value.vdouble.scalar.Time; import org.djutils.exceptions.Throw; import org.djutils.immutablecollections.Immutable; import org.djutils.immutablecollections.ImmutableArrayList; import org.djutils.immutablecollections.ImmutableList; import org.opentrafficsim.base.WeightedMeanAndSum; import org.opentrafficsim.kpi.sampling.KpiLaneDirection; import org.opentrafficsim.kpi.sampling.Sampler; import org.opentrafficsim.kpi.sampling.SpaceTimeRegion; /** * A {@code GraphPath} defines the spatial dimension of graphs. It has a number of sections, each of which may have one or more * source objects depending on the number of series. For example, a 3-lane road may result in a few sections each having 3 * series. Graphs can aggregate the series, or show multiple series. *
* Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License.
*
* @version $Revision$, $LastChangedDate$, by $Author$, initial version 19 okt. 2018
* Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
*
* @version $Revision$, $LastChangedDate$, by $Author$, initial version 20 okt. 2018
* @author Alexander Verbraeck
* @author Peter Knoppers
* @author Wouter Schakel
* @param underlying type of path sections
*/
public class GraphPath extends AbstractGraphSpace
{
/** Sections. */
private final List section : sections)
{
this.startDistances.add(cumulativeLength);
cumulativeLength = cumulativeLength.plus(section.getLength());
}
this.totalLength = cumulativeLength;
WeightedMeanAndSum section : sections)
{
mean.add(section.getSpeedLimit().si, section.getLength().si);
}
this.speedLimit = Speed.instantiateSI(mean.getMean());
}
/**
* Returns the start distance of the section.
* @param section Section<S>; Section<S> section
* @return Length; start distance of the section
*/
public final Length getStartDistance(final Section section)
{
int index = this.sections.indexOf(section);
Throw.when(index == -1, IllegalArgumentException.class, "Section is not part of the path.");
return this.startDistances.get(index);
}
/**
* Returns the total path length.
* @return Length; total path length
*/
public final Length getTotalLength()
{
return this.totalLength;
}
/**
* Returns the mean speed over the entire section.
* @return Speed; mean speed over the entire section
*/
public final Speed getSpeedLimit()
{
return this.speedLimit;
}
/**
* Returns a section.
* @param index int; index of section
* @return Section<S>; section
*/
public Section get(final int index)
{
return this.sections.get(index);
}
/** {@inheritDoc} */
@Override
public Iterator iterator()
{
return new Iterator()
{
/** Section iterator. */
private Iterator sourceIterator = this.sectionIterator.hasNext() ? this.sectionIterator.next().iterator() : null;
/** {@inheritDoc} */
@Override
public boolean hasNext()
{
if (this.sourceIterator != null && this.sourceIterator.hasNext())
{
return true;
}
while (this.sectionIterator.hasNext())
{
Iterator it = this.sectionIterator.next().iterator();
if (it.hasNext())
{
this.sourceIterator = it;
return true;
}
}
this.sourceIterator = null;
return false;
}
/** {@inheritDoc} */
@Override
public S next()
{
Throw.when(!hasNext(), NoSuchElementException.class, "No more element left.");
return this.sourceIterator.next();
}
};
}
/** {@inheritDoc} */
@Override
public Iterator iterator(final int series)
{
List list = new ArrayList<>();
for (Section section : this.sections)
{
list.add(section.getSource(series));
}
return new ImmutableArrayList<>(list, Immutable.WRAP).iterator();
}
/**
* Returns an immutable list of the sections.
* @return ImmutableList<Section<S>>; sections
*/
public ImmutableList
* BSD-style license. See OpenTrafficSim License.
*
* @author Alexander Verbraeck
* @author Peter Knoppers
* @author Wouter Schakel
* @param underlying type
*/
public static interface Section extends Iterable
{
/**
* Returns the section length.
* @return Length; section length
*/
Length getLength();
/**
* Returns the speed limit on the section.
* @return Speed; speed limit on the section
*/
Speed getSpeedLimit();
/**
* Returns the source object.
* @param series int; number
* @return S; underlying object of the series
*/
S getSource(int series);
}
/** {@inheritDoc} */
@Override
public String toString()
{
return "GraphPath [sections=" + this.sections + ", startDistances=" + this.startDistances + ", totalLength="
+ this.totalLength + ", speedLimit=" + this.speedLimit + "]";
}
/**
* Start recording along path.
* @param sampler Sampler<?>; sampler
* @param path GraphPath<KpiLaneDirection>; path
*/
public static void initRecording(final Sampler> sampler, final GraphPath