001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Collection; 005import java.util.HashSet; 006import java.util.Objects; 007import java.util.Set; 008 009/** 010 * This is an extension of {@link RelationMember} that stores the parent relation and the index in it in addition to the role/child. 011 */ 012public class RelationToChildReference { 013 014 /** 015 * Replies a set of all {@link RelationToChildReference}s for a given child primitive. 016 * 017 * @param child the child primitive 018 * @return a set of all {@link RelationToChildReference}s for a given child primitive 019 */ 020 public static Set<RelationToChildReference> getRelationToChildReferences(OsmPrimitive child) { 021 Set<Relation> parents = OsmPrimitive.getFilteredSet(child.getReferrers(), Relation.class); 022 Set<RelationToChildReference> references = new HashSet<>(); 023 for (Relation parent: parents) { 024 for (int i = 0; i < parent.getMembersCount(); i++) { 025 if (parent.getMember(i).refersTo(child)) { 026 references.add(new RelationToChildReference(parent, i, parent.getMember(i))); 027 } 028 } 029 } 030 return references; 031 } 032 033 /** 034 * Replies a set of all {@link RelationToChildReference}s for a collection of child primitives 035 * 036 * @param children the collection of child primitives 037 * @return a set of all {@link RelationToChildReference}s to the children in the collection of child 038 * primitives 039 */ 040 public static Set<RelationToChildReference> getRelationToChildReferences(Collection<? extends OsmPrimitive> children) { 041 Set<RelationToChildReference> references = new HashSet<>(); 042 for (OsmPrimitive child: children) { 043 references.addAll(getRelationToChildReferences(child)); 044 } 045 return references; 046 } 047 048 private final Relation parent; 049 private final int position; 050 private final String role; 051 private final OsmPrimitive child; 052 053 /** 054 * Create a new {@link RelationToChildReference} 055 * @param parent The parent relation 056 * @param position The position of the child in the parent 057 * @param role The role of the child 058 * @param child The actual child (member of parent) 059 */ 060 public RelationToChildReference(Relation parent, int position, String role, OsmPrimitive child) { 061 this.parent = parent; 062 this.position = position; 063 this.role = role; 064 this.child = child; 065 } 066 067 /** 068 * Create a new {@link RelationToChildReference} 069 * @param parent The parent relation 070 * @param position The position of the child in the parent 071 * @param member The role and relation for the child 072 */ 073 public RelationToChildReference(Relation parent, int position, RelationMember member) { 074 this(parent, position, member.getRole(), member.getMember()); 075 } 076 077 /** 078 * Get the parent relation 079 * @return The parent 080 */ 081 public Relation getParent() { 082 return parent; 083 } 084 085 /** 086 * Get the position of the child in the parent 087 * @return The position of the child 088 */ 089 public int getPosition() { 090 return position; 091 } 092 093 /** 094 * Get the role of the child 095 * @return The role 096 */ 097 public String getRole() { 098 return role; 099 } 100 101 /** 102 * Get the actual child 103 * @return The child 104 */ 105 public OsmPrimitive getChild() { 106 return child; 107 } 108 109 @Override 110 public boolean equals(Object obj) { 111 if (this == obj) return true; 112 if (obj == null || getClass() != obj.getClass()) return false; 113 RelationToChildReference that = (RelationToChildReference) obj; 114 return position == that.position && 115 Objects.equals(parent, that.parent) && 116 Objects.equals(role, that.role) && 117 Objects.equals(child, that.child); 118 } 119 120 @Override 121 public int hashCode() { 122 return Objects.hash(parent, position, role, child); 123 } 124}