/*- * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart * * This file is part of CityDoctor2. * * CityDoctor2 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 3 of the License, or * (at your option) any later version. * * CityDoctor2 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 CityDoctor2. If not, see . */ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.Checkable; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError; import de.hft.stuttgart.citydoctor2.check.error.RingDuplicatePointError; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; /** * CP_DUPPOINT checks if there is any double point in a linear ring. Each point * must occur only once in a linear ring.
*
* Dependency:
*
*
CP_CLOSE
* * @author Matthias Betz - 12bema1bif@hft-stuttgart.de * */ public class DuplicatePointsCheck extends Check { private static final String EPSILON_NAME = "minVertexDistance"; private static final List dependencies; private static final List> applicableToClasses; static { ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); deps.add(CheckId.C_GE_R_NOT_CLOSED); dependencies = Collections.unmodifiableList(deps); ArrayList> classes = new ArrayList<>(); classes.add(LinearRing.class); applicableToClasses = Collections.unmodifiableList(classes); } private double epsilon = 0.0001; @Override public void init(Map params, ParserConfiguration config) { String epsilonString = params.get(EPSILON_NAME); if (epsilonString == null) { epsilon = 0.0001; } else { epsilon = Double.parseDouble(epsilonString); } } public DuplicatePointsCheck() { super(CheckId.C_GE_R_DUPLICATE_POINT); } @Override public List getDependencies() { return dependencies; } @Override public List> getApplicableToClasses() { return applicableToClasses; } @Override public void check(LinearRing lr) { List pointList = lr.getVertices(); // check for consecutive points first for (int i = 0; i < pointList.size() - 1; i++) { Vertex point1 = pointList.get(i); Vertex point2 = pointList.get(i + 1); if (point1.equalsWithEpsilon(point2, epsilon)) { // consecutive points same CheckError err = new ConsecutivePointSameError(lr, point1, point2); CheckResult cr = new CheckResult(this, ResultStatus.ERROR, err); lr.addCheckResult(cr); return; } } // ignore last point, because last point = first, but this is allowed for (int i = 0; i < pointList.size() - 2; i++) { for (int j = i + 2; j < pointList.size() - 1; j++) { Vertex point1 = pointList.get(i); Vertex point2 = pointList.get(j); if (point1.equalsWithEpsilon(point2, epsilon)) { // non consecutive points same CheckError err = new RingDuplicatePointError(lr, point1, point2); CheckResult cr = new CheckResult(this, ResultStatus.ERROR, err); lr.addCheckResult(cr); return; } } } CheckResult cr = new CheckResult(this, ResultStatus.OK, null); lr.addCheckResult(cr); } @Override public CheckType getType() { return CheckType.GEOMETRY; } @Override public Check createNewInstance() { return new DuplicatePointsCheck(); } }