What additional shapes can you draw on the OpenLayers map?

OpenLayers additional shapes

Drawing your own shapes in OpenLayers is a nice option, which gives us an opportunity to customize the existing map. I mean not only the plain map set by the basic coding but also the map, which is already equipped with some important data. A good example here is the map generated by the QGIS2Web plugin, which usually includes our product prepared in QGIS. In this case, when we still need to add something more than the standard map content, the drawing feature kit can be very vital.
We can draw at least several types of shapes in the OpenLayers maps, which have been developed across the existing libraries. For the most up-to-date library (at the time when this post is produced) – 6.9.0 the users can draw the following shape types (Pic. 1):
– lines,
– points,
– polygons,
– boxes,
– rectangles,
– circles,
– ellipses,
– stars,
– arrows.

OpenLayers custom drawings - standard shapes

Pic. 1 Standard shapes of the OpenLayers custom drawings, where: 1 – Circle; 2 – Box; 3 – Rectangle; 4 – Star; 5 – Points; 6 – Lines; 7 – Polygons; 8 – Ellipse; 9 – Oblique ellipse; 10 – Arrow.

All the codes for the aforementioned shapes you can find by searching the attached links beneath this text.

Apart from this standard kit presented above, the user can modify the JavaScript code slightly and get some additional objects in order to expand its signatures gear. It’s a really straightforward thing and can be achieved by modifying the code for the “Star” shape, which looks initially like this:

var starInteraction = new ol.interaction.Draw({
    source: vectorLayer.getSource(),
    type: 'Circle',
  geometryFunction: function (coordinates, geometry) {
    if (!geometry) {
      geometry = new ol.geom.Polygon([]);
    }
              var center = coordinates[0];
              var last = coordinates[1];
              var dx = center[0] - last[0];
              var dy = center[1] - last[1];
              var radius = Math.sqrt(dx * dx + dy * dy);
              var rotation = Math.atan2(dy, dx);
              var newCoordinates = [];
              var numPoints = 12;
              for (var i = 0; i < numPoints; ++i) {
                var angle = rotation + i * 2 * Math.PI / numPoints;
                var fraction = i % 2 === 0 ? 1 : 0.5;
                var offsetX = radius * fraction * Math.cos(angle);
                var offsetY = radius * fraction * Math.sin(angle);
                newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
              }
              newCoordinates.push(newCoordinates[0].slice());
              geometry.setCoordinates([newCoordinates]);
              return geometry;
            }
});

where the most interesting lines have been highlighted in blue and red. The most profitable is the red code lines, where you can do the modification without disturbing the rotation features. Below I have listed the 15 new shapes, which we can implement easily in our drawing kit.

A. FLAT TRIANGLE

var numPoints = 3;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 50 === 0 ? 0 : 2;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

B. EQUILATERAL TRIANGLE

var numPoints = 6;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 1 : 0.5;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

C. ISOSCELES TRIANGLE

var numPoints = 3;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 0.5 : 2;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

other approaches:

var fraction = i % 2 === 1 ? 7 : 4;
var fraction = i % 10 === 0 ? 3 : 2;

D.  DIAMOND

var numPoints = 4;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 1 : 0.5;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

E. PENTAGON

var numPoints = 5;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 1 ? 2 : 2;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

F. HEXAGON

var numPoints = 6;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 3 === 3 ? 1 : 0.5;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

other approaches:

var fraction = i % 0 === 0 ? 1 : 0.5;

G. OCTAGON

var numPoints = 8;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 1 === 0 ? 1 : 10;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

H. BOW

var numPoints = 8;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 4 === 0 ? 1 : 10;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

I. PACMAN

var numPoints = 24;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 50 === 0 ? 0 : 2;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

J. 12 ARM STAR

var numPoints = 24;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 0.5 : 25;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

K. 3 ARM CROSS

var numPoints = 6;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 1 : 7.5;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

Other approaches:

var fraction = i % 2 === 1 ? 0.5 : 10;

L. 4 ARM CROSS

var numPoints = 8;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 1 : 10;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

M. 4 ARM CROSS THIN

var numPoints = 8;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 0 ? 0.5 : 25;
               var offsetX = radius * fraction * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

N. PARALLELOGRAM

var numPoints = 8;
             for (var i = 0; i < numPoints; ++i) {
               var angle = rotation + i * 2 * Math.PI / numPoints;
               var fraction = i % 2 === 1 ? 1 : 1.5;
               var offsetX = (radius*3) * (fraction) * Math.cos(angle);
               var offsetY = radius * fraction * Math.sin(angle);
               newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);

O. SEMICIRCLE

var numPoints = 48;
              for (var i = 0.5; i * 2 < numPoints; ++i) {
                var angle = rotation + i * 2 * Math.PI / numPoints;
                var fraction = i % 2 === 0 ? 1 : 0.5;
                var offsetX = radius * fraction * Math.cos(angle);
                var offsetY = radius * fraction * Math.sin(angle);
                newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
              }

As a summary of my approaches, please see all the considered shapes below:

OpenLayers additional shapes

Pic. 2 Additional shapes, which can be implemented to your drawing kit in OpenLayers, where: 1 – Flat triangle (A); 2 – Equilateral triangle (B); 3 – Isosceles triangle (C); 4 – Diamond (D); 5 – Pentagon (E); 6 – Hexagon (F); 7 – Oxagon (G); 8 – Bow (H); 9 – Pacman (I); 10 – 12 arm star (J); 11 – 3 arm cross (K); 12 – 4 arm cross (L); 13 – 4 arm cross thin (M); 14 – Parallelogram (N); 15 – Semicircle (O).

and treat them purely as a proposal. I guess you can still fiddle with the code presented, both for the “Star” shape as well as others, and provide your own geometry, which you need. This article is mostly for OpenLayers users, who are in an entry-level position with javascript coding and can tweak just some values. If you are savvier with this stuff, the geometry section will be something too big to adjust.

Mariusz Krukar

References:

  1. Farkas G., 2016, Mastering OpenLayers 3, Packt Publishing, Birmingham
  2. Langley J.P., Perez A.S., 2016, OpenLayers 3.x Cookbook – Second Edition, Packt Publishing, Birmingham, ISBN 9781785287756

Links:

  1. https://openlayers.org/en/latest/examples/draw-shapes.html
  2. https://openlayers.org/en/latest/examples/draw-and-modify-features.html
  3. https://openlayers.org/en/latest/examples/regularshape.html
  4. OpenLayers – drawing shapes – code example 1
  5. http://tsauerwein.github.io/ol3/animation-flights/examples/draw-features.html
  6. OpenLayers – drawing geometric figures – code example
  7. https://www.giserdqy.com/wp-content/guids/ol-v4.6.5/apidoc/ol.interaction.Draw.html
  8. OpenLayers API draw (Chinese)
  9. https://openlayers.org/en/latest/examples/layer-z-index.html
  10. https://dolmenweb.it/viewers/openlayer/examples/draw-shapes.html
  11. https://openlayers.org/en/latest/examples/line-arrows.html
  12. https://openlayers.org/workshop/en/vector/draw.html
  13. Drawing regular shapes with OpenLayers

Forums:

  1. https://gis.stackexchange.com/questions/263626/drawing-shapes-and-features-in-openlayers-4
  2. OpenLayers can you draw some special shapes?
  3. https://stackoverflow.com/questions/45849772/styling-openlayers-draw-interaction
  4. https://gis.stackexchange.com/questions/303646/customize-behaviour-of-ol-interaction-draw-createbox-geometryfunction
  5. ol.interaction.Draw – start point
  6. https://stackoverflow.com/questions/46709716/openlayers-4-changing-the-draw-order-of-selected-features
  7. Draw shape – star
  8. https://stackoverflow.com/questions/41606206/draw-arrow-without-using-any-image-in-openlayers3
  9. https://stackoverflow.com/questions/50917824/openlayer-4-draw-arrows-on-map/50922088
  10. https://stackoverflow.com/questions/31647238/how-to-draw-an-ellipse-using-openlayers3
  11. https://gis.stackexchange.com/questions/270603/drawing-ellipse-in-openlayers
  12. https://stackoverflow.com/questions/23264721/how-to-draw-circle-with-radius-in-openlayers
  13. https://stackoverflow.com/questions/33996409/draw-a-circle-with-defined-diameter-in-openlayers

My questions:

  1. https://stackoverflow.com/questions/69301542/openlayers-cant-draw-the-star
  2. https://stackoverflow.com/questions/69768050/problem-with-drawing-arrows-in-openlayers
  3. https://stackoverflow.com/questions/69311837/openlayers-circle-coordinates-are-missing

 

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *