Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenLayers rendering Geometry to Canvas

I saw an example of "Render geometries to a canvas":

  var canvas = document.getElementById('canvas');
  var vectorContext = ol.render.toContext(canvas.getContext('2d'), {size: [100, 100]});

  var fill = new ol.style.Fill({color: 'blue'});
  var stroke = new ol.style.Stroke({color: 'black'});
  var style = new ol.style.Style({
    fill: fill,
    stroke: stroke,
    image: new ol.style.Circle({
      radius: 10,
      fill: fill,
      stroke: stroke
    })
  });
  vectorContext.setStyle(style);

  vectorContext.drawGeometry(new ol.geom.LineString([[10, 10], [90, 90]]));
  vectorContext.drawGeometry(new ol.geom.Polygon([[[2, 2], [98, 2], [2, 98], [2, 2]]]));
  vectorContext.drawGeometry(new ol.geom.Point([88, 88]));

But what to do with the geometry in the projection EPSG:4326 (or EPSG:3857)?

PS I saw the question "How can we render an OpenLayers 3 feature to a canvas using a style but not using a map", but I don't understand what projection the code works with. And to clarify the author does not allow me to low reputation on stackoverflow.

like image 933
Евгений Гуреев Avatar asked Apr 25 '26 22:04

Евгений Гуреев


1 Answers

@Catch I dug in a little. In that answer he uses canvas.width (in pixels) and ol.extent.getWidth(extent) /height. ol.Extent is only array of numbers and don't have any information about coordinate system. If you would use geographic coordinates it would work with them like they are carthesian. So it depends on what area you want to diplay, but I would recomend to tranform it to some projection and then use the advised approach - translate, scale, translate (scale is now supported in ol.geom).

I was able to draw a polygon on canvas:

    var geoJson = '{"type":"Polygon","coordinates":[[[32.00592041015625,49.55951603052614],[31.97296142578125,49.51673910294474],[32.103424072265625,49.433752230525585],[32.224273681640625,49.346151509388676],[32.54974365234375,49.24718981286537],[32.81890869140625,49.09814978542761],[32.80517578125,49.0729662700941],[32.85736083984375,49.0657686340536],[32.87933349609375,49.08376076915357],[32.95623779296875,49.067568140816434],[32.98370361328125,49.09095579858044],[33.145751953125,49.081961848889364],[33.11828613281251,49.067568140816434],[33.123779296875,49.056770122686174],[33.24737548828125,49.063969062121345],[33.23089599609375,49.16284875720291],[33.12652587890625,49.18080571099239],[33.079833984375,49.256153800301064],[32.95898437500001,49.28841067865025],[32.87933349609375,49.3295971091282],[32.83538818359375,49.38863055043896],[32.8436279296875,49.42794681507826],[32.67608642578125,49.4672315972079],[32.67333984375001,49.4297331699307],[32.7447509765625,49.352413884497594],[32.66510009765625,49.34794084076262],[32.52227783203125,49.38460779401288],[32.31079101562501,49.513172668717914],[32.18856811523438,49.50247180563116],[32.18856811523438,49.50247180563116],[32.00592041015625,49.55951603052614]]]}';
var parser  = new ol.format.GeoJSON();
var feature = parser.readFeature( geoJson );
var geom    = feature.getGeometry();

var canvas  = document.getElementById( 'canvas' );

var fill   = new ol.style.Fill({ color: 'blue' });
var stroke = new ol.style.Stroke({ color: 'black' });
var style  = new ol.style.Style({
    fill  : fill,
    stroke: stroke,
    image : new ol.style.Circle({
        radius: 10,
        fill  : fill,
        stroke: stroke
    })
});



function render( height, width, canvas, geometry, style ) {
    var vectorContext = ol.render.toContext(
                                            canvas.getContext( '2d' ),
                                            { size: [width, height] }
                                        );

    var geom   = geometry.clone(),
        line   = geom.getCoordinates()[0],
        extent = ol.extent.boundingExtent( line );

    var dxy = ol.extent.getCenter(extent),
        sxy = [ 
            width / ol.extent.getWidth(extent),
            height / ol.extent.getHeight(extent)
        ];

    var dx = dxy[0],
        dy = dxy[1],
        sx = sxy[0],
        sy = sxy[1];

    geom.translate( -dx, -dy );
    geom.scale( Math.min(sx, sy), -Math.min(sx, sy) );
    geom.translate( width / 2, height / 2 );

    vectorContext.setStyle( style );
    vectorContext.drawGeometry( geom );
}


geom.transform( 'EPSG:4326', 'EPSG:3857' );
render( 400, 400, canvas, geom, style );
<script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
<canvas id="canvas" width="400" height="400" style="width: 400px; height: 400px;"></canvas>

Example:

OpenLayers rendering Geometry to Canvas

like image 116
Евгений Гуреев Avatar answered Apr 28 '26 12:04

Евгений Гуреев