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?
- oneThe 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
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
|