canvas模拟中国铁路运行图

原理说明

1、在知道canvas画布尺寸的情况下,需要将地理经纬度信息转换为canvas画布x,y坐标,因为中国地图地理经纬度坐标取值范围为73.33-135.05(经度)37-50(维度),所以第一步需要确认的就是画布的中心位置,这里命名为centerX和centerY,同样的确认中国地图经纬度对应的中心位置,这里命名为positionX,positionY。

2、人为定义一个放大值range,这个值主要作用就是等比例的将中国地图在canvas画布中放大,range的数值需要根据画布横向尺寸跨度值与中国地图经纬度中经度跨度值相除来求解出来。

3、根据range值将中国地图等比例的在canvas画布上绘制出来。

4、获取地图上需要展示的轨迹经纬度信息,根据上述2,3在canvas画布上绘制出来。

5、定义一个rate值,用于表示在轨迹上运行物体的速度,为了能够保证运行物体轨迹沿着轨迹运行,需要在轨迹任意两个点之间求出横向宽度和纵向跨度,并且以跨度最大的那个为基准求解出轨迹上需要绘制多少个轨迹点,然后从过跨度较小的那个除以求解出来的轨迹点数量得出相应的速率。

6、在轨迹上点和横纵向运行速度确定之后,通过调用requestAnimationFrame函数实现标记点的运动。

效果图如下(图中轨迹经纬度信息纯属虚构)

中国地图绘制方法

function drawShapeOptionFun () {
   // 绘制中国地图
   chinaGeometry.features.forEach(function (chinaItem, chinaIndex) {
      var length = chinaItem.geometry.coordinates.length;
      var multipleBool = length > 1 ? true : false;
      chinaItem.geometry.coordinates.forEach(function (chinaChildItem, wordItemIndex) {
          if (multipleBool) {
             // 值界可以使用的经纬度信息
             if (chinaChildItem.length && chinaChildItem[0].length == 2) {
                 drawCanvasFun(chinaChildItem);
             }
             // 需要转换才可以使用的经纬度信息
             if (chinaChildItem.length && chinaChildItem[0].length > 2) {
                 chinaChildItem.forEach(function (countryItem, countryIndex) {
                     drawCanvasFun(countryItem);
                 })
             }
          } else {
              var countryPos = null;
              if (chinaChildItem.length > 1) {
                  countryPos = chinaChildItem;
              } else {
                 countryPos = chinaChildItem[0];
              }
              if (countryPos) {
                  drawCanvasFun(countryPos);
              }
           }
        })
     })
}
// canvas绘制平面
function drawCanvasFun (itemPosition) {
    ctx.fillStyle = mapColor;
    ctx.strokeStyle = mapLineColor;
    ctx.beginPath();
    ctx.moveTo(width / 2 + (itemPosition[0][0] - averageX) * range, height / 2 - (itemPosition[0][1] - averageY) * range);
        itemPosition.forEach(function (item) {
        ctx.lineTo(width / 2 + (item[0] - averageX) * range, height / 2 - (item[1] - averageY) * range);
    })
    ctx.fill();
    ctx.stroke();
    ctx.closePath();}

中国地图上轨迹和轨迹上运行点坐标确认方法

function drawMetapFun (pointObj,index) {
      ctx.shadowOffsetX = 0; // 设置水平位移
      ctx.shadowOffsetY = 0; // 设置垂直位移
      ctx.shadowBlur = 1; // 设置模糊度
      ctx.shadowColor = pointObj.color; // 设置阴影颜色
      ctx.strokeStyle = pointObj.color;
      ctx.lineWidth = pointObj.lineWidth;
      ctx.beginPath();
      ctx.moveTo(width / 2 + (pointObj.data[0][0] - averageX) * range,height / 2 - (pointObj.data[0][1] - averageY) * range)
      pointObj.data.forEach(function (item, index) {
        if (index != 0) {
            ctx.lineTo(width / 2 + (item[0] - averageX) * range,height / 2 - (item[1] - averageY) * range)
         }
      })
      ctx.stroke();
      // 轨迹上运行的点
      ctx.shadowOffsetX = 0; // 设置水平位移
      ctx.shadowOffsetY = 0; // 设置垂直位移
      ctx.shadowBlur = 1; // 设置模糊度
      ctx.shadowColor = pointObj.color; // 设置阴影颜色
      ctx.fillStyle = pointObj.color;
      ctx.beginPath();
      ctx.arc(width / 2 + (pointPositionArray[index].data[pointPositionArray[index].index][0] - averageX) * range,
          height / 2 - (pointPositionArray[index].data[pointPositionArray[index].index][1] - averageY) * range,
          ballRadius,0,2*Math.PI);
//                  ctx.arc(pointPositionArray[index].data[pointPositionArray[index].index][0] + offsetX,pointPositionArray[index].data[pointPositionArray[index].index][1] + offsetY,ballRadius,0,2*Math.PI);
      ctx.closePath();
      ctx.fill();
      if (pointPositionArray[index].index >= pointPositionArray[index].length - 1) {
         pointPositionArray[index].index = 0;
       }
      pointPositionArray[index].index ++;
}
function getMetap (pointArray) {
      pointArray.forEach(function (item) {
        getMetapFun(item);
      })
}
function getMetapFun (pointObj) {
      var dataArray = [];
      pointObj.data.forEach(function (item, index) {
        metapXMax = item[0] > metapXMax ? item[0] : metapXMax;
        metapYMax = item[1] > metapYMax ? item[1] : metapYMax;
        metapXMin = item[0] < metapXMin ? item[0] : metapXMin;
        metapYMin = item[1] < metapYMin ? item[1] : metapYMin;
        if (index != 0) {
               ctx.lineTo(item[0],item[1]);
               space = Math.abs(space);
              var diffX = item[0] - pointObj.data[index - 1][0];
               var diffY = item[1] - pointObj.data[index - 1][1];
               var num = 0;
               var _space = 0;
               dataArray.push[pointObj.data[index - 1][0],pointObj.data[index - 1][1]];
               if (Math.abs(diffX) > Math.abs(diffY)) {
                   num = parseInt(Math.abs(diffX) / space);
                   _space = diffY / num;
                   space = diffX > 0 ? space : -space;
                   for (var i = 0; i < num; i ++) {
                      dataArray.push([pointObj.data[index - 1][0] + i * space,pointObj.data[index - 1][1] + i * _space])
                   }
               } else {
                   num = parseInt(Math.abs(diffY) / space);
                   _space = diffX / num;
                   space = diffY > 0 ? space : -space;
                   for (var i = 0; i < num; i ++) {
                      dataArray.push([pointObj.data[index - 1][0] + i * _space,pointObj.data[index - 1][1] + i * space])
                   }
               }
         }
      })
      pointPositionArray.push({
        index: 0,
        length: dataArray.length,
        data: dataArray
      })
}

实例预览地址:canvas模拟中国铁路运行图

后话

希望上述讲解能够帮助到读者!!!

原文地址:https://www.cnblogs.com/gaozhiqiang/p/11762099.html

时间: 2024-11-09 07:19:55

canvas模拟中国铁路运行图的相关文章

用canvas模拟钟表

很久没有更新博客了,最近忙实习准备面试,快要心力交瘁-_-.空闲下来后,用HTML5的canvas模拟的简易钟表,贴上代码. 效果如下: <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>canvas模拟钟表</title> <style> bod

经典!HTML5 Canvas 模拟可撕裂布料效果

这是一个模拟可撕裂布料效果的 HTML5 Canvas 应用演示,效果逼真.你会看到,借助 Canvas 的强大绘图和动画功能,只需很少的代码就能实现让您屏息凝神的效果. 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safari 等现代浏览器中浏览. 源码下载     效果演示 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 404 错误页面设计 让网站动起来!

结合 CSS3 &amp; Canvas 模拟人行走的效果

HTML5 和 CSS3 技术给 Web 带来了新的利器,点燃了 Web 开发人员的激情.所谓只有想不到,没有做不到,的确如此.下面给大家分享一个结合 CSS3 & Canvas 模拟人行走的动画效果. 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safari 等现代浏览器中浏览. 插件下载     效果演示 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 40

canvas 模拟小球上抛运动的物理效果

最近一直想用学的canvas做一个漂亮的小应用,但是,发现事情并不是想的那么简单.比如,游戏的逼真效果,需要自己来coding…… 所以,自己又先做了一个小demo,算是体验一下亲手打造物理引擎的感觉吧.*_* 代码效果预览地址:http://code.w3ctech.com/detail/2524 html: 1 <div class="container"> 2 <canvas id="canvas" style="border:1p

用Canvas,画中国国旗(Canvas基本知识点)

.getContext("2d")=======>获取绘图接口 //2d .beginPath()========>创建绘图路径开始点 .moveTo(x,y)==========>移动绘画点到x,y .lineTo(x,y)============>绘制线条 .strokeStyle = "#000"  ======>设置线条颜色 //黑色(#000) .fillStyle = "#000"  =========&

canvas模拟重力效果

总结 速度和加速度是动画的基础元素,其中两者都是向量,包括了一个重要因素:方向. 要学会应用 分解 和 合成 ,将速度或加速度分解到x.y轴上,然后将每条轴上的加速度或速度相加,然后再分别与物体的位置坐标相加. 附录: 总要公式: (1)将角速度分解为x.y轴上的速度向量 vx = speed * Math.cos(angle) vy = spedd * Math.sin(angle) (2)将角加速度分解为x.y轴上的加速度 ax = force * Math.cos(angle) ay =

pythonGUI编程用Canvas模拟画板

代码如下: from tkinter import * import webbrowser root = Tk() w = Canvas(root,width=400,height=200) w.pack() def paint(event): x1,y1 = (event.x-1),(event.y-1) x2,y2 = (event.x+1),(event.y+1) w.create_oval(x1,y1,x2,y2,fill="red") w.bind("<B1-

《高铁风云录》:铁路与火车的历史,精彩程度不逊于集装箱的历史。讲中国的部分成为资料的堆砌,不够精彩。3星

本书全部资料都是二手的.前半部分讲铁路与火车的发明创造改进的历史,以及日本铁路的发展史,精彩程度不亚于<集装箱改变世界>中的集装箱的历史.后半部分讲中国高铁的发展史,感觉变成资料的堆砌.总体评价3星. 以下是书中一些信息的摘抄: 1:铁路发明的意义再怎么夸大都不为过,这是人类诞生以来第一次能够自如地实现陆上大规模长距离旅行,而这一天的到来到现在还不到200年.#219 2:在铁路的催化下,分裂的德意志走向了统一,并与法国展开了欧洲大陆霸权的争夺,进而引发了两次世界大战:#221 3:瓦特与茶壶

精品软件 推荐 铁路订票网站12306手机订票客户端 家,就在身边

精品软件 推荐  铁路订票网站12306手机订票客户端  家,就在身边 中国铁路客户服务中心订票网站12306.cn今天低调推出手机客户端,目前支持iOS和Android两大系统,目前下载页面已经上线完毕(实际上只有Android能用,iOS版本估计要等到上了App Store才会发行),但我们并没有在首页上看到它的入口,下载测试后证实可用,无论如何大家先下了用用看吧: 官方地址:https://kyfw.12306.cn/otn/appDownload/init