Power Query Retravailler un fichier JSON avec PQ

Staple1600

XLDnaute Barbatruc
Bonjour

Pour faire suite à ma discussion : Carte choroplèthe, je cherche à manipuler un fichier *.json avec PowerQuery

J'arrive bien à faire les 1ères étapes
PowerQuery:
let
    Source = Json.Document(File.Contents("C:\Users\STAPLE\Documents\communes-france.json")),
    #"Converti en table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Column1 développé" = Table.ExpandRecordColumn(#"Converti en table", "Column1", {"geo_point_2d", "geo_shape", "year", "reg_code", "reg_name", "dep_code", "dep_name", "arrdep_code", "arrdep_name", "ze2020_code", "ze2020_name", "bv2012_code", "bv2012_name", "epci_code", "epci_name", "ept_code", "ept_name", "com_code", "com_current_code", "com_name", "com_name_upper", "com_name_lower", "com_area_code", "com_type", "ze2010_name", "ze2010_code", "com_cataeu2010_code", "com_cataeu2010_name", "com_uu2010_code", "com_uu2010_status", "com_au2010_code", "com_cateaav2020_code", "com_cateaav2020_name", "com_uu2020_code", "com_uu2020_status", "com_aav2020_code", "com_cv_code", "com_in_ctu", "com_siren_code", "com_is_mountain_area"}, {"Column1.geo_point_2d", "Column1.geo_shape", "Column1.year", "Column1.reg_code", "Column1.reg_name", "Column1.dep_code", "Column1.dep_name", "Column1.arrdep_code", "Column1.arrdep_name", "Column1.ze2020_code", "Column1.ze2020_name", "Column1.bv2012_code", "Column1.bv2012_name", "Column1.epci_code", "Column1.epci_name", "Column1.ept_code", "Column1.ept_name", "Column1.com_code", "Column1.com_current_code", "Column1.com_name", "Column1.com_name_upper", "Column1.com_name_lower", "Column1.com_area_code", "Column1.com_type", "Column1.ze2010_name", "Column1.ze2010_code", "Column1.com_cataeu2010_code", "Column1.com_cataeu2010_name", "Column1.com_uu2010_code", "Column1.com_uu2010_status", "Column1.com_au2010_code", "Column1.com_cateaav2020_code", "Column1.com_cateaav2020_name", "Column1.com_uu2020_code", "Column1.com_uu2020_status", "Column1.com_aav2020_code", "Column1.com_cv_code", "Column1.com_in_ctu", "Column1.com_siren_code", "Column1.com_is_mountain_area"}),
    #"Column1.geo_point_2d développé" = Table.ExpandRecordColumn(#"Column1 développé", "Column1.geo_point_2d", {"lon", "lat"}, {"Column1.geo_point_2d.lon", "Column1.geo_point_2d.lat"}),
    #"Column1.geo_shape développé" = Table.ExpandRecordColumn(#"Column1.geo_point_2d développé", "Column1.geo_shape", {"type", "geometry", "properties"}, {"Column1.geo_shape.type", "Column1.geo_shape.geometry", "Column1.geo_shape.properties"}),
    #"Column1.geo_shape.geometry développé" = Table.ExpandRecordColumn(#"Column1.geo_shape développé", "Column1.geo_shape.geometry", {"coordinates", "type"}, {"Column1.geo_shape.geometry.coordinates", "Column1.geo_shape.geometry.type"})
in
    #"Column1.geo_shape.geometry développé"
Mais dans le tableau structuré, j'ai plusieurs colonnes avec comme valeurs : [List]

Je n'arrive pas à trouver quelles actions je dois choisir dans le ruban pour avoir dans le tableau Excel le fichier JSON correctement "interprété".

Ci-dessous le lien pour télécharger le fichier JSON ( 3 837 Ko)
fichier JSON
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Bonjour @klin89

Grâce à ta syntaxe, j'a adapté comme suit
et j'ai le contour du département
Code:
[out:json][timeout:25];
// Recherche de la relation correspondante à la ville de Rennes
area[name="Ille-et-Vilaine"]->.a;
rel(area.a)["admin_level"="6"]["boundary"="administrative"]["name"="Ille-et-Vilaine"];
// Extraction des limites de la relation
out geom;
{{style:
  node {
    width: 0;
    opacity:0;
    fill-opacity:0;
  }
}}
Et si j'importe le *.geojson obtenu, j'ai un marqueur au milieu de la carte.

Ce que j'essaie d'obtenir (juste par curiosité sur l'outil overpass turbo), c'est ce que donne les deux fichiers (quand on les importe sur un site cartographie comme celui-ci par exemple)
contour du département (dans le zip joint)
contour des communes

PS: Quelqu'un peut me dire la limite des PJ sur XLD car j'ai voulu joindre les deux fichiers dans un zip de 1305 Ko ?
=> Refus de Xenforo
 

Pièces jointes

  • ContoursD35_vide.zip
    9.5 KB · Affichages: 3

Staple1600

XLDnaute Barbatruc
Re

@klin89
Je suis avec intérêt toutes vos interventions et je dois avouer que je suis un peu largué.
Je vais redétailler ce que j'essaie de faire
1) Trouver la syntaxe M la plus simple pour importer avec PQ N fichiers *.JSON dans Excel
Dans l'idéal, une seule requête PQ (la seule chose que l'on changerait serait la source)
2) Une fois l'import dans un tableau structuré, dessinez une carte en VBA
(en passant le DataBodyRange dans un Array)

NB: On peut prendre comme source les fichiers JSON utilisés par @p56 (dans le post#39)

PS 1: J'étudie parallèlement toutes les propositions du fil
Mais certaines sont trop complexes pour mon niveau VBA.

PS 2: J'ai adapté la requête de mromain (-> source = url web)
Cela fonctionne pour le jeu de données des communes.
Il me reste à trouver comment créer une fonction personnalisée pour choisir facilement la source et comment faire pour importer les données sans se préoccuper des noms des colonnes.
(Ce qui compte, si j'ai bien compris, ce sont les latitude et longitude)
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Re

@mromain
J'essaie de trouver comment faire manuellement ce qui se fait à cet étape (dans ta requête)
ValeursExtraites = Table.TransformColumns(DonnéesRecupérées...
Je vois que tu utilises ta fonction personnalisée : fnExtractShapesCoordinates

Est-ce possible d'obtenir le même résultat en pilotant PQ avec la souris ?
 

klin89

XLDnaute Accro
Re à tous 🙂

Pour le fun, voici une requête overpass turbo qui dessine le contour des communes limitrophes à la commune de Langouet (35)
CSS:
[out:xml][timeout:25];
// Recherche de la relation correspondante aux communes limitrophes de Langouet
area["ref:INSEE"="35146"]->.a;
rel(area.a)["admin_level"="8"]["boundary"="administrative"];
out geom;
// Extraction des limites de la relation
{{style:
relation{text:name}
node{width: 0;opacity:0;fill-opacity:0;}
}}
>;
is_in;
rel(pivot)
["boundary"="administrative"] ["admin_level"="8"];
out geom;
On peut remplacer relation{text:name} par relation{text: population} qui affichera le nombre d'habitants dans les étiquettes.

Langouet35.jpg

CSS:
[out:xml][timeout:25];
// Recherche de la relation correspondante au canton de Bruz
area["ref:INSEE"="3504"]->.a;
rel(area.a)["admin_level"="8"]["boundary"="administrative"];
out geom;
// Extraction des limites de la relation
{{style:
relation{text:name}
node{width: 0;opacity:0;fill-opacity:0;}
}}
Via cette autre requête, je dessine le contour du canton de Bruz (35) (5 communes)
Bruz35.jpg


Bon dimanche,
klin89
 
Dernière édition:

mromain

XLDnaute Barbatruc
Bonjour à tous,

@Staple1600 :
J'essaie de trouver comment faire manuellement ce qui se fait à cet étape (dans ta requête)
ValeursExtraites = Table.TransformColumns(DonnéesRecupérées...
Je vois que tu utilises ta fonction personnalisée : fnExtractShapesCoordinates

Est-ce possible d'obtenir le même résultat en pilotant PQ avec la souris ?

Je ne pense pas que ce soit faisable via l'IHM car les listes présentes dans la colonne geo_shape.geometry.coordinates n'ont pas toutes la même structure.
Les listes des simples Polygon diffèrent des liste des MultiPolygon.

Après, c'est mon avis. Peut-être me trompè-je.

A+
 

Staple1600

XLDnaute Barbatruc
Bonjour @mromain

Ce qui me titille c'est comme tu obtiens Table à cet étape ?
J'ai déduis que c'était ta fonction personnalisée ? Me trompe-je ?
Ou c'est Text.Combine ?
Et comment faire la même chose si on ne disposait de ta fonction ?
(Donc par une des commandes présentes sur le ruban de PQ)
TablePQ.png
 

klin89

XLDnaute Accro
re 🙃

Après, j'arrête les essais :
Cette requête dessine le contour du dept 35 et le contour des 6 communes désignées par ref:INSEE
CSS:
[out:xml][timeout:100];
// Recherche de la relation correspondante aux 6 communes désignées
area["ref:INSEE"~"35024|35051|35059|35099|35001|35281"]->.a;

rel(area.a)["admin_level"="8"]["boundary"="administrative"];

out geom;
// Extraction des limites de la relation
>;
is_in;
rel(pivot)
["boundary"="administrative"]["ref:INSEE"="35"];
out geom;
{{style:
  node {width: 0;opacity:0;fill-opacity:0;}
}}
6_communes_du_35.jpg

Cette autre requête dessine le contour de l'arrondissement de Saint Malo et le contour de l'Ile et Vilaine;
Arrondissement_St_Malo.jpg

CSS:
[out:xml][timeout:100];
// Recherche de la relation correspondante à l'arrondissement de St Malo
area["ref:INSEE"="354"]->.a;
rel(area.a)["admin_level"="8"]["boundary"="administrative"];
out geom;
>;
is_in;
rel(pivot)
["boundary"="administrative"]["ref:INSEE"="35"];
out geom;
{{style:
  node {width: 0;opacity:0;fill-opacity:0;}
}}
J'ai essayé avec le code d'un canton mais bizarrement cela me renvoie le contour de 2 cantons, pas pigé.
Y'a plus qu'à importer le fichier JSON dans Power Query et récupérer les données géométriques, pour l'instant je ne sais pas faire.

Edit staple1600 :
Pour cacher les marqueurs, voir ci-dessous, on ne peut pas les supprimer, on peut les rendre invisible.
CSS:
{{style:
  node {width: 0;opacity:0;fill-opacity:0;}
}}

klin89
 
Dernière édition:

mromain

XLDnaute Barbatruc
Rebonjour,

@Staple1600
Ce qui me titille c'est comme tu obtiens Table à cet étape ?
J'ai déduis que c'était ta fonction personnalisée ? Me trompe-je ?
Non, c'est bien ça. La fonction prend une list en entrée et retourne une table.

Et comment faire la même chose si on ne disposait de ta fonction ?
(Donc par une des commandes présentes sur le ruban de PQ)
Comme je te le disais précédemment, je ne sais pas, et je ne suis même pas sûr que ce soit faisable car les données correspondant aux coordonnées diffèrent entre les Polygon et les MultiPolygon.

Ce qui est étrange, c'est que sur les données des cantons (ton dernier MP), les données des Poligon et des MultiPolygon ont la même structure. Du coup, là, on peut tout faire via l'IHM.
Ci-dessous un exemple. La colonne Index correspond au ShapeID :
Code:
let
    Source = Json.Document(Web.Contents("https://data.opendatasoft.com/api/explore/v2.1/catalog/datasets/canton_iev@rennes-metropole/exports/json?lang=fr&timezone=Europe%2FBerlin")),
    ToTable = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    DonnéesRecupérées = Table.ExpandRecordColumn(ToTable, "Column1", {"geo_shape", "code_canton", "nom_canton"}, {"geo_shape", "code_canton", "nom_canton"}),
    // test OK
    #"geo_shape développé" = Table.ExpandRecordColumn(DonnéesRecupérées, "geo_shape", {"geometry"}, {"geometry"}),
    // suite de la requete réalisée avec l'assistant PQ
    #"geometry développé" = Table.ExpandRecordColumn(#"geo_shape développé", "geometry", {"coordinates"}, {"coordinates"}),
    #"coordinates développé" = Table.ExpandListColumn(#"geometry développé", "coordinates"),
    #"Index ajouté" = Table.AddIndexColumn(#"coordinates développé", "Index", 1, 1),
    #"coordinates développé1" = Table.ExpandListColumn(#"Index ajouté", "coordinates"),
    #"coordinates développé2" = Table.ExpandListColumn(#"coordinates développé1", "coordinates"),
    #"Valeurs extraites" = Table.TransformColumns(#"coordinates développé2", {"coordinates", each Text.Combine(List.Transform(_, Text.From), " "), type text}),
    #"Fractionner la colonne par délimiteur" = Table.SplitColumn(#"Valeurs extraites", "coordinates", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"coordinates.1", "coordinates.2"}),
    #"Type modifié" = Table.TransformColumnTypes(#"Fractionner la colonne par délimiteur",{{"coordinates.1", type number}, {"coordinates.2", type number}})
in
    #"Type modifié"

A+
 

Staple1600

XLDnaute Barbatruc
Re

@mromain
Donc si on devait résumer quel mode opératoire "générique" on pourrait mettre en place pour traiter X fichier JSON
Au final, il faut un tableau avec
Shape_IDlatitudelongitudenom
Ici, tout a été piloté à la souris depuis PQ
PowerQuery:
let
    Source = Json.Document(Web.Contents("https://data.opendatasoft.com/api/explore/v2.1/catalog/datasets/canton_iev@rennes-metropole/exports/json?lang=fr&timezone=Europe%2FBerlin")),
    #"Converti en table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Column1 développé" = Table.ExpandRecordColumn(#"Converti en table", "Column1", {"geo_point_2d", "geo_shape"}, {"geo_point_2d", "geo_shape"}),
    #"geo_point_2d développé" = Table.ExpandRecordColumn(#"Column1 développé", "geo_point_2d", {"lon", "lat"}, {"lon", "lat"}),
    #"geo_shape développé" = Table.ExpandRecordColumn(#"geo_point_2d développé", "geo_shape", {"geometry"}, {"geometry"}),
    #"geometry développé" = Table.ExpandRecordColumn(#"geo_shape développé", "geometry", {"coordinates"}, {"coordinates"}),
    #"coordinates développé" = Table.ExpandListColumn(#"geometry développé", "coordinates"),
    #"Index ajouté" = Table.AddIndexColumn(#"coordinates développé", "Index", 1, 1),
    #"coordinates développé1" = Table.ExpandListColumn(#"Index ajouté", "coordinates"),
    #"coordinates développé2" = Table.ExpandListColumn(#"coordinates développé1", "coordinates"),
    #"Valeurs extraites" = Table.TransformColumns(#"coordinates développé2", {"coordinates", each Text.Combine(List.Transform(_, Text.From), " "), type text}),
    #"Fractionner la colonne par délimiteur" = Table.SplitColumn(#"Valeurs extraites", "coordinates", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"coordinates.1", "coordinates.2"}),
    #"Type modifié" = Table.TransformColumnTypes(#"Fractionner la colonne par délimiteur",{{"coordinates.1", type number}, {"coordinates.2", type number}})
in
    #"Type modifié"
En théorie, dans un fichier JSON, on trouve toujours geo_shape et geo_point_2d, non ?
Et ici je ne prends pas en compte les noms de colonnes.
(Donc communes ou cantons cela devrait fonctionner)
Je vais tester après mon petit frichti du soir ;)
 
Dernière édition:

mromain

XLDnaute Barbatruc
Bonjour à tous, Bonjour Staple,

Donc si on devait résumer quel mode opératoire "générique" on pourrait mettre en place pour traiter X fichier JSON
Malheureusement, je ne pense pas que ce soit faisable.

En y regardant de plus près, je me suis aperçu que les fichiers json n'ont pas la même structure : celui issu de data.bretagne.bzh (post #1) diffère de ceux générés par overpass-turbo, qui eux-mêmes diffèrent de celui généré par data.opendatasoft.com (post #54).

Par contre, chacun d'eux possède des géométries (plus ou moins bas dans l'arborescence du json) qui sont, elles, cohérentes.
Il s'agit à chaque fois d'un record nommé geometry contenant un type (Polygon, MultiPolygon, Point, ...) et des coordinates.

Du coup, j'ai retouché la fonction et l'ai renommé fnExtractGeometryInfos afin qu'elle prenne en entrée le record geometry et qu'elle retourne la table contenant le ShapeID, la Longiture et la Latitude pour les géométries de type Polygon et MultiPolygon.
PowerQuery:
(geometry as record) as table =>
let
    fnExtractPointsCoordinates = (list as list) as list => List.Transform(list{1}{0}, each [ShapeID = list{0}, Longitude=_{0}, Latitude=_{1}]),
    shapesList = 
        let 
            list = geometry[coordinates],
            listCount = List.Count(list),
            geoType = geometry[type]
        in 
            if geoType = "Polygon" then {{1, geometry[coordinates]}} else if geoType = "MultiPolygon" then List.Zip({{1 .. listCount}, list}) else {},
    shapeCoordinates = List.Combine(List.Transform(shapesList, fnExtractPointsCoordinates)),
    toTable = if List.Count(shapeCoordinates) > 0 then Table.FromRecords(shapeCoordinates) else #table({"ShapeID", "Longitude", "Latitude"}, {}),
    changeTypes = Table.TransformColumnTypes(toTable,{{"ShapeID", Int64.Type}, {"Longitude", type number}, {"Latitude", type number}})
in
    changeTypes

Cette fonction semble donc marcher avec les différents fichiers json/geojson qu'on a vu sur ce fil. Il ne reste plus qu'à adapter la navigation dans les fichier avant d'appeler la fonction :
  • avec un export de overpass-turbo (testé avec l'export du post #32 - emplacement du fichier à adapter) :
    PowerQuery:
    let
        fnExtractGeometryInfos = (geometry as record) as table =>
            let
                fnExtractPointsCoordinates = (list as list) as list => List.Transform(list{1}{0}, each [ShapeID = list{0}, Longitude=_{0}, Latitude=_{1}]),
                shapesList = 
                    let 
                        list = geometry[coordinates],
                        listCount = List.Count(list),
                        geoType = geometry[type]
                    in 
                        if geoType = "Polygon" then {{1, geometry[coordinates]}} else if geoType = "MultiPolygon" then List.Zip({{1 .. listCount}, list}) else {},
                shapeCoordinates = List.Combine(List.Transform(shapesList, fnExtractPointsCoordinates)),
                toTable = if List.Count(shapeCoordinates) > 0 then Table.FromRecords(shapeCoordinates) else #table({"ShapeID", "Longitude", "Latitude"}, {}),
                changeTypes = Table.TransformColumnTypes(toTable,{{"ShapeID", Int64.Type}, {"Longitude", type number}, {"Latitude", type number}})
            in
                changeTypes,
    
        Source = Json.Document(File.Contents("C:\...\export.geojson")),
        RecupFeatures = Source[features],
        ToTable = Table.FromList(RecupFeatures, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        ExpandDatas = Table.ExpandRecordColumn(ToTable, "Column1", {"properties", "geometry"}, {"properties", "geometry"}),
        ExpandProperties = Table.ExpandRecordColumn(ExpandDatas, "properties", {"ref:INSEE", "name"}, {"ref:INSEE", "name"}),
        TransformShapesCoordonates = Table.TransformColumns(ExpandProperties,{{"geometry", fnExtractGeometryInfos, type table}}),
        ExpandShapesCoordonates = Table.ExpandTableColumn(TransformShapesCoordonates, "geometry", {"ShapeID", "Longitude", "Latitude"}, {"ShapeID", "Longitude", "Latitude"})
    in
        ExpandShapesCoordonates
  • avec data.bretagne.bzh :
    PowerQuery:
    let
        fnExtractGeometryInfos = (geometry as record) as table =>
            let
                fnExtractPointsCoordinates = (list as list) as list => List.Transform(list{1}{0}, each [ShapeID = list{0}, Longitude=_{0}, Latitude=_{1}]),
                shapesList = 
                    let 
                        list = geometry[coordinates],
                        listCount = List.Count(list),
                        geoType = geometry[type]
                    in 
                        if geoType = "Polygon" then {{1, geometry[coordinates]}} else if geoType = "MultiPolygon" then List.Zip({{1 .. listCount}, list}) else {},
                shapeCoordinates = List.Combine(List.Transform(shapesList, fnExtractPointsCoordinates)),
                toTable = if List.Count(shapeCoordinates) > 0 then Table.FromRecords(shapeCoordinates) else #table({"ShapeID", "Longitude", "Latitude"}, {}),
                changeTypes = Table.TransformColumnTypes(toTable,{{"ShapeID", Int64.Type}, {"Longitude", type number}, {"Latitude", type number}})
            in
                changeTypes,
    
        Source = Json.Document(Web.Contents("https://data.bretagne.bzh/api/explore/v2.1/catalog/datasets/communes-france/exports/json?lang=fr&facet=facet(name%3D%22reg_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22dep_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22arrdep_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22ze2020_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22bv2012_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22epci_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22ept_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22com_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22ze2010_name%22%2C%20disjunctive%3Dtrue)&facet=facet(name%3D%22com_is_mountain_area%22%2C%20disjunctive%3Dtrue)&refine=dep_name%3A%22Ille-et-Vilaine%22&timezone=Europe%2FBerlin")),
        ToTable = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        ExpandDatas = Table.ExpandRecordColumn(ToTable, "Column1", {"com_code", "com_name", "geo_shape"}, {"com_code", "com_name", "geo_shape"}),
        ExpandComCode = Table.TransformColumns(ExpandDatas, {"com_code", each Text.Combine(List.Transform(_, Text.From)), type text}),
        ExpandComName = Table.TransformColumns(ExpandComCode, {"com_name", each Text.Combine(List.Transform(_, Text.From)), type text}),
        ExpandGeometries = Table.ExpandRecordColumn(ExpandComName, "geo_shape", {"geometry"}, {"geometry"}),
        TransformShapesCoordonates = Table.TransformColumns(ExpandGeometries,{{"geometry", fnExtractGeometryInfos, type table}}),
        ExpandShapesCoordonates = Table.ExpandTableColumn(TransformShapesCoordonates, "geometry", {"ShapeID", "Longitude", "Latitude"}, {"ShapeID", "Longitude", "Latitude"})
    in
        ExpandShapesCoordonates
  • Avec data.opendatasoft.com :
    PowerQuery:
    let
        fnExtractGeometryInfos = (geometry as record) as table =>
            let
                fnExtractPointsCoordinates = (list as list) as list => List.Transform(list{1}{0}, each [ShapeID = list{0}, Longitude=_{0}, Latitude=_{1}]),
                shapesList = 
                    let 
                        list = geometry[coordinates],
                        listCount = List.Count(list),
                        geoType = geometry[type]
                    in 
                        if geoType = "Polygon" then {{1, geometry[coordinates]}} else if geoType = "MultiPolygon" then List.Zip({{1 .. listCount}, list}) else {},
                shapeCoordinates = List.Combine(List.Transform(shapesList, fnExtractPointsCoordinates)),
                toTable = if List.Count(shapeCoordinates) > 0 then Table.FromRecords(shapeCoordinates) else #table({"ShapeID", "Longitude", "Latitude"}, {}),
                changeTypes = Table.TransformColumnTypes(toTable,{{"ShapeID", Int64.Type}, {"Longitude", type number}, {"Latitude", type number}})
            in
                changeTypes,
    
        Source = Json.Document(Web.Contents("https://data.opendatasoft.com/api/explore/v2.1/catalog/datasets/canton_iev@rennes-metropole/exports/json?lang=fr&timezone=Europe%2FBerlin")),
        ToTable = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        ExpandDatas = Table.ExpandRecordColumn(ToTable, "Column1", {"code_canton", "nom_canton", "geo_shape"}, {"code_canton", "nom_canton", "geo_shape"}),
        ExpandGeometries = Table.ExpandRecordColumn(ExpandDatas, "geo_shape", {"geometry"}, {"geometry"}),
        TransformShapesCoordonates = Table.TransformColumns(ExpandGeometries,{{"geometry", fnExtractGeometryInfos, type table}}),
        ExpandShapesCoordonates = Table.ExpandTableColumn(TransformShapesCoordonates, "geometry", {"ShapeID", "Longitude", "Latitude"}, {"ShapeID", "Longitude", "Latitude"})
    in
        ExpandShapesCoordonates

Du coup, pas de fonction générique pour traiter n'importe quel fichier json, mais une fonction générique pour extraire les coordonnées des géométries.

A+
 

Staple1600

XLDnaute Barbatruc
Bonjour le fil, @mromain

Impressionnant !👏

Ne connaissant pas bien les fonctions personnalisées, j'ai une petite question.
Est-ce qu'on peut stocker quelque part la fonction fnExtractGeometryInfos pour ne pas devoir la dupliquer dans chaque requête ?

Est-ce que cela se fait avec Gérer/Référence ?

Autre question:
Pourquoi dans une requête existante, si on fait Nouvelle Source et qu'on copie/colle une nouvelle URL, cela n'actualise pas la requête mais en créé une nouvelle ?

Maintenant je m'attelle au dessin des Shapes
PS: @mromain: ton exemple qui passe avec Powerpoint (avec des modules de classe) est trop complexe pour moi.
Mais je l'ai gardé au chaud pour l'étudier plus tard. ;)
 

mromain

XLDnaute Barbatruc
Bonsoir Staple,

Ne connaissant pas bien les fonctions personnalisées, j'ai une petite question.
Est-ce qu'on peut stocker quelque part la fonction fnExtractGeometryInfos pour ne pas devoir la dupliquer dans chaque requête ?

Est-ce que cela se fait avec Gérer/Référence ?
C'est faisable oui. Pour ce, il faut mettre le premier code de mon précédent post dans une requête.
Je te joins un fichier exemple. La requête OverpassTurbo ne fonctionnera pas en l'état, il faut adapter l'emplacement du fichier au niveau de la Source.

Pourquoi dans une requête existante, si on fait Nouvelle Source et qu'on copie/colle une nouvelle URL, cela n'actualise pas la requête mais en créé une nouvelle ?
En fait, Nouvelle Source veut dire "nouvelle requête à partir d'une source".
Le comportement est donc normal...

Bonne soirée
 

Pièces jointes

  • Exemple.xlsx
    27.9 KB · Affichages: 2

Staple1600

XLDnaute Barbatruc
Bonsoir @mromain

Merci pour ce fichier

Pourquoi Overpass Turbo généré des fichiers JSON plus volumineux ?
(526669 lignes vs 85451 lignes pour databretagne)
Les deux concernent pourtant les 333 communes du département 35

PS: Une fois 3 requêtes chargées , le classeur passe à 24 751 Ko.
Je crois que je vais un classeur par requete car quand la carte sera dessinée, Excel risque de tousser ;)

Bonne soirée et merci encore pour ton support et ton savoir poweresque ;)
 

mromain

XLDnaute Barbatruc
Bonjour à tous, Bonjour Staple,

Pourquoi Overpass Turbo généré des fichiers JSON plus volumineux ?
(526669 lignes vs 85451 lignes pour databretagne)
Les deux concernent pourtant les 333 communes du département 35
C'est juste une histoire de "précision" des cartes.

Par exemple, si on considère la commune de Saint-Malo :
  • sur overpass-turbo, elle est composée de 26 formes, pour un total de 3620 coordonnées ;
  • sur data.bretagne.bzh, elle est composée de 7 formes, pour un total de 653 coordonnées.

Le rendu diffère donc un peu :
Saint-Malo.png


A+
 

Membres actuellement en ligne

Statistiques des forums

Discussions
314 628
Messages
2 111 337
Membres
111 105
dernier inscrit
Joffrette