From b08b1552ef3b88ecbac542873df9d084c0568f81 Mon Sep 17 00:00:00 2001 From: Hadrien Patte Date: Mon, 29 Jun 2020 01:48:47 -0400 Subject: [PATCH 1/2] Convert map from CSV to GeoJSON --- .travis.yml | 4 +- README.md | 6 +- checkcsv.py | 40 ----- checkgeojson.py | 44 +++++ map.csv | 29 ---- map.geojson | 453 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 502 insertions(+), 74 deletions(-) delete mode 100644 checkcsv.py create mode 100644 checkgeojson.py delete mode 100644 map.csv create mode 100644 map.geojson diff --git a/.travis.yml b/.travis.yml index 9e2ca2c..706e603 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: python python: - - "3.6" + - "3.8" script: - - python3 checkcsv.py map.csv + - python3 checkgeojson.py map.geojson diff --git a/README.md b/README.md index 321ffcb..0f0b4cf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -Carte des anciens Rezomen +Carte des anciens Rézomen ========================= -Ce fichier CSV liste la position des anciens Rézomen. À partir de ces données, une [carte Google Maps est accessible ici](https://www.google.com/maps/d/viewer?mid=1R_ogcebnWSXzlkURnYW6t5LaXIA). +Ce fichier [GeoJSON](https://tools.ietf.org/html/rfc7946) liste la position des anciens Rézomen. À partir de ces données, une [carte est accessible ici](./map.geojson). -[![screenshot](sample.png)](https://www.google.com/maps/d/viewer?mid=1R_ogcebnWSXzlkURnYW6t5LaXIA) +[![screenshot](sample.png)](./map.geojson) Ajoutez-vous via pull request ; merci de respecter l'ordre promo (descendant), nom de famille. diff --git a/checkcsv.py b/checkcsv.py deleted file mode 100644 index dcea5e7..0000000 --- a/checkcsv.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -import csv -import re -import sys - - -COLUMNS = ['Pseudo', 'Nom', 'Promo', 'Mise à jour', 'Latitude', 'Longitude'] - - -def error(msg, line): - sys.stderr.write(msg) - sys.stderr.write(" ligne %d\n" % (line + 1)) - sys.exit(1) - - -_promo = re.compile(r'^(19|20)[0-9][0-9]$') -_date = re.compile(r'^20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]$') -_coord = re.compile(r'^-?[0-9]{1,3}\.[0-9]{1,10}$') - - -if __name__ == '__main__': - with open(sys.argv[1]) as fp: - cols = None - lines = enumerate(csv.reader(fp)) - line, firstline = next(lines) - if firstline != COLUMNS: - error("Header invalide", line) - for line, row in lines: - if len(row) != len(COLUMNS): - error("Nombre de colonnes invalide", line) - if not _promo.match(row[2]): - error("Promo invalide %r" % row[2], line) - if not _date.match(row[3]): - error("Date de mise a jour invalide %r" % row[3], line) - if not _coord.match(row[4]): - error("Latitude invalide %r" % row[4], line) - if not _coord.match(row[5]): - error("Longitude invalide %r" % row[5], line) - print("%d lignes validees" % (line + 1)) diff --git a/checkgeojson.py b/checkgeojson.py new file mode 100644 index 0000000..aa685e8 --- /dev/null +++ b/checkgeojson.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import re +import sys +import json + +REZOMAN_FIELDS = ['pseudo', 'name', 'promo', 'last_update'] + +def error(msg, rezoman = None): + error_msg = f"Error: {msg}" + if rezoman: + error_msg += f" for rezoman {rezoman['properties']['pseudo']}" + sys.stderr.write(error_msg + '\n') + sys.exit(1) + + +_promo = re.compile(r'^(19|20)[0-9][0-9]$') +_date = re.compile(r'^20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]$') +_coord = re.compile(r'^-?[0-9]{1,3}\.[0-9]{1,10}$') + + +if __name__ == '__main__': + with open(sys.argv[1]) as json_map: + rezomap = json.load(json_map) + + for rezoman in rezomap['features']: + # Fields check + if not list(rezoman['properties'].keys()) == REZOMAN_FIELDS: + error('Invalid properties fields') + + # Type checks + for field in REZOMAN_FIELDS: + if type(rezoman['properties'][field]) != str: + error(f"Field {field} must be a string", rezoman) + + # Value checks + if not _promo.match(rezoman["properties"]["promo"]): + error('Invalid Promo', rezoman) + if not _date.match(rezoman["properties"]["last_update"]): + error('Invalid update date', rezoman) + if not _coord.match(str(rezoman["geometry"]["coordinates"][0])): + error('Invalid latitude', rezoman) + if not _coord.match(str(rezoman["geometry"]["coordinates"][1])): + error('Invalid longitude', rezoman) diff --git a/map.csv b/map.csv deleted file mode 100644 index 54605d1..0000000 --- a/map.csv +++ /dev/null @@ -1,29 +0,0 @@ -Pseudo,Nom,Promo,Mise à jour,Latitude,Longitude -Fitz,Victor Fauth,2019,2019-02-08,53.330938,-6.246632 -redlink,Romain Poirot,2019,2019-02-08,48.9233333,2.445 -Frost,Hugo Waltsburger,2019,2019-03-03,48.707930,2.161854 -Froux,François d'Yvoire,2019,2019-04-02,51.507351,-0.127758 -warp,Sylvain Pascou,2018,2018-07-27,35.742217,139.687067 -toadjaune,Arnaud Venturi,2017,2018-10-26,48.89511,2.2730 -tyreunom,Julien Lepiller,2016,2016-09-20,48.10853,-1.67051 -BackIsBachus,Jean-Sébastien Renaud,2016,2020-06-14,43.6171465,7.0706538 -zeroNounours,Gauthier Sebaux,2016,2017-01-24,48.823558,2.371982 -Altay,Nicolas Audebert,2015,2018-07-27,48.714577,2.232761 -tetram,Guillaume Dhainaut,2015,2016-09-21,43.604652,1.444209 -Ningirsu,Sélim Menouar,2015,2016-06-21,48.7451216,2.30184 -Th3oSMith,Rémi Robert,2015,2018-07-27,59.380086,17.901535 -horo,Maxime PRUNEAU,2014,2017-01-18,35.6395369,139.6997184 -Ryen,Remi Chaintreuil,2013,2019-02-08,30.2433284,-97.8478371 -Damdam,Fabien Schwebel,2013,2018-09-25,40.4138184,-3.6920454 -VnC,Vincent Barbaresi,2012,2016-09-21,48.84133,2.29159 -Lily,Marc Delorme,2012,2016-09-20,35.00617,135.72593 -Zertrin,Marc Gallet,2012,2019-02-07,1.294791,103.836897 -ciblout,Cyprien Oger,2012,2018-10-09,47.206591,-1.538067 -Remram,Rémi Rampin,2012,2018-07-27,40.696,-73.983 -Yqnn,Yann Armelin,2011,2020-05-27,43.594,7.101 -Gagou,Olivier Gatimel,2009,2019-02-10,45.750000,4.850000 -Phyce,Philippe Guillebert,2006,2016-09-20,49.25683,-123.15060 -guitou,David Marchand,2005,2018-09-22,44.806634,-0.632543 -P.O.,Pierre-Olivier Gaillard,1996,2019-02-25,40.659502,-73.645469 -Garz,Frédéric Garzon,1996,2019-02-25,48.8588377,2.2770209 -SuperU,Nicolas Lejeune,1996,2019-02-25,43.295797,5.375253 diff --git a/map.geojson b/map.geojson new file mode 100644 index 0000000..fe82b09 --- /dev/null +++ b/map.geojson @@ -0,0 +1,453 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 53.330938, + -6.246632 + ] + }, + "properties": { + "pseudo": "Fitz", + "name": "Victor Fauth", + "promo": "2019", + "last_update": "2019-02-08" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.9233333, + 2.445 + ] + }, + "properties": { + "pseudo": "redlink", + "name": "Romain Poirot", + "promo": "2019", + "last_update": "2019-02-08" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.707930, + 2.161854 + ] + }, + "properties": { + "pseudo": "Frost", + "name": "Hugo Waltsburger", + "promo": "2019", + "last_update": "2019-03-03" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 51.507351, + -0.127758 + ] + }, + "properties": { + "pseudo": "Froux", + "name": "François d'Yvoire", + "promo": "2019", + "last_update": "2019-04-02" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 35.742217, + 139.687067 + ] + }, + "properties": { + "pseudo": "warp", + "name": "Sylvain Pascou", + "promo": "2018", + "last_update": "2018-07-27" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.89511, + 2.2730 + ] + }, + "properties": { + "pseudo": "toadjaune", + "name": "Arnaud Venturi", + "promo": "2017", + "last_update": "2018-10-26" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.10853, + -1.67051 + ] + }, + "properties": { + "pseudo": "tyreunom", + "name": "Julien Lepiller", + "promo": "2016", + "last_update": "2016-09-20" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 43.6171465, + 7.0706538 + ] + }, + "properties": { + "pseudo": "BackIsBachus", + "name": "Jean-Sébastien Renaud", + "promo": "2016", + "last_update": "2020-06-14" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.823558, + 2.371982 + ] + }, + "properties": { + "pseudo": "zeroNounours", + "name": "Gauthier Sebaux", + "promo": "2016", + "last_update": "2017-01-24" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.714577, + 2.232761 + ] + }, + "properties": { + "pseudo": "Altay", + "name": "Nicolas Audebert", + "promo": "2015", + "last_update": "2018-07-27" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 43.604652, + 1.444209 + ] + }, + "properties": { + "pseudo": "tetram", + "name": "Guillaume Dhainaut", + "promo": "2015", + "last_update": "2016-09-21" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.7451216, + 2.30184 + ] + }, + "properties": { + "pseudo": "Ningirsu", + "name": "Sélim Menouar", + "promo": "2015", + "last_update": "2016-06-21" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 59.380086, + 17.901535 + ] + }, + "properties": { + "pseudo": "Th3oSMith", + "name": "Rémi Robert", + "promo": "2015", + "last_update": "2018-07-27" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 35.6395369, + 139.6997184 + ] + }, + "properties": { + "pseudo": "horo", + "name": "Maxime PRUNEAU", + "promo": "2014", + "last_update": "2017-01-18" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 30.2433284, + -97.8478371 + ] + }, + "properties": { + "pseudo": "Ryen", + "name": "Remi Chaintreuil", + "promo": "2013", + "last_update": "2019-02-08" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 40.4138184, + -3.6920454 + ] + }, + "properties": { + "pseudo": "Damdam", + "name": "Fabien Schwebel", + "promo": "2013", + "last_update": "2018-09-25" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.84133, + 2.29159 + ] + }, + "properties": { + "pseudo": "VnC", + "name": "Vincent Barbaresi", + "promo": "2012", + "last_update": "2016-09-21" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 35.00617, + 135.72593 + ] + }, + "properties": { + "pseudo": "Lily", + "name": "Marc Delorme", + "promo": "2012", + "last_update": "2016-09-20" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 1.294791, + 103.836897 + ] + }, + "properties": { + "pseudo": "Zertrin", + "name": "Marc Gallet", + "promo": "2012", + "last_update": "2019-02-07" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 47.206591, + -1.538067 + ] + }, + "properties": { + "pseudo": "ciblout", + "name": "Cyprien Oger", + "promo": "2012", + "last_update": "2018-10-09" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 40.696, + -73.983 + ] + }, + "properties": { + "pseudo": "Remram", + "name": "Rémi Rampin", + "promo": "2012", + "last_update": "2018-07-27" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 43.594, + 7.101 + ] + }, + "properties": { + "pseudo": "Yqnn", + "name": "Yann Armelin", + "promo": "2011", + "last_update": "2020-05-27" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 45.750000, + 4.850000 + ] + }, + "properties": { + "pseudo": "Gagou", + "name": "Olivier Gatimel", + "promo": "2009", + "last_update": "2019-02-10" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 49.25683, + -123.15060 + ] + }, + "properties": { + "pseudo": "Phyce", + "name": "Philippe Guillebert", + "promo": "2006", + "last_update": "2016-09-20" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 44.806634, + -0.632543 + ] + }, + "properties": { + "pseudo": "guitou", + "name": "David Marchand", + "promo": "2005", + "last_update": "2018-09-22" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 40.659502, + -73.645469 + ] + }, + "properties": { + "pseudo": "P.O.", + "name": "Pierre-Olivier Gaillard", + "promo": "1996", + "last_update": "2019-02-25" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 48.8588377, + 2.2770209 + ] + }, + "properties": { + "pseudo": "Garz", + "name": "Frédéric Garzon", + "promo": "1996", + "last_update": "2019-02-25" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 43.295797, + 5.375253 + ] + }, + "properties": { + "pseudo": "SuperU", + "name": "Nicolas Lejeune", + "promo": "1996", + "last_update": "2019-02-25" + } + } + ] +} From de008b153e81d886da17c9c54a6b3a5ee2adb1a5 Mon Sep 17 00:00:00 2001 From: Hadrien Patte Date: Mon, 29 Jun 2020 02:01:57 -0400 Subject: [PATCH 2/2] Invert latitude and longitude --- checkgeojson.py | 4 +- map.geojson | 112 ++++++++++++++++++++++++------------------------ 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/checkgeojson.py b/checkgeojson.py index aa685e8..ac92264 100644 --- a/checkgeojson.py +++ b/checkgeojson.py @@ -39,6 +39,6 @@ def error(msg, rezoman = None): if not _date.match(rezoman["properties"]["last_update"]): error('Invalid update date', rezoman) if not _coord.match(str(rezoman["geometry"]["coordinates"][0])): - error('Invalid latitude', rezoman) - if not _coord.match(str(rezoman["geometry"]["coordinates"][1])): error('Invalid longitude', rezoman) + if not _coord.match(str(rezoman["geometry"]["coordinates"][1])): + error('Invalid latitude', rezoman) diff --git a/map.geojson b/map.geojson index fe82b09..36c0a92 100644 --- a/map.geojson +++ b/map.geojson @@ -6,8 +6,8 @@ "geometry": { "type": "Point", "coordinates": [ - 53.330938, - -6.246632 + -6.246632, + 53.330938 ] }, "properties": { @@ -22,8 +22,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.9233333, - 2.445 + 2.445, + 48.9233333 ] }, "properties": { @@ -38,8 +38,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.707930, - 2.161854 + 2.161854, + 48.707930 ] }, "properties": { @@ -54,8 +54,8 @@ "geometry": { "type": "Point", "coordinates": [ - 51.507351, - -0.127758 + -0.127758, + 51.507351 ] }, "properties": { @@ -70,8 +70,8 @@ "geometry": { "type": "Point", "coordinates": [ - 35.742217, - 139.687067 + 139.687067, + 35.742217 ] }, "properties": { @@ -86,8 +86,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.89511, - 2.2730 + 2.2730, + 48.89511 ] }, "properties": { @@ -102,8 +102,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.10853, - -1.67051 + -1.67051, + 48.10853 ] }, "properties": { @@ -118,8 +118,8 @@ "geometry": { "type": "Point", "coordinates": [ - 43.6171465, - 7.0706538 + 7.0706538, + 43.6171465 ] }, "properties": { @@ -134,8 +134,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.823558, - 2.371982 + 2.371982, + 48.823558 ] }, "properties": { @@ -150,8 +150,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.714577, - 2.232761 + 2.232761, + 48.714577 ] }, "properties": { @@ -166,8 +166,8 @@ "geometry": { "type": "Point", "coordinates": [ - 43.604652, - 1.444209 + 1.444209, + 43.604652 ] }, "properties": { @@ -182,8 +182,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.7451216, - 2.30184 + 2.30184, + 48.7451216 ] }, "properties": { @@ -198,8 +198,8 @@ "geometry": { "type": "Point", "coordinates": [ - 59.380086, - 17.901535 + 17.901535, + 59.380086 ] }, "properties": { @@ -214,8 +214,8 @@ "geometry": { "type": "Point", "coordinates": [ - 35.6395369, - 139.6997184 + 139.6997184, + 35.6395369 ] }, "properties": { @@ -230,8 +230,8 @@ "geometry": { "type": "Point", "coordinates": [ - 30.2433284, - -97.8478371 + -97.8478371, + 30.2433284 ] }, "properties": { @@ -246,8 +246,8 @@ "geometry": { "type": "Point", "coordinates": [ - 40.4138184, - -3.6920454 + -3.6920454, + 40.4138184 ] }, "properties": { @@ -262,8 +262,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.84133, - 2.29159 + 2.29159, + 48.84133 ] }, "properties": { @@ -278,8 +278,8 @@ "geometry": { "type": "Point", "coordinates": [ - 35.00617, - 135.72593 + 135.72593, + 35.00617 ] }, "properties": { @@ -294,8 +294,8 @@ "geometry": { "type": "Point", "coordinates": [ - 1.294791, - 103.836897 + 103.836897, + 1.294791 ] }, "properties": { @@ -310,8 +310,8 @@ "geometry": { "type": "Point", "coordinates": [ - 47.206591, - -1.538067 + -1.538067, + 47.206591 ] }, "properties": { @@ -326,8 +326,8 @@ "geometry": { "type": "Point", "coordinates": [ - 40.696, - -73.983 + -73.983, + 40.696 ] }, "properties": { @@ -342,8 +342,8 @@ "geometry": { "type": "Point", "coordinates": [ - 43.594, - 7.101 + 7.101, + 43.594 ] }, "properties": { @@ -358,8 +358,8 @@ "geometry": { "type": "Point", "coordinates": [ - 45.750000, - 4.850000 + 4.850000, + 45.750000 ] }, "properties": { @@ -374,8 +374,8 @@ "geometry": { "type": "Point", "coordinates": [ - 49.25683, - -123.15060 + -123.15060, + 49.25683 ] }, "properties": { @@ -390,8 +390,8 @@ "geometry": { "type": "Point", "coordinates": [ - 44.806634, - -0.632543 + -0.632543, + 44.806634 ] }, "properties": { @@ -406,8 +406,8 @@ "geometry": { "type": "Point", "coordinates": [ - 40.659502, - -73.645469 + -73.645469, + 40.659502 ] }, "properties": { @@ -422,8 +422,8 @@ "geometry": { "type": "Point", "coordinates": [ - 48.8588377, - 2.2770209 + 2.2770209, + 48.8588377 ] }, "properties": { @@ -438,8 +438,8 @@ "geometry": { "type": "Point", "coordinates": [ - 43.295797, - 5.375253 + 5.375253, + 43.295797 ] }, "properties": {