Здравствуйте. Используем ГИС Конструктор 13.0.0.5 под AstraLinux 1.6. Необходимо определить береговую черту в заданном радиусе. Для этого строю площадной объект hCircle (красный круг), и ищу для него линии пересечения с объектами "Океаны и моря". Линии пересечения копируются в hLand.
Код
while(mapWhatObjectBySelect(h_gd, hObj, &frame, select, flag, PP_PLANE ))
{
flag = WO_NEXT;
if(hObj)
{
excode = mapObjectExcode(hObj);
if(excode == 31110000 ) //океаны и моря
{
//пересечение
HCROSS hCross = mapCreateObjectsCross( hCircle, hObj, LOCAL_LINE, 0);
if (hCross) //0 если нет пересечения или если ошибка
{
HOBJ hIntersect = mapCreateSiteObject(h_gd, taskCoord);
mapRegisterObject(hIntersect, 221054733,LOCAL_LINE);
while( mapGetNextCross( hCross, hIntersect) ) //0 если ошибки
{
int cnt = mapPointCount( hIntersect, 0 );
if( cnt )
{
int subject(0);
if( mapPointCount( hLand, 0 ) ) subject = mapCreateSubject( hLand ); //если метрика объекта занята - создаем подобъект
for( int i = 1; i <= cnt; i++ )
mapAppendPointPlane( hLand, mapXPlane( hIntersect, i ), mapYPlane( hIntersect, i ), subject );
}
}
mapFreeObject( hIntersect );
}
mapFreeObjectsCross( hCross );
}
}
}
Предполагается, что в случае, когда hCircle пересекает один объект в нескольких местах, за счет while(...) мы обрабатываем их все. Но на практике обрабатывается только первое пересечение, а для следующего mapGetNextCross() возвращает 0.
Окружность вырезает у ломаной 3 части, которые находятся внутри окружности. Возвращает 3 объекта. Если разомкнуть окружность, то нарезка будет выдавать все части нарезанного объекта. В данном примере - 7 частей (3 внутри и 4 снаружи).
Для поиска точек пересечения есть, например, функция - mapCreateObjectCrossPointsEx
Oleg Belenkov,если честно, понятней не стало. У меня, насколько я могу судить, написано тоже самое. Окружность пересекает ломанную в нескольких местах, это видно глазами. Но при этом
Код
while (mapGetNextCross(hcross, hobj) != 0)
после первого прохода возвращает 0.
Переформулирую вопрос: что не так в коде, который привел я?
В ответе на Ваш вопрос размещен рабочий тест с исходными данными. Может в Вашем примере на вход функции передаются 2 одинаковых объекта или другая ошибка в логике.
if(excode == /*131044100*/31110000) //131044100 - корона, 31110000 - океаны и моря
В этом случае в качестве объекта, который режут, выступает полигон "Океаны и моря". В результате получаем только одну линию пересечения, хотя очевидно, что должна быть как минимум вторая в правом нижнем углу. Очевидно потому, что этот объект "Океаны и моря" выглядит вот так, если выделить его (QDMapView::SetObjSelected()).
Возможно, причина - сложность полигона "Океаны и моря", он имеет полости, как видно на картинке. Как бы то ни было, мне нужно получить все линии пересечения.
Илья Аникин написал: В этом случае в качестве объекта, который режут, выступает полигон "Океаны и моря". В результате получаем только одну линию пересечения, хотя очевидно, что должна быть как минимум вторая в правом нижнем углу. Очевидно потому, что этот объект "Океаны и моря" выглядит вот так , если выделить его (QDMapView::SetObjSelected()).Возможно, причина - сложность полигона "Океаны и моря", он имеет полости, как видно на картинке .Как бы то ни было, мне нужно получить все линии пересечения.
Просьба прислать пример карты с двумя объектами для проверки. Можно выслать на КБ Панорама <panorama@gisinfo.ru>
Поскольку операция нарезки выполняется с полигоном (океаны и моря), то результатом является тоже полигон, в котором содержатся сразу все части.
После операции нарезки для полученного объекта можно вызвать методы:
Код
// Установить признак мультиполигона, если есть внешние контура
mapSetMultiPolygonEx(hobj, 1, 1);
// Запросить число внешних контуров
int count = mapGetMultiSubjectCount(hobj);
// Выбрать внешние контура с подобъектами
for(int i = 1; i <= count; i++)
{
mapReadCopyMultiSubject(hdest, hobj, i);
}
Можно воспользоваться одним из следующих способов: - преобразовать полученный объект в мультиполигон (доступно в ГИС Конструктор версии 14); - перерегистровать тип объектов в линейный до выполнения нарезки.