Skip to main content
`Ctrl`+`K`

# ng911ok.lib.topology module

Implements functionality related to `topology.yml`. Exposes `topology_config`, which contains the data derived from topology.yml``.

Provides constructors for the following YAML tags (on `yaml.SafeLoader`):

- `!FieldRole` (Scalar -> `NG911Field`) - Given a field’s `role`, returns the corresponding field object

- `!DomainName` (Scalar -> `NG911Domain`) - Given a domain’s `name`, returns the corresponding field object

final class TopologyRule(dataset: str, member1: NG911FeatureClass, rule: str, member2: NG911FeatureClass | None = None)

  Bases: `object`

  Class representing a topology rule specified by the Standards.

  classmethod as_df(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') → DataFrame

    Returns all registered topology rules as a `DataFrame` with three columns: `member1`, `rule`, and `member2`.

    The `member1` and `member2` columns will have the dtype `object` if members_as is `OBJECT` or the dtype `string[python]` if members_as is `ROLE` (meaning the `NG911FeatureClass.role` attribute) or `NAME` (meaning the `NG911FeatureClass.name` attribute).

    The `rule` column will have the dtype `string[python]`.

    Parameters:

      - members_as (Literal["OBJECT", "ROLE", "NAME"]) – How the member should be represented.

      - rule_as (Literal["DESCRIPTION", "ETRT"]) – How the rules should be represented.

    Return pd.DataFrame:

      The registered topology rules as a `DataFrame`.

  classmethod from_dict(dataset: str, data: _OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict) → Self
  add_rule_to_topology(topology_name: str, manager: EnvManager | None = None) → Result

    Adds the rule to a topology using `arcpy`.

  as_series(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') → Series
  has_member(feature_class: NG911FeatureClass) → bool

    Returns whether a given feature class is a member of the rule.

  _registered_rules: ClassVar[list[Self]] = [TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>)]

    List of instances of this class, which are automatically registered after initialization.

  dataset: str

    The name of the feature dataset containing the feature class(es) to which the rule applies.

  member1: NG911FeatureClass

    The first member (“origin”) feature class included in the rule.

  member2: NG911FeatureClass | None

    The second member (“destination”) feature class included in the rule.

  property members: tuple[NG911FeatureClass] | tuple[NG911FeatureClass, NG911FeatureClass]

    Returns a tuple of the member or members of the rule.

  property name1: str

    Returns the `name` of `member1`.

  property name2: str | None

    Returns the `name` of `member2`.

  rule: str

    The name (from `_ESRI_RULE_NAMES`) of the topology rule.

  property rule_code: str

    Returns the `esriTopologyRuleType` code for the rule.

    See also

    `_ESRI_RULE_CODES`

class _NG911TopologyConfig(exception_field: NG911Field, exception_domain: NG911Domain, required_dataset_topology_name: str, optional_dataset_topology_name: str, required_dataset_rules: FrozenList[TopologyRule], optional_dataset_rules: FrozenList[TopologyRule])

  Bases: `YAMLObject`

  yaml_loader

    alias of `SafeLoader`

  classmethod from_yaml(loader: SafeLoader, node: Node)

    Convert a representation node to a Python object.

  enrich_error_df(error_df: DataFrame, members: Collection[DataFrame], fill_na_submit: bool | None = None) → DataFrame

    Processes a topology error DataFrame (from the Export Topology Errors geoprocessing tool). Unless it is empty, the returned `pandas.DataFrame` will have the following columns:

    Column Name | `dtype`
    --- | ---
    `OriginObjectClassName` | `string`
    `OriginObjectID` | `Int32`
    `DestinationObjectClassName` | `string`
    `DestinationObjectID` | `Int32`
    `RuleType` | `string`
    `RuleDescription` | `string`
    `SHAPE` | `geometry`
    `OriginObjectClassObject` | `object`
    `OriginObjectNGUID` | `string`
    `OriginObjectSubmit` | `boolean`
    `OriginObjectExceptions` | `object`
    `DestinationObjectClassObject` | `object`
    `DestinationObjectNGUID` | `string`
    `DestinationObjectSubmit` | `boolean`
    `DestinationObjectExceptions` | `object`
    `RuleObject` | `object`
    `IsException` | `boolean`

    Parameters:

      - error_df – Topology error DataFrame

      - members – All relevant member feature classes as DataFrames

      - fill_na_submit – Value to assume for invalid values of `
        SUBMIT`; if `None`, a ValueError will be raised if any features involved in an error have an invalid or missing value for that attribute; default None

    Returns:

      Copy of topology error DataFrame with additional columns

  get_rule(member1: NG911FeatureClass | NAType | None, rule_code: esriTopologyRuleType | str, member2: NG911FeatureClass | NAType | None = None) → TopologyRule | None

    Searches through the known rules for a rule matching the arguments and returns it. Returns `None` if no rule is found.

    Parameters:

      - member1 (NG911FeatureClass | NAType | None) – Feature class representing the first member

      - rule_code (esriTopologyRuleType | str) – The string code (e.g., esriTRTLineNoDangles), the string description (e.g., “Must Not Have Dangles (Line)”), or the `esriTopologyRuleType` instance representing the rule

      - member2 (NG911FeatureClass | NAType | None) – Feature class representing the second member, or `None` (or `pandas.NA`, which will be treated the same as `None`) if not applicable; default `None`

    Returns:

      The rule matching the arguments, or `None` if no such rule could be found

    Return type:

      TopologyRule | None

  _dangle_exc = frozenset({'esriTRTLineNoDangles'})
  _inside_exc = frozenset({'esriTRTLineInsideArea', 'esriTRTPointProperlyInsideArea'})
  address_point_allowed_values: ClassVar[frozenset[str]] = frozenset({'INSIDE_EXCEPTION', 'NO_EXCEPTION'})
  exception_domain: NG911Domain
  exception_field: NG911Field
  exception_mapping: ClassVar[FrozenDict[LiteralString, frozenset[str]]] = FrozenDict({'DANGLE_EXCEPTION': frozenset({'esriTRTLineNoDangles'}), 'INSIDE_EXCEPTION': frozenset({'esriTRTPointProperlyInsideArea', 'esriTRTLineInsideArea'}), 'BOTH_EXCEPTION': frozenset({'esriTRTLineNoDangles', 'esriTRTPointProperlyInsideArea', 'esriTRTLineInsideArea'}), 'NO_EXCEPTION': frozenset()})
  property optional_dataset_members: frozenset[NG911FeatureClass]

    Returns a `frozenset` with all `NG911FeatureClass` objects that are involved in `self.optional_dataset_rules`.

  optional_dataset_rules: FrozenList[TopologyRule]
  optional_dataset_topology_name: str
  property required_dataset_members: frozenset[NG911FeatureClass]

    Returns a `frozenset` with all `NG911FeatureClass` objects that are involved in `self.required_dataset_rules`.

  required_dataset_rules: FrozenList[TopologyRule]
  required_dataset_topology_name: str
  yaml_tag = '!TopologyConfig'

class _OneMemberTopologyRuleDict

  Bases: `TypedDict`

  member: str
  rule: str

class _TopologyConfigDict

  Bases: `TypedDict`

  exception_domain: NG911Domain
  exception_field: NG911Field
  optional_dataset_rules: NotRequired[list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]]
  optional_dataset_topology_name: str
  required_dataset_rules: list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]
  required_dataset_topology_name: str

class _TwoMemberTopologyRuleDict

  Bases: `TypedDict`

  member1: str
  member2: str
  rule: str

_construct_domain_from_name(loader: SafeLoader, node: Node) → NG911Domain

_construct_field_from_role(loader: SafeLoader, node: Node) → NG911Field

ODST: Final[str] = 'OptionalLayers_Topology'

  Name of the optional feature dataset‘s topology. Acronym for Optional Dataset Topology. Alias of `topology_config.required_dataset_topology_name`.

RDST: Final[str] = 'NG911_Topology'

  Name of the required feature dataset‘s topology. Acronym for Required Dataset Topology. Alias of `topology_config.required_dataset_topology_name`.

_ESRI_RULE_CODES: Final[frozenset[str]] = frozenset({'esriTRTAreaAreaCoverEachOther', 'esriTRTAreaBoundaryCoveredByAreaBoundary', 'esriTRTAreaBoundaryCoveredByLine', 'esriTRTAreaContainOnePoint', 'esriTRTAreaContainPoint', 'esriTRTAreaCoveredByArea', 'esriTRTAreaCoveredByAreaClass', 'esriTRTAreaNoGaps', 'esriTRTAreaNoOverlap', 'esriTRTAreaNoOverlapArea', 'esriTRTLineCoveredByAreaBoundary', 'esriTRTLineCoveredByLineClass', 'esriTRTLineEndpointCoveredByPoint', 'esriTRTLineInsideArea', 'esriTRTLineNoDangles', 'esriTRTLineNoIntersectLine', 'esriTRTLineNoIntersectOrInteriorTouch', 'esriTRTLineNoIntersectOrInteriorTouchLine', 'esriTRTLineNoIntersection', 'esriTRTLineNoMultipart', 'esriTRTLineNoOverlap', 'esriTRTLineNoOverlapLine', 'esriTRTLineNoPseudos', 'esriTRTLineNoSelfIntersect', 'esriTRTLineNoSelfOverlap', 'esriTRTPointCoincidePoint', 'esriTRTPointCoveredByAreaBoundary', 'esriTRTPointCoveredByLine', 'esriTRTPointCoveredByLineEndpoint', 'esriTRTPointDisjoint', 'esriTRTPointProperlyInsideArea'})

  Set of Esri topology rule codes, e.g., `esriTRTLineNoDangles`.

_ESRI_RULE_NAMES: Final[frozenset[str]] = frozenset({'Boundary Must Be Covered By (Area-Line)', 'Boundary Must Be Covered By Boundary Of (Area-Area)', 'Contains One Point (Area-Point)', 'Contains Point (Area-Point)', 'Endpoint Must Be Covered By (Line-Point)', 'Must Be Covered By (Area-Area)', 'Must Be Covered By (Point-Line)', 'Must Be Covered By Boundary Of (Line-Area)', 'Must Be Covered By Boundary Of (Point-Area)', 'Must Be Covered By Endpoint Of (Point-Line)', 'Must Be Covered By Feature Class Of (Area-Area)', 'Must Be Covered By Feature Class Of (Line-Line)', 'Must Be Disjoint (Point)', 'Must Be Inside (Line-Area)', 'Must Be Properly Inside (Point-Area)', 'Must Be Single Part (Line)', 'Must Coincide With (Point-Point)', 'Must Cover Each Other (Area-Area)', 'Must Not Have Dangles (Line)', 'Must Not Have Gaps (Area)', 'Must Not Have Pseudo-Nodes (Line)', 'Must Not Intersect (Line)', 'Must Not Intersect Or Touch Interior (Line)', 'Must Not Intersect With (Line-Line)', 'Must Not Intersect or Touch Interior With (Line-Line)', 'Must Not Overlap (Area)', 'Must Not Overlap (Line)', 'Must Not Overlap With (Area-Area)', 'Must Not Overlap With (Line-Line)', 'Must Not Self-Intersect (Line)', 'Must Not Self-Overlap (Line)'})

  Set of Esri topology rule names, e.g., `Must Not Have Dangles (Line)`.

_SUBMIT: Final[str] = 'SUBMIT'

  Name of the `
  SUBMIT` field.

_TOPOLOGY_YAML_PATH: Final[Path] = WindowsPath('G:/ArcGIS/Project Files/NG911/NG911_Pro/NG911-Pro/topology.yml')

  Path to `topology.yml`.

topology_config: _NG911TopologyConfig = _NG911TopologyConfig(exception_field=NG911Field(role='topoexcept', name='TopoExcept', type='String', priority='M', length=20, domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, fill_value='NO_EXCEPTION'), exception_domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, required_dataset_topology_name='NG911_Topology', optional_dataset_topology_name='OptionalLayers_Topology', required_dataset_rules=FrozenList((TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>))), optional_dataset_rules=FrozenList(()))

  The single instance of `_NG911TopologyConfig` that contains the topology rules specified in `topology.yml`.