Checks.java 5.78 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
32
33
34
35
36

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;
import de.hft.stuttgart.citydoctor2.checks.geometry.DuplicatePointsCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.FaceOutCheck;
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
37
import de.hft.stuttgart.citydoctor2.checks.geometry.MultipleConnectedComponentCheck;
38
import de.hft.stuttgart.citydoctor2.checks.geometry.NestedRingsCheck;
Matthias Betz's avatar
Matthias Betz committed
39
import de.hft.stuttgart.citydoctor2.checks.geometry.NonManifoldEdgeCheck;
Matthias Betz's avatar
Matthias Betz committed
40
import de.hft.stuttgart.citydoctor2.checks.geometry.NumPointsCheck;
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
49
50
51
52
53
54
import de.hft.stuttgart.citydoctor2.checks.geometry.RingSelfIntCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidNotClosedCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidSelfIntCheck;
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;
import de.hft.stuttgart.citydoctor2.checks.semantics.RoofSurfaceUnfragmentedCheck;
Matthias Betz's avatar
Matthias Betz committed
55
import de.hft.stuttgart.citydoctor2.utils.Localization;
56
57
58
59
60
61
62
63
64

/**
 * 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
65
66
	
	public static final double MIN_VERTEX_DISTANCE_DEFAULT = 0.0001;
67

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

	private static List<CheckPrototype> checkPrototypes;
	private static Map<CheckId, CheckPrototype> prototypeMap;

	private Map<CheckId, Check> checkMap;

	static {
		checkPrototypes = new ArrayList<>();
Matthias Betz's avatar
Matthias Betz committed
77
		prototypeMap = new HashMap<>();
78
79

		// add new checks here
Matthias Betz's avatar
Matthias Betz committed
80
		// ring checks
81
		publish(new NumPointsCheck());
Matthias Betz's avatar
Matthias Betz committed
82
		publish(new RingNotClosedCheck());
83
84
		publish(new DuplicatePointsCheck());
		publish(new RingSelfIntCheck());
Matthias Betz's avatar
Matthias Betz committed
85
86
		
		// polygon checks
87
88
89
90
		publish(new PlanarCheck());
		publish(new PolygonSameOrientationCheck());
		publish(new HoleOutsideCheck());
		publish(new NestedRingsCheck());
Matthias Betz's avatar
Matthias Betz committed
91
		publish(new PolygonIntersectingRingsCheck());
92
		publish(new InteriorDisconnectedCheck());
Matthias Betz's avatar
Matthias Betz committed
93
94
		
		// solid checks
Matthias Betz's avatar
Matthias Betz committed
95
		publish(new MultipleConnectedComponentCheck());
96
		publish(new SolidNotClosedCheck());
Matthias Betz's avatar
Matthias Betz committed
97
98
		publish(new NonManifoldEdgeCheck());
		publish(new PolygonWrongOrientationCheck());
99
100
101
102
103
104
105
106
107
108
109
		publish(new FaceOutCheck());
		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());
Matthias Betz's avatar
Matthias Betz committed
110
111
112
113
114
115
		
		// load checks from service loader
		ServiceLoader<Check> checkLoader = ServiceLoader.load(Check.class);
		for (Check c : checkLoader) {
			publish(c);
		}
116
117
118
119
120
121
122
	}

	/**
	 * 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
123
		checkMap = new HashMap<>();
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

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

	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
161
		if (c == null && logger.isWarnEnabled()) {
Matthias Betz's avatar
Matthias Betz committed
162
			logger.warn(Localization.getText("Checks.missingCheck"), id);
163
164
165
166
		}
		return c;
	}
}