0

I am using OpenLayers 5 https://openlayers.org/ and want the user to draw a simple grid (like in the attached image). The user should be able to draw the grid anywhere on the map like a polygon. I was searching for a build-in solution in OpenLayers, but I only found the graticule layer (https://openlayers.org/en/latest/examples/graticule.html), what does not really fit my requirements. As I understand the graticule overlays the whole map and cannot be modified.

Furthermore, it should be possible to move and change the size of the grid, and to make the grid cell size customizable (maybe with the modify interaction). Additionally, if such a grid is on the map and the user draws a line with the draw interaction, the snap interaction should work to the grid.

Does anyone know an easy solution for this problem or do I have to make this on my own with draw interaction and more polygones inside.

Any help is welcome!

enter image description here

K.E.
  • 818
  • 2
  • 12
  • 28

1 Answers1

0

The following typescript code will hopefully put you on the right track to draw a grid on an openlayers map. The modify and snap interactions are not in it (translate interaction is), but good luck with it. ;)

/*
 * Add a Grid drawing
 */
drawGrid(rows: number, cols: number, gridColor: string) {
    this.gridDraw = new Draw({
        source: this.drawingLayer.getSource(),
        type: GeometryType.CIRCLE,
        geometryFunction: createBox()
    });

    // Add the interaction for drawing to the map
    this.map.addInteraction(this.gridDraw);

    // On the start of the drawing, a feature is created and we set now the style (with the correct line color)
    this.gridDraw.on('drawend', e => {
        e.feature.setStyle(this.getGridStyle(e.feature, cols, rows, gridColor));

        // Translate is to drag the feature
        const translate = new Translate({
            features: new Collection([e.feature]),
        });

        translate.on('translating', ev => {
            ev.features.getArray()[0].setStyle(this.getGridStyle(ev.features.getArray()[0], cols, rows, gridColor));
        });
        translate.on('translateend', ev => {
            ev.features.getArray()[0].setStyle(this.getGridStyle(ev.features.getArray()[0], cols, rows, gridColor));
        });
        this.map.addInteraction(translate);
        this.gridInteractions.push(translate);
    });
}

/*
 * Set the styles for the grid
 */
private getGridStyle(feature: Feature, cols: number, rows: number, gridColor: string | number[]) {
    const styles = [];
    // Add the outer box style
    styles.push(new Style({
        stroke: new Stroke({
            color: gridColor,
            width: 2
        }),
        fill: new Fill({
            color: 'transparent'
        })
    }));

    // Get the coordinates of the outer box
    const extent = feature.getGeometry().getExtent();
    const bottomLeftCoord = getBottomLeft(extent);
    const topLeftCoord = getTopLeft(extent);
    const topRightCoord = getTopRight(extent);

    // Cols
    const gridWidth = topRightCoord[0] - topLeftCoord[0];
    const colWidth = gridWidth / cols;
    let xColCoord = [topLeftCoord[0] + colWidth, topLeftCoord[1]];
    const yColCoord = [bottomLeftCoord[0] + colWidth, bottomLeftCoord[1]];

    // Draw a vertical line for each column
    for (let i = 1; i <= cols - 1; i++) {
        styles.push(new Style({
            geometry: new LineString([xColCoord, yColCoord]),
            stroke: new Stroke({
                color: gridColor,
                width: 2
            })
        }));

        // Update the coordinates for the next column
        xColCoord[0] = xColCoord[0] + colWidth;
        yColCoord[0] = yColCoord[0] + colWidth;
    }

    // Rows
    const gridHeight = bottomLeftCoord[1] - topLeftCoord[1];
    const rowHeight = gridHeight / rows;
    const xRowCoord = [topLeftCoord[0], topLeftCoord[1] + rowHeight];
    let yRowCoord = [topRightCoord[0], topRightCoord[1] + rowHeight];

    // Draw a horizontal line for each row
    for (let i = 1; i <= rows - 1; i++) {
        styles.push(new Style({
            geometry: new LineString([xRowCoord, yRowCoord]),
            stroke: new Stroke({
                color: gridColor,
                width: 2
            })
        }));

        // Update the coordinates for the next row
        xRowCoord[1] = xRowCoord[1] + rowHeight;
        yRowCoord[1] = yRowCoord[1] + rowHeight;
    }

    return styles;
}
KGilis
  • 1
  • 2