合并(联盟?)并简化/减少GeoJson的DbGeometry记录 [英] Combine (union?) and simplify/reduce DbGeometry records for GeoJson

查看:191
本文介绍了合并(联盟?)并简化/减少GeoJson的DbGeometry记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个表中有许多空间实体,其中一个geometry字段称为Boundaries.我想生成具有简化形状/几何形状的GeoJson文件.

I have a number of spatial entities in a table, with a geometry field called Boundaries. I want to produce a GeoJson file with the simplified shapes/geometries.

这是我的第一次尝试:

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;

结果的问题是,由于单独简化了几何形状,因此边界并不常见,如下所示:

The problem with the result is that, because the geometries are simplified individually, the boundaries aren't common, as shown below:

第二种尝试是先合并实体,然后进行简化,然后将其输出为GeoJson:

A second attempt is to combine the entities first, then simplify, then output as 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;

然而,尽管此处所述这不会发生. (然后,我也没有机会在每个功能上添加一个ID,因此现在仅使用"ALL").结果是完全融合的形状:

However, the .Union is combining the entities into a single entity, despite what is said here that this doesn't happen. (I also then don't have the opportunity to put an Id on each feature, so just used 'ALL' for now). The result is the completely merged shape:

所以问题是:如何合并行之间的边界,然后进行简化,然后生成为要素集合,而每个要素都具有 正确的ID,可以在MapShaper中完成(如下所示)?

So the question is: how do I combine the boundaries across rows, then simplify, then produce as a feature collection, with each feature having the correct Id, as can be done in MapShaper (shown below)?

推荐答案

在SQL Server中看起来像这样.

Looks like this is not possible in SQL Server.

您需要将几何转换为拓扑,然后进行简化,然后匹配回原始几何以保留属性/属性/id/etc.

You need to convert the geometries to topologies, then simplify, then match back to the original geometries to preserve the properties/attributes/id/etc.

请参阅: https://trac.osgeo.org/postgis/wiki/UsersWikiSimplifyWithTopologyExt

SQL Server不支持拓扑.

SQL Server doesn't have support for Topologies.

我正在下面的代码中,该代码将多边形(而非多多边形)转换为线串,将线串合并以有效地获得拓扑层,然后对其进行简化.它确实工作得很好,但是困难不在于将多线串转换为多多边形,这可能需要工具像这样.

I'm working on the code below, which converts polygons (not multipolygons) to linestrings, unions the linestrings to effectively get a topology layer, then simplifies that. It works really well, but the difficulty is not in converting the multilinestrings to multipolygons, which might need a tool like this.

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,可以将线串转换回多边形.然后,您必须使用面积交集比率将多边形匹配回原始对象,然后(如果匹配)可以重新关联属性.

Using NetTopologySuite, it can be done. I've written it up here. Using the Polygonizer, you can convert the linestrings back to polygons. Then you have to match the polygons back to the originals by using a ratio of area intersection, and then (if matched) you can re-associate the properties.

这篇关于合并(联盟?)并简化/减少GeoJson的DbGeometry记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆