Customer Service | Training | Contact Us
You are here: Home > User Forums > arcgis desktop discussion forums > Thread Replies

ArcGIS Desktop Discussion Forums

ArcGIS Desktop - Data Editing forum

Create Equal Area Polygons Inside Existing...   John Siceloff Dec 01, 2006
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Dec 02, 2006
Re: Create Equal Area Polygons Inside Exist...   John Siceloff Dec 04, 2006
Re: Create Equal Area Polygons Inside Exist...   Anna Forrest Mar 05, 2007
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 17, 2008
Re: Create Equal Area Polygons Inside Exist...   John Siceloff Dec 04, 2006
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Mar 06, 2007
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Mar 06, 2007
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Mar 06, 2007
Re: Create Equal Area Polygons Inside Exist...   Sandy Burns Mar 09, 2007
Re: Create Equal Area Polygons Inside Exist...   Sara Ovalle May 17, 2007
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 17, 2008
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 18, 2008
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Sep 18, 2008
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 18, 2008
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Sep 22, 2008
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 22, 2008
Re: Create Equal Area Polygons Inside Exist...   Miles Hitchen Sep 22, 2008
Re: Create Equal Area Polygons Inside Exist...   Todd Lusk Sep 22, 2008
Re: Create Equal Area Polygons Inside Exist...   Larry Phelps Oct 08, 2008
Report Inappropriate Content • Top • Print • Reply    
Subject Create Equal Area Polygons Inside Existing Polygons 
Author John Siceloff 
Date Dec 01, 2006 
Message I have a coverage of Sections (square miles). I would like to create a "grid" inside each square mile. This grid needs to be evenly divided based on the size of the section, such as 100 equal area cells, 10 by 10, approximately 528 feet each side of the cell. The problem is, here in Alaska, we're so close to the North Pole, our section lines (north-south, and east-west) 1.) are not 'strait,' 2.) regardless of projection are slightly skewed, and 3.) the sides of the 'square' are usually differing lengths. Any kind of grid I make uses 'absolutes' in direction and spacing for creating the grids. Thus, the grid borders don't match the sections. For one square mile, the difference is slight, hardly noticeable, but over the thousands of square miles I need, the error aggregates to a huge distance inaccuracy.

I can convert the polygons to polylines, and properly segment the lines, however, I'm left only with points along the borders, not inside the sections as I need (although I would prefer polygons, points will suffice). I would have to literally draw hundreds of thousands of lines to 'connect the dots.'

Since lines can easily be divided into certain lengths, or an equal spacing, does anyone know if the same can be done to polygons? Has anyone written a script to convert slightly irregular polygons into equal area polygons inside of the original? I can understand the geometric complexity (and multitude of possible outcomes) in accomplishing this task with highly irregular polygons, but this is frustrating when my polygons are very close to ‘square,’ but not quite.

Any help would be greatly appreciated. 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Dec 02, 2006 
Message Hi john,

Any chance you could post a shapefile containing a sample area or two? I don't think it would be too tricky to write a script to do it, but need something to work with.

Cheers,
Miles.
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author John Siceloff 
Date Dec 04, 2006 
Message Thank you for the interest Miles. I’ll attach the whole coverage of square miles (and Township / Range for reference) for the Kenai Peninsula, in Alaska (if you need a smaller sample, you can chop it out to work with). When I spoke with ESRI technical support, they stated this operation could not be done except by a talented programmer (this was iterated to me from one of their top ‘coordinate’ folks). Additionally, ESRI would be interested in viewing the code (just fyi). In the knowledge database, I’ve read several other people trying to attempt a similar task, so I believe a successful code would generate quite a bit of interest.

This ‘grid’ I am trying to build is for assigning addresses (and verifying the Master Street Address Guide for 911 dispatch (fire, police, ambulance)). In the infinite wisdom of the government, the origin for the entire area is located at the intersection of a Township / Range line (of which these square miles are based, 36 per), starting at address #10,000. In the usual American fashion, nothing is standardized, such as the metric system, and my guess is a few politicians were drinking beer and throwing darts at maps to find the starting location and drawing the grid.

My point is:

1.) The address grid would be very similar to a simple X-Y (cartesian) grid. A square mile is roughly 5280 feet by 5280 feet. Except for my square miles which seem to differ slightly.

2.) The grid inside each square mile wouldn’t have to be perfect, there can be a some tolerance since one address number is assigned every 5.28 feet (1000 addresses per mile). What I’m looking to build is a reference for the square feet and the corresponding addresses for the entire coverage, simple X-Y coordinate ranges contained in polygon form. However, if the grid is based uniformly over the entire coverage from the origin, the error becomes several miles incorrect on the edges of the coverage, which doesn’t help me.

3.) I need the origin at the intersection of the line between Ranges 4 West and 5 West, and the line between Townships 1 South and 1 North. For addresses, this starting point is 10,000 – 10,000 (I’m assuming North and West). For our projection, we use NAD 27, State Plane Coordinate System (UTM) Alaska Zone 4. Our measurements are in feet. The origin would be 490,349 – 2,238,397 in feet coordinates.

4.) I would like to make the grid as tight as possible, 100 by 100 in each square mile (every 52.8 feet or so, every 10 addresses or so). This resolution might make the files to large, so the best resolution possible, down to 10 by 10 would be great, even if the grids were separated into different coverages.

That’s all the details I can think to volunteer at this time. I really appreciate your looking into this.

Regards,

John

 
  sections.zip (opens in new window)
TownshipRange.zip (opens in new window)
 
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Anna Forrest 
Date Mar 05, 2007 
Message Any luck with this? I'm trying to do a similar job and would appreciate any assistance.

Regards,

Anna Forrest 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 17, 2008 
Message Thanks for asking this question. I've been trying to do something similar. 
  Todd Lusk
Dakota County, MN 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author John Siceloff 
Date Dec 04, 2006 
Message Oh yea, the numbers I provided, none are negative, they are all positive. The dash simply acts to separate X and Y numbers. I used commas to make the numbers easier to read, not separate them. Sorry about the confusion. There are no negative numbers. In the ‘negative’ areas of the grid, the numbers simply change direction, such a 400 North, and 400 South. 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Mar 06, 2007 
Message Hi Anna, John,

Sorry I didn't get back to you sooner John.

Could you confirm that what you're looking for is a utility to basically grid an irregualr 4-sided polygon (see attached image)? If this is the case then it wouldn't be too difficult to write the code. Also, I notice from John's shape files that the polygons have more than 4 vertices, most have 5 vertices per side. Is this necessarry?

Cheers,
Miles.
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Mar 06, 2007 
Message Here's the image!
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
  Gridding a Quadrilateral.JPG (opens in new window)
 
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Mar 06, 2007 
Message Hi,

The script below will grid the selected polygon (assuming it's roughly quadrilateral). To use the code copy it into a new Module in the VBA editor. Close the editor. Make sure your map has two polygon layers, the first containing the polygons you want to grid, the second being an empty polygon featureclass.

Now select a polygon (from the first layer) that you want to grid and then run the macro called "GridQuadrilateral". The code can easily be changed to grid all selected polygons, so let me know if it's what you need.

Cheers,
Miles.

 
 
Public Sub GridQuadrilateral()
Dim pMxDoc As IMxDocument
Dim pInFtrLyr As IFeatureLayer
Dim pFtrSel As IFeatureSelection
Dim pOutFtrLyr As IFeatureLayer
Dim pPolygon As IPolygon
Dim pSegColl As ISegmentCollection
Dim lIdx As Long
Dim lCornerIdx(3, 1) As Double
Dim l As Long

    ' Get the first selected polygon on the first layer
    Set pMxDoc = ThisDocument
    Set pInFtrLyr = pMxDoc.FocusMap.Layer(0)
    Set pFtrSel = pInFtrLyr
    Set pPolygon = pInFtrLyr.FeatureClass.GetFeature(pFtrSel.SelectionSet.IDs.Next).Shape
    Set pSegColl = pPolygon
    
    ' Get the corner coords of the quad
    lIdx = 0
    For l = 0 To 3
        lIdx = GetIndexOfNextCornerSegment(lIdx, pPolygon)
        lCornerIdx(l, 0) = pSegColl.Segment(lIdx).FromPoint.X
        lCornerIdx(l, 1) = pSegColl.Segment(lIdx).FromPoint.Y
    Next l

    
' Calculate the grid coordinates and store in array
Const GRID_SIZE = 10
Dim dStep As Double
Dim i As Long, j As Long
Dim dx As Double, dy As Double
Dim pt1x As Double, pt1y As Double, pt2x As Double, pt2y As Double
Dim nx As Double, ny As Double
Dim dCoords(GRID_SIZE, GRID_SIZE, 1) As Double

    dStep = 1 / CDbl(GRID_SIZE)

    For i = 0 To GRID_SIZE
        dx = (lCornerIdx(1, 0) - lCornerIdx(0, 0)) * dStep * i
        dy = (lCornerIdx(1, 1) - lCornerIdx(0, 1)) * dStep * i
        pt1x = lCornerIdx(0, 0) + dx
        pt1y = lCornerIdx(0, 1) + dy
        
        dx = (lCornerIdx(2, 0) - lCornerIdx(3, 0)) * dStep * i
        dy = (lCornerIdx(2, 1) - lCornerIdx(3, 1)) * dStep * i
        pt2x = lCornerIdx(3, 0) + dx
        pt2y = lCornerIdx(3, 1) + dy
        
        For j = 0 To GRID_SIZE
            dx = (pt2x - pt1x) * dStep * j
            dy = (pt2y - pt1y) * dStep * j
            nx = pt1x + dx
            ny = pt1y + dy
            
            dCoords(j, i, 0) = nx
            dCoords(j, i, 1) = ny
            
        Next j
    Next i


' Now create the polygons
Dim pFtrCls As IFeatureClass
Dim pFtrCsr As IFeatureCursor
Dim pFtrBfr As IFeatureBuffer
Dim pPtColl As IPointCollection
Dim pPt As IPoint

    Set pOutFtrLyr = pMxDoc.FocusMap.Layer(1)
    Set pFtrCls = pOutFtrLyr.FeatureClass
    Set pFtrBfr = pFtrCls.CreateFeatureBuffer
    Set pFtrCsr = pFtrCls.Insert(True)
    
    For i = 0 To GRID_SIZE - 1
        For j = 0 To GRID_SIZE - 1
        
            Set pPtColl = New Polygon
            Set pPt = New Point
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i + 1, 0), dCoords(j, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i + 1, 0), dCoords(j + 1, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i, 0), dCoords(j + 1, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            
            Set pFtrBfr.Shape = pPtColl
            pFtrCsr.InsertFeature pFtrBfr
            
        Next j
    Next i

    pMxDoc.ActiveView.Refresh
    
End Sub


Private Function GetIndexOfNextCornerSegment(lStartIdx As Long, pPolygon As IPolygon) As Long
Dim PI As Double
Dim pSegColl As ISegmentCollection
Dim pLine1 As ILine, pLine2 As ILine
Dim l As Long
Dim lNxtIdx As Long
Dim dAng As Double

    PI = Atn(1) * 4
    Set pSegColl = pPolygon
    For l = 0 To pSegColl.SegmentCount - 2
        lNxtIdx = lStartIdx + l
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine1 = pSegColl.Segment(lNxtIdx)
        lNxtIdx = lNxtIdx + 1
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine2 = pSegColl.Segment(lNxtIdx)
        dAng = Abs(pLine1.Angle - pLine2.Angle) * 180 / PI
        If dAng > 20 Then
            ' The start point of this segment is a corner point
            GetIndexOfNextCornerSegment = lNxtIdx
            Exit Function
        End If
    Next l
    
GetIndexOfNextCornerSegment = -1
End Function
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Sandy Burns 
Date Mar 09, 2007 
Message Miles.......I am also trying to split a polygon (a long rectangle) and have many to do. I was able to make your module work, but what I need is to be able to tell it to make each new poly 24 inches wide. There may or may not be enough room to make the last row 24 inches wide, which is fine. Is there a way to modify your module to make it do that? My skills w/VB Editor are pretty much non-existent. Thanks in advance for any direction you can provide. 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Sara Ovalle 
Date May 17, 2007 
Message Could you change the code to grid all selected polygons.

Thanks so much! 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 17, 2008 
Message Thank you Miles for taking the time to pull this code together. It works great and does exactly what I need it to do. 
  Todd Lusk
Dakota County, MN 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 18, 2008 
Message Miles, I hope you're watching this thread...

If so, I have two quesitons. First, say I wanted to divide my polygons into different numbers of "cells" in the horiztonal and vertical direction (say 26 horizontally and 10 vertically). I'm assuming this code could be modified to do that. I tried to make the modifications, but apparently haven't quite found the right spot to make the changes.

Second, could this be modified so that it would do all of polygons in a layer rather than just one at a time?

For reference, I included my modified code (that didn't work).

Thanks!
 
 
Public Sub GridQuadrilateral()
Dim pMxDoc As IMxDocument
Dim pInFtrLyr As IFeatureLayer
Dim pFtrSel As IFeatureSelection
Dim pOutFtrLyr As IFeatureLayer
Dim pPolygon As IPolygon
Dim pSegColl As ISegmentCollection
Dim lIdx As Long
Dim lCornerIdx(3, 1) As Double
Dim l As Long

    ' Get the first selected polygon on the first layer
    Set pMxDoc = ThisDocument
    Set pInFtrLyr = pMxDoc.FocusMap.layer(0)
    Set pFtrSel = pInFtrLyr
    Set pPolygon = pInFtrLyr.FeatureClass.GetFeature(pFtrSel.SelectionSet.IDs.Next).Shape
    Set pSegColl = pPolygon
    
    ' Get the corner coords of the quad
    lIdx = 0
    For l = 0 To 3
        lIdx = GetIndexOfNextCornerSegment(lIdx, pPolygon)
        lCornerIdx(l, 0) = pSegColl.Segment(lIdx).FromPoint.X
        lCornerIdx(l, 1) = pSegColl.Segment(lIdx).FromPoint.Y
    Next l

    
' Calculate the grid coordinates and store in array
Const GRID_SIZE = 10
Const GRID_SIZEX = 26
Const GRID_SIZEY = 10
Dim dStep As Double
Dim dStepX As Double
Dim dStepY As Double
Dim i As Long, j As Long
Dim dx As Double, dy As Double
Dim pt1x As Double, pt1y As Double, pt2x As Double, pt2y As Double
Dim nx As Double, ny As Double
Dim dCoords(GRID_SIZEX, GRID_SIZEY, 1) As Double

    'dStep = 1 / CDbl(GRID_SIZE)
    dStepX = 1 / CDbl(GRID_SIZEX)
    dStepY = 1 / CDbl(GRID_SIZEY)

    For i = 0 To GRID_SIZEX
        dx = (lCornerIdx(1, 0) - lCornerIdx(0, 0)) * dStepX * i
        dy = (lCornerIdx(1, 1) - lCornerIdx(0, 1)) * dStepY * i
        pt1x = lCornerIdx(0, 0) + dx
        pt1y = lCornerIdx(0, 1) + dy
        
        dx = (lCornerIdx(2, 0) - lCornerIdx(3, 0)) * dStepX * i
        dy = (lCornerIdx(2, 1) - lCornerIdx(3, 1)) * dStepY * i
        pt2x = lCornerIdx(3, 0) + dx
        pt2y = lCornerIdx(3, 1) + dy
        
        For j = 0 To GRID_SIZEY
            dx = (pt2x - pt1x) * dStepX * j
            dy = (pt2y - pt1y) * dStepY * j
            nx = pt1x + dx
            ny = pt1y + dy
            
            dCoords(j, i, 0) = nx
            dCoords(j, i, 1) = ny
            
        Next j
    Next i


' Now create the polygons
Dim pFtrCls As IFeatureClass
Dim pFtrCsr As IFeatureCursor
Dim pFtrBfr As IFeatureBuffer
Dim pPtColl As IPointCollection
Dim pPt As IPoint

    Set pOutFtrLyr = pMxDoc.FocusMap.layer(1)
    Set pFtrCls = pOutFtrLyr.FeatureClass
    Set pFtrBfr = pFtrCls.CreateFeatureBuffer
    Set pFtrCsr = pFtrCls.Insert(True)
    
    For i = 0 To GRID_SIZEX - 1
        For j = 0 To GRID_SIZEY - 1
        
            Set pPtColl = New Polygon
            Set pPt = New Point
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i + 1, 0), dCoords(j, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i + 1, 0), dCoords(j + 1, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i, 0), dCoords(j + 1, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            
            Set pFtrBfr.Shape = pPtColl
            pFtrCsr.InsertFeature pFtrBfr
            
        Next j
    Next i

    pMxDoc.ActiveView.Refresh
    
End Sub

Private Function GetIndexOfNextCornerSegment(lStartIdx As Long, pPolygon As IPolygon) As Long
Dim pi As Double
Dim pSegColl As ISegmentCollection
Dim pLine1 As ILine, pLine2 As ILine
Dim l As Long
Dim lNxtIdx As Long
Dim dAng As Double

    pi = Atn(1) * 4
    Set pSegColl = pPolygon
    For l = 0 To pSegColl.SegmentCount - 2
        lNxtIdx = lStartIdx + l
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine1 = pSegColl.Segment(lNxtIdx)
        lNxtIdx = lNxtIdx + 1
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine2 = pSegColl.Segment(lNxtIdx)
        dAng = Abs(pLine1.Angle - pLine2.Angle) * 180 / pi
        If dAng > 20 Then
            ' The start point of this segment is a corner point
            GetIndexOfNextCornerSegment = lNxtIdx
            Exit Function
        End If
    Next l
    
GetIndexOfNextCornerSegment = -1
End Function
 
  Todd Lusk
Dakota County, MN 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Sep 18, 2008 
Message Hi Todd,

Yep, I've been watching the the thread, I watch most of my old ones! It shouldn't be too difficult to make the changes you requested, ie different width/height cells and apply to all polygons in a layer. I should be able to make the changes within the next 24hrs, if you need it sooner, I'm sure we can come to some sort of financial arrangement ;O)

Cheers,
Miles.
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 18, 2008 
Message The next 24 hours would be plenty good enough. I apprecaite the effort! Thank you! 
  Todd Lusk
Dakota County, MN 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Sep 22, 2008 
Message Hi Todd,

The code below will grid the selected polygons from the first layer into the 2nd layer, as defined by the vars xSplit and ySplit. You may get odd results if the first point of the original polygons isn't in the same relative location, ie the first point for all selected polygons should be topleft, or the first point for all selected polygons sould be bottomright, etc.. If this isn't the case then you'll get the x/y grid spacing alternating, in which case you need to come up with a logical rule which can determine which side of the polygon should be the xSplit and which should be the ySplit.

Let me know how you get on.
Cheers, Miles.
 
 
Option Explicit
    
Const xSplit As Long = 10
Const ySplit As Long = 5
Dim dCoords(xSplit, ySplit, 1) As Double


Public Sub GridSelectedQuadrilaterals()
Dim pMxDoc As IMxDocument
Dim pInFtrLyr As IFeatureLayer
Dim pFtrSel As IFeatureSelection
Dim pPolygon As IPolygon
Dim pEnumIDs As IEnumIDs
Dim lID As Long

    ' Get the first selected polygon on the first layer
    Set pMxDoc = ThisDocument
    Set pInFtrLyr = pMxDoc.FocusMap.Layer(0)
    Set pFtrSel = pInFtrLyr
    Set pEnumIDs = pFtrSel.SelectionSet.IDs
    pEnumIDs.Reset
    
    lID = pEnumIDs.Next
    While lID >= 0
        Set pPolygon = pInFtrLyr.FeatureClass.GetFeature(lID).Shape
        GridQuadrilateral pPolygon
        lID = pEnumIDs.Next
    Wend

    MsgBox "Finished"

End Sub


Private Sub GridQuadrilateral(pPolygon As IPolygon)
Dim pSegColl As ISegmentCollection
Dim lIdx As Long
Dim cx(3) As Double, cy(3) As Double
Dim dx(3) As Double, dy(3) As Double
Dim dx2 As Double, dy2 As Double
Dim x1 As Double, x2 As Double, x3 As Double
Dim y1 As Double, y2 As Double, y3 As Double
Dim l As Long, xs As Long, ys As Long

    Set pSegColl = pPolygon
    
    ' Get the corner coords of the quad
    lIdx = 0
    For l = 0 To 3
        lIdx = GetIndexOfNextCornerSegment(lIdx, pPolygon)
        cx(l) = pSegColl.Segment(lIdx).FromPoint.X
        cy(l) = pSegColl.Segment(lIdx).FromPoint.Y
    Next l

    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 To ySplit
      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) / xSplit
    
      For xs = 0 To xSplit
        x3 = x1 + dx2 * xs
        y3 = y1 + dy2 * xs
        dCoords(xs, ys, 0) = x3
        dCoords(xs, ys, 1) = y3
      Next xs
    
    Next ys

    BuildGrid
    
End Sub


Private Function GetIndexOfNextCornerSegment(lStartIdx As Long, pPolygon As IPolygon) As Long
Dim PI As Double
Dim pSegColl As ISegmentCollection
Dim pLine1 As ILine, pLine2 As ILine
Dim l As Long
Dim lNxtIdx As Long
Dim dAng As Double

    PI = Atn(1) * 4
    Set pSegColl = pPolygon
    For l = 0 To pSegColl.SegmentCount - 2
        lNxtIdx = lStartIdx + l
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine1 = pSegColl.Segment(lNxtIdx)
        lNxtIdx = lNxtIdx + 1
        If lNxtIdx = pSegColl.SegmentCount Then lNxtIdx = 0
        Set pLine2 = pSegColl.Segment(lNxtIdx)
        dAng = Abs(pLine1.Angle - pLine2.Angle) * 180 / PI
        If dAng > 20 Then
            ' The start point of this segment is a corner point
            GetIndexOfNextCornerSegment = lNxtIdx
            Exit Function
        End If
    Next l
    
GetIndexOfNextCornerSegment = -1
End Function


Private Sub BuildGrid()
' Now create the polygons on 2nd layer
Dim pMxDoc As IMxDocument
Dim pOutFtrLyr As IFeatureLayer
Dim i As Long, j As Long
Dim pFtrCls As IFeatureClass
Dim pFtrCsr As IFeatureCursor
Dim pFtrBfr As IFeatureBuffer
Dim pPtColl As IPointCollection
Dim pPt As IPoint

    Set pMxDoc = ThisDocument
    Set pOutFtrLyr = pMxDoc.FocusMap.Layer(1)
    Set pFtrCls = pOutFtrLyr.FeatureClass
    Set pFtrBfr = pFtrCls.CreateFeatureBuffer
    Set pFtrCsr = pFtrCls.Insert(True)
    
    For i = 0 To ySplit - 1
        For j = 0 To xSplit - 1
        
            Set pPtColl = New Polygon
            Set pPt = New Point
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i + 1, 0), dCoords(j, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i + 1, 0), dCoords(j + 1, i + 1, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j + 1, i, 0), dCoords(j + 1, i, 1)
            pPtColl.AddPoint pPt
            pPt.PutCoords dCoords(j, i, 0), dCoords(j, i, 1)
            pPtColl.AddPoint pPt
            
            Set pFtrBfr.Shape = pPtColl
            pFtrCsr.InsertFeature pFtrBfr
            
        Next j
    Next i

    pMxDoc.ActiveView.Refresh

End Sub
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 22, 2008 
Message Overall this works great! I'm assuming the weird cases like I'm seeing in the attached image are probably because the vertexes aren't in the expected order. 
  Todd Lusk
Dakota County, MN 
  grid.GIF (opens in new window)
 
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Miles Hitchen 
Date Sep 22, 2008 
Message Hi Todd,

If you post a shapefile containing the polygon with the odd results I'll see what's causing it.

It could be that one of the polygons corners is less than 20 degrees, in this case the code assumes it's an extra vertex and ignores it, moving onto the next vertex.

Cheers,
Miles.
 
  Miles Hitchen
Software Engineer
Geospatial Team
Ordnance Survey
UK
 
   
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Todd Lusk 
Date Sep 22, 2008 
Message Oh, that could be it.

A sample area is attached in the zip file. It only has nine polygons in it to spare you the pain of the entire dataset (which has 635 polygons). This area has quie a few areas where this is happening.

The code is very effecient. I would say it only took a minute or so to run all 635 polygons when I tried it.

Thank you so much for taking the time to help out with all this. I really do appreciate it! 
  Todd Lusk
Dakota County, MN 
  esri_sample.JPG (opens in new window)
sample_area_esri.zip (opens in new window)
 
Report Inappropriate Content • Top • Print • Reply    
Subject Re: Create Equal Area Polygons Inside Existing Polygons 
Author Larry Phelps 
Date Oct 08, 2008 
Message I ran into the same problem with the tool in an unprojected environment, it cant calculate angles very well in Lat / Long. When I projected the datasets it worked fine. Has anyone found a tool to re-orientate the polygons. My polygons dont always start in Upper Right or Lower Right.