ASP.NET/ Swagger/ NetTopologySuite.Geometries 修正样例值

如之前的随笔提到的,NTS的图形类型对应的Swagger UI中的Example Value是图形类型的完整结构,这明显不是我们想要的。

我们期望在Example Value中显示可供使用的GeoJSON的样板,这样既直观,也更有利于调试。

点击查看代码
{
"name": "string",
"geom": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinates": [
{
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
],
"dimension": 0,
"boundaryDimension": 0,
"x": 0,
"y": 0,
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"z": 0,
"m": 0
},
"interiorPoint": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinates": [
{
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
],
"dimension": 0,
"boundaryDimension": 0,
"x": 0,
"y": 0,
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"z": 0,
"m": 0
},
"pointOnSurface": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinates": [
{
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
],
"dimension": 0,
"boundaryDimension": 0,
"x": 0,
"y": 0,
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"z": 0,
"m": 0
},
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"startPoint": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinates": [
{
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
],
"dimension": 0,
"boundaryDimension": 0,
"x": 0,
"y": 0,
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"z": 0,
"m": 0
},
"endPoint": {
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinateSequence": {
"ordinates": 0,
"first": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"last": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
},
"coordinates": [
{
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
],
"dimension": 0,
"boundaryDimension": 0,
"x": 0,
"y": 0,
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
},
"z": 0,
"m": 0
},
"ogcGeometryType": 1,
"boundary": {
"coordinate": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
},
"dimension": 0,
"boundaryDimension": 0,
"ogcGeometryType": 1,
"boundary": "string",
"factory": {
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"coordinateSequenceFactory": {
"ordinates": 0
},
"srid": 0,
"geometryServices": {
"geometryOverlay": {},
"coordinateEqualityComparer": {},
"defaultCoordinateSequenceFactory": {
"ordinates": 0
},
"defaultPrecisionModel": {
"scale": 0,
"precisionModelType": 0
}
}
},
"userData": "string",
"srid": 0,
"precisionModel": {
"scale": 0,
"precisionModelType": 0
},
"centroid": "string",
"interiorPoint": "string",
"pointOnSurface": "string",
"envelope": "string",
"envelopeInternal": {
"centre": {
"x": 0,
"y": 0,
"z": 0,
"m": 0,
"coordinateValue": "string"
}
}
}
}
}

查了资料,发明可以通过给特殊类型添加Open API的Scheme来实现,首先找到了GeoJSON在Open API Scheme描述:

https://gist.github.com/codan-telcikt/e1d59ccc9a3af83e083f1a514c84026c

本来打算自己以此为模板用C#做一遍描述,还是因为懒,继续在Gayhub搜索:OpenApiSchema LineString,只找到了五条记录,心理一凉,本来以为无了,没想到还真有轮子。

是一个还在beta版本的工具,目前来看也没有太活跃,不过他确实实现了GeoJSON的大部分到Open API Scheme的映射,源文件在:

https://github.com/RocketSurgeonsGuild/LaunchPad/blob/master/src/AspNetCore.Spatial/OpenApi/NetTopologySuiteSwashbuckleExtensions.cs

直接想使用轮子的话可以直接

dotnet add package Rocket.Surgery.LaunchPad.AspNetCore.Spatial --version 0.1.0-beta.1

考虑到软件为测试版本,且应用的内容很少,于是我决定直接使用代码段:

点击查看代码
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 DEMO.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"
}
}
}
}
}
);
}
}
也粘到了gist

https://gist.github.com/yuhangch/90a63e4821ba6b2d6f1eee31b025cbf2

之后在Program.cs中的AddSwaggerGen方法中应用即可。

builder.Services.AddSwaggerGen(GeoJSONSchemes.ConfigureForNetTopologySuite);

这时Example Value就如我们期望的那样了:

{
"name": "string",
"geom": {
"type": "LineString",
"coordinates": [
[
0,
0
]
]
}
}
posted @   陈昱行  阅读(301)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示