mapview icon indicating copy to clipboard operation
mapview copied to clipboard

Cannot plot sf dataframes without this error: "Error: Field count reached: duplicate names present?"

Open hkhirsh opened this issue 1 year ago • 2 comments

I am getting "Error: Field count reached: duplicate names present?" every time I try to plot an sf data.frame, specifically after left joining an sf dataframe with a regular dataframe.

My code previously ran fine but recently this error started popping up and I cannot find information relating this error to Mapview online. I am using a Mac.

I updated R to see if that fixed it. It did not. So I reverted back to R version 4.2.1. It still does not work (for me) A friend was able to run my code on a Windows computer using R version 4.2.1 but not using the updated R.

I'm not sure the best way to share my specific code here (without data since it is not yet published). This is my first time seeking help in this way. Has anyone received this error?

hkhirsh avatar Aug 28 '24 22:08 hkhirsh

I have never come across this error. And without a reproducible example, I don't think I can help.

tim-salabim avatar Aug 29 '24 04:08 tim-salabim

Could you share the output of traceback() just after the error occurs? That would tell us where it happens.

edzer avatar Aug 29 '24 05:08 edzer

I also came across this error on some code that previsously worked:

Is this helpful to you?

library(osmdata)
library(mapview)


# Example Polygons
# OSM public data buildings marburg
# load OSM data for the Marburg region

buildings <- osmdata::opq(bbox = "marburg de") %>%
  osmdata::add_osm_feature(key = "building") %>%
  osmdata::osmdata_sf()

buildings <- buildings$osm_polygons

mapview::mapview(buildings)

sessionInfo()

output:

library(osmdata) Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright library(mapview) GDAL version >= 3.1.0 | setting mapviewOptions(fgb = TRUE) buildings <- osmdata::opq(bbox = "marburg de") %>%

  • osmdata::add_osm_feature(key = "building") %>%
  • osmdata::osmdata_sf()

buildings <- buildings$osm_polygons mapview::mapview(buildings) Error: Field count reached: duplicate names present? sessionInfo() R version 4.4.1 (2024-06-14 ucrt) Platform: x86_64-w64-mingw32/x64 Running under: Windows 11 x64 (build 22621)

Matrix products: default

locale: [1] LC_COLLATE=German_Germany.utf8 LC_CTYPE=German_Germany.utf8 LC_MONETARY=German_Germany.utf8 LC_NUMERIC=C
[5] LC_TIME=German_Germany.utf8

time zone: Europe/Berlin tzcode source: internal

attached base packages: [1] stats graphics grDevices datasets utils methods base

other attached packages: [1] mapview_2.11.2 osmdata_0.2.5

loaded via a namespace (and not attached): [1] jsonlite_1.8.8 compiler_4.4.1 Rcpp_1.0.12 xml2_1.3.6 leaflet_2.2.2 scales_1.3.0 png_0.1-8
[8] fastmap_1.2.0 lattice_0.22-6 R6_2.5.1 generics_0.1.3 curl_5.2.1 classInt_0.4-10 satellite_1.0.5
[15] httr2_1.0.1 sf_1.0-16 htmlwidgets_1.6.4 units_0.8-5 munsell_0.5.1 lubridate_1.9.3 DBI_1.2.3
[22] rlang_1.1.4 sp_2.1-4 terra_1.7-78 timechange_0.3.0 cli_3.6.3 magrittr_2.0.3 class_7.3-22
[29] crosstalk_1.2.1 digest_0.6.36 grid_4.4.1 rstudioapi_0.16.0 leafem_0.2.3 rappdirs_0.3.3 base64enc_0.1-3
[36] lifecycle_1.0.4 KernSmooth_2.23-24 proxy_0.4-27 glue_1.7.0 raster_3.6-26 codetools_0.2-20 stats4_4.4.1
[43] e1071_1.7-14 colorspace_2.1-0 tools_4.4.1 htmltools_0.5.8.1

Baldl avatar Sep 18 '24 10:09 Baldl

@edzer this seems to be a problem with writing the features to a temp flatgeobuf file. Specifically with the attributes (names?), as

mapview(st_geometry(buildings))
mapview(buildings[, 5:288])

works without problems, whereas e.g.

mapview(buildings[, 2:288])
mapview(buildings[, 1:115])

does throw the error.

Here's the traceback.

mapview::mapview(buildings)
Error: Field count reached: duplicate names present?
> traceback()
14: stop(structure(list(message = "Field count reached: duplicate names present?\n", 
        call = NULL, cppstack = structure(list(file = "", line = -1L, 
            stack = c("/home/tim/R/x86_64-pc-linux-gnu-library/4.4/sf/libs/sf.so(Rcpp::exception::exception(char const*, bool)+0x9a) [0x7f62996db78a]", 
            "/home/tim/R/x86_64-pc-linux-gnu-library/4.4/sf/libs/sf.so(void Rcpp::stop<>(char const*)+0x4f) [0x7f62996b32b6]", 
            "/home/tim/R/x86_64-pc-linux-gnu-library/4.4/sf/libs/sf.so(+0x3723c) [0x7f62996b723c]", 
            "/home/tim/R/x86_64-pc-linux-gnu-library/4.4/sf/libs/sf.so(CPL_write_ogr(Rcpp::Vector<19, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<19, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, Rcpp::Vector<16, Rcpp::PreserveStorage>, bool, Rcpp::Vector<10, Rcpp::PreserveStorage>, bool, bool, bool, int)+0xb4d) [0x7f629970eafd]", 
            "/home/tim/R/x86_64-pc-linux-gnu-library/4.4/sf/libs/sf.so(_sf_CPL_write_ogr+0x2b2) [0x7f62996d58b2]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x1037f0) [0x7f62a01037f0]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x146d88) [0x7f62a0146d88]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x15a89d) [0x7f62a015a89d]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(Rf_eval+0x17b) [0x7f62a015ac0b]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x15cddf) [0x7f62a015cddf]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x15dbc7) [0x7f62a015dbc7]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x15e5ed) [0x7f62a015e5ed]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x1a3ca4) [0x7f62a01a3ca4]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x1a4371) [0x7f62a01a4371]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x1a46f2) [0x7f62a01a46f2]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x13f71f) [0x7f62a013f71f]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(+0x15a89d) [0x7f62a015a89d]", 
            "/opt/R/4.4.1/lib/R/lib/libR.so(Rf_eval+0x17b) [0x7f62a015ac0b]", 
     ...
13: CPL_write_ogr(obj, dsn, layer, driver, as.character(dataset_options), 
        as.character(layer_options), geom, dim, fids, config_options, 
        quiet, append, delete_dsn, delete_layer, write_geometries, 
        getOption("width"))
12: st_write.sf(obj = x, dsn = fl, driver = "FlatGeobuf", layer_options = c("SPATIAL_INDEX=NO"), 
        append = FALSE, quiet = TRUE)
11: sf::st_write(obj = x, dsn = fl, driver = "FlatGeobuf", layer_options = c("SPATIAL_INDEX=NO"), 
        append = FALSE, quiet = TRUE)
10: sfFgb(x = x, map = map, pane = pane, zcol = zcol, color = color, 
        col.regions = col.regions, at = at, na.color = na.color, 
        cex = cex, lwd = lwd, alpha = alpha, alpha.regions = alpha.regions, 
        map.types = map.types, verbose = verbose, popup = popup, 
        layer.name = layer.name, label = label, legend = legend, 
        legend.opacity = legend.opacity, homebutton = homebutton, 
        native.crs = native.crs, highlight = highlight, maxpoints = maxpoints, 
        attributes = sf2DataFrame(x, drop_sf_column = TRUE), canvas = canvas, 
        viewer.suppress = viewer.suppress, hide = hide, ...)
9: leaflet_sf(x, map = map, pane = pane, zcol = zcol, color = color, 
       col.regions = col.regions, at = at, na.color = na.color, 
       cex = cex, lwd = lwd, alpha = alpha, alpha.regions = alpha.regions, 
       na.alpha = na.alpha, map.types = map.types, verbose = verbose, 
       popup = popup, layer.name = layer.name, label = label, legend = legend, 
       legend.opacity = legend.opacity, homebutton = homebutton, 
       native.crs = native.crs, highlight = highlight, maxpoints = maxpoints, 
       canvas = canvas, viewer.suppress = viewer.suppress, hide = hide, 
       ...)
8: .local(x, ...)
7: mapView(...)
6: mapView(...)
5: mapview(...)
4: eval(mc, env)
3: eval(mc, env)
2: standardGeneric("mapview")
1: mapview::mapview(buildings)

tim-salabim avatar Sep 21 '24 08:09 tim-salabim

Would you mind providing a reprex? Is this specific for flatgeobuf?

edzer avatar Sep 21 '24 09:09 edzer

It's this example. I don't think this is specific to flatgeobuf. Using mapviewOptions(fgb = FALSE) produces JSON.parse error(s) in the browser console. So this might well be an issue with the data or how it is prepared by osmdata.

tim-salabim avatar Sep 21 '24 09:09 tim-salabim

Big mystery.

edzer avatar Sep 21 '24 13:09 edzer

I had this problem but managed to solve this by cleaning up the names of my columns. I assume some case normalisation is happening along the process that causes 'cluster' and 'Cluster' to have the same column name despite having different information. Ideally I should be naming my columns properly but I got lazy along the way...

odour_sf <- st_as_sf(vis_df, coords = c("longitude", "latitude"), crs = 4326)

mapview(odour_sf) Error: Field count reached: duplicate names present?

colnames(odour_sf) [1] "cluster" "Observed Location" "Date and Time"
[4] "Cluster ID" "Cluster" "geometry"

colnames(odour_sf)[1] <- "New_Cluster_Name"

Works fine after this.

Robbie-RL avatar Sep 25 '24 06:09 Robbie-RL

Thanks @Robbie-RL , this seems to be the problem indeed! There's two fields named FIXME and fixme. After assingning a new name to one of them things work as expected...

library(osmdata)
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(mapview)


# Example Polygons
# OSM public data buildings marburg
# load OSM data for the Marburg region

buildings <- osmdata::opq(bbox = "marburg de") %>%
  osmdata::add_osm_feature(key = "building") %>%
  osmdata::osmdata_sf()

buildings <- buildings$osm_polygons

anyDuplicated(tolower(names(buildings)))
#> [1] 113

names(buildings)[113]
#> [1] "fixme"

grep("fixme", tolower(names(buildings)))
#> [1]   3 113

names(buildings)[c(3, 113)]
#> [1] "FIXME" "fixme"

names(buildings)[113] = "fixme2"

# mapview(buildings)

Created on 2024-09-25 with reprex v2.1.0

tim-salabim avatar Sep 25 '24 07:09 tim-salabim

Is this something that could be fixed in osmdata, @mpadge?

edzer avatar Sep 25 '24 07:09 edzer

@edzer Yes indeed. I'll ping you back here when that's done.

mpadge avatar Sep 25 '24 09:09 mpadge

library(osmdata)
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
packageVersion ("osmdata")
#> [1] '0.2.5.23'
buildings <- osmdata::opq(bbox = "marburg de") %>%
  osmdata::add_osm_feature(key = "building") %>%
  osmdata::osmdata_sf()

buildings <- buildings$osm_polygons
any(duplicated(tolower(names(buildings))))
#> [1] FALSE

Created on 2024-09-25 with reprex v2.1.1

I'll submit new CRAN version pretty soon.

mpadge avatar Sep 25 '24 11:09 mpadge

Great, thanks Mark!

edzer avatar Sep 25 '24 12:09 edzer

Thanks @mpadge! Closing here. Feel free to re-open if issue still persists

tim-salabim avatar Sep 26 '24 14:09 tim-salabim