Objects are located on the map. Connections are established between the objects. The connection between the objects is displayed on the map as a line. The object must be moved along the line.
The problem is that for long distances the mark runs not along a line, but along an arc near the line. The arc is part of a large diameter circle, and the line between the objects is a chord that crosses this arc. At short distances it is imperceptible, and at long distances it is striking.
How to make the label run exactly along the line? It is permissible to connect objects not by straight lines, but by arcs. Visually, it will look like a straight line.
The calculations are made in the coordinate coordinate system.cartesian coordinate system describing the geometry of the Cartesian plane.
An example is to expand the example to the whole page.
$(document).ready(function() { ymaps.ready(init); function init () { var myMap = new ymaps.Map('map', { center: [52, 75], controls: ['zoomControl','typeSelector'], zoom: 5 }, ); // ΠΠ±ΡΠ΅ΠΊΡ ΠΠΈΠ½ΠΈΡ var data_line = { "type": "FeatureCollection", "features": [] } // ΠΠ±ΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠΊΠ° var data_star = { "type": "FeatureCollection", "features": [] } var start_coordinates = [55.0415,89.9343]; var finish_coordinates = [43.4199,39.9474]; // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΠΈΠ½ΠΈΡ var item_line = { "type": "Feature", "id": 1, "options": { "strokeWidth": 1, "strokeColor": "#255F06" }, "geometry": { "type": "LineString", "coordinates": [start_coordinates,finish_coordinates] }, } data_line.features[0] = item_line; // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠΊΠ° ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π±Π΅ΠΆΠ°ΡΡ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ var item_star = { "type": "Feature", "id": 1, "geometry": { "type": "Point", "coordinates": start_coordinates }, "properties": { // ΠΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ Π±Π΅Π³ΡΡΠ΅Π³ΠΎ ΡΠ°ΡΠΈΠΊΠ°: ΠΠ°ΡΠ°Π»ΠΎ ΠΈ ΠΠΎΠ½Π΅Ρ start: start_coordinates, finish: finish_coordinates } } data_star.features[0] = item_star; var objectManager_line = new ymaps.ObjectManager(); myMap.geoObjects.add(objectManager_line); objectManager_line.add(data_line); var objectManager_star = new ymaps.ObjectManager(); myMap.geoObjects.add(objectManager_star); objectManager_star.add(data_star); setTimeout(animatePoint, 100); // Π‘Π²Π΅ΡΡΡΠ°ΡΡΡ ΠΠ΅ΡΠΊΠ° Π±Π΅ΠΆΠΈΡ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ function animatePoint() { var step = 0; setInterval(function() { var object; var iterator = objectManager_star.objects.getIterator(); while ((object = iterator.getNext()) != iterator.STOP_ITERATION) { // if (step>0) { var start = object.properties.start; var finish = object.properties.finish; var path = ymaps.coordSystem.cartesian.solveInverseProblem(start, finish).pathFunction; var position = path(step/10).point; object.geometry.coordinates = position; // } } myMap.geoObjects.add(objectManager_star); if (step>=10) step=0; else step++; }, 1000); }; } }); <!DOCTYPE html> <html> <head> <title>Demo. ΠΠ΅ΡΠΊΠ° Π±Π΅Π³ΡΡΠ°Ρ Π²Π΄ΠΎΠ»Ρ Π»ΠΈΠ½ΠΈΠΈ</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="https://api-maps.yandex.ru/2.1/?lang=ru-RU&apikey=978c8365-3c1b-4757-bc96-35dd14045e22" type="text/javascript"></script> <script src="https://yandex.st/jquery/2.2.3/jquery.min.js" type="text/javascript"></script> <script src="js/demo.js" type="text/javascript"></script> <style> html, body, #map { width: 100%; height: 100%; padding: 0; margin: 0; } </style> </head> <body> <div id="map"></div> </body> </html> Tried to convert geographic coordinates to pixel and back (function animatePoint ()). The result is the same. The label runs along the curve along the line.
An example is to expand the example to the whole page.
$(document).ready(function() { ymaps.ready(init); function init () { var myMap = new ymaps.Map('map', { center: [52, 75], // center: [55.76, 37.64], controls: ['zoomControl','typeSelector'], zoom: 5 // 4 }, ); // ΠΠ±ΡΠ΅ΠΊΡ ΠΠΈΠ½ΠΈΡ var data_line = { "type": "FeatureCollection", "features": [] } // ΠΠ±ΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠΊΠ° var data_star = { "type": "FeatureCollection", "features": [] } var start_coordinates = [55.0415,89.9343]; var finish_coordinates = [43.4199,39.9474]; // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΠΈΠ½ΠΈΡ var item_line = { "type": "Feature", "id": 1, "options": { "strokeWidth": 1, "strokeColor": "#255F06" }, "geometry": { "type": "LineString", "coordinates": [start_coordinates,finish_coordinates] }, } data_line.features[0] = item_line; // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠΊΠ° ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π±Π΅ΠΆΠ°ΡΡ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ var item_star = { "type": "Feature", "id": 1, "geometry": { "type": "Point", "coordinates": start_coordinates }, "properties": { // ΠΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ Π±Π΅Π³ΡΡΠ΅Π³ΠΎ ΡΠ°ΡΠΈΠΊΠ°: ΠΠ°ΡΠ°Π»ΠΎ ΠΈ ΠΠΎΠ½Π΅Ρ start: start_coordinates, finish: finish_coordinates } } data_star.features[0] = item_star; var objectManager_line = new ymaps.ObjectManager(); myMap.geoObjects.add(objectManager_line); objectManager_line.add(data_line); var objectManager_star = new ymaps.ObjectManager(); myMap.geoObjects.add(objectManager_star); objectManager_star.add(data_star); setTimeout(animatePoint, 100); // ΠΠ΅ΡΠΊΠ° Π±Π΅ΠΆΠΈΡ ΠΏΠΎ Π»ΠΈΠ½ΠΈΠΈ function animatePoint() { var step = 0; setInterval(function() { var projection = myMap.options.get('projection'); var zoom = myMap.getZoom(); var object; var iterator = objectManager_star.objects.getIterator(); while ((object = iterator.getNext()) != iterator.STOP_ITERATION) { var start = object.properties.start; var finish = object.properties.finish; var start_px = projection.fromGlobalPixels(start, zoom); var finish_px = projection.fromGlobalPixels(finish, zoom); var ln_x = finish_px[0] - start_px[0]; var ln_y = finish_px[1] - start_px[1]; var dx = ln_x /10; var dy = ln_y /10; if (step>0) { cur_px = [start_px[0] + (dx*step), start_px[1] + (dy*step)]; var cur_coord = projection.toGlobalPixels(cur_px, zoom); object.geometry.coordinates = cur_coord; } } myMap.geoObjects.add(objectManager_star); if (step>=10) step=0; else step++; }, 1000); }; } }); <!DOCTYPE html> <html> <head> <title>Demo. ΠΠ΅ΡΠΊΠ° Π±Π΅Π³ΡΡΠ°Ρ Π²Π΄ΠΎΠ»Ρ Π»ΠΈΠ½ΠΈΠΈ</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="https://api-maps.yandex.ru/2.1/?lang=ru-RU&apikey=978c8365-3c1b-4757-bc96-35dd14045e22" type="text/javascript"></script> <script src="https://yandex.st/jquery/2.2.3/jquery.min.js" type="text/javascript"></script> <script src="js/demo.js" type="text/javascript"></script> <style> html, body, #map { width: 100%; height: 100%; padding: 0; margin: 0; } </style> </head> <body> <div id="map"></div> </body> </html>