--- title: "Discovering Tampa Bay data" description: "Search the checked catalog and live portals, then interpret and filter the results." output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Discovering Tampa Bay data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = FALSE) ``` `tampaBayOpenData` searches a bundled catalog of 52 checked layers or the live ArcGIS portals of six Tampa Bay publishers. Maintainers have validated the configured endpoints for checked layers. A `discovered` layer comes from a portal index and has not received those checks. Live examples below are displayed but not run while the site is built. The checked-catalog example runs offline. ## Start offline ```{r checked-catalog, eval=TRUE} library(tampaBayOpenData) tampaBayOpenData::tbod_list_portals()[, c("id", "publisher", "jurisdiction")] tampaBayOpenData::tbod_list_datasets(source = "checked")[, c("id", "title", "jurisdiction", "validation_status")] tampaBayOpenData::tbod_search_datasets( "park", source = "checked", spatial = TRUE, jurisdiction = c("stpete", "clearwater") ) tampaBayOpenData::tbod_dataset_info("construction-permits")[ c("title", "scope_note", "verified")] ``` `source = "checked"` reads the registry without HTTP. IDs such as `construction-permits` and `stpete-parks` are package names, not ArcGIS item IDs. `tbod_dataset_info(id)` gives the scope, terms, source URL, and endpoint verification date; that date says nothing about record freshness. The [coverage article](coverage.html) has counts by publisher, and the [selection policy](https://github.com/Jaclenga/tampaBayOpenData/blob/main/docs/checked-catalog-policy.md) explains which layers enter the catalog. ## Discover live portal layers ```{r live-search} found <- tbod_search_datasets("housing", source = "live", portals = "city") found[, c("id", "title", "publisher", "validation_status", "modified")] # A one-row result carries the source needed for inspection or retrieval. if (nrow(found)) { selected <- found[1, ] selected[, c("item_id", "service_url", "layer_id", "portal")] tbod_dataset_info(selected) } ``` By default, `tbod_list_datasets()` and `tbod_search_datasets()` use `source = "all"`: they search all six portals and include the checked catalog. `source = "live"` returns only layers found through portal indexes, including checked layers when a live endpoint matches a checked entry. If a source is not indexed or an index lags, it may not appear in live results; a compatible public ArcGIS layer can still be retrieved by URL with `tbod_get_arcgis_layer()`. Use `portals = "city"` for Tampa, `"tbrpc"` for the regional planning council, or `"stpete"`, `"clearwater"`, `"hillsborough"`, or `"pinellas"` for the other publishers. A vector selects several. `tbod_list_portals()` shows their publisher names and source locations offline. `jurisdiction` defaults to `"all"` for catalog functions and can be a code or a vector of codes. A jurisdiction or publisher filter narrows the organizations scanned and filters checked entries. `portals` only selects live organizations; it does not filter checked entries when `source = "all"`. Retrieval and download functions default to `jurisdiction = NULL`: a checked ID resolves across the bundled catalog when it is unique. If two jurisdictions use the same ID, supply `jurisdiction` to select one. When a live endpoint matches a checked entry, the result keeps its package ID, scope, and terms, combines checked and portal tags and categories, and uses the portal item's modification time. New IDs have the form `arcgis::` and can be passed to `tbod_get_dataset()` later. The item or service can still change or disappear. Retrieval checks query responses and requires `Query` when the layer advertises a capabilities list. ## Search beyond the bundled publishers `tbod_discover()` accepts a public ArcGIS sharing REST root, FeatureServer or MapServer service root, or a layer URL. Portal queries search public service items; service queries filter layer names. Both return rows accepted by `tbod_get_dataset()`. Portal results have `discovered` status and stable `arcgis:` IDs; service results have `not_checked` status and use the layer URL as their ID. Queryable MapServer layers are supported. ```{r custom-discovery} # Replace this example address with your portal's public sharing REST root. portal <- "https://example.maps.arcgis.com/sharing/rest" other <- tbod_discover(portal, query = "parks", max_items = 10) if (nrow(other)) { data <- tbod_get_dataset(other[1, ], limit = 100) # A stable ArcGIS ID can also be resolved later through its own portal. same_layer <- tbod_get_dataset(other$id[[1]], portal = portal, limit = 100) } ``` Custom sources default to an `"unspecified"` jurisdiction. Set `publisher` and `jurisdiction` in `tbod_discover()` when you know them; these labels then travel with the discovery row and its retrieval provenance. The `portal` argument on retrieval applies only to a stable `arcgis::` ID. When retrieving a direct layer URL, `tbod_get_dataset()` does not accept a `jurisdiction` override. ## Filter results Both catalog functions accept these optional filters: | Filter | Match | | --- | --- | | `jurisdiction` | One or more codes from `tbod_list_portals()`; default `"all"`. | | `publisher` | Exact publisher names from `tbod_list_portals()`, ignoring case. | | `validation_status` | `"checked"` or `"discovered"`. | | `spatial` | `TRUE` for geometry layers, `FALSE` for tables; unknown geometry is excluded when filtering. | | `topic` | Literal substring in tags and categories, ignoring case. | | `category` | Exact category path or final category label, ignoring case. | | `modified_after`, `modified_before` | Inclusive bounds on the catalog's `modified` timestamp. | Character filters accept vectors: values within one filter are alternatives; separate filters and the search text must all match. Date bounds accept a `Date` or strict `"YYYY-MM-DD"` string for a whole UTC day, or a `POSIXct` value for an exact instant. Rows with unknown modification times are excluded only when a date bound is supplied. ```{r county-search} county_transport <- tbod_search_datasets( "road", source = "live", jurisdiction = "pinellas", spatial = TRUE, topic = "transportation", modified_after = as.Date("2025-01-01"), max_items = 10 ) county_transport[, c("id", "title", "publisher", "modified", "modified_source")] ``` `modified_source = "portal_item"` identifies a live ArcGIS item timestamp; `"checked_snapshot"` identifies an upstream timestamp saved in the checked registry. Neither establishes when every record was last updated. The separate checked `verified` date records an endpoint check, not feature freshness. ## Understand scan limits and failures `max_items` caps **portal service items per organization**, not the number of expanded layers. The default scans at most 25 items per organization. Use `max_items = Inf` explicitly for a full live listing, with a suitable `total_timeout`. A capped listing can miss matching items beyond the scan limit. `jurisdiction` and `publisher` narrow organizations before scanning; other filters apply after discovery and the checked overlay. Consequently, an item matching `topic` or `modified_after` may be missed by a capped scan. ```{r scan-metadata} results <- tbod_list_datasets(source = "live", portals = "stpete", max_items = 10) attr(results, "discovery_complete") attr(results, "discovery_truncated_portals") attr(results, "discovery_scanned_items") attr(results, "discovery_issues") attr(results, "discovery_failed_portals") ``` Check `discovery_complete` before treating results as a complete portal catalog. The other attributes show scan progress, skipped items, and failed portals. A combined search retains rows from working publishers or from earlier pages of a failed scan. If all selected portals fail before returning rows, `source = "live"` errors; `source = "all"` warns and returns checked rows. Continue with [retrieval and downloads](retrieval.html) or read about [coverage and source limits](coverage.html).