OpenLayers 将几何渲染为 Canvas

OpenLayers rendering Geometry to Canvas

我看到了“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]));

但是如何处理投影中的几何体EPSG:4326(或EPSG:3857)?

PS 我看到了问题“”,但我不明白代码使用的是什么投影。并澄清作者不允许我在 Whosebug.

上的低声誉

HTML canvas 元素用于通过 JavaScript 动态绘制图形。 如果您在 canvas 中的绘图不再有投影,则您处于像素坐标中。您必须以像素为单位转换几何图形。

如果您在地图中绘图,请参阅地图的 getPixelFromCoordinate 功能 canvas。

@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).

我能够在 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>

示例:

OpenLayers rendering Geometry to Canvas