Search code examples
angularopenlayers-6angular-openlayers

Angular/Openlayers6: show a polygon on a map


How can I draw a polygon on a map using Openlayers 6 and Angular 10?

My component HTML file is:

<div id="map" class="map"></div>

The component's styling:

.map {
  width: 100%;
  height: 100vh;
}

The component logic:

import ... all imports

@Component({
  selector: 'app-openlayers-polygon',
  templateUrl: './openlayers-polygon.component.html',
  styleUrls: ['./openlayers-polygon.component.css']
})
export class OpenlayersPolygonComponent implements AfterViewInit {
  map: Map;
  vectorSource: VectorSource;
  vectorLayer: Vector;
  // Update via @Mike
  coordinatesPolygon = [[[48.12345, 25.1234], [46.12345, 25.1234], [46.12345, 28.1234], [48.12345, 28.1234], [48.12345, 25.1234]]];

  ngAfterViewInit() {
    let polygonStyle = new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 0, 0.2)'
      }),
      stroke: new Stroke({
        color: '#ffcc33',
        width: 10
      })
    });
    this.vectorSource = new VectorSource({ features: [] });
    this.vectorLayer = new Vector({
      source: this.vectorSource,
      styles: [polygonStyle]
    });
    this.map = new Map({
      target: 'map',
      layers: [
        new TileLayer({
          source: new XYZ({
            url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
          })
        }),
        this.vectorLayer
      ],
      view: new View({
        center: [813079.7791264898, 5929220.284081122],
        zoom: 7
      }),
      controls: defaultControls().extend([
        new ZoomToExtent({
          extent: [
            813079.7791264898, 5929220.284081122,
            848966.9639063801, 5936863.986909639
          ]
        })
      ])
    });
    this.addPolygon();
  }

  addPolygon() {
    // Update via @Mike
    const geometry = new Polygon(this.coordinatesPolygon).transform('EPSG:4326', this.map.getView().getProjection());
    this.vectorLayer.getSource().addFeature(geometry);
  }
}

I checked also whether the layer ordering was right. No change.

The final solution realised by @Mike is:

import {AfterViewInit, Component} from '@angular/core';
import {defaults as defaultControls} from 'ol/control';

import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import ZoomToExtent from "ol/control/ZoomToExtent";
import VectorSource from "ol/source/Vector";
import Vector from "ol/layer/Vector";
import { Fill, Stroke, Style } from "ol/style";
import Polygon from "ol/geom/Polygon";
import Feature from "ol/Feature";

@Component({
  selector: 'app-openlayers-polygon',
  templateUrl: './openlayers-polygon.component.html',
  styleUrls: ['./openlayers-polygon.component.css']
})
export class OpenlayersPolygonComponent implements AfterViewInit {
  vectorLayer: Vector;
  map: Map;
  coordinatesPolygon = [
    [
      [15.1234, 48.12345],
      [15.1234, 46.12345],
      [18.1234, 46.12345],
      [18.1234, 48.12345],
      [15.1234, 48.12345]
    ]
  ];

  ngAfterViewInit() {
    let polygonStyle = new Style({
      fill: new Fill({
        color: "rgba(255, 255, 0, 0.2)"
      }),
      stroke: new Stroke({
        color: "#ffcc33",
        width: 10
      })
    });
    let vectorSource = new VectorSource({features: []});
    this.vectorLayer = new Vector({
      source: vectorSource,
      styles: [polygonStyle]
    });
    this.map = new Map({
      target: "map",
      layers: [
        new TileLayer({
          source: new XYZ({
            url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          })
        }),
        this.vectorLayer
      ],
      view: new View({
        center: [813079.7791264898, 5929220.284081122],
        zoom: 7
      }),
      controls: defaultControls().extend([
        new ZoomToExtent({
          extent: [
            813079.7791264898,
            5929220.284081122,
            848966.9639063801,
            5936863.986909639
          ]
        })
      ])
    });
    this.addPolygon();
  }

  addPolygon() {
    const geometry = new Polygon( this.coordinatesPolygon).transform( "EPSG:4326", this.map.getView().getProjection());
    this.vectorLayer.getSource().addFeature(new Feature(geometry));
  }
}

Solution

  • LinearRing and Polygon are constructed directly from coordinate arrays as in the GeoJSON specification. Projection transforms can also be applied to complete geometries.

      coordinatesPolygon = [[[48.12345, 25.1234], [46.12345, 25.1234], [46.12345, 28.1234], [48.12345, 28.1234], [48.12345, 25.1234]]];
    
      let geometry = new Polygon(coordinatesPolygon).transform('EPSG:4326', this.map.getView().getProjection());