/** @methodtype set */
  public SphericCoordinate setLongitude(double longitude) {
    // precondition
    assertIsValidLongitude(longitude);

    SphericCoordinate result = getInstance(this.latitude, longitude, this.radius);

    // postcondition
    assertClassInvariants();
    return result;
  }
  /** @methodtype set */
  public SphericCoordinate setRadius(double radiusInKm) {

    // precondition
    assertIsValidRadius(radiusInKm);

    SphericCoordinate result = getInstance(this.latitude, this.longitude, radiusInKm);

    // postcondition
    assertClassInvariants();
    return result;
  }
  /** @methodtype constructor */
  private SphericCoordinate(double latitude, double longitude, double radiusInKm) {
    // preconditions
    assertIsValidLatitude(latitude);
    assertIsValidLongitude(longitude);
    assertIsValidRadius(radiusInKm);

    this.latitude = latitude;
    this.longitude = longitude;
    this.radius = radiusInKm;

    // postconditions
    assertClassInvariants();
  }
  /**
   * @methodtype conversion
   * @param Coordinate to convert
   * @return SphericCoordinate
   */
  private static SphericCoordinate convertToSpheric(Coordinate other) {
    if (SphericCoordinate.class.isInstance(other)) {
      return (SphericCoordinate) other;
    } else if (CartesianCoordinate.class.isInstance(other)) {
      CartesianCoordinate carOther = (CartesianCoordinate) other;

      double r =
          Math.sqrt(
              Math.pow(carOther.getX(), 2)
                  + Math.pow(carOther.getY(), 2)
                  + Math.pow(carOther.getZ(), 2));
      double latitude = Math.toDegrees(Math.asin(carOther.getZ() / r));
      double longitude = Math.toDegrees(Math.atan2(carOther.getY(), carOther.getX()));

      SphericCoordinate toRet = getSphericCoordinate(latitude, longitude, r);
      toRet.assertClassInvariants();
      return toRet;
    } else {
      throw new UnsupportedOperationException("Unknown Type of Coordinate");
    }
  }