private void assertCorrectEdge(
     Point referencePoint, Point pointOnEdge, int expectedPreviousPoint) {
   ClosestEdge edge = geom.getShell().getClosestEdge(referencePoint, true);
   assertEquals(1, (int) edge.getDistanceToEdge());
   assertEquals(expectedPreviousPoint, edge.getIndexOfPrevious());
   assertEquals(pointOnEdge, edge.getPointOnLine());
   assertEquals(
       new Coordinate(pointOnEdge.getX() + .5, pointOnEdge.getY() + 0.5), edge.getAddedCoord());
   assertEquals(geom, edge.getGeom());
   assertEquals(geom.getShell(), edge.getPart());
 }
 /**
  * @param numGeoms number of expected geometries
  * @param numShellPoints expected number of points in shells of each geometry
  * @param numHoles expected number of holes of each geometry
  * @param numHolesPoints expected number of points in all holes of each geometry
  */
 private void assertPixMapState(
     EditBlackboard map, int numGeoms, int numShellPoints, int numHoles, int numHolesPoints) {
   assertEquals("numGeoms", numGeoms, map.getGeoms().size()); // $NON-NLS-1$
   for (EditGeom geom : map.getGeoms()) {
     assertEquals("numShellPoints", numShellPoints, geom.getShell().getNumPoints()); // $NON-NLS-1$
     assertEquals("numHoles", numHoles, geom.getHoles().size()); // $NON-NLS-1$
     for (PrimitiveShape hole : geom.getHoles()) {
       assertEquals(
           "numHolesPoints ", numHolesPoints, hole.getNumPoints()); // $NON-NLS-1$
     }
   }
 }
  /*
   * Test method for
   * 'net.refractions.udig.tools.edit.support.PrimitiveShape.getClosestEdge(Point)'
   */
  @Test
  public void testGetClosestEdge() {
    bb = new TestEditBlackboard();
    geom = bb.newGeom("id", ShapeType.POLYGON);
    bb.addPoint(10, 10, geom.getShell());
    bb.addPoint(20, 10, geom.getShell());
    bb.addPoint(20, 20, geom.getShell());
    bb.addPoint(10, 20, geom.getShell());
    bb.addPoint(10, 10, geom.getShell());

    // test getClosest for each edge
    assertCorrectEdge(Point.valueOf(12, 9), Point.valueOf(12, 10), 0);
    assertCorrectEdge(Point.valueOf(21, 12), Point.valueOf(20, 12), 1);
    assertCorrectEdge(Point.valueOf(18, 21), Point.valueOf(18, 20), 2);
    assertCorrectEdge(Point.valueOf(9, 18), Point.valueOf(10, 18), 3);
  }
 private void prepareToPath() {
   currentPoint = null;
   points = null;
   nextPoint = null;
   currentShape = null;
   shapes = geom.iterator();
 }
  @Test
  public void testMoveGeom() throws Exception {
    TestEditBlackboard bb = new TestEditBlackboard();
    EditGeom geom = bb.getGeoms().get(0);
    PrimitiveShape shell = geom.getShell();
    bb.addPoint(10, 10, shell);
    bb.addPoint(11, 10, shell);
    bb.addPoint(12, 10, shell);
    bb.addPoint(13, 10, shell);
    bb.addPoint(14, 10, shell);

    bb.moveSelection(1, 0, geom.createSelection());

    assertEquals(Point.valueOf(11, 10), shell.getPoint(0));
    assertEquals(Point.valueOf(12, 10), shell.getPoint(1));
    assertEquals(Point.valueOf(13, 10), shell.getPoint(2));
    assertEquals(Point.valueOf(14, 10), shell.getPoint(3));
    assertEquals(Point.valueOf(15, 10), shell.getPoint(4));
  }
  public Path toPath(Device device) {
    prepareToPath();

    if (geom.getShell().getNumPoints() == 1) {
      Path createPoint = createPointPath(device);
      if (createPoint != null) return createPoint;
    }

    return AWTSWTImageUtils.createPath(this, device);
  }
  /**
   * Returns a shape that can be draw.
   *
   * <p>It is recommended to call getShape() every time a draw is needed because the shape does not
   * update if the EditGeom is updated between draws. getShape is guaranteed to get a shape that is
   * representative of the current state of geom.
   *
   * @return
   */
  public Shape toShape() {
    prepareToPath();

    if (geom.getShell().getNumPoints() == 1) {
      Shape createPoint = createPoint();
      if (createPoint != null) return createPoint;
    }
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);

    path.append(this, false);

    return path;
  }
  @Before
  public void setUp() throws Exception {
    handler = new TestHandler();
    bb = handler.getEditBlackboard();
    geom = bb.newGeom("newFeature", ShapeType.LINE);

    shell = geom.getShell();
    bb.addPoint(10, 10, shell);
    bb.addPoint(11, 10, shell);
    bb.addPoint(10, 10, shell);
    bb.addPoint(2, 20, shell);
    bb.addPoint(2, 20, shell);
    bb.addPoint(4000, 8000, shell);
    bb.addPoint(4000, 8000, shell);
  }
  @Test
  public void testCreateBasedOnShapeType() throws Exception {
    TestEditBlackboard bb = new TestEditBlackboard();
    String fid = "FeatureID";
    EditGeom geom = bb.newGeom(fid, null);
    bb.addPoint(10, 10, geom.getShell());
    EditGeom geom2 = bb.newGeom(fid, null);
    AttributeTypeBuilder builder = new AttributeTypeBuilder();
    builder.setBinding(Geometry.class);
    builder.setName("geom");
    GeometryDescriptor at = builder.buildDescriptor("geom", builder.buildGeometryType());
    bb.addPoint(100, 100, geom2.getShell());

    String fid2 = "FID2";
    EditGeom differentGeom = bb.newGeom(fid2, null);
    bb.addPoint(200, 200, differentGeom.getShell());

    Map<String, Bag> result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(Point.class, result.get(fid2).jts.get(0).getClass());

    differentGeom.setShapeType(ShapeType.LINE);
    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(LineString.class, result.get(fid2).jts.get(0).getClass());

    differentGeom.setShapeType(ShapeType.POLYGON);
    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(Polygon.class, result.get(fid2).jts.get(0).getClass());

    differentGeom.setShapeType(ShapeType.UNKNOWN);
    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(Point.class, result.get(fid2).jts.get(0).getClass());

    bb.addPoint(200, 200, differentGeom.getShell());

    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(Point.class, result.get(fid2).jts.get(0).getClass());

    bb.addPoint(200, 210, differentGeom.getShell());

    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(LineString.class, result.get(fid2).jts.get(0).getClass());

    bb.addPoint(200, 200, differentGeom.getShell());

    result = GeometryCreationUtil.createAllGeoms(geom, Point.class, at, false);
    assertEquals(1, result.get(fid2).jts.size());
    assertEquals(Polygon.class, result.get(fid2).jts.get(0).getClass());
  }
  // Test the move method that declares which coords to move.
  @Test
  public void testMoveVertexSrcDestToMove() throws Exception {
    EventListener l = new EventListener();
    EditBlackboard map =
        new EditBlackboard(SCREEN.x, SCREEN.y, new AffineTransform(), layerToWorld);
    EditGeom geom = map.getGeoms().get(0);
    map.addPoint(10, 10, geom.getShell());
    map.addPoint(10, 10, geom.getShell());
    map.selectionAdd(Point.valueOf(10, 10));
    map.addPoint(10, 10, geom.getShell());

    map.getListeners().add(l);
    map.moveSelection(0, 5, map.getSelection());

    Iterator<Point> iter = map.getSelection().iterator();
    assertEquals(Point.valueOf(10, 15), iter.next());
    assertFalse(iter.hasNext());
    assertEquals(1, map.getCoords(10, 10).size());
    assertEquals(2, map.getCoords(10, 15).size());
    assertEquals(Point.valueOf(10, 15), geom.getShell().getPoint(0));
    assertEquals(Point.valueOf(10, 10), geom.getShell().getPoint(1));

    map.clear();

    // test moving coord when it is the only coord.
    geom = map.getGeoms().get(0);
    map.addPoint(0, 0, geom.getShell());
    map.selectionAdd(Point.valueOf(0, 0));

    map.moveSelection(0, 5, map.getSelection());
    assertEquals(0, map.getCoords(0, 0).size());
    assertEquals(1, map.getCoords(0, 5).size());
    assertEquals(1, geom.getShell().getNumPoints());
    assertEquals(1, geom.getShell().getNumCoords());
    assertEquals(Point.valueOf(0, 5), geom.getShell().getPoint(0));

    map.moveSelection(0, -5, map.getSelection());
    assertEquals(1, map.getCoords(0, 0).size());
    assertEquals(0, map.getCoords(0, 5).size());
    assertEquals(1, geom.getShell().getNumPoints());
    assertEquals(1, geom.getShell().getNumCoords());
    assertEquals(Point.valueOf(0, 0), geom.getShell().getPoint(0));

    map.clear();

    // test moving coord that is in middle of a shape rather than at the beginning
    geom = map.getGeoms().get(0);
    map.addPoint(0, 0, geom.getShell());
    map.addPoint(10, 0, geom.getShell());
    map.addPoint(10, 10, geom.getShell());
    map.selectionAdd(Point.valueOf(10, 10));
    map.addPoint(10, 10, geom.getShell());
    map.addPoint(0, 10, geom.getShell());
    map.addPoint(0, 0, geom.getShell());

    map.moveSelection(0, 5, map.getSelection());

    assertEquals(1, map.getCoords(10, 10).size());
    assertEquals(1, map.getCoords(10, 15).size());
    assertEquals(6, geom.getShell().getNumPoints());
    assertEquals(Point.valueOf(10, 15), geom.getShell().getPoint(2));
    assertEquals(Point.valueOf(10, 10), geom.getShell().getPoint(3));

    map.moveSelection(0, -5, map.getSelection());
    assertEquals(5, geom.getShell().getNumPoints());
    assertEquals(2, map.getCoords(10, 10).size());
    assertEquals(0, map.getCoords(10, 15).size());
    assertEquals(Point.valueOf(10, 10), geom.getShell().getPoint(2));
    assertEquals(Point.valueOf(0, 10), geom.getShell().getPoint(3));

    map.selectionClear();
    map.selectionAdd(Point.valueOf(10, 10));

    map.moveSelection(-10, 0, map.getSelection());
    assertEquals(3, map.getCoords(0, 10).size());
    assertEquals(0, map.getCoords(10, 10).size());
    assertEquals(4, geom.getShell().getNumPoints());
    assertEquals(Point.valueOf(0, 10), geom.getShell().getPoint(2));
    assertEquals(Point.valueOf(0, 0), geom.getShell().getPoint(3));

    map.moveSelection(5, 0, map.getSelection());
    assertEquals(1, map.getCoords(0, 10).size());
    assertEquals(2, map.getCoords(5, 10).size());
    assertEquals(5, geom.getShell().getNumPoints());
    assertEquals(Point.valueOf(5, 10), geom.getShell().getPoint(2));
    assertEquals(Point.valueOf(0, 10), geom.getShell().getPoint(3));

    // test the case where the layer is not in the same projection as the map.
    MathTransform albersToWGS84 =
        CRS.findMathTransform(
            CRS.decode("EPSG:3005"), DefaultGeographicCRS.WGS84, true); // $NON-NLS-1$
    map =
        new EditBlackboard(
            SCREEN.x, SCREEN.y, AffineTransform.getTranslateInstance(0, 0), albersToWGS84);

    map.addPoint(0, 0, map.getGeoms().get(0).getShell());
    Coordinate c = new Coordinate();
    JTS.transform(map.getCoords(0, 0).get(0), c, albersToWGS84);

    assertEquals(0, (int) c.x);
    assertEquals(0, (int) c.y);

    map.selectionAdd(Point.valueOf(0, 0));
    map.moveSelection(10, 5, map.getSelection());

    JTS.transform(map.getCoords(10, 5).get(0), c, albersToWGS84);

    assertEquals(10, (int) c.x);
    assertEquals(5, (int) c.y);
  }
  @Test
  public void testSetup() throws Exception {
    EventListener l = new EventListener();
    EditBlackboard map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    assertPixMapState(map, 1, 0, 0, 0);

    map.addPoint(10, 5, map.getGeoms().get(0).getShell());
    assertPixMapState(map, 1, 1, 0, 0);
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(0).getX());
    assertEquals(5, map.getGeoms().get(0).getShell().getPoint(0).getY());
    assertEquals(EventType.ADD_POINT, l.event.getType());
    EditBlackboardEvent editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(10, 5), editBlackboardEvent.getNewValue());
    assertEquals(map.getGeoms().get(0).getShell(), editBlackboardEvent.getSource());

    map.addPoint(10, 10, map.getGeoms().get(0).getShell());

    assertPixMapState(map, 1, 2, 0, 0);
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(1).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(1).getY());
    assertEquals(EventType.ADD_POINT, l.event.getType());
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(10, 10), editBlackboardEvent.getNewValue());
    assertEquals(map.getGeoms().get(0).getShell(), editBlackboardEvent.getSource());

    GeometryFactory factory = new GeometryFactory();
    Geometry geom = factory.createPoint(new Coordinate(10, 5));
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    Map<Geometry, EditGeom> mapping = map.setGeometries(geom, null);
    assertNotNull(mapping.get(geom));
    assertEquals(ShapeType.POINT, mapping.get(geom).getShapeType());
    assertPixMapState(map, 1, 1, 0, 0);
    assertEquals(20, map.getGeoms().get(0).getShell().getPoint(0).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(0).getY());
    assertEquals(EventType.SET_GEOMS, l.event.getType());
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(1, ((List) editBlackboardEvent.getOldValue()).size());
    assertEquals(1, ((List) editBlackboardEvent.getNewValue()).size());
    assertEquals(map, editBlackboardEvent.getSource());

    geom =
        factory.createMultiPoint(new Coordinate[] {new Coordinate(10, 5), new Coordinate(20, 10)});
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    String string = "featureID"; // $NON-NLS-1$
    mapping = map.setGeometries(geom, string);
    EditGeom next = mapping.values().iterator().next();
    assertEquals(ShapeType.POINT, next.getShapeType());
    assertEquals(string, next.getFeatureIDRef().get());
    assertNotNull(mapping.get(geom.getGeometryN(0)));
    assertNotNull(mapping.get(geom.getGeometryN(1)));
    assertPixMapState(map, 2, 1, 0, 0);
    assertEquals(20, map.getGeoms().get(0).getShell().getPoint(0).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(0).getY());
    assertEquals(30, map.getGeoms().get(1).getShell().getPoint(0).getX());
    assertEquals(15, map.getGeoms().get(1).getShell().getPoint(0).getY());
    assertEquals(new Coordinate(10, 5), map.getGeoms().get(0).getShell().getCoord(0));
    assertEquals(new Coordinate(20, 10), map.getGeoms().get(1).getShell().getCoord(0));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(2, ((List) editBlackboardEvent.getNewValue()).size());
    assertEquals(map, editBlackboardEvent.getSource());

    LinearRing ring = createShellRing(factory, 10);

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    mapping = map.setGeometries(ring, null);
    assertEquals(ShapeType.LINE, mapping.get(ring).getShapeType());
    assertNotNull(mapping.get(ring));
    assertPixMapState(map, 1, 5, 0, 0);
    assertEquals(20, map.getGeoms().get(0).getShell().getPoint(0).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(0).getY());
    assertEquals(30, map.getGeoms().get(0).getShell().getPoint(1).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(1).getY());
    assertEquals(30, map.getGeoms().get(0).getShell().getPoint(2).getX());
    assertEquals(15, map.getGeoms().get(0).getShell().getPoint(2).getY());
    assertEquals(20, map.getGeoms().get(0).getShell().getPoint(3).getX());
    assertEquals(15, map.getGeoms().get(0).getShell().getPoint(3).getY());
    assertEquals(20, map.getGeoms().get(0).getShell().getPoint(4).getX());
    assertEquals(10, map.getGeoms().get(0).getShell().getPoint(4).getY());
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(1, ((List) editBlackboardEvent.getNewValue()).size());
    assertEquals(map, editBlackboardEvent.getSource());

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    Polygon polygon = createPolygon(factory, 10);
    mapping = map.setGeometries(polygon, null);
    assertEquals(ShapeType.POLYGON, mapping.get(polygon).getShapeType());
    assertNotNull(mapping.get(polygon));
    assertPixMapState(map, 1, 5, 1, 5);
    assertEquals(Point.valueOf(20, 10), map.getGeoms().get(0).getShell().getPoint(0));
    assertEquals(Point.valueOf(25, 12), map.getGeoms().get(0).getHoles().get(0).getPoint(0));
    assertEquals(Point.valueOf(30, 10), map.getGeoms().get(0).getShell().getPoint(1));
    assertEquals(Point.valueOf(28, 12), map.getGeoms().get(0).getHoles().get(0).getPoint(1));
    assertEquals(new Coordinate(15, 7), map.getGeoms().get(0).getHoles().get(0).getCoord(0));
    assertEquals(new Coordinate(18, 7), map.getGeoms().get(0).getHoles().get(0).getCoord(1));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(1, ((List) editBlackboardEvent.getNewValue()).size());
    assertEquals(map, editBlackboardEvent.getSource());

    geom =
        factory.createMultiPolygon(
            new Polygon[] {createPolygon(factory, 0), createPolygon(factory, 20)});

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    mapping = map.setGeometries(geom, null);
    assertPixMapState(map, 2, 5, 1, 5);
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(2, ((List) editBlackboardEvent.getNewValue()).size());
    assertEquals(map, editBlackboardEvent.getSource());
  }
  private void assertTranslation(EditBlackboard map, EditGeom geom, int diffX, int diffY) {
    // check coords moved
    assertEquals(map.getCoords(20 + diffX, 10 + diffY).get(0), geom.getShell().getCoord(0));
    assertEquals(map.getCoords(30 + diffX, 10 + diffY).get(0), geom.getShell().getCoord(1));
    assertEquals(map.getCoords(30 + diffX, 15 + diffY).get(0), geom.getShell().getCoord(2));
    assertEquals(map.getCoords(20 + diffX, 15 + diffY).get(0), geom.getShell().getCoord(3));
    assertEquals(map.getCoords(20 + diffX, 10 + diffY).get(0), geom.getShell().getCoord(4));
    // check hole
    assertEquals(map.getCoords(25 + diffX, 12 + diffY).get(0), geom.getHoles().get(0).getCoord(0));
    assertEquals(map.getCoords(28 + diffX, 12 + diffY).get(0), geom.getHoles().get(0).getCoord(1));
    assertEquals(map.getCoords(28 + diffX, 13 + diffY).get(0), geom.getHoles().get(0).getCoord(2));
    assertEquals(map.getCoords(25 + diffX, 13 + diffY).get(0), geom.getHoles().get(0).getCoord(3));
    assertEquals(map.getCoords(25 + diffX, 12 + diffY).get(0), geom.getHoles().get(0).getCoord(4));

    // check geoms moved
    assertSame(map.getGeoms(20 + diffX, 10 + diffY).get(0), geom);
    assertSame(map.getGeoms(30 + diffX, 10 + diffY).get(0), geom);
    assertSame(map.getGeoms(30 + diffX, 15 + diffY).get(0), geom);
    assertSame(map.getGeoms(20 + diffX, 15 + diffY).get(0), geom);
    assertSame(map.getGeoms(20 + diffX, 10 + diffY).get(0), geom);
    // check hole
    assertEquals(map.getGeoms(25 + diffX, 12 + diffY).get(0), geom);
    assertEquals(map.getGeoms(28 + diffX, 12 + diffY).get(0), geom);
    assertEquals(map.getGeoms(28 + diffX, 13 + diffY).get(0), geom);
    assertEquals(map.getGeoms(25 + diffX, 13 + diffY).get(0), geom);
    assertEquals(map.getGeoms(25 + diffX, 12 + diffY).get(0), geom);

    // check points in EditGeoms
    assertEquals(Point.valueOf(20 + diffX, 10 + diffY), geom.getShell().getPoint(0));
    assertEquals(Point.valueOf(30 + diffX, 10 + diffY), geom.getShell().getPoint(1));
    assertEquals(Point.valueOf(30 + diffX, 15 + diffY), geom.getShell().getPoint(2));
    assertEquals(Point.valueOf(20 + diffX, 15 + diffY), geom.getShell().getPoint(3));
    assertEquals(Point.valueOf(20 + diffX, 10 + diffY), geom.getShell().getPoint(4));
    // check hole
    assertEquals(Point.valueOf(25 + diffX, 12 + diffY), geom.getHoles().get(0).getPoint(0));
    assertEquals(Point.valueOf(28 + diffX, 12 + diffY), geom.getHoles().get(0).getPoint(1));
    assertEquals(Point.valueOf(28 + diffX, 13 + diffY), geom.getHoles().get(0).getPoint(2));
    assertEquals(Point.valueOf(25 + diffX, 13 + diffY), geom.getHoles().get(0).getPoint(3));
    assertEquals(Point.valueOf(25 + diffX, 12 + diffY), geom.getHoles().get(0).getPoint(4));
  }
  /*
   * Test method for 'org.locationtech.udig.tools.edit.support.PixelCoordMap.addCoord(int, int, Coordinate)'
   */
  @Test
  public void testAddCoord() {
    EventListener l = new EventListener();

    GeometryFactory factory = new GeometryFactory();
    Geometry geom = factory.createPoint(new Coordinate(10, 5));
    EditBlackboard map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);

    map.setGeometries(geom, null);
    assertPixMapState(map, 1, 1, 0, 0);

    EditGeom geomShape = map.getGeoms().get(0);
    map.addPoint(10, 5, geomShape.getShell());
    assertPixMapState(map, 1, 2, 0, 0);
    assertEquals(1, map.getCoords(10, 5).size());
    assertEquals(EventType.ADD_POINT, l.getEditBlackboardEvent().getType());
    EditBlackboardEvent editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(10, 5), editBlackboardEvent.getNewValue());

    LinearRing ring = createShellRing(factory, 10);

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    Map<Geometry, EditGeom> mapping = map.setGeometries(ring, null);
    assertPixMapState(map, 1, 5, 0, 0);

    // add at a particular index.
    map.insertCoord(25, 15, 3, mapping.get(ring).getShell());
    assertEquals(Point.valueOf(20, 10), mapping.get(ring).getShell().getPoint(0));
    assertEquals(Point.valueOf(30, 10), mapping.get(ring).getShell().getPoint(1));
    assertEquals(Point.valueOf(30, 15), mapping.get(ring).getShell().getPoint(2));
    assertEquals(Point.valueOf(25, 15), mapping.get(ring).getShell().getPoint(3));
    assertEquals(Point.valueOf(20, 15), mapping.get(ring).getShell().getPoint(4));
    assertEquals(EventType.ADD_POINT, l.event.getType());
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(25, 15), editBlackboardEvent.getNewValue());
    assertEquals(mapping.get(ring).getShell(), editBlackboardEvent.getSource());

    // create a geom one point at a time   test ordering of geometries
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    geomShape = map.getGeoms().get(0);
    map.addPoint(0, 0, geomShape.getShell());
    map.addPoint(0, 100, geomShape.getShell());
    map.addPoint(50, 100, geomShape.getShell());
    map.addPoint(100, 100, geomShape.getShell());
    map.addPoint(50, 150, geomShape.getShell());

    assertEquals(Point.valueOf(0, 0), geomShape.getShell().getPoint(0));
    assertEquals(Point.valueOf(0, 100), geomShape.getShell().getPoint(1));
    assertEquals(Point.valueOf(50, 100), geomShape.getShell().getPoint(2));
    assertEquals(Point.valueOf(100, 100), geomShape.getShell().getPoint(3));
    assertEquals(Point.valueOf(50, 150), geomShape.getShell().getPoint(4));

    // test the coordinates were created correcly
    assertEquals(new Coordinate(-9.5, -4.5), geomShape.getShell().getCoord(0));
    assertEquals(new Coordinate(-9.5, 95.5), geomShape.getShell().getCoord(1));
    assertEquals(new Coordinate(40.5, 95.5), geomShape.getShell().getCoord(2));
    assertEquals(new Coordinate(90.5, 95.5), geomShape.getShell().getCoord(3));
    assertEquals(new Coordinate(40.5, 145.5), geomShape.getShell().getCoord(4));

    // now making sure the the CoordMap is correctly updated too.
    assertEquals(1, map.getCoords(0, 0).size());
    assertEquals(new Coordinate(-9.5, -4.5), map.getCoords(0, 0).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(-9.5, 95.5), map.getCoords(0, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(40.5, 95.5), map.getCoords(50, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(90.5, 95.5), map.getCoords(100, 100).get(0));
    assertEquals(1, map.getCoords(50, 150).size());
    assertEquals(new Coordinate(40.5, 145.5), map.getCoords(50, 150).get(0));

    // insert a vertex in a hole
    Polygon polygon = createPolygon(factory, 10);
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    mapping = map.setGeometries(polygon, null);
    assertPixMapState(map, 1, 5, 1, 5);

    // add at a particular index.
    PrimitiveShape hole = mapping.get(polygon).getHoles().get(0);
    map.insertCoord(26, 13, 3, hole);
    assertEquals(Point.valueOf(25, 12), hole.getPoint(0));
    assertEquals(Point.valueOf(28, 12), hole.getPoint(1));
    assertEquals(Point.valueOf(28, 13), hole.getPoint(2));
    assertEquals(Point.valueOf(26, 13), hole.getPoint(3));
    assertEquals(Point.valueOf(25, 13), hole.getPoint(4));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(26, 13), editBlackboardEvent.getNewValue());
    assertEquals(hole, editBlackboardEvent.getSource());

    // add on an edge test ordering of geometries
    LinearRing ring2 = createShellRing(factory, 30);
    LinearRing ring3 = createShellRing(factory, 32);

    ring3.getCoordinateN(2).y = 20;

    mapping = map.setGeometries(ring2, null);
    mapping.putAll(map.addGeometry(ring3, null));

    map.addToNearestEdge(54, 12, mapping.get(ring2), true);
    assertEquals(1, map.getCoords(54, 12).size());
    assertEquals(new Coordinate(44.5, 7.5), mapping.get(ring2).getShell().getCoord(2));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(54, 12), editBlackboardEvent.getNewValue());
    assertEquals(mapping.get(ring2).getShell(), editBlackboardEvent.getSource());

    mapping = map.setGeometries(ring2, null);
    mapping.putAll(map.addGeometry(ring3, null));

    List<ClosestEdge> added = map.addToNearestEdge(51, 12, true);
    assertEquals(2, added.size());
    assertTrue(
        added.get(0).getGeom() == mapping.get(ring3)
            || added.get(1).getGeom() == mapping.get(ring3));
    assertTrue(
        added.get(0).getGeom() == mapping.get(ring2)
            || added.get(1).getGeom() == mapping.get(ring2));
    assertEquals(2, map.getCoords(51, 12).size());
    assertEquals(new Coordinate(41.5, 7.5), mapping.get(ring2).getShell().getCoord(2));
    assertEquals(new Coordinate(41.5, 7.5), mapping.get(ring3).getShell().getCoord(2));
    editBlackboardEvent = l.getEditBlackboardEvent();
    assertEquals(null, editBlackboardEvent.getOldValue());
    assertEquals(Point.valueOf(51, 12), editBlackboardEvent.getNewValue());
    assertTrue(((Collection) l.event.getSource()).contains(added.get(0).getPart()));
    assertTrue(((Collection) l.event.getSource()).contains(added.get(1).getPart()));

    // create hole one point at a time
    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, layerToWorld);
    map.getListeners().add(l);
    geomShape = map.getGeoms().get(0);
    hole = geomShape.newHole();
    try {
      map.addPoint(0, 0, null);
      fail();
    } catch (Exception e) {
      // good
    }

    map.addPoint(0, 0, hole);
    assertEquals(Point.valueOf(0, 0), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(0, 100, hole);
    assertEquals(Point.valueOf(0, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(50, 100, hole);
    assertEquals(Point.valueOf(50, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(100, 100, hole);
    assertEquals(Point.valueOf(100, 100), l.getEditBlackboardEvent().getNewValue());
    map.addPoint(50, 150, hole);
    assertEquals(null, l.getEditBlackboardEvent().getOldValue());
    assertEquals(Point.valueOf(50, 150), l.getEditBlackboardEvent().getNewValue());
    assertEquals(hole, l.getEditBlackboardEvent().getSource());

    assertEquals(Point.valueOf(0, 0), geomShape.getHoles().get(0).getPoint(0));
    assertEquals(Point.valueOf(0, 100), geomShape.getHoles().get(0).getPoint(1));
    assertEquals(Point.valueOf(50, 100), geomShape.getHoles().get(0).getPoint(2));
    assertEquals(Point.valueOf(100, 100), geomShape.getHoles().get(0).getPoint(3));
    assertEquals(Point.valueOf(50, 150), geomShape.getHoles().get(0).getPoint(4));

    // test the coordinates were created correcly
    assertEquals(new Coordinate(-9.5, -4.5), geomShape.getHoles().get(0).getCoord(0));
    assertEquals(new Coordinate(-9.5, 95.5), geomShape.getHoles().get(0).getCoord(1));
    assertEquals(new Coordinate(40.5, 95.5), geomShape.getHoles().get(0).getCoord(2));
    assertEquals(new Coordinate(90.5, 95.5), geomShape.getHoles().get(0).getCoord(3));
    assertEquals(new Coordinate(40.5, 145.5), geomShape.getHoles().get(0).getCoord(4));

    // now making sure the the CoordMap is correctly updated too.
    assertEquals(1, map.getCoords(0, 0).size());
    assertEquals(new Coordinate(-9.5, -4.5), map.getCoords(0, 0).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(-9.5, 95.5), map.getCoords(0, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(40.5, 95.5), map.getCoords(50, 100).get(0));
    assertEquals(1, map.getCoords(0, 100).size());
    assertEquals(new Coordinate(90.5, 95.5), map.getCoords(100, 100).get(0));
    assertEquals(1, map.getCoords(50, 150).size());
    assertEquals(new Coordinate(40.5, 145.5), map.getCoords(50, 150).get(0));

    // call add to edge so that it is added to a hole
    polygon = createPolygon(factory, 10);
    LinearRing ring1 = createShellRing(factory, 10);
    mapping = map.setGeometries(ring1, null);
    mapping.putAll(map.addGeometry(polygon, null));

    added = map.addToNearestEdge(26, 12, true);
    assertEquals(1, added.size());
    assertEquals(6, added.iterator().next().getGeom().getHoles().get(0).getNumCoords());

    map = new EditBlackboard(SCREEN.x, SCREEN.y, transform, this.layerToWorld);
    map.getListeners().add(l);
    added = map.addToNearestEdge(26, 12, true);
    assertEquals(Point.valueOf(26, 12), map.getGeoms().get(0).getShell().getPoint(0));
  }
  @Test
  public void testIntersectsPrimitiveShape() throws Exception {
    // Test point - point
    EditGeom geom1 = bb.newGeom("shp1", ShapeType.POINT);
    bb.addPoint(10, 10, geom1.getShell());

    EditGeom geom2 = bb.newGeom("shp2", ShapeType.POINT);
    bb.addPoint(10, 11, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, true));

    geom2 = bb.newGeom("shp2", ShapeType.POINT);
    bb.addPoint(10, 10, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, true));

    // test line-point
    geom1 = bb.newGeom("shp1", ShapeType.LINE);
    bb.addPoint(10, 10, geom1.getShell());
    bb.addPoint(20, 10, geom1.getShell());

    geom2 = bb.newGeom("shp2", ShapeType.POINT);
    bb.addPoint(10, 11, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, true));

    geom2 = bb.newGeom("shp2", ShapeType.POINT);
    bb.addPoint(15, 10, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, true));
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));

    // test line-line
    geom1 = bb.newGeom("shp1", ShapeType.LINE);
    bb.addPoint(10, 10, geom1.getShell());
    bb.addPoint(20, 10, geom1.getShell());

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(10, 11, geom2.getShell());
    bb.addPoint(20, 11, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(15, 5, geom2.getShell());
    bb.addPoint(15, 15, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(15, 10, geom2.getShell());
    bb.addPoint(15, 15, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, true));
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));

    // test polygon-line
    geom1 = bb.newGeom("shp1", ShapeType.POLYGON);
    bb.addPoint(0, 0, geom1.getShell());
    bb.addPoint(10, 0, geom1.getShell());
    bb.addPoint(10, 10, geom1.getShell());
    bb.addPoint(0, 10, geom1.getShell());
    bb.addPoint(0, 0, geom1.getShell());

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(10, 11, geom2.getShell());
    bb.addPoint(20, 11, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(5, 5, geom2.getShell());
    bb.addPoint(5, 15, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));

    geom2 = bb.newGeom("shp2", ShapeType.LINE);
    bb.addPoint(5, 2, geom2.getShell());
    bb.addPoint(5, 8, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));

    // test polygon-polygon
    geom1 = bb.newGeom("shp1", ShapeType.POLYGON);
    bb.addPoint(0, 0, geom1.getShell());
    bb.addPoint(10, 0, geom1.getShell());
    bb.addPoint(10, 10, geom1.getShell());
    bb.addPoint(0, 10, geom1.getShell());
    bb.addPoint(0, 0, geom1.getShell());

    // no intersection
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(0, 11, geom2.getShell());
    bb.addPoint(10, 11, geom2.getShell());
    bb.addPoint(10, 21, geom2.getShell());
    bb.addPoint(0, 21, geom2.getShell());
    bb.addPoint(0, 11, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));

    //   ---------
    // ------    |
    // | |  |    |
    // ------    |
    //   ---------
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(-5, 2, geom2.getShell());
    bb.addPoint(5, 2, geom2.getShell());
    bb.addPoint(5, 8, geom2.getShell());
    bb.addPoint(-5, 8, geom2.getShell());
    bb.addPoint(-5, 2, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));

    //    ---------
    // ----------------
    // |  |       |   |
    // ----------------
    //    ---------
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(-5, 2, geom2.getShell());
    bb.addPoint(15, 2, geom2.getShell());
    bb.addPoint(15, 8, geom2.getShell());
    bb.addPoint(-5, 8, geom2.getShell());
    bb.addPoint(-5, 2, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));

    //     ---------
    // ----        |
    // |  |        |
    // ----        |
    //     ---------
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(-5, 2, geom2.getShell());
    bb.addPoint(0, 2, geom2.getShell());
    bb.addPoint(0, 8, geom2.getShell());
    bb.addPoint(-5, 8, geom2.getShell());
    bb.addPoint(-5, 2, geom2.getShell());
    assertFalse(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertFalse(geom2.getShell().overlap(geom1.getShell(), false, false));
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, true));

    // ---------
    // ---     |
    // | |     |
    // ---     |
    // ---------
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(0, 2, geom2.getShell());
    bb.addPoint(5, 2, geom2.getShell());
    bb.addPoint(5, 8, geom2.getShell());
    bb.addPoint(0, 8, geom2.getShell());
    bb.addPoint(0, 2, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, true));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, true));

    // ---------
    // | ---   |
    // | | |   |
    // | ---   |
    // ---------
    geom2 = bb.newGeom("shp2", ShapeType.POLYGON);
    bb.addPoint(2, 2, geom2.getShell());
    bb.addPoint(8, 2, geom2.getShell());
    bb.addPoint(8, 8, geom2.getShell());
    bb.addPoint(2, 8, geom2.getShell());
    bb.addPoint(2, 2, geom2.getShell());
    assertTrue(geom1.getShell().overlap(geom2.getShell(), false, false));
    assertTrue(geom2.getShell().overlap(geom1.getShell(), false, false));
  }
 protected Path createPointPath(Device device) {
   Point point = geom.getShell().getPoint(0);
   Path path = new Path(device);
   path.addRectangle(point.getX() - 2, point.getY() - 2, 4, 4);
   return path;
 }
 /**
  * Called if there is only a single point in the geom. Default behaviour is to return a small
  * square. If null is returned then this PathIterator will be used to create a geometry.
  *
  * @return a shape to draw or null if PathIterator should be used to create a shape.
  */
 protected Shape createPoint() {
   Point point = geom.getShell().getPoint(0);
   return new Rectangle(point.getX() - 2, point.getY() - 2, 4, 4);
 }