@Test
  public void testRing() {
    List<Point> pts = new ArrayList<Point>();
    pts.add(new Point(0.0, 0.0));
    pts.add(new Point(0.0, 1.0));
    pts.add(new Point(1.0, 2.0));
    pts.add(new Point(2.0, 1.0));
    pts.add(new Point(1.0, 0.0));
    pts.add(new Point(0.0, 0.0));
    LinearRing geo = new LinearRing(pts, true);
    assertEquals(1, geo.getNumParts());
    assertEquals(pts.size(), geo.getNumPoints());
    assertFalse(geo.is3D());
    // center: (1.0' 0" E, 1.0' 0" N)
    Geodetic2DPoint center = geo.getCenter();
    assertEquals(1.0, center.getLatitudeAsDegrees(), EPSILON);
    assertEquals(1.0, center.getLongitudeAsDegrees(), EPSILON);

    geo = new LinearRing(geo.getBoundingBox());
    assertEquals(1, geo.getNumParts());
    assertEquals(5, geo.getNumPoints());
    // center: (1.0' 0" E, 1.0' 0" N)
    center = geo.getCenter();
    assertEquals(1.0, center.getLatitudeAsDegrees(), EPSILON);
    assertEquals(1.0, center.getLongitudeAsDegrees(), EPSILON);
  }
  @Test
  public void testPolygon() {
    List<Point> pts = new ArrayList<Point>(6);
    // Outer LinearRing in Polygon must be in clockwise point order
    pts.add(new Point(0.0, 0.0));
    pts.add(new Point(1.0, 0.0));
    pts.add(new Point(2.0, 1.0));
    pts.add(new Point(1.0, 2.0));
    pts.add(new Point(0.0, 1.0));
    pts.add(new Point(0.0, 0.0));
    final LinearRing ring = new LinearRing(pts, true);
    Polygon geo = new Polygon(ring, true);
    assertEquals(1, geo.getNumParts());
    assertNotNull(geo.getPart(0));
    assertEquals(pts.size(), geo.getNumPoints());
    assertFalse(geo.is3D());
    Geodetic2DPoint cp = geo.getCenter();
    // center: (1.0' 0" E, 1.0' 0" N)
    assertEquals(1.0, cp.getLatitudeAsDegrees(), EPSILON);
    assertEquals(1.0, cp.getLongitudeAsDegrees(), EPSILON);

    // create new polygon with outer and inner ring
    pts = new ArrayList<Point>();
    pts.add(new Point(0.2, 0.2));
    pts.add(new Point(0.2, 0.8));
    pts.add(new Point(0.8, 0.8));
    pts.add(new Point(0.8, 0.2));
    pts.add(new Point(0.2, 0.2));
    LinearRing ir = new LinearRing(pts);
    geo = new Polygon(ring, Collections.singletonList(ir));
    assertEquals(2, geo.getNumParts());
    assertEquals(ring.getNumPoints() + ir.getNumPoints(), geo.getNumPoints());
    cp = geo.getCenter();
    // center: (1.0' 0" E, 1.0' 0" N)
    assertEquals(1.0, cp.getLatitudeAsDegrees(), EPSILON);
    assertEquals(1.0, cp.getLongitudeAsDegrees(), EPSILON);
  }
  @Test
  public void testMultiLine() {
    List<Line> lines = new ArrayList<Line>();
    List<Point> pts = new ArrayList<Point>();
    for (int i = 0; i < 10; i++) {
      pts.add(new Point(i * .01 + 0.1, i * .01 + 0.1, true)); // sets 0.0 elevation
    }
    Line line = new Line(pts);
    line.setTessellate(false);
    line.setAltitudeMode(AltitudeModeEnumType.clampToGround);
    lines.add(line);
    pts = new ArrayList<Point>();
    for (int i = 0; i < 10; i++) {
      pts.add(new Point(i * .02 + 0.2, i * .02 + 0.2, 100));
    }
    line = new Line(pts);
    line.setTessellate(true);
    lines.add(line);
    Geometry geo = new MultiLine(lines);
    assertEquals(2, geo.getNumParts());
    assertEquals(20, geo.getNumPoints());
    assertTrue(geo.is3D());
    Geodetic2DBounds bounds = geo.getBoundingBox();
    assertTrue(bounds instanceof Geodetic3DBounds);
    // bounding box of MultiLine must contain bounding box for each of its lines
    assertTrue(bounds.contains(line.getBoundingBox()));

    // (0� 14' 24" E, 0� 14' 24" N) @ 0m
    final Geodetic2DPoint cp = geo.getCenter();
    System.out.println("multiline center=" + cp);
    assertEquals(0.24, cp.getLatitudeAsDegrees(), EPSILON);
    assertEquals(0.24, cp.getLongitudeAsDegrees(), EPSILON);

    List<Point> points = geo.getPoints(); // all 20 points
    assertEquals(20, points.size());
    for (int i = 0; i < 10; i++) {
      assertEquals(pts.get(i), points.get(i + 10));
    }

    List<Geometry> geometries = new ArrayList<Geometry>();
    geometries.add(pts.get(0));
    geometries.add(line);
    geo = new GeometryBag(geometries);
    assertEquals(2, geo.getNumParts());
    assertTrue(geo.is3D());
  }
  @Test
  public void testGeometryBag() {
    List<Geometry> geometries = new ArrayList<Geometry>();
    geometries.add(new Point(2.0, 2.0));
    List<Point> points = new ArrayList<Point>();
    points.add(new Point(0.0, 0.0));
    points.add(new Point(0.0, 1.0));
    points.add(new Point(1.0, 0.0));
    final Line line = new Line(points);
    geometries.add(line);
    GeometryBag geo = new GeometryBag(geometries);
    assertEquals(2, geo.size()); // number of geometries
    assertEquals(2, geo.getNumParts()); // aggregate parts of all geometries
    assertNotNull(geo.getPart(0));
    assertNull(geo.getPart(2));
    assertEquals(1 + points.size(), geo.getNumPoints());
    assertFalse(geo.is3D());
    assertTrue(geo.contains(line));
    assertFalse(geo.isEmpty());

    // center = (1� 15' 0" E, 1� 15' 0" N)
    final Geodetic2DPoint cp = geo.getCenter();
    assertEquals(1.0, cp.getLatitudeAsDegrees(), EPSILON);
    assertEquals(1.0, cp.getLongitudeAsDegrees(), EPSILON);

    geo.clear();
    assertEquals(0, geo.size());
    assertEquals(0, geo.getNumParts());
    assertTrue(geo.isEmpty());
    assertFalse(geo.is3D());

    geometries.clear();
    final Point pt = new Point(30.0, 40.0, 400);
    geometries.add(pt);
    geo = new GeometryBag(geometries);
    assertEquals(1, geo.size());
    assertTrue(geo.is3D());
    Object[] objs = geo.toArray();
    assertTrue(objs.length == 1);
    assertTrue(geo.remove(pt));
    assertEquals(0, geo.size());
    assertNull(geo.getBoundingBox());
  }
  @Test
  public void testClippedAtDateLine() {
    // create outline of Fiji islands which wrap international date line
    List<Point> pts = new ArrayList<Point>();
    final Point firstPt = new Point(-16.68226928264316, 179.900033693558);
    pts.add(firstPt);
    pts.add(new Point(-16.68226928264316, -180));
    pts.add(new Point(-17.01144405215603, -180));
    pts.add(new Point(-17.01144405215603, 179.900033693558));
    pts.add(firstPt);
    Line line = new Line(pts);
    assertTrue(line.clippedAtDateLine());

    // (179� 57' 0" E, 16� 50' 49" S)
    Geodetic2DPoint cp = line.getCenter();
    // System.out.println("Fctr=" + cp.getLatitudeAsDegrees() + " " + cp.getLongitudeAsDegrees());
    assertEquals(-16.846856667399592, cp.getLatitudeAsDegrees(), EPSILON);
    assertEquals(179.950016846779, cp.getLongitudeAsDegrees(), EPSILON);

    LinearRing ring = new LinearRing(pts, true);
    assertTrue(ring.clippedAtDateLine());
    assertEquals(cp, ring.getCenter());
  }