¿Convertir dataset de alta precisión en geodatabase de archivos a baja precisión usando ArcObjects?

8

Se cargó un conjunto de datos de alta precisión desde una geodatabase de archivos en arcsde 9.3.1. La carga de datos se logró mediante copiar / pegar en ArcCatalog.

Una herramienta personalizada (arcobjects) que extrae del conjunto de datos a una geodatabase personal de baja precisión ahora falla al intentar crear la clase de entidad de salida.

No es factible actualizar la geodatabase personal a alta precisión ya que todos los demás conjuntos de datos que extrae de sde son de baja precisión.

¿Se puede degradar el conjunto de datos de alta precisión?

nef001
fuente
¿ha considerado crear un nuevo conjunto de datos de baja precisión y luego importar los datos de alta precisión? Esto podría automatizarse aún más con el generador de modelos.
Jakub Sisak GeoGraphics
Buscando una manera de evitar la recarga ya que el conjunto de datos es muy grande, pero puede ser la única forma.
nef001
Por precisión, ¿quiere decir precisión numérica (por ejemplo, float16 vs float32) o detalles en el conjunto de datos?
Paul Hiemstra
Cuando ESRI lanzó 9.3, introdujeron las llamadas referencias espaciales de alta precisión y proporcionaron herramientas para actualizar las geodatabases anteriores a 9.3 a alta precisión. Pero no puede extraer un conjunto de datos de alta precisión a una geodatabase de baja precisión.
nef001
En realidad era 9.2
nef001

Respuestas:

2

Terminé resolviendo esto modificando el código de extracción personalizado para tener en cuenta la precisión de las referencias espaciales de origen y destino.

Código:

        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
fuente
1

Siempre mantengo los datos antiguos de Esri ArcTutor para las versiones de ArcGIS 9.0 / 9.1 / 9.2. Las geodatabases utilizadas son de baja precisión y siempre puedo usarlas como plantilla para la importación / exportación de datos cuando necesito cambiar la precisión. Hable con sus representantes de Esri o eche un vistazo a sus unidades compartidas de software, tal vez encuentre algunos datos antiguos de ArcTutor o quizás geodatabases de ArcGIS antiguas que podrían servir para este propósito.

Alex Tereshenkov
fuente
-1

Bueno, si hay un lugar decimal en el número, digamos 10.343243, podría usar la función izquierda ({column name}, #preserved) en la base de datos de atributos de arcmap. Dándole 10.343, que sería menos preciso.

Si el número es 10343243, podría usar la misma función nuevamente, solo agregando ceros nuevamente al número después de la función inicial. Una especie de redondeo rudimentario.

¿Tener sentido?

Thad
fuente
Gracias, pero esta pregunta se relaciona con la precisión de las referencias espaciales de ESRI en geodatabases.
nef001