Je travaille avec des données cartographiques et le Latitude/Longitude
s'étend jusqu'à 8 décimales. Par exemple:
Latitude 40.71727401
Longitude -74.00898606
J'ai vu dans le document Google Qui utilise:
lat FLOAT( 10, 6 ) NOT NULL,
lng FLOAT( 10, 6 ) NOT NULL
cependant, leurs décimales ne vont pas jusqu'à 6.
Devrais-je utiliser FLOAT(10, 8)
ou existe-t-il une autre méthode à considérer pour stocker ces données afin qu'elles soient précises Il sera utilisé avec les calculs de carte. Merci!
DECIMAL est le type de données MySQL pour l'arithmétique exacte. Contrairement à FLOAT, sa précision est fixe pour toute taille de nombre. Ainsi, en l’utilisant à la place de FLOAT, vous éviterez les erreurs de précision lors de certains calculs. Si vous ne faites que stocker et récupérer les nombres sans calcul, alors dans la pratique, FLOAT serait sûr, bien que l'utilisation de DECIMAL ne présente aucun danger. Avec des calculs, FLOAT est toujours correct, mais il faut être absolument sûr de 8d.p. précision, vous devez utiliser DECIMAL.
Les latitudes varient de -90 à +90 (degrés), donc DECIMAL (10, 8) convient, mais les longitudes vont de -180 à +180 (degrés), vous avez donc besoin de DECIMAL (11, 8). Le premier nombre correspond au nombre total de chiffres enregistrés et le second au nombre situé après le point décimal.
En bref: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL
Ceci explique le fonctionnement de MySQL avec les types de données à virgule flottante.
De plus, vous verrez que les valeurs float
sont arrondies.
// exemple: valeurs données 41.0473112,29.0077011 float (11,7) | décimal (11,7) --------------------------- 41.0473099 | 41.0473112 29.0077019 | 29.0077011
Vous pouvez définir votre type de données comme entier signé. Lorsque vous stockez les coordonnées dans SQL, vous pouvez définir lat * 10000000 et long * 10000000. Et lorsque vous sélectionnez distance/rayon, vous divisez les coordonnées de stockage en 10000000. Je l’ai testé avec 300 000 lignes, le temps de réponse à la requête est bon. (2 x CPU 2,67 GHz, 2 Go de RAM, MySQL 5.5.49)
N'utilisez pas de float ... Il arrondira vos coordonnées, ce qui entraînera des événements étranges.
Utilisez décimal
en laravel utilisé colonne décimale type pour la migration
$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);
pour plus d'informations voir type de colonne disponible
La meilleure façon dans mon cas était de sauvegarder les coordonnées en tant que DOUBLE.
lat DOUBLE NOT NULL,
lng DOUBLE NOT NULL
Cela économisera la valeur entière sans arrondir.
Si vous devez arrondir la valeur, mon conseil est que ce traitement est effectué à l'origine des données, par exemple dans l'interface utilisateur.
MySQL supporte maintenant les types de données spatiales depuis que cette question a été posée. La réponse acceptée actuellement n’est donc pas fausse, mais si vous recherchez des fonctionnalités supplémentaires, telles que la recherche de tous les points d’un polygone donné, utilisez le type de données POINT.
Consultez la documentation Mysql sur les types de données géospatiales et les fonctions d'analyse spatiale
Utiliser Migration de Ruby on Rails
class CreateNeighborhoods < ActiveRecord::Migration[5.0]
def change
create_table :neighborhoods do |t|
t.string :name
t.decimal :latitude, precision: 15, scale: 13
t.decimal :longitude, precision: 15, scale: 13
t.references :country, foreign_key: true
t.references :state, foreign_key: true
t.references :city, foreign_key: true
t.timestamps
end
end
end
Je pense que le meilleur moyen de stocker Lat/Lng dans MySQL est d’avoir une colonne POINT (type de données 2D) avec un index SPATIAL.
CREATE TABLE `cities` (
`Zip` varchar(8) NOT NULL,
`country` varchar (2) GENERATED ALWAYS AS (SUBSTRING(`Zip`, 1, 2)) STORED,
`city` varchar(30) NOT NULL,
`centre` point NOT NULL,
PRIMARY KEY (`Zip`),
KEY `country` (`country`),
KEY `city` (`city`),
SPATIAL KEY `centre` (`centre`)
) ENGINE=InnoDB;
INSERT INTO `cities` (`Zip`, `city`, `centre`) VALUES
('CZ-10000', 'Prague', POINT(50.0755381, 14.4378005));