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&amp;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&amp;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> 

  • try to reduce the amount of code - michael_best
  • one
    The fact is that in the projection of the mercator "Parallels are parallel lines, the distance between which near the equator is equal to the distance between the meridians and increases rapidly when approaching the poles." therefore dividing by 10 you do not get the point lying on the line vertically, but get a point slightly offset to the equator. I see such solutions: 1. Use tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/ ... and put a mark on the point closest to the line 2. Create a line from the points and jump over these points. - se0ga

0