<commit_before>package com.planetmayo.debrief.satc.model.legs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import com.planetmayo.debrief.satc.model.contributions.BaseContribution;
import com.planetmayo.debrief.satc.model.states.BoundedState;
import com.planetmayo.debrief.satc.model.states.CourseRange;
import com.planetmayo.debrief.satc.model.states.LocationRange;
import com.planetmayo.debrief.satc.model.states.SpeedRange;
import com.planetmayo.debrief.satc.model.states.State;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.util.AffineTransformation;

public class StraightLeg extends CoreLeg
{
	/*
	 * the route permutations through the leg This array will always be
	 * rectangular
	 */
	StraightRoute[][] myRoutes;

	/**
	 * the routes, sorted according to their performance
	 * 
	 */
	SortedSet<CoreRoute> topRoutes;

	/**
	 * create a straight leg.
	 * 
	 * @param name
	 *          what to call the leg
	 * @param states
	 *          the set of bounded states that comprise the leg
	 */
	public StraightLeg(String name, ArrayList<BoundedState> states)
	{
		super(name, states);
	}

	@Override
	protected void createAndStoreLeg(ArrayList<Point> startP,
			ArrayList<Point> endP, int i, int j, String thisName)
	{
		StraightRoute newRoute = new StraightRoute(thisName, startP.get(i),
				getFirst().getTime(), endP.get(j), getLast().getTime());

		// tell the route to decimate itself
		newRoute.generateSegments(_states);

		// and store the route
		myRoutes[i][j] = newRoute;
	}

	/**
	 * work out what if the route is achievable, by scaling the locations to check
	 * that they overlap
	 * 
	 * @author Ian
	 * 
	 */
	public static class ScaledPolygons implements RouteOperator
	{

		private final ArrayList<BoundedState> _myStates;

		public ScaledPolygons(ArrayList<BoundedState> states)
		{
			_myStates = states;
		}

		@Override
		public void process(StraightRoute theRoute)
		{
			// do we already know this isn't possible?
			if (!theRoute.isPossible())
				return;

			// bugger, we'll have to get on with our hard sums then

			// sort out the origin.
			State startState = theRoute.getStates().get(0);
			Coordinate startCoord = startState.getLocation().getCoordinate();

			// also sort out the end state
			State endState = theRoute.getStates()
					.get(theRoute.getStates().size() - 1);
			Point endPt = endState.getLocation();

			// remeber the start time
			long tZero = startState.getTime().getTime();

			// how long is the total run?
			long elapsed = theRoute.getElapsedTime();

			// allow for multiple fidelity processing
			int ctr = 0;

			// how frequently shall we process the polygons?
			// calculating the scaled polygons is really expensive. this
			// give us most of the benefits, at a third of the speed (well,
			// with a freq of '3' it does)
			final int freq = 3;

			// loop through our states
			Iterator<BoundedState> iter = _myStates.iterator();
			while (iter.hasNext())
			{
				BoundedState thisB = iter.next();

				LocationRange thisL = thisB.getLocation();
				if (thisL != null)
				{
					// ok, what's the time difference
					long thisDelta = thisB.getTime().getTime() - tZero;

					// convert to secs
					long tDelta = thisDelta / 1000;

					// is this our first state
					if (tDelta > 0)
					{
						// ok, we've got a location - increment the counter
						ctr++;

						// is this one we're going to process?
						if (((ctr % freq) == 0) || ctr == _myStates.size() - 1)
						{
							double scale = (1d * elapsed) / tDelta;

							// ok, project the shape forwards
							AffineTransformation st = AffineTransformation.scaleInstance(
									scale, scale, startCoord.x, startCoord.y);

							// ok, apply the transform to the location
							Geometry originalGeom = thisL.getGeometry();
							Geometry newGeom = st.transform(originalGeom);

							// see if the end point is in the new geometry
							if (endPt.coveredBy(newGeom))
							{
								// cool, this route works
							}
							else
							{
								// bugger, can't do this one
								theRoute.setImpossible();
								break;
							}
						}
					}
				}
			}
		}
	}

	/**
	 * use a simple speed/time decision to decide if it's possible to navigate a
	 * route
	 */
	public void decideAchievableRoutes()
	{
		StraightLeg.RouteOperator speed = new RouteOperator()
		{

			@Override
			public void process(StraightRoute theRoute)
			{
				double distance = theRoute.getDistance();
				double elapsed = theRoute.getElapsedTime();
				double speed = distance / elapsed;

				SpeedRange speedR = _states.get(0).getSpeed();
				if (speedR == null)
				{
					// hey, we can't calculate it then
				}
				else if (!speedR.allows(speed))
				{
					theRoute.setImpossible();
				}
			}
		};
		StraightLeg.RouteOperator course = new RouteOperator()
		{

			@Override
			public void process(StraightRoute theRoute)
			{
				double thisC = theRoute.getCourse();
				CourseRange courseR = _states.get(0).getCourse();
				
				if (courseR == null)
				{
					// hey, no prob with me ;-)
				}
				else if (!courseR.allows(thisC))
				{
					theRoute.setImpossible();
				}
			}

		};
		StraightLeg.RouteOperator scaledPolygons = new ScaledPolygons(_states);

		applyToRoutes(speed);
		applyToRoutes(course);
		applyToRoutes(scaledPolygons);
	}

	/**
	 * apply the operator to all my routes
	 * 
	 * @param operator
	 */
	public void applyToRoutes(StraightLeg.RouteOperator operator)
	{
		for (int i = 0; i < _startLen; i++)<commit_msg>only test the routes if we think they may be possible<commit_after>package com.planetmayo.debrief.satc.model.legs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import com.planetmayo.debrief.satc.model.contributions.BaseContribution;
import com.planetmayo.debrief.satc.model.states.BoundedState;
import com.planetmayo.debrief.satc.model.states.CourseRange;
import com.planetmayo.debrief.satc.model.states.LocationRange;
import com.planetmayo.debrief.satc.model.states.SpeedRange;
import com.planetmayo.debrief.satc.model.states.State;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.util.AffineTransformation;

public class StraightLeg extends CoreLeg
{
	/*
	 * the route permutations through the leg This array will always be
	 * rectangular
	 */
	StraightRoute[][] myRoutes;

	/**
	 * the routes, sorted according to their performance
	 * 
	 */
	SortedSet<CoreRoute> topRoutes;

	/**
	 * create a straight leg.
	 * 
	 * @param name
	 *          what to call the leg
	 * @param states
	 *          the set of bounded states that comprise the leg
	 */
	public StraightLeg(String name, ArrayList<BoundedState> states)
	{
		super(name, states);
	}

	@Override
	protected void createAndStoreLeg(ArrayList<Point> startP,
			ArrayList<Point> endP, int i, int j, String thisName)
	{
		StraightRoute newRoute = new StraightRoute(thisName, startP.get(i),
				getFirst().getTime(), endP.get(j), getLast().getTime());

		// tell the route to decimate itself
		newRoute.generateSegments(_states);

		// and store the route
		myRoutes[i][j] = newRoute;
	}

	/**
	 * work out what if the route is achievable, by scaling the locations to check
	 * that they overlap
	 * 
	 * @author Ian
	 * 
	 */
	public static class ScaledPolygons implements RouteOperator
	{

		private final ArrayList<BoundedState> _myStates;

		public ScaledPolygons(ArrayList<BoundedState> states)
		{
			_myStates = states;
		}

		@Override
		public void process(StraightRoute theRoute)
		{
			// do we already know this isn't possible?
			if (!theRoute.isPossible())
				return;

			// bugger, we'll have to get on with our hard sums then

			// sort out the origin.
			State startState = theRoute.getStates().get(0);
			Coordinate startCoord = startState.getLocation().getCoordinate();

			// also sort out the end state
			State endState = theRoute.getStates()
					.get(theRoute.getStates().size() - 1);
			Point endPt = endState.getLocation();

			// remeber the start time
			long tZero = startState.getTime().getTime();

			// how long is the total run?
			long elapsed = theRoute.getElapsedTime();

			// allow for multiple fidelity processing
			int ctr = 0;

			// how frequently shall we process the polygons?
			// calculating the scaled polygons is really expensive. this
			// give us most of the benefits, at a third of the speed (well,
			// with a freq of '3' it does)
			final int freq = 3;

			// loop through our states
			Iterator<BoundedState> iter = _myStates.iterator();
			while (iter.hasNext())
			{
				BoundedState thisB = iter.next();

				LocationRange thisL = thisB.getLocation();
				if (thisL != null)
				{
					// ok, what's the time difference
					long thisDelta = thisB.getTime().getTime() - tZero;

					// convert to secs
					long tDelta = thisDelta / 1000;

					// is this our first state
					if (tDelta > 0)
					{
						// ok, we've got a location - increment the counter
						ctr++;

						// is this one we're going to process?
						if (((ctr % freq) == 0) || ctr == _myStates.size() - 1)
						{
							double scale = (1d * elapsed) / tDelta;

							// ok, project the shape forwards
							AffineTransformation st = AffineTransformation.scaleInstance(
									scale, scale, startCoord.x, startCoord.y);

							// ok, apply the transform to the location
							Geometry originalGeom = thisL.getGeometry();
							Geometry newGeom = st.transform(originalGeom);

							// see if the end point is in the new geometry
							if (endPt.coveredBy(newGeom))
							{
								// cool, this route works
							}
							else
							{
								// bugger, can't do this one
								theRoute.setImpossible();
								break;
							}
						}
					}
				}
			}
		}
	}

	/**
	 * use a simple speed/time decision to decide if it's possible to navigate a
	 * route
	 */
	public void decideAchievableRoutes()
	{
		StraightLeg.RouteOperator speed = new RouteOperator()
		{

			@Override
			public void process(StraightRoute theRoute)
			{
				// do we already know this isn't possible?
				if (!theRoute.isPossible())
					return;

				double distance = theRoute.getDistance();
				double elapsed = theRoute.getElapsedTime();
				double speed = distance / elapsed;

				SpeedRange speedR = _states.get(0).getSpeed();
				if (speedR == null)
				{
					// hey, we can't calculate it then
				}
				else if (!speedR.allows(speed))
				{
					theRoute.setImpossible();
				}
			}
		};
		StraightLeg.RouteOperator course = new RouteOperator()
		{

			@Override
			public void process(StraightRoute theRoute)
			{
				// do we already know this isn't possible?
				if (!theRoute.isPossible())
					return;
				double thisC = theRoute.getCourse();
				CourseRange courseR = _states.get(0).getCourse();

				if (courseR == null)
				{
					// hey, no prob with me ;-)
				}
				else if (!courseR.allows(thisC))
				{
					theRoute.setImpossible();
				}
			}

		};
		StraightLeg.RouteOperator scaledPolygons = new ScaledPolygons(_states);

		applyToRoutes(speed);
		applyToRoutes(course);
		applyToRoutes(scaledPolygons);
	}

	/**
	 * apply the operator to all my routes
	 * 
	 * @param operator
	 */
	public void applyToRoutes(StraightLeg.RouteOperator operator)
	{
		for (int i = 0; i < _startLen; i++)
{'fraction_non_alphanumeric': 0.1066369022065768, 'fraction_numerical': 0.0027474886236799174, 'mean_word_length': 2.9008707300736774, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '140207', 'n_tokens_mistral': 4568, 'n_tokens_neox': 3593, 'n_words': 1023}