<commit_before>/*
 * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.osgi.util.position;

import org.osgi.util.measurement.Measurement;
import org.osgi.util.measurement.Unit;

/**
 * Position represents a geographic location, based on the WGS84 System (World
 * Geodetic System 1984).
 * <p>
 * The <code>org.osgi.util.measurement.Measurement</code> class is used to
 * represent the values that make up a position.
 * <p>
 * <p>
 * A given position object may lack any of it's components, i.e. the altitude
 * may not be known. Such missing values will be represented by null.
 * <p>
 * Position does not override the implementation of either equals() or
 * hashCode() because it is not clear how missing values should be handled. It
 * is up to the user of a position to determine how best to compare two position
 * objects. A <code>Position</code> object is immutable.
 * 
 * @Immutable
 * @version $Revision$
 */
public class Position {
	private final Measurement	altitude;
	private final Measurement	longitude;
	private final Measurement	latitude;
	private final Measurement	speed;
	private final Measurement	track;

	/**
	 * Constructs a <code>Position</code> object with the given values.
	 * 
	 * @param lat a <code>Measurement</code> object specifying the latitude in
	 *        radians, or null
	 * @param lon a <code>Measurement</code> object specifying the longitude in
	 *        radians, or null
	 * @param alt a <code>Measurement</code> object specifying the altitude in
	 *        meters, or null
	 * @param speed a <code>Measurement</code> object specifying the speed in
	 *        meters per second, or null
	 * @param track a <code>Measurement</code> object specifying the track in
	 *        radians, or null
	 */
	public Position(Measurement lat, Measurement lon, Measurement alt,
			Measurement speed, Measurement track) {
		if (lat != null) {
			if (!Unit.rad.equals(lat.getUnit())) {
				throw new IllegalArgumentException("Invalid Latitude");
			}
		}
		if (lon != null) {
			if (!Unit.rad.equals(lon.getUnit())) {
				throw new IllegalArgumentException("Invalid Longitude");
			}
		}
		if (alt != null) {
			if (!Unit.m.equals(alt.getUnit())) {
				throw new IllegalArgumentException("Invalid Altitude");
			}
		}
		if (speed != null) {
			if (!Unit.m_s.equals(speed.getUnit())) {
				throw new IllegalArgumentException("Invalid Speed");
			}
		}
		if (track != null) {
			if (!Unit.rad.equals(track.getUnit())) {
				throw new IllegalArgumentException("Invalid Track");
			}
		}

		/*
		 * Verify the longitude and latitude parameters so they fit the normal
		 * coordinate system. A latitude is between -90 (south) and +90 (north).
		 * A longitude is between -180 (Western hemisphere) and +180 (eastern
		 * hemisphere). This method first normalizes the latitude and longitude
		 * between +/- 180. If the |latitude| > 90, then the longitude is added
		 * 180 and the latitude is normalized to fit +/-90. (Example are with
		 * degrees though radians are used) <br> No normalization takes place
		 * when either lon or lat is null.
		 */
		normalizeLatLon: {
			if (lat == null || lon == null) {
				break normalizeLatLon;
			}
			double dlat = lat.getValue();
			double dlon = lon.getValue();
			if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
					&& dlat <= LAT_RANGE) {
				break normalizeLatLon;
			}
			dlon = normalize(dlon, LON_RANGE);
			dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
			// Check if we have to move to other side of the earth
			if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
				dlon = normalize(dlon - LON_RANGE, LON_RANGE);
				dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
			}
			lon = new Measurement(dlon, lon.getError(), lon.getUnit(), lon
					.getTime());
			lat = new Measurement(dlat, lat.getError(), lat.getUnit(), lat
					.getTime());
		}

		/*
		 * Normalize track to be a value such that: 0 <= value < +2PI. This
		 * corresponds to 0 deg to +360 deg. 0 is North, 0.5PI is East, PI is
		 * South, 1.5PI is West
		 */
		normalizeTrack: {
			double dtrack = track.getValue();
			if ((0.0D <= dtrack) && (dtrack < TRACK_RANGE)) {
				break normalizeTrack; /* value is already normalized */
			}
			dtrack %= TRACK_RANGE;
			if (dtrack < 0.0D) {
				dtrack += TRACK_RANGE;
			}
			track = new Measurement(dtrack, track.getError(), track.getUnit(),
					track.getTime());
		}
<commit_msg>fix NPE with null track parameter<commit_after>/*
 * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.osgi.util.position;

import org.osgi.util.measurement.Measurement;
import org.osgi.util.measurement.Unit;

/**
 * Position represents a geographic location, based on the WGS84 System (World
 * Geodetic System 1984).
 * <p>
 * The <code>org.osgi.util.measurement.Measurement</code> class is used to
 * represent the values that make up a position.
 * <p>
 * <p>
 * A given position object may lack any of it's components, i.e. the altitude
 * may not be known. Such missing values will be represented by null.
 * <p>
 * Position does not override the implementation of either equals() or
 * hashCode() because it is not clear how missing values should be handled. It
 * is up to the user of a position to determine how best to compare two position
 * objects. A <code>Position</code> object is immutable.
 * 
 * @Immutable
 * @version $Revision$
 */
public class Position {
	private final Measurement	altitude;
	private final Measurement	longitude;
	private final Measurement	latitude;
	private final Measurement	speed;
	private final Measurement	track;

	/**
	 * Constructs a <code>Position</code> object with the given values.
	 * 
	 * @param lat a <code>Measurement</code> object specifying the latitude in
	 *        radians, or null
	 * @param lon a <code>Measurement</code> object specifying the longitude in
	 *        radians, or null
	 * @param alt a <code>Measurement</code> object specifying the altitude in
	 *        meters, or null
	 * @param speed a <code>Measurement</code> object specifying the speed in
	 *        meters per second, or null
	 * @param track a <code>Measurement</code> object specifying the track in
	 *        radians, or null
	 */
	public Position(Measurement lat, Measurement lon, Measurement alt,
			Measurement speed, Measurement track) {
		if (lat != null) {
			if (!Unit.rad.equals(lat.getUnit())) {
				throw new IllegalArgumentException("Invalid Latitude");
			}
		}
		if (lon != null) {
			if (!Unit.rad.equals(lon.getUnit())) {
				throw new IllegalArgumentException("Invalid Longitude");
			}
		}
		if (alt != null) {
			if (!Unit.m.equals(alt.getUnit())) {
				throw new IllegalArgumentException("Invalid Altitude");
			}
		}
		if (speed != null) {
			if (!Unit.m_s.equals(speed.getUnit())) {
				throw new IllegalArgumentException("Invalid Speed");
			}
		}
		if (track != null) {
			if (!Unit.rad.equals(track.getUnit())) {
				throw new IllegalArgumentException("Invalid Track");
			}
		}

		/*
		 * Verify the longitude and latitude parameters so they fit the normal
		 * coordinate system. A latitude is between -90 (south) and +90 (north).
		 * A longitude is between -180 (Western hemisphere) and +180 (eastern
		 * hemisphere). This method first normalizes the latitude and longitude
		 * between +/- 180. If the |latitude| > 90, then the longitude is added
		 * 180 and the latitude is normalized to fit +/-90. (Example are with
		 * degrees though radians are used) <br> No normalization takes place
		 * when either lon or lat is null.
		 */
		normalizeLatLon: {
			if (lat == null || lon == null) {
				break normalizeLatLon;
			}
			double dlat = lat.getValue();
			double dlon = lon.getValue();
			if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
					&& dlat <= LAT_RANGE) {
				break normalizeLatLon;
			}
			dlon = normalize(dlon, LON_RANGE);
			dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
			// Check if we have to move to other side of the earth
			if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
				dlon = normalize(dlon - LON_RANGE, LON_RANGE);
				dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
			}
			lon = new Measurement(dlon, lon.getError(), lon.getUnit(), lon
					.getTime());
			lat = new Measurement(dlat, lat.getError(), lat.getUnit(), lat
					.getTime());
		}

		/*
		 * Normalize track to be a value such that: 0 <= value < +2PI. This
		 * corresponds to 0 deg to +360 deg. 0 is North, 0.5PI is East, PI is
		 * South, 1.5PI is West
		 */
		normalizeTrack: {
			if (track == null) {
				break normalizeTrack;
			}
			double dtrack = track.getValue();
			if ((0.0D <= dtrack) && (dtrack < TRACK_RANGE)) {
				break normalizeTrack; /* value is already normalized */
			}
			dtrack %= TRACK_RANGE;
			if (dtrack < 0.0D) {
				dtrack += TRACK_RANGE;
			}
			track = new Measurement(dtrack, track.getError(), track.getUnit(),
					track.getTime());
		}

{'fraction_non_alphanumeric': 0.1106691856418415, 'fraction_numerical': 0.011931987670279408, 'mean_word_length': 3.28, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1462344', 'n_tokens_mistral': 3479, 'n_tokens_neox': 2950, 'n_words': 1138}