Я не хочу отвечать на свой собственный вопрос, но я ждал достаточно много отзывов, так что вот что я в итоге сделал:
Я пошел в Компонент Один Silverlight Studio. На $ 1200 баксов это немного круто, но это прекрасно работает. Я использовал C1pdfDocument и C1pdfViewer, чтобы интегрировать решение PDF в свое веб-приложение Silverlight. Пользователи нажимают кнопку, я генерирую PDF в поток памяти и загружаю его в программу просмотра.
Извлеченные уроки:
У меня были небольшие проблемы с рисованием цветных полигонов, пока я не понял, что C1pdfDocument принимает непрозрачность только 1,0, а все остальное вообще не отображается как цвет.
Мне нужно было преобразовать точки lon / lat в координаты x / y и перевернуть вертикальный доступ, поскольку я рисую фигуры во Флориде (северное полушарие), а затем переместить x / y в начало координат ящик, в котором я рисовал. Мне потребовалось немного времени, чтобы понять это правильно, поэтому я решил опубликовать его здесь. Обратите внимание, что я не использую много причудливых сферических или конических проекций, простое преобразование работает достаточно близко для моих целей.
Надеюсь, это кому-нибудь поможет. (Если да, дай мне голос, а?)
public void AddFillPolygon(List<Point> points, Color color)
{
DrawMainPolygon(points, color, mapBorderWidth, mapBorderHeight);
}
public void AddZoomFillPolygon(List<Point> points, Color color)
{
DrawTampaPolygon(points, color);
}
private void DrawMainPolygon(List<Point> points, Color color,
double borderWidth, double borderHeight)
{
double lonMin = -87.8;
double lonMax = -79.9;
double latMin = 24.29;
double latMax = 31.11;
DrawGenericPolygon(points, color,
lonMin, lonMax,
latMin, latMax,
borderWidth, borderHeight);
}
private void DrawTampaPolygon(List<Point> points, Color color)
{
double lonMin = -82.855;
double lonMax = -82.07;
double latMin = 27.57;
double latMax = 28.175;
DrawClippedPolygon(points, color,
lonMin, lonMax,
latMin, latMax,
tampaWidth, tampaHeight, tampaCursor);
}
private void DrawGenericPolygon(List<Point> points, Color color,
double lonMin, double lonMax,
double latMin, double latMax,
double borderWidth, double borderHeight)
{
Point[] XYPoints = ConvertLatLonToXYList(points, lonMin, lonMax,
latMin, latMax, borderWidth, borderHeight, 1);
ShiftXYPointsToOrigin(XYPoints, mapBorderCursor);
pdf.FillPolygon(color, XYPoints);
pdf.DrawPolygon(new Pen(Colors.Black, 0.25), XYPoints);
}
private void DrawClippedPolygon(List<Point> points, Color color,
double lonMin, double lonMax,
double latMin, double latMax,
double borderWidth, double borderHeight,
PDFCursor clipCursor)
{
Point[] XYPoints = ConvertLatLonToXYList(points, lonMin, lonMax, latMin, latMax,
borderWidth, borderHeight, 6);
ShiftXYPointsToOrigin(XYPoints, clipCursor);
pdf.SetClipRect(new Rect(new Point(clipCursor.x, clipCursor.y),
new Size(borderWidth, borderHeight)));
pdf.FillPolygon(color, XYPoints);
pdf.DrawPolygon(new Pen(Colors.Black, 0.25), XYPoints);
pdf.ResetClipRect();
}
private static Point[] ConvertLatLonToXYList(List<Point> modifiedPoints,
double lonMinValue, double lonMaxValue,
double latMinValue, double latMaxValue,
double borderWidthX, double borderHeightY,
int roundDecimalPoints)
{
Point[] XYPoints = new Point[modifiedPoints.Count] ;
int index = 0;
foreach (var z in modifiedPoints)
{
XYPoints[index] = ConvertLatLonToXYPoint(z, lonMinValue, lonMaxValue,
latMinValue, 0.0, 0.0,
borderWidthX, borderHeightY, roundDecimalPoints);
index++;
}
return XYPoints;
}
public static Point ConvertLatLonToXYPoint(Point latlon,
double lonMinValue, double lonMaxValue, double latMinValue,
double xScaledMin, double yScaledMin,
double xScaledMax, double yScaledMax,
int roundDecimalPoints)
{
Point result = new Point();
double scale = (float)(xScaledMax - xScaledMin) / (float)(lonMaxValue - lonMinValue);
double offsetX = lonMinValue * scale - xScaledMin;
result.X = latlon.X * scale - offsetX;
// use the same scale to adjust lattitude
double offsetY = latMinValue * scale - yScaledMin;
result.Y = latlon.Y * scale - offsetY;
// The y value is inverted on the map, because lat/lon origin (for florida) is at bottom right
// x/y origin (for PDF document canvas) is at top left
// this means for y values number comes out inverted and we have to flip it
result.Y = yScaledMax * ((yScaledMax - result.Y) / yScaledMax);
return result;
//return (double)Math.Round(result, roundDecimalPoints);
}
private void ShiftXYPointsToOrigin(Point[] points, PDFCursor originCursor)
{
for (int index = 0; index < points.Length; index++)
{
points[index].X += originCursor.x;
points[index].Y += originCursor.y;
}
}