/* 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.XmlWriter; import com.google.gdata.data.ExtensionDescription; import com.google.gdata.data.ExtensionPoint; import com.google.gdata.data.ExtensionProfile; import com.google.gdata.data.geo.Box; import com.google.gdata.data.geo.Namespaces; import com.google.gdata.data.geo.Point; import java.io.IOException; /** * The georss:where element. This can contain other elements, so it is * extensible, but it also acts as a Point object. It can also act as a Box as * well, and can be extended to support other GML object types. * * */ public class GeoRssWhere extends ExtensionPoint implements Point, Box { static final String NAME = "where"; /** * Constructs an empty georss:where element. */ public GeoRssWhere() {} /** * Constructs a georss:where element containing the given lat/lon point. * If the given lat and lon are null, will construct an empty gml:Point * element. */ public GeoRssWhere(Double lat, Double lon) { this(new GmlPoint(lat, lon)); } /** * Constructs a georss:where element containing the given point. If the point * is already a gml:Point object, it will be used as the extension directly, * otherwise a copy will be created. If the point is null no extensions will * be added. */ public GeoRssWhere(Point point) { if (point != null) { if (!(point instanceof GmlPoint)) { point = new GmlPoint(point); } setExtension(point); } } /** * Constructs a georss:where element containing the four coordinates that * define a box. If all of the points are null then an empty gml:envelope * will be created. */ public GeoRssWhere(Double lowerLat, Double lowerLon, Double upperLat, Double upperLon) { this(new GmlEnvelope(lowerLat, lowerLon, upperLat, upperLon)); } /** * Constructs a georss:where element containing the given gml:lowerCorner * and gml:upperCorner elements. If both lower and upper are null then an * empty gml:envelope will be created. */ public GeoRssWhere(Point lower, Point upper) { this(new GmlEnvelope(lower, upper)); } /** * Constructs a georss:where element containing the given box. If the box * is null no extension will be set. */ public GeoRssWhere(Box box) { if (box != null) { if (!(box instanceof GmlEnvelope)) { box = new GmlEnvelope(box); } setExtension(box); } } /** * Returns the default extension description for this element. */ public static ExtensionDescription getDefaultDescription(boolean repeatable) { ExtensionDescription desc = new ExtensionDescription(); desc.setExtensionClass(GeoRssWhere.class); desc.setNamespace(Namespaces.GEO_RSS_NAMESPACE); desc.setLocalName(NAME); desc.setRepeatable(repeatable); return desc; } /** * Returns the suggested extension description and is repeatable. */ public static ExtensionDescription getDefaultDescription() { return getDefaultDescription(true); } /* * Declare the extensions for georss:where. This contains elements for * points, boxes, polygons, and lines. This can be extended to include other * types of information as well. */ @Override public void declareExtensions(ExtensionProfile extProfile) { // Declare the gml extensions we support. extProfile.declare(GeoRssWhere.class, GmlPoint.getDefaultDescription(false)); new GmlPoint().declareExtensions(extProfile); extProfile.declare(GeoRssWhere.class, GmlEnvelope.getDefaultDescription(false)); new GmlEnvelope().declareExtensions(extProfile); super.declareExtensions(extProfile); } /* * Get the latitude by pulling it from the gml:Point element (if it exists). */ public Double getLatitude() { GmlPoint point = getExtension(GmlPoint.class); return point != null ? point.getLatitude() : null; } /* * Get the longitude by pulling it from the gml:Point element (if it exists). */ public Double getLongitude() { GmlPoint point = getExtension(GmlPoint.class); return point != null ? point.getLongitude() : null; } /* * Set the latitude and longitude by creating or removing the gml:Point * element as needed. If the existing wrapped point is non-null but the given * lat and lon are both null, it is removed. Otherwise its new latitude and * longitude are set. If the gml:Point element doesn't exist, it is only * created if the given coordinates are non-null. We also rely on the * gml:Point object to do checking of valid values. */ public void setGeoLocation(Double lat, Double lon) { GmlPoint point = getExtension(GmlPoint.class); if (point != null) { point.setGeoLocation(lat, lon); } else if (lat != null || lon != null) { point = new GmlPoint(); setExtension(point); point.setGeoLocation(lat, lon); } } /* * Pull out the envelope and use its lower left point. */ public GmlLowerCorner getLowerLeft() { GmlEnvelope envelope = getExtension(GmlEnvelope.class); return envelope != null ? envelope.getLowerLeft() : null; } /* * Pull out the envelope and use its upper right point. */ public GmlUpperCorner getUpperRight() { GmlEnvelope envelope = getExtension(GmlEnvelope.class); return envelope != null ? envelope.getUpperRight() : null; } /* * Set the bounding box points. This correctly handles all cases where the * existing gml:envelope is null or has null values. In particular: * * 1) Remove the lower and upper corner of the GmlEnvelope * if lowerLeft and upperRight are null. * 2) Create a new extension if it doesn't exist and either lowerLeft or * upperRight are non-null. * 3) Otherwise just set the lowerLeft and upperRight on the existing point. */ public void setGeoLocation(Point lowerLeft, Point upperRight) { GmlEnvelope envelope = getExtension(GmlEnvelope.class); if (envelope != null) { envelope.setGeoLocation(lowerLeft, upperRight); } else if (lowerLeft != null || upperRight != null) { envelope = new GmlEnvelope(); setExtension(envelope); envelope.setGeoLocation(lowerLeft, upperRight); } } /** * @return true if this GeoRssWhere element contains a point element. */ public boolean hasPoint() { return getExtension(GmlPoint.class) != null; } /** * @return true if this GeoRssWhere element contains an envelope element. */ public boolean hasBox() { return getExtension(GmlEnvelope.class) != null; } /** * Removes the GmlPoint element inside this GeoRssWhere. */ public void clearPoint() { removeExtension(GmlPoint.class); } /** * Removes the GmlEnvelope element inside this GeoRssWhere. */ public void clearBox() { removeExtension(GmlEnvelope.class); } /* * Just write out the start tag, any extensions, and the end tag. * This will automatically handle any extensions we add, so shouldn't need * to be updated as we add more gml types. */ @Override public void generate(XmlWriter w, ExtensionProfile p) throws IOException { generateStartElement(w, Namespaces.GEO_RSS_NAMESPACE, NAME, null, null); generateExtensions(w, p); w.endElement(Namespaces.GEO_RSS_NAMESPACE, NAME); } }