将SQL Server Geography转换为PNG图像

3
我们有一个API,可以将MS SQL地理类型转换为well-known text,并将其发送到前端,然后前端将WKT发送到OpenLayer地图,该地图呈现画布(边框、区域等)。
我正在寻找一种在后端将多边形、多重多边形和地图等内容转换为png以减少客户端负载的方法。
我尝试将画布转换为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,但它似乎不支持Spatial Geography,只支持geometry。

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

编辑2: 我正在使用SHP文件进行测试,但我真正想要的是从Sql Server Geography类型呈现它。


@OndrejSvejdar 这不仅仅与库有关。也许有人知道为什么我的SharpMap代码无法工作。 - Robert
1个回答

6
SharpMap仍在维护,但nuget包已不再更新。而那些年代久远的软件包(2014年)与所有依赖项(GeoAPI,ProjNet等)的当前nuget版本不兼容。 我的建议是:
  1. 不要使用SharpMap nuget,从github构建自己的SharpMap程序集(大多数程序集编译没有任何问题,特别是主要的SharpMap程序集)
  2. 引用该程序集(仅该程序集)
  3. 手动逐个引用需要的最新版本的依赖程序集。
以下是您的WinForms代码,使用了最新的SharpMap,GeoAPIProjNet
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();
    }
}

这将显示这个:

enter image description here

如您所见,这张地图看起来很有趣,如果您恰好熟悉法国轮廓的话。如果您想要正确的投影,请在图层中添加以下代码:
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;
    }
}

现在你会得到这个:

enter image description here

SharpMap可能有些臃肿,但它仍然提供了有价值的代码和样例。由于文档难以找到,如果你使用它,你可能需要深入源码。

此外,你需要知道SharpMap使用的GDI+不被Microsoft在服务器端官方支持。这并不意味着它不能工作,你需要在自己的环境中尝试。


哇,谢谢!在测试代码时,我发现了一个错误。你指出我应该引用ProjNet包,但我却使用了Proj.Net包进行编译。只因为一个点,让我头疼了好久 :)你能详细解释一下为什么第一次地图显示有问题,以及为什么我需要添加Wgs84ToGoogle?在没有添加它的情况下,一切都正常。但是一旦添加它,就会出现带有红叉的picturebox。 - Robert
我没有 Proj.Net,只有 ProjNet... 我把我的测试项目主文件放在这里:https://gist.github.com/smourier/3d7739c0c719ee0c81fccbd2131fe62c。funny 的意思是图像明显失真。 - Simon Mourier
你的代码很好用,帮我找到了90%的解决方案。你知道如何将我的坐标从4326投影转换为3857子午线吗?我尝试了提供的代码,但当我使用CoordinateTransformation时它不起作用。 - Robert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接