R/cartociudad_get_location_info.R

Defines functions cartociudad_get_location_info cartociudad_get_cadastral_info cartociudad_get_census_info

Documented in cartociudad_get_location_info

##########################################################################
# Luz frías, 2016-04-08
# Gets location info (mun, prov, censal section, etc.) for a location
##########################################################################

cartociudad_get_census_info <- function(bbox, year) {
  if (!year %in% c(2001, 2007:2016))
    warning("We have no census data for this year (available years: 2001, 2007-2016).")

  # The layers are associated to the year
  if (year == 2001) {
    layer.secciones <- paste0(year, "_CPV_Secciones")
    layer.distritos <- paste0(year, "_CPV_Distritos")
  } else if (year %in% c(2007, 2010:2011)) {
    layer.secciones <- paste0(year, "_PA_Secciones")
    layer.distritos <- paste0(year, "_PA_Distritos")
  } else {
    layer.secciones <- paste0(year, "_Secciones")
    layer.distritos <- paste0(year, "_Distritos")
  }
  layers <- c(layer.secciones, layer.distritos)

  query.parms <- list(
    bbox             = paste(bbox,   collapse = ","),
    layers           = paste(layers, collapse = ","),
    query_layers     = paste(layers, collapse = ","),
    width            = 1,
    height           = 1,
    version          = "1.3.0",
    format           = "text/xml",
    info_format      = "text/xml",
    service          = "WMS",
    request          = "GetFeatureInfo",
    styles           = "",
    crs              = "EPSG:4258"
  )

  url <- "http://servicios.internet.ine.es/WMS/WMS_INE_SECCIONES_G01/MapServer/WMSServer"
  ua <- get_cartociudad_user_agent()

  res <- httr::GET(url, query = query.parms, ua)
  httr::stop_for_status(res)
  info <- httr::content(res, "parsed", encoding = "UTF-8")

  # Parse the response
  if (xml2::xml_length(info) == 0) {
    return(list())
  }
  node.sec <- xml2::xml_find_first(info, '//*[@CUSEC]')
  node.dis <- xml2::xml_find_first(info, '//*[@CUDIS]')

  res <- list(seccion   = xml2::xml_attr(node.sec, "CUSEC"),
              distrito  = xml2::xml_attr(node.dis, "CUDIS"),
              provincia = xml2::xml_attr(node.sec, "NPRO"),
              municipio = xml2::xml_attr(node.sec, "NMUN"))
  return(res)
}

cartociudad_get_cadastral_info <- function(bbox) {

  layer <- "Catastro"
  # BBOX structure for cadastre API is (lon, lat, lon, lat)
  bbox <- c(bbox[2], bbox[1], bbox[4], bbox[3])

  query.parms <- list(
    bbox             = paste(bbox, collapse = ","),
    layers           = layer,
    query_layers     = layer,
    width            = 101,
    height           = 101,
    X                = 50,
    Y                = 50,
    version          = "1.1.1",
    format           = "image/png",
    info_format      = "text/html",
    service          = "WMS",
    request          = "GetFeatureInfo",
    styles           = "",
    srs              = "EPSG:4258"
  )

  url <- "http://ovc.catastro.meh.es/Cartografia/WMS/ServidorWMS.aspx"
  ua <- get_cartociudad_user_agent()

  res <- httr::GET(url, query = query.parms, ua)
  httr::stop_for_status(res)
  info <- httr::content(res, "parsed")

  # Parse the response
  if (is.null(info) || xml2::xml_length(info) == 0) {
    return(list())
  }
  node <- xml2::xml_find_first(info, "//a[@href]")
  res <- list(ref.catastral     = xml2::xml_text(node),
              url.ref.catastral = xml2::xml_attr(node, "href"))
  return(res)
}





#' @title Administrative information for a location
#'
#' @description Returns the administrative information related to a geographical
#'   point in Spain: province, municipality, censal district, censal section,
#'   cadastral reference and reverse geocoding data.
#'
#' @details This function consults administrative information for a point within
#'   Spain. Censal information is consulted from a different set of layers, each
#'   one corresponding to a different year. Whereas provincial and municipal
#'   information is mostly stable, censal districts and sections may be subject
#'   to greater changes over the years.
#'
#' @usage cartociudad_get_location_info(latitude, longitude, year = 2016,
#'   info.source = c("census", "cadastre", "reverse"))
#'
#' @param latitude Point latitude in geographical coordinates (e.g., 40.473219)
#' @param longitude Point longitude in geographical coordinates (e.g.,
#'   -3.7227241)
#' @param year Reference year; see Details section
#' @param info.source A character vector specifying the APIs to consult.
#'   Possible values are "census", "cadastre" and "reverse"
#'
#' @return A list contaning the administrative information for the given point.
#'   For \code{info.source = "census"} it contains the province, municipality,
#'   censal discrict and censal section codes. For \code{info.source =
#'   "cadastre"} it contains the cadastral reference and the url to the spanish
#'   cadastre website. For \code{info.source = "reverse"} it contains the
#'   details of the address closest to the specified location, such us road
#'   type, number, zip code, street name, ... More information about reverse
#'   geocoding in \code{\link{cartociudad_reverse_geocode}}.
#'
#' @author Luz Frías with small edits by Carlos J. Gil Bellosta
#'
#' @references INE's web service is mostly undocumented and the function has
#'   been built by reverse engineering API calls. However, users may want to
#'   check the \emph{capabilities} of INEs WMS service at
#'   \url{http://goo.gl/aKn3vj}. Cadastre web service documentation can be
#'   consulted at \url{http://goo.gl/lKkwK} and WMS service \emph{capabilities}
#'   at \url{http://goo.gl/5JAd9N}.
#'
#' @examples
#' cartociudad_get_location_info(40.473219, -3.7227241)
#'
#' @export
#'
cartociudad_get_location_info <- function(latitude, longitude, year = 2016,
                                          info.source = c("census", "cadastre", "reverse")) {

  bbox1 <- latitude
  bbox2 <- longitude
  # if the bbox has no area, the request fails
  bbox3 <- latitude  + 1e-5
  bbox4 <- longitude + 1e-5
  bbox <- c(bbox1, bbox2, bbox3, bbox4)

  result <- list()

  if ("census" %in% info.source) {
    result <- cartociudad_get_census_info(bbox, year)
  }
  if ("cadastre" %in% info.source) {
    result <- append(result, cartociudad_get_cadastral_info(bbox))
  }
  if ("reverse" %in% info.source) {
    result <- append(result, cartociudad_reverse_geocode(latitude, longitude))
  }

  # Avoid duplicated information. Different sources may both return results for
  #  the same field (e.g. province)
  result <- result[unique(names(result))]
  return(result)
}
cjgb/caRtociudad documentation built on June 2, 2022, 7:15 p.m.