1

I've been following the various examples including this OpenLayers: Get Coordinates of drawn features and this https://openlayers.org/en/master/examples/snap.html

and have produced the code below (note in custom projection).

How can I view the coordinates for a drawn point or polygon in a web page?

And even better store them so they can go into a database?

From the old post I can see that the answer involves going back the vector layer and storing the geometries in a new araay, but can't work out the next steps to view in page and save.

  import 'ol/ol.css';
  import Map from 'ol/Map.js';
  import View from 'ol/View.js';
  import {Draw, Modify, Select, Snap} from 'ol/interaction.js';    
  import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js';
  import {TileWMS, Vector as VectorSource} from 'ol/source.js';
  import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
  import WMTS, {optionsFromCapabilities} from 'ol/source/WMTS.js';              
  import {getWidth, getCenter} from 'ol/extent.js';
  import {get as getProjection} from 'ol/proj.js';
  import {register} from 'ol/proj/proj4.js';
  import {format} from 'ol/coordinate';
  import proj4 from 'proj4';
  import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js';      

  proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
      '+x_0=400000 +y_0=-100000 +ellps=airy ' +
      '+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
      '+units=m +no_defs');
  register(proj4);

  var proj27700 = getProjection('EPSG:27700');
  proj27700.setExtent([0, 0, 700000, 1300000]);

  var raster = 
    new TileLayer({
      source: new TileWMS({
      url: 'myserver',
      params: {'LAYERS': 'mylayer', 'TILED': true},
      transition: 0,
      serverType: 'bla'       
      })
    });
  var vector = new VectorLayer({
    source: new VectorSource(),
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Stroke({
        color: '#ffcc33',
        width: 2
      }),
      image: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#ffcc33'
        })
      })
    })
  });

  var map = new Map({      
    layers: [raster, vector],
    target: 'map',
    view: new View({
      projection: 'EPSG:27700',
      center: [408188, 308846],
      zoom: 9
    })
  });

  var ExampleModify = {
    init: function() {
      this.select = new Select();
      map.addInteraction(this.select);

      this.modify = new Modify({
        features: this.select.getFeatures()
      });
      map.addInteraction(this.modify);

      this.setEvents();
    },
    setEvents: function() {
      var selectedFeatures = this.select.getFeatures();

      this.select.on('change:active', function() {
        selectedFeatures.forEach(function(each) {
          selectedFeatures.remove(each);
        });
      });
    },
    setActive: function(active) {
      this.select.setActive(active);
      this.modify.setActive(active);
    }
  };
  ExampleModify.init();

  var optionsForm = document.getElementById('options-form');

  var ExampleDraw = {
    init: function() {
      map.addInteraction(this.Point);
      this.Point.setActive(false);
      map.addInteraction(this.LineString);
      this.LineString.setActive(false);
      map.addInteraction(this.Polygon);
      this.Polygon.setActive(false);
      map.addInteraction(this.Circle);
      this.Circle.setActive(false);
    },
    Point: new Draw({
      source: vector.getSource(),
      type: 'Point'
    }),
    LineString: new Draw({
      source: vector.getSource(),
      type: 'LineString'
    }),
    Polygon: new Draw({
      source: vector.getSource(),
      type: 'Polygon'
    }),
    Circle: new Draw({
      source: vector.getSource(),
      type: 'Circle'
    }),
    getActive: function() {
      return this.activeType ? this[this.activeType].getActive() : false;
    },
    setActive: function(active) {
      var type = optionsForm.elements['draw-type'].value;
      if (active) {
        this.activeType && this[this.activeType].setActive(false);
        this[type].setActive(true);
        this.activeType = type;
      } else {
        this.activeType && this[this.activeType].setActive(false);
        this.activeType = null;
      }
    }
  };
  ExampleDraw.init();

  optionsForm.onchange = function(e) {
    var type = e.target.getAttribute('name');
    var value = e.target.value;
    if (type == 'draw-type') {
      ExampleDraw.getActive() && ExampleDraw.setActive(true);
    } else if (type == 'interaction') {
      if (value == 'modify') {
        ExampleDraw.setActive(false);
        ExampleModify.setActive(true);
      } else if (value == 'draw') {
        ExampleDraw.setActive(true);
        ExampleModify.setActive(false);
      }
    }
  };

  ExampleDraw.setActive(true);
  ExampleModify.setActive(false);

  var snap = new Snap({
    source: vector.getSource()
  });
  map.addInteraction(snap);

1 Answer 1

3

Probably best done by listening for drawend events on each of your draw interactions:

myDraw.on('drawend', function(evt) { 
  console.log(evt.feature.getGeometry().getCoordinates());
});

... and since you are also using a modify interaction:

myModify.on('modifyend', function(evt) { 
  console.log(evt.features.item(0).getGeometry().getCoordinates());
});
3
  • Thanks, I've got that to work with a simplified version of the code. I think I can scale it up from there.
    – user142706
    May 8, 2019 at 15:38
  • getCoordinates() show error if drawed feature is circle.
    – peiman F.
    Mar 2, 2020 at 20:47
  • Yes, circles have .getCenter() and getRadius() methods so you may need to test .getType() before using .getCoordinates()
    – Mike
    Mar 2, 2020 at 22:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.