-
Notifications
You must be signed in to change notification settings - Fork 0
/
paris-velib-via-developer-jcdecaux.html
109 lines (100 loc) · 14.1 KB
/
paris-velib-via-developer-jcdecaux.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Paris Vélib via Developer JCDecaux - Toto do stuff</title><meta name="description" content="JCDecaux à ouvert son site web open data où l'on peux trouver toutes les informations relatives à leur solutions de vélo publique implémentées dans différentes…"><meta name="generator" content="Publii Open-Source CMS for Static Site"><link rel="canonical" href="https://totetmatt.github.io/paris-velib-via-developer-jcdecaux.html"><link rel="alternate" type="application/atom+xml" href="https://totetmatt.github.io/feed.xml"><link rel="alternate" type="application/json" href="https://totetmatt.github.io/feed.json"><meta property="og:title" content="Paris Vélib via Developer JCDecaux"><meta property="og:site_name" content="Toto do stuff"><meta property="og:description" content="JCDecaux à ouvert son site web open data où l'on peux trouver toutes les informations relatives à leur solutions de vélo publique implémentées dans différentes…"><meta property="og:url" content="https://totetmatt.github.io/paris-velib-via-developer-jcdecaux.html"><meta property="og:type" content="article"><style>:root{--body-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--heading-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--logo-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--menu-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}</style><link rel="stylesheet" href="https://totetmatt.github.io/assets/css/style.css?v=825c89ac06c7215b642eda05e8a14751"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://totetmatt.github.io/paris-velib-via-developer-jcdecaux.html"},"headline":"Paris Vélib via Developer JCDecaux","datePublished":"2013-05-14T12:27","dateModified":"2020-06-20T00:35","description":"JCDecaux à ouvert son site web open data où l'on peux trouver toutes les informations relatives à leur solutions de vélo publique implémentées dans différentes…","author":{"@type":"Person","name":"Totetmatt","url":"https://totetmatt.github.io/authors/totetmatt/"},"publisher":{"@type":"Organization","name":"Totetmatt"}}</script></head><body><div class="site-container"><header class="top" id="js-header"><a class="logo" href="https://totetmatt.github.io/">Toto do stuff</a></header><main><article class="post"><div class="hero"><figure class="hero__image hero__image--overlay"><img src="https://totetmatt.github.io/media/website/bg.jpg" srcset="https://totetmatt.github.io/media/website/responsive/bg-xs.jpg 300w, https://totetmatt.github.io/media/website/responsive/bg-sm.jpg 480w, https://totetmatt.github.io/media/website/responsive/bg-md.jpg 768w, https://totetmatt.github.io/media/website/responsive/bg-lg.jpg 1024w, https://totetmatt.github.io/media/website/responsive/bg-xl.jpg 1360w, https://totetmatt.github.io/media/website/responsive/bg-2xl.jpg 1600w" sizes="(max-width: 1600px) 100vw, 1600px" loading="eager" alt=""></figure><header class="hero__content"><div class="wrapper"><div class="post__meta"><time datetime="2013-05-14T12:27">13/05/14</time></div><h1>Paris Vélib via Developer JCDecaux</h1><div class="post__meta post__meta--author"><a href="https://totetmatt.github.io/authors/totetmatt/" class="feed__author invert">Totetmatt</a></div></div></header></div><div class="wrapper post__entry"><p>JCDecaux à ouvert son site web <a href="http://developer.jcdecaux.com">open data</a> où l'on peux trouver toutes les informations relatives à leur solutions de vélo publique implémentées dans différentes villes comme <strong>Paris</strong>, <strong>Lyon</strong>, <strong>Marseille</strong> pour la France et <strong>Bruxelle</strong>, <strong>Toyama</strong> ou encore <strong>Goetborg</strong> pour le reste du monde.</p><p>C'est une très bonne nouvelle, car on a enfin une <strong>solution officielle</strong> nous fournissant des données assez utiles sur les stations de vélo dans les villes ainsi que l'état en temps réels de ces dernières.</p><p>J'ai voulu jouer avec ces données.<br>J'ai pris le json de la carte de Paris, qui donne <strong>toutes les stations de Vélib</strong> comme ceci:</p><pre>[
{"number":7022, // un identifiant
"name":"07022 - PONT DE L'ALMA", // Un nom
"address":"3 AVENUE BOSQUET - 75007 PARIS", // l'adresse de la station
"latitude":48.86164049957625, // sa latitude
"longitude":2.302250344175951}, // sa longitude
{..}
,..
]</pre><p>Et tout ça, ça s'exporte bien dans <a title="Gephi" href="http://gephi.org/">Gephi </a>!</p><pre>import json
from GephiStreamer import Node,Edge,GephiStreamerManager
t = GephiStreamerManager()
with open('Paris.json', 'r') as f:
read_data = f.read()
f.closed
jdata = json.loads(read_data)
for d in jdata:
print d['number']
n= Node(d['number'],label=d['name'])
n.property['address'] = d['address']
n.property['latitude'] = d['latitude']
n.property['longitude'] = d['longitude']
t.add_node(n)
t.commit()</pre><p>Un coup de <strong>Geo-Layout</strong> et pof, on a une belle représentation de nos stations.</p><p>Mais, ça manque un peu de lien, alors on va en créer.</p><h1>1er idée</h1><p>Relier une station A à une autre station B si B est la station la plus proche de A.</p><pre>t = GephiStreamerManager()
with open('Paris.json', 'r') as f:
read_data = f.read()
f.closed
jdata = json.loads(read_data)
for d in jdata:
print d['number']
n= Node(d['number'],label=d['name'])
n.property['address'] = d['address']
n.property['latitude'] = d['latitude']
n.property['longitude'] = d['longitude']
t.add_node(n)
t.commit()
map_distance = {}
for d in jdata:
map_distance[d['number']]=[]
for dd in jdata:
if dd['number'] != d['number']:
latpow = (d['latitude']-dd['latitude'])*(d['latitude']-dd['latitude'])
lonpow = (d['longitude']-dd['longitude'])*(d['longitude']-dd['longitude'])
dist = math.sqrt(latpow+lonpow)
map_distance[d['number']]+=[{'id':dd['number'],'dist':dist}]
for d in map_distance:
for m in map_distance[d]:
m = min(map_distance[d], key=lambda x:x['dist'])
e = Edge(d,m['id'],False)
t.add_edge(e)
t.commit()</pre><p>Et tada ! Un bel ensemble d'îlots de stations !</p><figure class="size-medium wp-image-146 aligncenter"><a href="http://matthieu-totet.fr/Koumin/wp-content/uploads/2013/05/ParisClose.png"><img loading="lazy" alt="Paris Close Station" src="https://totetmatt.github.io/media/posts/14/ParisClose-300x300.png" sizes="(max-width: 48em) 100vw, 768px" srcset="https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-xs.png 300w, https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-sm.png 480w, https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-md.png 768w, https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-lg.png 1024w, https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-xl.png 1360w, https://totetmatt.github.io/media/posts/14/responsive/ParisClose-300x300-2xl.png 1600w" width="300" height="300"></a></figure><p></p><h1>2e idée</h1><p>Relier une station A à une station B si A et B sont distantes de moins d' 1 kilomètres</p><p><strong>/!\</strong> Pour calculer la distance entre 2 points, on utilise généralement la <strong>distance euclidienne</strong>. Ici on utilise des points génographique avec des coordonnées en degrés. Vu que la distance exprimé ne représente pas quelques chose de très commun ( une distance en degrés si je me trompe pas) et qu'on travaille sur une petite surface (on va omettre les problématiques d'<a title="Orthodromie" href="http://fr.wikipedia.org/wiki/Orthodromie">Orthodromie</a> ) je prends comme base que 0.01 Degré = 832.2m ou 1000m = 0.0120163422254266 Degré</p><pre>t = GephiStreamerManager()
with open('Paris.json', 'r') as f:
read_data = f.read()
f.closed
jdata = json.loads(read_data)
for d in jdata:
print d['number']
n= Node(d['number'],label=d['name'])
n.property['address'] = d['address']
n.property['latitude'] = d['latitude']
n.property['longitude'] = d['longitude']
t.add_node(n)
t.commit()
#0.01 = 0.8322km = 832.2m
map_distance = {}
moydis = 0
countdis = 0
for d in jdata:
map_distance[d['number']]=[]
for dd in jdata:
if dd['number'] != d['number']:
latpow = (d['latitude']-dd['latitude'])*(d['latitude']-dd['latitude'])
lonpow = (d['longitude']-dd['longitude'])*(d['longitude']-dd['longitude'])
dist = math.sqrt(latpow+lonpow)
map_distance[d['number']]+=[{'id':dd['number'],'dist':dist}]
for d in map_distance:
for m in map_distance[d]:
moydis += m['dist']
countdis +=1
if m['dist'] <= 0.0120163422254266:
e = Edge(d,m['id'],False,weight=(m['dist']/0.0120163422254266)*1000)
e.property['dist'] = (m['dist']/0.0120163422254266)*1000
t.add_edge(e)
print "Distance moyenne : %s"%(moydis/countdis)
t.commit()</pre><p>et Tada !</p><figure class="size-medium wp-image-147 aligncenter"><a href="http://matthieu-totet.fr/Koumin/wp-content/uploads/2013/05/ParisFinalMap.jpg"><img loading="lazy" alt="Paris Velib Station" src="https://totetmatt.github.io/media/posts/14/ParisFinalMap-300x300.jpg" sizes="(max-width: 48em) 100vw, 768px" srcset="https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-xs.jpg 300w, https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-sm.jpg 480w, https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-md.jpg 768w, https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-lg.jpg 1024w, https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-xl.jpg 1360w, https://totetmatt.github.io/media/posts/14/responsive/ParisFinalMap-300x300-2xl.jpg 1600w" width="300" height="300"></a></figure><p></p><p>On voit bien que le cœur des stations vélib se trouvent dans le centre de paris (pas le centre centre, il est légèrement décalé vers le nord). Néanmoins, on voit que la disposition des stations n'est pas homogène dans son ensemble, on trouve des "communautés" de stations, voir des micro-îlots (2 à 3 stations) qui sont exclus de la composante principale.</p><p>Une autre visualisation en cours de création est une réalisation que j'avais essayé de faire il y'a quelques années, et qui n'avait pas aboutit, faute d'accès trop fréquent à l'API (officieuse à l'époque :D). Il s'agit de voir l'évolution de l'occupation des stations au cours du temps via<strong> time-laps</strong>, grâce à la nouvelle <a href="https://developer.jcdecaux.com/#/opendata/vls?page=dynamic">Api temps réel</a> de JCDecaux qui nous facilite grandement l'accès aux données.</p></div><footer class="wrapper post__footer"><p class="post__last-updated">This article was updated on 20/06/20</p><ul class="post__tag"><li><a href="https://totetmatt.github.io/gephi/">Gephi</a></li><li><a href="https://totetmatt.github.io/jcdecaux/">JCDecaux</a></li><li><a href="https://totetmatt.github.io/paris/">Paris</a></li><li><a href="https://totetmatt.github.io/velib/">Vélib</a></li></ul><div class="post__share"></div><div class="post__bio bio"><div class="bio__info"><h3 class="bio__name"><a href="https://totetmatt.github.io/authors/totetmatt/" class="invert" rel="author">Totetmatt</a></h3></div></div></footer></article><nav class="post__nav"><div class="post__nav-inner"><div class="post__nav-prev"><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://totetmatt.github.io/assets/svg/svg-map.svg#arrow-prev"/></svg> <a href="https://totetmatt.github.io/timelaps-of-foursquare-activity-on-twitter.html" class="invert post__nav-link" rel="prev"><span>Previous</span> Timelaps of Foursquare activity on Twitter</a></div><div class="post__nav-next"><a href="https://totetmatt.github.io/cityviz-jcdecaux.html" class="invert post__nav-link" rel="next"><span>Next</span> Cityviz JCDecaux </a><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://totetmatt.github.io/assets/svg/svg-map.svg#arrow-next"/></svg></div></div></nav><div class="post__related related"><div class="wrapper"><h2 class="h5 related__title">You should also read:</h2><article class="related__item"><div class="feed__meta"><time datetime="2013-05-18T11:35" class="feed__date">13/05/18</time></div><h3 class="h1"><a href="https://totetmatt.github.io/cityviz-jcdecaux.html" class="invert">Cityviz JCDecaux</a></h3></article></div></div></main><footer class="footer"><div class="footer__copyright"><p>Powered by <a href="https://getpublii.com" target="_blank" rel="nofollow noopener">Publii Static CMS</a></p></div><button class="footer__bttop js-footer__bttop" aria-label="Back to top"><svg><title>Back to top</title><use xlink:href="https://totetmatt.github.io/assets/svg/svg-map.svg#toparrow"/></svg></button></footer></div><script>window.publiiThemeMenuConfig = {
mobileMenuMode: 'sidebar',
animationSpeed: 300,
submenuWidth: 'auto',
doubleClickTime: 500,
mobileMenuExpandableSubmenus: true,
relatedContainerForOverlayMenuSelector: '.top',
};</script><script defer="defer" src="https://totetmatt.github.io/assets/js/scripts.min.js?v=f4c4d35432d0e17d212f2fae4e0f8247"></script><script>var images = document.querySelectorAll('img[loading]');
for (var i = 0; i < images.length; i++) {
if (images[i].complete) {
images[i].classList.add('is-loaded');
} else {
images[i].addEventListener('load', function () {
this.classList.add('is-loaded');
}, false);
}
}</script></body></html>