将 SQL 服务器地理转换为 PNG 图像

Convert SQL Server Geography to PNG image

我们有一个 API 将 MS SQL 地理类型转换为 well-known text,并将其发送到前端,然后将 WKT 发送到 OpenLayer 地图,从而呈现 canvas(边界、地区等)。

我正在寻找一种方法来减少客户端的负载,并在后端将多边形、多边形和一般地图转换为 png。

我尝试的是将 canvas 转换为 base64,并将其另存为 PNG。这很好用,但我需要一个完整的后端解决方案。

我尝试使用 SharpMap,但它太旧了,它导致了我的依赖性问题,而且我没能让它工作。

我找到了一个测试 SHP 文件并尝试将其渲染到 windows 形式的 PictureBox 进行测试,但我得到的只是一个空的白框。

SharpMap.Map myMap = new SharpMap.Map(new Size(600, 300));
myMap.BackColor = Color.White;
var shapeFileProvider = new SharpMap.Data.Providers.ShapeFile(@"C:\Users\test\Downloads\FRA_adm\FRA_adm1.shp", true);

SharpMap.Layers.VectorLayer myLayer = new SharpMap.Layers.VectorLayer("World Countries");
myMap.Layers.Add(myLayer);
myMap.ZoomToExtents();
myLayer.DataSource = shapeFileProvider;
pictureBox1.Image = myMap.GetMap();

关于如何解决这个问题有什么想法吗?

编辑: 我什至尝试了 geoserver,但它看起来不支持空间地理,但只支持几何。

我需要找到一种方法将边界、区域、国家/地区转换为 C# 后端中的图像。

编辑 2: 你正在使用 SHP 文件进行测试,但我真正想要的是从 Sql 服务器地理类型呈现它。

SharpMap 仍在维护,但 nuget 包没有。并且这些包(日期为 2014 年)与当前 nuget 版本的所有依赖项(GeoAPI、ProjNet 等)都不兼容。 我的建议是:

  1. 不要使用 SharpMap nuget,从 github 构建您自己的 SharpMap 程序集(大多数程序集编译 w/o 任何问题,尤其是主要的 SharpMap)
  2. 引用那个程序集(而且只有那个)
  3. 需要时手动一一引用最新版本的依赖程序集。

这是您使用最新的 SharpMap 改编的 WinForms 代码,GeoAPI and ProjNet:

public partial class Form1 : Form
{
    public Form1()
    {
        // just add a PictureBox on the Winform.
        InitializeComponent();
        DrawMap();
    }

    private void DrawMap()
    {
        Session.Instance.SetCoordinateSystemServices(
            new CoordinateSystemServices(
                    new CoordinateSystemFactory(),
                    new CoordinateTransformationFactory(),
                    SpatialReference.GetAllReferenceSystems()));

        var map = new Map(pictureBox1.Size);
        map.BackColor = Color.White;
        var file = new ShapeFile(@"D:\Downloads\FRA_adm\FRA_adm1.shp", true);
        var layer = new VectorLayer("France", file);
        map.Layers.Add(layer);
        map.ZoomToExtents();
        pictureBox1.Image = map.GetMap();
    }
}

这将显示:

如您所见,地图看起来很有趣,如果您碰巧知道法国的等高线:-)。如果你想要正确的投影,你需要在图层中添加这段代码:

layer.CoordinateTransformation = Wgs84ToGoogle;

...

// Wgs84 to Google Mercator Coordinate Transformation
// this code comes from SharpMap\Examples\WinFormSamples\LayerTools.cs
private ICoordinateTransformation _wgs84ToGoogle;
public ICoordinateTransformation Wgs84ToGoogle
{
    get
    {
        if (_wgs84ToGoogle == null)
        {
            var csFac = new CoordinateSystemFactory();
            var ctFac = new CoordinateTransformationFactory();

            var wgs84 = csFac.CreateGeographicCoordinateSystem(
              "WGS 84", AngularUnit.Degrees, HorizontalDatum.WGS84, PrimeMeridian.Greenwich,
              new AxisInfo("north", AxisOrientationEnum.North), new AxisInfo("east", AxisOrientationEnum.East));

            var parameters = new List<ProjectionParameter>();
            parameters.Add(new ProjectionParameter("semi_major", 6378137.0));
            parameters.Add(new ProjectionParameter("semi_minor", 6378137.0));
            parameters.Add(new ProjectionParameter("latitude_of_origin", 0.0));
            parameters.Add(new ProjectionParameter("central_meridian", 0.0));
            parameters.Add(new ProjectionParameter("scale_factor", 1.0));
            parameters.Add(new ProjectionParameter("false_easting", 0.0));
            parameters.Add(new ProjectionParameter("false_northing", 0.0));

            var projection = csFac.CreateProjection("Google Mercator", "mercator_1sp", parameters);
            var epsg900913 = csFac.CreateProjectedCoordinateSystem(
              "Google Mercator", wgs84, projection, LinearUnit.Metre, new AxisInfo("East", AxisOrientationEnum.East),
              new AxisInfo("North", AxisOrientationEnum.North));

            ((CoordinateSystem)epsg900913).DefaultEnvelope = new[] { -20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789 };

            _wgs84ToGoogle = ctFac.CreateFromCoordinateSystems(wgs84, epsg900913);
        }
        return _wgs84ToGoogle;
    }
}

你现在会得到这个:

SharpMap 可能有点臃肿,但它仍然提供了有价值的代码和示例工作。由于文档很难找到,如果你使用它,你可能需要挖掘源代码。

另外,你想知道SharpMap使用的GDI+在服务器端并没有被微软官方支持。这并不意味着它不起作用,您必须根据自己的情况自行尝试。