Ganda atau desimal untuk nilai lintang / bujur di C #

97

Apa tipe data terbaik untuk digunakan saat menyimpan data geopositional di C #? Saya akan menggunakan desimal untuk ketepatannya, tetapi operasi pada bilangan desimal floating point lebih lambat dari bilangan biner floating point (ganda).

Saya membaca bahwa sebagian besar waktu Anda tidak memerlukan lebih dari 6 atau 7 digit ketepatan untuk lintang atau bujur. Apakah ketidaktepatan dua kali lipat itu penting atau dapatkah diabaikan?

KRTac
sumber
6
Saya akan mengajukan pertanyaan sebaliknya: Apakah perbedaan kinerja itu penting atau dapatkah itu diabaikan?
Heinzi
1
Dalam database, Anda harus menggunakan "tipe data spasial sql" untuk menyimpan bujur dan lintang
azhar_SE_nextbridge
8
Perhatikan bahwa .NET BCL sendiri menggunakan dua kali lipat dalam kelas GeoCoordinate , yang merupakan indikasi kuat bahwa presisi mungkin cukup.
Heinzi
1
TzdbZoneLocation NodaTime menggunakan double juga.
Rick Davin
4
1) Saya akan mempertimbangkan titik tetap. 2) Karena Anda sering perlu melakukan operasi trigonometri pada koordinat geografis, dan itu hanya diterapkan untuk double, doublemungkin paling cocok.
CodesInChaos

Jawaban:

120

Untuk itu double, ada beberapa alasan.

  • Fungsi trigonometri hanya tersedia untuk ganda
  • Presisi ganda (kisaran 100 nanometer) jauh melampaui apa pun yang Anda perlukan untuk nilai Lintang / Bujur
  • Kelas GeoCoordinate dan modul Pihak ketiga (misalnya DotSpatial ) juga menggunakan ganda untuk koordinat
Wernfried Domscheit
sumber
75

Ganda memiliki presisi hingga 15 digit desimal. Jadi, mari kita asumsikan tiga dari angka tersebut akan berada di sebelah kiri koma desimal untuk nilai lintang / bujur (maksimal 180 derajat). Ini menyisakan 12 digit presisi di sebelah kanan. Karena derajat lintang / bujur adalah ~ 111km, 5 dari 12 digit tersebut akan memberi kita presisi pada pengukur. 3 digit lagi akan memberi kita presisi ke milimeter. 4 digit sisanya akan membuat kita presisi menjadi sekitar 100 nanometer. Karena dobel akan menang dari perspektif kinerja dan memori, saya tidak melihat alasan untuk mempertimbangkan penggunaan desimal.

MarkPflug
sumber
2
Ditambah satu untuk penjelasan rinci dan tepat.
Najeeb
4

Saya menghadapi pertanyaan ini beberapa waktu yang lalu ketika saya mulai dengan pemrograman spasial. Saya membaca sebuah buku beberapa waktu lalu yang membawa saya pada hal ini.

//sql server has a really cool dll that deals with spacial data such like
//geography points and so on. 
//add this namespace
Using Microsoft.SqlServer.Types;

//SqlGeography.Point(dblLat, dblLon, srid)

var lat_lon_point = Microsoft.SqlServer.Types.SqlGeography.Point(lat, lon, 4326);

Ini adalah cara terbaik saat bekerja di aplikasi Anda dengan data spasial. kemudian untuk menyimpan data gunakan ini di sql

CREATE TABLE myGeoTable
{
LatLonPoint GEOMETRY 
}

lain, jika Anda menggunakan sesuatu yang lain yang bukan sql, cukup ubah titik menjadi heksadesimal dan simpan. Saya tahu setelah sekian lama menggunakan spasial bahwa ini adalah yang paling aman.

Jonny
sumber
Saya kesulitan menemukan LatLonPoint, referensi atau paket apa yang harus Anda sertakan atau 'penggunaan' apa dalam proyek c # Anda? (dengan asumsi buat tabel adalah untuk model Identitas / kode c #, karena jenis itu juga tidak mengevaluasi di SSMS). Terima kasih sebelumnya!
Chris
1

Dua kali lipat

Menggabungkan jawaban itu adalah bagaimana Microsoft merepresentasikan dirinya di perpustakaan SqlGeography

[dapatkan: Microsoft.SqlServer.Server.SqlMethod (IsDeterministic = true, IsPrecise = true)] publik System.Data.SqlTypes.SqlDouble Lat {get; } Nilai Properti SqlDouble A SqlDouble nilai yang menentukan garis lintang.

alex.peter
sumber