예제 #1
0
  /**
   * populates the model with the relation members in relation my and their
   *
   * @param my my relation. Must not be null.
   * @param their their relation. Must not be null.
   * @throws IllegalArgumentException if my is null
   * @throws IllegalArgumentException if their is null
   */
  public void populate(Relation my, Relation their) {
    this.myDataset = my.getDataSet();

    CheckParameterUtil.ensureParameterNotNull(my, "my");
    CheckParameterUtil.ensureParameterNotNull(their, "their");

    getMergedEntries().clear();
    getMyEntries().clear();
    getTheirEntries().clear();

    for (RelationMember n : my.getMembers()) {
      getMyEntries().add(n);
    }
    for (RelationMember n : their.getMembers()) {
      getTheirEntries().add(n);
    }
    if (myAndTheirEntriesEqual()) {
      for (RelationMember m : getMyEntries()) {
        getMergedEntries().add(cloneEntryForMergedList(m));
      }
      setFrozen(true);
    } else {
      setFrozen(false);
    }

    fireModelDataChanged();
  }
예제 #2
0
  @Override
  public boolean isFixable(TestError testError) {
    if (!(testError.getTester() instanceof DuplicateRelation)
        || testError.getCode() == SAME_RELATION) return false;

    // We fix it only if there is no more than one relation that is relation member.
    Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
    HashSet<Relation> relations = new HashSet<Relation>();

    for (OsmPrimitive osm : sel)
      if (osm instanceof Relation) {
        relations.add((Relation) osm);
      }

    if (relations.size() < 2) return false;

    int relationsWithRelations = 0;
    for (Relation w : relations) {
      List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class);
      if (!rel.isEmpty()) {
        ++relationsWithRelations;
      }
    }
    return (relationsWithRelations <= 1);
  }
예제 #3
0
 protected Relation createRouteMaster(LineType line) {
   Relation r = createPtRelation(OSM_ROUTE_MASTER, line);
   switch (line.getTransportModeName()) {
     case BUS:
       r.put(OSM_ROUTE_MASTER, OSM_BUS);
       break;
     case AIR:
       r.put(OSM_ROUTE_MASTER, OSM_AERIALWAY);
       break;
     case FERRY:
       r.put(OSM_ROUTE_MASTER, OSM_FERRY);
       break;
     case METRO:
       r.put(OSM_ROUTE_MASTER, OSM_SUBWAY);
       break;
     case TRAIN:
       r.put(OSM_ROUTE_MASTER, OSM_TRAIN);
       break;
     case TRAMWAY:
       r.put(OSM_ROUTE_MASTER, OSM_TRAM);
       break;
     case TROLLEYBUS:
       r.put(OSM_ROUTE_MASTER, OSM_TROLLEYBUS);
       break;
     default:
       Main.warn("Unsupported transport mode: " + line.getTransportModeName());
   }
   r.put("ref", line.getNumber());
   r.put(
       "name",
       line.getTransportModeName().value() + " " + line.getNumber() + ": " + line.getName());
   return r;
 }
 /**
  * Returns the set of incomplete members of the given relations.
  *
  * @param rels The relations to inspect.
  * @return The set of incomplete members of the given relations.
  */
 public Set<OsmPrimitive> buildSetOfIncompleteMembers(Collection<Relation> rels) {
   Set<OsmPrimitive> ret = new HashSet<OsmPrimitive>();
   for (Relation r : rels) {
     ret.addAll(r.getIncompleteMembers());
   }
   return ret;
 }
예제 #5
0
    /**
     * Extract and store relation information based on the relation member
     *
     * @param src The relation member to store information about
     */
    public RelMember(RelationMember src) {
      role = src.getRole();
      type = src.getType();
      rel_id = 0;
      coor = new ArrayList<LatLon>();

      if (src.isNode()) {
        Node r = src.getNode();
        tags = r.getKeys();
        coor = new ArrayList<LatLon>(1);
        coor.add(r.getCoor());
      }
      if (src.isWay()) {
        Way r = src.getWay();
        tags = r.getKeys();
        List<Node> wNodes = r.getNodes();
        coor = new ArrayList<LatLon>(wNodes.size());
        for (Node wNode : wNodes) {
          coor.add(wNode.getCoor());
        }
      }
      if (src.isRelation()) {
        Relation r = src.getRelation();
        tags = r.getKeys();
        rel_id = r.getId();
        coor = new ArrayList<LatLon>();
      }
    }
예제 #6
0
  public void produceRelation(HashSet<Channel> subset, int n) {
    if (isProduced(subset)) {
      return;
    }
    LinkedList<OsmPrimitive> ways = new LinkedList<OsmPrimitive>();
    Iterator<Channel> cit = subset.iterator();
    while (cit.hasNext()) {
      Channel c = cit.next();
      // System.out.println(c.getWay().getId());
      if (!(ways.contains(
          plugin.getOsmlayer().data.getPrimitiveById(c.getWay().getId(), OsmPrimitiveType.WAY)))) {
        ways.add(
            plugin.getOsmlayer().data.getPrimitiveById(c.getWay().getId(), OsmPrimitiveType.WAY));
      }
    }
    Main.map.mapView.setActiveLayer(plugin.getOsmlayer());
    plugin.getOsmlayer().data.setSelected(ways);

    Relation jrelation = new Relation();
    jrelation.put("type", "junction");
    jrelation.put("n", Integer.toString(n));
    for (int i = 0; i < ways.size(); i++) {
      jrelation.addMember(new RelationMember("part of", ways.get(i)));
    }

    plugin.getOsmlayer().data.addPrimitive(jrelation);
  }
예제 #7
0
 @Override
 protected void parseRelations(List<Osmformat.Relation> osmRels) {
   if (exception == null) {
     try {
       for (Osmformat.Relation r : osmRels) {
         final Info info = r.getInfo();
         if (!info.hasVersion()) discourageUpload = true;
         final Relation rel = new Relation(r.getId(), info.hasVersion() ? info.getVersion() : 1);
         setMetadata(rel, info);
         Map<String, String> keys = new HashMap<>();
         for (int i = 0; i < r.getKeysCount(); i++) {
           keys.put(getStringById(r.getKeys(i)), getStringById(r.getVals(i)));
         }
         rel.setKeys(keys);
         long previousId = 0; // Member ids are delta coded
         Collection<RelationMemberData> members = new ArrayList<>();
         for (int i = 0; i < r.getMemidsCount(); i++) {
           members.add(
               new RelationMemberData(
                   getStringById(r.getRolesSid(i)),
                   mapOsmType(r.getTypes(i)),
                   previousId += r.getMemids(i)));
         }
         relations.put(rel.getUniqueId(), members);
         externalIdMap.put(rel.getPrimitiveId(), rel);
       }
     } catch (IllegalDataException e) {
       exception = e;
     }
   }
   if (discourageUpload) ds.setUploadDiscouraged(true);
 }
예제 #8
0
  protected Relation parseRelation() throws XMLStreamException {
    RelationData rd = new RelationData();
    readCommon(rd);
    Relation r = new Relation(rd.getId(), rd.getVersion());
    r.setVisible(rd.isVisible());
    r.load(rd);
    externalIdMap.put(rd.getPrimitiveId(), r);

    Collection<RelationMemberData> members = new ArrayList<RelationMemberData>();
    while (true) {
      int event = parser.next();
      if (event == XMLStreamConstants.START_ELEMENT) {
        if (parser.getLocalName().equals("member")) {
          members.add(parseRelationMember(r));
        } else if (parser.getLocalName().equals("tag")) {
          parseTag(r);
        } else {
          parseUnknown();
        }
      } else if (event == XMLStreamConstants.END_ELEMENT) {
        break;
      }
    }
    if (r.isDeleted() && members.size() > 0) {
      System.out.println(tr("Deleted relation {0} contains members", r.getUniqueId()));
      members = new ArrayList<RelationMemberData>();
    }
    relations.put(rd.getUniqueId(), members);
    return r;
  }
예제 #9
0
  /**
   * Formats a name for a relation
   *
   * @param relation the relation
   * @return the name
   */
  @Override
  public String format(Relation relation) {
    StringBuilder name = new StringBuilder();
    if (relation.isIncomplete()) {
      name.append(tr("incomplete"));
    } else {
      TaggingPreset preset =
          TaggingPresetNameTemplateList.getInstance().findPresetTemplate(relation);

      formatRelationNameAndType(relation, name, preset);

      int mbno = relation.getMembersCount();
      name.append(trn("{0} member", "{0} members", mbno, mbno));

      if (relation.hasIncompleteMembers()) {
        name.append(", ").append(tr("incomplete"));
      }

      name.append(")");
    }
    decorateNameWithId(name, relation);

    String result = name.toString();
    for (NameFormatterHook hook : formatHooks) {
      String hookResult = hook.checkFormat(relation, result);
      if (hookResult != null) return hookResult;
    }

    return result;
  }
예제 #10
0
  @Override
  public void mouseClicked(MouseEvent e) {
    if (Main.main.getCurrentDataSet() == null) return;

    Way way = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
    Collection<Relation> selectedRelations = Main.main.getCurrentDataSet().getSelectedRelations();

    if (way != null) {

      if (selectedRelations.isEmpty()) {
        JOptionPane.showMessageDialog(Main.parent, tr("No relation is selected"));
      }

      for (OsmPrimitive rel : selectedRelations) {
        Relation r = (Relation) rel;
        RelationMember foundMember = null;
        for (RelationMember member : r.getMembers()) {
          if (member.getMember() == way) {
            foundMember = member;
            break;
          }
        }

        if (foundMember != null) {
          Main.main.undoRedo.add(new RemoveRelationMemberCommand(r, new RelationMember("", way)));
        } else {
          Relation newRelation = new Relation(r);
          newRelation.addMember(new RelationMember("", way));
          Main.main.undoRedo.add(new ChangeCommand(r, newRelation));
        }
      }
    }
  }
  @Test
  public void testBackrefrenceForWay_Full() throws OsmTransferException {
    Way w = lookupWay(ds, 1);
    assertNotNull(w);
    // way with name "way-1" is referred to by two relations
    //

    OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(w);
    reader.setReadFull(true);
    DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE);
    assertEquals(6, referers.getWays().size()); // 6 ways referred by two relations
    for (Way w1 : referers.getWays()) {
      assertEquals(false, w1.isIncomplete());
    }
    assertEquals(2, referers.getRelations().size()); // two relations referring to
    Set<Long> expectedNodeIds = new HashSet<Long>();
    for (Way way : referers.getWays()) {
      Way orig = (Way) ds.getPrimitiveById(way);
      for (Node n : orig.getNodes()) {
        expectedNodeIds.add(n.getId());
      }
    }
    assertEquals(expectedNodeIds.size(), referers.getNodes().size());
    for (Node n : referers.getNodes()) {
      assertEquals(true, expectedNodeIds.contains(n.getId()));
    }

    Relation r = lookupRelation(referers, 0);
    assertNotNull(r);
    assertEquals(false, r.isIncomplete());
    r = lookupRelation(referers, 1);
    assertEquals(false, r.isIncomplete());
  }
 void addRelationMembers(Relation r) {
   add(trn("{0} Member: ", "{0} Members: ", r.getMembersCount(), r.getMembersCount()));
   for (RelationMember m : r.getMembers()) {
     s.append(INDENT).append(INDENT);
     addHeadline(m.getMember());
     s.append(tr(" as \"{0}\"", m.getRole()));
     s.append(NL);
   }
 }
예제 #13
0
 private static final boolean addStopToRoute(Relation route, OsmPrimitive stop) {
   if (route.getMembersCount() == 0
       || !route.getMember(route.getMembersCount() - 1).getMember().equals(stop)) {
     route.addMember(new RelationMember(stop.get(OSM_PUBLIC_TRANSPORT), stop));
     return true;
   } else {
     return false;
   }
 }
예제 #14
0
 @Override
 public void visit(Relation r) {
   if (!r.isUsable() || r.hasIncompleteMembers()) return;
   List<RelationMember> rMembers = r.getMembers();
   Map<String, String> rkeys = r.getKeys();
   for (String key : ignoreKeys) rkeys.remove(key);
   RelationPair rKey = new RelationPair(rMembers, rkeys);
   relations.put(rKey, r);
   relations_nokeys.put(rMembers, r);
 }
 /**
  * Populates the turn restriction editor model with a turn restriction. {@code turnRestriction} is
  * an arbitrary relation. A tag type=restriction isn't required. If it is missing, it is added
  * here. {@code turnRestriction} must not be null and it must belong to a dataset.
  *
  * @param turnRestriction the turn restriction
  * @throws IllegalArgumentException thrown if turnRestriction is null
  * @throws IllegalArgumentException thrown if turnRestriction doesn't belong to a dataset
  */
 public void populate(Relation turnRestriction) {
   CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction");
   if (turnRestriction.getDataSet() != null && turnRestriction.getDataSet() != layer.data) {
     throw new IllegalArgumentException(
         // don't translate - it's a technical message
         MessageFormat.format(
             "turnRestriction {0} must not belong to a different dataset than the dataset of layer ''{1}''",
             turnRestriction.getId(), layer.getName()));
   }
   initFromTurnRestriction(turnRestriction);
 }
 /**
  * Replies true if {@code tp1} and {@code tp2} have the same tags and the same members
  *
  * @param tp1 a turn restriction. Must not be null.
  * @param tp2 a turn restriction . Must not be null.
  * @return true if {@code tp1} and {@code tp2} have the same tags and the same members
  * @throws IllegalArgumentException thrown if {@code tp1} is null
  * @throws IllegalArgumentException thrown if {@code tp2} is null
  */
 public static boolean hasSameMembersAndTags(Relation tp1, Relation tp2)
     throws IllegalArgumentException {
   CheckParameterUtil.ensureParameterNotNull(tp1, "tp1");
   CheckParameterUtil.ensureParameterNotNull(tp2, "tp2");
   if (!TagCollection.from(tp1).asSet().equals(TagCollection.from(tp2).asSet())) return false;
   if (tp1.getMembersCount() != tp2.getMembersCount()) return false;
   for (int i = 0; i < tp1.getMembersCount(); i++) {
     if (!tp1.getMember(i).equals(tp2.getMember(i))) return false;
   }
   return true;
 }
 public RelationMemberConflictDecision(Relation relation, int pos) {
   CheckParameterUtil.ensureParameterNotNull(relation, "relation");
   RelationMember member = relation.getMember(pos);
   if (member == null)
     throw new IndexOutOfBoundsException(
         tr(
             "Position {0} is out of range. Current number of members is {1}.",
             pos, relation.getMembersCount()));
   this.relation = relation;
   this.pos = pos;
   this.originalPrimitive = member.getMember();
   this.role = member.hasRole() ? member.getRole() : "";
   this.decision = UNDECIDED;
 }
예제 #18
0
  /**
   * Will add own multipolygon relation to the "previously existing" relations. Fixup is done by
   * fixRelations
   *
   * @param inner List of already closed inner ways
   * @param outer The outer way
   * @return The list of relation with roles to add own relation to
   */
  private RelationRole addOwnMultigonRelation(Collection<Way> inner, Way outer) {
    if (inner.isEmpty()) return null;
    // Create new multipolygon relation and add all inner ways to it
    Relation newRel = new Relation();
    newRel.put("type", "multipolygon");
    for (Way w : inner) {
      newRel.addMember(new RelationMember("inner", w));
    }
    cmds.add(new AddCommand(newRel));

    // We don't add outer to the relation because it will be handed to fixRelations()
    // which will then do the remaining work.
    return new RelationRole(newRel, "outer");
  }
예제 #19
0
 public void visit(Relation r) {
   if (r.isNewOrUndeleted() || r.isModified() || r.isDeleted()) {
     hull.add(r);
     for (OsmPrimitive p : r.getMemberPrimitives()) {
       // add new relation members. Don't include modified
       // relation members. r shouldn't refer to deleted primitives,
       // so wont check here for deleted primitives here
       //
       if (p.isNewOrUndeleted()) {
         p.visit(this);
       }
     }
   }
 }
예제 #20
0
 public void build(Collection<Relation> relations) {
   this.relations = new HashSet<Relation>();
   for (Relation relation : relations) {
     if (!relation.isNewOrUndeleted()) {
       continue;
     }
     this.relations.add(relation);
     for (RelationMember m : relation.getMembers()) {
       if (m.isRelation() && m.getMember().isNewOrUndeleted()) {
         addDependency(relation, (Relation) m.getMember());
       }
     }
   }
 }
 /**
  * Applies the current state in the model to a turn restriction
  *
  * @param turnRestriction the turn restriction. Must not be null.
  */
 public void apply(Relation turnRestriction) {
   CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction");
   TagCollection tags = tagEditorModel.getTagCollection();
   turnRestriction.removeAll();
   tags.applyTo(turnRestriction);
   memberModel.applyTo(turnRestriction);
 }
예제 #22
0
 public static String generateRelationMemberSigtext(TrustRelation trust, String memID) {
   Relation r = (Relation) trust.getOsmPrimitive();
   List<RelationMember> members = r.getMembers();
   RelationMember member = null;
   for (RelationMember m : members) {
     if (TrustOsmPrimitive.createUniqueObjectIdentifier(m.getMember()).equals(memID)) {
       member = m;
       break;
     }
   }
   if (member == null) return "";
   String sigtext = "RelID=" + r.getUniqueId() + "\n";
   sigtext +=
       TrustOsmPrimitive.createUniqueObjectIdentifier(member.getMember()) + "," + member.getRole();
   return sigtext;
 }
예제 #23
0
파일: Addresses.java 프로젝트: jawohl/josm
 protected List<Relation> getAndCheckAssociatedStreets(OsmPrimitive p) {
   List<Relation> list = OsmPrimitive.getFilteredList(p.getReferrers(), Relation.class);
   for (Iterator<Relation> it = list.iterator(); it.hasNext(); ) {
     Relation r = it.next();
     if (!r.hasTag("type", ASSOCIATED_STREET)) {
       it.remove();
     }
   }
   if (list.size() > 1) {
     List<OsmPrimitive> errorList = new ArrayList<OsmPrimitive>(list);
     errorList.add(0, p);
     errors.add(
         new AddressError(
             MULTIPLE_STREET_RELATIONS, errorList, tr("Multiple associatedStreet relations")));
   }
   return list;
 }
예제 #24
0
 @Override
 public void startTest(ProgressMonitor monitor) {
   super.startTest(monitor);
   multipolygonways = new LinkedList<Way>();
   for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
     if (r.isUsable() && r.isMultipolygon()) {
       for (RelationMember m : r.getMembers()) {
         if (m.getMember() != null
             && m.getMember() instanceof Way
             && m.getMember().isUsable()
             && !m.getMember().isTagged()) {
           multipolygonways.add((Way) m.getMember());
         }
       }
     }
   }
 }
예제 #25
0
  static List<Double> loadLengths(Relation r, String key, double lengthBound) {
    final List<Double> result = new ArrayList<Double>();

    if (r != null && r.get(key) != null) {
      for (String s : Constants.SPLIT_PATTERN.split(r.get(key))) {
        // TODO what should the exact input be (there should probably be
        // a unit (m))
        final Double length = Double.parseDouble(s.trim());

        if (length > lengthBound) {
          result.add(length);
        }
      }
    }

    return result;
  }
예제 #26
0
 /**
  * Replies the subset of relations in <code>relations</code> which are not referring to any new
  * relation
  *
  * @param relations a list of relations
  * @return the subset of relations in <code>relations</code> which are not referring to any new
  *     relation
  */
 protected List<Relation> filterRelationsNotReferringToNewRelations(
     Collection<Relation> relations) {
   List<Relation> ret = new LinkedList<Relation>();
   for (Relation relation : relations) {
     boolean refersToNewRelation = false;
     for (RelationMember m : relation.getMembers()) {
       if (m.isRelation() && m.getMember().isNewOrUndeleted()) {
         refersToNewRelation = true;
         break;
       }
     }
     if (!refersToNewRelation) {
       ret.add(relation);
     }
   }
   return ret;
 }
예제 #27
0
 private SearchContext(String state) throws ParseError {
   m = SearchCompiler.compile(state);
   n = SearchCompiler.compile('-' + state);
   ds.addPrimitive(n1);
   ds.addPrimitive(n2);
   w1.addNode(n1);
   w1.addNode(n2);
   w2.addNode(n1);
   w2.addNode(n2);
   ds.addPrimitive(w1);
   ds.addPrimitive(w2);
   r1.addMember(new RelationMember("", w1));
   r1.addMember(new RelationMember("", w2));
   r2.addMember(new RelationMember("", w1));
   r2.addMember(new RelationMember("", w2));
   ds.addPrimitive(r1);
   ds.addPrimitive(r2);
 }
예제 #28
0
        @Override
        public int compare(Relation r1, Relation r2) {
          // TODO This doesn't work correctly with formatHooks

          TaggingPreset preset1 =
              TaggingPresetNameTemplateList.getInstance().findPresetTemplate(r1);
          TaggingPreset preset2 =
              TaggingPresetNameTemplateList.getInstance().findPresetTemplate(r2);

          if (preset1 != null || preset2 != null) {
            StringBuilder name1 = new StringBuilder();
            formatRelationNameAndType(r1, name1, preset1);
            StringBuilder name2 = new StringBuilder();
            formatRelationNameAndType(r2, name2, preset2);

            int comp = name1.toString().compareTo(name2.toString());
            if (comp != 0) return comp;
          } else {

            String type1 = getRelationTypeName(r1);
            String type2 = getRelationTypeName(r2);

            int comp = ALPHANUM_COMPARATOR.compare(type1, type2);
            if (comp != 0) return comp;

            String name1 = getRelationName(r1);
            String name2 = getRelationName(r2);

            comp = ALPHANUM_COMPARATOR.compare(name1, name2);
            if (comp != 0) return comp;
          }

          if (r1.getMembersCount() != r2.getMembersCount())
            return (r1.getMembersCount() > r2.getMembersCount()) ? 1 : -1;

          int comp =
              Boolean.valueOf(r1.hasIncompleteMembers())
                  .compareTo(Boolean.valueOf(r2.hasIncompleteMembers()));
          if (comp != 0) return comp;

          if (r1.getUniqueId() > r2.getUniqueId()) return 1;
          else if (r1.getUniqueId() < r2.getUniqueId()) return -1;
          else return 0;
        }
예제 #29
0
  /**
   * Adds the previously removed relations again to the outer way. If there are multiple
   * multipolygon relations where the joined areas were in "outer" role a new relation is created
   * instead with all members of both. This function depends on multigon relations to be valid
   * already, it won't fix them.
   *
   * @param rels List of relations with roles the (original) ways were part of
   * @param outer The newly created outer area/way
   * @param ownMultipol elements to directly add as outer
   * @param relationsToDelete set of relations to delete.
   */
  private void fixRelations(
      List<RelationRole> rels,
      Way outer,
      RelationRole ownMultipol,
      Set<Relation> relationsToDelete) {
    List<RelationRole> multiouters = new ArrayList<RelationRole>();

    if (ownMultipol != null) {
      multiouters.add(ownMultipol);
    }

    for (RelationRole r : rels) {
      if (r.rel.isMultipolygon() && r.role.equalsIgnoreCase("outer")) {
        multiouters.add(r);
        continue;
      }
      // Add it back!
      Relation newRel = new Relation(r.rel);
      newRel.addMember(new RelationMember(r.role, outer));
      cmds.add(new ChangeCommand(r.rel, newRel));
    }

    Relation newRel;
    switch (multiouters.size()) {
      case 0:
        return;
      case 1:
        // Found only one to be part of a multipolygon relation, so just add it back as well
        newRel = new Relation(multiouters.get(0).rel);
        newRel.addMember(new RelationMember(multiouters.get(0).role, outer));
        cmds.add(new ChangeCommand(multiouters.get(0).rel, newRel));
        return;
      default:
        // Create a new relation with all previous members and (Way)outer as outer.
        newRel = new Relation();
        for (RelationRole r : multiouters) {
          // Add members
          for (RelationMember rm : r.rel.getMembers())
            if (!newRel.getMembers().contains(rm)) {
              newRel.addMember(rm);
            }
          // Add tags
          for (String key : r.rel.keySet()) {
            newRel.put(key, r.rel.get(key));
          }
          // Delete old relation
          relationsToDelete.add(r.rel);
        }
        newRel.addMember(new RelationMember("outer", outer));
        cmds.add(new AddCommand(newRel));
    }
  }
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((decision == null) ? 0 : decision.hashCode());
   result = prime * result + ((originalPrimitive == null) ? 0 : originalPrimitive.hashCode());
   result = prime * result + pos;
   result = prime * result + ((relation == null) ? 0 : relation.hashCode());
   result = prime * result + ((role == null) ? 0 : role.hashCode());
   return result;
 }