# Esri & GIS sync

> Connect ArcGIS feature services, map GIS fields onto AssetLab columns, and keep AssetLab synchronized nightly - or import GeoJSON, shapefiles, and CSV through the wizard.

Source: https://app.assetlab.ca/docs/infrastructure/esri-sync

If your infrastructure inventory lives in ArcGIS, it should flow into AssetLab, not be retyped. Sync connects to Esri **feature services**, pulls features and geometry, and keeps them current nightly.

## The division of labour

- **Esri owns**: geometry, and the attributes you map from GIS. Corrections to *what and where things are* happen in GIS and flow down.
- **AssetLab owns**: condition, inspections, work orders, costs, lifecycle overrides, and planning. None of it writes back to GIS.

One direction, no conflicts, and both teams keep their system of record.

The edit form enforces this split: on an Esri-synced feature, GIS-owned fields (name, network, physical attributes, condition, install date) are locked with a note pointing at the source, and only the AssetLab-owned financial, planning, and risk fields stay editable. Manually created features keep the full form.

## Setting up a source

Under **Infrastructure → Import**, add an Esri source. One source connects **one layer** of a feature service to **one network** - the [feature class](/docs/infrastructure/networks-and-classes) comes from that network, so create the network (and check its class rates) first.

1. **Service URL and layer** - the feature service endpoint and the layer number. Secured services authenticate with a token you provide.
2. **Match key** - must be the layer's **GlobalID** field. OBJECTID-class keys are rejected, because geodatabase compaction renumbers them - a sync keyed on OBJECTID would silently re-identify your features.
3. **Field mapping** - GIS attributes onto AssetLab's fixed column set: name, feature code, description, material, install date, inspection date, condition score, diameter, from/to street, from/to invert, slope, width, depth, lanes, status, and asset type - plus a **condition scale** setting that tells the sync how to read the source's condition values.
4. **Options** - an optional server-side WHERE filter to sync a subset of the layer, and a feature type strategy: segments, nodes, or both.
5. **Initial sync** - run it, review counts, and spot-check on the [map](/docs/infrastructure/map).

## Ongoing sync

Sources with sync enabled run nightly on a fixed schedule - a 03:00 UTC window, one source every 5 minutes. The schedule isn't tenant-configurable; **Sync now** runs a source on demand regardless of the sync-enabled flag. Each run is capped at 150,000 features (paged 2,000 at a time) and:

- **Adds** features new in GIS
- **Updates** geometry and mapped attributes that changed
- **Handles removals** - features gone from GIS are soft-deleted in AssetLab rather than hard-deleted, because their work and cost history must survive

Sync history is visible per source: each run logs its insert, update, soft-delete, and reject counts (with reasons for the rejects), so "is AssetLab current with GIS?" has an auditable answer.

> [!warning] Field mapping is where sync quality is won or lost. Map install date and material at minimum: without them, lifecycle math falls back to class defaults for everything, and your replacement forecast flattens into fiction.

## What sync does to valuation

Synced geometry yields measured quantities (segment lengths), and quantity × the resolved unit rate maintains replacement value automatically. Redraw a segment in GIS and its value updates on the next sync - your network valuation stays as current as your GIS.

## No ArcGIS?

The Infrastructure module has its own import wizard - separate from the [general import wizard](/docs/start/importing-data) - that loads **GeoJSON**, **zipped shapefiles**, or **CSV** files up to 64 MB per file (split larger layers by area or asset class and import in parts). It walks seven steps: upload, match key, field mapping, coordinate system, topology (with a snap tolerance for closing small gaps), preview, and import - and it supports an update mode for re-importing against an existing network. Field mapping covers the same column set as GIS sync (create mode), the wizard reads your file's actual columns into drop-downs with best-guess pre-fills, and columns you don't map are kept on each feature's record. The mapping step can also create [custom fields](/docs/manage/org-settings) on the spot - pick a source column, name the field, choose its type - or **Add all** to carry every unmapped column at once - and the import fills them for every feature (up to 10 custom fields per record type). Features can also be created directly in AssetLab. GIS sync is the best path, not the only one.

Two guardrails protect the import itself. If a shapefile arrives without a readable .prj (or a CSV carries no coordinate system), the wizard stops at the coordinate system step and asks you to pick the source CRS rather than guessing - when the coordinates look like latitude/longitude it preselects WGS 84 for you to confirm. GeoJSON normally skips that step, because the format's own specification says it is longitude/latitude - but ArcGIS and ogr2ogr both write projected GeoJSON anyway, so a file whose coordinates are not degrees gets the coordinate system step too (and a stated `crs` member in the file is read and used). And if you re-import a file that is byte-for-byte identical to one already imported into the same network in create mode, the wizard warns you before the preview runs - re-importing would duplicate every feature - and points you at update mode instead (you can still proceed deliberately).
