koenderks / rcityviews

rcityviews is a user-friendly R interface for creating stylized city maps using OpenStreetMap (www.openstreetmap.org) data, implemented as an R package and a Shiny web application.
https://koenderks.github.io/rcityviews/
GNU General Public License v3.0
163 stars 22 forks source link

[Bug] Error when asking local Overpass API server #17

Closed stalkerGH closed 10 months ago

stalkerGH commented 10 months ago

When using local Overpass API server, rcityview stops with message _Error in overpass_query(query = obj$overpasscall, 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: https://github.com/ropensci/osmdata/issues/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

koenderks commented 10 months ago

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.

stalkerGH commented 10 months ago

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.