从坐标地图绘制多边形 canvas
Draw polygon canvas from coordinates map
如何将坐标图转换为点canvas?
我有地图传单Map leaflet
当我 select 多边形时,我想用 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]]
难点在于如何从地图坐标中获取点
此示例显示多边形 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>
感谢您的帮助。
地图投影
难题
地球的问题在于它并不平坦,我们人类用来绘制和渲染的大部分内容往往是平坦的。为了解决这个问题,我们通过应用从圆形地球到平面地图的投影来接受地图所代表的一些变形。有许多不同类型的投影,一种常见的是墨卡托投影(参见 google 地图),它会扭曲您所在的赤道以南和以北的区域。但它这样做是为了保持方向。你可以把指南针放在墨卡托投影的地图上,得到准确的方位,但你不能拿尺子来测量距离。
但大小很重要,简单的解决方案
但这一切都有一个可取之处。与地球相比,我们人类是渺小的,对于局部地图来说,地球曲率造成的扭曲是如此之小以至于无关紧要。
如果您在一个小区域(例如城市和郊区)有一组坐标,您可以只使用正方形投影。其中lat和long是渲染表面网格上的x和y。
循序渐进
如何获取一些映射数据并将其拟合到 canvas 维护方面。
所以你有一组点和一个canvas上下文
<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;
现在您有了地图范围,您可以通过找到适合宽度和高度的最小比例将其缩放到 canvas。
const scale = Math.min(canvas.width / mapWidth,canvas.height / mapHeight);
现在绘制地图时可以先减去地图中心,然后按比例放大,然后移动到canvas中心。
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>
如何将坐标图转换为点canvas?
我有地图传单Map leaflet 当我 select 多边形时,我想用 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]]
难点在于如何从地图坐标中获取点
此示例显示多边形 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>
感谢您的帮助。
地图投影
难题
地球的问题在于它并不平坦,我们人类用来绘制和渲染的大部分内容往往是平坦的。为了解决这个问题,我们通过应用从圆形地球到平面地图的投影来接受地图所代表的一些变形。有许多不同类型的投影,一种常见的是墨卡托投影(参见 google 地图),它会扭曲您所在的赤道以南和以北的区域。但它这样做是为了保持方向。你可以把指南针放在墨卡托投影的地图上,得到准确的方位,但你不能拿尺子来测量距离。
但大小很重要,简单的解决方案
但这一切都有一个可取之处。与地球相比,我们人类是渺小的,对于局部地图来说,地球曲率造成的扭曲是如此之小以至于无关紧要。
如果您在一个小区域(例如城市和郊区)有一组坐标,您可以只使用正方形投影。其中lat和long是渲染表面网格上的x和y。
循序渐进
如何获取一些映射数据并将其拟合到 canvas 维护方面。
所以你有一组点和一个canvas上下文
<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;
现在您有了地图范围,您可以通过找到适合宽度和高度的最小比例将其缩放到 canvas。
const scale = Math.min(canvas.width / mapWidth,canvas.height / mapHeight);
现在绘制地图时可以先减去地图中心,然后按比例放大,然后移动到canvas中心。
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>