Je veux stocker l'emplacement de mes utilisateurs en utilisant la longitude et la latitude, pour le moment cela vient de Google Maps, mais j'utiliserai GeoDango et un certain point pour calculer également les distances entre les points.
Cependant, ma première confusion est le champ dans Django que je devrais utiliser pour stocker les valeurs de longitude et de latitude? Les informations que je reçois sont en conflit.
La documentation officielle utilise un FloatField
https://docs.djangoproject.com/en/dev/ref/contrib/gis/tutorial/#geographic-models
lon = models.FloatField()
lat = models.FloatField()
Où presque toutes les réponses sur stackoverflow montrent un DecimalField
long = models.DecimalField(max_digits=8, decimal_places=3)
lat = models.DecimalField(max_digits=8, decimal_places=3)
Alors, que dois-je utiliser?
Float est généralement une approximation, voir ici pour quelques exemples simples. Vous pourriez obtenir des résultats très agréables en modifiant votre modèle en quelque chose comme DecimalField(max_digits=9, decimal_places=6)
, car les décimales sont très importantes en coordonnées mais utiliser plus de 6 n'a pratiquement aucun sens.
Utilisez PointField pour stocker lat long
p = Point(85.3240, 27.7172,srid=4326)
Django: 1.X:
https://docs.djangoproject.com/en/1.11/ref/contrib/gis/model-api/#pointfield
Django: 2.X:
https://docs.djangoproject.com/en/2.2/ref/contrib/gis/model-api/#pointfield
La suggestion ici d'utiliser DecimalField(max_digits=9, decimal_places=6)
a entraîné des erreurs pour moi lorsque j'essaie d'enregistrer des positions à partir de Google Maps.
Si nous supposons que le cas d'utilisation le plus courant consiste à récupérer des emplacements de points à partir de l'API Maps et une URL typique de Google Maps lorsque vous cliquez avec le bouton droit et sélectionnez "Qu'est-ce que c'est ici?" donne quelque chose comme:
https://www.google.com/maps/place/37°48'52.3"N+122°17'09.1"W/@37.814532,-122.2880467,17z
(endroit aléatoire)
La longitude a donc 15 positions avant et après la décimale, c'est pourquoi la réponse acceptée ne fonctionne pas. Puisqu'il n'y a aucune raison de valider pour "aussi court que possible" et que le stockage db est bon marché, j'utilise:
max_digits=22,
decimal_places=16)