# Geometry Requirements

## Error codes for geometric errors
as defined in the [CityGML Quality Interoperability Experiment, chapter 7.5](http://mail.opengeospatial.org/lists/lt.php?id=fR4CDVYeAlJfHwhTCwA).

!!! note
	The requirements were renamed in CityDoctor to be more human readable. The were renamed according to the error codes.

All the geometric errors are in the "GE" domain. Also, since the geometric validation is performed at 3 different
levels (based on the primitives), the requirements also contain the level:

* Ring: R
* Polygon: P
* Shell: S

Error codes follow the same system as the requirements mentioned [fundamentals](basic.md). A violation of each respective data quality requirement should result in an error which must
be reported with an error code according to the requirement ID.
For each error code, extra information can (and should) be returned. For instance: if a ring is not closed (GE_R_NOT_CLOSED) then the ID of the ring (e.g., its
position (first, second..) in the polygon)  should be returned;
if a polygon is not planar (GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE) then the ID of the
polygon and the max. deviation from the reference plane should be returned; or
if a shell is not 'watertight' (GE_S_NOT_CLOSED) then the location of the hole(s) should be returned.

## Vertex Requirement

Vertices A and B are the same if the euclidean distance between them is smaller than (*minVertexDistance*). It is also used to check whether a point is touching an edge. If a point is within *minVertexDistance* distance to an edge it is considered touching. This parameter is used in multiple checks with the same value:

*  R_GE_R_CONSECUTIVE_POINTS_SAME
*  R_GE_R_NOT_CLOSED
*  R_GE_R_SELF_INTERSECTION
*  R_GE_P_INTERIOR_DISCONNECTED

The following requirements are defined for the three respective geometric levels [(adopted from Ledoux (2013))]( https://doi.org/10.1111/mice.12043):

## Linear Ring

| Requirement ID | Description | Error code | Known checks |
| --------------- | ------------ | ---------- |-------------------- |
| [R_GE_R_TOO_FEW_POINTS](R_GE_R_TOO_FEW_POINTS.md)| too few points | GE_R_TOO_FEW_POINTS | C_GE_R_TOO_FEW_POINTS |
| [R_GE_R_CONSECUTIVE_POINTS_SAME](R_GE_R_CONSECUTIVE_POINTS_SAME.md)| 2 consecutive points are the same | GE_R_CONCECUTIVE_POINTS_SAME | C_GE_R_CONCECUTIVE_POINTS_SAME, C_GE_R_DUPLICATE_POINT |
| [R_GE_R_NOT_CLOSED](R_GE_R_NOT_CLOSED.md)| first-last points are not the same | GE_R_NOT_CLOSED | C_GE_R_NOT_CLOSED |
| [R_GE_R_SELF_INTERSECTION](R_GE_R_SELF_INTERSECTION.md)| self-intersects, i.e., a bowtie | GE_R_SELF_INTERSECTION | C_GE_R_SELF_INTERSECTION, C_GE_R_DUPLICATE_POINT |
| [R_GE_R_COLLAPSED_TO_LINE](R_GE_R_COLLAPSED_TO_LINE.md)|  **Currently not in use as it is redundant with R_GE_R_SELF_INTERSECTION**<br/> is point or line  | GE_R_COLLAPSED_TO_LINE | C_GE_R_COLLAPSED_TO_LINE |
| R_GE_R_ALL | Container for: R_GE_R_TOO_FEW_POINTS, R_GE_R_CONSECUTIVE_POINTS_SAME, R_GE_R_NOT_CLOSED, R_GE_R_SELF_INTERSECTION | -- | -- |

## Polygon

| Requirement ID | Description | Error code | Known checks |
| --------------- | ------------ | ---------- |-------------------- |
| [R_GE_P_INTERSECTING_RINGS](R_GE_P_INTERSECTING_RINGS.md) | 2+ rings intersect | GE_P_INTERSECTING_RINGS | C_GE_P_INTERSECTING_RINGS |
| [R_GE_P_NON_PLANAR](R_GE_P_NON_PLANAR.md) | Non planar polygon, both distance and normal deviation | GE_P_NON_PLANAR_POLYGON_DISTANCE_PLANE, GE_P_NON_PLANAR_POLYGON_NORMALS_DEVIATION | C_GE_P_NON_PLANAR |
| [R_GE_P_INTERIOR_DISCONNECTED](R_GE_P_INTERIOR_DISCONNECTED.md) | interior is not connected | GE_P_INTERIOR_DISCONNECTED | C_GE_P_INTERIOR_DISCONNECTED |
| [R_GE_P_HOLE_OUTSIDE](R_GE_P_HOLE_OUTSIDE.md) | 1 or more interior rings are located outside the exterior ring | GE_P_HOLE_OUTSIDE | C_GE_P_HOLE_OUTSIDE |
| [R_GE_P_INNER_RINGS_NESTED](R_GE_P_INNER_RINGS_NESTED.md) | interior ring is located inside other | GE_P_INNER_RINGS_NESTED | C_GE_P_INNER_RINGS_NESTED |
| [R_GE_P_ORIENTATION_RINGS_SAME](R_GE_P_ORIENTATION_RINGS_SAME.md) | exterior and interior rings have same orientation | GE_P_ORIENTATION_RINGS_SAME | C_GE_P_ORIENTATION_RINGS_SAME |
| R_GE_P_ALL | Container for: R_GE_P_INTERSECTING_RINGS, R_GE_P_NON_PLANAR, R_GE_P_INTERIOR_DISCONNECTED, R_GE_P_HOLE_OUTSIDE, R_GE_P_INNER_RINGS_NESTED, R_GE_P_ORIENTATION_RINGS_SAME, R_GE_R_ALL | -- | -- |

## Solid / Shell

| Requirement ID | Description | Error code | Known checks |
| --------------- | ------------ | ---------- |-------------------- |
| [R_GE_S_TOO_FEW_POLYGONS](R_GE_S_TOO_FEW_POLYGONS.md) | <4 polygons | GE_S_TOO_FEW_POLYGONS | C_GE_S_TOO_FEW_POLYGONS |
| [R_GE_S_NOT_CLOSED](R_GE_S_NOT_CLOSED.md) | there is 1+ hole(s) on the surface | GE_S_NOT_CLOSED | C_GE_S_NOT_CLOSED |
| [R_GE_S_NON_MANIFOLD_VERTEX](R_GE_S_NON_MANIFOLD_VERTEX.md) | Each shell must be simple | GE_S_NON_MANIFOLD_VERTEX | C_GE_S_NON_MANIFOLD_VERTEX |
| [R_GE_S_NON_MANIFOLD_EDGE](R_GE_S_NON_MANIFOLD_EDGE.md) | Each edge of a shell should have exactly 2 incident polygons. | GE_S_NON_MANIFOLD_EDGE | C_GE_S_NON_MANIFOLD_EDGE |
| [R_GE_S_MULTIPLE_CONNECTED_COMPONENTS](R_GE_S_MULTIPLE_CONNECTED_COMPONENTS.md) | 1+ polygons not connected to main shell | GE_S_MULTIPLE_CONNECTED_COMPONENTS | C_GE_S_MULTIPLE_CONNECTED_COMPONENTS |
| [R_GE_S_SELF_INTERSECTION](R_GE_S_SELF_INTERSECTION.md) | Solid self intersects | GE_S_SELF_INTERSECTION | C_GE_S_SELF_INTERSECTION |
| [R_GE_S_POLYGON_WRONG_ORIENTATION](R_GE_S_POLYGON_WRONG_ORIENTATION.md) | orientation of a polygon not correct | GE_S_POLYGON_WRONG_ORIENTATION | C_GE_S_POLYGON_WRONG_ORIENTATION |
| [R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION](R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION.md) | normals all pointing in wrong direction | GE_S_ALL_POLYGONS_WRONG_ORIENTATION | C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION |
| R_GE_S_ALL | Container for: R_GE_S_TOO_FEW_POLYGONS, R_GE_S_NOT_CLOSED, R_GE_S_NON_MANIFOLD_VERTEX, R_GE_S_NON_MANIFOLD_EDGE, R_GE_S_MULTIPLE_CONNECTED_COMPONENTS, R_GE_S_SELF_INTERSECTION, R_GE_S_POLYGON_WRONG_ORIENTATION, R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION | -- | -- |

## Parameter Overview

| Name | Description | Used in | Unit |
| ---- | ------------ | ------------ | ------- |
| minVertexDistance | The minimum distance between two points before they are considered the same point | R_GE_R_CONSECUTIVE_POINTS_SAME, R_GE_R_NOT_CLOSED, R_GE_R_SELF_INTERSECTION, R_GE_P_INTERIOR_DISCONNECTED | Meter |
| type | Planar check type, can be *distance*, *angle*, *both* sein | R_GE_P_NON_PLANAR | - |
| distanceTolerance | Distance from the regression plane before a point is considered not in plane | R_GE_P_NON_PLANAR | Meter |
| angleTolerance | Difference in normal vectors before a plane is not considered planar | R_GE_P_NON_PLANAR | Radiant |

## Dependency tree

This is the order the checks will be executed. If one of the depending checks is not executed or has reported an error the following check will not be executed.

```mermaid
graph TD;
  X0001[R_SC_SCHEMA_VALIDATION]
  R0001[R_GE_R_TOO_FEW_POINTS]
  R0002[R_GE_R_CONSECUTIVE_POINTS_SAME]
  R0003[R_GE_R_NOT_CLOSED]
  R0004[R_GE_R_SELF_INTERSECTION]
  P0001[R_GE_P_INTERSECTING_RINGS]
  P0002[R_GE_P_NON_PLANAR]
  P0003[R_GE_P_INTERIOR_DISCONNECTED]
  P0004[R_GE_P_HOLE_OUTSIDE]
  P0005[R_GE_P_INNER_RINGS_NESTED]
  P0006[R_GE_P_ORIENTATION_RINGS_SAME]

  S0001[R_GE_S_TOO_FEW_POLYGONS]
  S0002[R_GE_S_NOT_CLOSED]
  S0003[R_GE_S_NON_MANIFOLD_VERTEX]
  S0004[R_GE_S_NON_MANIFOLD_EDGE]
  S0005[R_GE_S_MULTIPLE_CONNECTED_COMPONENTS]
  S0006[R_GE_S_SELF_INTERSECTION]
  S0007[R_GE_S_POLYGON_WRONG_ORIENTATION]
  S0008[R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION]
  
  X0001-->R0003;
  R0003-->R0001;
  R0001-->R0002;
  R0002-->R0004;
  R0004-->P0002;
  P0002-->P0006;
  P0006-->P0003;
  P0006-->P0004;
  P0006-->P0005;
  P0004-->P0001;
  P0005-->P0001;
  P0001-->S0001;
  P0003-->S0001;
  S0001-->S0002;
  S0001-->S0004;
  S0001-->S0003;
  S0001-->S0005;
  S0002-->S0007;
  S0004-->S0007;
  S0007-->S0006;
  S0003-->S0006;
  S0005-->S0006;
  S0006-->S0008; 
```

## Multisurface and Solid geometry
In order to simplify the definition of a validation plan, two requirement will be introduced in addition to the CityGML QIE: valid MultiSurface and valid Solid geometry. These requirements are just a collection of the linear ring, polygon and shell requirements. No extra check is required.

| Requirement ID | Description | Dependencies | Error code | Known checks |
| --------------- | ------------ | -------------- | ---------- |-------------------- |
| [R_GE_MS](R_GE_MS.md) | valid multisurface geometry | R_SC-SCHEMA-VALIDATION, R_GE_P_ALL | -- | -- |
| [R_GE_SO](R_GE_SO.md) | valid solid geometry | R_SC-SCHEMA-VALIDATION, R_GE_S_ALL | -- | -- |