Analysis of OpenStreetMap contributions from organised teams (including corporations).
# Organised teams statistics per month
df = duckdb.sql("""
WITH monthly_total AS (
SELECT
year,
month,
CONCAT(year, '-', LPAD(CAST(month as VARCHAR), 2, '0')) as months,
COUNT(DISTINCT user_name) as total_contributors,
CAST(SUM(edit_count) as BIGINT) as total_edits
FROM '../changeset_data/year=*/month=*/*.parquet'
GROUP BY year, month
),
monthly_organised_team AS (
SELECT
year,
month,
CONCAT(year, '-', LPAD(CAST(month as VARCHAR), 2, '0')) as months,
COUNT(DISTINCT user_name) as team_contributors,
CAST(SUM(edit_count) as BIGINT) as team_edits
FROM '../changeset_data/year=*/month=*/*.parquet'
WHERE organised_team IS NOT NULL
GROUP BY year, month
)
SELECT
mt.months,
mt.total_contributors as "Total Contributors",
COALESCE(mot.team_contributors, 0) as "Organised Team Contributors",
mt.total_edits as "Total Edits",
COALESCE(mot.team_edits, 0) as "Organised Team Edits",
ROUND((COALESCE(mot.team_contributors, 0) * 100.0) / mt.total_contributors, 2) as "Percent Contributors from Organised Teams",
ROUND((COALESCE(mot.team_edits, 0) * 100.0) / mt.total_edits, 2) as "Percent Edits from Organised Teams"
FROM monthly_total mt
LEFT JOIN monthly_organised_team mot ON mt.year = mot.year AND mt.month = mot.month
ORDER BY mt.year, mt.month
""").df()
util.show_figure(
[
util.FigureConfig(
title="Percentage of Edits from Organised Teams",
label="Edits Percentage",
x_col="months",
y_col="Percent Edits from Organised Teams",
y_unit_hover_template="%",
query_or_df=df,
),
util.FigureConfig(
title="Monthly Edits from Organised Teams",
label="Edits",
x_col="months",
y_col="Organised Team Edits",
query_or_df=df,
),
util.FigureConfig(
title="Percentage of Contributors from Organised Teams",
label="Contributors Percentage",
x_col="months",
y_col="Percent Contributors from Organised Teams",
y_unit_hover_template="%",
query_or_df=df,
),
util.FigureConfig(
title="Monthly Contributors from Organised Teams",
label="Contributors",
x_col="months",
y_col="Organised Team Contributors",
query_or_df=df,
),
]
)
# Top 10 organised teams by contributors
df_top10 = duckdb.sql("""
WITH top_organised_teams AS (
SELECT organised_team
FROM (
SELECT
organised_team,
SUM(edit_count) as total_edits
FROM '../changeset_data/year=*/month=*/*.parquet'
WHERE organised_team IS NOT NULL
GROUP BY organised_team
ORDER BY total_edits DESC
LIMIT 10
)
),
user_first_appearance AS (
SELECT
user_name,
year,
month,
organised_team,
ROW_NUMBER() OVER (PARTITION BY user_name ORDER BY year, month) as rn
FROM (
SELECT DISTINCT user_name, year, month, organised_team
FROM '../changeset_data/year=*/month=*/*.parquet'
WHERE organised_team IN (SELECT organised_team FROM top_organised_teams)
)
),
first_appearances AS (
SELECT user_name, year, month, organised_team
FROM user_first_appearance
WHERE rn = 1
),
monthly_contributors AS (
SELECT
year,
month,
CONCAT(year, '-', LPAD(CAST(month as VARCHAR), 2, '0')) as months,
organised_team,
COUNT(DISTINCT user_name) as "Contributors",
CAST(SUM(edit_count) as BIGINT) as "Edits"
FROM '../changeset_data/year=*/month=*/*.parquet'
WHERE organised_team IN (SELECT organised_team FROM top_organised_teams)
GROUP BY year, month, organised_team
),
monthly_new_contributors AS (
SELECT
year,
month,
organised_team,
COUNT(DISTINCT user_name) as "New Contributors"
FROM first_appearances
GROUP BY year, month, organised_team
)
SELECT
mc.months,
mc.organised_team,
mc."Contributors",
COALESCE(mnc."New Contributors", 0) as "New Contributors",
mc."Edits"
FROM monthly_contributors mc
LEFT JOIN monthly_new_contributors mnc ON mc.year = mnc.year AND mc.month = mnc.month AND mc.organised_team = mnc.organised_team
ORDER BY mc.year, mc.month, mc.organised_team
""").df()
util.show_figure(
[
util.FigureConfig(
title="Monthly Edits by Top 10 Organised Teams",
label="Edits",
x_col="months",
y_col="Edits",
group_col="organised_team",
query_or_df=df_top10,
),
util.FigureConfig(
title="Monthly Contributors by Top 10 Organised Teams",
label="Contributors",
x_col="months",
y_col="Contributors",
group_col="organised_team",
query_or_df=df_top10,
),
util.FigureConfig(
title="Monthly New Contributors by Top 10 Organised Teams",
label="New Contributors",
x_col="months",
y_col="New Contributors",
group_col="organised_team",
query_or_df=df_top10,
),
]
)
query = """
WITH organised_team_totals AS (
SELECT
organised_team as "Organised Team",
CAST(SUM(edit_count) as BIGINT) as total_edits_all_time,
CAST(COUNT(DISTINCT user_name) as BIGINT) as total_contributors_all_time
FROM '../changeset_data/year=*/month=*/*.parquet'
WHERE organised_team IS NOT NULL
GROUP BY organised_team
),
yearly_metrics AS (
SELECT
d.year,
d.organised_team as "Organised Team",
CAST(SUM(d.edit_count) as BIGINT) as "Edits",
CAST(COUNT(DISTINCT d.user_name) as BIGINT) as "Contributors"
FROM '../changeset_data/year=*/month=*/*.parquet' d
WHERE d.organised_team IS NOT NULL
GROUP BY d.year, d.organised_team
)
SELECT
ym.year,
ym."Organised Team",
ym."Edits",
ym."Contributors",
ott.total_edits_all_time as "Total Edits",
ott.total_contributors_all_time as "Total Contributors"
FROM yearly_metrics ym
JOIN organised_team_totals ott ON ym."Organised Team" = ott."Organised Team"
ORDER BY year DESC, "Edits" DESC
"""
df_all = duckdb.sql(query).df()
table_configs = [
util.TableConfig(
title="Edits Per Organised Team by Year",
label="Edits",
query_or_df=df_all,
x_axis_col="year",
y_axis_col="Organised Team",
value_col="Edits",
center_columns=["Rank", "Organised Team"],
sum_col="Total Edits",
),
util.TableConfig(
title="Contributors Per Organised Team by Year",
label="Contributors",
query_or_df=df_all,
x_axis_col="year",
y_axis_col="Organised Team",
value_col="Contributors",
center_columns=["Rank", "Organised Team"],
sum_col="Total Contributors",
),
]
util.show_tables(table_configs)
| Rank | Organised Team | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | Total Edits |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Meta | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 78,815 | 4,296,035 | 20,247,234 | 28,957,510 | 50,673,799 | 83,060,907 | 51,973,945 | 25,494,310 | 1,074,076 | 1,926,751 | 496,118 | 268,279,500 |
| 2 | Kaart | 0 | 22,922 | 7,559 | 364,177 | 976,391 | 730,863 | 780,037 | 623,276 | 1,509,967 | 6,907,406 | 7,390,957 | 8,620,818 | 21,691,873 | 28,594,458 | 19,554,990 | 17,457,242 | 14,494,192 | 10,150,874 | 9,947,172 | 990,031 | 150,815,205 |
| 3 | Apple | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 517,919 | 3,592,733 | 8,817,766 | 10,193,904 | 4,749,530 | 6,034,234 | 6,546,721 | 6,913,301 | 8,609,816 | 644,522 | 56,620,446 |
| 4 | Amazon | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 68 | 960,001 | 12,655,507 | 23,277,677 | 14,696,014 | 951,439 | 621,752 | 62,845 | 103,725 | 872 | 53,329,900 |
| 5 | Mapbox | 0 | 0 | 45,339 | 130,377 | 336,422 | 1,812,554 | 2,975,135 | 5,001,072 | 10,364,605 | 7,176,557 | 6,020,903 | 5,478,836 | 1,039,305 | 1,528,567 | 1,150,373 | 1,848,191 | 1,427,806 | 1,787,103 | 4,338,791 | 83,695 | 52,545,631 |
| 6 | DigitalEgypt | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7,815 | 4,835,241 | 4,385,173 | 3,475,331 | 4,657,479 | 4,054,066 | 3,732,908 | 2,303,981 | 260,237 | 27,712,231 |
| 7 | TomTom | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 13,356 | 904 | 14 | 256 | 5,163,115 | 5,383,053 | 5,994,057 | 5,209,686 | 4,758,992 | 507,143 | 27,030,576 |
| 8 | Grab | 0 | 0 | 0 | 0 | 0 | 0 | 61 | 0 | 360,575 | 158,382 | 457,508 | 843,767 | 3,055,958 | 2,913,731 | 8,905,274 | 3,945,732 | 522,616 | 371,924 | 527,754 | 78,070 | 22,141,352 |
| 9 | Microsoft | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 298 | 1,064,188 | 4,888,550 | 3,876,132 | 3,863,712 | 1,324,223 | 1,395,808 | 731,208 | 2,121,418 | 856,594 | 20,122,131 |
| 10 | GeoCompas | 0 | 0 | 0 | 0 | 23,957 | 1,421,771 | 2,478,856 | 2,860,814 | 3,100,322 | 1,768,042 | 582,325 | 1,756,308 | 580,203 | 456,227 | 99,606 | 844,325 | 967,220 | 730,673 | 1,717,922 | 46,308 | 19,434,879 |
| 11 | Lyft | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 18,674 | 924,763 | 351,377 | 333,234 | 1,668,703 | 2,370,224 | 2,255,647 | 1,579,109 | 227,213 | 9,728,944 |
| 12 | VK_Maps | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 19 | 3,157 | 19,605 | 108,003 | 1,183,951 | 1,390,851 | 1,925,937 | 1,657,395 | 1,094,996 | 59,192 | 7,443,106 |
| 13 | Ola | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 381,080 | 3,535,451 | 1,838,614 | 687,425 | 20,108 | 6,462,678 |
| 14 | Lightcyphers | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 792,152 | 2,358,928 | 1,790,772 | 332,143 | 38 | 169 | 3,765 | 1,937 | 0 | 5,279,904 |
| 15 | Wildberries Geo Team | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 107 | 9,810 | 95,944 | 654,015 | 599,785 | 840,244 | 721,364 | 1,391,698 | 49,724 | 4,362,691 |
| 16 | Telenav | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 58,334 | 303,600 | 892,891 | 1,053,569 | 384,426 | 105,963 | 50,794 | 70,937 | 1,696 | 2 | 0 | 0 | 2,922,212 |
| 17 | FixMyCity | 12 | 0 | 0 | 0 | 0 | 0 | 2,988 | 93,720 | 1,419 | 69,178 | 32,469 | 99,973 | 19,132 | 187,495 | 488,560 | 596,890 | 312,207 | 323,420 | 570,797 | 51,648 | 2,849,908 |
| 18 | Mapy.com | 0 | 1 | 0 | 0 | 7 | 95 | 19 | 66 | 1,579 | 2,668 | 15,765 | 31,292 | 242,644 | 302,011 | 291,539 | 183,711 | 149,239 | 464,607 | 806,010 | 85,744 | 2,576,997 |
| 19 | Neshan | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 11 | 34 | 13 | 112,540 | 9 | 506,381 | 481,299 | 198,237 | 479,892 | 479,234 | 298,715 | 1,234 | 28 | 2,557,627 |
| 20 | Ozon | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 154 | 0 | 0 | 0 | 0 | 0 | 34,748 | 1,804,025 | 236,006 | 2,074,933 |
| 21 | Uber | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 128,227 | 93,662 | 20,904 | 7,876 | 8,719 | 14,944 | 35,215 | 1,139,065 | 102,535 | 1,551,155 |
| 22 | Bolt | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 76,244 | 364,645 | 608,904 | 177,867 | 13,667 | 8,760 | 412 | 1,250,499 |
| 23 | Wonder | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 25,983 | 88,313 | 79,845 | 215,450 | 144,224 | 69,255 | 85,399 | 0 | 0 | 0 | 708,469 |
| 24 | OpenSidewalks | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 18,654 | 80,592 | 10,728 | 88,443 | 196,028 | 130,770 | 118,558 | 10,761 | 654,534 |
| 25 | Snapp | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1,447 | 0 | 44,429 | 166,913 | 52,062 | 83,623 | 98,455 | 104,044 | 64,201 | 27,953 | 512 | 643,639 |
| 26 | Rocketdata.io | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 11,827 | 71,556 | 140,653 | 178,608 | 154,610 | 65,082 | 5,096 | 627,432 |
| 27 | Snap | 0 | 0 | 0 | 0 | 211 | 914 | 645 | 526 | 10,196 | 65,937 | 23,805 | 8,679 | 34,762 | 34,214 | 325,971 | 10,619 | 422 | 344 | 3,167 | 0 | 520,412 |
| 28 | Graphmasters | 0 | 0 | 0 | 0 | 31 | 0 | 0 | 0 | 74 | 35 | 48 | 1,081 | 50,687 | 283,072 | 22,588 | 35,234 | 37,476 | 27,312 | 46,076 | 3,532 | 507,246 |
| 29 | Stackbox | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 293,886 | 159,794 | 4,376 | 20,412 | 460 | 478,932 |
| 30 | TIDBO | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 153,262 | 305,050 | 8,585 | 0 | 3,085 | 6,445 | 40 | 0 | 0 | 476,467 |
| 31 | TfNSW | 0 | 0 | 7 | 0 | 7 | 673 | 825 | 1,416 | 2,312 | 8,747 | 9,607 | 30,403 | 76,672 | 26,235 | 88,297 | 81,260 | 31,329 | 35,051 | 69,844 | 5,747 | 468,432 |
| 32 | NextBillion.AI | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 401,141 | 30 | 10 | 0 | 0 | 0 | 0 | 401,181 |
| 33 | Geovelo | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 19,937 | 34,283 | 36,104 | 18,496 | 21,500 | 20,491 | 43,063 | 35,802 | 59,905 | 18,291 | 307,872 |
| 34 | AMAT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 391 | 106 | 9 | 14,464 | 1,522 | 29,674 | 179,036 | 60,883 | 8,193 | 2,793 | 0 | 297,071 |
| 35 | Kontur | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2,632 | 282,941 | 766 | 0 | 0 | 0 | 286,339 |
| 36 | Swiggy | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 695 | 7,196 | 207 | 1,021 | 111,108 | 79,923 | 33,664 | 3,529 | 237,343 |
| 37 | NNG | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 945 | 150,374 | 36,314 | 2,303 | 189,936 |
| 38 | Expedia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 25,618 | 57,852 | 69,542 | 4,141 | 442 | 17 | 157,614 |
| 39 | Digiroad | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 905 | 56,027 | 1 | 0 | 0 | 2,067 | 44 | 0 | 0 | 59,044 |
| 40 | AppLogica | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 30,001 | 0 | 0 | 0 | 0 | 30,001 |
| 41 | GOAT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 165 | 356 | 23,845 | 1,375 | 820 | 958 | 198 | 354 | 1 | 0 | 28,072 |
| 42 | Getpin | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5,219 | 3,905 | 1,173 | 915 | 11,212 |
| 43 | WIGeoGIS | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 517 | 127 | 150 | 285 | 159 | 459 | 221 | 663 | 327 | 301 | 106 | 0 | 3,315 |
| 44 | DINAclub | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 105 | 76 | 6 | 3 | 0 | 112 | 134 | 1,577 | 700 | 49 | 2,762 |
| 45 | Balad | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | 2,649 | 0 | 29 | 18 | 18 | 0 | 0 | 0 | 2,722 |
| 46 | Komoot | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 142 | 400 | 173 | 122 | 443 | 692 | 19 | 1,991 |
| 47 | Gojek | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1,185 | 32 | 0 | 56 | 55 | 0 | 1,328 |
| 48 | TeleClinic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 92 | 87 | 95 | 9 | 285 |
| 49 | Blitzer.de | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 27 | 99 | 104 | 0 | 230 |