最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Draw polygon canvas from coordinates map - Stack Overflow

programmeradmin5浏览0评论

How to transform coordinates map to point canvas?

I have a map leaflet Map leaflet and when i select polygon, i want to draw the polygon with canvas html5

I have coordinates like this :

[[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]]

The difficulty is how to get points from map coordinates

This example to display polygon canvas :

<!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>

Thanks for your help.

How to transform coordinates map to point canvas?

I have a map leaflet Map leaflet and when i select polygon, i want to draw the polygon with canvas html5

I have coordinates like this :

[[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]]

The difficulty is how to get points from map coordinates

This example to display polygon canvas :

<!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>

Thanks for your help.

Share Improve this question asked Jul 7, 2017 at 11:39 IssamIssam 351 silver badge8 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

Map projections

Difficult problem

The problem with the earth is that is is not flat, and most of what we humans use to draw and render to tends to be flat. To fix the problem we accept some deformation of what the map represents by applying a projection from the round Earth to the flat map. There are many many different types of projections, a mon one is the mercator projection (see google maps), it distorts area the further south and north of the equator you are. But it does this to maintain direction. You can put a pass on a mercator projected map and get an accurate bearing, but you can't take a ruler and measure the distance.

But size matters, easy solution

But there is one saving grace in all this. We humans are tiny pared to the Earth and for local maps the distortion caused by the curvature of the Earth is so small to be irrelevant.

If you have a set of coordinates in a small area (eg a city and suburbs) you can just use a square projection. Where lat and long are x and y on the grid of rendering surface.

Step by step

How to take some mapping data and fit it to a canvas maintaining the aspect.

So you have a set of points and a canvas context

<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]]

Then find the extent of those points (the min and max coordinates)

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;

Now you have the map extent you can scale it to the canvas by finding the smallest scale to fit both width and height.

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

Now you can draw the map first subtracting the map center, then scaling it up, then moving ot to the canvas center.

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

And a working example.

 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>

发布评论

评论列表(0)

  1. 暂无评论