首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Open层ImageCanvas canvasFunction从另一个源中提取特性

使用Open层ImageCanvas canvasFunction从另一个源中提取特性
EN

Stack Overflow用户
提问于 2022-08-05 20:49:52
回答 1查看 116关注 0票数 1

我正在开发一些定制的绘图工具,这些工具将应用非常具体的样式,最容易创建并直接绘制到画布上。我很难弄清楚如何正确地将坐标与像素对齐,并将其锚定在地图上。

我也想不出如何在ImageCanvas上画任何东西- -180 (或者可能超过360),除非在预/后渲染中直接修改画布的转换,但我也不能完全正确地工作。

在下面的小提琴,我有两个线功能添加到一个矢量源。一个从-180,0绘制到0,0,另一个从-400,0,到-300,0。

在第一行功能下面显示了一条红线,它是由ImageCanvas绘制的,但它位于错误的位置,放大/移出,或者翻译/平移地图会使它移动。红线应该覆盖蓝线。

第二行功能没有可见的红线。这似乎与变换有关,但我不确定。

我尝试在投影对象中添加范围,这似乎确实改变了一些事情,但在我的例子中,还不清楚应该做什么。

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

代码语言:javascript
运行
复制
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
  }),
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-08 16:42:02

好的,我研究了这个问题,并简化了一些事情。我仍然有兴趣了解如何更多地使用ImageCanvas,但目前.

我能够直接在画布上使用vlayer.getRenderer().context绘制矢量层本身的“布局器”。

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

代码语言:javascript
运行
复制
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', (e) => {

  var ctx = vlayer.getRenderer().context; 

  for (let f of vsource.getFeatures()) {        
    const coords = f.getGeometry().getCoordinates();       
    const pixel1 = ol.render.getRenderPixel(e,map.getPixelFromCoordinate(coords[0]));           
    const pixel2 = ol.render.getRenderPixel(e,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
  }),
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73255146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档