Version 4.9.2 | QGIS Plugin | Production-Ready 🎉
🚀 Explore, filter & export vector data with lightning-fast performance on ANY data source.
QGIS 3 / Qt5 and QGIS 4 / Qt6: v4.9.2 fixes the GeoPackage layer that came back empty when it was re-filtered as a source after being filtered as a target (a parenthesis lost while combining with the R-tree subset), and makes a new source filter replace the previous one when the combine option is off. v4.9.1 fixed two regressions of the new project switch with the panel open: a Python error when the previous layer is gone, and a QGIS crash after a plugin reload followed by a project close (the panel is now removed and deleted on unload). v4.9.0 brought the project switch itself, one FilterMate project row per project, a PostgreSQL feature list without server-side sort nor freeze, type-to-find in the layer combo, plain-language error messages and accessible names.
📖 New to FilterMate? Follow the step-by-step tutorial: User Guide (English) · Guide utilisateur (français)
| Feature | Description |
|---|---|
| 🔍 Smart Search | Intuitive entity search across all layer types |
| 📐 Geometric Filtering | Spatial predicates with buffer support |
| ⭐ Filter Favorites | Save and reuse filter configurations |
| 🤝 Favorites Sharing | Publish favorites to git repos with QGIS authcfg credentials |
| 🌐 REST API | Drive FilterMate from external tools (X-API-Key auth) |
| 📝 Undo/Redo | Complete filter history |
| 🌍 34 Languages | Full internationalization |
| 🎨 Dark Mode | Automatic theme detection |
| 📦 GPKG Project Export | Embedded QGIS project with group hierarchy, styles & CRS |
| 🚀 Multi-Backend | PostgreSQL, Spatialite, OGR |
| 🧰 Processing Toolbox | Batch-filter multiple layers with one expression, from the Processing panel or a model |
- GeoPackage layer empty after a second filter: a layer filtered as a target (R-tree prefilter) and then used as the source with an attribute expression showed 0 features. The subset combiners dropped one closing parenthesis and the SQL was invalid without any error, since OGR accepts the subset string. Verified on the BD TOPO 31 GeoPackage.
- Combine option off means replace: the new source filter replaces the previous subset instead of being ANDed to it, as the target layers already did.
See the 4.9.2 changelog for details.
- PostgreSQL, selections of 100 000 features or more: the filter was refused on the first click and accepted on the second (the materialized-view path called a facade method that does not exist).
- Project switch with the panel open: no more
RuntimeError: wrapped C/C++ object of type QgsVectorLayer has been deletedwhen the previous layer is gone (exploring and filtering controllers). - Plugin reload then project close: the panel is removed and deleted on unload, so a feature-picker gather can no longer outlive its layer (QGIS access violation in
QgsFeaturePickerModelBase::endUpdate). ⏱ layer_change_validate/⏱ layer_change_resettiming lines infiltermate.log.
See the 4.9.1 changelog for details.
- Project switch with the panel open: the panel follows the new project (a dead weak reference on the deferred
add_layers, a never-drained orchestrator queue,clear()on the layer combo and baredisconnect()calls on QGIS signals were each hiding the next). - FilterMate database: one project row per project (the save no longer renames or empties the row with the next / closed project's name) and duplicate favorites removed.
- PostgreSQL feature list: no server-side ORDER BY (QGIS fetched and sorted the whole table before the limit: 13 s → 30 ms on 370 000 rows) and population deferred while the canvas renders (no 17 s freeze at project open); one population per layer change.
- Panel: type to find a layer in the current-layer combo, busy cursor and pressed button during a task, plain-language error messages, accessible names and tooltips on icon buttons, HiDPI sizes.
- Under the hood: entry-module and app logging reaches
filtermate.log, stored geometry column verified once, zip without translation sources and internal docs (5.8 → 5.0 MB), flake8 in CI, AST guards (Qt6 enums,clear()on map layer combos, baredisconnect()on QGIS signals).
See the 4.9.0 changelog for details.
- PostgreSQL buffer filters:
ST_Intersects(target, ST_Buffer(source, d))is replaced byST_DWithin(target, source, d)for intersects with a positive round buffer, and every EXISTS is preceded by a bbox test of the target against the envelope of the selected source rows, served by the target's GiST index. A roads + 20 m buffer cascade that never finished now takes 25 s for 16 layers (zone_de_vegetation 322 s to 3 s). The source-selection materialized view is created with the right index columns and committed, and the corrupted-subset cleaner accepts the new expressions. - Project switch: with
APP.AUTO_ACTIVATEoff (the default) the open panel never reloaded onprojectRead; it now reloads the new project's layers, source layer and favorites. - GeoPackage / Spatialite buffers: the static buffer is applied once in QGIS and simplified with a tolerance bounded by the buffer; no more convex hull fallback (a 20 m buffer around 7 000 road segments returned everything inside the hull). The source read in SUBSET mode is retried when the attribute-less request comes back empty.
- OGR: the buffered source is computed once per task instead of once per target layer, and the primary keys of the selected features are fetched in one request.
- Repair: 48 SQL templates in 16 modules had lost their
fprefix since the 2026-02-10 clean-up (PostgreSQL materialized view, subset history, Spatialite temp tables, progressive strategies); restored, with a test that fails the build if it happens again. - Exploring: identical feature-list populations deduplicated, single-selection picker bounded to
feature_picker_limit,⏱ picker_populateand⏱ layer_change_*timing lines; the per-layer expression trace is DEBUG.
See the 4.8.10 changelog for details.
- GeoPackage cascades use the spatial index: the Spatialite expression starts with the R-tree candidate clause GDAL uses for its own spatial filter. Filtering 37 BD TOPO layers by the commune of Toulouse took 371 s; it now takes 1.6 to 3 s. No second full scan after a filter (
reload()removed on PostgreSQL/OGR). - PostgreSQL with the centroid option keeps its GiST index:
"t"."geom" && sourceis tested beforeST_Intersects(ST_PointOnSurface("t"."geom"), source). A five-commune cascade went from 49.6 s to under 4 s, and the worker no longer counts each target twice. - Connection and rendering: psycopg2 tries an IPv4
hostaddrwithgssencmode=disablefirst (a 21 s stall onlocalhostresolving to IPv6 first), the canvas is frozen for the whole task and redrawn once, no auto-zoom after unfilter/reset, no fixed pauses between layers of the same GeoPackage. - Fix: a filter launched with no target layer no longer fails.
- More
⏱timing lines infiltermate.log(pg_layer_connect,apply_subsets,apply_subset_layer,layer_filter,cascade_filter,set_subset).
See the 4.8.9 changelog for details.
- No more freezes on large layers: the multiple-selection list loads at most
feature_picker_limitrows (default 1000, sorted). When truncated, the text filter searches the whole layer, "Select All" loads the full list and canvas selections beyond the loaded rows are fetched by identifier. A click on a row is one indexed lookup instead of a full-layer scan. - Faster project load: layer variables are applied per layer in one batched write instead of 42 gated writes per layer; unchanged values are skipped; display-field detection is memoised.
- Filter engine: GEOS cascaded union replaces the quadratic
combine()loop, Spatialite source features load without attributes, interruptible SQLite queries wake up as soon as the worker finishes. - Hygiene: stale unsaved projects are purged from the FilterMate database, INFO log level by default (
FILTERMATE_LOG_LEVEL=DEBUGfor verbose output), and three timing lines (⏱ project_open,⏱ layer_change,⏱ task_filter) infiltermate.logto compare releases.
See the 4.8.8 changelog for details.
- Consistent panels: Exploring and Filtering share input dimensions, button-bar styles and checkboxes across dark, light and gray themes. Gutters match the panel background, with more space below Exploring titles.
- Readable configuration: white labels and values on dark backgrounds, including custom configuration cells.
- Theme-change fix: remove the obsolete
IconManager.set_theme()call that raised an error on QGIS palette changes. - Project shutdown: cancel pending layer additions and avoid repeated per-layer cleanup when removing all layers or unloading the plugin.
See the 4.8.7 changelog for details.
- QGIS themes: follow native colors in Default, Night Mapping and Blend of Gray. Existing
defaultsettings now follow QGIS; chooselightordarkto force an appearance. - Readable icons: invert PNG artwork in dark mode and refresh icons after startup and subsequent changes, including tabs and centroid controls.
- Filtering alignment: match the upper and lower icon-rail widths and expand the second layer row like the first. All buttons and their dimensions are preserved.
- Compatibility: retain the Qt5/Qt6 checkbox and mouse-event fixes. The 37 targeted theme/configuration tests pass under both bindings; see validation details.
- Checkbox rendering: correct the QStyle primitive name used by the custom delegate.
- Feature-list clicks: support both Qt5
pos()and Qt6position(). - Tests: 1499 passed, 1 skipped (Python 3.12).
- Config log cleanup: the "Schema file not found" message logged on every config reload (the schema was intentionally removed as unused in an earlier release) is now
Infoinstead ofWarning. Also closed out 2 live-testing reports as confirmed non-bugs: theQGIS3-named settings path is QGIS 4.2's own behavior, and a 33%-stuck "Adding layers" dialog turned out to be QGIS's own project loader, not FilterMate. - Tests: 1493 ✅.
- 🚑 Second QGIS 4.x hotfix: v4.8.1's dockwidget fix still crashed (
DockWidgetFeature has no attribute 'AllDockWidgetFeatures') — that convenience constant was deprecated in Qt 5.13 and is fully removed in Qt6, not just moved into a nested enum. Now ORs the 3 individual flags it used to stand for. - Tests: 1493 ✅.
- 🚑 Critical QGIS 4.x fix: the dockwidget could fail to load entirely on QGIS 4.x — PyQt6's UI loader can't resolve the
.uifile's dock-widgetfeaturesflag, so plugin startup crashed outright. Now set programmatically instead. Also fixed the new Processing Toolbox algorithm crashing on open (BatchFilterAlgorithm.tr()was missing —QgsProcessingAlgorithmnever provides it). Found via real-world QGIS 4.2/Windows testing right after v4.8.0. - Tests: 1493 ✅.
- 🎉 Full QGIS 4.2 / Qt6 support: closed out every remaining PyQt5→PyQt6 gap found by three sweeps across the codebase —
QgsField.type()field-detection migrated toQMetaType.Type,QShortcutmoved back toQtGui(Qt6 relocated it there along withQAction/QActionGroup/QFileSystemModel/QUndoCommand/QUndoGroup/QUndoStack, which was breaking dockwidget keyboard shortcuts and the JSON config search widget at load time), and the last flat PyQt5-style enum accesses qualified to their scoped form. Two new AST-based static regression guards keep these bug classes from resurfacing. - New — Processing Toolbox: FilterMate algorithms are now registered via a
QgsProcessingProvider. First algorithm, "Filtrer plusieurs couches (batch)", applies one filter expression to multiple vector layers in a single run — usable from Processing models and batch processing. - Tests: 1486 ✅ (7 pre-existing, unrelated export-pipeline failures tracked separately).
- QGIS →
Plugins→Manage and Install Plugins - Search "FilterMate" →
Install Plugin
Download from GitHub Releases and extract to:
| OS | Path |
|---|---|
| Windows | %APPDATA%\QGIS\QGIS3\profiles\default\python\plugins\ |
| Linux | ~/.local/share/QGIS/QGIS3/profiles/default/python/plugins/ |
| macOS | ~/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins/ |
pip install psycopg2-binary| Tutorial | Link |
|---|---|
| 📺 Complete Overview | Watch |
| 🔍 Dataset Exploration | Watch |
| 🛣️ Road Network Filtering | Watch |
| 📦 GeoPackage Export | Watch |
| 📐 Negative Buffer | Watch |
| Backend | 10k | 100k | 1M Features |
|---|---|---|---|
| 🟢 PostgreSQL | <1s | <2s | ~10s |
| 🔵 Spatialite | <2s | ~10s | ~60s |
| 🟠 OGR | ~5s | ~30s | >120s |
Tip: Install psycopg2-binary for optimal performance with large datasets.
- QGIS: 3.22+ — including QGIS 4.x / Qt6 (fully supported since v4.8.0)
- Python: 3.9+ (included with QGIS)
- Optional: psycopg2 for PostgreSQL backend
- Users: Documentation Website
- Use cases: Use cases (English) · Cas d'usage (français) — eight business questions answered step by step on a full BD TOPO department (1.17 M buildings): commune dossier, road noise, flood setback, bridges, brush clearing, emergency access, favorites, Processing
- Tutorial: User Guide (English) · Guide utilisateur (français) — installation, first filter, exploring, predicates and buffers, favorites, export, backends, configuration
- Developers: docs/ARCHITECTURE.md
- Changelog: CHANGELOG.md
GNU General Public License v3.0 - See LICENSE
Developed by: imagodata | Contact: simon.ducournau+filter_mate@gmail.com