001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Collection; 005import java.util.Objects; 006import java.util.Set; 007import java.util.stream.Collectors; 008import java.util.stream.IntStream; 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 return parents.stream().flatMap(parent1 -> IntStream.range(0, parent1.getMembersCount()) 024 .filter(i -> parent1.getMember(i).refersTo(child)) 025 .mapToObj(i -> new RelationToChildReference(parent1, i, parent1.getMember(i)))) 026 .collect(Collectors.toSet()); 027 } 028 029 /** 030 * Replies a set of all {@link RelationToChildReference}s for a collection of child primitives 031 * 032 * @param children the collection of child primitives 033 * @return a set of all {@link RelationToChildReference}s to the children in the collection of child 034 * primitives 035 */ 036 public static Set<RelationToChildReference> getRelationToChildReferences(Collection<? extends OsmPrimitive> children) { 037 return children.stream() 038 .flatMap(child -> getRelationToChildReferences(child).stream()) 039 .collect(Collectors.toSet()); 040 } 041 042 private final Relation parent; 043 private final int position; 044 private final String role; 045 private final OsmPrimitive child; 046 047 /** 048 * Create a new {@link RelationToChildReference} 049 * @param parent The parent relation 050 * @param position The position of the child in the parent 051 * @param role The role of the child 052 * @param child The actual child (member of parent) 053 */ 054 public RelationToChildReference(Relation parent, int position, String role, OsmPrimitive child) { 055 this.parent = parent; 056 this.position = position; 057 this.role = role; 058 this.child = child; 059 } 060 061 /** 062 * Create a new {@link RelationToChildReference} 063 * @param parent The parent relation 064 * @param position The position of the child in the parent 065 * @param member The role and relation for the child 066 */ 067 public RelationToChildReference(Relation parent, int position, RelationMember member) { 068 this(parent, position, member.getRole(), member.getMember()); 069 } 070 071 /** 072 * Get the parent relation 073 * @return The parent 074 */ 075 public Relation getParent() { 076 return parent; 077 } 078 079 /** 080 * Get the position of the child in the parent 081 * @return The position of the child 082 */ 083 public int getPosition() { 084 return position; 085 } 086 087 /** 088 * Get the role of the child 089 * @return The role 090 */ 091 public String getRole() { 092 return role; 093 } 094 095 /** 096 * Get the actual child 097 * @return The child 098 */ 099 public OsmPrimitive getChild() { 100 return child; 101 } 102 103 @Override 104 public boolean equals(Object obj) { 105 if (this == obj) return true; 106 if (obj == null || getClass() != obj.getClass()) return false; 107 RelationToChildReference that = (RelationToChildReference) obj; 108 return position == that.position && 109 Objects.equals(parent, that.parent) && 110 Objects.equals(role, that.role) && 111 Objects.equals(child, that.child); 112 } 113 114 @Override 115 public int hashCode() { 116 return Objects.hash(parent, position, role, child); 117 } 118}