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