【问题标题】:Draw polygon canvas from coordinates map从坐标图绘制多边形画布
【发布时间】:2017-12-11 16:46:36
【问题描述】:

如何将坐标图转换为点画布?

我有一张地图传单Map leaflet 当我选择多边形时,我想用画布 html5 绘制多边形

我有这样的坐标:

[[2.809510437833253,49.408625488749216],[2.8095461924850422,49.40864172401838],[2.8095226856172806,49.40866595550704],[2.809565304449213,49.40868849340382],[2.8097185865450465,49.40858536874469],[2.809677338568488,49.40856463072128],[2.8096442193374154,49.408580757620854],[2.809609885351463,49.40855283978645],[2.809510437833253,49.408625488749216]]

难点在于如何从地图坐标中获取点

这个例子显示多边形画布:

<!DOCTYPE html>
<html>
<body>
<svg height="110" width="200">
<polygon points="130,0 0,160 0,485 270,645 560,485 560,160"/>
</svg>
</body>
</html>

感谢您的帮助。

【问题讨论】:

    标签: javascript html canvas leaflet polygon


    【解决方案1】:

    地图投影

    难题

    地球的问题在于它并不平坦,而我们人类用来绘制和渲染的大部分内容往往是平坦的。为了解决这个问题,我们通过将圆形地球的投影应用到平面地图来接受地图所代表的一些变形。有许多不同类型的投影,常见的一种是墨卡托投影(参见谷歌地图),它会扭曲赤道更南和更北的区域。但这样做是为了保持方向。您可以将指南针放在墨卡托投影地图上并获得准确的方位,但您不能拿尺子来测量距离。

    但大小很重要,简单的解决方案

    但这一切都有一个可取之处。与地球相比,我们人类非常渺小,对于局部地图而言,地球曲率造成的失真是如此之小以至于无关紧要。

    如果您在一个小区域(例如城市和郊区)有一组坐标,您可以只使用方形投影。其中 lat 和 long 是渲染表面网格上的 x 和 y。

    一步一步

    如何获取一些映射数据并将其调整到维护方面的画布。

    所以你有一组点和一个画布上下文

    <canvas id="canvas" width =300 height = 200></canvas>
    ctx = canvas.getContext("2d");
    
     var myPoints = [[2.809510437833253,49.408625488749216],[2.8095461924850422,49.40864172401838],[2.8095226856172806,49.40866595550704],[2.809565304449213,49.40868849340382],[2.8097185865450465,49.40858536874469],[2.809677338568488,49.40856463072128],[2.8096442193374154,49.408580757620854],[2.809609885351463,49.40855283978645],[2.809510437833253,49.408625488749216]]
    

    然后找到这些点的范围(最小和最大坐标)

    var minX,minY,maxX,maxY; 
    myPoints.forEach((p,i) => {
       if(i === 0){ // if first point 
          minX = maxX = p[0];
          minY = maxY = p[1]; 
       }else{
          minX = Math.min(p[0],minX);
          minY = Math.min(p[1],minY);
          maxX = Math.max(p[0],maxX);
          maxY = Math.max(p[1],maxY);
       }
     });
     // now get the map width and heigth in its local coords
     const mapWidth = maxX-minX;
     const mapHeight = maxY-minY;
     const mapCenterX = (maxX + minX) /2;
     const mapCenterY = (maxY + minY) /2;
    

    现在您有了地图范围,您可以通过找到适合宽度和高度的最小比例将其缩放到画布。

     const scale = Math.min(canvas.width / mapWidth,canvas.height / mapHeight);
    

    现在您可以先减去地图中心来绘制地图,然后将其放大,然后移至画布中心。

     ctx.beginPath();
     myPoints.forEach(p => { 
          ctx.lineTo(
              (p[0] - mapCenterX) * scale + canvas.width /2 ,
              (p[1] - mapCenterY) * scale + canvas.height / 2 
          );
     });
     ctx.stroke();
    

    还有一个工作示例。

     ctx = canvas.getContext("2d");
     
     var myPoints = [[2.809510437833253,49.408625488749216],[2.8095461924850422,49.40864172401838],[2.8095226856172806,49.40866595550704],[2.809565304449213,49.40868849340382],[2.8097185865450465,49.40858536874469],[2.809677338568488,49.40856463072128],[2.8096442193374154,49.408580757620854],[2.809609885351463,49.40855283978645],[2.809510437833253,49.408625488749216]]
    
    var minX,minY,maxX,maxY; 
    myPoints.forEach((p,i) => {
       if(i === 0){ // if first point 
          minX = maxX = p[0];
          minY = maxY = p[1]; 
       }else{
          minX = Math.min(p[0],minX);
          minY = Math.min(p[1],minY);
          maxX = Math.max(p[0],maxX);
          maxY = Math.max(p[1],maxY);
       }
     });
     // now get the map width and heigth in its local coords
     const mapWidth = maxX-minX;
     const mapHeight = maxY-minY;
     const mapCenterX = (maxX + minX) /2;
     const mapCenterY = (maxY + minY) /2;
     
     // to find the scale that will fit the canvas get the min scale to fit height or width
     const scale = Math.min(canvas.width / mapWidth,canvas.height / mapHeight);
     
     // Now you can draw the map centered on the cavas
     ctx.beginPath();
     myPoints.forEach(p => { 
          ctx.lineTo(
              (p[0] - mapCenterX) * scale + canvas.width /2 ,
              (p[1] - mapCenterY) * scale + canvas.height / 2 
          );
     });
     ctx.stroke();
    canvas { border : 2px solid black; }
    &lt;canvas id="canvas" width =300 height = 200&gt;&lt;/canvas&gt;

    【讨论】:

    • 非常感谢您提供这个无价的答案。我正要问同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 2012-08-19
    • 1970-01-01
    • 2011-06-17
    相关资源
    最近更新 更多