D3+ArcGIS 迁徙图实现(缩放过程中断点连续运动)

    用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的pauseAnimationsunpauseAnimations属性控制断点可以继续运动,保证缩放和平移可以不出现间断

//让动画时间停止
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


发布了11 篇原创文章 · 获赞 3 · 访问量 3618

猜你喜欢

转载自blog.csdn.net/qq_35241223/article/details/79779295