Changer l’écran d’un Kindle 4

J’adore la liseuse d’Amazon, j’ai été un des premiers acquéreurs et elle m’a permis de me remettre à lire. Ca ne prend pas de places et cela supporte pas mal de bouquins pour les vacances, les transports en commun, les files d’attentes, …

Par contre, c’est fragile…

Lire la suite

Introduction aux shapefile

Une utilisation cartographique

En voulant m’intéresser à titre personnel aux données cartographiques, j’ai téléchargé sur le site de l’IGN la base de données Route 500, disponible sous licence ouverte. Cette base de données contient les données de 500 000 km de routes en France métropolitaine.

L’archive (161 Mo compressés, 857 décompressés) contient plusieurs descriptifs et des métadonnées, je ne les ai pas consultés entièrement mais je salue l’initiative de joindre des descriptifs. Qui n’a jamais téléchargé  une archive au nom obscur  et oublié distraitement son utilité plusieurs mois plus tard ? Clignement d'œil

Je ne savais pas du tout à quoi m’attendre comme format de fichier en téléchargeant cette base, uniquement l’indication “format Shapefile”.  En fouillant différents dossiers, dont je présumais que l’arborescence n’avais pas beaucoup d’importance, j’ai repéré non pas différents fichiers mais plusieurs ensembles de fichiers. En effet, chaque “fichier” semblait en fait constitué de plusieurs fichiers aux noms identiques mais  aux extensions différentes (cpg, dbf, prj, shp et shx). Aucune de ces extensions ne m’était connue, et en tant que curieux bien trop hâtif, je me suis bien entendu précipité pour essayer de lire ces fichiers au plus vite avec un éditeur de texte, bien entendu sans avoir lu la moindre documentation au préalable. Seulement, avec un éditeur de texte, seuls les fichiers prj et cpg étaient lisibles, les différents cpg contenant toujours “1252” et les différents prj contenant à chaque fois un ensemble de constantes semblables à des sortes de référentiels géographiques. Quant aux autres fichiers, les plus volumineux, ils étaient illisibles (partiellement pour les dbf et totalement pour les shx et shp). Je n’ai donc pas pu éviter de lire dans un premier temps un bref descriptif encyclopédique puis une documentation complète.

Le format

Contenu général

Habitué à parser du json, du xml, des csv ou d’autres formats simples, le format shapefile m’a beaucoup surpris au départ ! Tout d’abord, comme énoncé plus haut, il n’est non pas composé d’un fichier, ni de deux, mais de trois fichiers (minimum)! Ensuite, il est quasiment impossible (mis à part pour le fichier dbf où on devine des chaines de caractères) de lire les fichiers principaux avec un éditeur de texte. En effet, le format datant des années 90, plusieurs centaines de mégaoctets de données représentaient une empreinte de stockage important, il était alors surement impensable de stocker des données sous forme de texte brut. En prenant simplement l’exemple d’un nombre entier, celui-ci sera stocké dans exactement 4 octets en format binaire au lieu de jusqu’à 10 octets en encodage de texte brut. Ainsi, il est totalement impossible de parser le fichier sans documentation. Néanmoins celle ci n’est pas très compliquée à comprendre.

Le fichier le plus important, celui contenant les formes en elles-mêmes, le shp, est constitué de deux parties. La première partie est un en-tête de taille fixe contenant différentes métadonnées comme un type de géométrie, un nombre d’objet présent et une taille par objet. Il suffit donc ensuite de lire le fichier par blocs de taille indiquée, pour trouver le nombre préconisé d’objet au format opportun.

L’endianisme

Le premier point du format qui m’a beaucoup surpris (et mit un petit moment en difficulté) est l’endianisme. Pour ceux qui ne connaissent pas ce terme ni sa traduction anglaise (endianess), cela correspond au sens de lecture de nombres quand ceux-ci ont sur plusieurs octets. Vu qu’un exemple vaut mille discours, imaginez un nombre entier codé sur 4 octets : 0x1A2B3C4D, qui, si on le découpe en octets, se présentera pour un développeur ainsi :

Poids de l’octet 3 2 1 0
Octet 1A 2B 3C 4D

Le premier octet ainsi rencontré est l’octet de poids-fort, ce sens est appelé “Big-endian”. Celui ci à l’avantage de se lire “naturellement” pour un humain mais a l’inconvénient de devoir être lu en commençant par la fin pour une machine. Pour palier à ce problème à l’ère des premiers processeurs, certains systèmes d’exploitation ont alors implémenté le “Little-endian”, c’est à dire la lecture des octets en commençant par celui de poids faible et terminant par ceux de poids forts. Le même nombre en little-endian sera noté ainsi : 4D3C2B1A.

Poids de l’octet 0 1 2 3
Octet 4D 3C 2B 1A

Le problème qu’a le format shapefile avec l’endianisme n’est pas qu’il en utilise un différent de celui de ma machine (Windows sur x86 étant en little-endian), mais qu’il utilise les deux ! En effet, les octets de 0 à 27 du début du fichier sont composés de 7 entiers notés en big-endian puis sont suivis de deux entiers et 8 décimaux notés en…little endian ! De même pour chaque enregistrement du fichier, l’en-tête sera en big-endian alors que les enregistrements eux-mêmes sont composés d’entiers ou de décimaux en little-endian ! Il m’a donc fallu adapter les méthodes de lectures de nombres pour spécifier l’endianisme….

La projection

Il m’est venu ensuite un problème de projection vis à vis des coordonnées. Ce problème n’est pas directement lié au format shape, mais plutôt son utilisation par l’IGN et l’administration française. En effet, nous avons l’habitude d’utiliser des coordonnées dans le système WGS83 (pour World Geodetic System 1983) sous forme de degrés géographiques, ou plus communément appelées “coordonnées GPS”. Ici, les fichiers fournis présentent des données dans la projection cartographiques Lambert 93. Pour faire simple et rapide : je n’ai tout simplement pas réussi à faire la conversion, malgré de la documentation, pourtant en français, je n’arrive pas à implémenter le calcul…

Mis à part cela, une fois les en-têtes de fichiers et d’enregistrement décodés, il suffit d’implémenter la lecture des différents types de données présents, une dizaine en tout mais toujours un seul type dans un même fichier. Ce format n’est ni nouveau, ni complexe et son utilisation est répandue, maitriser son utilisation ne présente pas un gros avantage technologique. Néanmoins, implémenter tous le format peut être assez long pour une seule personne donc autant partager ce code. J’en ai donc profité pour créer un repository (en C#) sur GitHub ! N’hésitez pas à aller  voir mon code, me faire des retours, voire participer (surtout si vous-mêmes ou une de vos connaissance sait convertir des coordonnées Lambert 93 en WGS83…).

Pour la documentation des fichiers shape : ici (et un complément ici pour les fichiers dBASE). Et, encore une fois, si par chance l’un de vous saurait m’aider à implémenter ce calcul,qu’il se fasse connaitre Clignement d'œil

Par Mathieu Hollebecq

Enregistrer

Hey le dév ! t’as pas un 06 ?

Vous êtes chasseurs de têtes ? Vous voulez faire craquer tous les développeurs ? Vous voulez augmenter votre reach ? Ces conseils sont pour vous !

Lire la suite

Héberger ses packages sur Visual Studio Online

Depuis Novembre 2015, Visual Studio Online permet de gérer l’hébergement de packages au travers d’un service nuget. Voyons comment cela fonctionne.

Lire la suite

Visual Studio 2013 + Mumble = Patatra !

Lors d’une récente session de dev sous Visual Studio 2013, et pour discuter tranquillement avec des amis, j’ai lancé en simultané le logiciel Mumble. Seulement, dès le démarrage de Visual Studio, quasiment rien de l’interface graphique ne se rafraîchissait. Par exemple, lorsque je survolais les menus avec la souris, je ne voyais pas le « hover » sur les éléments du menu mais si je cliquais le menu s’affichait bien. De même, la fenêtre des propriétés marchait parfaitement bien lorsque je cliquais sur un élément dans l’explorateur de solution mais je ne voyais pas la sélection dans ce dernier. Et le pire étant dans la fenêtre de code, rien de ce que je tapais ne s’affichait, sauf lorsque je redimensionnais Visual Studio.
Pour mieux illustrer, un autre développeur ayant eu le même problème a fait une vidéo sur Youtube :

Apres avoir changé de thème, recherché des potentielles mise à jour correctrices et redémarré le pc, j’ai eu l’idée de tester de couper Mumble et là… MIRACLE ! Tous fonctionnait à nouveau ! En ajoutant « Mumble » à ma recherche sur le net, j’ai trouvé une solution plus précise : desactiver l’overlay de Mumble, celui qui s’affiche en haut à droite de l’écran pour indiquer les personnes en ligne.

En espérant que cet article permettent à d’autres personnes de ne pas rester bloqués trop longtemps.

Mathieu Hollebecq

Obtenir des MaidSafeCoins en 4 étapes

MaidSafe est une entité qui est en train de mettre au point un « nouvel internet » totalement décentralisé et anonyme. Un projet réellement ambitieux mais qui peut rendre internet vraiment anonyme et faciliter la persistance d’une information.
Ce système se base sur une monnaie, les MaidSafeCoins qui sont indexés sur l’espace de stockage mis à disposition par les utilisateurs du réseau. Voyons comment acheter des MaidSafeCoins.

Lire la suite

Obtenir des bitcoins en France

Nous allons voir dans cet article comment acheter des bitcoins de manière sécurisée en étant français avec des euros.
Cet article sera purement technique, et a pour vocation d’expliquer la procédure d’achat des premiers bitcoins plutôt que la philosophie derrière.

Lire la suite

L’API Streaming de Twitter avec le HttpClient .net

La recherche et le streaming

Un des fonctionnalités intéressantes de l’API Twitter est l’utilisation du Streaming. Tout comme la recherche, cette API nous permet de spécifier un mot clé et de récupérer les tweets liés à ce mot clé. Cet article a pour but de vous montrer la différence entre la recherche et le streaming sur l’API Twitter ainsi que l’implémentation de ce streaming en C#.

La différence entre l’API de recherche et l’API de streaming réside en la manière de récupérer les tweets. Avec la première, vous envoyez une requête au serveur Twitter qui vous retourne alors page par page les tweets correspondant à la recherche dans une seule et même réponse. Le fonctionnement est celui d’un échange client-serveur classique :


(crédits image : https://dev.twitter.com )

Principe du streaming

Concernant le streaming, les tweets retournés ne vont pas l’être dans une seule et même réponse. En effet le serveur maintiendra la connexion indéfiniment et dès qu’un nouveau tweet concerné par la recherche faite va être soumis à Twitter, celui ci va nous être retourné dans la foulée. Ce cas d’utilisation est notamment intéressant dans des applications de type “live tweet” :

(crédits image : https://dev.twitter.com )

Implémentation en C#

L’url de requête sera https://stream.twitter.com/1.1/statuses/filter.json en POST. A cela s’ajoute un ou plusieurs paramètres. Pour une utilisation de base, nous ajouterons le paramètre “track” qui aura comme valeur votre recherche (un hashtag ou tout simplement un mot ).

Cette requête ne semble pas compliquée, mais l’extrait de code suivant, qui fonctionne dans le cas d’une simple recherche, va ici échouer. Le souci ne vient pas directement de ce code mais de la librairie OAuth que j’avais réalisée suite à un de mes précédents articles (code source disponible en une seule classe ici : https://skydrive.live.com/?cid=230FED47B214039C&id=230FED47B214039C%212851 )

static async void ComputeStreaming(string search)
{
    OAuthRequester.ComputeHmacSha1 = ComputeHMACSHA1Hash;
    string consumerKey = "yourConsumerKey";
    string consumerSecret = "yourConsumerSecret";
    string oauthToken = "yourOAuthToken";
    string oAuthTokenSecret = "yourTokenSecret";
    string searchUrl = 
"https://stream.twitter.com/1.1/statuses/filter.json"; Dictionary<string, string> contentParams = new Dictionary<string, string>(); contentParams.Add("track", search); var searchRequest = OAuthRequester.SignRequest(HttpMethod.Post,
searchUrl, consumerKey, consumerSecret, contentParams,
oauthToken, oAuthTokenSecret);
using (StreamReader reader = new StreamReader(
await (await searchRequest).Content.ReadAsStreamAsync())) { while (!reader.EndOfStream) { string result = reader.ReadLine(); JObject root = JObject.Parse(result); Console.WriteLine(root["text"].ToString()); } } }

Il n’y pas forcément d’erreur de conception dans ma librairie, l’erreur serait similaire avec l’utilisation de “WebClient” ou “WebHttpRequest”. De la même manière, la requête sera lancée, mais rien ne sera renvoyé et au bout d’une minute, vous recevrez un timeout. Le souci provient de la manière dont HttpClient traite la réponse par défaut, le client a bien commencé à recevoir la réponse, mais il attend d’avoir reçu tous le contenu avant de renvoyer votre objet “HttpResponseMessage”. Or, le principe du streaming est de laisser la connexion ouverte et de recevoir le contenu au fur et à mesure, donc HttpClient ne peut pas gérer le cas de figure de cette manière. Mais, heureusement, il suffit d’une petite modification pour gérer le cas particulier des réponses sous forme de flux et non de sous forme de contenu entier. Il suffit de modifier l’appel de la méthode “client.SendAsync(…)”, dans notre cas, nous utiliserons la surcharge suivante:

HttpResponseMessage response = await client.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead);

La différence réside en l’ajout du paramètre de type “HttpCompletionOption” qui, s’il est omis, prend par défaut la valeur “ResponseContentRead” qui signifie que HttpClient attend de recevoir tout le contenu de la réponse avant de la traiter. La valeur qui nous intéresse ici est “ResponseHeaderRead” qui signifie que la réponse sera traitée dès que les header seront reçus. Le contenu en lui même sera reçu plus tard, lors de l’appel de “ReadAsStreamAsync()”. Avec la modification de la requête, vous pouvez à présent tester le code un peu plus haut qui fonctionnera cette fois-ci (testez avec un sujet populaire du moment pour voir le streaming agir ).

Conclusion

Parfois complexe à utiliser dans certains SDK, l’API streaming de Twitter consiste en une simple requête en POST. La seule petite difficulté est de ne pas attendre de recevoir tous le contenu pour traiter la requête comme le font par défaut les clients HTTP en .net mais de la traiter dès réception des headers. HttpClient permet ce traitement particulier avec la modification du paramètre HttpCompletionOption.
La mise à jour de la classe helper OAuth 1.0 est disponible ici.

Par Mathieu Hollebecq

Récupérer une session perdue sous firefox

Je suis un grand fan des onglets mais il arrive que Firefox crashe inopinément et me perde ma 100aine de sites que je dois regarder…

Mais on peut heureusement les récupérer !

Sous Windows (et uniquement sous Windows)

Attention : Si vous aviez plusieurs fenêtres ouvertes et que vous avez fermé par inadvertance la mauvaise, vous pouvez peut-être encore tenter de cliquer sur “historique” dans le menu (appuyez sur la touche alt pour l’ouvrir) puis “fenêtres récemment fermées”. Sinon, si c’est dû à un caprice de firefox après fermeture, essayez la procédure suivante :

1. Fermez Firefox

2. Rendez-vous dans votre dossier AppData/Roaming/Mozilla/Firefox/Profiles ou entrez directement %APPDATA%/Mozilla/Firefox/Profiles dans la barre d’adresse de l’explorer.

image

3. Ensuite ouvrez le répertoire au nom bizarre : xxxxx.default.

Et cherchez un fichier répondant au nom de sessionstore.bak. Vérifiez que le contenu correspond bien à vos onglets en l’ouvrant avec un éditeur de texte (clic droit / Ouvrir avec…). Si ce n’est pas les bons sites, cherchez le fichier sessionstore.bak le plus récent (il peut y en avoir plusieurs).

4. Copiez-le dans un endroit sûr au cas-où puis renommez-le en sessionstore.js

5. Réouvrez Firefox, vos onglets devrez être là ! Dans ce cas, vous pouvez supprimer la copie faite au point 4 (Ne touchez plus au sessionstore.js !)

6. Partagez cet article, vous sauverez sûrement d’autres personnes !

PS : Si vous ne trouvez malheureusement pas votre sessionstore dans ce répertoire, il est possible que vous n’ayez pas choisi de conserver vos onglets, ou que votre version de firefox soit trop vieille. Dans ce cas, je suis désolé, cet article ne pourra vous aider plus…

Par JCVASSELON

[Windows 8] Réimplémenter le RemoveBackEntry

Dans le cas d’un projet, il me fallait empêcher le retour sur la page précédente mais revenir sur une page particulière. Exemple : MainPage –> Page Sommaire –> Page 1 –> Page 2 –> Page 3
Le bouton précédent depuis les pages 1 à 3 devait me ramener sur la page Sommaire.

Ma première réflexion a été d’utiliser le GoBack juste avant de naviguer vers la page suivante. Sur PC, ce retour en arrière ne se voyait pas mais sur une tablette ARM, le chargement de la page précédente puis de la suivante était flagrant et inésthétique.

J’ai donc cherché le RemoveBackEntry comme il existe sur Windows Phone pour supprimer la page précédente, mais malheureusement il n’existe pas en WinRT… Mais il est possible de manipuler la pile de navigation !

Manipuler la pile de navigation

La méthode GetNavigationState d’un objet Frame nous permet de récupérer la pile de navigation sérialisée sous forme de string tandis que SetNavigationState nous permet de la modifier.

Avertissement

La documentation du GetNavigationState, le précise bien. Il est formellement déconseillé de le faire, cette méthode est utilisée en interne et la manière de sérialiser peut être modifiée par Microsoft dans une version future de Windows. Son usage permet actuellement de stocker la page courante de l’utilisateur lors de la fermeture de l’application et de le ramener sur cette page à la prochaine ouverture.

Autre point, la déserialisation est impossible si vous passez des objets entre 2 pages. Ce système ne marchera que si vous faites une navigation basique d’une page à une autre. Si vous souhaitez passer des objets utilisez des Messengers ou simplement un Cache, mais ce n’est pas le sujet de l’article.

Mettons les mains dans le cambouis

La méthode GetNavigationState() va nous retourner une chaîne sous cette forme :

1,3,2,31,MonNamespace.MainPage,12,0,40,MonNamespace.Sommaire,0,33,MonNamespace.Page1,0

Découpons la chaînes et expliquons chaque partie :

1,3,2 :

  • 1, je ne sais pas… Certainement le signalement du début de la chaîne
  • 3, correspond au nombre de pages dans la pile
  • 2, à l’id de la page courante

31, MonNamespace.MainPage, 12, 0

  • 31 correspond à l’id du type de la page chargée
  • MonNamespace.MainPage est le type de la page chargée
  • 12, aucune idée, ce nombre n’est présent que dans l’ensemble lié à la 1ère page
  • 0, je pense que c’est le séparateur entre chaque page, on le retrouve à la fin de chaque page chargée

40,MonNamespace.Sommaire,0

  • 40 correspond à l’id du type de la page chargée
  • MonNamespace.Sommaire est le type de la page chargée
  • 0, idem que précédemment

Vous avez compris la structure. L’idée est donc, pour supprimer le dernier élément, de le retirer de la chaîne de caractère, et de décrémenter l’ID de la page courante ainsi que le nombre de pages chargées.

Pour cela, je me suis créé une méthode d’extension à la classe Frame :

public static classFrameExtension
{
public static void RemoveBackEntry(thisFrameframe)
{
varparts = frame.GetNavigationState().Split(‘,’);
varcount =Int32.Parse(parts[1]);

if(count > 1)
{
parts[1] = (
int.Parse(parts[1]) – 1).ToString();
parts[2] = (
int.Parse(parts[2]) – 1).ToString();
varstate =String.Join(« , », parts, 0, parts.Length – 3);

frame.SetNavigationState(state);
}
}
}

Quelques précisions

Il nous suffit donc de faire un this.Frame.RemoveBackEntry pour supprimer la dernière page visitée de notre pile de navigation. L’appel sur GoBack() nous ramènera sur la page encore précédente. Exemple : MainPage –> SommairePage-> Page1->RemoveBackEntry->Page2. Depuis la page 2, GoBack nous ramènera sur SommairePage.

Attention, l’appel du SetNavigationState() lance une navigation vers la page courante (normal vu qu’il doit être appelé au démarrage de l’application pour repositionner l’utilisateur sur la page sur laquelle il était) du coup, le “OnNavigatedTo” de votre page sera appelé en mode GoBack, pensez-y si vous avez un comportement bizarre.

Par JCVASSELON