org.openstreetmap.atlas.geography.atlas.complete.CompletePoint Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlas Show documentation
Show all versions of atlas Show documentation
"Library to load OSM data into an Atlas format"
package org.openstreetmap.atlas.geography.atlas.complete;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.openstreetmap.atlas.exception.CoreException;
import org.openstreetmap.atlas.geography.Location;
import org.openstreetmap.atlas.geography.Rectangle;
import org.openstreetmap.atlas.geography.atlas.change.eventhandling.event.TagChangeEvent;
import org.openstreetmap.atlas.geography.atlas.change.eventhandling.listener.TagChangeListener;
import org.openstreetmap.atlas.geography.atlas.items.Point;
import org.openstreetmap.atlas.geography.atlas.items.Relation;
/**
* Independent {@link Point} that contains its own data. At scale, use at your own risk.
*
* @author matthieun
* @author Yazad Khambata
*/
public class CompletePoint extends Point implements CompleteLocationItem
{
private static final long serialVersionUID = 309534717673911086L;
private Rectangle bounds;
private long identifier;
private Location location;
private Map tags;
private Set relationIdentifiers;
private final TagChangeDelegate tagChangeDelegate = TagChangeDelegate.newTagChangeDelegate();
/**
* Create a {@link CompletePoint} from a given {@link Point} reference. The
* {@link CompletePoint}'s fields will match the fields of the reference. The returned
* {@link CompletePoint} will be full, i.e. all of its associated fields will be non-null.
*
* @param point
* the {@link Point} to copy
* @return the full {@link CompletePoint}
*/
public static CompletePoint from(final Point point)
{
if (point instanceof CompletePoint && !((CompletePoint) point).isFull())
{
throw new CoreException("Point parameter was a CompletePoint but it was not full: {}",
point);
}
return new CompletePoint(point.getIdentifier(), point.getLocation(), point.getTags(), point
.relations().stream().map(Relation::getIdentifier).collect(Collectors.toSet()));
}
/**
* Create a shallow {@link CompletePoint} from a given {@link Point} reference. The
* {@link CompletePoint}'s identifier will match the identifier of the reference {@link Point}.
* The returned {@link CompletePoint} will be shallow, i.e. all of its associated fields will be
* null except for the identifier.
*
* @param point
* the {@link Point} to copy
* @return the shallow {@link CompletePoint}
*/
public static CompletePoint shallowFrom(final Point point)
{
if (point.bounds() == null)
{
throw new CoreException("Point parameter bounds were null");
}
return new CompletePoint(point.getIdentifier()).withBoundsExtendedBy(point.bounds());
}
public CompletePoint(final Long identifier, final Location location,
final Map tags, final Set relationIdentifiers)
{
super(new EmptyAtlas());
if (identifier == null)
{
throw new CoreException("Identifier can never be null.");
}
this.bounds = location != null ? location.bounds() : null;
this.identifier = identifier;
this.location = location;
this.tags = tags;
this.relationIdentifiers = relationIdentifiers;
}
CompletePoint(final long identifier)
{
this(identifier, null, null, null);
}
@Override
public void addTagChangeListener(final TagChangeListener tagChangeListener)
{
this.tagChangeDelegate.addTagChangeListener(tagChangeListener);
}
@Override
public Rectangle bounds()
{
return this.bounds;
}
@Override
public CompleteItemType completeItemType()
{
return CompleteItemType.POINT;
}
public CompletePoint copy()
{
return new CompletePoint(this.identifier, this.location, this.tags,
this.relationIdentifiers);
}
@Override
public boolean equals(final Object other)
{
if (other instanceof CompletePoint)
{
final CompletePoint that = (CompletePoint) other;
return CompleteEntity.basicEqual(this, that)
&& Objects.equals(this.getLocation(), that.getLocation());
}
return false;
}
@Override
public void fireTagChangeEvent(final TagChangeEvent tagChangeEvent)
{
this.tagChangeDelegate.fireTagChangeEvent(tagChangeEvent);
}
@Override
public long getIdentifier()
{
return this.identifier;
}
@Override
public Location getLocation()
{
return this.location;
}
@Override
public Map getTags()
{
return this.tags;
}
@Override
public int hashCode()
{
return super.hashCode();
}
@Override
public boolean isFull()
{
return this.bounds != null && this.location != null && this.tags != null
&& this.relationIdentifiers != null;
}
@Override
public boolean isShallow()
{
return this.location == null && this.tags == null && this.relationIdentifiers == null;
}
@Override
public String prettify(final PrettifyStringFormat format, final boolean truncate)
{
String separator = "";
if (format == PrettifyStringFormat.MINIMAL_SINGLE_LINE)
{
separator = "";
}
else if (format == PrettifyStringFormat.MINIMAL_MULTI_LINE)
{
separator = "\n";
}
final StringBuilder builder = new StringBuilder();
builder.append(this.getClass().getSimpleName() + " ");
builder.append("[");
builder.append(separator);
builder.append("identifier: " + this.identifier + ", ");
builder.append(separator);
if (this.location != null)
{
builder.append("location: " + this.location + ", ");
builder.append(separator);
}
if (this.tags != null)
{
builder.append("tags: " + new TreeMap<>(this.tags) + ", ");
builder.append(separator);
}
if (this.relationIdentifiers != null)
{
builder.append("parentRelations: " + new TreeSet<>(this.relationIdentifiers).toString()
+ ", ");
builder.append(separator);
}
if (this.bounds != null)
{
builder.append("bounds: " + this.bounds.toWkt() + ", ");
builder.append(separator);
}
builder.append("]");
return builder.toString();
}
@Override
public Set relationIdentifiers()
{
return this.relationIdentifiers;
}
@Override
public Set relations()
{
/*
* Note that the Relations returned by this method will technically break the Located
* contract, since they have null bounds.
*/
return this.relationIdentifiers == null ? null
: this.relationIdentifiers.stream().map(CompleteRelation::new)
.collect(Collectors.toSet());
}
@Override
public void removeTagChangeListeners()
{
this.tagChangeDelegate.removeTagChangeListeners();
}
@Override
public void setTags(final Map tags)
{
this.tags = tags != null ? new HashMap<>(tags) : null;
}
@Override
public String toString()
{
return this.getClass().getSimpleName() + " [identifier=" + this.identifier + ", location="
+ this.location + ", tags=" + this.tags + ", relationIdentifiers="
+ this.relationIdentifiers + "]";
}
@Override
public String toWkt()
{
if (this.location == null)
{
return null;
}
return this.location.toWkt();
}
@Override
public CompletePoint withAddedRelationIdentifier(final Long relationIdentifier)
{
this.relationIdentifiers.add(relationIdentifier);
return this;
}
public CompletePoint withBoundsExtendedBy(final Rectangle bounds)
{
if (this.bounds == null)
{
this.bounds = bounds;
return this;
}
this.bounds = Rectangle.forLocated(this.bounds, bounds);
return this;
}
@Override
public CompletePoint withGeometry(final Iterable locations)
{
if (!locations.iterator().hasNext())
{
throw new CoreException("Cannot interpret empty Iterable as a Location");
}
return this.withLocation(locations.iterator().next());
}
@Override
public CompletePoint withIdentifier(final long identifier)
{
this.identifier = identifier;
return this;
}
@Override
public CompletePoint withLocation(final Location location)
{
this.location = location;
if (this.location != null)
{
this.bounds = location.bounds();
}
return this;
}
@Override
public CompletePoint withRelationIdentifiers(final Set relationIdentifiers)
{
this.relationIdentifiers = relationIdentifiers;
return this;
}
@Override
public CompletePoint withRelations(final Set relations)
{
this.relationIdentifiers = relations.stream().map(Relation::getIdentifier)
.collect(Collectors.toSet());
return this;
}
@Override
public CompletePoint withRemovedRelationIdentifier(final Long relationIdentifier)
{
this.relationIdentifiers = this.relationIdentifiers.stream()
.filter(keepId -> keepId != relationIdentifier.longValue())
.collect(Collectors.toSet());
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy