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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.StringTokenizer;

import com.planetmayo.debrief.satc.model.states.BaseRange.IncompatibleStateException;
import com.planetmayo.debrief.satc.model.states.BoundedState;
import com.planetmayo.debrief.satc.model.states.LocationRange;
import com.planetmayo.debrief.satc.model.states.ProblemSpace;
import com.planetmayo.debrief.satc.util.GeoSupport;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;

public class BearingMeasurementContribution extends BaseContribution
{

	public static final String BEARING_ERROR = "bearing_error";

	/**
	 * the allowable bearing error (in degrees)
	 * 
	 */
	private double _degError = 0;

	/**
	 * the set of measurements we store
	 * 
	 */
	private ArrayList<BMeasurement> _measurements = new ArrayList<BMeasurement>();

	/**
	 * utility method to create one of these contributions
	 * 
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static BearingMeasurementContribution getSample()
	{
		BearingMeasurementContribution res = new BearingMeasurementContribution();
		res.setName("Approaching Buoy");
		res.setActive(true);
		res.setWeight(7);

		// add a couple of bearings
		res.addEstimate(12.2, 12.3, new Date(2012, 3, 3, 12, 2, 2), 55, 1200);
		res.addEstimate(12.3, 12.32, new Date(2012, 3, 3, 12, 3, 2), 58, 1200);
		res.addEstimate(12.3, 12.33, new Date(2012, 3, 3, 12, 4, 2), 60, 1200);
		res.addEstimate(12.4, 12.34, new Date(2012, 3, 3, 12, 5, 2), 62, 1200);

		return res;
	}

	/**
	 * utility class for storing a measurement
	 * 
	 * @author ian
	 * 
	 */
	private static class BMeasurement
	{
		private final Location _origin;
		private final double _bearingDegs;
		private final Date _time;
		/**
		 * the (optional) maximum range for this measurement
		 * 
		 */
		private final Double _theRange;

		public BMeasurement(Location loc, double bearing, Date time, Double theRange)
		{
			_origin = loc;
			_bearingDegs = bearing;
			_time = time;
			_theRange = theRange;
		}
	}

	/**
	 * utility class for storing a 2-d location
	 * 
	 * @author ian
	 * 
	 */
	private static class Location
	{
		private final double _lat;
		private final double _lon;

		public Location(double lat, double lon)
		{
			_lat = lat;
			_lon = lon;
		}
	}

	public void loadFrom(InputStream fstream)
	{
		// load from this source
		// ;;IGNORE YYMMDD HHMMSS IGNORE IGNORE LAT_DEG LAT_MIN LAT_SEC LAT_HEM
		// LONG_DEG LONG_MIN LONG_SEC LONG_HEM BEARING MAX_RNG
		// ;SENSOR: 100112 121329 SENSOR @A 0 3 57.38 S 30 0 8.65 W 1.5 15000
		try
		{

			// Get the object of DataInputStream
	//		DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

			String strLine;

			// Read File Line By Line
			while ((strLine = br.readLine()) != null)
			{
				// hey, is this a comment line?
				if (strLine.startsWith(";;"))
				{
					// just ignore it
				}
				else
				{
					// ok, get parseing it
					StringTokenizer st = new StringTokenizer(strLine, " \t");

					// skip the read of the header
					st.nextToken();

					// now the date
					String date = st.nextToken();

					// and the time
					String time = st.nextToken();

					// ignore the next
					st.nextElement();

					// and the next
					st.nextElement();

					String latDegs = st.nextToken();
					String latMins = st.nextToken();
					String latSecs = st.nextToken();
					String latHemi = st.nextToken();

					String lonDegs = st.nextToken();
					String lonMins = st.nextToken();
					String lonSecs = st.nextToken();
					String lonHemi = st.nextToken();

					// and the beraing
					String bearing = st.nextToken();

					// and the range
					String range = st.nextToken();

					// ok,now construct the date=time
					DateFormat df = new SimpleDateFormat("yyMMdd hhmmss");
					Date theDate = df.parse(date + " " + time);

					// and the location
					double lat = Double.valueOf(latDegs) + Double.valueOf(latMins) / 60d
							+ Double.valueOf(latSecs) / 60d / 60d;
					if (latHemi.toUpperCase().equals("W"))
						lat = -lat;
					double lon = Double.valueOf(lonDegs) + Double.valueOf(lonMins) / 60d
							+ Double.valueOf(lonSecs) / 60d / 60d;
					if (lonHemi.toUpperCase().equals("S"))
						lon = -lon;

					Location theLoc = new Location(lat, lon);
					BMeasurement measure = new BMeasurement(theLoc,
							Double.valueOf(bearing), theDate, GeoSupport.m2deg(Double.valueOf(range)));

					addThis(measure);

				}
			}
			
			// stick in a duff error measurement
			this.setError(10d);

			// Close the input stream
			fstream.close();

		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (ParseException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * store this new measurement
	 * 
	 * @param measure
	 */
	private void addThis(BMeasurement measure)
	{
		// extend the time period accordingly
		if (this.getStartDate() == null)
		{
			this.setStartDate(measure._time);
			this.setFinishDate(measure._time);
		}
		else
		{
			long newTime = measure._time.getTime();
			if (this.getStartDate().getTime() > newTime)
				this.setStartDate(measure._time);
			if (this.getFinishDate().getTime() < newTime)
				this.setFinishDate(measure._time);
		}

		_measurements.add(measure);
	}<commit_msg>tidier handling for file-read problems<commit_after>package com.planetmayo.debrief.satc.model.contributions;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.Status;

import com.planetmayo.debrief.satc.SATC_Activator;
import com.planetmayo.debrief.satc.model.states.BaseRange.IncompatibleStateException;
import com.planetmayo.debrief.satc.model.states.BoundedState;
import com.planetmayo.debrief.satc.model.states.LocationRange;
import com.planetmayo.debrief.satc.model.states.ProblemSpace;
import com.planetmayo.debrief.satc.util.GeoSupport;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;

public class BearingMeasurementContribution extends BaseContribution
{

	public static final String BEARING_ERROR = "bearing_error";

	/**
	 * the allowable bearing error (in degrees)
	 * 
	 */
	private double _degError = 0;

	/**
	 * the set of measurements we store
	 * 
	 */
	private ArrayList<BMeasurement> _measurements = new ArrayList<BMeasurement>();

	/**
	 * utility method to create one of these contributions
	 * 
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static BearingMeasurementContribution getSample()
	{
		BearingMeasurementContribution res = new BearingMeasurementContribution();
		res.setName("Approaching Buoy");
		res.setActive(true);
		res.setWeight(7);

		// add a couple of bearings
		res.addEstimate(12.2, 12.3, new Date(2012, 3, 3, 12, 2, 2), 55, 1200);
		res.addEstimate(12.3, 12.32, new Date(2012, 3, 3, 12, 3, 2), 58, 1200);
		res.addEstimate(12.3, 12.33, new Date(2012, 3, 3, 12, 4, 2), 60, 1200);
		res.addEstimate(12.4, 12.34, new Date(2012, 3, 3, 12, 5, 2), 62, 1200);

		return res;
	}

	/**
	 * utility class for storing a measurement
	 * 
	 * @author ian
	 * 
	 */
	private static class BMeasurement
	{
		private final Location _origin;
		private final double _bearingDegs;
		private final Date _time;
		/**
		 * the (optional) maximum range for this measurement
		 * 
		 */
		private final Double _theRange;

		public BMeasurement(Location loc, double bearing, Date time, Double theRange)
		{
			_origin = loc;
			_bearingDegs = bearing;
			_time = time;
			_theRange = theRange;
		}
	}

	/**
	 * utility class for storing a 2-d location
	 * 
	 * @author ian
	 * 
	 */
	private static class Location
	{
		private final double _lat;
		private final double _lon;

		public Location(double lat, double lon)
		{
			_lat = lat;
			_lon = lon;
		}
	}

	public void loadFrom(InputStream fstream)
	{
		// load from this source
		// ;;IGNORE YYMMDD HHMMSS IGNORE IGNORE LAT_DEG LAT_MIN LAT_SEC LAT_HEM
		// LONG_DEG LONG_MIN LONG_SEC LONG_HEM BEARING MAX_RNG
		// ;SENSOR: 100112 121329 SENSOR @A 0 3 57.38 S 30 0 8.65 W 1.5 15000
		try
		{

			// Get the object of DataInputStream
	//		DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

			String strLine;

			// Read File Line By Line
			while ((strLine = br.readLine()) != null)
			{
				// hey, is this a comment line?
				if (strLine.startsWith(";;"))
				{
					// just ignore it
				}
				else
				{
					// ok, get parseing it
					StringTokenizer st = new StringTokenizer(strLine, " \t");

					// skip the read of the header
					st.nextToken();

					// now the date
					String date = st.nextToken();

					// and the time
					String time = st.nextToken();

					// ignore the next
					st.nextElement();

					// and the next
					st.nextElement();

					String latDegs = st.nextToken();
					String latMins = st.nextToken();
					String latSecs = st.nextToken();
					String latHemi = st.nextToken();

					String lonDegs = st.nextToken();
					String lonMins = st.nextToken();
					String lonSecs = st.nextToken();
					String lonHemi = st.nextToken();

					// and the beraing
					String bearing = st.nextToken();

					// and the range
					String range = st.nextToken();

					// ok,now construct the date=time
					DateFormat df = new SimpleDateFormat("yyMMdd hhmmss");
					Date theDate = df.parse(date + " " + time);

					// and the location
					double lat = Double.valueOf(latDegs) + Double.valueOf(latMins) / 60d
							+ Double.valueOf(latSecs) / 60d / 60d;
					if (latHemi.toUpperCase().equals("W"))
						lat = -lat;
					double lon = Double.valueOf(lonDegs) + Double.valueOf(lonMins) / 60d
							+ Double.valueOf(lonSecs) / 60d / 60d;
					if (lonHemi.toUpperCase().equals("S"))
						lon = -lon;

					Location theLoc = new Location(lat, lon);
					BMeasurement measure = new BMeasurement(theLoc,
							Double.valueOf(bearing), theDate, GeoSupport.m2deg(Double.valueOf(range)));

					addThis(measure);

				}
			}
			
			// stick in a duff error measurement
			this.setError(10d);

			// Close the input stream
			fstream.close();

		}
		catch (IOException e)
		{
			SATC_Activator.log(Status.ERROR, "File load problem", e);
		}
		catch (ParseException e)
		{
			SATC_Activator.log(Status.ERROR, "File parse problem", e);
		}
		
		// TODO: set the start/end times = just for tidiness
	}

	/**
	 * store this new measurement
	 * 
	 * @param measure
	 */
	private void addThis(BMeasurement measure)
	{
		// extend the time period accordingly
		if (this.getStartDate() == null)
		{
			this.setStartDate(measure._time);
			this.setFinishDate(measure._time);
		}
		else
		{
			long newTime = measure._time.getTime();
			if (this.getStartDate().getTime() > newTime)
				this.setStartDate(measure._time);
			if (this.getFinishDate().getTime() < newTime)
				this.setFinishDate(measure._time);
		}

		_measurements.add(measure);
	}
{'fraction_non_alphanumeric': 0.11635325721961047, 'fraction_numerical': 0.02350570852921424, 'mean_word_length': 3.199154035953472, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '6652446', 'n_tokens_mistral': 4925, 'n_tokens_neox': 3897, 'n_words': 1002}