All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vividsolutions.jts.operation.buffer.validate.BufferResultValidator Maven / Gradle / Ivy

There is a newer version: 0.1.4
Show newest version
/*
 * The JTS Topology Suite is a collection of Java classes that
 * implement the fundamental operations required to validate a given
 * geo-spatial data set to a known topological specification.
 *
 * Copyright (C) 2001 Vivid Solutions
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * For more information, contact:
 *
 *     Vivid Solutions
 *     Suite #1A
 *     2328 Government Street
 *     Victoria BC  V8T 5G5
 *     Canada
 *
 *     (250)385-6040
 *     www.vividsolutions.com
 */
package com.vividsolutions.jts.operation.buffer.validate;

import com.vividsolutions.jts.geom.*;

/**
 * Validates that the result of a buffer operation
 * is geometrically correct, within a computed tolerance.
 * 

* This is a heuristic test, and may return false positive results * (I.e. it may fail to detect an invalid result.) * It should never return a false negative result, however * (I.e. it should never report a valid result as invalid.) *

* This test may be (much) more expensive than the original * buffer computation. * * @author Martin Davis */ public class BufferResultValidator { private static boolean VERBOSE = false; /** * Maximum allowable fraction of buffer distance the * actual distance can differ by. * 1% sometimes causes an error - 1.2% should be safe. */ private static final double MAX_ENV_DIFF_FRAC = .012; public static boolean isValid(Geometry g, double distance, Geometry result) { BufferResultValidator validator = new BufferResultValidator(g, distance, result); if (validator.isValid()) return true; return false; } /** * Checks whether the geometry buffer is valid, * and returns an error message if not. * * @param g * @param distance * @param result * @return an appropriate error message * or null if the buffer is valid */ public static String isValidMsg(Geometry g, double distance, Geometry result) { BufferResultValidator validator = new BufferResultValidator(g, distance, result); if (! validator.isValid()) return validator.getErrorMessage(); return null; } private Geometry input; private double distance; private Geometry result; private boolean isValid = true; private String errorMsg = null; private Coordinate errorLocation = null; private Geometry errorIndicator = null; public BufferResultValidator(Geometry input, double distance, Geometry result) { this.input = input; this.distance = distance; this.result = result; } public boolean isValid() { checkPolygonal(); if (! isValid) return isValid; checkExpectedEmpty(); if (! isValid) return isValid; checkEnvelope(); if (! isValid) return isValid; checkArea(); if (! isValid) return isValid; checkDistance(); return isValid; } public String getErrorMessage() { return errorMsg; } public Coordinate getErrorLocation() { return errorLocation; } /** * Gets a geometry which indicates the location and nature of a validation failure. *

* If the failure is due to the buffer curve being too far or too close * to the input, the indicator is a line segment showing the location and size * of the discrepancy. * * @return a geometric error indicator * or null if no error was found */ public Geometry getErrorIndicator() { return errorIndicator; } private void report(String checkName) { if (! VERBOSE) return; System.out.println("Check " + checkName + ": " + (isValid ? "passed" : "FAILED")); } private void checkPolygonal() { if (! (result instanceof Polygon || result instanceof MultiPolygon)) isValid = false; errorMsg = "Result is not polygonal"; errorIndicator = result; report("Polygonal"); } private void checkExpectedEmpty() { // can't check areal features if (input.getDimension() >= 2) return; // can't check positive distances if (distance > 0.0) return; // at this point can expect an empty result if (! result.isEmpty()) { isValid = false; errorMsg = "Result is non-empty"; errorIndicator = result; } report("ExpectedEmpty"); } private void checkEnvelope() { if (distance < 0.0) return; double padding = distance * MAX_ENV_DIFF_FRAC; if (padding == 0.0) padding = 0.001; Envelope expectedEnv = new Envelope(input.getEnvelopeInternal()); expectedEnv.expandBy(distance); Envelope bufEnv = new Envelope(result.getEnvelopeInternal()); bufEnv.expandBy(padding); if (! bufEnv.contains(expectedEnv)) { isValid = false; errorMsg = "Buffer envelope is incorrect"; errorIndicator = input.getFactory().toGeometry(bufEnv); } report("Envelope"); } private void checkArea() { double inputArea = input.getArea(); double resultArea = result.getArea(); if (distance > 0.0 && inputArea > resultArea) { isValid = false; errorMsg = "Area of positive buffer is smaller than input"; errorIndicator = result; } if (distance < 0.0 && inputArea < resultArea) { isValid = false; errorMsg = "Area of negative buffer is larger than input"; errorIndicator = result; } report("Area"); } private void checkDistance() { BufferDistanceValidator distValid = new BufferDistanceValidator(input, distance, result); if (! distValid.isValid()) { isValid = false; errorMsg = distValid.getErrorMessage(); errorLocation = distValid.getErrorLocation(); errorIndicator = distValid.getErrorIndicator(); } report("Distance"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy