#' @rdname location_initialize
#' @export
#' @importFrom MazamaCoreUtils stopIfNull
#' @importFrom MazamaSpatialUtils getCountryCode getStateCode getTimezone
#' @importFrom dplyr tibble
#' @importFrom stringr str_sub
#'
#' @title Create known location record with core metadata
#'
#' @param longitude Single longitude in decimal degrees E.
#' @param latitude Single latitude in decimal degrees N.
#' @param stateDataset Name of spatial dataset to use for determining state
#' @param elevationService Name of the elevation service to use for determining
#' the elevation. Default: NULL skips this step. Accepted values: "usgs".
#' @param addressService Name of the address service to use for determining
#' the street address. Default: NULL skips this step. Accepted values: "photon".
#' @param precision \code{precision} argument passed on to \link{location_createID}.
#' @param verbose Logical controlling the generation of progress messages.
#'
#' @return Tibble with a single new known location.
#'
#' @description Creates a known location record with the following columns
#' of core metadata:
#' \itemize{
#' \item{locationID}
#' \item{locationName}
#' \item{longitude}
#' \item{latitude}
#' \item{elevation}
#' \item{countryCode}
#' \item{stateCode}
#' \item{countyName}
#' \item{timezone}
#' \item{houseNumber}
#' \item{street}
#' \item{city}
#' \item{postalCode}
#' }
#'
#' @examples
#' \donttest{
#' library(MazamaLocationUtils)
#'
#' # Fail gracefully if any resources are not available
#' try({
#'
#' # Set up standard directories and spatial data
#' spatialDataDir <- tempdir() # typically "~/Data/Spatial"
#' initializeMazamaSpatialUtils(spatialDataDir)
#'
#' # Wenatchee
#' lon <- -120.325278
#' lat <- 47.423333
#'
#' locationRecord <- location_initialize(lon, lat)
#' str(locationRecord)
#'
#' }, silent = FALSE)
#' }
location_initialize <- function(
longitude = NULL,
latitude = NULL,
stateDataset = "NaturalEarthAdm1",
elevationService = NULL,
addressService = NULL,
precision = 10,
verbose = TRUE
) {
validateMazamaSpatialUtils()
# ----- Validate parameters --------------------------------------------------
validateLonLat(longitude, latitude)
MazamaCoreUtils::stopIfNull(stateDataset)
MazamaCoreUtils::stopIfNull(precision)
if ( !exists(stateDataset) ) {
stop(paste0(
"You must load \"stateDataset\" with: \n",
" loadSpatialData(\"", stateDataset, "\")\n"
))
}
if ( !is.null(addressService) ) {
if ( !is.character(addressService) ) {
stop("Currently, only the \"photon\" address service is supported.")
} else {
if ( tolower(addressService) != "photon" )
stop("Currently, only the \"photon\" address service is supported.")
}
}
if ( !is.null(elevationService) ) {
if ( !is.character(elevationService) ) {
stop("Currently, only the \"usgs\" address service is supported.")
} else {
if ( tolower(elevationService) != "usgs" )
stop("Currently, only the \"usgs\" address service is supported.")
}
}
# ----- locationID, Elevation ------------------------------------------------
locationID <- location_createID(
longitude = longitude,
latitude = latitude,
algorithm = "geohash",
precision = precision
)
if ( is.null(elevationService) ) {
elevation <- NA
} else {
if ( tolower(elevationService) != "usgs" ) {
elevation <- NA
} else {
elevation <- location_getSingleElevation_USGS(
longitude = longitude,
latitude = latitude,
verbose = verbose
)
}
}
# ----- Country, State, County, Timezone -------------------------------------
countryCode <- MazamaSpatialUtils::getCountryCode(
lon = longitude,
lat = latitude,
dataset = "EEZCountries",
useBuffering = FALSE
)
stateCode <- MazamaSpatialUtils::getStateCode(
lon = longitude,
lat = latitude,
dataset = stateDataset,
useBuffering = TRUE
)
countyName <- MazamaSpatialUtils::getUSCounty(
lon = longitude,
lat = latitude,
dataset = "USCensusCounties",
stateCodes = stateCode,
useBuffering = TRUE
)
timezone <- MazamaSpatialUtils::getTimezone(
lon = longitude,
lat = latitude,
dataset = "OSMTimezones",
useBuffering = TRUE
)
# ----- LocationName ---------------------------------------------------------
# NOTE: The default locationName is intended to give folks a more memorable
# NOTE: handel than the locationID but is not guaranteed to be unique. It is
# NOTE: expected that users will add their own, more relevant names
# NOTE: appropriate for the community of practice using a particular
# NOTE: collectionName of known locations.
locationName <- paste0(
tolower(countryCode), ".",
tolower(stateCode), "_",
stringr::str_sub(locationID, 1, 6)
)
# ----- Address --------------------------------------------------------------
if ( is.null(addressService) ) {
addressList <- list(
"houseNumber" = as.character(NA),
"street" = as.character(NA),
"city" = as.character(NA),
"postalCode" = as.character(NA)
)
} else {
if ( tolower(addressService) != "photon" ) {
addressList <- list(
"houseNumber" = as.character(NA),
"street" = as.character(NA),
"city" = as.character(NA),
"postalCode" = as.character(NA)
)
} else {
addressList <- location_getSingleAddress_Photon(
longitude = longitude,
latitude = latitude,
verbose = verbose
)
# NOTE: The Photon reverse geocoding service returns NA for countryCode
# NOTE: and stateCode when no specific address can be found. In these
# NOTE: cases (remote areas) we want to use the MazamaSpatialUtils results.
# NOTE: Otherwise, we trust that Photon reverse geocoding is more accurate
# NOTE: than the point-in-polygon seraches done by MazamaSpatialUtils.
if ( !is.na(addressList$countryCode) &&
addressList$countryCode != countryCode ) {
# Trust address data over MazamaSpatialUtils result
if ( verbose ) {
warning(sprintf(
"Using address countryCode \"%s\" over MazamaSpatialUtils \"%s\"",
addressList$countryCode, countryCode
))
}
countryCode <- addressList$countryCode
}
if ( !is.na(addressList$stateCode) &&
addressList$stateCode != stateCode ) {
# Trust address data over MazamaSpatialUtils result
MazamaStateCode <- stateCode
# Change stateCode and reset possibly incorrect countyName
stateCode <- addressList$stateCode
countyName <- as.character(NA)
# Update locationName
locationName <- paste0(
tolower(countryCode), ".",
tolower(stateCode), "_",
stringr::str_sub(locationID, 1, 6)
)
if ( verbose ) {
warning(sprintf(
"For %s, using address stateCode \"%s\" over MazamaSpatialUtils \"%s\"",
locationName, addressList$stateCode, MazamaStateCode
))
}
}
}
} # END is.null(addressService) check
# ----- Return ---------------------------------------------------------------
locationTbl <- dplyr::tibble(
"locationID" = locationID,
"locationName" = locationName,
"longitude" = longitude,
"latitude" = latitude,
"elevation" = elevation,
"countryCode" = toupper(countryCode),
"stateCode" = toupper(stateCode),
"countyName" = countyName,
"timezone" = timezone,
"houseNumber" = as.character(addressList$houseNumber),
"street" = as.character(addressList$street),
"city" = as.character(addressList$city),
"postalCode" = as.character(addressList$postalCode)
)
return(locationTbl)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.