Каков наилучший способ перехода из файла KMZ в PDF с использованием стека .NET? Silverlight хороший, но не обязательный - PullRequest
0 голосов
/ 12 июля 2011

Мне нужно приложение для создания файла PDF с использованием нескольких различных пользовательских шаблонов.

У меня есть файл kmz, который определяет мои входные географические формы, метки и координаты.

Выходные данные должныбыть для обычной бумаги размером 8 1/2 "x 11" или для плоттеров 32 "x 36"

Мое приложение использует стек C # .net и веб-службу, где у меня есть доступ к пространственным функциям SQLServer.

Я хотел бы реализовать его как часть моего веб-приложения Silverlight, но если мне понадобится отдельное настольное приложение, я его приму.

Мне нужно быстрое решение, и начальник заплатитдля этого - значит, коммерческая библиотека в порядке.

Мое приложение Silverlight находится на http://MyDistrictBuilder.FloridaRedistricting.org

Пример файла KMZ на http://censusvalidator.blob.core.windows.net/mydistrictbuilderdata/Public%20Redistricting%20Plan%20Submissions/HPUBC0005_Kelly_Henry_KMZ.kmz

Пример выходного файла PDFв http://censusvalidator.blob.core.windows.net/mydistrictbuilderdata/Public%20Redistricting%20Plan%20Submissions/HPUBC0005_Kelly_Henry_8x11.pdf

ОБНОВЛЕНИЕ:
Я думаю, что я могу использовать библиотеку ComponentOne C1pdf в моем приложении Silverlight.

  1. Получить фигуры с точками широты / долготы из моей базы данных
  2. Конвертировать их в координаты х / уinates (не совсем уверен в этом, но некоторые другие сообщения здесь могут помочь) (Также не уверен насчет правильного размера бумаги)
  3. открыть документ C1pdf
  4. нарисовать фигуры в документе, используяC1pdf.

Есть ли опыт работы с ComponentOne?

1 Ответ

0 голосов
/ 13 августа 2011

Я не хочу отвечать на свой собственный вопрос, но я ждал достаточно много отзывов, так что вот что я в итоге сделал:

Я пошел в Компонент Один Silverlight Studio. На $ 1200 баксов это немного круто, но это прекрасно работает. Я использовал C1pdfDocument и C1pdfViewer, чтобы интегрировать решение PDF в свое веб-приложение Silverlight. Пользователи нажимают кнопку, я генерирую PDF в поток памяти и загружаю его в программу просмотра.

Извлеченные уроки:

  1. У меня были небольшие проблемы с рисованием цветных полигонов, пока я не понял, что C1pdfDocument принимает непрозрачность только 1,0, а все остальное вообще не отображается как цвет.

  2. Мне нужно было преобразовать точки 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;

        }
    }
...