基于ArcGIS开发动态视域效果

说明

sdk为ArcGIS Runtime SDK for .NET(100.9.0),参考资料有Viewshed (location)Viewshed for GeoElement

本文主要在动态视域的基础上添加了自定义路线,实现效果如图

Viewshed for GeoElement的官方示例为手动点击触发,想将其变为自定义路线循环运行,需要完成以下几点:
1.设置一个定时器,完成坦克移动的整个轨迹
2.MoveTank方法每次只移动了一点点距离,需要循环调用来完成从一个点到另一个点的移动
3.基于上一点,每次调用完MoveTank方法后,判断坦克是否达到目标点(这里允许有一些误差),以便切换到下一个目标点

关键代码

设置定时器


System.Timers.Timer animationTimer2 = new System.Timers.Timer(15000)
{
    Enabled = true,
    AutoReset = true
};
// - Move the tank every time the timer expires.
animationTimer2.Elapsed += (o, e) =>
{
    MoveTankForRoute();
};
//马上执行一次
Task.Run(() =>
{
    MoveTankForRoute();
});
// - Start the timer.
animationTimer2.Start();

单次路线的执行控制

private void MoveTankForRoute()
{
    if (!isAnimateTank && isFinishRoute)
    {
        isFinishRoute = false;
        foreach (var p in route)
        {
            while (true)
            {
                MoveTank(p);
                var nowLocation = _tank.Geometry as MapPoint;
                //手动等待坦克到位
                if (nowLocation.X <= p.X + gap
                && nowLocation.X >= p.X - gap
                && nowLocation.Y <= p.Y + gap
                && nowLocation.Y >= p.Y - gap)
                {
                    break;
                }
                if (isAnimateTank)
                {
                    break;
                }
                Thread.Sleep(60);
            }
            if (isAnimateTank)
            {
                break;
            }
        }
        isFinishRoute = true;
    }
}

单次移动坦克一小段距离,加上坦克转向

private GeodeticDistanceResult MoveTank(MapPoint endPoint)
{
    // Get the current location and distance from the destination.
    MapPoint location = (MapPoint)_tank.Geometry;
    //var rightMapPoint = GeometryEngine.Project(location, endPoint.SpatialReference) as MapPoint;
    GeodeticDistanceResult distance = GeometryEngine.DistanceGeodetic(
        location, endPoint, _metersUnit, _degreesUnit, GeodeticCurveType.Geodesic);

    // Move the tank a short distance.
    location = GeometryEngine.MoveGeodetic(new List<MapPoint>() { location }, 1.0, _metersUnit, distance.Azimuth1, _degreesUnit,
        GeodeticCurveType.Geodesic).First();
    _tank.Geometry = location;

    // Rotate to face the destination.
    double heading = (double)_tank.Attributes["HEADING"];
    heading = heading + (distance.Azimuth1 - heading) / 10;
    _tank.Attributes["HEADING"] = heading;

    return distance;
}

注意事项

坦克模型需要下载,如果安装了ArcGIS Runtime Local Server SDK则有该模型,如果不想安装,也可以在Viewshed for GeoElementOffline data下下载

示例代码

CubeCollision.xaml
CubeCollision.xaml.cs

posted @ 2020-11-09 22:02  Lulus  阅读(238)  评论(0编辑  收藏  举报