Api Platform : générer directement un format geojson

Le problème exposé dans ce sujet a été résolu.

Hello ! J’avance sur mon petit projet perso consistant notamment à placer des points sur une carte. J’ai mes données correctes en BDD, j’ai une carte Mapbox prête à les recevoir. Maintenant, je cherche à exporter mes données au format GeoJson (uniquement GET), et je me demandais si un pro d’API Platform par ici pourrait m’indiquer si il y a moyen de directement dire à Api Platform de me sortir une liste directement au bon format, ce qui éviterait de devoir retraiter les données ultérieurement.

Voilà le type de données attendues par MapBox:

places: { "type": "FeatureCollection", "features": [ //Point 1 { "type": "Feature", "geometry": { "type": "Point", "coordinates": [..., ...] }, "properties": { "id": "", "name": "...", //autres données potentiellement utiles } }, //Point 2, etc. {}, {}, ] }

(pardon pour la mise en page médiocre, mais vous voyez le principe ?) Je ne trouve aucun résultat probant sur internet contenant le format geojson et api platform, ce qui me pousserait à penser que je suis à côté de la plaque dans ma démarche. Je dois créer mon propre format de "Content Negotiation" comme ici https://api-platform.com/docs/core/content-negotiation/ ou bien il y a un moyen plus simple ?

Merci pour vos conseils.

Attends attends attends. Je voudrais revenir sur ta dernière phrase, là…Je n’ai pas dû bien comprendre ce qu’était le GeoJson, il me semblait que c’était juste un formatage des données ?

Parce qu’en BDD, j’ai par exemple une table "places", qui contient notamment des champs id, name, latitude, longitude, etc. J’utilise déjà des Calculated Fields sur certains champs, comme pour générer des "coordinates" sous forme d’Array à partir des latitudes et longitudes. Bref, tout est prêt dans cette table ! Là par défaut, Api Platform me sort une liste d’objets JSON classique (format Hydra), c’est juste transformer cette liste en format GeoJson qui m’intéressait de base…

Qu’est-ce que tu veux dire par "stocker directement […] en base" ? Quelle forme ça aurait ? Quel type de table/champ ?

Je ne sais pas si j’ai vraiment cerné ton problème mais créer une entité suivant le schéma GeoJSON ne te convient pas ?
EDIT : J’ai relu et compris ton problème. Dans tous les cas il faudra bien dire à API Platform la structure que tu souhaites.
Le Content Negociation n’est pas la bonne solution, comme dit plus haut par viki53 le GeoJSON reste du JSON.
Il faut créer une entité GeoJSON. Ensuite je vois deux solutions :

  • Si aucune raison ne justifie le contraire, au moment de l’écriture on peut stocker les données directement sous la bonne structure (donc l’entité GeoJSON)
  • Sinon au moment de la sortie, on peut utiliser les Data Transfer Objects (DTOs) ou une Custom Operation par exemple.

Également je te conseille de ne pas foncer tête baissée concernant le stockage de données géographiques. Il faut lister ses besoins dans un premier temps. Par exemple, comptes-tu faire des recherches du type "récupérer tous les points à moins de 5km de la coordonnée (X,Y)" ?

+0 -0

Pardon, je n’ai pas eu d’alerte sur ton message ! Désolé de ne pas avoir répondu plus tôt.

Mes "Places" stockées en BDD servent à la fois à être affichées sur une carte Mapbox - les coordonnées sont donc indispensables, et oui, à termes, à "récupérer tous les points à moins de X km" de l’utilisateur - et à générer une page d’info détaillant la "Place" cliquée. Ces deux actions ne vont pas chercher les mêmes infos dans la BDD : la liste utilisée pour la carte ne prend que les champs utiles pour l’affichage : les coordonnées, le nom, une photo, et en gros de quoi générer le lien vers la page dédiée à cette "Place" et utiliser un système simple de filtres. Sur la page dédiée, il y a toutes les autres infos de la Place. La liste utilisée doit a priori être générée à chaque fois, les Places changeant régulièrement, et l’utilisateur devant théoriquement utiliser les filtres pour afficher uniquement ce qui l’intéresse.

Il s’avère qu’entre temps j’ai eu des tas de soucis techniques pénibles liés sans doute à l’ordre de chargement de la page : le GeoJson que j’ai fini par réussir à créer (en trichant avec Javascript en attendant de trouver une solution avec API Platform) n’était pris en compte que si il était chargé avant la carte. Pas réussi à mettre en place le chargement d’une source avec l’API Mapbox de base. J’ai ensuite trouvé sur GitHub Vue-Mapbox qui en simplifie l’usage. Au lieu d’un fichier GeoJson, je peux dorénavant juste fournir un Array, et Vue me crée les Markers. Pour l’instant j’en suis à tâcher de juger l’efficacité du script et voir si un système de filtres fonctionne sur les Markers. A suivre, donc.


Pour revenir sur le stockage en GeoJson, histoire d’être sûr de comprendre : je créerais une table à part, type 'geojson-places" avec un seul champ de type json contenant l’ensemble des données de chaque Place ? C’est ça ?

Créer un objet dans API Platform ne signifie pas forcément qu’il faudra stocker ses instances en base de données !
Ici, l’idée c’est de créer l’objet GeoJSON qui sera construit à partir de l’objet Place (qui lui par contre est stocké en bdd).

Pour gérer les futures requêtes du type "récupérer les lieux dans un rayon de 5km" je te conseille de regarder si ton SGBD ne possède pas une fonctionnalité pour traiter les données géographiques comme PostGIS pour PostgreSQL par exemple. Ensuite, il faudra créer une Custom Doctrine ORM Extension puis un Custom Filter pour l’utiliser. Même si cela peut paraître long et compliqué à mettre en place, tu ne le regretteras pas quand le projet gagnera en complexité !

Pfiou. Je vois. Merci pour toutes ces précisions. Pas sûr d’avoir le niveau, toutefois. Enfin si, potentiellement, mais vu que je suis tout seul sur toute cette partie, ça va me prendre une petite éternité, tellement j’ai de points à régler. Allez, courage, moi.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte