web-dev-qa-db-fra.com

Quel champ de modèle utiliser dans Django pour stocker les valeurs de longitude et de latitude?

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 FloatFieldhttps://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?

51
Prometheus

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.

74
mccc

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

17
Amulya Acharya

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)
2
shacker