Функция CalcCrossObjectSquare прекрасно рассчитывает площадь пересечения двух площадных объектов. SquareObject := CalcCrossObjectSquare(form_main.mvMap.MapHandle, form_main.MapObj2.ObjHandle, form_main.MapObj1.ObjHandle);
Но только в том случаи если в MapObj1 нет подобъектов. В нашем случаи MapObj2 пересекает MapObj1 именно в районе подобъекта. В этом случаи функция, к сожалению, возвращает лишь площадь MapObj2. На Рис.1 показан вариант, когда площадь пересечения SquareObject вычисляется без проблем. На Рис.2 показан вариант с подобъектом в MapObj1. Площадь пересечения SquareObject ожидается показанная желтым цветом. Однако, на Рис.3 показано фактическое значение рассчитанной площади пересечения SquareObject, которое получилось равное всей площади MapObj2. Что не правильно? Просьба подсказать, какую функцию и как использовать, чтобы получить площадь пересечения как на Рис.2?
Функции CalcCrossObjectSquare не знаю и в АПИ ГИС-ядра ее нет. Есть компонент TMapOverlay, который создает пересечения двух площадных объектов с учетом подобъектов.
Вот функция, которая использовалась, для расчета. Можно ли в ней учесть подобъект, или вы рекомендуете использовать компонент TMapOverlay?
function CalcCrossObjectSquare(ExtMap : HMap; baseObj, crossObj : HObj): double;
//------------------------------------------------------------// // Функция поиска пересечений. Возвращает площадь пересечения // //------------------------------------------------------------// function CalcCrossObjectSquare(ExtMap : HMap; baseObj, crossObj : HObj): double; var cross : HCross; obj : HObj; i : integer; n : integer; begin cross := mapCreateObjectsCrossSquare(baseObj, crossObj, 0.001); result := 0; if Cross=0 then exit; obj := mapCreateSiteObject (ExtMap, ExtMap, KM_IDFLOAT3, 0); while mapGetNextCross(cross, obj)<>0 do result := result+mapConventionalSquare(obj); n := mapPolyCount(obj); For i:=1 to n do begin result := result-mapConventionalSubjectSquare(obj, i); end; mapFreeObjectsCross(cross); mapFreeObject(obj); end;
Andrey Gheleznyakov написал: Функции CalcCrossObjectSquare не знаю и в АПИ ГИС-ядра ее нет. Есть компонент TMapOverlay, который создает пересечения двух площадных объектов с учетом подобъектов.
Взял в качестве примера тестовый пример. И шаблон и обрабатываемый объект ищет хорошо. Если обрабатываемый объект пересекает край объекта шаблона, то все хорошо. Площадь пересечения вычисляется правильно. Но если обрабатываемый объект пересекает шаблон в районе его подобъекта, то компонент TMapOverlay не считает, что обрабатываемый объект пересекает шаблон. Это так и задумано? Но такую программу пользователь не примет.
Скорее всего дело в том, что у объекта (подобъектов) контура имеют самопересечения, например, контур одного подобъекта пересекается с другим контуром (объекта, подобъекта). Пришлите фрагмент карты.
Andrey Gheleznyakov написал: Скорее всего дело в том, что у объекта (подобъектов) контура имеют самопересечения, например, контур одного подобъекта пересекается с другим контуром (объекта, подобъекта). Пришлите фрагмент карты.
Проверил определение пересечений на тестовом примере из инсталляции - работает. Для поиска пересечений с учетом подобъектов надо в в качестве шаблона выбирать объект с один контуром (или указывать номер контура), а другой объект уже указывать с подобъектами и в примере надо вызов ovlObj.SetObjectCross(0, 0.001, 0, ovl_METHOD_SQUARE, ovl_ANYOBJECT); заменить на ovlObj.SetObjectCross(-1, 0.001, 0, ovl_METHOD_SQUARE, ovl_ANYOBJECT); (первый параметр равен -1).
Первое не понятно, сделали так: // res := ovlObj.SetObjectCross(0, 0.001, 0, ovl_METHOD_SQUARE, ovl_ANYOBJECT); res := ovlObj.SetObjectCross(-1, 0.001, 0, ovl_METHOD_SQUARE, ovl_ANYOBJECT); // Результат тот же, обрабатываемый объект считает, что он просто внутри объекта шаблона, а не пересекает его
Второе не понятно, рассмотрели это: res := ovlObj.CreateOVL(1, 0.001, 0, 0); // третий параметр 0, это означает, что рассматривать в качестве контра шаблона, основной контур, или это не правильно?
Третье не понятно, не понятно то, что Вы пишите "...а другой объект уже указывать с подобъектами..." другой объект, это же обрабатываемый объект. Он без подобъектов изначально. При чем здесь подобъекты?
//============================================================================= // Найти объекты пересечений //============================================================================= procedure TfrmOvl.btnFindCrossObjClick(Sender: TObject); var res : integer; ll, tt : integer; SquareObject : double; begin ll := frmOvl.Left + 10; tt := frmOvl.Top + btnFindCrossObj.Top + 120;
if (edTemplet.Text = EmptyStr) or (edObjIn.Text = EmptyStr) then begin ShowMessagePos('Выберите на карте шаблон и обрабатываемый объект?', ll, tt); exit; end;
if res = 0 then begin ShowMessagePos('Ошибка создания объекта оверлейных операций!', ll, tt); exit; end; res := ovlObj.SetObjectCross(-1, 0.001, 0, ovl_METHOD_SQUARE, ovl_ANYOBJECT);
case res of 1 : begin if mapGetExclusiveSubject(temp.ObjHandle, 0) = 0 // шаблон не замкнут then ShowMessagePos('Все контура объекта совпадают с шаблоном (лежат на шаблоне)!', ll, tt); if mapGetExclusiveSubject(temp.ObjHandle, 0) <> 0 // шаблон замкнут then ShowMessagePos('Все контура объекта внутри шаблона, либо совпадают!', ll, tt); end; 2 : ShowMessagePos('Все контура объекта вне шаблона!', ll, tt); 3 : ShowMessagePos('Один или несколько контуров объекта пересекаются с шаблоном!', ll, tt); 4 : ShowMessagePos('Контур шаблона внутри контура объекта!', ll, tt); 0 : begin ShowMessagePos('Ошибка установки обрабатываемого объекта и метода обработки!', ll, tt); exit; end; end; if not (res in [3,4]) then exit; while 1=1 do begin objOut.CreateObjectByKey(1, KM_IDDOUBLE2, objIn.KeyName);
res := ovlObj.GetNextObject; if res = 0 then break; objOut.Commit; mvMap.Repaint; objOut.Style := OS_SELECT;
if MessageDlgPos('Вычислить следующее пересечение?',mtConfirmation, mbOKCancel, 0, ll, tt) = IDCANCEL then begin // если нажата кнопка Отмена, то ObjOut.Delete; // удалить созданный рез. объект exit; // и на выход... end;
ObjOut.Delete; // если нажата кнопка Ок, то просто удалить // объект и в начало цикла ... end;
// если пересечений больше нет, то выдать сообщение и на выход ShowMessagePos('Пересечений больше нет!', ll, tt); finally ovlObj.FreeOVL; end; end;