Search code examples
htmlrgisr-sfr-leaflet

Import data from a leaflet map as an sf object


I want to import data as an sf object in R from a leaflet map. The map is this site: https://erickgn.github.io/mapafc/ I also have the HTML from the map as following:https://raw.githubusercontent.com/erickgn/mapafc/main/index.html.


Solution

  • I also have the HTML from the map as following:https://raw.githubusercontent.com/erickgn/mapafc/main/index.html.

    Then you have everything. Either save the page locally, either scrape it using xml2 package. If you look on the page source, you can find something like:

    geo_json_b75320e180b34bb88a8a9025dff8675e_add({"bbox": [-44.447264,
     -23.03329, -41.6957233, -22.2949485],[...]
    

    as seems that are your features, you can read it with sf::st_read or jsonlite package.

    A small example for the first JSON:

    library(rvest)
    url <- "https://raw.githubusercontent.com/erickgn/mapafc/main/index.html"
    text <- html_text(read_html(url))
    

    Now we have to locate two strings which are before and after json and take the part between. Please note +1, -22 -- the first one is quite obvious, the second one is a bit of trying to remove unnecessary new lines etc.

    library(stringi)
    
    st <- stri_locate_first_fixed(text, "geo_json_b75320e180b34bb88a8a9025dff8675e_add(")[2]+1
    fi <- stri_locate_first_fixed(text, "geo_json_b75320e180b34bb88a8a9025dff8675e.bindTooltip(")[1]-22
    
    json <- substring(text, st, fi)
    

    And finally let's convert json to R objects:

    jsonlite::fromJSON(json)
    #> $bbox
    #> [1] -44.44726 -23.03329 -41.69572 -22.29495
    #> 
    #> $features
    #>                                           bbox
    #> 1   -43.59792, -22.82906, -43.58869, -22.82160
    #> 2   -43.38023, -22.96123, -43.37173, -22.95453
    #> 3   -43.50182, -23.03329, -43.49279, -23.02227
    #> 4   -43.29931, -22.99099, -43.29163, -22.98606
    [...]
    

    You can repeat similar steps for next json(s).

    And reading with sf package:

    library(sf)
    a <- st_read(json)
    #> Reading layer `OGRGeoJSON' from data source 
    #> [...]
    #>   using driver `GeoJSON'
    #> Simple feature collection with 249 features and 16 fields
    #> Geometry type: POLYGON
    #> Dimension:     XY
    #> Bounding box:  xmin: -44.44726 ymin: -23.03329 xmax: -41.69572 ymax: -22.29495
    #> Geodetic CRS:  WGS 84
    plot(a$geometry)
    

    Regards, Grzegorz