Global Mapper Pro

Generating Contour Layers (Success) then exporting that layer as a Shape file (Fails)

codemouse
codemouse Global Mapper UserTrusted User
edited August 2010 in SDK
In C#.

Can generate contour layers successfully, but then when I send the contour layer handle to export vector, it returns an error:

GlobalMapperInterface
Unable to open ˆc÷ for export.
OK

or some other strange chars after "open" and before "for".
Code for ExportShapeFile:

        private void ExportShapeFile(IntPtr layerHandle, GM_LayerInfo_t layerInfo)   
        {
            var filename = "c:\\test\\test.shp";

            var vectorExportFormat = GM_VectorExportFormat_t32.GM_Export_Shapefile;

            var vectorExportFlags = GM_VectorExportFlags_t32.GM_VectorExportFlags_ExportLines;

            var rectangle = new GM_Rectangle_t
            {
                mMaxX = layerInfo.mGlobalRect.mMaxX,
                mMaxY = layerInfo.mGlobalRect.mMaxY,
                mMinX = layerInfo.mGlobalRect.mMinX,
                mMinY = layerInfo.mGlobalRect.mMinY
            };

            uint formatOptions = 0;

            _lastGmError = GlobalMapper.GM_ExportVector(ref filename, vectorExportFormat, layerHandle, ref rectangle, vectorExportFlags, formatOptions);
        }

Code for generating contour layers prior to this step (via imported ASCII file):
private IntPtr GenerateContoursLayer(IntPtr asciiLayerHandle, GM_LayerInfo_t asciiLayerInfo)
        {
            IntPtr contoursLayerHandle;

            float contourInterval;
            var elevationRange = asciiLayerInfo.mMaxElevation - asciiLayerInfo.mMinElevation;
            if (elevationRange < 200.0)
                contourInterval = 5;
            else if (elevationRange < 400.0)
                contourInterval = 10;
            else if (elevationRange < 800.0)
                contourInterval = 20;
            else if (elevationRange < 1000.0)
                contourInterval = 25;
            else if (elevationRange < 2000.0)
                contourInterval = 50;
            else if (elevationRange < 4000.0)
                contourInterval = 100;
            else
                contourInterval = 200;

            var contourParameters = new GM_ContourParams_t
            {
                mSize = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(typeof(GM_ContourParams_t)),
                mDesc = "Generated Contours",
                mContourBounds = new GM_Rectangle_t(),
                mContourInterval = contourInterval,
                mIntervalInFeet = 0,
                mGenerateAreas = 0,
                mGenerateSpotElevs = 0,
                mNumberOnlyLabels = 0,
                mShowProgress = 0,
                mDisableSmoothing = 0,
                mXSpacing = 0.0,
                mYSpacing = 0.0,
                mSimpThreshold = 0.0
            };

            _lastGmError = GlobalMapper.GM_GenerateContours(asciiLayerHandle, ref contourParameters, out contoursLayerHandle);

            return contoursLayerHandle;
        }

Thoughts on this error? I achieved the export via the GUI (and imported the Shape File into ArcMap so I know the data is "good").

Thanks,

Brian

Comments

  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    It looks like the filename that you are passing into the SDK is not an ANSI C string (1-byte per character). What is the type of your 'filename' variable, you just declared it as 'var' rather than using an explicit type. You need to make sure that it isn't being passed as a Unicode string as that is not what the SDK uses.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    The call to the DLL looks like this:


    /// <summary>
    /// Exports one or more layers to a new vector file (not implemented on WinCE).
    /// </summary>
    /// <param name="aFilename">Name of new file to create.</param>
    /// <param name="aFormat">Format to export.</param>
    /// <param name="aLayer">Layer to export or NULL for all.</param>
    /// <param name="aWorldBounds">World bounds to export or NULL for all.</param>
    /// <param name="aFlags">Export flags.</param>
    /// <param name="aFormatOptions">Format-specific options (NULL for defaults).</param>
    /// <returns></returns>
    [DllImport(GlobalMapperInterface, CharSet = CharSet.Ansi, EntryPoint = "GM_ExportVector")]
    public static extern GM_Error_t32 GM_ExportVector([MarshalAs(UnmanagedType.LPStr)] ref string aFilename, GM_VectorExportFormat_t32 aFormat, IntPtr aLayer, ref GM_Rectangle_t aWorldBounds, GM_VectorExportFlags_t32 aFlags, uint aFormatOptions);


    Trying to figure out how to adjust. .NET is "supposed to" handle this via System.String (or alias, string). Any idea? If I find the solution I will post.

    Thanks,

    Brian
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    I'm bummed. I really thought this would work and it didn't:

    /// <summary>
            /// Exports one or more layers to a new vector file (not implemented on WinCE).
            /// </summary>
            /// <param name="aFilename">Name of new file to create.</param>
            /// <param name="aFormat">Format to export.</param>
            /// <param name="aLayer">Layer to export or NULL for all.</param>
            /// <param name="aWorldBounds">World bounds to export or NULL for all.</param>
            /// <param name="aFlags">Export flags.</param>
            /// <param name="aFormatOptions">Format-specific options (NULL for defaults).</param>
            /// <returns></returns>
            [DllImport(GlobalMapperInterface, EntryPoint = "GM_ExportVector")]
            public static extern GM_Error_t32 GM_ExportVector([MarshalAs(UnmanagedType.AnsiBStr)] ref string aFilename, GM_VectorExportFormat_t32 aFormat, IntPtr aLayer, ref GM_Rectangle_t aWorldBounds, GM_VectorExportFlags_t32 aFlags, uint aFormatOptions);
    


    Brian
  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    A BStr is not what you want, that is a special kind of string where I believe the length is stored at the beginning before the actual text. It is not the same as an ANSI C string.

    Try passing the parameter as ByVal (or whatever you say in C#) rather than 'ref', I think maybe you are passing in the address of the String variable rather than the actual string in it.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    Silly of me. In the end, yes, this worked (this was one of those cases where i stared at it too long and ignored the pass by ref):

    /// <summary>
            /// Exports one or more layers to a new vector file (not implemented on WinCE).
            /// </summary>
            /// <param name="aFilename">Name of new file to create.</param>
            /// <param name="aFormat">Format to export.</param>
            /// <param name="aLayer">Layer to export or NULL for all.</param>
            /// <param name="aWorldBounds">World bounds to export or NULL for all.</param>
            /// <param name="aFlags">Export flags.</param>
            /// <param name="aFormatOptions">Format-specific options (NULL for defaults).</param>
            /// <returns>Error code of type GM_Error_t32.</returns>
            [DllImport(GlobalMapperDLL, EntryPoint = "GM_ExportVector")]
            public static extern GM_Error_t32 GM_ExportVector(string aFilename, GM_VectorExportFormat_t32 aFormat, IntPtr aLayer, ref GM_Rectangle_t aWorldBounds, GM_VectorExportFlags_t32 aFlags, uint aFormatOptions);
    

    Two additional questions - are they flags for overwriting or not overwriting an export file name? And secondly, can you pass in Shape File options to aFormatOptions per GM_ExportOptsSHP_t (as listed in the C header?).

    THANK YOU,

    Brian
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Third thing too - if I wanted to export a SHAPE file AND it's corresponding Projection file AND also hide all progress, how would i accomplish all 3 flags in a single call?

    Thank you again,

    Brian
  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    Just add the flags together (OR them together is the same thing).

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    That's what I thought , figured that one - thanks. Additional weirdness - When I export a ShapeFile of say Generated Contours, how to I either export the Projection of the current display layer OR add a projection to the Vector layer (I want a PRJ file when I'm done).

    Thanks,

    Brian.
  • global_mapper
    global_mapper Administrator
    edited August 2010
    You can use the GM_SaveProjectionToFile function to save any GM_Projection_t definition to a PRJ file.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    Thanks for the projection tip, but unfortunately I keep getting the wrong projection written. Here is the basics of the code - this seems like this should work, but it's spitting out the wrong projection settings to file:
                var projection = new GM_Projection_t
                {
                    mProjSys = PROJSYS.GM_PRJ_GEO,
                    mDatum = DATUM.GM_DATUM_WGS_84,
                    mUnit = UNIT.GM_PRJ_UNIT_ARC_DEGREES,
                    mNumAttrs = 0
                };
    
                var filename = "c:\\test\\test.prj";
                uint reserved = 0;
                _lastGmError = GlobalMapper.GM_SaveProjectionToFile(filename, ref projection, reserved);
    
    
            /// <summary>
            /// Sets the new projection. This is the projection that all draws and
            /// exports will be done in. It is also the projection that all world bound
            /// rectangles will be in.
            /// </summary>
            /// <param name="aProj">A projection.</param>
            /// <returns>Error code of type GM_Error_t32.</returns>
            [DllImport(GlobalMapperDLL, EntryPoint = "GM_SetProjection")]
            public static extern GM_Error_t32 GM_SetProjection(ref GM_Projection_t aProj);
    

    And the file keeps spitting out what seems like the "Default"?:
    GEOGCS["Geographic Coordinate System",DATUM["D_ADNDN",SPHEROID["Clarke_1880",6378249.145,293.4650000030293]],PRIMEM["Greenwich",0],UNIT["Radian",1]]
    

    Ideas?

    Thanks,

    Brian
  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    It looks like your GM_Projection_t structure is being initialized to all zeroes rather than the values you are setting. I'm not much of a C# programmer, but I'm guessing how you are initializing the structure isn't working. Try the following instead:

    var projection = new GM_Projection_t;
    projection.mProjSys = PROJSYS.GM_PRJ_GEO;
    projection.mDatum = DATUM.GM_DATUM_WGS_84;
    projection.mUnit = UNIT.GM_PRJ_UNIT_ARC_DEGREES;
    projection.mNumAttrs = 0;

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    I agree - it's almost like it is the case. For fun, I tried setting object properties vs using an Initializer and came up with the same results.

    IF you examine the object in memory during debug - all the way up to and after the time of export, the properties are all set the way I want them to be. It's as if the GM_SaveProjectionToFile C method is simply ignoring whatever I pass to it (I could pass a blank projection, or any one of my choosing and it performs the same). I also tried GM_SetProjection and GM_GetProjection with no luck in saving a projection to file correctly.

    I can accomplish this in the GUI via the Projection I set - and can obtain a correct PRJ file export when doing a Vector export. Something is a little screwy here. Any other ideas?

    Thanks,

    Brian
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    Fixed. In GM_Projection_t struct - one of the attributes was out of order. Corrected and it had no issues: (correct code listed below):
    namespace MyNameSpace
    {
        using System;
    
        /// <summary>
        /// This type is used to fully describe a projection.
        /// </summary>
        public struct GM_Projection_t
        {
            /// <summary>
            /// Projection system.
            /// </summary>
            public PROJSYS mProjSys;
    
            /// <summary>
            /// Horizontal datum.
            /// </summary>
            public DATUM mDatum;
    
            /// <summary>
            /// Ground units.
            /// </summary>
            public UNIT mUnit;
    
            /// <summary>
            /// Number of attributes in attribute list.
            /// </summary>
            public uint mNumAttrs;
    
            // Attribute value list items [GM_MAX_ATTR_PER_PROJ = 16] or maximum attributes a single projection might have (C# doesn't support fixed length arrays).
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr1;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr2;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr3;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr4;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr5;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr6;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr7;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr8;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr9;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr10;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr11;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr12;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr13;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr14;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr15;
    
            /// <summary>
            /// 
            /// </summary>
            public GM_ProjAttrValue_t mAttr16;
        }
    }
    
Sign In or Register to comment.