We have in the Code Community a project Labeling Based On Columns that responds, I think, almost exactely to what you are looking for. It allows to display labels on the map based on a point based layer with the font color, size, angle etc coming from columns.
code.thinkgeo.com/projects/show/labelingbasedoncol
Below, I slightly modified the class ColumBasedTextStyle to have the labels drawn according to some X and Y offset from columns. You can see how the function canvas.DrawText allows drawing the label with offsets in the override DrawCore.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace LabelingBasedOnColumns
{
class ColumnBasedTextStyle : TextStyle
{
private string sizeColumnName;
private string angleColumnName;
private string colorColumnName;
private string fontColumnName;
private string xOffsetColumnName;
private string yOffsetColumnName;
public ColumnBasedTextStyle()
: this(string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty,string.Empty)
{ }
public ColumnBasedTextStyle( string TextColumnName, string SizeColumnName, string AngleColumnName, string ColorColumnName, string FontColumnName,
string XOffsetColumnName, string YOffsetColumnName)
{
this.TextColumnName = TextColumnName;
this.sizeColumnName = SizeColumnName;
this.angleColumnName = AngleColumnName;
this.colorColumnName = ColorColumnName;
this.fontColumnName = FontColumnName;
this.xOffsetColumnName = XOffsetColumnName;
this.yOffsetColumnName = YOffsetColumnName;
}
public string SizeColumnName
{
get { return sizeColumnName; }
set { sizeColumnName = value; }
}
public string AngleColumnName
{
get { return angleColumnName; }
set { angleColumnName = value; }
}
public string ColorColumnName
{
get { return colorColumnName; }
set { colorColumnName = value; }
}
public string FontColumnName
{
get { return fontColumnName; }
set { fontColumnName = value; }
}
public string XOffsetColumnName
{
get { return xOffsetColumnName; }
set { xOffsetColumnName = value; }
}
public string YOffsetColumnName
{
get { return yOffsetColumnName; }
set { yOffsetColumnName = value; }
}
protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
// Loop through each feature and get the values for the different columns to label.
foreach (Feature feature in features)
{
//Get the values for Text, Angle, Size and Font of each feature.
string Text = feature.ColumnValues[TextColumnName];
float Angle = Convert.ToSingle(feature.ColumnValues[AngleColumnName]);
float Size = Convert.ToSingle(feature.ColumnValues[SizeColumnName]);
int Color = Convert.ToInt32(feature.ColumnValues[ColorColumnName]);
string Font = feature.ColumnValues[FontColumnName];
float XOffset = Convert.ToInt32(feature.ColumnValues[XOffsetColumnName]);
float YOffset = Convert.ToInt32(feature.ColumnValues[YOffsetColumnName]);
//Convert from world coordinate to screen coordinate the location of the feature.
ScreenPointF textScreenPoint = ExtentHelper.ToScreenCoordinate (canvas .CurrentWorldExtent ,feature ,canvas. Width,canvas .Height );
//Use DrawText method of canvas to label according to the values previously set.
canvas.DrawText(Text,new GeoFont(Font,Size),new GeoSolidBrush(GeoColor.FromWin32(Color)), null, new ScreenPointF[] { textScreenPoint }, DrawingLevel.LevelFour, XOffset, YOffset,Angle );
}
}
protected override Collection<string> GetRequiredColumnNamesCore()
{
// Here we grab the columns from the textStyle and then add
// the required columns to make sure we pull back the column
// that we need for labeling.
Collection<string> columns = new Collection<string>();
if (!columns.Contains(TextColumnName))
{
columns.Add(TextColumnName);
}
if (!columns.Contains(sizeColumnName))
{
columns.Add(sizeColumnName);
}
if (!columns.Contains(angleColumnName))
{
columns.Add(angleColumnName);
}
if (!columns.Contains(colorColumnName))
{
columns.Add(colorColumnName);
}
if (!columns.Contains(fontColumnName))
{
columns.Add(fontColumnName);
}
if (!columns.Contains(xOffsetColumnName))
{
columns.Add(xOffsetColumnName);
}
if (!columns.Contains(yOffsetColumnName))
{
columns.Add(yOffsetColumnName);
}
return columns;
}
}
}