{"id":39826061,"url":"https://github.com/mdsumner/rustycogs","last_synced_at":"2026-01-18T13:05:02.493Z","repository":{"id":283781636,"uuid":"952903507","full_name":"mdsumner/rustycogs","owner":"mdsumner","description":"What the Package Does (One Line, Title Case)","archived":false,"fork":false,"pushed_at":"2025-03-22T19:59:26.000Z","size":246,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-12T02:48:14.301Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mdsumner.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-22T05:38:39.000Z","updated_at":"2025-03-22T23:42:46.000Z","dependencies_parsed_at":"2025-03-22T06:37:13.815Z","dependency_job_id":null,"html_url":"https://github.com/mdsumner/rustycogs","commit_stats":null,"previous_names":["mdsumner/rustycogs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mdsumner/rustycogs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdsumner%2Frustycogs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdsumner%2Frustycogs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdsumner%2Frustycogs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdsumner%2Frustycogs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mdsumner","download_url":"https://codeload.github.com/mdsumner/rustycogs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdsumner%2Frustycogs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28536688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T10:13:46.436Z","status":"ssl_error","status_checked_at":"2026-01-18T10:13:11.045Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-18T13:04:57.025Z","updated_at":"2026-01-18T13:05:02.488Z","avatar_url":"https://github.com/mdsumner.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\neditor_options: \n  chunk_output_type: console\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# rustycogs\n\n\u003c!-- badges: start --\u003e\n\u003c!-- badges: end --\u003e\n\nThe goal of rustycogs is ... another attempt learning to wrap Rust. \n\nVery very WIP. Using grout and gdalraster for now to get the metadata so we can sanely plot the tile bytes. \n\n\nObviously need some checks on the actual block size ...\n\n```R\n## gdal_translate /vsicurl/https://projects.pawsey.org.au/idea-gebco-tif/GEBCO_2024.tif?ovr=0 -outsize 4320 2160 -co TILED=YES gebco_4320.tif\n\ndsn \u003c- \"/tiff/gebco_4320.tif\"\ndevtools::load_all()\ntiles \u003c- tile_scheme(dsn)\n\nplot(range(c(tiles$xmin, tiles$xmax)), range(c(tiles$ymin, tiles$ymax)))\n\n\nfor (i in seq_along(tiles$tile)) {\ntx \u003c- tiles[i, ]\nsize \u003c- unlist(tx[c(\"ncol\", \"nrow\")]) |\u003e  as.integer()\ntile_idx \u003c- unlist(tx[c(\"tile_col\", \"tile_row\")]) |\u003e as.integer()\nbytes \u003c- rusty(dsn, tile = tile_idx - 1)  ## 0-based internally, 1-based in grout\n\nximage::ximage(matrix(readBin(bytes, \"integer\", size = 2L, n = prod(size)), size[2L], byrow = TRUE), \n               unlist(tx[c(\"xmin\", \"xmax\", \"ymin\", \"ymax\")]), col = hcl.colors(24), add = TRUE)\n\n}\n\n```\n\n![alt text][id]\n\n[id]: Rplot.png \"Title\"\n\n\nIs it really worth it? We automatically get type-conversion via GDAL ... though I guess we have spinup overhead for every read in the Rust, which is probably the differnce\n\n```R\ndsn \u003c- \"/tiff/gebco_4320.tif\"\ndevtools::load_all()\ntiles \u003c- tile_scheme(dsn)\n\nplot(range(c(tiles$xmin, tiles$xmax)), range(c(tiles$ymin, tiles$ymax)))\n\nsystem.time({\nfor (i in seq_along(tiles$tile)) {\n  tx \u003c- tiles[i, ]\n  size \u003c- unlist(tx[c(\"ncol\", \"nrow\")]) |\u003e  as.integer()\n  tile_idx \u003c- unlist(tx[c(\"tile_col\", \"tile_row\")]) |\u003e as.integer()\n  bytes \u003c- rusty(dsn, tile = tile_idx - 1)  ## 0-based internally, 1-based in grout\n}\n})\n# user  system elapsed \n# 0.593   0.684   1.368\n\nsystem.time({\n  ds \u003c- new(gdalraster::GDALRaster, dsn)\n  for (i in seq_along(tiles$tile)) {\n    tx \u003c- tiles[i, ]\n    size \u003c- unlist(tx[c(\"ncol\", \"nrow\")]) |\u003e  as.integer()\n    tile_offset \u003c- unlist(tx[c(\"offset_x\", \"offset_y\")]) |\u003e as.integer()\n    values \u003c- ds$read(band = 1L, xoff = tile_offset[1L], yoff = tile_offset[2L], \n                      xsize = size[1L], ysize = size[2L], \n                      out_xsize = size[1L], out_ysize = size[2L])\n                      plot(values); scan(\"\", 1)\n    \n  }\n})\n\n#user  system elapsed \n#0.056   0.000   0.056 \n```\n\n\nDo it with spinup for every read, so yes we can compete with GDAL if we keep the reader open in Rust ;). Not sure I get the compulsion though, because we can parallelize the read with GDAL too and not have to rewrite everything. \n\n```R\nsystem.time({\n  for (i in seq_along(tiles$tile)) {\n    tx \u003c- tiles[i, ]\n    size \u003c- unlist(tx[c(\"ncol\", \"nrow\")]) |\u003e  as.integer()\n    tile_offset \u003c- unlist(tx[c(\"offset_x\", \"offset_y\")]) |\u003e as.integer()\n    values \u003c- vapour::vapour_read_raster(dsn, window = c(tile_offset[1L], tile_offset[2L], size))\n    \n\n  }\n})\nuser  system elapsed \n1.010   0.020   1.029\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdsumner%2Frustycogs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdsumner%2Frustycogs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdsumner%2Frustycogs/lists"}