使用 .NET 堆栈从 KMZ 文件转换为 PDF 的最佳方法是什么? Silverlight 不错,但不是必需的

发布于 2024-11-24 01:41:03 字数 1393 浏览 2 评论 0原文

我需要一个应用程序来使用多个不同的自定义模板生成 PDF 文件。

我有一个 kmz 文件,它定义了我输入的地理形状、标签和地理形状。坐标。

输出需要适用于 8 1/2" x 11" 普通纸张,或适用于 32" x 36" 绘图仪

我的应用程序使用 C# .net 堆栈和 Web 服务,我可以在其中访问 SQLServer 空间函数。

我想将其实现为我的 Web 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

更新:
我想我可以在我的 silverlight 应用程序中使用 ComponentOne C1pdf 库。

  1. 从我的数据库中获取带有纬度/经度点的形状
  2. 将它们转换为 x/y 坐标 (对此不太确定,但这里的其他一些帖子可能会有所帮助) (也不确定是否获得正确的纸张尺寸)
  3. 打开 C1pdf 文档,
  4. 使用 C1pdf 将形状绘制到文档中。

有使用 ComponentOne 的经验吗?

I need an application to produce a PDF file using several different custom templates.

I have a kmz file that defines my input geographic shapes, labels & coordinates.

The output needs to be for 8 1/2" x 11" normal paper, or for 32" x 36" plotters

My application uses a C# .net stack and a web service where I have access to SQLServer spatial functions.

I would like to implement it as part of my web silverlight application, but if I need to have a separate desktop application I will take that.

I need a solution quick, and the boss will pay for it - so a commercial library is OK.

My silverlight application is at http://MyDistrictBuilder.FloridaRedistricting.org

An example KMZ file is at
http://censusvalidator.blob.core.windows.net/mydistrictbuilderdata/Public%20Redistricting%20Plan%20Submissions/HPUBC0005_Kelly_Henry_KMZ.kmz

A example output PDF file is at
http://censusvalidator.blob.core.windows.net/mydistrictbuilderdata/Public%20Redistricting%20Plan%20Submissions/HPUBC0005_Kelly_Henry_8x11.pdf

UPDATE:
I'm thinking I can use ComponentOne C1pdf library in my silverlight app.

  1. Get shapes with lat/lon points from my database
  2. Convert them to x/y coordinates
    (not quite sure about this, but some other posts here may help)
    (Also not sure about getting the right paper size)
  3. open a C1pdf document
  4. draw the shapes to the document using C1pdf.

Any experience out there with ComponentOne?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不寐倦长更 2024-12-01 01:41:03

我不想回答我自己的问题,但我已经等了足够长的时间才得到一些反馈,所以这就是我最终要做的:

我选择了 Component One Silverlight Studio。 1200美元的价格有点贵,但效果很好。我使用 C1pdfDocument 和 C1pdfViewer 将 pdf 解决方案集成到我的基于 Web 的 silverlight 应用程序中。用户单击按钮,我将 pdf 生成到内存流中并将其加载到查看器中。

经验教训:

  1. 我在绘制彩色多边形时确实遇到了一些麻烦,直到我意识到 C1pdfDocument 只需要 1.0 的不透明度,其他任何东西都显示为没有颜色。

  2. 我需要将经/纬度点转换为 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;

        }
    }

I hate to answer my own question, but I've waited long enough for some feedback, so here is what I wound up doing:

I went with the Component One Silverlight Studio. At $1200 bucks, it's a little steep, but it works great. I used the C1pdfDocument and C1pdfViewer to integrate a pdf solution right into my web based silverlight app. The users click a button, I generate the pdf into a memory stream and load it into the viewer.

Lessons Learned:

  1. I did have a little trouble with drawing colored polygons, till I realized that C1pdfDocument only takes an opacity of 1.0, anything else shows up as no color at all.

  2. I needed to convert my lon/lat points to x/y coordinates, and flip the vertical access since I'm drawing shapes in Florida (Northern hemisphere), and then move the x/y to the origin of the box I was drawing in. It took me a little time to get it right, so I figured I'd post it here. Note that I don't use a lot of fancy sperical or conical projections, the simple conversion works close enough for my purposes.

Hope this helps somebody. (If it does, give me an upvote, eh?)

    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;

        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文