Getting map scale in standalone C# application.

2826
3
08-23-2011 07:40 AM
Highlighted
New Contributor III
Hi everyone,

I am writing a standalone C# application for creating jpg maps that is being converted from VBA. With help from several people on the forums, I have been able to get everything working without having to use ArcMap at all. I am down to just one glitch and can't figure out how to get around it. At one point, I add a scalebar to the layout and depending on the map scale, I set the units of the scale bar to either esriMiles or esriFeet. The problem I am having is that since I am not running ArcMap and this is all being done in memory, I don't really have map scale to adjust.

In the code below, I get an error at if (m_pMap.MapScale >= 25000) with an error of "The data necessary to complete this operation is not yet available."

I have seen a couple of similar posts on the forums but no firm solutions. I have tried everything suggested on these threads including making sure the map has a spatial reference and units.

Later on in another method, I use the map scale also to set the scale to a rounded number (24,000 instead of 24,323) since the layout also has a scale text object.

How can I get/set the map scale if I am not using ArcMap?

Any help is greatly appreciated!!!
Carlos


public static void AddScaleBar()
{
    try
    {
 stdole.StdFont pFont = new stdole.StdFont();
 pFont.Name = "Arial";

 ITextSymbol pTextSymbol = new TextSymbolClass();
 pTextSymbol.Font = pFont as stdole.IFontDisp;
 pTextSymbol.Size = 5;

 IGraphicsContainer pGraphicsContainer = m_pPageLayout as IGraphicsContainer;
 IFrameElement pFrameElement = pGraphicsContainer.FindFrame(m_pMap);
 IMapFrame mapFrame = pFrameElement as IMapFrame;

 IUID uid = new UIDClass();
 uid.Value = "esriCarto.AlternatingScaleBar";
 IMapSurroundFrame mapSurroundFrame = mapFrame.CreateSurroundFrame(uid as UID, null);
 IElement element = mapSurroundFrame as IElement;

 IEnvelope envelope = new EnvelopeClass();
 envelope.PutCoords(1.24, 0.4, 3.58, 0.55);
 element.Geometry = envelope;

 pGraphicsContainer.AddElement(element, 0);
 IMapSurround mapSurround = mapSurroundFrame.MapSurround;
 IScaleBar pScaleBar = mapSurround as IScaleBar;
 pScaleBar.Divisions = 1;
 pScaleBar.Subdivisions = 2;
 pScaleBar.DivisionsBeforeZero = 0;
 pScaleBar.LabelSymbol = pTextSymbol;
 pScaleBar.UnitLabelPosition = esriScaleBarPos.esriScaleBarBelow;
 pScaleBar.UnitLabelSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
 pScaleBar.UnitLabelSymbol = pTextSymbol;
 pScaleBar.UnitLabelSymbol.Font = pFont as stdole.IFontDisp;
 pScaleBar.UnitLabelSymbol.Size = pTextSymbol.Size;
 pScaleBar.Name = "scalebar";

 //if map scale is greater than 25000, switch the scale units to miles
 if (m_pMap.MapScale >= 25000)
     pScaleBar.Units = esriUnits.esriMiles;
 else
     pScaleBar.Units = esriUnits.esriFeet;

 IGraphicsContainerSelect pGraphicsContainerSelect = pGraphicsContainer as IGraphicsContainerSelect;
 pGraphicsContainerSelect.UnselectAllElements();
    }
    catch (Exception ex)
    {
 MessageBox.Show(ex.Message);
    }
}
Reply
0 Kudos
3 Replies
Highlighted
New Contributor II

Carlos Piccirillo Did you eventually get around this issue?

Reply
0 Kudos
Highlighted
New Contributor II

i have the same issue. Only when the Process runs in an background job, even if IMap is initialized. The IMap Object is not null, but the access to IMap.Mapscale aborts.

Reply
0 Kudos
Highlighted
New Contributor III

This is how I solved it.

/// <summary>

/// Purpose: Determine map scale once you are zoomed into the desired extent.

/// Cannot use m_pMap.MapScale because it cannot be used outside of ArcMap.

/// pMapFrame.MapBounds.Height is height of the DataFrame in feet and 7.8 is

/// the height of the DataFrame in inches. Before we calculate map scale, ground

/// distance needs to be in like units (inches), hence, pMapFrame.MapBounds.Height * 12.

/// </summary>

/// <returns>Int32</returns>

private static Int32 GetMapScale()

{

IMapFrame pMapFrame = new MapFrameClass();

IGraphicsContainer pGraphicsContainer = null;

try

{

pGraphicsContainer = m_pPageLayout as IGraphicsContainer;

pMapFrame = pGraphicsContainer.FindFrame(m_pMap) as IMapFrame;

double groundDistanceInInches = pMapFrame.MapBounds.Height * 12;

Int32 mapScale = Convert.ToInt32(groundDistanceInInches / 7.8);

return mapScale;

}

catch (Exception ex)

{

Queries.LogError(ex.StackTrace, ex.Message, "GetMapScale", "ensRegulatoryApplicationTools");

return 0;

}

finally

{

if (pMapFrame != null) { Marshal.ReleaseComObject(pMapFrame); pMapFrame = null; }

}

}

Reply
0 Kudos