c# - 合并(联合?)并简化/减少 GeoJson 的 DbGeometry 记录
问题描述
我在一个表中有许多空间实体,其中一个geometry
名为Boundaries
. 我想生成一个具有简化形状/几何形状的 GeoJson 文件。
这是我的第一次尝试:
var entities = await db.Entities.ToListAsync();
dynamic geoJson = new ExpandoObject();
geoJson.type = "FeatureCollection";
var features = new List<dynamic>();
foreach (var entity in entities)
{
// simplify (uses SqlGeometry.Reduce)
var simplified = Utilities.Geo.Simplify(entity.Boundaries, tolerance);
// convert to GeoJSON4EntityFramework.Feature with the appropriate Id
var feature = Utilities.Geo.GetFeature(simplified, entity.Id);
features.Add(feature);
}
geoJson.features = features;
return geoJson;
结果的问题在于,由于几何是单独简化的,边界并不常见,如下所示:
第二种尝试是先组合实体,然后简化,然后输出为 GeoJson:
var entities = await db.Entities.ToListAsync();
// bit of a hack to union all the boundaries
DbGeometry allBoundaries = null;
for (var i = 0; i < entities.Count; i++)
{
if (i == 0) allBoundaries = entities[i].Boundaries;
else allBoundaries = allBoundaries.Union(entities[i].Boundaries);
}
// simplify (uses SqlGeometry.Reduce)
var simplified = Utilities.Geo.Simplify(allBoundaries, tolerance);
dynamic geoJson = new ExpandoObject();
geoJson.type = "FeatureCollection";
var features = new List<dynamic>();
// convert to GeoJSON4EntityFramework.Feature with the (in)appropriate Id
var feature = Utilities.Geo.GetFeature(simplified, "ALL");
features.Add(feature);
geoJson.features = features;
return geoJson;
然而,这.Union
是将实体组合成一个实体,尽管这里说这不会发生。(我也没有机会在每个功能上放置一个 Id,所以现在只使用“ALL”)。结果是完全合并的形状:
所以问题是:我如何组合跨行的边界,然后简化,然后生成一个特征集合,每个特征都有正确的 ID,就像在 MapShaper 中所做的那样(如下所示)?
解决方案
看起来这在 SQL Server 中是不可能的。
您需要将几何转换为拓扑,然后简化,然后匹配回原始几何以保留属性/属性/id/等。
请参阅:https ://trac.osgeo.org/postgis/wiki/UsersWikiSimplifyWithTopologyExt
SQL Server 不支持拓扑。
编辑
我正在处理下面的代码,它将多边形(不是多面体)转换为线串,合并线串以有效地获得拓扑层,然后简化它。它工作得非常好,但困难不在于将多线串转换为多面体,这可能需要这样的工具。
select
geometry::STGeomFromText(replace(replace(e1.boundaries.STAsText(), 'POLYGON (', 'LINESTRING '), '))', ')'), 4326)
.STUnion(geometry::STGeomFromText(replace(replace(e2.boundaries.STAsText(), 'POLYGON (', 'LINESTRING '), '))', ')'), 4326))
.STUnion(geometry::STGeomFromText(replace(replace(e3.boundaries.STAsText(), 'POLYGON (', 'LINESTRING '), '))', ')'), 4326))
.Reduce(0.1)
from entities e1
cross join entities e2
cross join entities e3
where e1.code = 'dc7'
and e2.code = 'dc6'
and e3.code = 'dc8'
编辑
使用NetTopologySuite,就可以做到。我已经把它写在这里了。使用Polygonizer
,您可以将线串转换回多边形。然后,您必须使用面积相交比率将多边形与原始多边形匹配,然后(如果匹配)您可以重新关联属性。
推荐阅读
- android - 如何在 Android 8.1 及更高版本中更改默认通知
- mediawiki - 如何让 MediaWiki 搜索忽略重音符号?
- c++ - OpenGL 2D modelToWorld 矩阵不起作用
- c++ - 虚拟继承不适用于特定的 g++ 版本
- laravel - Laravel 5.7 未定义变量
- javascript - 我如何为我访问的每个页面执行这行代码,而不是在我单击书签时?
- r - 修改现有代码以将 geom_count 插入 ggplot
- ubuntu - 如何使用 MIPI 相机在 NanoPC T4 中获取 cam(0)?
- java - 在 intellij idea 中设置 tomcat 的问题
- vb.net - 更新标签的文本