ArcObjects SDK開發 014 MapSurround和普通Element

2022-12-10 18:01:06

1、如何獲取MapSurround

和獲取MapFrame類似,如果你已經獲取指北針、比例尺等物件,可以通過IGraphicsContainer的FindFrame函數獲取。如果沒有,則通過IGraphicsContainer迴圈所有Element去判斷即可。

2、新增MapSurround

指北針、比例尺、圖例等都是MapSurround,我們以最簡單的指北針為例,把MapSurround新增到PageLayout上。

var myGraphicsContainer = pLayoutApplication.PageLayout as IGraphicsContainer;
var myActiveView = pLayoutApplication.PageLayout as IActiveView;
var myMap = myActiveView.FocusMap;
var myMapFrame = myGraphicsContainer.FindFrame(myMap) as IMapFrame;
if (this._MapSurroundFrame == null)
{
    this._MapSurroundFrame = new MapSurroundFrameClass();
    var myMarkerNorthArrow = new MarkerNorthArrowClass();
    var myMarkerSymbol = myMarkerNorthArrow.MarkerSymbol;
    var myCharacterMarkerSymbol = myMarkerSymbol as ICharacterMarkerSymbol;
    myCharacterMarkerSymbol.CharacterIndex = 177;
    myMarkerNorthArrow.MarkerSymbol = myCharacterMarkerSymbol;
    myMarkerNorthArrow.Size = 30;
    this._MapSurroundFrame.MapSurround = myMarkerNorthArrow;
    this._MapSurroundFrame.MapFrame = myMapFrame;
    var myQuerySize = this._MapSurroundFrame.MapSurround as IQuerySize;
    double myWidth = 0;
    double myHeight = 0;
    myQuerySize.QuerySize(ref myWidth, ref myHeight);
    var myUnitConverter = new UnitConverterClass();
    this.Width = Math.Round(myUnitConverter.ConvertUnits(myWidth, esriUnits.esriPoints, esriUnits.esriMillimeters), 1);
    this.Height = Math.Round(myUnitConverter.ConvertUnits(myHeight, esriUnits.esriPoints, esriUnits.esriMillimeters), 1);
}
else
{
    this._MapSurroundFrame.MapFrame = myMapFrame;
}
var myNewEnvelope = new EnvelopeClass
{
    XMin = this.X,
    YMin = this.Y,
    Width = this.Width,
    Height = this.Height
};
this.GetElment().Geometry = myNewEnvelope;
if (GraphicsContainerHelper.Contain(myGraphicsContainer, this.GetElment()) == false)
{
    myGraphicsContainer.AddElement(this.GetElment(), 0);
}

新增MapSurround流程都是一樣的,不同的地方主要是在範例化具體MapSurround的程式碼。例如指北針、比例尺、圖例等。範例化比例尺的程式碼如下。

IGraphicsContainer myGraphicsContainer = pLayoutApplication.PageLayout as IGraphicsContainer;
if (this._MapSurroundFrame != null)
{
    myGraphicsContainer.DeleteElement(this._MapSurroundFrame as IElement);
    this._MapSurroundFrame = null;
}

IActiveView myActiveView = pLayoutApplication.PageLayout as IActiveView;
IMap myMap = myActiveView.FocusMap;
IMapFrame myMapFrame = myGraphicsContainer.FindFrame(myMap) as IMapFrame;

this._MapSurroundFrame = new MapSurroundFrameClass();
this._MapSurroundFrame.MapFrame = myMapFrame;

//建立比例尺
this._ScaleBar = this.CreateScaleBar();
this._ScaleBar.Map = myMapFrame.Map;
this._ScaleBar.ResizeHint = esriScaleBarResizeHint.esriScaleBarFixed;
this._ScaleBar.LabelFrequency = esriScaleBarFrequency.esriScaleBarDivisions;
this._MapSurroundFrame.MapSurround = this._ScaleBar;

this._ScaleBar.BarHeight = this.BarHeight;
this._ScaleBar.Division = this.Division;
this._ScaleBar.Divisions = this.Divisions;
this._ScaleBar.Subdivisions = this.Subdivisions;
this._ScaleBar.DivisionsBeforeZero = this.DivisionsBeforeZero;

this._ScaleBar.LabelPosition = this.LabelPosition;
this._ScaleBar.LabelGap = this.LabelGap;
ITextSymbol myLabelSymbol = new TextSymbolClass();
IFontDisp myFontDisp = myLabelSymbol.Font;
myFontDisp.Name = "Times New Roman";
myLabelSymbol.Font = myFontDisp;
myLabelSymbol.Size = this.LabelSize;
this._ScaleBar.LabelSymbol = myLabelSymbol;

//pScaleBar的UnitLabel屬性設定需要放在pScaleBar.Units設定程式碼之後。這樣UnitLabel設定才有效果。
this._ScaleBar.Units = esriUnits.esriKilometers;
this._ScaleBar.UnitLabel = this.UnitLabel;
this._ScaleBar.UnitLabelGap = this.UnitLabelGap;
ITextSymbol myUnitLabelSymbol = new TextSymbolClass();
myFontDisp = myUnitLabelSymbol.Font;
myFontDisp.Name = "Times New Roman";
myUnitLabelSymbol.Font = myFontDisp;
myUnitLabelSymbol.Size = this.UnitLabelFontSize;
this._ScaleBar.UnitLabelSymbol = myUnitLabelSymbol;
this._ScaleBar.UnitLabelPosition = this.UnitLabelPosition;

IScaleMarks myScaleMarks = this._ScaleBar as IScaleMarks;
myScaleMarks.MarkFrequency = esriScaleBarFrequency.esriScaleBarDivisionsAndSubdivisions;
myScaleMarks.MarkPosition = this.MarkPosition;
myScaleMarks.DivisionMarkHeight = this.DivisionMarkHeight;
ILineSymbol myDivisionMarkSymbol = new SimpleLineSymbolClass();
myDivisionMarkSymbol.Color = new RgbColorClass() { Red = 0, Green = 0, Blue = 0 };
myDivisionMarkSymbol.Width = this.DivisionMarkWidth;
myScaleMarks.DivisionMarkSymbol = myDivisionMarkSymbol;
myScaleMarks.SubdivisionMarkHeight = this.SubdivisionMarkHeight;
ILineSymbol mySubdivisionMarkSymbol = new SimpleLineSymbolClass();
mySubdivisionMarkSymbol.Color = new RgbColorClass() { Red = 0, Green = 0, Blue = 0 };
mySubdivisionMarkSymbol.Width = this.SubdivisionMarkWidth;
myScaleMarks.SubdivisionMarkSymbol = mySubdivisionMarkSymbol;

IElement myElement = this._MapSurroundFrame as IElement;
IGeometry myGeometry = myElement.Geometry;
if (myGeometry != null && myGeometry.IsEmpty == false)
{
    IEnvelope myGeometryEnvelope = myGeometry.Envelope;
    this.Width = myGeometryEnvelope.Width;
    this.Height = myGeometryEnvelope.Height;
}
IEnvelope myEnvelope = new EnvelopeClass();
myEnvelope.PutCoords(this.X, this.Y, this.X + this.Width, this.Y + this.Height);
myElement.Geometry = myEnvelope;
myGraphicsContainer.AddElement(this._MapSurroundFrame as IElement, 0);

/// <summary>
/// 建立比例尺
/// </summary>
private IScaleBar CreateScaleBar()
{
    IScaleBar myScaleBar;
    if (this.BarType == "AlternatingScaleBar")
    {
        myScaleBar = new AlternatingScaleBar();
    }
    else if (this.BarType == "DoubleAlternatingScaleBar")
    {
        myScaleBar = new DoubleAlternatingScaleBar();
    }
    else if (this.BarType == "HollowScaleBar")
    {
        myScaleBar = new HollowScaleBar();
    }
    else if (this.BarType == "SteppedScaleLine")
    {
        myScaleBar = new SteppedScaleLine();
    }
    else
    {
        myScaleBar = new ScaleLine();
    }
    myScaleBar.Name = this.BarType;
    return myScaleBar;
}

3、普通Element

繼承IElement介面的類如下圖所示。

image1.png

這個列表中的Elment,除了MapFrame、MapSurroundFrame以及後面帶()的外,其他的基本上都是我們常用的,例如點元素、線元素、面元素、圓元素、橢圓元素、各種圖片元素等。

IElement有一個關鍵屬性Geometry,如果是MarkerElement或者TextElement,那麼Geometry就是IPoint型別,如果是LineElement,那麼Geometry是IPolyline型別,PolygonElement的Geometry為IPolygon型別,圖片Element一般傳入IEnvelope。

一些特殊的Element例如橢圓的Geometry傳什麼呢?這樣不確定的問題,我們可以去SDK幫助中查詢,一般幫助中會解釋的很清楚。

image2.png

幫助中說的比較明確,可以傳遞IEnvelope,這樣會在IEnvelope生成 一個橢圓。也可以傳由EllipticArc組成的Polygon物件。不過我們一般會傳IEnvelope,主要原因是簡單直觀。

除了Geometry外,很對圖形狀的元素包含Symbol屬性。例如MarkerElement可設定IMarkerSymbol,TextElement可以設定ITextSymbol,IPolylineElement可設定ILineSymbol,PolygonElement、CircleElement和EllipseElement可以設定IFillSymbol。