Author: Pavel Penev, Software Engineer @ Thermopylae Sciences and Technology
Even though you could, perhaps, get a circle on an Open Layers canvas by importing a data source, the ability to author and modify circles seemed to be an often-requested feature, including for users of iSpatial who may want the option to use Open Layers for their visualization.
What made implementing that feature less trivial is that the data structures used for feature modification in OpenLayers were premised on being able to split all modifiable features into a set of line segments. These were added to a simplified Java Script implementation of an R-* tree, called an R-* bush. That tree can be queried to find what line segments the mouse pointer is over, or near to. Then, the pointer could be snapped to a line segment end point so it can be dragged, or to the nearest point along a line segment so a new control point, splitting the line segment into two segments, can be added.
A cleaner implementation of circle authoring by removing the above premise that all features are composed of independent line segments would require a rather far-reaching refactoring.
In the mean time, we pretended that a circle is composed of two line segments: a center (whose start and end point coincide), and a circumference (which for the purpose of being stored as a line segment in the data structures also starts and ends at the center).
We had to override the logic in a number of methods for the case of processing ‘line segments’ that were, actually, a circle’s center or its circumference. For example, functions calculating the nearest distance between a point (such as the mouse pointer location) and the ‘line segment’ had to change.
The data structure storing a line segment in the R-* bush also had to be extended. Before it was enough to know what line segment an end point belonged to, and update the point’s coordinates in it when it was dragged. In the case of dragging the center of a circle, we need to also find the ‘line segment’ representing the circumference, and reindex it with the same radius but at a different location in the R-* bush.
Here’s a link to the pull request that was merged:
Here’s the discussion of the issue ticket: