RustGIS v0.5.0 deepens the everyday workflow. One expression language now drives queries, Calculate Field and symbols, and QGIS-style symbols and labels reach much further. New overlay and summary tools fill out Analysis, GeoPackage and PostGIS edits save back to their source, web services gain time, legends, identify and ArcGIS sign-in, and large files open a chunk at a time. Windows on ARM64 joins the native builds.
Highlights
- Expressions: one expression language, with functions,
CASEand map scale variables, for queries, Calculate Field and attribute rules. Set a symbol's size, colours, outline width and angle per feature by expression. See Expressions. - Richer symbols and labels: hatch, marker, gradient and shapeburst polygon fills, markers and hash marks along lines, font markers, and stacked, shifted and turned point marks. Labels gain halos with their own colour and width, offsets, backgrounds, letter spacing, wrapping, repeats along lines and other places to try round a point. New class methods and the full matplotlib colour map library. See Cartography.
- More analysis tools: Intersect, Identity, Union, Symmetrical Difference, Update and Split overlays, Near, Merge, Join Field, Pivot Table, Kernel Density and Feature Vertices To Points. Spatial Join joins by centre, largest overlap, closest and distance with merge rules, Summary Statistics takes several statistics and case fields, buffers and measurements use the WGS 84 ellipsoid, and Project Raster puts a raster on a chosen grid. See Analysis.
- Edit and work safely: save edits back to GeoPackage and PostGIS tables, with conflicts refused. The desktop app autosaves and offers unsaved work back after a crash, and asks before unsaved changes are lost. Projects survive a move with portable data paths and Repair Data Source, and a session log records every command run. Customize keyboard shortcuts and carry them between computers.
- Web services and time: WMS and WMTS layers follow the time slider, answer Identify, show their legends and draw in other coordinate systems. Sign in to ArcGIS Online and Enterprise with OAuth, ask feature services for an area only, and open data cubes from a new Data Cubes pane. See Web Data.
- Bigger data, faster: open large Shapefiles, GeoPackage, FlatGeobuf and GeoParquet layers in place a chunk at a time, and export them the same way. Export vector and raster layers to PMTiles. Indexed Clip and Select by Location and thinned display geometry speed up large layers, and a tilted or turned map moves more smoothly.
- Everywhere you work: native Windows on ARM64 builds, a native macOS menu bar, web app and command line images on ghcr.io, a static web app archive to host yourself,
rustgis.qt.MapWidgetfor Qt applications, saved secrets from the CLI and Python, GeoLibre projects opened as maps, and Polish as an interface language.
Download
Get the app for your platform at https://downloads.rustgis.app (or below), and see https://rustgis.app/installation/ for which file to pick.
What's Changed
- docs(roadmap): fill in the everyday workflow's missing steps by @Mavrick-F in #861
- feat(labels): the ribbon's label groups edit and choose the Labeling pane's class by @jgregoriorincon in #863
- CI: keep skipped runs from cancelling the downloads mirror sync by @giswqs in #866
- fix(edit): discard stale vertex drag gestures by @yongyin-leon in #867
- docs: archive RustGIS on Zenodo and add citation by @giswqs in #869
- feat(python): add PMTiles archive helper by @choupeanut in #870
- Layouts: pick a publication sheet's style from the New Layout menu by @elpidioassinaturas in #874
- feat(map): QGIS import reads merged categories, dashes and QGIS 1/2 names, and notes what it drops by @pick2510 in #876
- fix(ui): keep checkbox menus open while editing options by @deniial00 in #878
- feat(map): QGIS import colours rasters as QGIS does, and QGIS raster styles apply to rasters by @pick2510 in #877
- feat(analysis): Spatial Join by centre, largest overlap, closest and distance, with merge rules by @Mavrick-F in #864
- fix(ui): correct layer drop placement and list endpoints by @choupeanut in #875
- fix(data): say when a zip entry is encrypted or ZIP64, and allow 65,535 entries by @subarna-kandel in #868
- test(map): a corpus of QGIS projects and styles the importer reads by @pick2510 in #881
- feat(labels): a class header in the Labeling pane, with Remove set apart by @jgregoriorincon in #892
- fix(ui): restore whole-block layer drop halves by @deniial00 in #893
- Assistant: keep the ChatGPT sign-in's tokens in the OS keychain by @deniial00 in #884
- Web data: a catalog of data cubes, opened in one step (#683, part 1) by @elpidioassinaturas in #871
- feat(map): QGIS projects in degrees open in Equirectangular, as QGIS draws them by @pick2510 in #885
- fix(analysis): use normalized polygon coordinates for zonal statistics by @choupeanut in #899
- Analysis: trends and summaries over raster stacks on mixed grids and over multi-band GeoTIFFs dated by their band descriptions (#579) by @elpidioassinaturas in #890
- feat(project): portable data paths and Repair Data Source by @deniial00 in #886
- feat(map): markers and hash marks along lines, as QGIS's marker and hashed lines draw them by @pick2510 in #900
- i18n: add Polish (pl) interface language by @Wolren in #901
- fix(render): marks along a line on the globe follow it up to the horizon by @pick2510 in #907
- test(ui): the blocked-stdin Stop test waits for the agent's stop job by @pick2510 in #908
- Analysis: buffers, Tissot's circles and Spatial Join distances on the WGS 84 ellipsoid (#888) by @elpidioassinaturas in #905
- docs: define ribbon design and contribution guidelines by @deniial00 in #903
- Plugins: document the native Rust process template by @giswqs in #910
- fix(render): bound the pixels an SVG layout export embeds by @alteralto in #912
- feat(labels): the Labeling pane in a tab per topic, the map's settings left to the ribbon by @jgregoriorincon in #917
- ArcGIS: sign in to ArcGIS Online and Enterprise portals with OAuth by @giswqs in #915
- Symbology: the full matplotlib colour map library, as GeoLibre lists it by @giswqs in #918
- fix(analysis): keep polygon simplification monotonic at large tolerances by @choupeanut in #911
- Raster: new single-band rasters drawn with gray, Invert off by @giswqs in #920
- refactor(labels): the label field as a searchable box, as the font is by @jgregoriorincon in #919
- fix(render): slanted label letters are solid, without stripes by @pick2510 in #927
- feat(map): a character of a font as a marker, as QGIS's font markers draw one by @pick2510 in #926
- feat(ui): autosave unsaved work and offer it back after a crash by @Mavrick-F in #896
- test(analysis): check overlay, selection and join tools against GEOS by @Mavrick-F in #916
- Python: rustgis.qt.MapWidget, the app in a Qt application by @giswqs in #922
- fix(map): zoom in to site plans and finds drawings, past 1:1 by @Mavrick-F in #923
- Services: ask a WFS, OGC API or ArcGIS feature layer for an area only (#819) by @elpidioassinaturas in #924
- fix(analysis): calculate geometry attributes on the WGS 84 ellipsoid by @choupeanut in #928
- feat(map): a point's marks stacked, shifted and turned, and markers turned by a field by @pick2510 in #933
- fix(engine): reject indirect task re-entry by @yongyin-leon in #941
- feat(edit): move coincident polygon vertices together by @yongyin-leon in #929
- Data: read Monte Mario (Rome) from .prj and WKT2, and add Italian CRS test cases (#898) by @GISspecialistAlejandraDuque in #931
- Reorganize Home ribbon with Locate dropdown and direct data access by @deniial00 in #932
- Honour the legacy GeoJSON crs member on import by @deniial00 in #936
- feat(layout): bring a layout element to the front or send it to the back by @huzaifffa in #925
- chore(ci): use Haiku 5.5 for Claude reviews by @giswqs in #950
- fix(geom): preserve invalid haversine distances by @choupeanut in #946
- Services: follow-ups to #924 (a plainer note, /items in any case, the timeout hint only without bbox) by @elpidioassinaturas in #944
- feat(ui): a fixed Labeling tab for every label control on the ribbon by @jgregoriorincon in #935
- fix(geom): show nonfinite measurements as unavailable by @choupeanut in #960
- feat(ui): choose which layers to add from a file holding several (#934) by @pick2510 in #952
- fix(ui): reserve popup header space for controls by @deniial00 in #955
- Layouts: any installed font family for a text element, with sans or serif as its fallback (#762) by @elpidioassinaturas in #949
- Analysis: project a raster onto a chosen grid (raster.project, #821 part 1) by @elpidioassinaturas in #953
- feat(services): identify WMS layers with GetFeatureInfo by @pick2510 in #943
- fix(data): reject impossible FlatGeobuf index sizes by @choupeanut in #965
- docs(comparison): present RustGIS and GeoLibre as complements (#951) by @Mavrick-F in #963
- feat(map): Arithmetic Progression and Head/Tail Breaks class methods, Method lists in alphabetical order by @gsueur in #961
- fix(services): ask a WMS layer again in the next answer format after the service's error by @pick2510 in #969
- Perf: read WKB coordinate runs in bulk, write WKT into one buffer by @Wolren in #968
- feat(raster): label legend classes with the category names of the .aux.xml by @GISspecialistAlejandraDuque in #971
- refactor(labels): one note under the label class SQL, the first thing that decides by @jgregoriorincon in #967
- feat(ui): ask to save unsaved changes before quitting or replacing the project by @Mavrick-F in #945
- feat(web): a Dockerfile to self-host the web app by @flight1973 in #974
- feat(labels): a halo's own colour and width, and letter spacing, as QGIS's buffer and spacing by @pick2510 in #964
- chore(deps): bump anthropics/claude-code-action from 1.0.257 to 1.0.261 in the actions-minor-patch group by @dependabot[bot] in #977
- chore(deps): bump ureq from 3.4.2 to 3.5.0 in the cargo-minor-patch group by @dependabot[bot] in #978
- chore(deps): bump pollster from 0.4.0 to 1.0.1 by @dependabot[bot] in #983
- chore(deps): bump miniz_oxide from 0.8.9 to 0.9.1 by @dependabot[bot] in #979
- chore(deps): bump weezl from 0.1.12 to 0.2.1 by @dependabot[bot] in #981
- chore(deps): bump calamine from 0.36.1 to 0.37.0 by @dependabot[bot] in #985
- ci(docker): publish the web app and command line images to ghcr.io by @giswqs in #986
- ci(docker): publish only from main and releases; latest follows main by @giswqs in #988
- chore(deps): bump epaint_default_fonts from 0.36.2 to 0.37.0 by @dependabot[bot] in #992
- fix(data): preserve ASCII grid pixel dimensions by @choupeanut in #989
- chore(deps): bump zip from 2.4.2 to 9.0.5 by @dependabot[bot] in #990
- chore(deps): bump pyo3 from 0.29.3 to 0.30.1 by @dependabot[bot] in #991
- fix(labels): the class rule note only with more than one visible class by @jgregoriorincon in #994
- Tweak/add from service dialog QoL by @mgaux-dev in #975
- feat(analysis): add an Intersect overlay tool by @Mavrick-F in #980
- ci: add a claude-autofix label workflow by @giswqs in #996
- fix(ci): resolve autofix threads with the maintainer token by @giswqs in #997
- fix(ci): resolve threads autofix finds already addressed by @giswqs in #999
- fix(analysis): break mode ties as GDAL does in Project Raster by @GISspecialistAlejandraDuque in #972
- fix(ci): harden the claude-autofix workflow by @giswqs in #1002
- feat(labels): a label's offset and background, as QGIS's offset from a point and its rectangle background by @pick2510 in #1007
- feat(services): WMS and WMTS legends in the Layers pane, as ArcGIS Pro's Contents shows them by @pick2510 in #1009
- fix(ui): a tile legend's screen-reader label is translatable as one message by @pick2510 in #1010
- feat(layouts): measured grids, eastings and northings in a projected system, beside the graticule by @pick2510 in #1012
- feat(analysis): add Identity and Union overlay tools by @Mavrick-F in #982
- fix(ci): unbreak the autofix thread staging script by @giswqs in #1015
- test(render): accept a blended text edge in the turned label background check by @giswqs in #1016
- fix(ci): stop autofix's git add failing on the ignored .autofix by @giswqs in #1018
- fix(ci): unstage .autofix with git reset, not git rm --cached by @giswqs in #1020
- feat(labels): wrapping and repeat along lines, as QGIS's wrap and repeat distance by @pick2510 in #1014
- docs(citation): add Dominik Strebel's ORCID by @pick2510 in #1024
- feat(ui): a right-click menu on every text field (undo, cut, copy, paste, delete, select all) by @pick2510 in #1023
- docs(citation): Dominik Strebel in the citations by @pick2510 in #1026
- docs: encourage screenshot evidence for substantial UI changes by @deniial00 in #1028
- feat(web): Paste in a text field's right-click menu reads the clipboard in the browser by @pick2510 in #1029
- feat(postgis): a PostGIS tab to connect, edit and save tables, refusing conflicts by @andriyanto in #671
- feat(layers): new layers go on top, web tile layers take a place among the map's layers (#808) by @pick2510 in #1031
- fix(web): filter QGIS project picker for qgs and qgz by @deniial00 in #1030
- fix(plugins): show one full-description tooltip in Browse by @deniial00 in #1035
- fix(macos): keep the bundle's icon in the Dock by @janroller96 in #1036
- feat(symbology): stacked polygon fills — hatch lines and markers, from QGIS fill symbols (#882 piece 5a) by @pick2510 in #1022
- fix(layers): tile layers stay over a layer or group that a move leaves where it was by @pick2510 in #1034
- feat(analysis): add a Near tool by @Mavrick-F in #984
- feat(tiles): export vector layers to PMTiles by @deniial00 in #1006
- fix(project): a saved selection holds each row once, in order by @flight1973 in #1032
- feat(identify): tile layers can be selected in Layers and identified with Selected in Layers by @pick2510 in #1040
- feat(assistant): read standalone tables with read_features by @Mavrick-F in #1038
- docs(analysis): drop the built-in tool count by @flight1973 in #1044
- feat(analysis): Feature Vertices To Points, a point at each vertex by @flight1973 in #1003
- feat(project): import GeoLibre projects as maps by @Mavrick-F in #1005
- Data: open Shapefiles too large to load whole in place by @giswqs in #1058
- fix(map): keep the frame while a layer over tiles is restyled by @giswqs in #1059
- fix(models): a model from a file has each step checked with its tool (#1043) by @pick2510 in #1072
- feat(data): read GeoTIFFs made on request in place from addresses without a file name by @siiinc in #1052
- Open the STAC dialog on sentinel-2-c1-l2a by @elpidioassinaturas in #1069
- fix(macos): keep the bundle's icon in the Dock, not egui's by @pick2510 in #1074
- fix(data): keep every database schema and table reachable by @deniial00 in #1073
- perf(render): mitre the outlines of small filled polygons (#1064) by @pick2510 in #1078
- Web data: a Data Cubes pane, and the catalog of data cubes kept up to date with the app's assets (#683, part 2) by @elpidioassinaturas in #1060
- Add keyboard shortcut customization by @choupeanut in #1004
- feat(analysis): several statistics and case fields in Summary Statistics by @Mavrick-F in #1070
- fix(data): read the .dbf language drivers dbase doesn't know (#1079) by @pick2510 in #1082
- chore: late review fixes for small-polygon outlines and .dbf language drivers by @pick2510 in #1087
- feat(data): save GeoPackage edits back to their source table by @deniial00 in #1045
- Use saved secrets from the CLI and Python by @deniial00 in #1037
- feat(analysis): add a Pivot Table tool by @Mavrick-F in #1084
- UI: open the Notebook beside the map on half the window by @giswqs in #1089
- Docs: say the Notebook pane opens at least 320 points wide by @giswqs in #1090
- fix(ui): a WMS layer's answer takes its place in the pop-up by drawing order by @pick2510 in #1086
- fix(data): write a .prj for Swiss, Krovak and named-meridian systems (#1095) by @pick2510 in #1096
- fix(ui): the identify pop-up waits for the WMS answers to show all it found together by @pick2510 in #1098
- Add native Merge tool for vector layers by @choupeanut in #1076
- feat: WMS layers with a time dimension, and WMS and WMTS time layers on the time slider by @pick2510 in #1100
- test(data): cover documented DBF language-driver markers by @choupeanut in #1091
- feat(tiles): source layers of a vector archive in the Layers pane, each with its visibility by @deniial00 in #1101
- feat(layers): nested layer groups and outline commands to indent and outdent (#836) by @deniial00 in #1102
- feat: layers with a time dimension follow the time slider by default by @pick2510 in #1106
- docs: a period longer than the time slider's steps is stepped every second, fourth… step by @pick2510 in #1110
- feat(symbology): gradient and shapeburst polygon fills, from QGIS fill symbols (#882 piece 5b) by @pick2510 in #1104
- fix(render): a thin shapeburst's tiles stop at the frame's budget by @pick2510 in #1114
- fix(data): refuse a source over the read limit instead of reading a sample as the whole of it by @deniial00 in #1116
- fix(ui): live tiles move with a GPU scene shown as a picture by @pick2510 in #1124
- feat(plugins): a tree widget for plugin panels by @jgregoriorincon in #1080
- fix(data): a layer that lists one time is a plain map, not a map by date by @pick2510 in #1125
- feat: export raster layers to PMTiles by @choupeanut in #1123
- perf(analysis): reuse terrain raster constants by @choupeanut in #1122
- feat(analysis): add Symmetrical Difference, Update and Split overlay tools by @Mavrick-F in #1103
- perf(render): draw tiny filled polygons by coverage by @choupeanut in #1118
- fix(analysis): aspect and hillshade face the right way on bottom-up grids by @Bortlesboat in #1085
- fix(engine): inspect format before parsing to handle newer versions (#1088) by @sutharprin098 in #1092
- perf(analysis): index the polygons in countPoints by @Mavrick-F in #1119
- fix(python): run the Qt tests without WebEngine's GPU (#1113) by @deniial00 in #1117
- feat(labels): point labels try other positions round the point when theirs is taken. Part 1a by @jgregoriorincon in #1025
- fix(raster): draw lon/lat grids stored past 180° (0 to 360°) all the way round (#1109) by @deniial00 in #1112
- feat(plugins): compact ribbon columns and nested menus by @deniial00 in #1115
- feat(macos): a native menu bar beside the ribbon by @pick2510 in #1126
- perf(render): thin display geometry before projecting by @Mavrick-F in #1120
- fix(services): WMS and WMTS layers are drawn down to the detail their service gives by @pick2510 in #1129
- fix(macos): menu bar work only when the language or keymap changes by @pick2510 in #1133
- perf(map): a tilted map moves without stopping to draw its drape by @pick2510 in #1132
- feat(analysis): add native Kernel Density analysis tool by @quanguet0409 in #1063
- feat(analysis): implement native Join Field non-spatial attribute join by @quanguet0409 in #1075
- feat(services): WMS and WMTS layers in other coordinate systems, drawn in the map's own when offered in it by @pick2510 in #1127
- perf(analysis): process terrain gradients by row by @choupeanut in #1130
- test(data): exercise corrupted GeoPackage headers by @choupeanut in #1138
- fix(services): WMS and WMTS axis order as EPSG defines it by @pick2510 in #1149
- fix(ui): AddService scrollbar consistency, resizing, multiline layer names by @mgaux-dev in #1147
- fix(services): judge a WFS answer's axes from its positions and the type's bounds, not its crs name (#1053) by @elpidioassinaturas in #1071
- feat(earthdata): remember the Earthdata Login token on this computer by @deniial00 in #1153
- fix(symbology): expose polygon fill controls on mixed geometry layers by @robmarkcole in #1139
- fix(services): a regional geographic WMTS corner is read by its layer by @pick2510 in #1158
- fix(map): a tilted map's frame isn't left waiting after its worker panics by @pick2510 in #1160
- feat(sources): swisstopo's WMS in the Library, whose layers answer Identify by @pick2510 in #1167
- feat(data): an expression language for queries and Calculate Field (#882 pieces 6+7, part 1) by @pick2510 in #1164
- fix(layout): a legend lists WMS and WMTS layers with their service's legend picture by @pick2510 in #1168
- fix(ui): Calculate Field's hint lists the operators the expression language reads by @pick2510 in #1172
- fix(services): WMS and map service layers drawn as one picture of the view, or tiles of 256-1024 px (#1162) by @pick2510 in #1169
- fix(layout): the browser's layout page is drawn again once its legend pictures land, not on every fetch by @pick2510 in #1177
- fix(services): an address by its box with no size to write isn't drawn on request by @pick2510 in #1179
- fix(ui): a Web Data catalog's list fills its pane by @deniial00 in #1176
- feat(services): a WMS or map service added by its address is one picture of the view too by @pick2510 in #1180
- fix(services): one picture of the view in any projection with an EPSG code, and for WMS offering Web Mercator among others by @pick2510 in #1183
- feat(symbology): symbol size, colours, outline width and angle by expression (#882 pieces 6+7, part 2) by @pick2510 in #1185
- fix(render): a complete render draws again once its own fetches have come, not every fetch in the process by @pick2510 in #1188
- perf(map): a flat map turns without being drawn again each step by @pick2510 in #1184
- fix(table): a value typed into a cell is kept on Enter or a click away, Escape cancels by @pick2510 in #1189
- docs: add a security policy, code-origin rules and a Never silent rule by @Mavrick-F in #1140
- fix(web): load the GeoLibre tools from geolibre-wasm 1.8.0 by @Mavrick-F in #1212
- test(engine): run hostile_params_never_panic in eight shards side by side by @jgregoriorincon in #1203
- docs(contributing): faster local builds and test runs by @jgregoriorincon in #1206
- chore(deps): bump anthropics/claude-code-action from 1.0.261 to 1.0.264 in the actions-minor-patch group by @dependabot[bot] in #1196
- fix(labels): name locked labels by feature id, so a lock holds through edits that move rows by @jgregoriorincon in #1134
- fix(ui): keep font and field lists open to search them by @huzaifffa in #1173
- build(notices): ship the licences of code and data taken from other projects by @Mavrick-F in #1208
- feat(ui): edit tool fields and statistics as ordered lists by @Mavrick-F in #1136
- fix(plugins): a plugin's layer.addUrl downloads off the frame on the desktop by @jgregoriorincon in #1170
- fix(ui): a drag or a colour pick in the Style tab, the Symbology pane and the Format panes is one undo step (#1194) by @jgregoriorincon in #1200
- Session log: every command run in a session, with its time, parameters and outcome (#797, part 1) by @elpidioassinaturas in #947
- feat(data): read GeoPackage, FlatGeobuf and GeoParquet a chunk at a time by @Mavrick-F in #1131
- test(analysis): reference cases for Buffer and Calculate Geometry by @Mavrick-F in #1161
- test(fuzz): fuzz the file readers nightly by @Mavrick-F in #1171
- feat(labels): try other places round a point from the Labeling pane and labels.placement. Part 1b by @jgregoriorincon in #1141
- fix(ui): test the font list search box, not the input after it by @giswqs in #1218
- chore(deps): bump rusqlite from 0.40.2 to 0.41.0 by @dependabot[bot] in #1198
- perf(render): reuse streamed-layer thinning decisions by @Mavrick-F in #1121
- Notebook: keep Jupyter notebooks intact and show their outputs by @giswqs in #1097
- test(engine): run everyday jobs end to end, and on Census data nightly by @Mavrick-F in #1165
- test(tiles): replace the copied Liberty style with an original one by @Mavrick-F in #1211
- fix(analysis): keep buffer outlines at their distance between vertices by @Mavrick-F in #1207
- perf(analysis): index Clip and Select by Location candidates by @Mavrick-F in #1148
- test(analysis): drop the known marks #1207 made stale by @giswqs in #1220
- i18n: translate 477 new interface strings in every language by @giswqs in #1219
- chore(deps): bump the cargo-minor-patch group with 4 updates by @dependabot[bot] in #1197
- fix(services): a turned WFS answer drops its boxes; a list of features is left as it came (#1071 follow-ups) by @elpidioassinaturas in #1193
- build(release): ship a static web app archive by @giswqs in #1224
- perf(data): export a streamed layer a chunk at a time by @Mavrick-F in #1146
- feat(ui): import and export keyboard shortcuts by @Mavrick-F in #1094
- build(release): native Windows on ARM64 builds: app, CLI, installers and Python wheel by @pick2510 in #1192
- i18n: translate the keyboard shortcut import and export strings by @giswqs in #1228
- Release v0.5.0: version, roadmap and highlights by @giswqs in #1229
New Contributors
- @Wolren made their first contribution in #901
- @GISspecialistAlejandraDuque made their first contribution in #931
- @flight1973 made their first contribution in #974
- @mgaux-dev made their first contribution in #975
- @andriyanto made their first contribution in #671
- @janroller96 made their first contribution in #1036
- @siiinc made their first contribution in #1052
- @Bortlesboat made their first contribution in #1085
- @sutharprin098 made their first contribution in #1092
- @robmarkcole made their first contribution in #1139
Full Changelog: v0.4.0...v0.5.0