/* * Copyright (C) 2010, 2011, 2012 by Arne Kesting, Martin Treiber, Ralph Germ, Martin Budden * <movsim.org@gmail.com> * ----------------------------------------------------------------------------------------- * * This file is part of * * MovSim - the multi-model open-source vehicular-traffic simulator. * * MovSim is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MovSim is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MovSim. If not, see <http://www.gnu.org/licenses/> * or <http://www.movsim.org>. * * ----------------------------------------------------------------------------------------- */ package org.movsim.roadmappings; import java.util.ArrayList; import java.util.Iterator; import org.movsim.network.autogen.opendrive.OpenDRIVE.Road.PlanView.Geometry; /** * RoadMapping consisting of a number of consecutive heterogeneous RoadMappings. */ public class RoadMappingPoly extends RoadMapping implements Iterable<RoadMapping> { protected final ArrayList<RoadMapping> roadMappings = new ArrayList<>(); @Override public Iterator<RoadMapping> iterator() { return roadMappings.iterator(); } /** * Constructor. * * @param laneCount */ public RoadMappingPoly(int laneCount, double laneWidth) { super(laneCount, laneWidth, 0, 0); } /** * Constructor, adds an initial line. * * @param laneCount * @param x0 * @param y0 * @param x1 * @param y1 */ public RoadMappingPoly(int laneCount, double x0, double y0, double x1, double y1) { super(laneCount, x0, y0); final RoadMapping roadMapping = new RoadMappingLine(laneCount, x0, y0, x1, y1); roadLength = roadMapping.roadLength(); roadMappings.add(roadMapping); } /** * Called when the system is running low on memory, and would like actively running process to try to tighten their * belts. */ @Override protected void onLowMemory() { roadMappings.trimToSize(); } @Override public RoadMapping.PosTheta startPos() { return roadMappings.get(0).startPos(); } @Override public RoadMapping.PosTheta startPos(double lateralOffset) { return roadMappings.get(0).startPos(lateralOffset); } @Override public RoadMapping.PosTheta endPos() { return roadMappings.get(roadMappings.size() - 1).endPos(); } @Override public RoadMapping.PosTheta endPos(double lateralOffset) { return roadMappings.get(roadMappings.size() - 1).endPos(lateralOffset); } @Override public PosTheta map(double roadPos, double lateralOffset) { double pos = roadPos; for (final RoadMapping roadMapping : roadMappings) { if (pos <= roadMapping.roadLength()) { return roadMapping.map(pos, lateralOffset); } pos -= roadMapping.roadLength(); } // have gone past end of last road mapping in road segment // this can happen by up to half a vehicle length - vehicle's rear position is // on road mapping, but vehicle's mid position (which is used for drawing) has // gone past the end, so fix this as a special case. final RoadMapping roadMapping = roadMappings.get(roadMappings.size() - 1); return roadMapping.map(pos + roadMapping.roadLength(), lateralOffset); } public void addLinePoint(double x, double y) { final RoadMapping lastRoadMapping = roadMappings.get(roadMappings.size() - 1); final RoadMappingLine roadMapping = new RoadMappingLine(lastRoadMapping, x, y); roadLength += roadMapping.roadLength(); roadMappings.add(roadMapping); } public void addLinePointRelative(double dx, double dy) { final RoadMapping lastRoadMapping = roadMappings.get(roadMappings.size() - 1); final RoadMapping.PosTheta posTheta = lastRoadMapping.endPos(); final RoadMappingLine roadMapping = new RoadMappingLine(lastRoadMapping, posTheta.x + dx, posTheta.y + dy); roadLength += roadMapping.roadLength(); roadMappings.add(roadMapping); } public void addLine(double s, double x0, double y0, double theta, double length) { final RoadMappingLine roadMapping = new RoadMappingLine(laneCount, s, x0, y0, theta, length); roadLength += length; roadMappings.add(roadMapping); } public void addLine(Geometry geometry) { addLine(geometry.getS(), geometry.getX(), geometry.getY(), geometry.getHdg(), geometry.getLength()); } public void addArc(double s, double x0, double y0, double theta, double length, double curvature) { // final RoadMapping lastRoadMapping = roadMappings.get(roadMappings.size() - 1); // final RoadMapping.PosTheta posTheta = lastRoadMapping.endPos(); // <geometry s="3.66" x="-4.64" y="4.34" hdg="5.29" length="9.19"> // <arc curvature="-1.2698412698412698e-01"/> // </geometry> // RoadMappingArc(laneCount, s, x0, y0, theta, length, curvature) { final RoadMappingArc roadMapping = new RoadMappingArc(laneCount, s, x0, y0, theta, length, curvature); roadLength += length; roadMappings.add(roadMapping); } public void addArc(Geometry geometry) { addArc(geometry.getS(), geometry.getX(), geometry.getY(), geometry.getHdg(), geometry.getLength(), geometry .getArc().getCurvature()); } public void addSpiral(double s, double x0, double y0, double theta, double length, double startCurvature, double endCurvature) { final RoadMappingSpiral roadMapping = new RoadMappingSpiral(laneCount, s, x0, y0, theta, length, startCurvature, endCurvature); roadLength += length; roadMappings.add(roadMapping); } public void addPoly3(double s, double x0, double y0, double theta, double length, double a, double b, double c, double d) { final RoadMappingBezier roadMapping = new RoadMappingBezier(laneCount, s, x0, y0, theta, length, a, b, c, d); roadLength += length; roadMappings.add(roadMapping); } }