Клуб API Карт

не работает метод geometry.contains в api 2.0.20

Пост в архиве.

 

Есть полигон

myZone = new ymaps.Polygon([[[5.5,-2],[1.9,5.7],[-3.7,1.3],[-5.5,-6]]])
myMap.geoObjects.add(myZone)

var myPol=new ymaps.GeoObjectCollection()
myMap.geoObjects.add(myPol)

 

есть функция, которая генерирует 10 случайных окружностей, лежащих в пределах этого полигона

function GenCircle(R){

//var bounds=myZone.geometry.getBounds();
 var bounds=myMap.getBounds();
 var Xm=bounds[0][1], Xx=bounds[1][1]
 var Ym=bounds[0][0], Yx=bounds[1][0]
 for (j=0; j<10; j++){
   k=0;
   while (k<100){
     Xc=Math.floor(Math.random()*Xx)+Xm
     Yc=Math.floor(Math.random()*Yx)+Ym
     vertex=[Yc,Xc]
     k++;
     if (myZone.geometry.contains(vertex)){
       var myCircle = new ymaps.Circle([vertex,R])  
       myPol.add(myCircle)
       break;
     }
   }
 }
}

 

 

Под api 2.0.18 все работает отлично, центры окружностей генерятся в пределах полигона, учитывают и вложенные контуры

Под  api 2.0.20 окружности генерятся по всей видимой части карты (на самом деле я границы беру все-таки по полигону, но проблемы это не решает, центы рисуются в пределах всей области getBounds, игрорируя и вложенные контуры, если таковые имеются)

 

7 комментариев

Проверил, все работает, только у вас ошибка в логике.

Во первых

 

var Xm = bounds[0][0], Xx = bounds[1][0]-Xm;//Нужна же "ширина", а не правое значение
var Ym = bounds[0][1], Yx = bounds[1][1]-Ym;

Во вторых

 

 

var Xc = (Math.random() * Xx) + Xm//никакого floor, вы тут точность до градуса понижаете
var Yc = (Math.random() * Yx) + Ym

На выходе нормальная картинка

 

 

с floor я уже сообразила, у меня это вылилось в забавную картинку, что окружности за счет округления координат выстраивались строго по некоей "сетке"

Xx Xm (прошу прощения, не прокомментировала), это были максимальные и минимальные значения для рандомайзера, и в рабочем варианте они брались из описывающего прямоугольника для моего полигона, чтобы поменьше было неудачных попыток генерации координат.

НО, что самое интересное, на полчаса отключился интернет, сейчас полезла воспроизадить ситуацию, и все работает. хотя до этого часа два билась на двух разных компьютерах, один на работе, другой дома. Загадка. Но все равно, спасибо за ответы

вобщем ситуация вроде прояснилась. при работе в положительных координатах - работает код и на апи 18 и на 20. при работе в отрицательных координатах апи 18 работает корректно, а 20 - дает ложное срабатывание contains

Добрый день!

 

Не удается вопроизвести вашу проблему, можете прислать ссылку где она проявляется?

Загадочным образом, проблема исчезла сама, так что теперь я ее тоже воспроизвести не могу :)

удалось разобраться, почему ошибка не воспроизводится.

Я работаю в декартовых координатах.

в рабочем варианте кода полигон лежал и в области отрицательных координат и положительных. И была разница в работе апи 18 и 20.

Для примера, чтобы не вываливать дополнительный код генерации координат для отрицательных областей, я подвинула полигон и видимую область карты в зону положительных координат и проблема исчезла.

Поэтому, для рассмотрения я предлагаю файлы, где рассмотрена как ситуация с ошибкой, так и без нее.

Исходная задача: при щелчке по карте нарисовать 10 окружностей разного цвета и немного разного радиуса, случайным образом раскиданных в пределах полигона. Координаты генерятся рандомайзером, затем проверяются на принадлежность полигону. Каждой окружности дается 100 попыток сгенерить для себя правильные координаты, если не получилось - не выводиться.

Судя по всему, для отрицательных областей метод contains в апи 2.0.20 дает ложное срабатывание, потому что окружности выводятся всегда и везде. Для 2.0.18 видно, что иногда число окружностей меньше 10, но все лежат в полигоне.

Для экспериментов предлагаю 4 файла.

random18 и random20 не отличаются ничем, кроме версии подключенного api

суффикс p в имени файла означает, что для этой версии все координаты лежат в положительной области

суффикс m в имени файла означает, что для этой версии все координаты лежат в отрицательной области. Код сугубо тренировочный, для проверки проблемы

 random18m (api 18, отрицательные координаты)

 random18p (api 18, положительные координаты)

 random20m (api 20, отрицательные координаты)

 random20p (api 20, положительные координаты)

Еще поэкспериментировала и заметила интересную тенденцию:

Ложное срабатывание наблюдается только относительно компоненты Х и только для "более отрицательных". но не всегда.

Я создала тестовую область [-29,-20],[-20,-20],[-20,-29],[-29,-29] и смотрела, куда программа пытается ставить точки вообще, и какие именно признаются правильными.

Для 10 точек получилось вот что

15: -27.998, -38.720 (!)
8: -22.490, -32.969 (!)
13: -25.400, -30.268 (!)
2: -25.034, -37.917 (!)
22: -27.209, -23.261
11: -24.226, -38.046 (!)
4: -27.099, -36.208 (!)
5: -25.116, -25.568
1: -28.771, -20.360
6: -26.723, -38.155 (!)

Цифра на первой позиции, перед двоеточием, показывает, с какой попытки были получены верные координаты. Восклицательным знаком помечены те. которые  тем не менее, верными не являются.

С другой стороны, не все точки, лежащие левее тестовой зоны в пределах допустимых по Y значений, объявляются верными. Какой-то закономерности я пока не уловила.

 

на этой картинке маленькие темные точки - отвергнутые варианты координат, большие цветные окружности - координаты, признанные лежащими в полигоне