Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 57 additions & 25 deletions packages/vector_prep/vector_prep/fetch_arcgis_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _resolve_hub_slug(slug: str) -> tuple[str, str, int]:
# ---------------------------------------------------------------------------
# Feature Service field fetch
# ---------------------------------------------------------------------------
def _fetch_service_fields(service_url: str) -> list[dict]:
def fetch_service_fields(service_url: str) -> list[dict]:
"""GET the feature service layer JSON and return the ``fields`` array."""
resp = requests.get(service_url, params={"f": "json"}, timeout=30)
resp.raise_for_status()
Expand Down Expand Up @@ -201,27 +201,27 @@ def _fetch_fgdc_descriptions(item_id: str) -> dict[str, str]:
return descs


# ---------------------------------------------------------------------------
# Core: merge into columns list
# ---------------------------------------------------------------------------
def fetch_columns_from_hub_url(hub_url: str, include_system_fields: bool = False) -> list[dict]:
"""Fetch column definitions from an ArcGIS Hub dataset URL.
def build_columns_from_service_fields(
service_fields: list[dict],
field_descriptions: dict[str, str] | None = None,
friendly_name_overrides: dict[str, str] | None = None,
include_system_fields: bool = False,
use_service_alias_as_friendly_name: bool = True,
) -> list[dict]:
"""Build layer_definitions ``columns`` from ArcGIS feature-service fields.

Args:
hub_url: A Hub dataset page URL, e.g.
``https://gbp-blm-egis.hub.arcgis.com/datasets/BLM-EGIS::blm-natl-grazing-allotment-polygons/about``
include_system_fields: If True, include Esri system fields such as
``OBJECTID``, ``GlobalID``, ``Shape__Area``, etc.

Returns:
A list of column dicts ready to insert into a layer_definitions.json
``columns`` array.
service_fields: Raw ``fields`` array from a feature service layer JSON.
field_descriptions: Optional field-name keyed descriptions.
friendly_name_overrides: Optional field-name keyed friendly-name mapping.
If present for a field, override values take precedence over service
aliases.
include_system_fields: If True, include Esri-generated system fields.
use_service_alias_as_friendly_name: If True, use field ``alias`` when a
friendly-name override is not provided.
"""
slug = _extract_slug(hub_url)
item_id, service_url, _layer_index = _resolve_hub_slug(slug)

service_fields = _fetch_service_fields(service_url)
fgdc_descs = _fetch_fgdc_descriptions(item_id)
field_descriptions = field_descriptions or {}
friendly_name_overrides = friendly_name_overrides or {}

columns: list[dict] = []
for field in service_fields:
Expand All @@ -238,15 +238,17 @@ def fetch_columns_from_hub_url(hub_url: str, include_system_fields: bool = False

col: dict = {"name": name}

# friendly_name from service alias (only if it differs from the raw name)
alias = field.get("alias", "")
if alias and alias != name:
col["friendly_name"] = alias
# friendly_name from overrides or service alias.
friendly_name = friendly_name_overrides.get(name, "")
if not friendly_name and use_service_alias_as_friendly_name:
friendly_name = field.get("alias", "")
if friendly_name and friendly_name != name:
col["friendly_name"] = friendly_name

col["dtype"] = dtype

# description from FGDC metadata
desc = fgdc_descs.get(name, "")
# description from external metadata map.
desc = field_descriptions.get(name, "")
if desc:
col["description"] = desc

Expand All @@ -255,6 +257,36 @@ def fetch_columns_from_hub_url(hub_url: str, include_system_fields: bool = False
return columns


# ---------------------------------------------------------------------------
# Core: merge into columns list
# ---------------------------------------------------------------------------
def fetch_columns_from_hub_url(hub_url: str, include_system_fields: bool = False) -> list[dict]:
"""Fetch column definitions from an ArcGIS Hub dataset URL.

Args:
hub_url: A Hub dataset page URL, e.g.
``https://gbp-blm-egis.hub.arcgis.com/datasets/BLM-EGIS::blm-natl-grazing-allotment-polygons/about``
include_system_fields: If True, include Esri system fields such as
``OBJECTID``, ``GlobalID``, ``Shape__Area``, etc.

Returns:
A list of column dicts ready to insert into a layer_definitions.json
``columns`` array.
"""
slug = _extract_slug(hub_url)
item_id, service_url, _layer_index = _resolve_hub_slug(slug)

service_fields = fetch_service_fields(service_url)
fgdc_descs = _fetch_fgdc_descriptions(item_id)

return build_columns_from_service_fields(
service_fields,
field_descriptions=fgdc_descs,
include_system_fields=include_system_fields,
use_service_alias_as_friendly_name=True,
)


# ---------------------------------------------------------------------------
# Optional: patch an existing layer_definitions.json
# ---------------------------------------------------------------------------
Expand Down
103 changes: 103 additions & 0 deletions packages/vector_prep/vector_prep/layer_definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,109 @@
"description": "Used for improved spatial query performance. Added in Riverscapes processing."
}
]
},
{
"layer_id": "blm-natl-grazing-pasture-polygons-nm-bootheel",
"layer_name": "BLM Grazing Pastures for NM Bootheel",
"source_title": "US DOI Bureau of Land Management National Operations Center Staff",
"columns": [
{
"name": "OBJECTID",
"friendly_name": "OBJECTID",
"dtype": "INTEGER",
"description": ""
},
{
"name": "Allot_Number",
"friendly_name": "Allot_Number",
"dtype": "STRING",
"description": ""
},
{
"name": "Allot_Name",
"friendly_name": "Allot_Name",
"dtype": "STRING",
"description": ""
},
{
"name": "Pasture_Number",
"friendly_name": "Pasture_Number",
"dtype": "STRING",
"description": ""
},
{
"name": "Pasture_Name",
"friendly_name": "Pasture_Name",
"dtype": "STRING",
"description": ""
},
{
"name": "Pasture_Acres",
"friendly_name": "Pasture_Acres",
"dtype": "FLOAT",
"description": ""
},
{
"name": "Admin_State",
"friendly_name": "Admin_State",
"dtype": "STRING",
"description": ""
},
{
"name": "Admin_Agency",
"friendly_name": "Admin_Agency",
"dtype": "STRING",
"description": ""
},
{
"name": "Admin_Office",
"friendly_name": "Admin_Office",
"dtype": "STRING",
"description": ""
},
{
"name": "Pasture_Latitude",
"friendly_name": "Pasture_Latitude",
"dtype": "FLOAT",
"description": ""
},
{
"name": "Pasture_Longitude",
"friendly_name": "Pasture_Longitude",
"dtype": "FLOAT",
"description": ""
},
{
"name": "Shape_Length",
"friendly_name": "Shape_Length",
"dtype": "FLOAT",
"description": ""
},
{
"name": "Shape_Area",
"friendly_name": "Shape_Area",
"dtype": "FLOAT",
"description": ""
},
{
"name": "Pasture_ID",
"friendly_name": "Pasture ID",
"dtype": "STRING",
"description": "Unique ID for pasture"
},
{
"name": "geometry",
"friendly_name": "Geometry (binary)",
"dtype": "GEOMETRY",
"description": "Pasture Multi-Polygon geometry"
},
{
"name": "geometry_bbox",
"friendly_name": "Geometry Bounding Box",
"dtype": "STRUCTURED",
"description": "Used for improved spatial query performance. Added in Riverscapes processing."
}
]
}
]
}
Loading
Loading