使用 NetTopologySuite 删除 GeoJSON 的 bbox 字段
Remove bbox field of GeoJSON using NetTopologySuite
在 .NET Core 3 WebAPI 项目中,我正在使用 NetTopologySuite 创建一个 FeatureCollection。
然后我序列化为 GeoJSON 响应。完整代码如下:
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
namespace ProjectX.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class Xyz: ControllerBase
{
[HttpGet]
[Route("markets")]
[Produces("application/geo+json")]
[ProducesResponseType(typeof(FeatureCollection), 200)]
public ActionResult GetMarkets(int adm0code)
{
using (var db = new Models.Entities.Reporting_devContext())
{
var markets = (from m in db.Markets
where m.Adm0Code==adm0code
&& m.MarketDeleteDate==null
&& m.MarketLatitude.HasValue
&& m.MarketLongitude.HasValue
select new
{
m.MarketId,
m.Adm1Code,
m.Adm2Code,
m.MarketName,
m.MarketLatitude,
m.MarketLongitude
}).ToList();
FeatureCollection fc = new FeatureCollection();
foreach(var m in markets)
{
AttributesTable attribs = new AttributesTable();
attribs.Add("id", m.MarketId);
attribs.Add("name", m.MarketName);
Point p = new Point(m.MarketLongitude.Value, m.MarketLatitude.Value);
IFeature feature = new Feature(p, attribs);
fc.Add(feature);
}
return Ok(fc);
}
}
}
}
问题是它还添加了字段框,对于点的集合是完全没用的:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": 266,
"bbox": [
70.580022,
37.116638,
70.580022,
37.116638
],
"geometry": {
"type": "Point",
"coordinates": [
70.580022,
37.116638
]
},
"properties": {
"name": "Fayzabad"
}
},
...
}]
}
如何告诉 NetTopologySuite 不添加 bbox 字段?
查看NetTopologySuite.IO.GeoJSON的代码
https://github.com/NetTopologySuite/NetTopologySuite.IO.GeoJSON/blob/develop/src/NetTopologySuite.IO.GeoJSON/Converters/FeatureConverter.cs
我找到了管理 bbox 的代码 属性:
// bbox (optional)
if (serializer.NullValueHandling == NullValueHandling.Include || !(feature.BoundingBox is null))
{
var bbox = feature.BoundingBox ?? feature.Geometry?.EnvelopeInternal;
writer.WritePropertyName("bbox");
serializer.Serialize(writer, bbox, typeof(Envelope));
}
它说bbox是可选的,所以有一种方法可以避免编写它,并且代码会检查它是否忽略了空值...
在我的代码中,我没有为 bbox 设置任何值,顺便设置序列化程序以忽略空值,options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore , 解决问题:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options => {
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Point)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Coordinate)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(LineString)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(MultiLineString)));
}).AddNewtonsoftJson(options => {
foreach (var converter in NetTopologySuite.IO.GeoJsonSerializer.Create(new GeometryFactory(new PrecisionModel(), 4326)).Converters)
{
options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
options.SerializerSettings.Converters.Add(converter);
}
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
在 .NET Core 3 WebAPI 项目中,我正在使用 NetTopologySuite 创建一个 FeatureCollection。
然后我序列化为 GeoJSON 响应。完整代码如下:
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
namespace ProjectX.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class Xyz: ControllerBase
{
[HttpGet]
[Route("markets")]
[Produces("application/geo+json")]
[ProducesResponseType(typeof(FeatureCollection), 200)]
public ActionResult GetMarkets(int adm0code)
{
using (var db = new Models.Entities.Reporting_devContext())
{
var markets = (from m in db.Markets
where m.Adm0Code==adm0code
&& m.MarketDeleteDate==null
&& m.MarketLatitude.HasValue
&& m.MarketLongitude.HasValue
select new
{
m.MarketId,
m.Adm1Code,
m.Adm2Code,
m.MarketName,
m.MarketLatitude,
m.MarketLongitude
}).ToList();
FeatureCollection fc = new FeatureCollection();
foreach(var m in markets)
{
AttributesTable attribs = new AttributesTable();
attribs.Add("id", m.MarketId);
attribs.Add("name", m.MarketName);
Point p = new Point(m.MarketLongitude.Value, m.MarketLatitude.Value);
IFeature feature = new Feature(p, attribs);
fc.Add(feature);
}
return Ok(fc);
}
}
}
}
问题是它还添加了字段框,对于点的集合是完全没用的:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": 266,
"bbox": [
70.580022,
37.116638,
70.580022,
37.116638
],
"geometry": {
"type": "Point",
"coordinates": [
70.580022,
37.116638
]
},
"properties": {
"name": "Fayzabad"
}
},
...
}]
}
如何告诉 NetTopologySuite 不添加 bbox 字段?
查看NetTopologySuite.IO.GeoJSON的代码 https://github.com/NetTopologySuite/NetTopologySuite.IO.GeoJSON/blob/develop/src/NetTopologySuite.IO.GeoJSON/Converters/FeatureConverter.cs
我找到了管理 bbox 的代码 属性:
// bbox (optional)
if (serializer.NullValueHandling == NullValueHandling.Include || !(feature.BoundingBox is null))
{
var bbox = feature.BoundingBox ?? feature.Geometry?.EnvelopeInternal;
writer.WritePropertyName("bbox");
serializer.Serialize(writer, bbox, typeof(Envelope));
}
它说bbox是可选的,所以有一种方法可以避免编写它,并且代码会检查它是否忽略了空值...
在我的代码中,我没有为 bbox 设置任何值,顺便设置序列化程序以忽略空值,options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore , 解决问题:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options => {
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Point)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Coordinate)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(LineString)));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(MultiLineString)));
}).AddNewtonsoftJson(options => {
foreach (var converter in NetTopologySuite.IO.GeoJsonSerializer.Create(new GeometryFactory(new PrecisionModel(), 4326)).Converters)
{
options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
options.SerializerSettings.Converters.Add(converter);
}
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}