Konversi dataset presisi tinggi dalam file geodatabase ke presisi rendah menggunakan ArcObjects?

8

Dataset presisi tinggi dimuat dari file geodatabase ke arcsde 9.3.1. Dataload dicapai dengan menyalin / menempel di ArcCatalog.

Alat khusus (arcobjects) yang mengekstrak dari dataset ke geodatabase pribadi presisi rendah sekarang gagal ketika mencoba untuk membuat kelas fitur output.

Tidak layak untuk meningkatkan geodatabase pribadi ke presisi tinggi karena semua dataset lain yang diekstrak dari sde adalah presisi rendah.

Bisakah dataset presisi tinggi diturunkan?

nef001
sumber
sudahkah Anda mempertimbangkan untuk membuat dataset baru, presisi rendah, kemudian mengimpor data presisi tinggi ke dalamnya? Ini dapat diotomatisasi lebih lanjut dengan pembuat model.
Jakub Sisak GeoGraphics
Mencari cara untuk menghindari memuat ulang karena dataset sangat besar, tetapi mungkin satu-satunya cara.
nef001
Secara presisi, maksud Anda numeric precison (misalnya float16 vs float32) atau detail dalam dataset?
Paul Hiemstra
Ketika ESRI merilis 9.3 mereka memperkenalkan apa yang disebut referensi spasial presisi tinggi dan menyediakan alat untuk meningkatkan pra-9.3 geodatabases ke presisi tinggi. Tetapi Anda tidak dapat mengekstrak dataset presisi tinggi ke geodatabase presisi rendah.
nef001
Sebenarnya itu 9,2
nef001

Jawaban:

2

Saya akhirnya menyelesaikan ini dengan memodifikasi kode ekstraksi khusus untuk memperhitungkan ketepatan referensi spasial sumber dan tujuan.

Kode:

        public ISpatialReference createDestinationSpatialRef(IGeoDataset srcDataset, IFeatureWorkspace destinationWorkspace)
        {
            ISpatialReference result = srcDataset.SpatialReference;
            IControlPrecision2 sourceDatasetPrecision = result as IControlPrecision2;

            if (sourceDatasetPrecision.IsHighPrecision)
            {
                if (geodatabaseSupportsHighPrecision(destinationWorkspace))
                {
                    // HP to HP, no conversion
                }
                else
                {
                    IEnvelope extent = srcDataset.Extent;
                    result = ConvertSpatialReferenceFromHighToLowPrecision(result, extent);
                }
            }
            else
            {
                if (geodatabaseSupportsHighPrecision(destinationWorkspace))
                {
                    result = ConvertSpatialReferenceFromLowToHighPrecision(result, -1, 0, 0);
                }
                else
                {
                    // LP to LP, no conversion
                }
            }

            return result;
        }

        public bool geodatabaseSupportsHighPrecision(IFeatureWorkspace fws)
        {
            IGeodatabaseRelease2 release = fws as IGeodatabaseRelease2;
            // geodatabase release is numbered 2.2 at 9.2
            return ((release != null) && ((release.MajorVersion + 7) >= 9) && (release.MinorVersion >= 2));
        }



        /// <summary>
        /// Converts an existing low precision spatial reference and returns a new high precision spatial reference.
        /// </summary>
        /// <param name="lowSpatialReference">An ISpatialReference interface that is the low spatial reference to be converted.</param>
        /// <param name="xyDoubler">A System.Int32 that is the amount of doubling (2^x) based on the input resolution; -1 produces a value close to the default resolution. Example: -1</param>
        /// <param name="mDoubler">A System.Int32 that determines doubling of m-resolution based on input m-resolution; the default is 0. Example: 0</param>
        /// <param name="zDoubler">A System.Int32 that determines doubling of z-resolution based on input z-resolution; default is 0. Example: 0</param>
        /// <returns>An ISpatialReference interface that is the new high precision spatial reference.</returns>
        public ISpatialReference ConvertSpatialReferenceFromLowToHighPrecision(ISpatialReference lowSpatialReference, int xyDoubler, int mDoubler, int zDoubler)
        {
            IControlPrecision2 controlPrecision2 = lowSpatialReference as IControlPrecision2;
            if (controlPrecision2.IsHighPrecision)
                throw new ArgumentException("Expected a low precision spatial reference.", "lowSpatialReference");

            ISpatialReferenceFactory3 spatialReferenceFactory3 = new SpatialReferenceEnvironmentClass();
            ISpatialReference highSpatialReference = spatialReferenceFactory3.ConstructHighPrecisionSpatialReference(lowSpatialReference, xyDoubler, zDoubler, mDoubler);
            return highSpatialReference;
        }


        /// <summary>
        /// Converts an existing high precision spatial reference and returns a new low precision spatial reference.
        /// </summary>
        /// <param name="highSpatialReference">An ISpatialReference interface that is a high precision spatial reference.</param>
        /// <param name="envelope">An IEnvelope that is the area covering the extent of the new low precision spatial reference.</param>
        /// <returns>An ISpatialReference interface that is the new low precision spatial reference.</returns>
        public ISpatialReference ConvertSpatialReferenceFromHighToLowPrecision(ISpatialReference highSpatialReference, IEnvelope envelope)
        {
            IControlPrecision2 controlPrecision2 = highSpatialReference as IControlPrecision2;
            if (!controlPrecision2.IsHighPrecision)
                throw new ArgumentException("Expected a high precision spatial reference.", "highSpatialReference");
            ISpatialReference lowSpatialReference = null;

            ISpatialReferenceFactory3 spatialReferenceFactory3 = new SpatialReferenceEnvironmentClass();
            try
            {
                lowSpatialReference = spatialReferenceFactory3.ConstructLowPrecisionSpatialReference(true, highSpatialReference, envelope);
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                if (ex.ErrorCode == -2147220986)
                {
                    lowSpatialReference = spatialReferenceFactory3.ConstructLowPrecisionSpatialReference(false, highSpatialReference, envelope);
                }
            }
            return lowSpatialReference;
        }
nef001
sumber
1

Saya selalu menyimpan data Esri ArcTutor lama untuk versi ArcGIS 9.0 / 9.1 / 9.2. Geodatabases yang digunakan memiliki presisi rendah dan saya selalu dapat menggunakannya sebagai templat untuk impor / ekspor data ketika saya perlu mengubah presisi. Bicaralah dengan perwakilan Esri Anda atau lihat drive bersama perangkat lunak Anda, mungkin Anda akan menemukan beberapa data ArcTutor lama atau mungkin geodatabase ArcGIS lama yang dapat berfungsi untuk tujuan ini.

Alex Tereshenkov
sumber
-1

Nah jika ada tempat desimal dalam angka tersebut, katakanlah 10.343243 Anda bisa menggunakan fungsi left ({nama kolom}, #preserved) dalam database atribut arcmap. Memberi Anda 10.343, yang akan kurang tepat.

Jika angkanya 10343243 Anda dapat menggunakan fungsi yang sama lagi, hanya menambahkan nol kembali ke angka setelah fungsi awal. Semacam pembulatan yang belum sempurna.

Masuk akal?

Ini
sumber
Terima kasih tetapi pertanyaan ini berkaitan dengan ketepatan referensi spasial ESRI di geodatabases.
nef001