/// <summary> /// 复制 /// </summary> /// <returns></returns> public moTextSymbol Clone() { moTextSymbol sTextSymbol = new moTextSymbol(); sTextSymbol._Font = (Font)_Font.Clone(); sTextSymbol._FontColor = _FontColor; sTextSymbol._Alignment = _Alignment; sTextSymbol._OffsetX = _OffsetX; sTextSymbol._OffsetY = _OffsetY; sTextSymbol._UseMask = _UseMask; sTextSymbol._MaskColor = _MaskColor; sTextSymbol._MaskWidth = _MaskWidth; return(sTextSymbol); }
//绘制注记 internal static void DrawLabel(Graphics g, double dpm, PointF OriPoint, string labelText, moTextSymbol textSymbol) { SmoothingMode sSmoothMode = g.SmoothingMode; g.SmoothingMode = SmoothingMode.HighQuality; //说明,OriPoint:绘制原点(即注记左上点) SolidBrush sTextBrush = new SolidBrush(textSymbol.FontColor); Pen sMaskPen = new Pen(textSymbol.MaskColor, (float)(2 * textSymbol.MaskWidth * dpm / 1000)); float dpi = (float)(dpm * 0.0254); if (textSymbol.UseMask == true) { //需要描边 GraphicsPath sGraphicPath = new GraphicsPath(); sGraphicPath.AddString(labelText, textSymbol.Font.FontFamily, (Int32)textSymbol.Font.Style, textSymbol.Font.Size * dpi / 72, OriPoint, StringFormat.GenericDefault); g.DrawPath(sMaskPen, sGraphicPath); g.FillPath(sTextBrush, sGraphicPath); sGraphicPath.Dispose(); } else { //不需要描边 g.DrawString(labelText, textSymbol.Font, sTextBrush, OriPoint); } sTextBrush.Dispose(); sMaskPen.Dispose(); g.SmoothingMode = sSmoothMode; }
//获取注记的屏幕范围 private RectangleF GetLabelExtent(Graphics g, double dpm, PointF labelPoint, string labelText, moTextSymbol textSymbol) { //(1)测量注记大小 SizeF sLabelSize = g.MeasureString(labelText, textSymbol.Font); //注记的尺寸 //(2)计算偏移量 float sLabelOffsetX, sLabelOffsetY; //注记偏移量(屏幕坐标),向右、向上位正 sLabelOffsetX = (float)(textSymbol.OffsetX / 1000 * dpm); sLabelOffsetY = (float)(textSymbol.OffsetY / 1000 * dpm); //(3)根据布局计算左上点 PointF sTopLeftPoint = new PointF(); //注记左上点坐标(屏幕坐标) if (textSymbol.Alignment == moTextSymbolAlignmentConstant.TopLeft) { sTopLeftPoint.X = labelPoint.X + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.TopCenter) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width / 2 + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.TopRight) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.CenterLeft) { sTopLeftPoint.X = labelPoint.X + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height / 2 - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.CenterCenter) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width / 2 + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height / 2 - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.CenterRight) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height / 2 - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.BottomLeft) { sTopLeftPoint.X = labelPoint.X + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.BottomCenter) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width / 2 + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height - sLabelOffsetY; } else if (textSymbol.Alignment == moTextSymbolAlignmentConstant.BottomRight) { sTopLeftPoint.X = labelPoint.X - sLabelSize.Width + sLabelOffsetX; sTopLeftPoint.Y = labelPoint.Y - sLabelSize.Height - sLabelOffsetY; } else { throw new Exception("Invalid text symbol alignment!"); } //(4)返回注记范围矩形 RectangleF sRect = new RectangleF(sTopLeftPoint, sLabelSize); return(sRect); }
/// <summary> /// 绘制所有注记 /// </summary> /// <param name="g"></param> /// <param name="extent"></param> /// <param name="mapScale"></param> /// <param name="dpm"></param> /// <param name="mpu"></param> /// <param name="placedLabelExtents"></param> internal void DrawLabels(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, List <RectangleF> placedLabelExtents) { if (_LabelRenderer == null) { return; } if (_LabelRenderer.LabelFeatures == false) { return; } Int32 sFieldIndex = _AttributeFields.FindField(_LabelRenderer.Field); if (sFieldIndex < 0) { return; } Int32 sFeatureCount = _Features.Count; for (Int32 i = 0; i <= sFeatureCount - 1; i++) { moFeature sFeature = _Features.GetItem(i); if (IsFeatureInExtent(sFeature, extent) == false) { //要素不位于显示范围内,不显示注记 continue; } if (sFeature.Symbol == null) { //要素没有配置符号,不显示注记 continue; } if (IsFeatureSymbolVisible(sFeature) == false) { //要素符号不可见,自然就不显示注记 continue; } string sLabelText = GetValueString(sFeature.Attributes.GetItem(sFieldIndex)); if (sLabelText == string.Empty) { //注记文本为空,不显示注记 continue; } //根据要素几何类型采用相应的配置方案 if (sFeature.ShapeType == moGeometryTypeConstant.Point) { //点要素,取点的右上为定位点,但要考虑点符号的大小 //(1)复制符号 moTextSymbol sTextSymbol; //最终绘制注记所采用的符号 sTextSymbol = _LabelRenderer.TextSymbol.Clone(); //复制符号 //(2)计算定位点并设置符号 PointF sSrcLabelPoint; //定位点的屏幕坐标 moPoint sPoint = (moPoint)sFeature.Geometry; PointF sSrcPoint = FromMapPoint(extent, mapScale, dpm, mpu, sPoint); //点要素的屏幕坐标 moSimpleMarkerSymbol sMarkerSymbol = (moSimpleMarkerSymbol)sFeature.Symbol; float sSymbolSize = (float)(sMarkerSymbol.Size / 1000 * dpm); //符号的屏幕尺寸 //右上方并设置符号 sSrcLabelPoint = new PointF(sSrcPoint.X + sSymbolSize / 2, sSrcPoint.Y - sSymbolSize / 2); sTextSymbol.Alignment = moTextSymbolAlignmentConstant.BottomLeft; //(3)计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, sTextSymbol); //(4)冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } else if (sFeature.ShapeType == moGeometryTypeConstant.MultiPolyline) { //线要素,为每个部分的中点配置一个注记 //(1)获取符号,线要素无需复制符号 moTextSymbol sTextSymbol = _LabelRenderer.TextSymbol; //(2)对每个部分进行配置 moMultiPolyline sMultiPolyline = (moMultiPolyline)sFeature.Geometry; Int32 sPartCount = sMultiPolyline.Parts.Count; for (Int32 j = 0; j <= sPartCount - 1; j++) { //获取注记 moPoint sMapLabelPoint = moMapTools.GetMidPointOfPolyline(sMultiPolyline.Parts.GetItem(j)); PointF sSrcLabelPoint = FromMapPoint(extent, mapScale, dpm, mpu, sMapLabelPoint); //计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, _LabelRenderer.TextSymbol); //冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } } else if (sFeature.ShapeType == moGeometryTypeConstant.MultiPolygon) { //面要素,为面积最大的外环及其内环所构成的多边形配置一个注记 //(1)获取符号,面要素无需复制符号 moTextSymbol sTextSymbol = _LabelRenderer.TextSymbol; //(2)获取注记点 moMultiPolygon sMultiPolygon = (moMultiPolygon)sFeature.Geometry; moPoint sMapLabelPoint = moMapTools.GetLabelPointOfMultiPolygon(sMultiPolygon); PointF sSrcLabelPoint = FromMapPoint(extent, mapScale, dpm, mpu, sMapLabelPoint); //(3)计算注记的屏幕范围矩形 RectangleF sLabelExtent = GetLabelExtent(g, dpm, sSrcLabelPoint, sLabelText, _LabelRenderer.TextSymbol); //(4)冲突检测 if (HasConflict(sLabelExtent, placedLabelExtents) == false) { //没有冲突,则绘制并将当前注记范围矩形加入placedLabelExtents moMapDrawingTools.DrawLabel(g, dpm, sLabelExtent.Location, sLabelText, sTextSymbol); placedLabelExtents.Add(sLabelExtent); } } else { throw new Exception("Invalid shape type!"); } } }