001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.vector; 003 004import java.util.ArrayList; 005import java.util.Collections; 006import java.util.List; 007 008import org.openstreetmap.josm.data.osm.BBox; 009import org.openstreetmap.josm.data.osm.IPrimitive; 010import org.openstreetmap.josm.data.osm.IRelation; 011import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 012import org.openstreetmap.josm.data.osm.UniqueIdGenerator; 013import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 014 015/** 016 * The "Relation" type for vectors 017 * 018 * @author Taylor Smock 019 * @since 17862 020 */ 021public class VectorRelation extends VectorPrimitive implements IRelation<VectorRelationMember> { 022 private static final UniqueIdGenerator RELATION_ID_GENERATOR = new UniqueIdGenerator(); 023 private final List<VectorRelationMember> members = new ArrayList<>(); 024 private BBox cachedBBox; 025 026 /** 027 * Create a new relation for a layer 028 * @param layer The layer the relation will belong to 029 */ 030 public VectorRelation(String layer) { 031 super(layer); 032 } 033 034 @Override 035 public UniqueIdGenerator getIdGenerator() { 036 return RELATION_ID_GENERATOR; 037 } 038 039 @Override 040 public void accept(PrimitiveVisitor visitor) { 041 visitor.visit(this); 042 } 043 044 @Override 045 public BBox getBBox() { 046 if (this.cachedBBox == null) { 047 BBox tBBox = new BBox(); 048 for (IPrimitive member : this.getMemberPrimitivesList()) { 049 tBBox.add(member.getBBox()); 050 } 051 this.cachedBBox = tBBox.toImmutable(); 052 } 053 return this.cachedBBox; 054 } 055 056 protected void addRelationMember(VectorRelationMember member) { 057 this.members.add(member); 058 member.getMember().addReferrer(this); 059 cachedBBox = null; 060 } 061 062 /** 063 * Remove the first instance of a member from the relation 064 * 065 * @param member The member to remove 066 */ 067 protected void removeRelationMember(VectorRelationMember member) { 068 this.members.remove(member); 069 if (!this.members.contains(member)) { 070 member.getMember().removeReferrer(this); 071 } 072 } 073 074 @Override 075 public int getMembersCount() { 076 return this.members.size(); 077 } 078 079 @Override 080 public VectorRelationMember getMember(int index) { 081 return this.members.get(index); 082 } 083 084 @Override 085 public List<VectorRelationMember> getMembers() { 086 return Collections.unmodifiableList(this.members); 087 } 088 089 @Override 090 public void setMembers(List<VectorRelationMember> members) { 091 this.members.clear(); 092 this.members.addAll(members); 093 } 094 095 @Override 096 public long getMemberId(int idx) { 097 return this.getMember(idx).getMember().getId(); 098 } 099 100 @Override 101 public String getRole(int idx) { 102 return this.getMember(idx).getRole(); 103 } 104 105 @Override 106 public OsmPrimitiveType getMemberType(int idx) { 107 return this.getMember(idx).getType(); 108 } 109 110 @Override 111 public OsmPrimitiveType getType() { 112 return this.getMembers().stream().map(VectorRelationMember::getType) 113 .allMatch(OsmPrimitiveType.CLOSEDWAY::equals) ? OsmPrimitiveType.MULTIPOLYGON : OsmPrimitiveType.RELATION; 114 } 115}