簡體   English   中英

使用 Openlayers ImageCanvas canvasFunction 從另一個來源繪制特征

[英]Using Openlayers ImageCanvas canvasFunction to draw over features from another source

我正在開發一些自定義繪圖工具,這些工具將最容易創建並直接繪制到 canvas 的非常特定的樣式。 我很難弄清楚如何正確地將坐標與像素對齊並將其錨定到 map。

我也無法弄清楚如何在 -180 之前(或者可能 > 360 )之前在 ImageCanvas 上繪制任何東西,除非在預/后期渲染中直接修改畫布的變換,但我不能完全得到那個工作也對。

在下面的小提琴中,我將兩個線特征添加到矢量源中。 一個從 -180,0 到 0,0,另一個從 -400,0 到 -300,0。

在 ImageCanvas 繪制的第一條線特征下方顯示了一條紅線,但它位於錯誤的位置,放大/縮小或平移/平移 map 會導致它四處移動。 紅線應覆蓋藍線。

第二條線要素沒有可見的紅線。 它似乎與變換有關,但我不確定。

我嘗試將范圍添加到投影 object,這似乎確實改變了一些事情,但不清楚在我的情況下 go 應該是什么。

小提琴: https://jsfiddle.net/jroetman/fqsh2z46/51/

const extent = [-400, -85, 400, 85]
const textent = ol.proj.transformExtent(    
  extent,
  "EPSG:4326",
  "EPSG:3857"
)
const canvas = document.createElement("canvas");
const vsource = new ol.source.Vector({ wrapX: false });
const vlayer = new ol.layer.Vector({source: vsource})

const pixProj = new ol.proj.Projection({
  code: "pixel-projection",
  units: "pixels",
})

const points = [[extent[0],0], [extent[0] + 100,0]].map(p =>  ol.proj.transform(p, "EPSG:4326", "EPSG:3857"))
const points2 =  [[-180,0], [0,0]].map(p =>  ol.proj.transform(p, "EPSG:4326", "EPSG:3857"))
vsource.addFeature(new ol.Feature(new ol.geom.LineString(points)))
vsource.addFeature(new ol.Feature(new ol.geom.LineString(points2)))

var ic = new ol.source.ImageCanvas({
  ratio: 1,
  canvasFunction: (extent, resolution, pixelRatio, size, projection) => {

    var ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (let f of vsource.getFeatures()) {        
      const coords = f.getGeometry().getCoordinates();

      const pixel1 = this.map.getPixelFromCoordinate(coords[0]);              
      const pixel2 = this.map.getPixelFromCoordinate(coords[1]);

      ctx.save();
      ctx.beginPath();
      ctx.moveTo(pixel1[0],pixel1[1]);                                   
      ctx.lineTo(pixel2[0],pixel2[1]);                           
      ctx.closePath();
      ctx.strokeStyle = "red";
      ctx.stroke() 
      ctx.restore()


    }
    return canvas;
  },
  projection: pixProj
});


var imageLayer = new ol.layer.Image({
  className: "annotate",
  source: ic,
  zIndex: 100
}); 

var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vlayer,
    imageLayer
  ],
  view:  new ol.View({
    projection: "EPSG:3857",
    minZoom: 2.75,
    center: [-50000,-300000],
    zoom: 6,
    extent:textent
  }),
});

好的,我解決了這個問題,並簡化了一些事情。 我仍然有興趣了解如何更多地使用 ImageCanvas,但現在......

我能夠使用vlayer.getRenderer().context在其“postrender”中直接在矢量圖層本身的 canvas 上繪制

https://jsfiddle.net/jroetman/fqsh2z46/95/

const extent = [-400, -85, 400, 85]
const textent = ol.proj.transformExtent(    
  extent,
  "EPSG:4326",
  "EPSG:3857"
)
const canvas = document.createElement("canvas");
const vsource = new ol.source.Vector({ wrapX: false });
const vlayer = new ol.layer.Vector({source: vsource})


const points = [[extent[0],0], [extent[0] + 100,0]].map(p =>  ol.proj.transform(p, "EPSG:4326", "EPSG:3857"))
const points2 =  [[-50,0], [0,0]].map(p =>  ol.proj.transform(p, "EPSG:4326", "EPSG:3857"))
vsource.addFeature(new ol.Feature(new ol.geom.LineString(points)))
vsource.addFeature(new ol.Feature(new ol.geom.LineString(points2)))

vlayer.on('postrender', () => {

  var ctx = vlayer.getRenderer().context; 

  for (let f of vsource.getFeatures()) {        
    const coords = f.getGeometry().getCoordinates();       
    const pixel1 = this.map.getPixelFromCoordinate(coords[0]);              
    const pixel2 = this.map.getPixelFromCoordinate(coords[1]);

    ctx.save();
    ctx.beginPath();
    ctx.moveTo(pixel1[0],pixel1[1] );                                   
    ctx.lineTo(pixel2[0],pixel2[1]);                         
    ctx.closePath();
    ctx.strokeStyle = "red";
    ctx.stroke() 
    ctx.restore()      

  }       

});


var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vlayer,

  ],
  view:  new ol.View({
    projection: "EPSG:3857",
    minZoom: 2.75,
    center: ol.proj.transform([-10,-5],"EPSG:4326","EPSG:3857"),
    zoom: 5,
    extent:textent
  }),
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM