Networks & feature classes

The structural layer of the Infrastructure module - a tenant-level feature class catalog, networks filed under classes, and the rates and lifetimes that make valuation work.

Get this layer right and everything downstream - valuation, condition roll-ups, GIS mapping - falls into place. It's the infrastructure equivalent of classifications for vertical assets. Both networks and classes are managed under Settings → Infrastructure → Classes & networks (the old Infrastructure → Networks address redirects there).

The model

Feature classes are a tenant-level catalog of the kinds of things you manage: Watermain, Road Segment, Hydrant, Streetlight. A network is a service system - Roads, Water Distribution, Sanitary Sewer - and every network is filed under exactly one feature class. Classes contain networks, not the other way around: "Watermain" is the class, and "Water Distribution - North" and "Water Distribution - South" can both sit under it.

Create one network per system you'd report on separately to council - replacement value, condition distribution, and backlog all summarize per network. Resist the mega-network: "Public Works" as one network makes every roll-up useless.

Feature class settings

Each class in the catalog carries:

SettingWhat it does
CodeImmutable natural key - used in URLs and map tile filters
Label, category, color, sort orderHow the class presents in lists and on the map
Built-in flagShips with the product; see the restructuring notes below
Unit replacement rate + unit$ per m, each, m², or m³ - the basis for valuation
Service life (years)Default lifecycle for features priced through this class
Rate reviewed onThe date the rate was last reviewed
Rate sourceWhere the rate came from - "Engineering 2025", a tender reference. The line that makes the number defensible in an audit
CriticalityConsequence of failure (1-5) for features of this class that carry none, optionally escalated above a diameter

Rates resolve through three tiers

A feature's replacement rate (and its service life) resolves in order:

  1. The feature's own unit replacement value, when set
  2. The material default for its feature class and diameter - a row in Settings → Infrastructure → Material rates naming the material, the class, and the diameter band
  3. The any-class default for that material and diameter - the same grid, with the class left as Any class
  4. The class rate - the fallback that, on a typical Esri tenant, supplies all of the pricing

You never have to work the chain out by hand: a feature's page says which tier priced it in its Priced from row - the material band, the class rate, a value the feature carries itself (which no rate edit here will move), or a historical cost.

Criticality is set on the class

Criticality on a class is the consequence of failure, 1-5, that features of that class take when they carry none of their own. It is the answer to "how bad is it when one of these fails", and it is a property of the kind of thing, not of the individual feature - which is why it lives here rather than being typed a few thousand times.

Most classes need one number. A hydrant, a sign, a length of sidewalk: the consequence does not change with size, and there is no size to read. Where it does change - a trunk main against a lateral - open + size on the class and set a diameter and the criticality that applies at or above it. A feature below the threshold takes the base number, and so does a feature whose diameter was never recorded.

Leave a class's criticality empty and features of that class fall back to an organization-wide default, which is the same number for everything and says nothing about the class. Features show where their criticality came from, so a value standing on that default reads as Default rather than as an assessment - see feature risk.

Steps 2 and 3 are the same grid; a row either names a class or applies to all of them, and the narrower row wins. That matters because one material rarely costs the same everywhere: concrete in a sidewalk and concrete in a box culvert are different unit rates and often different units, and a single row cannot say both. Every row - here and on the class grid - carries a free-text Source ("Engineering 2025", "2024 tender, contract 24-118") alongside the reviewed-on date: the date says when the rate was last confirmed, the source says on whose authority.

The Material field on a feature picks from that same rates grid, showing the service life that applies for the network you have selected, so a feature is put onto a tier you have actually costed rather than a string that matches nothing. Materials your GIS publishes that aren't in the grid can still be typed in - CONC and Concrete stay separate rows on purpose, because merging them would silently reprice everything filed under either.

Editing a default re-prices every feature that resolves through it, without touching a row. A watermain class at $1,150/m values every synced segment automatically - 40 km of main becomes $46M of replacement value with no per-feature data entry.

What each unit multiplies

The rate is half the number. The other half is the quantity it multiplies, and the unit decides where that comes from:

UnitQuantity used
mThe feature's length, computed from its geometry when it syncs
each1 - what makes a node (hydrant, manhole, streetlight) priceable at all, since it has no length
m²Length × width
m³Length × width × depth

A feature's own quantity field overrides all of this when it is set.

Pick the unit your rates are actually quoted in. A sidewalk tendered at $180/m² prices a 120 m × 1.5 m walk at $32,400, and a 3 m walk at double that - a difference a per-metre rate cannot express. Width and depth arrive through the import mapping like any other attribute, so an area-priced class needs that field mapped.

Where the dimension a unit needs is missing, the feature shows no replacement value rather than a zero. An unpriced sidewalk and a free one are different things, and only one of them is a gap you can go and fill.

What ships out of the box

Every organization starts with eighteen built-in classes, each carrying the unit its assets are normally quoted in - and no rate and no service life, deliberately. A hydrant is priced per-each in every jurisdiction; what a hydrant costs is yours to set, and a default would flow into your FCI and capital plan looking like somebody chose it.

Service familyClassesUnit
TransportationRoad, Curb & Gutterm
Sidewalkm²
StormwaterStorm Sewerm
Catch Basineach
WastewaterSanitary Sewerm
Sanitary Manholeeach
WaterWatermainm
Hydrant, Water Valveeach
Gas, Electrical, TelecomGas, Electrical, Fibrem
Roadside / ElectricalSign, Streetlighteach
StructuresBridgeeach
Culvertm
OtherOther-

Diameter bands

Diameter is the largest driver of what a pipe costs to replace, so a rate row can name the diameter it starts at. Bands are a ladder of lower bounds: a feature takes the highest band at or below its own diameter, and a row with Diameter from left empty applies to any diameter.

A rate table like this:

DiameterRate
100-200 mm$340/m
250-400 mm$520/m
450-600 mm$780/m
600 mm and up$1,150/m

is entered as four rows with Diameter from of 100, 250, 450 and 600. A 300 mm main takes the 250 row; a 900 mm trunk takes the 600 row. Because bands are defined by where they start, two rows can never disagree about the same diameter and you cannot accidentally leave a gap between them.

Keep one row with Diameter from empty as the catch-all. A feature whose diameter was never recorded cannot be matched to a band, so it falls to that row - and without it, such a feature drops through to the class rate instead.

Add your own classes freely - the built-ins are a starting point, not a limit. They can't be deleted, but an unused class costs nothing but a row in this list.

Condition scales

Each network declares the condition scale its inspections arrive in: a 0-100 score, a 1-5 grade with 1 best, a 1-5 grade with 5 best, a pavement condition index (PCI) or a bridge condition index (BCI). Inspections are entered in the network's scale and converted to the internal 0-100 score by the database, keeping PACP-style sewer grades and road scores comparable in one portfolio.

PCI and BCI are 0-100 already, so they store unchanged, except that a value entered to a decimal place (72.5) is rounded. Choosing one is a declaration that the number is that index, not AssetLab's own score, and it is what O. Reg. 588/17 reporting computes the regulation's condition metrics from.

Class-level defaults, feature-level overrides

Features inherit rates and service life through the resolution chain but can override individually - the cast-iron main from 1962 can carry its own shortened life without a class fork. Prefer class and material defaults; override for documented exceptions.

Renaming and restructuring

Label, color, sort order, rate, service life, and criticality are editable on every class, and custom classes can also have their code and category changed - a code rename carries over to the networks filed under it. Built-in classes are partially frozen: their code and category can't change, and they can't be deleted. No class - built-in or custom - can be deleted while networks are still filed under it. Moving networks between classes changes how their features price - do it deliberately and re-check network totals on the map and dashboard afterward.

Deleting a network

Deleting a network deletes everything filed under it: every feature, and each feature's inspections, condition history, costs, comments, documents and route membership. Preventive maintenance schedules scoped to the network or to one of its features are deleted with it; work orders and work requests that referenced a deleted feature are kept, with the feature link cleared. You'll be asked to type the network's name to confirm.

On a large network the delete runs in batches and reports progress as it goes. Leave the window open until it finishes; closing it partway stops the run, and the network remains with whatever features have not yet been removed. Re-running the delete picks up where it stopped.

Any Esri source that pointed at the network survives the delete, but it is left unattached and its sync is switched off. To reuse it, point it at a new network and re-enable sync. Staged rows from the network's unfinished imports are cleared at the same time; the import history itself is kept.