# `GeoGenius.Providers.CSV`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/providers/csv.ex#L19)

Provider for a single delimited-text artifact with a header row.

One data row becomes one staged row: `payload` is a map keyed by header
name, every value a string, and `geom` is a `%Geo.Point{}` built from
`lon_column`/`lat_column` when both are configured and the row's cells for
them are non-empty, or `nil` otherwise. A CSV source carries no polygons --
a collection of postal codes with centroids and no boundaries is a
first-class catalog, not a degraded one. `normalize/2` reads the code and
names out of `payload` using the manifest's `options`, so the same module
serves any collection whose columns name their code and display name
differently.

`required_options/0` requires `"area_type"` and `"code_column"`. The
remaining `options` keys are optional:

  * `"name_column"` -- defaults to `"name"`.
  * `"authority"` -- defaults to the manifest's own authority, when it
    declares exactly one.
  * `"lon_column"` and `"lat_column"` -- both required together to build a
    centroid; neither alone.
  * `"attribute_columns"` -- a list; defaults to `[]`.
  * `"alias_columns"` -- a list; defaults to `[]`.
  * `"code_columns"` -- a list of `%{"type" => ..., "column" => ...}`;
    defaults to `[]`.
  * `"delimiter"` -- one of `","`, `"\t"`, `";"`, `"|"`; defaults to `","`.

See the option-vocabulary table in `GeoGenius.Provider`'s moduledoc for how
these correspond to `GeoGenius.Providers.GeoJSON`'s own option keys.

# `artifacts`

```elixir
@spec artifacts(GeoGenius.Manifest.t()) :: [GeoGenius.Manifest.Artifact.t()]
```

Every artifact declared across the manifest's sources; a CSV collection's artifacts are all delimited text.

# `asserted_relations`

```elixir
@spec asserted_relations(GeoGenius.Manifest.t(), GeoGenius.Staging.Row.t()) :: [
  {String.t(), String.t(), String.t()}
]
```

Asserts an edge from each area the row implies to the row's own area.

# `normalize`

```elixir
@spec normalize(GeoGenius.Manifest.t(), GeoGenius.Staging.Row.t()) ::
  {:ok, GeoGenius.Provider.Area.t()}
  | {:ok, [GeoGenius.Provider.Area.t()]}
  | :skip
  | {:error, String.t()}
```

Reads the code and names out of the staged row's payload, using the manifest's options.

# `relations`

```elixir
@spec relations(GeoGenius.Manifest.t()) :: :rebuild
```

CSV areas carry no hierarchy of their own; relations are always rebuilt.

# `required_options`

```elixir
@spec required_options() :: [String.t()]
```

Requires `area_type` and `code_column` in the manifest's options.

# `stage`

```elixir
@spec stage(
  GeoGenius.Manifest.t(),
  GeoGenius.Manifest.Artifact.t(),
  Path.t(),
  ([GeoGenius.Staging.Row.t()] -&gt; :ok),
  GeoGenius.Provider.stage_opts()
) :: :ok | {:error, GeoGenius.Provider.reason()}
```

Reads `path` as delimited text and emits its data rows in chunks of 1000 rows.

# `validate_options`

```elixir
@spec validate_options(map()) :: :ok | {:error, String.t()}
```

Validates the manifest's `implied_areas` entries, whose code key is `code_column`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
