Skip to content

Instantly share code, notes, and snippets.

@yuhangch
Last active January 18, 2024 18:00
Show Gist options
  • Save yuhangch/90a63e4821ba6b2d6f1eee31b025cbf2 to your computer and use it in GitHub Desktop.
Save yuhangch/90a63e4821ba6b2d6f1eee31b025cbf2 to your computer and use it in GitHub Desktop.
GeoJSON Schemes description for OpenAPI/Swagger in ASP.NET
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace hello.Common;
public class GeoJSONSchemes
{
class DocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
swaggerDoc.Components.Schemas.Add(
"Point3D",
new OpenApiSchema
{
Type = "array",
Description = "Point in 3D space",
ExternalDocs = new OpenApiExternalDocs
{
Url = new Uri("http://geojson.org/geojson-spec.html#id2")
},
MinItems = 2,
MaxItems = 3,
Items = new OpenApiSchema
{
Type = "number"
}
}
);
swaggerDoc.Components.Schemas.Add("Geometry",
new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#geometry-objects"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(Geometry).FullName)
},
Description = "GeoJSON geometry",
Discriminator = new OpenApiDiscriminator
{
PropertyName = "type",
},
Required = new HashSet<string> {"type"},
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("Point"),
new OpenApiString("LineString"),
new OpenApiString("Polygon"),
new OpenApiString("MultiPoint"),
new OpenApiString("MultiLineString"),
new OpenApiString("MultiPolygon"),
},
Description = "the geometry type"
}
}
}
);
}
}
public static void ConfigureForNetTopologySuite(SwaggerGenOptions c)
{
c.DocumentFilter<DocumentFilter>();
c.MapType<Geometry>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#geometry-objects"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(Geometry).FullName)
},
Description = "GeoJSON geometry",
Discriminator = new OpenApiDiscriminator
{
PropertyName = "type",
},
Required = new HashSet<string> {"type"},
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("Point"),
new OpenApiString("LineString"),
new OpenApiString("Polygon"),
new OpenApiString("MultiPoint"),
new OpenApiString("MultiLineString"),
new OpenApiString("MultiPolygon"),
},
Description = "the geometry type"
}
}
}
);
c.MapType<Point>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id2"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(Point).FullName)
},
Description = "GeoJSON Point",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["coordinates"] = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
},
}
);
c.MapType<LineString>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id3"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(LineString).FullName)
},
Description = "GeoJSON LineString",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema()
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("LineString"),
},
},
["coordinates"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
}
},
}
);
c.MapType<Polygon>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id4"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(Polygon).FullName)
},
Description = "GeoJSON Polygon",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema()
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("Polygon"),
},
},
["coordinates"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
}
}
},
}
);
c.MapType<MultiPoint>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id4"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(MultiPoint).FullName)
},
Description = "GeoJSON MultiPolygon",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema()
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("MultiPoint"),
},
},
["coordinates"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
}
},
}
);
c.MapType<MultiLineString>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id5"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(MultiLineString).FullName)
},
Description = "GeoJSON MultiLineString",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema()
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("MultiLineString"),
},
},
["coordinates"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
}
}
},
}
);
c.MapType<MultiPolygon>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#id6"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(MultiPolygon).FullName)
},
Description = "GeoJSON MultiPolygon",
AllOf = new List<OpenApiSchema>
{
new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry",
}
},
new OpenApiSchema
{
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema()
{
Type = "string",
Enum = new List<IOpenApiAny>
{
new OpenApiString("MultiPolygon"),
},
},
["coordinates"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Point3D"
}
}
}
}
}
}
}
},
}
);
c.MapType<GeometryCollection>(
() => new OpenApiSchema
{
ExternalDocs = new OpenApiExternalDocs
{
Url = new("http://geojson.org/geojson-spec.html#geometrycollection"),
},
Type = "object",
Extensions = new Dictionary<string, IOpenApiExtension>
{
["clrType"] = new OpenApiString(typeof(GeometryCollection).FullName)
},
Required = new HashSet<string> {"type", "geometries"},
Description = "GeoJSON geometry collection",
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema
{
Type = "string",
Enum = new List<IOpenApiAny> {new OpenApiString("GeometryCollection")},
},
["geometries"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Geometry"
}
}
}
}
}
);
c.MapType<Feature>(
() => new OpenApiSchema
{
Type = "object",
Description = "GeoJSON Feature",
Required = new HashSet<string> {"type", "id", "geometry"},
ExternalDocs = new OpenApiExternalDocs
{
Url = new("https://tools.ietf.org/html/rfc7946#section-3.2")
},
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema
{
Type = "string",
Enum = new List<IOpenApiAny> {new OpenApiString("Feature")}
},
["id"] = new OpenApiSchema
{
Type = "integer",
},
["geometry"] = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "GeometryCollection",
}
},
["properties"] = new OpenApiSchema
{
Type = "object"
}
}
}
);
c.MapType<FeatureCollection>(
() => new OpenApiSchema
{
Type = "object",
Description = "GeoJSON Feature collection",
Required = new HashSet<string> {"type", "features"},
ExternalDocs = new OpenApiExternalDocs
{
Url = new("https://tools.ietf.org/html/rfc7946#section-3.2")
},
Properties = new Dictionary<string, OpenApiSchema>
{
["type"] = new OpenApiSchema
{
Type = "string",
Enum = new List<IOpenApiAny> {new OpenApiString("FeatureCollection")}
},
["features"] = new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference
{
Type = ReferenceType.Schema,
Id = "Feature"
}
}
}
}
}
);
}
}
//ADD option
builder.Services.AddSwaggerGen(GeoJSONSchemes.ConfigureForNetTopologySuite);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment