将 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 等)都不兼容。
我的建议是:
- 不要使用 SharpMap nuget,从 github 构建您自己的 SharpMap 程序集(大多数程序集编译 w/o 任何问题,尤其是主要的 SharpMap)
- 引用那个程序集(而且只有那个)
- 需要时手动一一引用最新版本的依赖程序集。
这是您使用最新的 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+在服务器端并没有被微软官方支持。这并不意味着它不起作用,您必须根据自己的情况自行尝试。
我们有一个 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 等)都不兼容。 我的建议是:
- 不要使用 SharpMap nuget,从 github 构建您自己的 SharpMap 程序集(大多数程序集编译 w/o 任何问题,尤其是主要的 SharpMap)
- 引用那个程序集(而且只有那个)
- 需要时手动一一引用最新版本的依赖程序集。
这是您使用最新的 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+在服务器端并没有被微软官方支持。这并不意味着它不起作用,您必须根据自己的情况自行尝试。