' Centroid4Poly is Tim's name for it. ' ET.Poly2Cen ' Converts polygons in the active theme to centroid points ' Despite what ArcView's online help says, Polygon.ReturnCenter does NOT ' return the true centroid. This routine is adapted from O'Rourke, ' Computational Geometry in C. theTitle = "Convert Polygons to Centroids" theView = av.GetActiveDoc theTheme = theView.GetActiveThemes.Get(0) inFTab = theTheme.GetFTab ' Specify the output shapefile... fnDefault = FileName.Make("$HOME").MakeTmp("shape","shp") fnOutput = FileDialog.Put( fnDefault,"*.shp","Output Shape File" ) if (fnOutput = nil) then exit end ' Multipart option choicelist = {"Create one centroid point", "Create centroid point for each part"} mpOption = MsgBox.ChoiceAsString(choicelist,"Multipart polygons:",theTitle) if (mpOption = nil) then exit end ' Do it! fnOutput.SetExtension("shp") outFTab = FTab.MakeNew( fnOutput, POINT ) inFields = inFTab.GetFields newFields = List.Make for each f in inFields if (f.GetName <> "shape") then newFields.Add(f.Clone) end end outFTab.AddFields(newfields) ' Use selected shapes if there are any, otherwise iterate ' through the entire FTab... ' if (inFTab.GetSelection.Count > 0) then colToProcess = inFTab.GetSelection nRecs = colToProcess.Count else colToProcess = inFTab nRecs = colToProcess.GetNumRecords end nullCount = 0 nCount = 0 nRecAdded = 0 mpCount = 0 inSF = inFTab.FindField("shape") outSF = outFTab.FindField("shape") for each r in colToProcess val = inFTab.ReturnValue(inSF,r) if (val.IsNull) then nullCount = nullCount + 1 else if (val.Explode.Count > 1) then mpCount = mpCount + 1 end if (mpOption = "Create one centroid point") then polylist = {val} else polylist = val.explode end for each aPolygon in polylist ringlist = aPolygon.AsPolyLine.Flip.AsList CGx = 0 CGy = 0 Areasum2 = 0 for each plist in ringlist n = plist.Count for each i in 1..(n-2) x0 = plist.Get(0).GetX y0 = plist.Get(0).GetY x1 = plist.Get(i).GetX y1 = plist.Get(i).GetY x2 = plist.Get(i+1).GetX y2 = plist.Get(i+1).GetY Cent3x = x0 + x1 + x2 Cent3y = y0 + y1 + y2 A2 = ((x1 - x0) * (y2 - y0)) - ((x2 - x0) * (y1 - y0)) CGx = CGx + (A2 * Cent3x) CGy = CGy + (A2 * Cent3y) Areasum2 = Areasum2 + A2 end end CGx = CGx / (3 * Areasum2) CGy = CGy / (3 * Areasum2) p = CGx@CGy '**** checks whether p is in polygon, and moves to nearest if (aPolygon.Contains(p).Not) then mindist = 999999 newp = p aPolyListofLists = aPolygon.AsList for each plist in aPolyListofLists for each pt in plist dist = ((pt.GetX - CGx)^2 + (pt.GetY - CGy)^2).sqrt if (dist < mindist) then mindist = dist newp = pt.GetX@pt.GetY end end end p = newp end '**** add record nRecNew = outFTab.AddRecord outFTab.SetValue(outSF,nRecNew,p) for each inF in inFTab.GetFields fName = inF.GetName if (fName <> "shape") then outF = outFTab.FindField(fName) val = inFTab.ReturnValue(inF,r) outFTab.SetValue(outF,nRecNew,val) end end nRecAdded = nRecAdded + 1 end end nCount = nCount + 1 av.SetStatus((nCount / nRecs) * 100) end if (nullCount > 0) then MsgBox.Warning("There were " + nullCount.AsString + " null shapes in the folder that " +NL + "did not get centroids made.","") end av.ClearStatus av.ClearMsg theMsg = nCount.AsString++"points created."++NL+ mpCount.AsString++"multipart polygons processed." MsgBox.Info(theMsg, theTitle) if (MsgBox.YesNo("Add shapefile as theme to a view?", theTitle, true).Not) then exit end ' Create a list of views and allow the user to choose which view to ' add the new theme to... lstViews = {} for each d in av.GetProject.GetDocs if (d.Is(View)) then lstViews.Add( d ) end end lstViews.Add("") vweAddTo = MsgBox.ListAsString( lstViews,"Add Theme to:", "Convert Polygon to Point" ) ' Get the specified view, make the theme, and add it... if (vweAddTo <> nil) then if (vweAddTo = "") then vweAddTo = View.Make vweAddTo.GetWin.Open end thmNew = FTheme.Make(outFTab) vweAddTo.AddTheme( thmNew ) vweAddTo.GetWin.Activate end