Arcgis api for javascript study notes (Version 3.2) - constant speed track animation

I. Introduction

  There is such a demand: the known n points of latitude and longitude of a strip line array [[116.2968, 39.90245], [116.297443, 39.902454], [116.297454, 39.90312], [116.296295, 39.903133], [116.296258, 39.902454], [ 116.296794, 39.902446]], to achieve the object trajectory.

  If these two points are very close, so we can use a timer on each re-draw the map of a point, so that the naked eye to see the effect of exercise on this point.

  But if these two o'clock points from a distance, then the trajectory effect is throbbing kind, not the kind of coherence.

II. The realization of ideas

  Since the two points A, B because from a distance, leading to finish drawing A point B and then draw the feeling that there will be about to jump point A point B, then we can again average choice between Point A Point B two o'clock n points, the point a after completing the drawing, and then drawing the n-by-point, point B, and finally drawn, so that you can achieve the effect that smooth motion.

  But in the process of implementation, to consider the following questions:

  1. The distance between the issue points, some long, some short two, then the number of points selected in the end between two suitable points;

  2. If the problem is a point icon, such as a vehicular icon, then the icon should be parallel to the vehicle trajectory, and be moved towards the front direction;

  3. WGS84 problems as far as possible for correlation calculation, the correlation calculation because the screen coordinate point got to cause an error;

  Solution: object setting a _SPEED speed (km / sec), assuming timer _seed (ms / second), then the timer from each run is: _avg_distance = _speed * _seed / 1000 (one thousand meters / time)

         AB distance between two points is then calculated by an algorithm _distance (kilometers), so that you can judge again AB between two timers to be executed many times is the number of points to be selected

         AB points have then calculated direction angle, the direction angle is selected to give the N-point direction angle, and finally starting from the point A, point A in accordance with latitude and longitude coordinates, direction angle, _avg_distance individually calculated latitude and longitude coordinates of the point n

         Next, these points can be drawn, and that is too smooth motion effects

III. Implementation code

// the WGS84 conversion to web Mercator 
DEFINE ({
     // the core formula 
    // plane coordinates x = Lon * 20037508.34 / 108 
    // plane coordinates y = log (tan ((90+ latitude) * PI / 360)) / (the PI / 360) * 20,037,508.34 / 180 [ 
    // longitude coordinate plane = X / 180 [20,037,508.34 * 
    // latitude = 180 / (PI * (2 * atan (exp ( plane coordinates y / 20037508.34 * 180 * PI / 180)) - the PI / 2) 
    longlat2WebMercator: function (longitude, Latitude) {
         var X = longitude 20,037,508.34 * / 180 [ ;
         // The Math.log: on the logging function 
        var Y = The Math.log (Math.tan ((90 + Latitude) * the Math .PI / 360)) / (Math.PI / 180 [ );
        y = y * 20037508.34 / 180;
        return { "x": x, "y": y };
    },
    webMercator2LongLat: function (x, y) {
         var longitude = x / 20037508.34 * 180 ;
        var latitude = y / 20037508.34 * 180 ;
        latitude = 180 / Math.PI * (2 * Math.atan(Math.exp(latitude * Math.PI / 180)) - Math.PI / 2);
        return {
            "longitude": longitude,
            "latitude": latitude
        };
    }
});
// measurement calculation module 
DEFINE ([ "Extras / Coordinates"], function (Coordinates) {
     return {
        lengthByMercator: function (pt1, pt2) {
            //测距(单位:米)
            var a_pow = Math.pow((pt1.x - pt2.x), 2);
            var b_pow = Math.pow((pt1.y - pt2.y), 2);
            var c_pow = a_pow + b_pow;
            var length = Math.sqrt(c_pow);
            return length;
        },
        areaByMercator: function (PT1, PT2, PT3) {
             // measurement surface (units: meters) 
            return ((* pt2.y pt1.x - pt2.x pt1.y *) + (* pt3.y pt2.x - * pt2.y pt3.x) + (pt3.x pt1.y * - * pt1.x pt3.y)) / 2 ;
        },
        angleByLongLat: function (longitude1, latitude1, longitude2, latitude2) {
            var ptTemp1 = Coordinates.longlat2WebMercator(longitude1, latitude1);
            var ptTemp2 = Coordinates.longlat2WebMercator(longitude2, latitude2);
            var x = ptTemp2.x - ptTemp1.x;
            var y = ptTemp2.y - ptTemp1.y;
            var angle = Math.atan2(y, x);
            angle = (angle - Math.PI / 2) / Math.PI * 180;
            return angle;
        },
        angleByMercator: function (pt1, pt2) {
            var x = pt2.x - pt1.x;
            var y = pt2.y - pt1.y;
            var angle = Math.atan2(y, x);
            angle = (angle - Math.PI / 2) / Math.PI * 180;
            return angle;
        },
        EARTH_RADIUS: 6378.137, // earth equatorial radius (unit: km) 
        EARTH_ARC: 111.199,      // arc length (Unit: km) per degree earth 
        _RAD: function (Val) {
             // converted to radians (RAD) 
            return Val * the Math .PI / 180.0 ;;
        },
        distanceByLongLat: function (longitude1, latitude1, longitude2, latitude2) {
             // find two latitude and longitude distance (unit: km) 
            var R1 = the this ._rad (latitude1);
             var R2 = the this ._rad (longitude1);
             var A = the this ._rad (latitude2);
             var B = the this ._rad (longitude2);
             var S = Math.acos (
                Math.cos (R1) * Math.cos (a) * Math.cos (R2 - b)
                 + Math.sin (R1) * Math.sin (a)
            ) * this.EARTH_RADIUS;
            return s;
        },
        azimuthByLongLat: function (longitude1, latitude1, longitude2, latitude2) {
             // find two azimuth angles of latitude and longitude (unit: [deg.]) 
            var Azimuth = 0 ;
             // console.info ( "----------------------- ------------------------ "); 
            IF (longitude2 === longitude1 && latitude2> latitude1) {
                azimuth = 0;
            }
            else if (longitude2 === longitude1 && latitude2 < latitude1) {
                azimuth = 180;
            }
            else if (latitude2 === latitude1 && longitude2 < longitude1) {
                azimuth = 270;
            }
            else if (latitude2 === latitude1 && longitude2 > longitude1) {
                azimuth = 360;
            }
            else {
                var radLongitude1 = this._rad(longitude1);
                var radLongitude2 = this._rad(longitude2);
                var radLatitude1 = this._rad(latitude1);
                var radLatitude2 = this._rad(latitude2);
                azimuth = Math.sin(radLatitude1) * Math.sin(radLatitude2) + Math.cos(radLatitude1) * Math.cos(radLatitude2) * Math.cos(radLongitude2 - radLongitude1);
                azimuth = Math.sqrt(1 - azimuth * azimuth);
                azimuth = Math.cos(radLatitude2) * Math.sin(radLongitude2 - radLongitude1) / azimuth;
                azimuth = Math.asin(azimuth) * 180 / Math.PI;

                IF (latitude2 < latitude1) {
                     // console.info ( "thirty-four quadrant"); 
                    Azimuth = 180 [- Azimuth;
                }
                else if (latitude2 > latitude1 && longitude2 < longitude1) {
                    //console.info("第二象限");
                    azimuth = 360 + azimuth;
                }
                // the else { 
                //      console.info ( "quadrant"); 
                // } 
            }
             // console.info (Azimuth); 
            return Azimuth;
        },
        getNextPoint: function (longitude1, latitude1, Distance, Azimuth) {
             // Distance represents the distance between two points obtained (unit: km) 
            Azimuth = the this ._rad (Azimuth);
             // convert the calculated distances into longitude 
            var LON = longitude1 + (distance * Math.sin, (Azimuth)) / ( the this .EARTH_ARC * Math.cos ( the this ._rad (latitude1)));
             // the distance conversion formula to calculate the latitude 
            var LAT = latitude1 + (distance * the Math. COS (Azimuth)) / the this .EARTH_ARC;
             return { "longitude": LON, "Latitude" : LAT};
        }
    }
});
define([
    "dojo/_base/declare",
    'esri/Color',
    'esri/graphic',
    "esri/geometry/Point",
    'esri/geometry/Polyline',
    'esri/symbols/SimpleLineSymbol',
    'esri/symbols/PictureMarkerSymbol',
    'esri/layers/GraphicsLayer',
    "extras/MeatureTool"
], function (declare, Color, Graphic, Point, Polyline, SimpleLineSymbol, PictureMarkerSymbol, GraphicsLayer, MeatureTool) {
    return declare([GraphicsLayer], {
        _img: "",
        _pts: [],
        _ptIndex: 0,
        _ptGraphic: null ,     // graphic element 
        _seed: 100,           // how long execution time, (Unit: ms / time) 
        _SPEED: 10,           // object running speed (km / s) 
        _timer: null ,         // Timer 
        _Running: to true ,       // timer running state 
        Initial: function (Options) {
             var _this = the this ;
            _this._img = options.img;
            _this._speed = options.speed || _this._speed;
            _this._pts.length = 0;
            _this._ptIndex = 0;
            _this._timer = null;
            _this._running = true;

            //定义线符号
            var lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 2);
            var lineGeometry = new Polyline({ "paths": options.paths });
            var lineGraphic = new Graphic(lineGeometry, lineSymbol);
            _this.add(lineGraphic);

            _this._ptGraphic = new Graphic();
            _this.add(this._ptGraphic);

            var pathLastIndex = options.paths[0].length - 1;
            for (var i = 0; i < pathLastIndex; i++) {
                var longitude1 = options.paths[0][i][0];
                var latitude1 = options.paths[0][i][1];
                var longitude2 = options.paths[0][i + 1][0];
                var latitude2 = options.paths[0][i + 1][1];

                // Icon inclination angle between the two 
                var angle = MeatureTool.angleByLongLat (longitude1, latitude1, longitude2, latitude2);

                // direction between two points is calculated angle (unit: degree) 
                var Azimuth = MeatureTool.azimuthByLongLat (longitude1, latitude1, longitude2, latitude2);
                 // console.info (Azimuth); 
                // add to the array origin 
                _this. _pts.push ({ "longitude": longitude1, "Latitude": latitude1, "angle" : angle});

                // distance between two points is calculated (unit: one thousand meters) 
                var Distance = MeatureTool.distanceByLongLat (longitude1, latitude1, longitude2, latitude2);
                 // Distance Average per run timer (unit: km / h times) 
                var = avg_distance (_this._speed _this._seed *) / 1000 ;
                 // if the distance is less than the distance between two points obtained for each run timer, then do not select points in latitude and longitude between two points divided 
                IF (distance <= avg_distance) {
                     Continue ;
                }
                // calculation between two points, the number of timers need to perform 
                var Times = Distance / avg_distance;
                 for ( var J =. 1; J <Times; J ++ ) {
                     var curr_distance = avg_distance * J
                     var Pt = MeatureTool.getNextPoint (longitude1, latitude1 , curr_distance, azimuth);
                    pt.angle = angle;
                    _this._pts.push(pt);
                }
            }
            var ptLast = {
                "longitude": options.paths[0][pathLastIndex][0],
                "latitude": options.paths[0][pathLastIndex][1],
                "angle": _this._pts[_this._pts.length - 1].angle
            };
            _this._pts.push(ptLast);
            _this._ptDraw();
        },
        // Run animation 
        RUN: function () {
             var _this = the this ;
            _this._timer = setInterval(function () {
                if (_this._running) {
                    if (_this._ptIndex >= _this._pts.length) {
                        clearInterval(_this._timer);
                    }
                    if (_this._ptIndex <= _this._pts.length - 1) {
                        _this._ptDraw();
                    }
                }
            }, _this._seed);
        },
        toggle: function () {
            var _this = this;
            _this._running = !_this._running;
        },
        _ptDraw: function () {
            var _this = this;
            var pt = _this._pts[_this._ptIndex];
            var ptGeometry = new Point({
                "longitude": pt.longitude,
                "latitude": pt.latitude
            });
            var ptSymbol = new PictureMarkerSymbol({
                "url": _this._img,
                "height": 32,
                "width": 18,
                "type": "esriPMS",
                "angle": pt.angle,
            });
            _this._ptGraphic.setGeometry(ptGeometry);
            _this._ptGraphic.setSymbol(ptSymbol);
            _this._ptIndex++;
        }
    });
});
        require(["esri/map", "arcgis_js_v320_api_ex/MovingLayer", "dojo/domReady!"], function (Map, MovingLayer) {
            var map = new Map("viewDiv", {
                "basemap": "streets",
                "scale": 50000,
                "center": [116.29, 39.90],
            });
            var paths = [[
                [116.2968, 39.90245],
                [116.297443, 39.902454],
                [116.297454, 39.90312],
                [116.296295, 39.903133],
                [116.296258, 39.902454],
                [116.296794, 39.902446]
            ]];
            var movingLayer = new MovingLayer();
            map.addLayer(movingLayer);
            movingLayer.initial({
                "img": "/static/img/car.png",
                "paths": paths,
                "speed": 0.011
            });
            movingLayer.run();
        });

IV. Achieve results

   

Guess you like

Origin www.cnblogs.com/tracine0513/p/11792557.html