问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

three.js 怎么创建地图

发布网友 发布时间:2022-05-06 14:12

我来回答

2个回答

懂视网 时间:2022-04-23 01:12

本篇文章主要介绍了使用D3.js创建物流地图的示例代码,现在分享给大家,也给大家做个参考。

本文介绍了使用D3.js创建物流地图的示例代码,分享给大家,具体如下:

示例图

制作思路

  1. 需要绘制一张中国地图,做为背景。

  2. 需要主要城市的经纬坐标,以绘制路张起点和终点。

  3. 接收到物流单的城市,绘制一个闪烁的标记。

  4. 已经有过物流单的目标城市,不再绘制路线。

  5. 每次新产生一笔物流单,都有一个标记沿路线移向目标的动画效果。

  6. 绘制结束后的数据,需要清理掉,以减少对浏览器的资源占用。

开始撸码

1.创建网页模板

加载D3JS,为了方便调试,直接下载d3.js文件在本地,实际使用的时候,可以换成加载路径。注意,使用的是V4版的D3,和V3版有差异。

创建一个p块,准备绘图。

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf8">
 <script type="text/javascript" src="../../static/d3/d3.js"></script>
 <title>地图</title>
 </head>
 <body>
 <p class="fxmap">
 </p>
 </body>
 <script type="text/javascript"></script>
</html>

创建SVG,以下所有代码放在<script></script>中

var width=1000 , height=800; // 定义SVG宽高
var svg = d3.select("body p.fxmap")
  .append("svg")
  .attr("width", "width) 
  .attr("height", height)
  .style("background","#000"); //

创建SVG图形分组,以备调用

  1. gmp,保存背景地图和起点标记。

  2. mline,保存起点和目标之间的连线,以及目标点。

  3. buttion,测试用的按钮

gmap = svg.append("g").attr("id", "map").attr("stroke", "white").attr("stroke-width",1);
 mline = svg.append("g").attr("id", "moveto").attr("stroke", "#FFF").attr("stroke-width", 1.5).attr("fill","#FFF");
 button = svg.append("g").attr("id", "button").attr("stroke", "white").attr("stroke-width", 1).attr("fill", "white");

创建投影函数

  1. 经纬度不能直接用来绘图,需要转换成平面坐标。d3js提供了比较丰富的投影方法,本例中使用了geoEquirectangular()方法。

  2. projection 是将经纬度转换为平面坐标的方法

  3. path 是将经纬度转换为连线绘制点坐标的方法(省得自己再写函数构造path路径)

var projection = d3.geoEquirectangular()
  .center([465,395]) // 指定投影中心,注意[]中的是经纬度
  .scale(height)
  .translate([width / 2, height / 2]);
var path = d3.geoPath().projection(projection);

创建marker标记,以便多个连线终点调用

  1. 由于会有多个物流连线的终点,所以都放在一个marker标记中调用。

  2. 这个标记是由中间的 圆形 + 外圈 构成。外圈的闪烁效果另外创建。

marker = svg.append("defs")
  .append("marker")
  .append("marker")
  .attr("id", "pointer")
  .attr("viewBox","0 0 12 12") // 可见范围
  .attr("markerWidth","12") // 标记宽度
  .attr("markerHeight","12") // 标记高度
  .attr("orient", "auto") //
  .attr("markerUnits", "strokeWidth") // 随连接线宽度进行缩放
  .attr("refX", "6") // 连接点坐标
  .attr("refY", "6")
 // 绘制标记中心圆
 marker.append("circle")
 .attr("cx", "6")
 .attr("cy", "6")
 .attr("r", "3")
 .attr("fill", "white");
 // 绘制标记外圆,之后在timer()中添加闪烁效果
 marker.append("circle")
 .attr("id", "markerC")
 .attr("cx", "6")
 .attr("cy", "6")
 .attr("r", "5")
 .attr("fill-opacity", "0")
 .attr("stroke-width", "1")
 .attr("stroke", "white");

绘制中国地图,并标记起点(长沙)

地图使用的经纬集为china.json,这个文件网上有很多

// 记录长沙坐标
 var changsha = projection([112.59,28.12]);
 // 读取地图数据,并绘制中国地图
 mapdata = [];
 d3.json('china.json', function(error, data){
 if (error)
 console.log(error);
 // 读取地图数据
 mapdata = data.features;
 // 绘制地图
 gmap.selectAll("path")
 .data(mapdata)
 .enter()
 .append("path")
 .attr("d", path);
 // 标记长沙
 gmap.append("circle").attr("id","changsha")
 .attr("cx", changsha[0])
 .attr("cy", changsha[1])
 .attr("r", "6")
 .attr("fill", "yellow")
 gmap.append("circle").attr("id","changshaC")
 .attr("cx", changsha[0])
 .attr("cy", changsha[1])
 .attr("r", "10")
 .attr("stroke-width", "2")
 .attr("fill-opacity", "0");
 });

创建方法,绘制一条从指定起点到终点的连线,并在络点绘制marker标记。

  1. 方法需要输入终点城市名称(city)和经纬度(data)

  2. 调用之前建立的project()方法,将终点经纬度转换为平面坐标。

  3. 计算起点(长沙)和终点之前的距离,做为线条长度和动画时间参数。

  4. 在线条上绘制一个圆形标记,并实现从起点到终点的移动动画。

  5. 标记移动到终点后,即删除,节省资源。

  6. 如果线点在之前已经绘制过,则不绘线条,只绘制移动标记。

  7. 每处理一次物流单,则城市记录+1。

// 创建对象,保存每个城市的物流记录数量
 var citylist = new Object();
 // 创建方法,输入data坐标,绘制发射线
 var moveto = function(city, data){
 var pf = {x:projection([112.59,28.12])[0], y:projection([112.59,28.12])[1]};
 var pt = {x:projection(data)[0], y:projection(data)[1]};
 var distance = Math.sqrt((pt.x - pf.x)**2 + (pt.y - pf.y)**2);
 if (city in citylist){
 citylist[city]++;
 }else{
 mline.append("line")
  .attr("x1", pf.x)
  .attr("y1", pf.y)
  .attr("x2", pt.x)
  .attr("y2", pt.y)
  .attr("marker-end","url(#pointer)")
  .style("stroke-dasharray", " "+distance+", "+distance+" ")
  .transition()
  .duration(distance*30)
  .styleTween("stroke-dashoffset", function(){
  return d3.interpolateNumber(distance, 0);
  });
 citylist[city] = 1;
 };
 mline.append("circle")
 .attr("cx", pf.x)
 .attr("cy", pf.y)
 .attr("r", 3)
 .transition()
 .duration(distance*30)
 .attr("transform", "translate("+(pt.x-pf.x)+","+(pt.y-pf.y)+")")
 .remove();
 };

创建动画队例,实现标记外圈的闪烁效果

var scale = d3.scaleLinear();
 scale.domain([0, 1000, 2000])
 .range([0, 1, 0]);
 var start = Date.now();
 d3.timer(function(){
 var s1 = scale((Date.now() - start)%2000);
 // console.log(s1);
 gmap.select("circle#changshaC")
 .attr("stroke-opacity", s1);
 marker.select("circle#markerC")
 .attr("stroke-opacity", s1);
 });

创建测试按钮和测试的目标城市数据

var cityordinate = {
 '哈尔滨':[126.5416150000,45.8088260000],
 '石家庄':[116.46,39.92],
 '北京':[116.39564503787867,39.92998577808024],
 '上海':[121.480539,31.235929],
 '广州':[113.271431,23.135336],
 '重庆':[106.558434,29.568996],
 '青岛':[120.38442818368189,36.10521490127382],
 '福州':[119.30347,26.080429],
 '兰州':[103.840521,36.067235],
 '贵阳':[106.636577,26.653325],
 '成都':[104.081534,30.655822],
 '西安':[108.946466,34.347269],
 '长春':[125.3306020000,43.8219540000],
 '台湾':[120.961454,23.80406],
 '呼和浩特':[111.7555090000,40.8484230000],
 '澳门':[113.5494640000,22.1929190000],
 '武汉':[114.3115820000,30.5984670000],
 '昆明':[102.71460113878045,25.049153100453159],
 '乌鲁木齐':[87.56498774111579,43.84038034721766],
 '益阳':[112.36654664522563,28.58808777988717],
 '南京':[118.77807440802562,32.05723550180587],
 '武昌':[114.35362228468498,30.56486029278519],
 };

 // 随机获得目标城市
 var cityname = [], total = 0;
 for (var key in cityordinate){
 cityname[total++] = key;
 };
 
 // 创建操作按钮,每次点击发射一条物流线
 button.append("circle")
 .attr("cx", width*0.9)
 .attr("cy", height*0.8)
 .attr("r", width/20)
 .attr("text","click")
 .attr("fill", "grey");
 button.append("text")
 .attr("x", width*0.87)
 .attr("y", height*0.81)
 .style("font-size", "30px")
 .text("click");
 button.on("click", function(){
 var _index = ~~(Math.random() * total);
 moveto(cityname[_index], cityordinate[cityname[_index]]);
 });

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用百度地图如何实现地图网格

在nodejs中Express与Koa2对比区分(详细教程)

JS中的单例模式实现对数据增删改查

热心网友 时间:2022-04-22 22:20

three.js创建地图的方法:

1.定义html页面

<!DOCTYPE html>

<html>

  <head>

    <title>Three.js Step Tutorial</title>

    <style>

     body {

      margin: 0px;

      background-color: #fff;

      overflow: hidden;

     }

   </style>

  </head>

  <body>

   <script src="js/three.min.js"></script>

   <script src="js/three-tut.js"></script>

  </body>

</html>

2、编写动画脚本anotation.js

var camera; 定义相机

var scene;定义场景画布

var renderer;定义渲染入口

var mesh;定义恢复

  

init();初始化画布

animate();开始动画

  函数定义

function init() {

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);

  

    var light = new THREE.DirectionalLight( 0xffffff );

    light.position.set( 0, 1, 1 ).normalize();

    scene.add(light);

  

    var geometry = new THREE.CubeGeometry( 10, 10, 10);

    var material = new THREE.MeshPhongMaterial( { ambient: 0x050505, color: 0x0033ff, specular: 0x555555, shininess: 30 } );

  

    mesh = new THREE.Mesh(geometry, material );

    mesh.position.z = -50;

    scene.add( mesh );

  

    renderer = new THREE.WebGLRenderer();

    renderer.setSize( window.innerWidth, window.innerHeight );

    document.body.appendChild( renderer.domElement );

  

    window.addEventListener( 'resize', onWindowResize, false );

  

    render();

}

  

function animate() {

    mesh.rotation.x += .04;

    mesh.rotation.y += .02;

  

    render();

    requestAnimationFrame( animate );

}

  

function render() {

    renderer.render( scene, camera );

}

 形状变换

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;

    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

    render();

}

3、运行以上程序,效果如下:

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
找专业防水队做完还漏水怎么维权 法院会受理房屋漏水造成的纠纷吗? 巴西龟最长活多久,家养!!! 养胃的药最好的是什么啊 婴儿积食发烧不愿吃药怎么办 板门穴位在哪个部位 手机设置放偷看的方法? 凝结水回收器生产厂家? 个人账户养老金预测公式:现有5万元,缴费20年,能领多少钱? 临沂比较有名的男装品牌 姓张,男孩取什么名字好 从迪拜到中国: 1通过国际快递把藏红花寄回中国,好多的重量符合规定?可以顺带寄回巧克力吗?2如果人 迪拜有啥国内没有的好东西? 从迪拜回国,想给亲戚朋友带些国外的香烟。不知道买哪种比较好,最好要国内没有卖的,大家给点推荐吧 姓张的男孩取什么名字好 之前在迪拜看到高端聚会上用Laderach巧克力,有谁知道国内哪儿有卖? 阿联酋航空提供的巧克力是什么牌子的? hmgrade13@163·com 四川风干肘子四川风干肘子的做法 剑门关风景区的特色小吃 13h㎡是什么意思 白又方,嫩又香,能做菜,能煮汤,豆子是它爹和妈,它和爹妈不一样。 麦莉的百度百科里介绍她和中国的情缘,说道HM第一季13集里有她穿着印有万里长城的蓝色外套,你们看见了吗 HM因童装不符标准被罚13万,你觉得这个惩罚力度怎么样? hm在上海有多少分店 HM被罚13万,背后的原因是什么? HM十三薪上了刚好半年有嘛? 第一套到第五套硬币一共有多少枚 多肉植物可以用榨干的菜籽油做肥料吗 多肉植物可以用豆腐渣作为肥料吗? three.js实现全景地图 怎么创建地图 three.js 加载了大对象osgb,请问如何添加到场景中 长期不干家务,久生刷视频的坏处 代账客户要求代账会计作为经办人更改本公司公户银行预留信息应该如何操作 在1213新车选号随机自编没选上怎么办? 最新号段能随机选择吗 为什么太原网上机动车选号,老是不可选,我试了很多都不行?急 电脑电源坏了会不会把电脑主板烧坏 请问蚂蚁借呗下款到银行卡里对方说要公证费? 电脑主板会因为电源电压不稳而导致烧坏吗? 关于公司借款合同的公证问题 电源会烧坏主板和cpu么 鼠标边上两个按键是干什么的 还有中间一个按键是什么用的? 搜狗浏览器上面收藏夹??我收藏了好多链接地址,我想找到它们,请问在哪里?严重谢谢 搜狗高速浏览器在哪里输入网址? 过期的纯牛奶可以洗脸吗? 请问:1994年元宵节是阳历多少号?麻烦快速帮忙回答 在搜狗浏览器中怎样把打开的网址添加到最常访问栏? 搜狗浏览器6.0为网页设置在哪 过期的纯牛奶可以洗脸吗怎么洗