I want to divide a polygon into smaller polygons. For this purpose my procedure was to first convert the polygon into minimum bounding geometry and divide it into smaller polygons using major and minor axis and finally clip it using the main polygon. I have written a code but it divide the polygon wrongly, this is because for finding the major axis of the minimum bounding geometry, I have to use its envelope, and because the orientation of envelope is different from minimum bounding geometry, the line axis for dividing the polygon is determined wrongly. So, I searched the net and found the same problem that is solved in VBA. I tried to convert the code to C#. The link is as follows:
https://stackoverflow.com/questions/15291223/convex-quadrilateral-polygons-subdivision-in-equal-parts-using-python-ogr/16355198#16355198
And my code is as following:
const int xSplit = 5;
const int ySplit = 5;
Double[] dCoords=new double[3];
int lID;
/////////////////// select features
IPolygon pPolygon = new PolygonClass();
IFeatureCursor polygonFeatCursor = MBRFeatureClass.Search(null, false);
IFeature polygonFeature = polygonFeatCursor.NextFeature();
while (polygonFeature!=null)
{
pPolygon = polygonFeature.Shape as IPolygon;
GridQuadriLateral(pPolygon, buildingFeatureClass);
polygonFeature = polygonFeatCursor.NextFeature();
}
private void GridQuadriLateral(IPolygon pPolygon, IFeatureClass buildingFeatureClass)
{
ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;
const int xSplit = 5;
const int ySplit = 5;
Double[ , , ] dCoords =new double[xSplit,ySplit, 2];
int lIdx=0;
double[] cx = new double[4];
double[] cy = new double[4];
double[] dx = new double[4];
double[] dy = new double[4];
double dx2;
double dy2;
double x1;
double x2;
double x3;
double y1;
double y2;
double y3;
int l;
int xs;
int ys;
// Get the corner coords of the quad
for (l = 0; l <= 3; l++)
{
lIdx = GetIndexOfNextCornerSegment(lIdx, pPolygon);
cx[l] = pSegmentCollection.Segment[l].FromPoint.X;
cy[l] = pSegmentCollection.Segment[l].FromPoint.Y;
}
dx[0] = ((cx[1] - cx[0])/xSplit);
dx[1] = ((cx[1] - cx[2]) / ySplit);
dx[2] = ((cx[2] - cx[3]) / xSplit);
dx[3] = ((cx[0] - cx[3]) / ySplit);
dy[0] = ((cy[1] - cy[0]) / xSplit);
dy[1] = ((cy[1] - cy[2]) / ySplit);
dy[2] = ((cy[2] - cy[3]) / xSplit);
dy[3] = ((cy[0] - cy[3]) / ySplit);
for (ys= 0; ys<ySplit; ys++)
{
x1 = cx[3] + dx[3] * ys;
y1 = cy[3] + dy[3] * ys;
x2 = cx[2] + dx[1] * ys;
y2 = cy[2] + dy[1] * ys;
dx2 = ((x2 - x1) / xSplit);
dy2 = ((y2 - y1) / ySplit);
for (xs = 0; xs <xSplit; xs++)
{
x3 = x1 + dx2 * xs;
y3 = y1 + dy2 * ys;
dCoords[xs, ys,0] = x3;
dCoords[xs, ys,1] = y3;
}
}
//build grid
IFeatureBuffer pFtrBfr = null;
pFtrBfr = buildingFeatureClass.CreateFeatureBuffer();
IPointCollection pPointCollection ;
IPoint pPoint;
IFeatureCursor pFeatureCursor = buildingFeatureClass.Insert(true);
for (int i = 0; i < ySplit-1; i++)
{
for (int j = 0; j < xSplit-1; j++)
{
pPointCollection = new PolygonClass();
pPoint = new PointClass();
pPoint.PutCoords(dCoords[j,i,0], dCoords[j,i,1]);
pPointCollection.AddPoint(pPoint);
pPoint.PutCoords(dCoords[j, i+1, 0], dCoords[j, i+1, 1]);
pPointCollection.AddPoint(pPoint);
pPoint.PutCoords(dCoords[j+1, i+1, 0], dCoords[j+1, i+1, 1]);
pPointCollection.AddPoint(pPoint);
pPoint.PutCoords(dCoords[j+1, i, 0], dCoords[j+1, i, 1]);
pPointCollection.AddPoint(pPoint);
pPoint.PutCoords(dCoords[j, i, 0], dCoords[j, i, 1]);
pPointCollection.AddPoint(pPoint);
pFtrBfr.Shape = pPointCollection as IGeometry;
pFeatureCursor.InsertFeature(pFtrBfr);
pFeatureCursor.Flush();
/*
IPolygon ppPolygon = new PolygonClass();
ppPolygon = pPointCollection as IPolygon;
ppPolygon.Close();
IFeature pFeat = buildingFeatureClass.CreateFeature();
pFeat.Shape = ppPolygon;
pFeat.Store();
*/
}
}
m_hookHelper.ActiveView.Refresh();
//throw new NotImplementedException();
}
private int GetIndexOfNextCornerSegment(int lStartIdx, IPolygon pPolygon)
{
int index = 0;
ISegmentCollection pSegmentCollection = pPolygon as ISegmentCollection;
ILine pLine1 = new LineClass();
ILine pLine2 = new LineClass();
int l;
int lNxtIdx;
double dAng;
for ( l = 0; l < pSegmentCollection.SegmentCount-1; l++)
{
lNxtIdx = lStartIdx + 1;
if (lNxtIdx==pSegmentCollection.SegmentCount)
{
lNxtIdx = 0;
}
pLine1 = pSegmentCollection.Segment[lStartIdx] as ILine;
lNxtIdx = lNxtIdx + 1;
if (lNxtIdx==pSegmentCollection.SegmentCount)
{
lNxtIdx = 0;
}
pLine2 = pSegmentCollection.Segment[lNxtIdx] as ILine;
dAng = Math.Abs(pLine1.Angle-pLine2.Angle)*(180/(Math.PI));
if (dAng>=180)
{
dAng = 360 - dAng;
}
if (dAng>20)
{
index= lNxtIdx;
break;
}
}
return index;
//throw new NotImplementedException();
}
But now my problem is that when I run the code, the output is not partitioned completely. I am completely confused about it.
The image of the output is as follows:
Best Answer
Finally, I could partition a minimum bounding rectangle into smaller units using the following code: