/* * Copyright (c) 2016 Vivid Solutions. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * * http://www.eclipse.org/org/documents/edl-v10.php. */ package org.locationtech.jts.operation.valid; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.WKTReader; import junit.framework.TestCase; /** * Tests allowing IsValidOp to validate polygons with * Self-Touching Rings forming holes. * Mainly tests that configuring {@link IsValidOp} to allow validating * the STR validates polygons with this condition, and does not validate * polygons with other kinds of self-intersection (such as ones with Disconnected Interiors). * Includes some basic tests to confirm that other invalid cases remain detected correctly, * but most of this testing is left to the existing XML validation tests. * * @author Martin Davis * @version 1.7 */ public class ValidSelfTouchingRingFormingHoleTest extends TestCase { private static WKTReader rdr = new WKTReader(); public ValidSelfTouchingRingFormingHoleTest(String name) { super(name); } public static void main(String[] args) { junit.textui.TestRunner.run(ValidSelfTouchingRingFormingHoleTest.class); } /** * Tests a geometry with both a shell self-touch and a hole self-touch. * This is valid if STR is allowed, but invalid in OGC */ public void testShellAndHoleSelfTouch() { String wkt = "POLYGON ((0 0, 0 340, 320 340, 320 0, 120 0, 180 100, 60 100, 120 0, 0 0), (80 300, 80 180, 200 180, 200 240, 280 200, 280 280, 200 240, 200 300, 80 300))"; checkIsValidSTR(wkt, true); checkIsValidDefault(wkt, false); } /** * Tests a geometry representing the same area as in {@link #testShellAndHoleSelfTouch} * but using a shell-hole touch and a hole-hole touch. * This is valid in OGC. */ public void testShellHoleAndHoleHoleTouch() { String wkt = "POLYGON ((0 0, 0 340, 320 340, 320 0, 120 0, 0 0), (120 0, 180 100, 60 100, 120 0), (80 300, 80 180, 200 180, 200 240, 200 300, 80 300), (200 240, 280 200, 280 280, 200 240))"; checkIsValidSTR(wkt, true); checkIsValidDefault(wkt, true); } /** * Tests an overlapping hole condition, where one of the holes is created by a shell self-touch. * This is never valid. */ public void testShellSelfTouchHoleOverlappingHole() { String wkt = "POLYGON ((0 0, 220 0, 220 200, 120 200, 140 100, 80 100, 120 200, 0 200, 0 0), (200 80, 20 80, 120 200, 200 80))"; checkIsValidSTR(wkt, false); checkIsValidDefault(wkt, false); } /** * Ensure that the Disconnected Interior condition is not validated */ public void testDisconnectedInteriorShellSelfTouchAtNonVertex() { String wkt = "POLYGON ((40 180, 40 60, 240 60, 240 180, 140 60, 40 180))"; checkIsValidSTR(wkt, false); checkIsValidDefault(wkt, false); } /** * Ensure that the Disconnected Interior condition is not validated */ public void testDisconnectedInteriorShellSelfTouchAtVertex() { String wkt = "POLYGON ((20 20, 20 100, 140 100, 140 180, 260 180, 260 100, 140 100, 140 20, 20 20))"; checkIsValidSTR(wkt, false); checkIsValidDefault(wkt, false); } public void testShellCross() { String wkt = "POLYGON ((20 20, 120 20, 120 220, 240 220, 240 120, 20 120, 20 20))"; checkIsValidSTR(wkt, false); checkIsValidDefault(wkt, false); } public void testShellCrossAndSTR() { String wkt = "POLYGON ((20 20, 120 20, 120 220, 180 220, 140 160, 200 160, 180 220, 240 220, 240 120, 20 120, 20 20))"; checkIsValidSTR(wkt, false); checkIsValidDefault(wkt, false); } private void checkIsValidDefault(String wkt, boolean expected) { Geometry geom = fromWKT(wkt); IsValidOp validator = new IsValidOp(geom); boolean isValid = validator.isValid(); assertTrue(isValid == expected); } private void checkIsValidSTR(String wkt, boolean expected) { Geometry geom = fromWKT(wkt); IsValidOp validator = new IsValidOp(geom); validator.setSelfTouchingRingFormingHoleValid(true); boolean isValid = validator.isValid(); assertTrue(isValid == expected); } Geometry fromWKT(String wkt) { Geometry geom = null; try { geom = rdr.read(wkt); } catch (Exception ex) { ex.printStackTrace(); } return geom; } }