Skip to content

Instantly share code, notes, and snippets.

View sfkeller's full-sized avatar

Stefan sfkeller

View GitHub Profile
@sfkeller
sfkeller / QGIS_Dynamic_Filtering_Script.py
Created May 14, 2025 15:39
This QGS Python API script enables features in a vector layer to be filtered dynamically according to the layer's current visible extent on the map canvas.
"""
QGIS Dynamic Filtering Script
Usage:
0. Ensure your vector dataset contains a ranking field, then load it into QGIS.
1. Adapt 'LAYER_NAME' and 'SQL_FILTER_TEMPLATE' in the 'Constants' section below.
2. Open the Python console in QGIS, then open and execute this script.
3. To disable filtering, copy and paste the following into the Python console:
disable_dynamic_filter()
@sfkeller
sfkeller / Pop_For_CH_1950-2018.csv
Created February 4, 2025 21:06
From “Bevölkerungsdaten im Zeitvergleich, 1950-2018” vom Bundesamt für Statistik (BfS)
year population foreigners
1950 4717000 285000
1960 5360000 514000
1970 6193000 1001900
1980 6335000 913500
1990 6751000 1127100
1995 7062000 1363600
1996 7081000 1369000
1997 7096000 1375200
1998 7123537 1383645
@sfkeller
sfkeller / gist:baf6556a59a75036ec6f3a96465aa2db
Created November 26, 2024 22:27
Tree example with PostgreSQL ltree
create extension if not exists ltree;
create table tree( id serial primary key, letter char, path ltree );
insert into tree (letter, path) values ('A', 'A'), ('B', 'A.B'), ('C', 'A.C'), ('D', 'A.C.D'), ('E', 'A.C.E'), ('F', 'A.C.F'), ('G', 'A.B.G');
with recursive tree_hierarchy as (
select
id, letter, path, 1 as level, letter::text as full_path
from tree
where nlevel(path) = 1 -- start from the root node(s)
union all -- union
1 Roter Apfel aus biologischem Anbau Obst
2 Gelbe Banane Obst
3 Grüner Salat Gemüse
4 Bio-Apfelessig Würzmittel
5 Orangensaft frisch gepresst Getränke
@sfkeller
sfkeller / Overpass_QL_EBNF_v0.2_ChatGPT_generated.txt
Created September 15, 2024 19:14
Overpass QL EBNF Grammar, Version 0.2, by Stefan Keller and with the help of ChatGPT.
(* Overpass QL EBNF Grammar *)
(* Query *)
query ::= ( global_option )* ( statement )+ ( output_statement )*
(* Global Options *)
global_option ::= '[' option ( ';' option )* ']'
option ::= 'out:' format
| 'timeout:' number
| 'maxsize:' number
We can make this file beautiful and searchable if this error is corrected: It looks like row 10 should actually have 14 columns, instead of 8 in line 9.
CustID,Lastname,Firstname,Date_Birth,Nat,Gender,Kanton,Street,ZipCd,Place,Domicile_Country,Phone,Latitude,Longitude
101,Hauser,Pascal,20.05.1973,CH,M,ZH,Röschibachstr. 77,8037,Zürich,CH,044 530 81 97,47.383364,8.529977
102,Ragginger,Jean-Pierre,29.09.1983,CH,M,ZH,Saatlenzelg 24,8050,Zürich,CH,044 290 10 52,47.358601,8.531804
103,Faist,Jenny,08.10.1969,CH,F,ZH,Köschenrütistr. 69,8052,Zürich,CH,044 882 63 32,47.378758,8.527037
104,Silberer,Lucas,24.06.1977,CH,M,AG,Oberbodenstr. 10,5415,Nussbaumen AG ,CH,056 126 14 33,47.34379,8.278959
105,Fillinger,Claude,21.07.1975,CH,M,ZH,Rieterstr. 93,8002,Zürich,CH,044 623 40 22,47.371534,8.521665
106,Baillie,Marianne,11.08.1980,F,F,TG,Zielweg 5,8580,Amriswil,CH,071 125 36 56,46.248447,6.120923
107,Isler,Ruth,21.11.1979,CH,F,ZH,Weihermattstrasse 48,8902,Urdorf,CH,044 141 97 32,47.585746,7.580571
108,Vlassidis,Stamatis,22.12.1970,GR,M,ZH,Brunnacherstr. 34,8174,Stadel b. Niederglatt,CH,044 790 05 07,47.386621,8.056205
109,Ambühler,Urs,29.07.1977,CH,M,ZH,Gerechtigkeitsgasse
@sfkeller
sfkeller / OST_DataAna_Ueb_Wo04_GEE.js
Created March 17, 2022 23:46
Temperature Variance Analysis with GEE: Mit ASTER-Daten (100m 2008) sowie Licht-Emissionen als Maske, um grosslandschaftlich bedingte Temperatur-Schwankungen (z.B. kalter Alpenkamm) auszublenden.
var temperatureDataset = ee.Image('NASA/ASTER_GED/AG100_003'); // https://developers.google.com/earth-engine/datasets/catalog/NASA_ASTER_GED_AG100_003
var nightLightsDataset = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG') // https://developers.google.com/earth-engine/datasets/catalog/NOAA_VIIRS_DNB_MONTHLY_V1_VCMSLCFG?hl=en
.filterDate('2021-01-01')
.first();
var temperature = temperatureDataset.select('temperature').divide(100); // dataset is in 1/100 kelvin
var temperatureAverage = temperature.reduceNeighborhood(
ee.Reducer.mean(), // calculate the mean
ee.Kernel.square(2000, 'meters'), // of a square with 'radius' of 2000 m (which is 4000 * 4000 m)
@sfkeller
sfkeller / Netzwerkwelt_FOSSGIS_2021_POI-Beispiel.md
Last active May 23, 2021 15:56
POI-Beispiel für die Netzwerkwelt der FOSSGIS 2021
--
-- FUNCTION hstore_match_key_prefix(...)
--
--drop function hstore_match_key_prefix(hstore, text, text);
create or replace function hstore_match_key_prefix(tags hstore, key_prefix text, value_value text default 'yes')
returns text[]
as $$
select array_agg(substring(key, key_prefix||':#"%#"', '#'))
from (select (each(tags)).key as key, (each(tags)).value as value) as "alias"
where key like key_prefix||':%' and value = value_value
@sfkeller
sfkeller / ballparks2.sql
Last active April 4, 2021 20:31
Ballparks by James Fee
/*
---------------------------------
ballparks2.geojson from James Fee
---------------------------------
Note that there's attribute "Teams", which has a value of a JSON array of JSON objects.
QGIS 3 interprets this as string.
Turning this string into an array still is an array of JSON Objects.
So, this has to be treated first as a JSON object.