koenderks/rcityviews

[Bug] Error when asking local Overpass API server

stalkerGH opened this issue · 2 comments

When using local Overpass API server, rcityview stops with message Error in overpass_query(query = obj$overpass_call, quiet = quiet, encoding = encoding) : object 'doc' not found. When using default (Kumi Systems) server, OSM data are downloaded.

My knowledge of R is very basic so I have trouble with debugging this issue. I suspected osmdata package but it seems that my local server is working good and handling the queries as expected. I don't want to make this bug report longer as it should so please look at this thread on osmdata issue tracker: ropensci/osmdata#335

I tried to debug in RStudio using debug() and debug(cityview) commands but failed - as I said my knowledge of R is very basic.

I can add logs and do further tests but I need advice.

My configuration

  • OS: Ubuntu 22.04
  • R 4.3.2
  • rcityviews 1.1.1
  • other R packages in most current versions

The issue is probably in the osmdata package, and specifically the overpass_query() function. The function definition is given below:

function (query, quiet = FALSE, wait = TRUE, pad_wait = 5, encoding = "UTF-8") 
{
    if (missing(query)) {
        stop("query must be supplied", call. = FALSE)
    }
    if (!is.character(query) | length(query) > 1) {
        stop("query must be a single character string")
    }
    if (!is.logical(quiet)) {
        quiet <- FALSE
    }
    if (!is.logical(wait)) {
        wait <- TRUE
    }
    if (!is.numeric(pad_wait)) {
        message("pad_wait must be numeric; setting to 5s")
        pad_wait <- 5
    }
    if (pad_wait < 0) {
        warning("pad_wait must be positive; setting to 5s")
        pad_wait <- 5
    }
    if (!curl::has_internet()) {
        stop("Overpass query unavailable without internet", call. = FALSE)
    }
    if (!quiet) 
        message("Issuing query to Overpass API ...")
    o_stat <- overpass_status(quiet)
    overpass_url <- get_overpass_url()
    if (o_stat$available) {
        req <- httr2::request(overpass_url)
        req <- httr2::req_method(req, "POST")
        req <- httr2::req_retry(req, max_tries = 10L)
        req <- httr2::req_body_raw(req, body = query)
        resp <- httr2::req_perform(req)
    }
    else {
        if (wait) {
            wait <- max(0, as.numeric(difftime(o_stat$next_slot, 
                Sys.time(), units = "secs"))) + pad_wait
            message(sprintf("Waiting %s seconds", wait))
            Sys.sleep(wait)
            req <- httr2::request(overpass_url)
            req <- httr2::req_method(req, "POST")
            req <- httr2::req_retry(req, max_tries = 10L)
            req <- httr2::req_body_raw(req, body = query)
            resp <- httr2::req_perform(req)
        }
        else {
            stop("Overpass query unavailable", call. = FALSE)
        }
    }
    if (!quiet) {
        message("Query complete!")
    }
    httr2::resp_check_status(resp)
    if (resp$headers$`Content-Type` == "application/osm3s+xml") {
        doc <- httr2::resp_body_xml(resp)
        check_for_error(paste0(doc))
    }
    else if (resp$headers$`Content-Type` == "text/csv") {
        doc <- httr2::resp_body_string(resp)
    }
    return(doc)
}

As you can see, this function tries to create a doc object in these lines:

 if (resp$headers$`Content-Type` == "application/osm3s+xml") {
      doc <- httr2::resp_body_xml(resp)
      check_for_error(paste0(doc))
  }
  else if (resp$headers$`Content-Type` == "text/csv") {
      doc <- httr2::resp_body_string(resp)
  }

My guess is that this variable("resp$headers$Content-Type") is something different than either "application/osm3s+xml" or "text/csv", and therefore the doc object is undefined. But it is difficult to replicate since it works for me on my pc using the default server.

Thank you VERY much. Although I don't know all functions in above code, my understanding it's enough to dig further. And of course ask on osmdata issue tracker.