/* Copyright (c) 2011 Danish Maritime Authority.
*
* 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 dk.dma.ais.message;
import dk.dma.enav.model.geometry.Position;
import java.io.Serializable;
/**
* AIS position class
*
* Convert raw unsigned AIS position to signed 1/10000 degree position and provide helper methods for other formats
*
*/
public class AisPosition implements Serializable{
private int bitCorrection;
private long rawLatitude;
private long rawLongitude;
private double resolution = 10000.0;
public AisPosition() {}
/**
* Constructor given raw latitude and raw longitude as received in AIS message
*
* @param rawLatitude
* @param rawLongitude
*/
public AisPosition(long rawLatitude, long rawLongitude) {
this.rawLatitude = rawLatitude;
this.rawLongitude = rawLongitude;
}
/**
* Constructor given a GeoLocation
*
* @param location
*/
public AisPosition(Position location) {
setLatitude(Math.round(location.getLatitude() * resolution * 60.0));
setLongitude(Math.round(location.getLongitude() * resolution * 60.0));
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
AisPosition pos2 = (AisPosition) obj;
return pos2.rawLatitude == this.rawLatitude && pos2.rawLongitude == this.rawLongitude;
}
/**
* Get position as {@link Position} object
*
* @return
*/
public Position getGeoLocation() {
double lat = getLatitude() / resolution / 60.0;
double lon = getLongitude() / resolution / 60.0;
if (Position.isValid(lat, lon)) {
return Position.create(lat, lon);
}
return null;
}
/**
* Get signed latitude
*
* @return
*/
public long getLatitude() {
long latitude;
if (rawLatitude >= 0x4000000 >> bitCorrection) {
latitude = (0x8000000 >> bitCorrection) - rawLatitude;
latitude *= -1;
} else {
latitude = rawLatitude;
}
return latitude;
}
public double getLatitudeDouble() {
return getLatitude() / resolution / 60.0;
}
public double getLongitudeDouble() {
return getLongitude() / resolution / 60.0;
}
/**
* Get signed longitude
*
* @return
*/
public long getLongitude() {
long longitude;
if (rawLongitude >= 0x8000000 >> bitCorrection) {
longitude = (0x10000000 >> bitCorrection) - rawLongitude;
longitude *= -1;
} else {
longitude = rawLongitude;
}
return longitude;
}
public long getRawLatitude() {
return rawLatitude;
}
public long getRawLongitude() {
return rawLongitude;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + bitCorrection;
result = prime * result + (int) (rawLatitude ^ rawLatitude >>> 32);
result = prime * result + (int) (rawLongitude ^ rawLongitude >>> 32);
long temp;
temp = Double.doubleToLongBits(resolution);
result = prime * result + (int) (temp ^ temp >>> 32);
return result;
}
/**
* Set the resolution to be 25 and 24 bits for longitude and latitude respectively
*/
public void set2524() {
resolution = 1000.0;
bitCorrection = 3;
}
/**
* Set the resolution to be 18 and 17 bits for longitude and latitude respectively
*/
public void set1817() {
resolution = 10.0;
bitCorrection = 10;
}
/**
* Set signed latitude
*/
public void setLatitude(long latitude) {
if (latitude < 0) {
rawLatitude = latitude + (0x8000000 >> bitCorrection);
} else {
rawLatitude = latitude;
}
}
/**
* Set signed longitude
*/
public void setLongitude(long longitude) {
if (longitude < 0) {
rawLongitude = longitude + (0x10000000 >> bitCorrection);
} else {
rawLongitude = longitude;
}
}
/**
* Set the raw latitude as received from AIS
*
* @param rawLatitude
*/
public void setRawLatitude(long rawLatitude) {
this.rawLatitude = rawLatitude;
}
/**
* Set the raw longitude as received from AIS
*
* @param rawLongitude
*/
public void setRawLongitude(long rawLongitude) {
this.rawLongitude = rawLongitude;
}
@Override
public String toString() {
return "(" + getRawLatitude() + "," + getRawLongitude() + ") = (" + getLatitude() + ","
+ getLongitude() + ")";
}
}