Are you using GeoServer as a backend?
You could construct a GetMap request via JavaScript and use a HTML GET request to get that image.
I use this same approach to programmatically embed static maps into reports in Ms-Access.
EDIT:
I use PostgreSQL to store my data, and GeoServer handles the rendering and serving of that data.
To embed static maps in Ms-Access reports I first get the BoundingBox of the area I'd like a map of. This is done purely in SQL via a custom function to query my PostgreSQL database.
You could get the same answers using ol.extent and its methods (e.g. ol.extent.getBottomLeft()) to get your BoundingBox.
Here is my VBA Code constructing the request.
GetMapString = "http://" + GeoServerHost + "/geoserver/wms?request=GetMap&service=WMS&version=1.1.3" & _
"&layers=" + GeoServerWorkspace + ":" + LayerName & _
"&styles=" & _
"&srs=EPSG:27700" & _
"&bbox=" & x1 & "," & y1 & "," & x2 & "," & y2 & _
"&width=1200&height=1200" & _
"&format_options=dpi:300;antialiasing:on" & _
"&format=image%2Fpng8"
Building an equivalent GetMapString in JavaScript, then sending that with the HTML GET request, should return a PNG8 image.
Be sure to check & change the SRS parameter as you probably wouldn't want your image projected in British National Grid.
The way you're defining the extent assumes that the two extent corners equal two points of your polygon:
const extent = [ coordinates[0][0][0],
coordinates[0][0][1],
coordinates[0][2][0],
coordinates[0][2][1]];
As you can see in your result, the extent is a rectangle with its corners in two of the polygon corners.
Rather, what you want is the extent to contain the max/min values for your easting and northing (pseudocode follows):
const c = coordinates[0];
const extent = [ min( c[0][0], c[1][0], c[2][0], c[3][0] ),
min( c[0][1], c[1][1], c[2][1], c[3][1] ),
max( c[0][0], c[1][0], c[2][0], c[3][0] ),
max( c[0][1], c[1][1], c[2][1], c[3][1] ) ];
You can semi-automate this in several ways. You can use loops and Math.min
/Math.max
, or some OL utility (if this were Leaflet, we would be doing a polygon.getBounds()
call, or a LatLngBounds.extend()
loop).
If your polygon is static, you can simply pick the right points, which if I'm right should be:
const c = coordinates[0];
const extent = [ c[3][0],
c[0][1],
c[1][0],
c[2][1] ];
You should also be able to use ol.extent.boundingExtent
like:
// ol.extent.boundingExtent takes in a plain array of coordinates, so
// we should be able to simply use the outer ring as such.
const extent = ol.extent.boundingExtent(coordinates[0]);
Best Answer
I figured it out, solution would be to get bounds coords from pixels: