OpenLayers – How to Get Extent of Image Layer in OpenLayers

extentsopenlayers

Considering the code below (which uses openlayers and Viglino's ol-ext), how do I get the extent of the geoimg?

var map = new ol.Map({
  target: 'map',
  view: new ol.View({
    zoom: 18,
    center: ol.proj.fromLonLat([4.8728,52.3316])
  }),
  layers: [new ol.layer.Tile({
    source: new ol.source.OSM()
  })]
})

var geoimg = new ol.layer.Image({
  name: "Georef",
  opacity: 0.5,
  source: new ol.source.GeoImage({
    url: 'image.jpg',
    imageCenter: ol.proj.fromLonLat([4.8728,52.3316]),
    projection: 'EPSG:3857',
    imageScale: [1, 1]
  })
})
map.addLayer(geoimg);

Here is a jsfiddle, which shows how a 160×160 pixels geoimage, with an imageScale of [1,1] measures 100 by 100 meters on the map. You can measure it yourself, but I placed the picture on the map between 2 streets that I know are 100 meters apart.

Things that do not work:

geoimg.getExtent()

it correctly says undefined because getExtent only gets the extent that was set for the Image Layer, which is a masking extent according to the OpenLayers documentation.

I also tried to look into geoimg.values_.source.canvas_.extent, which obviously returns the extent of the canvas, i.e. the div with the id="map"

EDIT1: After the discussion I had with @TomazicM in the comments, I noticed that my question might not be clear. The picture I am overlaying is not a map picture as in Vigliano's example, but a regular picture. I don't want to find out the coordinates of where the geoimage should land to be georeferenced. This wouldn't make sense in the context of the image not being an actual map image. I only want to overlay an image somewhere on the map (which works perfectly, with the rotation and everything), and afterwards extract the map coordinates of the corners of the image as it was overlaid on the map.

If imageScale =[1,1] would have meant that 1 pixel = 1 map units, I would have managed to do the math myself. Math is not the problem. The problem is that scale seems to create an image that is about 1 pixel ~ 0.625 meters, for the EPSG:3857 CRS. I don't know whether this 0.625 or a close value is hardcoded somewhere in ol-ext, or in openlayers or maybe is calculated based on something. Either way, what I am missing is a reliable way to calculate the map coordinates of the corners of the image, once the image is overlaid on the map.

Best Answer

So here is finally the answer. If GeoImage is declared with imageScale: [1, 1] then each pixel on map measures 1 map unit. These units are usually called meters, but in projected CRS (usually Mercator) do not correspond to actual meters in nature. Further north you go, more distorted they become. Scale factor for short distances is factor = 1 / cos(latitude) (see Calculating distance scale factor by latitude for Mercator). cos(52.3316) is 0.611, almost exactly the value you found out in your calculation.

So, if center of your image in projected coordinates is

var center = ol.proj.fromLonLat([4.8728,52.3316]);

and dimensions of your picture are 160 by 160 pixels, then coordinates of upper left corner of the picture are

var imgUpLeft = ol.proj.toLonLat([center[0] - 80, center[1] - 80]);