Le Problème
Je vais essayer un nouvel acronyme ici - B2G - Business To GIS - signifiant la livraison de données gérées en externe dans ArcGIS. Il est très courant que des systèmes externes ("business") offrent une API REST que vous pouvez appeler pour obtenir des données au format commun comme JSON, mais il est aussi très courant que le serveur livre un jeu de données en plusieurs morceaux (c'est-à-dire "pages"), et que le JSON ne soit pas dans un dialecte bien défini comme GeoJSON - vous devez l'analyser en colonnes, potentiellement à partir d'objets struct ou array.
Ce post concerne la conquête des deux défis de la pagination et de l'analyse, sans codage, en utilisant ArcGIS Data Interoperability.
Mes données sujettes sont les données de plaintes clients de la Federal Communications Commission concernant les appels indésirables, filtrées pour 2024. Si vous voulez voir à quoi ressemble le JSON entrant cliquez ici pour 1000 enregistrements aléatoires, mais voici le résultat final sous forme de service de fonctionnalités :
FCC Customer Complaints - unwanted calls
Quelques recherches révèlent qu'il existe plusieurs approches courantes de pagination :
- Paramètres offset et limit définissant la position de départ et le nombre de lignes, lecture des données ordonnées.
- Cette approche peut inclure un autre paramètre pour quelle propriété définit l'ordre de tri
- Numéro de page et (optionnellement) taille de page.
- Pagination basée sur une requête, où une ligne de départ est définie par une requête logique, impliquant toute requête suivante.
- Requête basée sur le temps, un cas spécial de pagination basée sur une requête.
- Pagination basée sur un curseur, où l'API fournit les noms des pages, y compris toute page suivante, dans le résultat.
- Combinaisons des précédents.
Les deux premières approches sont les plus simples (et les seules que j'ai utilisées), le serveur effectue les calculs de construction des pages et le client n'a qu'à suivre un compteur simple, envoyant des requêtes jusqu'à ce que les données soient épuisées.
Voici un exemple d'API basée sur offset et limit et ici un exemple d'API basée sur page.
Pour un exemple du #6, combinant #3 & #4, vous pouvez lire sur la requête des couches de services d'entités hébergées. ArcGIS s'occupe de construire les requêtes pour vous.
Et l'analyse simplifiée ? Nous devons transformer des enregistrements comme celui-ci en colonnes typées et géométrie !
{
"issue_type" : "Phone",
"caller_id_number" : "830-210-2001",
"state" : "IL",
"method" : "Wired",
"advertiser_business_phone_number" : "None",
"issue_time" : "8:41 am",
"issue" : "Unwanted Calls",
"zip" : "60629",
"type_of_call_or_messge" : "Live Voice",
"issue_date" : "2024-01-04T00:00:00.000",
"id" : "3739134",
"location_1" : {
"latitude" : "41.781382",
"human_address" : "{\"address\": \"\", \"city\": \"IL\", \"state\": \"\", \"zip\": \"60629-5219\"}",
"needs_recoding" : false,
"longitude" : "-87.732853"
}
}
Pas de problème ! Commençons.
Pagination
Nous appelons ici une API REST, qui offre une réponse paginée. Dans ArcGIS Data Interoperability cela signifie appeler le transformateur HTTPCaller en boucle, dans ce cas avec les paramètres offset, limit et order, incrémentant la valeur offset à chaque appel, jusqu'à ce que toutes les données soient reçues et que la réponse soit un tableau vide. Vous ne saviez peut-être pas que vous pouvez boucler dans un environnement de programmation visuelle, mais c'est possible, et c'est facile. Le transformateur personnalisé vert menthe « UnwantedCallsLooper » près du coin supérieur gauche dans mon espace de travail fait ce travail. C'est un transformateur personnalisé en boucle.
Espace de travail ETL parent
Le transformateur personnalisé est intégré (inclus) dans la toile principale, il vit dans son propre onglet éponyme. Vous créez des transformateurs personnalisés en sélectionnant un ou plusieurs transformateurs ordinaires dans la toile principale puis un menu contextuel accessible par clic droit offre une option de création de transformateur personnalisé. Dans mon cas j'ai sélectionné juste un seul transformateur HTTPCaller.
Après avoir créé le transformateur personnalisé, il y a eu d'autres étapes d'édition pour configurer la boucle :
- Ajouter une connexion retour boucle via une option du menu contextuel dans la toile
- Ajouter un test d'achèvement avant le retour boucle
- Incrémenter le paramètre offset
Voici à quoi ressemble mon transformateur personnalisé. Au moment de l'exécution chaque entité arrivant depuis la toile principale a un attribut offset utilisé par le transformateur HTTPCaller. Les paramètres limit et order ne changent pas donc sont « codés en dur » dans HTTPCaller. Le flux inférieur est la condition loop-until - si la réponse n'est pas un tableau vide alors les données ne sont pas épuisées, donc incrémentez l'offset et bouclez !
Transformateur personnalisé en boucle
Analyse
Chaque réponse API est un tableau de structures JSON contenu dans un attribut nommé « _response_body ». Le tableau est éclaté en entités séparées avec un JSONFragmenter. Le paramètre JSON Query signifie simplement que nous fragmentons le tableau du niveau supérieur et les autres réglages assurent juste la livraison des fragments qui ressemblent au bloc de code ci-dessus.
JSONFragmenter
Maintenant nous analysons chaque entité fragment avec un JSONExtractor.
JSONExtractor
La grille Extract Queries définit les noms des attributs en sortie et d'où proviennent les données dans le fragment. Le Les requêtes JSON sont basées sur une syntaxe simple que vous pouvez saisir, mais il existe une astuce simple pour obtenir un sélecteur qui vous permet de naviguer dans la structure JSON et d'automatiser la génération de requêtes. Avant le JSONExtractor, échantillonnez temporairement une seule entité et écrivez-la dans un fichier, puis définissez temporairement votre source d'entrée JSONExtractor sur ce fichier et vous obtiendrez un sélecteur pratique pour vos requêtes ! Une fois que vous avez rempli vos requêtes d'extraction, supprimez le Sampler et réinitialisez la source d'entrée de votre JSONFragmenter pour qu'elle soit le document dans _response_body.<\/P>
Voilà qui démystifie la pagination et l'analyse ! Dans le téléchargement du blog, il y a deux fichiers source workspace fmw. CreateFC crée une sortie de géodatabase fichier et c'est là que j'ai compris le traitement des données, comme la correction des erreurs de données qui empêchaient la création d'un champ datetime. Je voulais de toute façon une classe d'entités initiale pour symboliser et partager comme mon service d'entités hébergé cible. UpdateFS emprunte les étapes de traitement des données dans CreateFC mais contient le transformateur personnalisé en boucle et une certaine logique pour détecter et appliquer les modifications des données chaque fois que l'outil ETL est exécuté, ce dont vous aurez probablement besoin en production.<\/P>
Veuillez commenter ce post avec toutes questions et observations. Paginer sans modération !<\/P>
<\/P>