Circle processor

Circle processor

Converts circle definitions of shapes to regular polygons which approximate them.

Table 6. Circle Processor Options

NameRequiredDefaultDescription

field

yes

-

The field to interpret as a circle. Either a string in WKT format or a map for GeoJSON.

target_field

no

field

The field to assign the polygon shape to, by default field is updated in-place

ignore_missing

no

false

If true and field does not exist, the processor quietly exits without modifying the document

error_distance

yes

-

The difference between the resulting inscribed distance from center to side and the circle’s radius (measured in meters for geo_shape, unit-less for shape)

shape_type

yes

-

Which field mapping type is to be used when processing the circle: geo_shape or shape

description

no

-

Description of the processor. Useful for describing the purpose of the processor or its configuration.

if

no

-

Conditionally execute the processor. See Conditionally run a processor.

ignore_failure

no

false

Ignore failures for the processor. See Handling pipeline failures.

on_failure

no

-

Handle failures for the processor. See Handling pipeline failures.

tag

no

-

Identifier for the processor. Useful for debugging and metrics.

error distance

  1. resp = client.indices.create(
  2. index="circles",
  3. mappings={
  4. "properties": {
  5. "circle": {
  6. "type": "geo_shape"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)
  12. resp1 = client.ingest.put_pipeline(
  13. id="polygonize_circles",
  14. description="translate circle to polygon",
  15. processors=[
  16. {
  17. "circle": {
  18. "field": "circle",
  19. "error_distance": 28,
  20. "shape_type": "geo_shape"
  21. }
  22. }
  23. ],
  24. )
  25. print(resp1)
  1. response = client.indices.create(
  2. index: 'circles',
  3. body: {
  4. mappings: {
  5. properties: {
  6. circle: {
  7. type: 'geo_shape'
  8. }
  9. }
  10. }
  11. }
  12. )
  13. puts response
  14. response = client.ingest.put_pipeline(
  15. id: 'polygonize_circles',
  16. body: {
  17. description: 'translate circle to polygon',
  18. processors: [
  19. {
  20. circle: {
  21. field: 'circle',
  22. error_distance: 28,
  23. shape_type: 'geo_shape'
  24. }
  25. }
  26. ]
  27. }
  28. )
  29. puts response
  1. const response = await client.indices.create({
  2. index: "circles",
  3. mappings: {
  4. properties: {
  5. circle: {
  6. type: "geo_shape",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);
  12. const response1 = await client.ingest.putPipeline({
  13. id: "polygonize_circles",
  14. description: "translate circle to polygon",
  15. processors: [
  16. {
  17. circle: {
  18. field: "circle",
  19. error_distance: 28,
  20. shape_type: "geo_shape",
  21. },
  22. },
  23. ],
  24. });
  25. console.log(response1);
  1. PUT circles
  2. {
  3. "mappings": {
  4. "properties": {
  5. "circle": {
  6. "type": "geo_shape"
  7. }
  8. }
  9. }
  10. }
  11. PUT _ingest/pipeline/polygonize_circles
  12. {
  13. "description": "translate circle to polygon",
  14. "processors": [
  15. {
  16. "circle": {
  17. "field": "circle",
  18. "error_distance": 28.0,
  19. "shape_type": "geo_shape"
  20. }
  21. }
  22. ]
  23. }

Using the above pipeline, we can attempt to index a document into the circles index. The circle can be represented as either a WKT circle or a GeoJSON circle. The resulting polygon will be represented and indexed using the same format as the input circle. WKT will be translated to a WKT polygon, and GeoJSON circles will be translated to GeoJSON polygons.

Circles that contain a pole are not supported.

Example: Circle defined in Well Known Text

In this example a circle defined in WKT format is indexed

  1. resp = client.index(
  2. index="circles",
  3. id="1",
  4. pipeline="polygonize_circles",
  5. document={
  6. "circle": "CIRCLE (30 10 40)"
  7. },
  8. )
  9. print(resp)
  10. resp1 = client.get(
  11. index="circles",
  12. id="1",
  13. )
  14. print(resp1)
  1. response = client.index(
  2. index: 'circles',
  3. id: 1,
  4. pipeline: 'polygonize_circles',
  5. body: {
  6. circle: 'CIRCLE (30 10 40)'
  7. }
  8. )
  9. puts response
  10. response = client.get(
  11. index: 'circles',
  12. id: 1
  13. )
  14. puts response
  1. const response = await client.index({
  2. index: "circles",
  3. id: 1,
  4. pipeline: "polygonize_circles",
  5. document: {
  6. circle: "CIRCLE (30 10 40)",
  7. },
  8. });
  9. console.log(response);
  10. const response1 = await client.get({
  11. index: "circles",
  12. id: 1,
  13. });
  14. console.log(response1);
  1. PUT circles/_doc/1?pipeline=polygonize_circles
  2. {
  3. "circle": "CIRCLE (30 10 40)"
  4. }
  5. GET circles/_doc/1

The response from the above index request:

  1. {
  2. "found": true,
  3. "_index": "circles",
  4. "_id": "1",
  5. "_version": 1,
  6. "_seq_no": 22,
  7. "_primary_term": 1,
  8. "_source": {
  9. "circle": "POLYGON ((30.000365257263184 10.0, 30.000111397193788 10.00034284530941, 29.999706043744222 10.000213571721195, 29.999706043744222 9.999786428278805, 30.000111397193788 9.99965715469059, 30.000365257263184 10.0))"
  10. }
  11. }

Example: Circle defined in GeoJSON

In this example a circle defined in GeoJSON format is indexed

  1. resp = client.index(
  2. index="circles",
  3. id="2",
  4. pipeline="polygonize_circles",
  5. document={
  6. "circle": {
  7. "type": "circle",
  8. "radius": "40m",
  9. "coordinates": [
  10. 30,
  11. 10
  12. ]
  13. }
  14. },
  15. )
  16. print(resp)
  17. resp1 = client.get(
  18. index="circles",
  19. id="2",
  20. )
  21. print(resp1)
  1. response = client.index(
  2. index: 'circles',
  3. id: 2,
  4. pipeline: 'polygonize_circles',
  5. body: {
  6. circle: {
  7. type: 'circle',
  8. radius: '40m',
  9. coordinates: [
  10. 30,
  11. 10
  12. ]
  13. }
  14. }
  15. )
  16. puts response
  17. response = client.get(
  18. index: 'circles',
  19. id: 2
  20. )
  21. puts response
  1. const response = await client.index({
  2. index: "circles",
  3. id: 2,
  4. pipeline: "polygonize_circles",
  5. document: {
  6. circle: {
  7. type: "circle",
  8. radius: "40m",
  9. coordinates: [30, 10],
  10. },
  11. },
  12. });
  13. console.log(response);
  14. const response1 = await client.get({
  15. index: "circles",
  16. id: 2,
  17. });
  18. console.log(response1);
  1. PUT circles/_doc/2?pipeline=polygonize_circles
  2. {
  3. "circle": {
  4. "type": "circle",
  5. "radius": "40m",
  6. "coordinates": [30, 10]
  7. }
  8. }
  9. GET circles/_doc/2

The response from the above index request:

  1. {
  2. "found": true,
  3. "_index": "circles",
  4. "_id": "2",
  5. "_version": 1,
  6. "_seq_no": 22,
  7. "_primary_term": 1,
  8. "_source": {
  9. "circle": {
  10. "coordinates": [
  11. [
  12. [30.000365257263184, 10.0],
  13. [30.000111397193788, 10.00034284530941],
  14. [29.999706043744222, 10.000213571721195],
  15. [29.999706043744222, 9.999786428278805],
  16. [30.000111397193788, 9.99965715469059],
  17. [30.000365257263184, 10.0]
  18. ]
  19. ],
  20. "type": "Polygon"
  21. }
  22. }
  23. }

Notes on Accuracy

Accuracy of the polygon that represents the circle is defined as error_distance. The smaller this difference is, the closer to a perfect circle the polygon is.

Below is a table that aims to help capture how the radius of the circle affects the resulting number of sides of the polygon given different inputs.

The minimum number of sides is 4 and the maximum is 1000.

Table 7. Circle Processor Accuracy

error_distanceradius in metersnumber of sides of polygon

1.00

1.0

4

1.00

10.0

14

1.00

100.0

45

1.00

1000.0

141

1.00

10000.0

445

1.00

100000.0

1000