从坐标图中绘制多边形画布

时间:2017-07-07 11:39:36

标签: javascript html5 canvas leaflet polygon

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

我有一张地图传单Map leaflet  当我选择多边形时,我想用canvas 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>

感谢您的帮助。

1 个答案:

答案 0 :(得分: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; }
<canvas id="canvas" width =300 height = 200></canvas>