C# 将SQL Server地理信息转换为PNG图像

C# 将SQL Server地理信息转换为PNG图像,c#,openlayers,polygons,geography,sqlgeography,C#,Openlayers,Polygons,Geography,Sqlgeography,我们有一个API,它将MS SQL地理类型转换为,并将其发送到前端,然后前端将WKT发送到OpenLayer maps,OpenLayer maps渲染画布(边界、区域等) 我正在寻找一种方法来减少客户端的负载,并在后端将多边形、多点透视图和地图转换为png 我尝试的是将画布转换为base64,并将其另存为PNG。这很好,但我需要一个完整的后端解决方案 我试着使用SharpMap,但它太旧了,它给我带来了依赖性问题,我没能让它工作 我找到了一个测试SHP文件,并试图将其渲染到windows窗体中

我们有一个API,它将MS SQL地理类型转换为,并将其发送到前端,然后前端将WKT发送到OpenLayer maps,OpenLayer maps渲染画布(边界、区域等)

我正在寻找一种方法来减少客户端的负载,并在后端将多边形、多点透视图和地图转换为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,但它似乎不支持空间地理,只支持几何图形

我需要找到一种方法,将边界、地区和国家转换为c#backend中的图像

编辑2:
您正在使用SHP文件进行测试,但我真正想要的是从Sql Server地理类型渲染它。

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

  • 不要使用SharpMap nuget,从中构建您自己的SharpMap程序集(大多数程序集编译时没有任何问题,尤其是主程序集SharpMap)
  • 引用该程序集(并且仅引用该程序集)
  • 需要时,请逐个手动引用依赖项程序集的最新版本
  • 以下是使用最新SharpMap改编的WinForms代码,以及:

    这将显示以下内容:

    如您所见,如果您碰巧知道法国等高线,那么地图看起来很有趣:-)。如果需要正确的投影,则需要将以下代码添加到图层:

    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;
        }
    }
    
    layer.CoordinateTransformation=WGS84Toogle;
    ...
    //Wgs84到Google Mercator坐标转换
    //此代码来自SharpMap\Examples\WinFormSamples\LayerTools.cs
    专用图像坐标转换_wgs84toogole;
    公共图标转换WGS84Toogle
    {
    得到
    {
    如果(_wgs84togogle==null)
    {
    var csFac=新的协调系统工厂();
    var ctFac=新的CoordinateTransformationFactory();
    var wgs84=csFac.creategeography坐标系(
    “WGS 84”,角度单位。度,水平基准面。WGS84,本初子午线。格林威治,
    新AxisInfo(“北”,AxisOrientationUnim.north),新AxisInfo(“东”,AxisOrientationUnim.east));
    var参数=新列表();
    添加(新的项目参数(“semi_major”,6378137.0));
    添加(新项目参数(“semi_minor”,6378137.0));
    添加(新的投影参数(“原点的纬度”,0.0));
    添加(新投影参数(“中央子午线”,0.0));
    添加(新的投影参数(“比例系数”,1.0));
    添加(新的投影参数(“假东距”,0.0));
    添加(新的ProjectionParameter(“假北距”,0.0));
    var projection=csFac.CreateProjection(“谷歌墨卡托”、“墨卡托1sp”,参数);
    变量epsg900913=csFac.CreateProjectedCoordinateSystem(
    “谷歌墨卡托”,wgs84,投影,LinearUnit.Meter,新AxisInfo(“东”,AxisOrientationEnum.East),
    新AxisInfo(“北”,AxisOrientum.North));
    ((协调系统)epsg900913).DefaultEnvelope=new[]{-20037508.342789,--20037508.34278920037508.34278920037508.34278920037508.342789};
    _wgs84ToGoogle=ctFac.CreateFromCoordinateSystems(wgs84,epsg900913);
    }
    返回wgs84ToGoogle;
    }
    }
    
    现在您将看到:

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


    另外,您还想知道SharpMap使用的GDI+在服务器端并没有得到微软的正式支持。这并不意味着它不起作用,你必须在自己的环境中自己尝试。

    @OndrejSvejdar它不仅与库相关。也许有人会知道为什么我的SharpMap代码不起作用哇,谢谢!在测试代码时,我发现了一个错误。您指出我应该引用ProjNet包,而我需要使用Proj.Net包进行编译。一个点,让我很头疼:)你能解释一下为什么地图在第一次使用时很“有趣”,以及为什么我必须添加WGS84Toogle吗?在我添加它之前,它可以正常工作。然后我得到一个有红十字的图片盒我没有Proj.Net只有ProjNet。。。我把我的测试项目主文件放在这里:搞笑意味着图像明显失真。你的代码运行良好,帮助我找到了90%的解决方案。你知道如何将坐标从4326投影转换为3857子午线吗?我尝试了提供的代码,但当我使用CoordinateTransformation时,它不起作用。
    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;
        }
    }