/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.plugin.editing.client.operation; import org.geomajas.geometry.Coordinate; import org.geomajas.geometry.Geometry; import org.geomajas.plugin.editing.client.service.GeometryIndexService; import org.geomajas.plugin.editing.client.service.GeometryIndexType; import org.junit.Assert; import org.junit.Test; /** * Test cases for inserting sub-geometries within any type of geometry. * * @author Pieter De Graef */ public class InsertGeometryOperationTest { private static final double DELTA = 0.0001; private GeometryIndexService service = new GeometryIndexService(); private Geometry point = new Geometry(Geometry.POINT, 0, 0); private Geometry lineString = new Geometry(Geometry.LINE_STRING, 0, 0); private Geometry linearRing = new Geometry(Geometry.LINEAR_RING, 0, 0); private Geometry polygon = new Geometry(Geometry.POLYGON, 0, 0); private Geometry multiPoint = new Geometry(Geometry.MULTI_POINT, 0, 0); private Geometry multiLineString = new Geometry(Geometry.MULTI_LINE_STRING, 0, 0); private Geometry multiPolygon = new Geometry(Geometry.MULTI_POLYGON, 0, 0); // ------------------------------------------------------------------------ // Constructor: initialize geometries. // ------------------------------------------------------------------------ public InsertGeometryOperationTest() { point.setCoordinates(new Coordinate[] { new Coordinate(1, 1) }); lineString .setCoordinates(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3) }); linearRing.setCoordinates(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) }); Geometry shell = new Geometry(Geometry.LINEAR_RING, 0, 0); shell.setCoordinates(new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }); Geometry hole = new Geometry(Geometry.LINEAR_RING, 0, 0); hole.setCoordinates(new Coordinate[] { new Coordinate(4, 4), new Coordinate(6, 4), new Coordinate(6, 6), new Coordinate(4, 6), new Coordinate(4, 4) }); polygon.setGeometries(new Geometry[] { shell, hole }); Geometry point2 = new Geometry(Geometry.POINT, 0, 0); point2.setCoordinates(new Coordinate[] { new Coordinate(2, 2) }); multiPoint.setGeometries(new Geometry[] { point, point2 }); Geometry lineString2 = new Geometry(Geometry.LINE_STRING, 0, 0); lineString2.setCoordinates(new Coordinate[] { new Coordinate(4, 4), new Coordinate(5, 5), new Coordinate(6, 6), new Coordinate(7, 7) }); multiLineString.setGeometries(new Geometry[] { lineString, lineString2 }); Geometry shell2 = new Geometry(Geometry.LINEAR_RING, 0, 0); shell2.setCoordinates(new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }); Geometry hole2 = new Geometry(Geometry.LINEAR_RING, 0, 0); hole2.setCoordinates(new Coordinate[] { new Coordinate(3, 3), new Coordinate(7, 3), new Coordinate(7, 7), new Coordinate(3, 7), new Coordinate(3, 3) }); Geometry polygon2 = new Geometry(Geometry.POLYGON, 0, 0); polygon2.setGeometries(new Geometry[] { shell2, hole2 }); multiPolygon.setGeometries(new Geometry[] { polygon, polygon2 }); } // ------------------------------------------------------------------------ // Test the GeometryIndexInsertGeometryOperation: // ------------------------------------------------------------------------ @Test public void testPointAndPoint() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); // Cannot add geometries to a point: try { operation.execute(point, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testLineStringAndPoint() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); // Cannot add geometries to a point: try { operation.execute(lineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testLinearRingAndPoint() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); // Cannot add geometries to a point: try { operation.execute(linearRing, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testPolygonAndPoint() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); // Cannot add geometries to a point: try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testPolygonAndLineString() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINE_STRING, 0, 0)); // Cannot add geometries to a point: try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testPolygonAndLinearRingAtBegin() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); int count = polygon.getGeometries().length; double value = polygon.getGeometries()[0].getCoordinates()[0].getX(); // Insert a ring at first position; the outer shell: Geometry result = operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[0].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testPolygonAndLinearRingAtMiddle() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); int count = polygon.getGeometries().length; double value = polygon.getGeometries()[1].getCoordinates()[0].getX(); // Insert a ring in the middle: Geometry result = operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 1)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[1].getCoordinates()); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testPolygonAndLinearRingAtEnd() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); int count = polygon.getGeometries().length; double value = polygon.getGeometries()[1].getCoordinates()[0].getX(); // Insert a ring at the last position: Geometry result = operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 2)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testPolygonWrongIndexTypes() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_EDGE, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_VERTEX, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testPolygonWrongIndices() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } try { operation.execute(polygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 3)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiPointAndPointAtBegin() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); int count = multiPoint.getGeometries().length; double value = multiPoint.getGeometries()[0].getCoordinates()[0].getX(); // Insert a point at the first position: Geometry result = operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[0].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPointAndPointAtMiddle() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); int count = multiPoint.getGeometries().length; double value = multiPoint.getGeometries()[1].getCoordinates()[0].getX(); // Insert a point at the middle: Geometry result = operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 1)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[1].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[2].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPointAndPointAtEnd() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); int count = multiPoint.getGeometries().length; double value = multiPoint.getGeometries()[1].getCoordinates()[0].getX(); // Insert a point at the end: Geometry result = operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 2)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPointAndLinearRing() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiPointCornerCases() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); try { operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } try { operation.execute(multiPoint, service.create(GeometryIndexType.TYPE_GEOMETRY, 3)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiLineStringAndLineStringAtBegin() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINE_STRING, 0, 0)); int count = multiLineString.getGeometries().length; double value = multiLineString.getGeometries()[0].getCoordinates()[0].getX(); // Insert a line at the first position: Geometry result = operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[0].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiLineStringAndLineStringAtMiddle() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINE_STRING, 0, 0)); int count = multiLineString.getGeometries().length; double value = multiLineString.getGeometries()[1].getCoordinates()[0].getX(); // Insert a line in the middle: Geometry result = operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 1)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[1].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[2].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiLineStringAndLineStringAtEnd() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINE_STRING, 0, 0)); int count = multiLineString.getGeometries().length; double value = multiLineString.getGeometries()[1].getCoordinates()[0].getX(); // Insert a line at the end: Geometry result = operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 2)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiLineStringAndLinearRing() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiLineStringCornerCases() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POINT, 0, 0)); try { operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } try { operation.execute(multiLineString, service.create(GeometryIndexType.TYPE_GEOMETRY, 3)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiPolygonAndPolygonAtBegin() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POLYGON, 0, 0)); int count = multiPolygon.getGeometries().length; double value = multiPolygon.getGeometries()[0].getGeometries()[0].getCoordinates()[0].getX(); // Insert a polygon at first position: Geometry result = operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[0].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[0].getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPolygonAndPolygonAtMiddle() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POLYGON, 0, 0)); int count = multiPolygon.getGeometries().length; double value = multiPolygon.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(); // Insert a polygon in the middle: Geometry result = operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 1)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[1].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[2].getGeometries()[0].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPolygonAndPolygonAtEnd() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POLYGON, 0, 0)); int count = multiPolygon.getGeometries().length; double value = multiPolygon.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(); // Insert a polygon at the end: Geometry result = operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 2)); Assert.assertEquals(count + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); Assert.assertEquals(value, result.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(), DELTA); // Undo delete operation: Geometry undone = operation.getInverseOperation().execute(result, operation.getGeometryIndex()); Assert.assertEquals(count, undone.getGeometries().length); Assert.assertEquals(value, undone.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(), DELTA); } @Test public void testMultiPolygonRecursively() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.POLYGON, 0, 0)); int count1 = multiPolygon.getGeometries().length; double value = multiPolygon.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(); // Insert a polygon at the last position: Geometry result = operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 2)); Assert.assertEquals(count1 + 1, result.getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); Assert.assertNull(result.getGeometries()[2].getGeometries()); Assert.assertEquals(value, result.getGeometries()[1].getGeometries()[0].getCoordinates()[0].getX(), DELTA); // Insert a ring at the first position in the last polygon: GeometryIndexOperation op2 = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); result = op2.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 2, 0)); Assert.assertEquals(count1 + 1, result.getGeometries().length); Assert.assertEquals(1, result.getGeometries()[2].getGeometries().length); Assert.assertNull(result.getGeometries()[2].getCoordinates()); // Undo delete operation: Geometry undone = op2.getInverseOperation().execute(result, op2.getGeometryIndex()); Assert.assertNull(undone.getGeometries()[2].getCoordinates()); Assert.assertNull(undone.getGeometries()[2].getGeometries()); } @Test public void testMultiPolygonAndLinearRing() throws GeometryOperationFailedException { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } @Test public void testMultiPolygonCornerCases() { GeometryIndexOperation operation = new InsertGeometryOperation(service, new Geometry(Geometry.LINEAR_RING, 0, 0)); try { operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 0, 0, 0)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } try { operation.execute(multiPolygon, service.create(GeometryIndexType.TYPE_GEOMETRY, 3)); Assert.fail(); } catch (GeometryOperationFailedException e) { // We expect an error... } } }