### Description

It would be really great if [CircleProcessor.java](https://github.com/elastic/elasticsearch/blob/0699c9351f1439e246d408fd6538deafde4087b6/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessor.java) could be published in some maven artifact.
We are thinking to convert Geoshape Circle into Geoshape Polygon on application side instead of ElasticSearch Server side. The benefits of it is that it would make possible for us to choose `error_distance` dynamically depending on different conditions.
With direct code access to [CircleProcessor.java](https://github.com/elastic/elasticsearch/blob/0699c9351f1439e246d408fd6538deafde4087b6/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessor.java) and [SpatialUtils.java](https://github.com/elastic/elasticsearch/blob/0699c9351f1439e246d408fd6538deafde4087b6/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialUtils.java) it would be possible to make application side custom conversion logic.
ElasticSearch version: >= 8
x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessorTests.java
processor.execute(ingestDocument);
        assertIngestDocument(originalIngestDocument, ingestDocument);
    }
    public void testNullValue() throws Exception {
        CircleProcessor processor = new CircleProcessor("tag", null, "field", "field", false, 10, GEO_SHAPE);
        IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), Collections.singletonMap("field", null));
        Exception e = expectThrows(Exception.class, () -> processor.execute(ingestDocument));
        assertThat(e.getMessage(), equalTo("field [field] is null, cannot process it."));
    }
    public void testNullValueWithIgnoreMissing() throws Exception {
        CircleProcessor processor = new CircleProcessor("tag", null, "field", "field", true, 10, GEO_SHAPE);
        IngestDocument originalIngestDocument = RandomDocumentPicks.randomIngestDocument(random(), Collections.singletonMap("field", null));
        IngestDocument ingestDocument = new IngestDocument(originalIngestDocument);
        processor.execute(ingestDocument);
        assertIngestDocument(originalIngestDocument, ingestDocument);
    }
    @SuppressWarnings("unchecked")
    public void testJson() throws IOException {
        Circle circle = new Circle(101.0, 1.0, 10);
        HashMap<String, Object> map = new HashMap<>();
        HashMap<String, Object> circleMap = new HashMap<>();
        circleMap.put("type", "Circle");
        circleMap.put("coordinates", List.of(circle.getLon(), circle.getLat()));
        circleMap.put("radius", circle.getRadiusMeters() + "m");
        map.put("field", circleMap);
        Geometry expectedPoly = SpatialUtils.createRegularGeoShapePolygon(circle, 4);
        assertThat(expectedPoly, instanceOf(Polygon.class));
        IngestDocument ingestDocument = TestIngestDocument.withDefaultVersion(map);
        CircleProcessor processor = new CircleProcessor("tag", null, "field", "field", false, 10, GEO_SHAPE);
        processor.execute(ingestDocument);