'******************DonutShop 2.0***08/12/98************************ '*-------------------------Jim Keller-----------------------------* '*---------------County of Santa Cruz GIS Staff-------------------* '*--------------email: pln943@co.santa-cruz.ca.us-----------------* '*---------------------phone: (408) 454-3122----------------------* '****************************************************************** '* * '* This script will cut doughnut holes out of any polygon (within * '* the editable layer) that contains other polygons. It is * '* written such that an edit/undo-feature-edits commands issued * '* after Doughnut Shop has been run will restore the original * '* polygon areas. * '* * '* To use this script : * '* Compile it, add a button to the view's button pad and attach * '* the script to the click field of the button. * '* * '* Please share back any improvements you make to this script. * '* * '**DISCLAIMER***DISCLAIMER***DISCLAIMER***DISCLAIMER***DISCLAIMER** '* * '* THIS SCRIPT IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY * '* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED * '* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * '* A PARTICULAR PURPOSE. * '* * '* This script is provided for non-commercial purposes only. * '* Permission to use, copy, and distribute is hereby granted, * '* provided there is no charge or fee for such copies. * '* * '****************************************************************** theView = av.GetActiveDoc theDisplay = theView.GetDisplay theTheme = theView.GetEditableTheme If (theTheme = nil) then 'Check to see if ther is an editable theme. MsgBox.Info("No Theme is set to Editable!", "Donut Shop") return nil 'abort script else 'continue script theTheme.ClearSelection theFTab = theTheme.GetFTab fldShape = theFTab.FindField("shape") 'Initialize a variable to point to the shape discription field of the FTab. theBitMap = theFTab.GetSelection 'get the fTab's selection set theFTab.BeginTransaction 'Mark the beginning of transaction to the FTab. theBitMap.ClearAll 'Deselect all records. bitCeiling = (theFTab.GetNumRecords ) 'Count the number of records in the FTab. theBit = 0 'TheBit variable initialized to 0 bitCount = 3 'BitCount Variable initialized to 3 donuts = 0 'Donuts variable initialized to 0 errors = 0 'Error count initialized to 0 while (TheBit < (BitCeiling -1)) 'Loop operation until each feature hase been checked for islands. if (BitCount < 3) then 'If BitCount is >2 it indicates that the feature is within more than one polygon and will requires reprocessing until all donut holes are cut. theBit = (theBit + 1) 'Since the feature doesn't require reprocessing the selected feature is incremented for the next looping. end'if theBitMap.ClearAll 'Deselect all features in the BitMap. theBitMap.set(TheBit) 'Select the feature currently being checked for islandness. r1 = theFTab.GetSelection.GetNextSet(-1) 'Initialize a variable to hold the polygon that is an island. theTheme.SelectByTheme (theTheme, #FTAB_RELTYPE_COMPLETELYCONTAINS, 0, #VTAB_SELTYPE_OR) 'Select all features in the theme that contain the polygon being checked. theBitMap = theFTab.GetSelection 'get the selected features (this will be the polygon being checked for islandness and any polygons containing it. bitCount = (theBitMap.count) 'Set variable to number of selected features. while (BitCount > 1) 'then 'If # of selected features is greater than 1 then the polygon being checked is an island needing to be cut out. r2 = theFTab.GetSelection.GetNextSet(r1) 'Initialize a variable to hold the first polygon that contains the island. if (r2 = -1) then r2= theFTab.GetSelection.GetNextSet(r2) end'if shpR2 = theFTab.ReturnValue(fldShape,R2) 'Initialize a variable holding the shape description of RecBack. shpR1 = theFTab.ReturnValue(fldShape,R1) 'Initialize a variable holding the shape description of RecFront. areaR2 = shpR2.returnarea/43560 'Initialize a variable holing the area of RecBack. areaR1 = shpR1.returnarea/43560 'Initialize a variable holding the area of RecFront. if(not(areaR2 > AreaR1)) then theBitMap.Clear(R2) else shpDiff = shpR2.ReturnDifference(shpR1) newArea = shpDiff.ReturnArea/43560 if((newArea.isNull) or (newArea = areaR2 ) ) then 'we have found in certain instances that a poly not actually containing another gets selected. This 'line prevents the storing of the new poly if this is the case since the subtract actually either deletes the hole poly's area or leaves it un altered. 'You could also place a counter or flagging routine here to track these instances. errors = errors + 1 theBitMap.Clear(R2) else theFTab.SetValue(fldShape,R2,shpDiff) 'replace the old shape value with the new, donuted one end'if end'if bitCount = bitCount - 1 if(bitCount = 1) then Donuts = (Donuts + 1) 'This increments the donut hole counter only on the last time the island is cut from its surrounding polygons. end'if end'while end'while end'if theFTab.Flush 'Commits the FTab in RAM to the FTAB File. theFtab.EndTransaction 'Ends the Transaction. theTheme.ClearSelection 'Clear all selected features. theTheme.Invalidate(TRUE) 'Flag a redraw of the theme. theDisplay.Invalidate(TRUE) 'Flag a redraw of the current window. if(errors > 0) then MsgBox.Warning("There were " ++errors.AsString +" errors encountered during processing.","Donut Shop") donuts = (donuts - errors) end'if MsgBox.Info (Donuts.asString ++" donut holes were made!","Donut Shop") 'Display message box indicatingthe number of donut holes made. This number should correspond to the number of islands in the Theme.