In cian.ru on the map of the city, you can click the β€œDraw area” button to draw an arbitrary contour on the map, then cian.ru smoothes it and displays the real estate objects inside this contour. I can not understand, are these opportunities from yandex cards or the development of cian itself?

  • one
    The geometry editor is part of the API, and anti-aliasing and searching inside the region is the development of cian itself over the API capabilities. - Reni

1 answer 1

The Yandex.Maps API has a polygon editor , but it is a bit different.

If you want behavior like on cian.ru, then it's easier to put it on top of the canvas map, draw on it and memorize the coordinates, and then build a polygon from them.

You can filter geo-objects by hitting a polygon using geoQuery(myObjects).searchInside(polygon) or polygon.contains(coordinates) .

 var polygonOptions = { strokeColor: '#0000ff', fillColor: '#8080ff', interactivityModel: 'default#transparent', strokeWidth: 4, opacity: 0.7 }; var canvasOptions = { strokeStyle: '#0000ff', lineWidth: 4, opacity: 0.7 }; ymaps.ready(['Map', 'Polygon']).then(function() { var map = new ymaps.Map('map', { center: [55.75, 37.62], zoom: 8 }); var polygon = null; var drawButton = document.querySelector('#draw'); drawButton.onclick = function() { drawButton.disabled = true; drawLineOverMap(map) .then(function(coordinates) { // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΈΠ· 0..1 Π² гСографичСскиС. var bounds = map.getBounds(); coordinates = coordinates.map(function(x) { return [ // Π¨ΠΈΡ€ΠΎΡ‚Π° (latitude). // Y пСрСворачиваСтся, Ρ‚.ΠΊ. Π½Π° canvas'Π΅ ΠΎΠ½ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ Π²Π½ΠΈΠ·. bounds[0][0] + (1 - x[1]) * (bounds[1][0] - bounds[0][0]), // Π”ΠΎΠ»Π³ΠΎΡ‚Π° (longitude). bounds[0][1] + x[0] * (bounds[1][1] - bounds[0][1]), ]; }); // Π’ΡƒΡ‚ Π½Π°Π΄ΠΎ ΡΠΈΠΌΠΏΠ»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ линию. // Для простоты я ΠΎΡΡ‚Π°Π²Π»ΡΡŽ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ‚Ρ€Π΅Ρ‚ΡŒΡŽ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρƒ. coordinates = coordinates.filter(function (_, index) { return index % 3 === 0; }); // УдаляСм старый ΠΏΠΎΠ»ΠΈΠ³ΠΎΠ½. if (polygon) { map.geoObjects.remove(polygon); } // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΠ»ΠΈΠ³ΠΎΠ½ polygon = new ymaps.Polygon([coordinates], {}, polygonOptions); map.geoObjects.add(polygon); drawButton.disabled = false; }); }; }); function drawLineOverMap(map) { var canvas = document.querySelector('#draw-canvas'); var ctx2d = canvas.getContext('2d'); var drawing = false; var coordinates = []; // Π—Π°Π΄Π°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ канвасу ΠΊΠ°ΠΊ Ρƒ ΠΊΠ°Ρ€Ρ‚Ρ‹. var rect = map.container.getParentElement().getBoundingClientRect(); canvas.style.width = rect.width + 'px'; canvas.style.height = rect.height + 'px'; canvas.width = rect.width; canvas.height = rect.height; // ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ стили. ctx2d.strokeStyle = canvasOptions.strokeStyle; ctx2d.lineWidth = canvasOptions.lineWidth; canvas.style.opacity = canvasOptions.opacity; ctx2d.clearRect(0, 0, canvas.width, canvas.height); // ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ канвас. Он Π±ΡƒΠ΄Π΅Ρ‚ свСрху ΠΊΠ°Ρ€Ρ‚Ρ‹ ΠΈΠ·-Π·Π° position: absolute. canvas.style.display = 'block'; canvas.onmousedown = function(e) { // ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΌΡ‹ΡˆΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π½Π°Ρ‡Π°Π»ΠΈ Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹. drawing = true; coordinates.push([e.offsetX, e.offsetY]); }; canvas.onmousemove = function(e) { // ΠŸΡ€ΠΈ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ‹ΡˆΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΈ рисуСм линию. if (drawing) { var last = coordinates[coordinates.length - 1]; ctx2d.beginPath(); ctx2d.moveTo(last[0], last[1]); ctx2d.lineTo(e.offsetX, e.offsetY); ctx2d.stroke(); coordinates.push([e.offsetX, e.offsetY]); } }; return new Promise(function(resolve) { // ΠŸΡ€ΠΈ отпускании ΠΌΡ‹ΡˆΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΈ скрываСм канвас. canvas.onmouseup = function(e) { coordinates.push([e.offsetX, e.offsetY]); canvas.style.display = 'none'; drawing = false; coordinates = coordinates.map(function(x) { return [x[0] / canvas.width, x[1] / canvas.height]; }); resolve(coordinates); }; }); } 
 <script src="//api-maps.yandex.ru/2.1/?lang=ru_RU"></script> <button id="draw">Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ</button> <div id="container" style="position: relative;"> <div id="map" style="width: 300px; height: 300px;"></div> <canvas id="draw-canvas" style="position: absolute; left: 0; top: 0; display: none;"></canvas> </div> 

  • flapenguin, thank you so much! I can not evaluate the decision, since the rating is small, but the solution is smart!)))) Thank you so much! - Natalya
  • 2
    @ Natalia, please. You can mark the answer as correct by clicking on the check mark on the left (under the voting arrows). - flapenguin
  • the question is solved!))) Tell me, please, is there any similar functionality in Google maps? - Natalya
  • 2
    @Natalya, you can put the same <canvas> over the map and then collect a polygon from the points. - flapenguin