用D3和ArcGIS结合做效果已经将近一年的时间,却一直没有时间整理博客,将知识分享,终于,我的第一遍博客将迎来了。
废话不多说,先来一个效果图(如果喜欢请关注,后续会持续更新地图方向的可视化):
具体流程:
1.svg叠合ArcGIS Server发布的地图服务叠加展示,在ArcGIS Server的地图中有一个svg标签可以供D3来绘制:
var
poitMoveSvg =
d3.
select(
"#" +
map.
id +
"_gc")
2.用svg的animateMotion标签来创建path路径,达到小圆圆的按照路径移动效果:
g.
append(
"circle")
.
attr(
"r",
5)
.
attr(
"fill",
colorArr[
2])
.
append(
'animateMotion')
.
attr(
'path',
path)
.
attr(
'rotate',
"auto")
.
attr(
'dur',
"10s")
.
attr(
'repeatCount',
"indefinite");
rotate:auto自动旋转方向
dur:路径运行完成时间
repeatCount:重复次数
3.svg的pauseAnimations与unpauseAnimations属性控制断点可以继续运动,保证缩放和平移可以不出现间断
//让动画时间停止
document.
getElementById(
"d3_svg").
pauseAnimations()
.......
........
//开始动画
document.
getElementById(
"d3_svg").
unpauseAnimations()
tip:svg时间控制的坑,svg时间从dom渲染完成开始计时,实际应用应该适时的删除svg标签,保证时间达到预期的效果
4.添加地图缩放和平移事件,重新整理数据进行更新
if (
zoomEvent_e ==
null) {
zoomEvent_e =
map.
on(
"zoom-end",
mig1);
}
if (
zoomEvent_s ==
null) {
zoomEvent_s =
map.
on(
"zoom-start",
d3Clear);
}
if (
panEvent_e ==
null) {
panEvent_e =
map.
on(
"pan-end",
mig1);
}
if (
panEvent_s ==
null) {
panEvent_s =
map.
on(
"pan-start",
d3Clear);
}
5.点移动源代码,仅供参考
//清除按钮,清除事件
function
clearClick() {
zoomEvent_s.
remove()
zoomEvent_e.
remove()
panEvent_s.
remove()
panEvent_e.
remove()
zoomEvent_s =
null;
zoomEvent_e =
null;
panEvent_s =
null;
panEvent_e =
null;
d3.
selectAll(
"#pointMove").
remove();
d3.
selectAll(
"#d3_svg").
remove();
}
//----------------------------------分割--------------------------------------------
//点移动
var
migData1 = [
[{
x:
110.85099,
y: -
74.25962166
}, {
x:
134.537944,
y: -
99.363874
}],
[{
x:
30.98670782,
y: -
60.99922008
}, {
x:
30.98670782,
y: -
51.998
}, {
x:
84.678,
y: -
53.744
}, {
x:
85.101,
y: -
56.739
}],
[{
x:
30.98670782,
y: -
60.99922008
}, {
x:
30.98670782,
y: -
50.998
}, {
x:
84.678,
y: -
52.744
}, {
x:
93.25,
y: -
40.759
}]
];
function
d3Clear() {
d3.
selectAll(
"#pointMove").
remove();
}
function
play() {
// 给svg标签transform属性,让svg没有偏移
var
poitMoveSvg =
d3.
select(
"#" +
map.
id +
"_gc")
.
attr(
"class",
"svgTransform")
.
append(
"svg")
.
attr(
"id",
"d3_svg");
mig1()
function
mig1() {
d3.
selectAll(
"#pointMove").
remove();
//让动画时间停止
document.
getElementById(
"d3_svg").
pauseAnimations()
if (
zoomEvent_e ==
null) {
zoomEvent_e =
map.
on(
"zoom-end",
mig1);
}
if (
zoomEvent_s ==
null) {
zoomEvent_s =
map.
on(
"zoom-start",
d3Clear);
}
if (
panEvent_e ==
null) {
panEvent_e =
map.
on(
"pan-end",
mig1);
}
if (
panEvent_s ==
null) {
panEvent_s =
map.
on(
"pan-start",
d3Clear);
}
//将数据变为屏幕坐标
for (
var
i =
0;
i <
migData1.
length;
i++) {
screenData = [];
for (
var
index =
0;
index <
migData1[
i].
length;
index++) {
screenData.
push(
map.
toScreen(
migData1[
i][
index]));
}
g =
d3.
select(
"#d3_svg")
.
append(
"g")
.
attr(
"id",
"pointMove");
//循环轨迹每一点生成path
var
path =
''
for (
var
j =
0;
j <
screenData.
length;
j++) {
path +=
j ==
0 ? (
'M' +
screenData[
j].
x +
',' +
screenData[
j].
y) : (
'L' +
screenData[
j].
x +
',' +
screenData[
j].
y)
}
g.
append(
"path")
.
attr(
"d",
path)
.
attr(
"stroke",
colorArr[
0])
//颜色
.
attr(
"fill",
"none")
.
attr(
"stroke-width",
"2");
g.
append(
"circle")
.
attr(
"r",
5)
.
attr(
"fill",
colorArr[
2])
.
append(
'animateMotion')
.
attr(
'path',
path)
.
attr(
'rotate',
"auto")
.
attr(
'dur',
"10s")
.
attr(
'repeatCount',
"indefinite");
//开始动画
document.
getElementById(
"d3_svg").
unpauseAnimations()
}
}
}
GIS可视化交流群:464238752