Checks.java 6.81 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*-
 *  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 <https://www.gnu.org/licenses/>.
 */
package de.hft.stuttgart.citydoctor2.checks;

import java.util.ArrayList;
Matthias Betz's avatar
Matthias Betz committed
22
import java.util.HashMap;
23
24
import java.util.List;
import java.util.Map;
Matthias Betz's avatar
Matthias Betz committed
25
import java.util.ServiceLoader;
26
27
28
29
30
31

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckId;
32
33
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.checks.geometry.AllPolygonsWrongOrientationCheck;
34
35
36
37
import de.hft.stuttgart.citydoctor2.checks.geometry.DuplicatePointsCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.HoleOutsideCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.InteriorDisconnectedCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.ManifoldVertexCheck;
Matthias Betz's avatar
Matthias Betz committed
38
import de.hft.stuttgart.citydoctor2.checks.geometry.MultipleConnectedComponentCheck;
39
import de.hft.stuttgart.citydoctor2.checks.geometry.NestedRingsCheck;
Matthias Betz's avatar
Matthias Betz committed
40
import de.hft.stuttgart.citydoctor2.checks.geometry.NonManifoldEdgeCheck;
41
import de.hft.stuttgart.citydoctor2.checks.geometry.PlanarCheck;
Matthias Betz's avatar
Matthias Betz committed
42
import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonIntersectingRingsCheck;
Matthias Betz's avatar
Matthias Betz committed
43
44
45
import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonSameOrientationCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonWrongOrientationCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.RingNotClosedCheck;
46
47
48
import de.hft.stuttgart.citydoctor2.checks.geometry.RingSelfIntCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidNotClosedCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidSelfIntCheck;
49
import de.hft.stuttgart.citydoctor2.checks.geometry.TooFewPointsCheck;
50
51
52
53
54
import de.hft.stuttgart.citydoctor2.checks.geometry.TooFewPolygonsCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsCeilingCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsFloorCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsGroundCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsWallCheck;
55
import de.hft.stuttgart.citydoctor2.checks.semantics.PolygonWithoutSurfaceCheck;
56
import de.hft.stuttgart.citydoctor2.checks.semantics.RoofSurfaceUnfragmentedCheck;
Matthias Betz's avatar
Matthias Betz committed
57
import de.hft.stuttgart.citydoctor2.utils.Localization;
58
59
60
61
62
63
64
65
66

/**
 * Container class for all checks. If new checks are added, they need to be
 * published here to be accessed by the checker instance.
 * 
 * @author Matthias Betz
 *
 */
public class Checks {
Matthias Betz's avatar
Matthias Betz committed
67
68
	
	public static final double MIN_VERTEX_DISTANCE_DEFAULT = 0.0001;
69

Matthias Betz's avatar
Matthias Betz committed
70
	private static final Logger logger = LogManager.getLogger(Checks.class);
71
72
73

	private static List<CheckPrototype> checkPrototypes;
	private static Map<CheckId, CheckPrototype> prototypeMap;
74
75
	private static Map<String, Requirement> availableRequirements;

76
77
78
79
80

	private Map<CheckId, Check> checkMap;

	static {
		checkPrototypes = new ArrayList<>();
Matthias Betz's avatar
Matthias Betz committed
81
		prototypeMap = new HashMap<>();
82
83

		// add new checks here
Matthias Betz's avatar
Matthias Betz committed
84
		// ring checks
85
		publish(new TooFewPointsCheck());
Matthias Betz's avatar
Matthias Betz committed
86
		publish(new RingNotClosedCheck());
87
88
		publish(new DuplicatePointsCheck());
		publish(new RingSelfIntCheck());
Matthias Betz's avatar
Matthias Betz committed
89
90
		
		// polygon checks
91
92
93
94
		publish(new PlanarCheck());
		publish(new PolygonSameOrientationCheck());
		publish(new HoleOutsideCheck());
		publish(new NestedRingsCheck());
Matthias Betz's avatar
Matthias Betz committed
95
		publish(new PolygonIntersectingRingsCheck());
96
		publish(new InteriorDisconnectedCheck());
Matthias Betz's avatar
Matthias Betz committed
97
98
		
		// solid checks
Matthias Betz's avatar
Matthias Betz committed
99
		publish(new MultipleConnectedComponentCheck());
100
		publish(new SolidNotClosedCheck());
Matthias Betz's avatar
Matthias Betz committed
101
102
		publish(new NonManifoldEdgeCheck());
		publish(new PolygonWrongOrientationCheck());
103
		publish(new AllPolygonsWrongOrientationCheck());
104
105
106
107
108
109
110
111
112
113
		publish(new TooFewPolygonsCheck());
		publish(new ManifoldVertexCheck());
		publish(new SolidSelfIntCheck());

		// semantic checks
		publish(new IsWallCheck());
		publish(new IsFloorCheck());
		publish(new IsCeilingCheck());
		publish(new IsGroundCheck());
		publish(new RoofSurfaceUnfragmentedCheck());
114
		publish(new PolygonWithoutSurfaceCheck());
Matthias Betz's avatar
Matthias Betz committed
115
116
117
118
119
120
		
		// load checks from service loader
		ServiceLoader<Check> checkLoader = ServiceLoader.load(Check.class);
		for (Check c : checkLoader) {
			publish(c);
		}
121
122
123
124
125
126
127
	}

	/**
	 * Creates new checks for every available check prototype and stores them in
	 * this container. Access the checks with {@link Checks#getCheckForId(CheckId)}.
	 */
	public Checks() {
Matthias Betz's avatar
Matthias Betz committed
128
		checkMap = new HashMap<>();
129
130
131
132
133
134
135

		for (CheckPrototype proto : checkPrototypes) {
			Check check = proto.createCheck();
			checkMap.put(check.getCheckId(), check);
		}
	}

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
	private static Map<String, Requirement> collectRequirements() {
		Map<String, Requirement> requirements = new HashMap<>();
		for (CheckPrototype proto : checkPrototypes) {
			for (Requirement req : proto.checksRequirements()) {
				requirements.put(req.getId(), req);
			}
		}
		return requirements;
	}
	
	/**
	 * Gets all requirements for which there are checks that can verify the
	 * requirements. This is dependent on the available checks as only the checks
	 * know which requirements they check.
	 * 
	 * @return a set of available requirements
	 */
	public static  Map<String, Requirement> getAvailableRequirements() {
		if (availableRequirements == null) {
			availableRequirements = collectRequirements();
		}
		return availableRequirements;
	}
	
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	private static void publish(Check check) {
		CheckPrototype prototype = new CheckPrototype(check);
		checkPrototypes.add(prototype);
		prototypeMap.put(prototype.getCheckId(), prototype);
	}

	/**
	 * 
	 * @return All available checks as prototypes, where they can be instantiated.
	 */
	public static List<CheckPrototype> getCheckPrototypes() {
		return checkPrototypes;
	}

	/**
	 * 
	 * @param key The check ID
	 * @return The prototype for the given ID or null if there is no such prototype.
	 */
	public static CheckPrototype getCheckPrototypeForId(CheckId key) {
		return prototypeMap.get(key);
	}

	/**
	 * 
	 * @param id The check ID
	 * @return The check for the check ID or null if it does not exist
	 */
	public Check getCheckForId(CheckId id) {
		Check c = checkMap.get(id);
Matthias Betz's avatar
Matthias Betz committed
190
		if (c == null && logger.isWarnEnabled()) {
Matthias Betz's avatar
Matthias Betz committed
191
			logger.warn(Localization.getText("Checks.missingCheck"), id);
192
193
194
195
		}
		return c;
	}
}