package com.github.filosganga.geogson.model;
import java.util.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
/**
* Feature is a collection of properties and a geometry
*
* Feature can contain properties with arbitrary json as the value. These values
* are returned as JsonElements and their serialization and de-serialization is
* left to the user.
*
* GeoJson reference: @see http://geojson.org/geojson-spec.html#feature-objects.
*
* eg: {@code
* Feature f = Feature.of(polygon).withId(id)
* }
*/
public class Feature {
private final Geometry<?> geometry;
// Feature properties can contain generic json objects
private final ImmutableMap<String, JsonElement> properties;
private final Optional<String> id;
public Feature(Geometry<?> geometry, ImmutableMap<String, JsonElement> properties, Optional<String> id) {
this.geometry = geometry;
this.properties = properties;
this.id = id;
}
/**
* Build a {@link Feature} with the given {@link Geometry}.
*
* @param geometry The Geometry to build Feature from
*
* @return An instance of Feature
*/
public static Feature of(Geometry<?> geometry) {
return new Feature(geometry, ImmutableMap.<String, JsonElement>of(), Optional.<String>absent());
}
/**
* The Geometry of this Feature.
*
* @return a Geometry instance.
*/
public Geometry<?> geometry() {
return geometry;
}
/**
* The properties of this Feature.
*
* @return an ImmutableMap containing the properties. An empty map if not properties have been set.
*/
public ImmutableMap<String, JsonElement> properties() {
return properties;
}
/**
* The id of the Feature.
*
* @return Optional.absent if this Feature does not have any id. A valued Optional otherwise.
*/
public Optional<String> id() {
return id;
}
/**
* Return a copy of this Feature with the given id.
*
* @param id The id of the new Feature instance.
* @return a new Feature instance.
*/
public Feature withId(String id) {
return new Feature(geometry, properties, Optional.of(id));
}
/**
* Return a copy of this Feature with the given properties.
*
* @param properties The properties of the new Feature instance.
* @return a new Feature instance.
*/
public Feature withProperties(ImmutableMap<String, JsonElement> properties) {
return new Feature(geometry, properties, id);
}
/**
* Return a copy of this Feature with the existing properties plus the given property.
*
* @param name The name of the property to add.
* @param value The value of the property to add.
*
* @return a new Feature instance.
*/
public Feature withProperty(String name, JsonElement value) {
return new Feature(geometry, ImmutableMap.<String, JsonElement>builder().putAll(properties).put(name, value).build(), id);
}
@Override
public int hashCode() {
return Objects.hash(getClass(), this.id, this.geometry, this.properties);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final Feature other = (Feature) obj;
return Objects.equals(this.id, other.id)
&& Objects.equals(this.properties, other.properties)
&& Objects.equals(this.geometry, other.geometry);
}
}