Опять polyline to polygon

0 голосов
спросил 26 Янв, 04 от dios (5,300 баллов) в категории Программные продукты Esri
HLP PLZ


есть тема незамкнутых полилиний.
есть задача собрать из этого один большой полигон (как сумму полигонов из каждой полилинии)

беру первую полилинию, переварачиваю в полигон, отображаю, все в порядке, пытаюсь сделать ей union, возвращяеться нулевой (пустой ) полигон.


               pFeatureKONT->get_ShapeCopy(&pGeomKONT);
               pPolyline = pGeomKONT;
               pPolygonPointCollLine = pPolyline;
               pGeometryFactory->CreateEmptyGeometryByESRIType(esriCore::esriShapePolygon,&tmpg);
               pPolygon = tmpg;
               pPolygonPointColl = pPolygon;
               pPolygonPointColl->AddPointCollection(pPolygonPointCollLine);
               pPolygon->Close();
               pGeomOutKONT1 = pPolygonOut;
               tmpg2 = pPolygon;


               CReturnUnion(tmpg2,pGeomOutKONT1,tmpg2);



//-------------------------------------------------
CCMDIsoBars::CReturnUnion(esriCore::IGeometryPtr pGeomIn, esriCore::IGeometryPtr & pGeomOutF, esriCore::IGeometryPtr pGeomOutD)
{
esriCore::ITopologicalOperatorPtr pTO;
     esriCore::IGeometryPtr pGeomN;
     
               pTO = pGeomOutD;
               pTO->Union(pGeomIn,&pGeomN);
               pGeomOutF=pGeomN;
}

В чем проблем кто-нить знает?

29 Ответы

0 голосов
ответил 26 Янв, 04 от dios (5,300 баллов)
Мля Господа, что вообще ни у кого нет никаких соображений?image
0 голосов
ответил 26 Янв, 04 от Alexander1 (32,520 баллов)

А можно поподробнее растолковать, как это вот происходит:

"беру первую полилинию, переварачиваю в полигон"

Т.е. уже точно известно, что некая полилиния замкнута и образует контур полигона?

0 голосов
ответил 27 Янв, 04 от dios (5,300 баллов)
есть тема контуров (набор незамкнутых полилиний)

надо из них сделать большой полигон. (из каждой линии контур и затем контура слить в один)

вот такая байда:

while(pFeatureKONT != NULL)
     {
          pFeatureKONT->get_ShapeCopy(&pGeomKONT);
          pPolyline = pGeomKONT;
          pPolygonPointCollLine = pPolyline;
          pGeometryFactory->CreateEmptyGeometryByESRIType(esriCore::esriShapePolygon,&tmpg);
          pPolygon = tmpg;
          pPolygonPointColl = pPolygon;
          pPolygonPointColl->AddPointCollection(pPolygonPointCollLine);
          pPolygon->Close();
          CReturnIntersection(NGDUPgnH,pGeomOut1,pPolygon);
          CReturnUnion(pGeomOutKONT2,pGeomOutKONT2,pGeomOut1);
          pFCursorKONT->NextFeature(&pFeatureKONT);
     }
если не делать intersection (NGDUPgnH - просто здоровый полигон, заранее больший чем все другие) полигон возвращяеться ущербным и union его брать не хочет(возвращяет пустой полигон), зато если его интерсектить с большим полигоном (в результате возврящяеться тот-же полигон) и затем загнать в union результат интерсекции - все работает.

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

может у кого есть какие-нибудь соображения по этому поводу?
0 голосов
ответил 27 Янв, 04 от dios (5,300 баллов)
это перед циклом

     esriCore::IGeometryPtr pGeomKONT(esriCore::CLSID_Polyline);

     esriCore::IGeometryPtr pGeomOutKONT1(esriCore::CLSID_Polygon);

          esriCore::IPointCollectionPtr pPolygonPointColl(esriCore::CLSID_Polygon);
          esriCore::IPointCollectionPtr pPolygonPointCollLine(esriCore::CLSID_Polyline);
          esriCore::IPolygonPtr pPolygon(esriCore::CLSID_Polygon);

          esriCore::IPolylinePtr pPolyline;

          esriCore::IGeometryFactoryPtr pGeometryFactory(esriCore::CLSID_GeometryEnvironment);


esriCore::IGeometryPtr tmpg;
0 голосов
ответил 27 Янв, 04 от Alexander1 (32,520 баллов)

Я бы перед тем, как создавать коллекцию из полилиний, проверил бы её на замкнутость. Ну, например, такой функцией:

Private Function IsClosed(pEnumFeatures As IEnumFeature) As Boolean
    Dim pGeometryBag As IGeometryCollection
    Dim pTopoOperator As ITopologicalOperator
    Dim pGeomCollection As IGeometryCollection
    Dim pFeature As IFeature
   
      pEnumFeatures.Reset
      Set pGeometryBag = New GeometryBag
      Set pFeature = pEnumFeatures.Next
      Do While Not pFeature Is Nothing
        pGeometryBag.AddGeometry pFeat.Shape
        Set pFeature = pEnumFeatures.Next
      Loop
      Set pTopoOperator = New Polyline
      pTopoOperator.ConstructUnion pGeometryBag
   
      Set pGeomCollection = pTopoOperator
      If pGeomCollection.GeometryCount > 1 Then
        IsClosed = False
      Else
        IsClosed = True
      End If
    '
    Set pGeometryBag = Nothing
    Set pTopoOperator = Nothing
    Set pGeomCollection = Nothing
    Set pFeature = Nothing
End Function

Ну и ещё перед любыми Spatial операциями делал бы  Simplify .

 

0 голосов
ответил 27 Янв, 04 от dios (5,300 баллов)
Полилинии ТОЧНО не замкнутые. (Должны быть, но их не я делаю)

Как на счет:
pPolygon->Close(); (см. Код)
0 голосов
ответил 27 Янв, 04 от Alexander1 (32,520 баллов)

Это не работает для ВСЕХ сегментов полилинии:

Closes all Rings in the Polygon by adding a Segment between the To Point and From Point of each Ring if those points are not already identical.  This may result in a non-simple Polygon with Rings crossing each other.  Also, this only closes the last segment and does not fix improperly constructed Rings.

0 голосов
ответил 28 Янв, 04 от dios (5,300 баллов)
В том то и дело, что должно работать


полилинии - это контура, они единственно, что не замкнутые, но енд и бегин пойнты у них почти совпадают
что-то в стиле:   (извиняюсь за корявость)

```___X_____
``/`````````\
``|`````````/
`/`````````/
|`````````|
\_________/
0 голосов
ответил 28 Янв, 04 от dios (5,300 баллов)
Вообще я заметил за аркой такое свойство, что иногда, она выдает ущербные полигоны, т.е. по одним данным программа отрабатывает, по другим, полигон из функции intersects или union или difference возвращяеться 0x000000000
Пустой т.е.
соответственно весь последующий алгоритм летит к чертям


для работы с ITopOp у меня простенькие процедурки в стиле

CReturnDifference(Geom1,Geom2,Geom3);


тело:

CCLASS::CReturnDifference(esriCore::IGeometryPtr pGeomIn1, esriCore::IGeometryPtr & pGeomOut1, esriCore::IGeometryPtr pGeomin2)
{
     esriCore::ITopologicalOperatorPtr pTO;
     esriCore::IGeometryPtr pGeomN;
     
               pTO = pGeomin2;
               pTO->Difference(pGeomIn1,&pGeomN);
               pGeomOut1=pGeomN;
}
0 голосов
ответил 28 Янв, 04 от Alexander1 (32,520 баллов)

"...они единственно, что не замкнутые..."

Вот этого и достаточно, чтобы Close Method не работал для твоей коллекции.

Добро пожаловать на сайт Вопросов и Ответов, где вы можете задавать вопросы по GIS тематике и получать ответы от других членов сообщества.
...