package com.google.maps.android.geojson;
import com.google.android.gms.maps.model.LatLngBounds;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
/**
* A GeoJsonFeature has a geometry, bounding box, id and set of properties. Styles are also stored
* in this class.
*/
public class GeoJsonFeature extends Observable implements Observer {
private final String mId;
private final LatLngBounds mBoundingBox;
private final HashMap<String, String> mProperties;
private GeoJsonGeometry mGeometry;
private GeoJsonPointStyle mPointStyle;
private GeoJsonLineStringStyle mLineStringStyle;
private GeoJsonPolygonStyle mPolygonStyle;
/**
* Creates a new GeoJsonFeature object
*
* @param geometry type of geometry to assign to the feature
* @param id common identifier of the feature
* @param properties hashmap of containing properties related to the feature
* @param boundingBox bounding box of the feature
*/
public GeoJsonFeature(GeoJsonGeometry geometry, String id,
HashMap<String, String> properties, LatLngBounds boundingBox) {
mGeometry = geometry;
mId = id;
mBoundingBox = boundingBox;
if (properties == null) {
mProperties = new HashMap<String, String>();
} else {
mProperties = properties;
}
}
/**
* Returns all the stored property keys
*
* @return iterable of property keys
*/
public Iterable<String> getPropertyKeys() {
return mProperties.keySet();
}
/**
* Gets the value for a stored property
*
* @param property key of the property
* @return value of the property if its key exists, otherwise null
*/
public String getProperty(String property) {
return mProperties.get(property);
}
/**
* Store a new property key and value
*
* @param property key of the property to store
* @param propertyValue value of the property to store
* @return previous value with the same key, otherwise null if the key didn't exist
*/
public String setProperty(String property, String propertyValue) {
return mProperties.put(property, propertyValue);
}
/**
* Checks whether the given property key exists
*
* @param property key of the property to check
* @return true if property key exists, false otherwise
*/
public boolean hasProperty(String property) {
return mProperties.containsKey(property);
}
/**
* Removes a given property
*
* @param property key of the property to remove
* @return value of the removed property or null if there was no corresponding key
*/
public String removeProperty(String property) {
return mProperties.remove(property);
}
/**
* Returns the style used to render GeoJsonPoints
*
* @return style used to render GeoJsonPoints
*/
public GeoJsonPointStyle getPointStyle() {
return mPointStyle;
}
/**
* Sets the style used to render GeoJsonPoints
*
* @param pointStyle style used to render GeoJsonPoints
*/
public void setPointStyle(GeoJsonPointStyle pointStyle) {
if (pointStyle == null) {
throw new IllegalArgumentException("Point style cannot be null");
}
if (mPointStyle != null) {
// Remove observer for previous style
mPointStyle.deleteObserver(this);
}
mPointStyle = pointStyle;
mPointStyle.addObserver(this);
checkRedrawFeature(mPointStyle);
}
/**
* Returns the style used to render GeoJsonLineStrings
*
* @return style used to render GeoJsonLineStrings
*/
public GeoJsonLineStringStyle getLineStringStyle() {
return mLineStringStyle;
}
/**
* Sets the style used to render GeoJsonLineStrings
*
* @param lineStringStyle style used to render GeoJsonLineStrings
*/
public void setLineStringStyle(GeoJsonLineStringStyle lineStringStyle) {
if (lineStringStyle == null) {
throw new IllegalArgumentException("Line string style cannot be null");
}
if (mLineStringStyle != null) {
// Remove observer for previous style
mLineStringStyle.deleteObserver(this);
}
mLineStringStyle = lineStringStyle;
mLineStringStyle.addObserver(this);
checkRedrawFeature(mLineStringStyle);
}
/**
* Returns the style used to render GeoJsonPolygons
*
* @return style used to render GeoJsonPolygons
*/
public GeoJsonPolygonStyle getPolygonStyle() {
return mPolygonStyle;
}
/**
* Sets the style used to render GeoJsonPolygons
*
* @param polygonStyle style used to render GeoJsonPolygons
*/
public void setPolygonStyle(GeoJsonPolygonStyle polygonStyle) {
if (polygonStyle == null) {
throw new IllegalArgumentException("Polygon style cannot be null");
}
if (mPolygonStyle != null) {
// Remove observer for previous style
mPolygonStyle.deleteObserver(this);
}
mPolygonStyle = polygonStyle;
mPolygonStyle.addObserver(this);
checkRedrawFeature(mPolygonStyle);
}
/**
* Checks whether the new style that was set requires the feature to be redrawn. If the
* geometry
* and the style that was set match, then the feature is redrawn.
*
* @param style style to check if a redraw is needed
*/
private void checkRedrawFeature(GeoJsonStyle style) {
if (mGeometry != null && Arrays.asList(style.getGeometryType())
.contains(mGeometry.getType())) {
// Don't redraw objects that aren't on the map
setChanged();
notifyObservers();
}
}
/**
* Gets the stored GeoJsonGeometry
*
* @return GeoJsonGeometry
*/
public GeoJsonGeometry getGeometry() {
return mGeometry;
}
/**
* Sets the stored GeoJsonGeometry and redraws it on the layer if it has already been added
*
* @param geometry GeoJsonGeometry to set
*/
public void setGeometry(GeoJsonGeometry geometry) {
mGeometry = geometry;
setChanged();
notifyObservers();
}
/**
* Gets the ID of the feature
*
* @return ID of the feature, if there is no ID then null will be returned
*/
public String getId() {
return mId;
}
/**
* Checks if the geometry is assigned
*
* @return true if feature contains geometry object, otherwise null
*/
public boolean hasGeometry() {
return (mGeometry != null);
}
/**
* Gets the array containing the coordinates of the bounding box for the feature. If
* the feature did not have a bounding box then null will be returned.
*
* @return LatLngBounds containing bounding box of the feature, null if no bounding box
*/
public LatLngBounds getBoundingBox() {
return mBoundingBox;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Feature{");
sb.append("\n bounding box=").append(mBoundingBox);
sb.append(",\n geometry=").append(mGeometry);
sb.append(",\n point style=").append(mPointStyle);
sb.append(",\n line string style=").append(mLineStringStyle);
sb.append(",\n polygon style=").append(mPolygonStyle);
sb.append(",\n id=").append(mId);
sb.append(",\n properties=").append(mProperties);
sb.append("\n}\n");
return sb.toString();
}
/**
* Update is called if the developer modifies a style that is stored in this feature
*
* @param observable GeoJsonStyle object
* @param data null, no extra argument is passed through the notifyObservers method
*/
@Override
public void update(Observable observable, Object data) {
if (observable instanceof GeoJsonStyle) {
checkRedrawFeature((GeoJsonStyle) observable);
}
}
}