Search code examples
c#asp.net-coreasp.net-web-apigeojsonnettopologysuite

Remove bbox field of GeoJSON using NetTopologySuite


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?


Solution

  • 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);
    
    }