Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

A high precision dataset was loaded from a file geodatabase into arcsde 9.3.1. The dataload was achieved by copy/paste in ArcCatalog.

A custom tool (arcobjects) that extracts from the dataset to a low precision personal geodatabase is now failing when attempting to create the output feature class.

It is not feasible to upgrade the personal geodatabase to high precision since all the other datasets it extracts from sde are low precision.

Can the hp dataset be downgraded?

share|improve this question
    
have you consider creating a new, low precision, dataset then importing the the high precision data into it? This could be further automated with model builder. –  Jakub Nov 9 '11 at 15:40
    
Looking for a way to avoid reloading since the dataset is so large, but it may be the only way. –  nef001 Nov 9 '11 at 15:53
    
By precision, do you mean numerical precison (e.g. float16 vs float32) or detail in the dataset? –  Paul Hiemstra Dec 31 '11 at 11:09
    
When ESRI released 9.3 they introduced so-called high precision spatial references and provided tools to upgrade pre-9.3 geodatabases to high precision. But you can't extract a high precision dataset to a low precision geodatabase. –  nef001 Jan 20 '12 at 13:31
    
Actually it was 9.2 –  nef001 Jan 20 '12 at 14:14

3 Answers 3

up vote 1 down vote accepted

I ended up solving this by modifying the custom extraction code to take into account the precision of source and destination spatial refs.

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;
        }
share|improve this answer

Well if there is a decimal place in the number, say 10.343243 you could just use left({column name}, #preserved) function in arcmap attribute database. Giving you 10.343, which would be less precise.

If the number is 10343243 you could use the same function again, only adding zeros back into the number after the initial function. Sort of a rudimentary rounding.

Make sense?

share|improve this answer
    
Thanks but this question relates to the precision of ESRI spatial references in geodatabases. –  nef001 Jan 20 '12 at 14:43

I always keep old Esri ArcTutor data for ArcGIS 9.0/9.1/9.2 versions. The geodatabases used are of low precision and I can always use them as template for data import/export when I need to change the precision. Talk to your Esri reps or take a look at your software shared drives, perhaps you will find some old ArcTutor data or maybe old ArcGIS geodatabases which could serve for this purpose.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.