/* Copyright (c) 2008 Google Inc.
*
* 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 com.google.gdata.data.geo.impl;
import com.google.gdata.util.common.xml.XmlNamespace;
import com.google.gdata.data.ValueConstruct;
import com.google.gdata.data.geo.GeoLat;
import com.google.gdata.data.geo.GeoLong;
import com.google.gdata.data.geo.Point;
/**
* A basic point construct consists of a space-separated coordinate in geo
* space. The namespace and name of the element are supplied by subclasses.
*
*
*/
public abstract class PointConstruct extends ValueConstruct implements Point {
private Double lat;
private Double lon;
/**
* Constructor to create an empty point object.
*/
public PointConstruct(XmlNamespace namespace, String name) {
super(namespace, name, null);
setRequired(false);
}
/**
* Constructor to create a point from a given lat/lon pair. Will create an
* empy point if both values are null, if only one value is null with throw
* an illegal argument exception.
*/
public PointConstruct(XmlNamespace namespace, String name,
Double lat, Double lon) {
super(namespace, name, null);
if (lat == null && lon == null) {
setRequired(false);
}
setGeoLocation(lat, lon);
}
/**
* Copy constructor to create a point from another point.
*/
public PointConstruct(XmlNamespace namespace, String name, Point copyFrom) {
this(namespace, name, copyFrom == null ? null : copyFrom.getLatitude(),
copyFrom == null ? null : copyFrom.getLongitude());
}
/*
* Just returns the stored latitude.
*/
public Double getLatitude() {
return lat;
}
/*
* Just returns the stored longitude.
*/
public Double getLongitude() {
return lon;
}
/*
* Sets the latitude and longitude values of this Point, and validates that
* the values are correct. Throws IllegalArgumentExceptions on invalid
* values, as well as when one is null and the other is not.
*/
public void setGeoLocation(Double lat, Double lon) {
if (lat != null && lon != null) {
if (lat.compareTo(GeoLat.MIN_LAT) < 0
|| lat.compareTo(GeoLat.MAX_LAT) > 0) {
throw new IllegalArgumentException("Latitude must be between "
+ "-90 and 90 degrees.");
}
if (lon.compareTo(GeoLong.MIN_LONG) < 0
|| lon.compareTo(GeoLong.MAX_LONG) > 0) {
throw new IllegalArgumentException("Longitude must be between "
+ "-180 and 180 degrees.");
}
} else if (lat != null || lon != null) {
throw new IllegalArgumentException(
"latitude and longitude must either both be null or non-null.");
}
this.lat = lat;
this.lon = lon;
super.setValue(toString());
}
/*
* Overriding toString to generate the string representation of the point.
*/
@Override
public String toString() {
if (lat != null && lon != null) {
return lat + " " + lon;
}
return null;
}
/*
* Overriding setValue to parse the string into a lat and long, and then
* setting those values. Will throw illegal argument exceptions if the format
* isn't correct.
*/
@Override
public void setValue(String v) {
Double lat = null;
Double lon = null;
if (v != null) {
v = v.trim();
int space = v.indexOf(' ');
if (space == -1) {
throw createInvalidValueException();
}
String latString = v.substring(0, space);
String lonString = v.substring(space + 1);
try {
lat = Double.valueOf(latString);
lon = Double.valueOf(lonString);
} catch (NumberFormatException e) {
throw createInvalidValueException();
}
}
// This will also call super.setValue so we don't call it here.
setGeoLocation(lat, lon);
}
@Override
protected void validate() throws IllegalStateException {
super.validate();
if ((lat == null && lon != null)
|| (lat != null && lon == null)) {
throw new IllegalStateException (
"latitude and longitude must either both be null or non-null.");
}
}
/**
* Helper to generate the nice error message when given illegal values.
*/
private IllegalArgumentException createInvalidValueException() {
return new IllegalArgumentException(
"Format of a coordinate is \"latitude longitude\", where latitude "
+ "and longitude are doubles, separated by a space.");
}
}