Konvertieren eines hochpräzisen Datasets in einer Datei-Geodatabase mit ArcObjects in eine niedrigpräzise Datenmenge?


8

Ein hochpräziser Datensatz wurde aus einer Datei-Geodatabase in arcsde 9.3.1 geladen. Das Laden der Daten wurde durch Kopieren / Einfügen in ArcCatalog erreicht.

Ein benutzerdefiniertes Tool (ArcObjects), das aus dem Dataset in eine persönliche Geodatabase mit geringer Genauigkeit extrahiert, schlägt jetzt fehl, wenn versucht wird, die Ausgabe-Feature-Class zu erstellen.

Es ist nicht möglich, die persönliche Geodatabase auf hohe Genauigkeit zu aktualisieren, da alle anderen Datensätze, die aus sde extrahiert werden, eine geringe Genauigkeit aufweisen.

Kann der hochpräzise Datensatz herabgestuft werden?


Haben Sie darüber nachgedacht, ein neues Dataset mit geringer Genauigkeit zu erstellen und dann die hochpräzisen Daten in dieses zu importieren? Dies könnte mit Model Builder weiter automatisiert werden.
Jakub Sisak GeoGraphics

Suchen Sie nach einer Möglichkeit, ein erneutes Laden zu vermeiden, da das Dataset so groß ist, aber dies ist möglicherweise die einzige Möglichkeit.
nef001

Mit Präzision meinen Sie die numerische Präzision (z. B. float16 vs float32) oder Details im Datensatz?
Paul Hiemstra

Als ESRI 9.3 veröffentlichte, führten sie sogenannte hochpräzise räumliche Referenzen ein und stellten Werkzeuge zur Verfügung, um Geodatabases vor 9.3 auf hohe Präzision zu aktualisieren. Sie können jedoch kein hochpräzises Dataset in eine niedrigpräzise Geodatabase extrahieren.
nef001

Eigentlich war es 9.2
nef001

Antworten:


2

Am Ende habe ich dieses Problem gelöst, indem ich den benutzerdefinierten Extraktionscode geändert habe, um die Genauigkeit der räumlichen Quellen- und Zielreferenzen zu berücksichtigen.

Code:

        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;
        }

1

Ich behalte immer alte Esri ArcTutor-Daten für ArcGIS 9.0 / 9.1 / 9.2-Versionen. Die verwendeten Geodatabases sind von geringer Genauigkeit und ich kann sie immer als Vorlage für den Datenimport / -export verwenden, wenn ich die Genauigkeit ändern muss. Sprechen Sie mit Ihren Esri-Vertretern oder sehen Sie sich Ihre gemeinsam genutzten Software-Laufwerke an. Möglicherweise finden Sie alte ArcTutor-Daten oder alte ArcGIS-Geodatabases, die für diesen Zweck dienen könnten.


-1

Wenn die Zahl eine Dezimalstelle enthält, z. B. 10.343243, können Sie einfach die Funktion left ({Spaltenname}, #reserved) in der arcmap-Attributdatenbank verwenden. Ich gebe Ihnen 10.343, was weniger genau wäre.

Wenn die Nummer 10343243 lautet, können Sie dieselbe Funktion erneut verwenden und erst nach der ursprünglichen Funktion wieder Nullen in die Nummer einfügen. Eine Art rudimentäre Rundung.

Sinn ergeben?


Vielen Dank, aber diese Frage bezieht sich auf die Genauigkeit von ESRI-Raumreferenzen in Geodatabases.
nef001
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.