javascript html5 canvas实现可拖动省份的中国地图
来源: 阅读:3413 次 日期:2016-07-20 16:18:50
温馨提示: 小编为您整理了“javascript html5 canvas实现可拖动省份的中国地图”,方便广大网友查阅!

本文实例分享了html5 canvas可拖动省份的中国地图实现方法,供大家参考,具体内容如下

1.数据获取

画地图需要省份边界坐标,理论上可以每次都用百度API获取数据并绘图,但为了增加效率,首先将所有坐标都获取下来并存入数据库中。

新建省份数据数组

代码如下:

var allZoneData = [{'name':'辽宁省','been':'yes','id':'01'},<span style="font-family: Arial, Helvetica, sans-serif;">{'name':'吉林省','been':'yes','id':'02'},……];</span> 

轮询该数组,根据省份名称请求百度API获取坐标数据,并将数据以ajax方式放松给php

var myGeo = new BMap.Geocoder(); 

(function(){ 

 for(var i = 0;i < allZoneData.length;i++){ 

  getAllZone(allZoneData[i].name,allZoneData[i].been,allZoneData[i].id); 

 } 

})(); 

//name为省份名,been表示是否去过,id为唯一标识,cir为省份圈号(有可能一个省份有两部分封闭圆圈构成) 

function getAllZone (name,been,id) { 

 var data,temp; 

 var bdary = new BMap.Boundary(); 

 bdary.get(name, function(rs){ 

  var count = rs.boundaries.length;  

  for(var j = 0; j < count; j++){      

   var ply = new BMap.Polygon(rs.boundaries[j], {strokeWeight: 2, strokeColor: "#ff0000"}); 

   data = ply.getPath(); 

   $.ajax({ 

    url: "addData.php", 

    type:"POST", 

    data: {'data':data,'name' : name,'cir':j,'been':been,'id':id}, 

    success: function(txt){ 

     console.log(txt); 

    }, 

    error: function(){ 

     alert('添加数据出错!'); 

    } 

   });   

  }         

 });         

php得到数据后,解析数据并将数据存储到事先建好的数据库中

<?php 

  header("content-type:text/html; charset=utf-8"); 

  $data = $_REQUEST['data']; 

  $name = $_REQUEST['name']; 

  $cir = $_REQUEST['cir']; 

  $been = $_REQUEST['been']; 

  $id = $_REQUEST['id']; 

  $con = mysql_connect("localhost","……","……"); 

  if (!$con){ 

    die('Could not connect: ' . mysql_error()); 

  } 

  mysql_select_db("……", $con); 

  mysql_set_charset('utf8',$con); 

  foreach ($data as $temp){ 

    $sql = "insert into place (id,name,lng,lat,cir,been) values ('".$id."', '".$name."', '".$temp['lng']."','".$temp['lat']."','".$cir."','".$been."')"; 

    if (!mysql_query($sql,$con)){ 

      die('Error: ' . mysql_error()); 

    } 

  } 

  mysql_close($con); 

  echo 'Success'; 

?> 

2.画地图(base地图画在mapCanvas层)

轮询省份数组,并以ajax方式请求该省份边界坐标,然后绘图

var drawMap = function (context,data,l,t) { //context为绘制所在的层,l和t为相对位置,data为边界对象数组 

 if(data.been == 'yes'){ 

  context.fillStyle = "green"; 

 }else{ 

  context.fillStyle = "grey"; 

 } 

 context.globalAlpha = 0.8; 

 context.beginPath(); 

 cleft = (data.coordinate[0].lng - temp_left) * bigger + l; //temp_left和temp_top为地图偏移位置. 

 ctop = (temp_top - data.coordinate[0].lat) * bigger + t; //bigger为放大倍数 

 context.moveTo(cleft,ctop); 

 for(var j = 1;j < data.coordinate.length;j++){ 

  cleft = (data.coordinate[j].lng - temp_left) * bigger + l; 

  ctop = (temp_top - data.coordinate[j].lat) * bigger + t; 

  context.lineTo(cleft,ctop); 

 } 

 context.closePath(); 

 context.stroke(); 

 context.fill(); 

3.画移动连线(连线和移动的省份画在moveMapCanvas层)

当在地图上拖动省份时,出现若干条连接移动的省份和原省份的直线

var drawLinkLine = function(data,l,t){ //此处的l和t表示移动的相对位置 

 for(var k = 0;k < data.coordinate.length;k++){ 

  if(k % 60 == 0){ 

   moveMapContext.beginPath(); 

   //根据移动距离的不同,设置连线的粗细 

   lineLength = Math.sqrt(l * l + t * t) / 100; 

   lineLength = lineLength >= 4.5 ? 4.5 : lineLength; 

   moveMapContext.lineWidth = 5 - lineLength; 

   moveMapContext.strokeStyle = "rgba(0,120,60,0.4)"; 

   cleft = (data.coordinate[k].lng - temp_left) * bigger; 

   ctop = (temp_top - data.coordinate[k].lat) * bigger; 

   moveMapContext.moveTo(cleft,ctop); 

   cleft = (data.coordinate[k].lng - temp_left) * bigger + l; 

   ctop = (temp_top - data.coordinate[k].lat) * bigger + t; 

   moveMapContext.lineTo(cleft,ctop); 

   moveMapContext.closePath(); 

   moveMapontext.stroke(); 

  } 

 } 

4.事件

鼠标按下事件:当点击到地图上时,要做的事是,判断点击位置,将位置信息转化成经纬度,再通过百度API根据经纬度获得省份名称。

$('#eventCanvas').mousedown(function(ev){ 

 //获取点击canvas的坐标 

 var mouseX, mouseY; 

 if(ev.layerX || ev.layerX==0){ 

  mouseX = ev.layerX; 

  mouseY = ev.layerY; 

 }else if(ev.offsetX || ev.offsetX==0){ 

  mouseX = ev.offsetX; 

  mouseY = ev.offsetY; 

 } 

 //保存点击时的原坐标值 

 tempX = mouseX; 

 tempY = mouseY; 

 //将坐标转化为经纬度 

 mouseX = mouseX/bigger + temp_left; 

 mouseY = temp_top - mouseY/bigger; 

 if(opts.dragAll){ 

  draging = true; 

 }else{ 

  moveMapContext.clearRect(0, 0, 1100, 630); 

  //根据经纬度获得所在地理位置并获取边界坐标再画线 

  myGeo.getLocation(new BMap.Point(mouseX, mouseY), 

   function(result){ 

    tempName = ''; 

    draging = true; 

    name = result.addressComponents.province; 

    tempName = name; 

    pubFuns.drawMoveLayerLine(0,0);    

  }); 

 } 

}); 

鼠标移动事件:根据点击的省份名,获得数据,并实时重绘移动层的省份

$('#eventCanvas').mousemove(function(ev){ 

 var mouseX, mouseY; 

 if(ev.layerX || ev.layerX==0){ 

  mouseX = ev.layerX; 

  mouseY = ev.layerY; 

 }else if(ev.offsetX || ev.offsetX==0){ 

  mouseX = ev.offsetX; 

  mouseY = ev.offsetY; 

 } 

 if(draging){ 

  if(opts.dragAll){ <span style="font-family: Arial, Helvetica, sans-serif;">//拖动整个地图,存在问题,地图画的太慢</span> 

   mapContext.clearRect(0, 0, 1100, 630); 

   for(var i = 0;i < allZoneData.length;i++){ 

    for(var j = 0;j < allData[allZoneData[i].name].length;j++){ //allData是第一次读取数据时放到内存里的变量,它包含了所有数据 

     pubFuns.drawMap(mapContext,allData[allZoneData[i].name][j],mouseX - tempX, mouseY - tempY); 

    } 

   } 

   }else{ 

    moveMapContext.clearRect(0, 0, 1100, 630); 

    pubFuns.drawMoveLayerLine(mouseX - tempX, mouseY - tempY); 

   }  

  } 

}); 

鼠标抬起事件:设置dragging为false,clear移动层。

$('#eventCanvas').mouseup(function(e){ 

 if(opts.dragAll){  

 }else{ 

  moveMapContext.clearRect(0, 0, 1100, 630); 

 } 

 draging = false; 

});

名单

小结:功能、原理都很简单,但能熟悉canvas的一些属性和方法。canvas层是可以重叠到一起的,这样就可以在不同的层画不同的内容,方便维护和管理。

以上就是本文的全部内容,希望对大家的学习有所帮助。

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map