public void addRelation(OSMRelation relation) {
      if (_relations.containsKey(relation.getId())) return;

      if (!(relation.isTag("type", "restriction"))
          && !(relation.isTag("type", "route") && relation.isTag("route", "road"))
          && !(relation.isTag("type", "multipolygon") && relation.hasTag("highway"))
          && !(relation.isTag("type", "level_map"))) {
        return;
      }

      _relations.put(relation.getId(), relation);

      if (_relations.size() % 100 == 0) _log.debug("relations=" + _relations.size());
    }
    /**
     * Handle turn restrictions
     *
     * @param relation
     */
    private void processRestriction(OSMRelation relation) {
      long from = -1, to = -1, via = -1;
      for (OSMRelationMember member : relation.getMembers()) {
        String role = member.getRole();
        if (role.equals("from")) {
          from = member.getRef();
        } else if (role.equals("to")) {
          to = member.getRef();
        } else if (role.equals("via")) {
          via = member.getRef();
        }
      }
      if (from == -1 || to == -1 || via == -1) {
        _log.warn(
            GraphBuilderAnnotation.register(graph, Variety.TURN_RESTRICTION_BAD, relation.getId()));
        return;
      }

      Set<TraverseMode> modes = EnumSet.of(TraverseMode.BICYCLE, TraverseMode.CAR);
      String exceptModes = relation.getTag("except");
      if (exceptModes != null) {
        for (String m : exceptModes.split(";")) {
          if (m.equals("motorcar")) {
            modes.remove(TraverseMode.CAR);
          } else if (m.equals("bicycle")) {
            modes.remove(TraverseMode.BICYCLE);
            _log.warn(
                GraphBuilderAnnotation.register(
                    graph, Variety.TURN_RESTRICTION_EXCEPTION, via, from));
          }
        }
      }
      modes = TraverseMode.internSet(modes);

      TurnRestrictionTag tag;
      if (relation.isTag("restriction", "no_right_turn")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.NO_TURN);
      } else if (relation.isTag("restriction", "no_left_turn")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.NO_TURN);
      } else if (relation.isTag("restriction", "no_straight_on")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.NO_TURN);
      } else if (relation.isTag("restriction", "no_u_turn")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.NO_TURN);
      } else if (relation.isTag("restriction", "only_straight_on")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.ONLY_TURN);
      } else if (relation.isTag("restriction", "only_right_turn")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.ONLY_TURN);
      } else if (relation.isTag("restriction", "only_left_turn")) {
        tag = new TurnRestrictionTag(via, TurnRestrictionType.ONLY_TURN);
      } else {
        _log.warn(
            GraphBuilderAnnotation.register(
                graph, Variety.TURN_RESTRICTION_UNKNOWN, relation.getTag("restriction")));
        return;
      }
      TurnRestriction restriction = new TurnRestriction();
      restriction.type = tag.type;
      restriction.modes = modes;
      turnRestrictionsByTag.put(tag, restriction);

      MapUtils.addToMapList(turnRestrictionsByFromWay, from, tag);
      MapUtils.addToMapList(turnRestrictionsByToWay, to, tag);
    }