In a .NET Core 3 WebAPI project, I'm creating a FeatureCollection using NetTopologySuite.
Then I serialize to a GeoJSON response. Full code below:
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);
}
}
}
}
The issue is that it adds also the field box, that for a collection of points is completely useless:
{
"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"
}
},
...
}]
}
How can I tell to NetTopologySuite to not add bbox field?
Looking at the code of NetTopologySuite.IO.GeoJSON https://github.com/NetTopologySuite/NetTopologySuite.IO.GeoJSON/blob/develop/src/NetTopologySuite.IO.GeoJSON/Converters/FeatureConverter.cs
I've found this code that manage the bbox property:
// 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));
}
It says bbox it's optional, so there's a way to avoid to write it, and also the code checks if it has ignore null value...
In my code I don't set any value for bbox, by the way setting the serializer to ignore null values, options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, solve the issue:
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);
}