/3.2 (Extension.1 Name: "Poly conversion to spaced points (1.2)" FirstRootClassName: "List" Roots: 2 Roots: 3 Roots: 4 Roots: 12 Roots: 13 Roots: 14 Roots: 15 Version: 32 About: "This extension adds an item to the View|Themes menu for converting polygon/polyline themes into points spaced at regular intervals. (c) 1999 QD." InstallScript: 16 UninstallScript: 17 ExtVersion: 1 ) (List.2 ) (List.3 ) (List.4 Child: 5 ) (List.5 Child: 6 Child: 10 Child: 11 ) (List.6 Child: 7 Child: 8 Child: 9 ) (AVStr.7 S: "View" ) (AVStr.8 S: "Theme" ) (AVStr.9 S: "View.PolythemesToPoint" ) (Choice.10 Disabled: 1 Help: "Poly themes to points//Convert polyline and polygon themes to points by interspersing nodes at a regular user-specified interval." Update: "View.PolyThemesToPoint.Update" Label: "Convert to Points..." Click: "View.PolyThemesToPoint" Shortcut: "Keys.None" ) (Numb.11 N: 6.00000000000000 ) (List.12 ) (Script.13 Name: "Theme.PolyToPointByInterval" SourceCode: "' Name: Theme.PolyToPointByInterval\n'\n' Headline: Convert a poly theme into a point theme\n'\n' Self: {\n' Theme: Theme to process\n' Dist: Distance to lay out points\n' thePrj: A projection\n' }\n'\n' Called by: View.PolyThemesToPoint\n'\n' Returns: NIL upon failure or user cancellation;\n' The new theme upon success\n'\n' Description: Converts each selected feature of the input theme into a \n ' series of points by laying out regular intervals equal to\n' Dist. A new\n' theme is created to hold the output. All attributes of the \n' input theme are copied to the output theme.\n'\n' Topics: Themes; conversion\n'\n' Search Keys:\n'\n' Requires:\n'\n' History: \n' 3-jan-00: Computes distances when Dist==0.\n' 24-dec-99: Computes bearings and point ids when Dist==0.\n' 8/3/99: Added code for Dist==0.\n' 1/26/99: Added \"temperature bar\" monitoring.\n' Pay attention to projections.\n' Enabled user to specify the start distance.\n' AV 3.0, 11/20/98 by Quantitative Decisions. whuber@quantdec.com\n'\n' Comments: If Dist is 0, the actual poly vertices are returned.\n' The bearing is degrees east of north from the previous vertex.\n' Point numbers go 0, 1, ..., for each shape.\n'========================================================== ==================='\ntheTheme = SELF.Get(0)\nDist = SELF.Get(1)\nthePrj = SELF.Get(2)\n\ntheTitle = \"Theme.PolyToPointByInterval (\" + theTheme.GetName + \")\"\ntheProject = av.GetProject\ntheWorkDir = theProject.GetWorkDir\n'============================================================================='\n'\n' Specify the output shapefile.\n'\ndefaultName = theWorkDir.MakeTmp(\"theme\",\"shp\")\nshpFileName = FileDialog.Put( defaultName,\"*.shp\", theTitle + \"--Output Shapefile\")\nif (shpFileName = Nil) then return NIL end\nshpF ileName.SetExtension(\"shp\")\n'============================================================================='\n'\n' Create an appropriate FTab.\n'\noutFTab = FTab.MakeNew( shpFileName, Point )\nif (outFTab = NIL) then\n MsgBox.Error(\"Unable to create an output shape file\", theTitle)\n return NIL\nend\n'============================================================================='\n'\n' Add a field to uniquely identify each point (in conjunction with whatever\n' identifier is originally present).\n'\nfldPtId = Field.Make( \"PtNum\", #FIELD_DECIMAL, 8, 0)\nfldPtId.SetAlias(\"Point #\")\noutFTab.AddFields({fldPtId})\n'\n' 24-dec-99: Add a field for bearing (to be computed only when dist==0).\n' The bearing will be in degrees east of north.\n'\nif (Dist <= 0) then\n fldBearing = Field.Make(\"Bearing\", #FIELD_DECIMAL, 9, 4)\n fldBearing.SetAlias(\"Bearing (deg E of N)\")\n \n fldDistance = Field.Make(\"Distance\", #FIELD_DECIMAL, 32, 8)\n if (thePrj.IsNull) then\n fldDistance.SetAlias(\"Distance (map units)\")\n else\n fldDistance.SetAlias(\"D istance (meters)\")\n end\n outFTab.AddFields({fldBearing, fldDistance})\nend\n'============================================================================='\n'\n' Find the shape fields; these are processed specially.\n'\ninFTab = theTheme.GetFTab\ninShapeField = inFtab.FindField(\"Shape\")\noutShapeField = outFTab.FindField(\"Shape\")\n'\n' Clone the fields in the inFTab for inclusion in the outFTab\n'\ninFieldList = inFTab.GetFields\noutFieldList = inFieldList.DeepClone \n\noutFieldList.Remove(0) ' omit the shape field... \noutFTab.AddFields( outFieldList )\n'============================================================================='\n'\n' If there are no selected features, convert all,\n' otherwise just convert the selected features.\n'\nif (inFTab.GetSelection.Count = 0) then\n theRecordsToConvert = inFTab\n numRecs = inFTab.GetNumRecords\nelse\n theRecordsToConvert = inFTab.GetSelection\n numRecs = theRecordsToConvert.Count\nend\n'============================================================================='\n'\n' Get a starting p oint.\n'\nx = Number.MakeRandom(0, 10000)*Dist/10000 ' Random start\nif (Dist > 0) then\n strX = \"?\"\n while (strX.IsNumber.Not)\n strX = MsgBox.Input(\"Starting point (a value between 0 and\" ++ Dist.AsString + \"):\", \n theTitle, x.AsString)\n if (strX = NIL) then return NIL end\n end\n x = strX.AsNumber\n if (x < 0) then x = Dist - ((-x) mod Dist) end\n x = x Mod Dist - Dist ' Back up before doing the first step\nend\n'=================================================================== =========='\n'\n' Perform the conversion.\n'\nav.ShowMsg(\"Converting\" ++ theTheme.GetName ++ \"...\")\nav.ShowStopButton\nav.SetStatus(0)\ni = 0\natBeginning = true ' A flag for the special case Dist == 0\n\nfor each rec in theRecordsToConvert\n inShape = inFtab.ReturnValue( inShapeField, rec ) ' A poly\n if (thePrj.IsNull.Not) then\n inShape = inShape.ReturnProjected(thePrj)\n end\n xLength = inShape.ReturnLength\n if (xLength = 0) then continue end\n \n i = i+100\n if (av.SetStatus(i/numRecs).Not) then\n MsgBox .Info(\"Conversion stopped. Only records already processed will be converted.\", theTitle)\n break\n end\n \n thePtId = 0\n if (Dist <= 0) then\n if (thePrj.IsNull.Not) then\n inShape = inShape.ReturnUnprojected(thePrj)\n end\n for each lstPts in inShape.AsList ' Process each part of the shape\n 'oldShape = lstPts.Get(lstPts.Count-1) ' 24-dec-99\n oldShape = NIL\n for each newShape in lstPts\n newRec = outFtab.AddRecord\n outFTab.SetValue( outShapeField, newRec, ne wShape )\n outFTab.SetValue( fldPtId, newRec, thePtId)\n thePtId = thePtId + 1\n '\n ' 24-dec-99: Compute the bearing.\n ' It will be in the interval ]-180, 180], with special values\n ' signaling no bearing (start point, error).\n '\n if (oldShape <> NIL) then\n if (thePrj.IsNull) then ' Use Euclidean geometry\n ptV = newShape - oldShape\n xDistance = ((ptV.GetX^2) + (ptV.GetY^2)).Sqrt\n if (ptV.GetX <> 0) then\n angBearing = (ptV.GetY/ptV.GetX).ATan.AsDegrees ' Between -90 and 90\n if (ptV.GetX < 0) then \n angBearing = -90 - angBearing ' In 0..-180\n else\n angBearing = 90 - angBearing ' In 0..180\n end\n else\n if (ptV.GetY >= 0) then\n angBearing = 0\n else\n angBearing = 180\n end\n end\n else ' There was a projection, so data are decimal degrees .\n theGeoCurve = GeoCurve.MakeFromTwoPoints( oldShape, newShape, 2, {thePrj, thePrj.GetSpheroid} )\n if (theGeoCurve.IsNull) then \n angBearing = 999.9999 ' Error!\n xDistance = 0.0\n else\n angBearing = theGeoCurve.ReturnAzimuth\n xDistance = theGeoCurve.ReturnRange ' Meters\n end\n end\n \n else ' No previous point is available.\n angBearing = -999.9999 ' Signals no bearing\n xDistance = 0.0\n end\n \n outFTab.SetValue( fldBearing, newRec, angBearing )\n outFTab.SetValue( fldDistance, newRec, xDistance )\n '\n ' Copy the rest of the attributes for this record.\n '\n fieldPtr = 0\n for each fOut in outFieldList\n fieldPtr = fieldPtr + 1\n fIn = inFieldList.Get( fieldPtr )\n outFTab.SetValue( fOut, newRec, inFTab.ReturnValue( fIn, rec ) )\n end\n \n oldShape = newShape\n end\n end\n \n else ' Laying off in positive Dist increments\n while (true)\n x = x + Dist\n if (x > xLength) then break end\n \n newShape = inShape.Along(100*x/xLength)\n if (thePrj.IsNull.Not) then\n newShape = newShape.ReturnUnprojected(thePrj)\n end\n newRec = outFtab.AddRecord\n outFTab.SetValue( outShapeField, newRec, newShape )\n outFTab.SetValue( fldPtId, newRec, thePtId)\n thePtId = thePtId + 1\n '\n ' Copy the rest of the attributes for this reco rd.\n '\n fieldPtr = 0\n for each fOut in outFieldList\n fieldPtr = fieldPtr + 1\n fIn = inFieldList.Get( fieldPtr )\n outFTab.SetValue( fOut, newRec, inFTab.ReturnValue( fIn, rec ) )\n end\n end ' processing the points for the current input shape\n \n x = x-(xLength + Dist) ' Back up one step to get ready for the next shape\n end ' if\n \nend ' processing input features\nav.SetStatus(100)\n\noutFtab.Flush\noutFTab.Refresh\n'============================================== ==============================='\n'\n' 8/16/96: Attempt to match field names.\n'\nlstFldOut = outFTab.GetFields\nlstFldIn = inFTab.GetFields\ni = lstFldIn.count\nwhile (i>0) \n i = i-1\n lstFldOut.Get(i).SetAlias(lstFldOut.Get(i).GetAlias)\nend\n'\ntheNewTheme = FTheme.Make( outFTab )\nreturn theNewTheme\n' End of script\n" ) (Script.14 Name: "View.PolyThemesToPoint.Update" SourceCode: "theView = av.GetActiveDoc\n\nisEnabled = false\ntheThemes = theView.GetActiveThemes\nif (theThemes <> NIL) then\n for each theTheme in theThemes\n if (theTheme.Is(FTheme)) then\n theFTab = theTheme.GetFTab\n theShapeName = theFTab.GetShapeClass.GetClassName\n if ((theShapeName = \"Polyline\") or (theShapeName = \"Polygon\")) then\n isEnabled = true\n break\n end\n end\n end\nend\nSELF.SetEnabled(isEnabled)" ) (Script.15 Name: "View.PolyThemesToPoint" SourceCode: "' Name: View.PolyThemesToPoint\n'\n' Headline: Convert poly{gon|line} themes into point themes\n'\n' Self: NIL\n'\n' Called by: --\n'\n' Returns: --\n'\n' Description: Converts each selected poly{gon|line} of the input themes into a \n' collection of points. New\n' themes are created to hold the output. All attributes of the \n' input themes are copied to the output themes.\n'\n' Topics: Themes; conversion\n'\n' Search Keys:\n'\n' Requires: The me.PolyToPointByInterval\n'\n' History: 8/3/99: Interval of 0 is used to convert to vertices.\n' 1/26/99: Reports the units in the theme name.\n' Works in projected units.\n' AV 3.0a, 11/20/97, by WAH\n'\n' Comments: Just a driver for Theme.PolyToPointByInterval. Install with a View GUI.\n'============================================================================='\ntheTitle = \"View.PolyThemesToPoint\"\ntheView = av.GetActiveDoc \n'============================== ==============================================='\n'\n' Ask for the interval to use.\n'\nstrUnits = Units.GetUnitString(theView.GetUnits).Trim ' The map units\nif (strUnits = \"\") then\n sU = \" \"\nelse\n sU = \" (\" + strUnits + \") \"\nend\nx = theView.GetDisplay.ReturnVisExtent.AsPolygon.ReturnLength/100\nstrX = MsgBox.Input( \"What interval\" + sU + \n \"do you want for laying out points (use 0 for vertices only)?\", theTitle, x.AsString)\nif ((strX = NIL) or (strX.IsNumber.Not) or (strX.AsNumber < 0)) then exit end\nx = str X.AsNumber\n'============================================================================='\n' \n' Create a list of active poly themes.\n' \ntheThemes = theView.GetActiveThemes\n\nthePolyThemes = {}\nfor each theTheme in theThemes\n if (theTheme.Is(FTheme)) then\n theFTab = theTheme.GetFTab\n theClassName = theFTab.GetShapeClass.GetClassName\n if (theClassName.Left(4) = \"Poly\") then\n thePolyThemes.Add(theTheme)\n end\n end\nend\n\nif (thePolyThemes.Count < 1) then\n MsgBox.Error(\"No poly themes in source view for converting\", theTitle)\n exit\nend\n'============================================================================='\n'\n' Ask for the destination view\n'\nviewList = {}\nfor each d in av.GetProject.GetDocs\n if (d.Is(View)) then\n viewList.Add( d )\n end\nend\n\nif (viewList.Count > 1) then\n vueDest = MsgBox.ListAsString( viewList, \"Select the destination view:\", theTitle )\nelse\n vueDest = viewList.Get(0)\nend\nif (vueDest = NIL) then exit end\n'=================================================== =========================='\n'\n' Do the work\n'\ntheArgs = {NIL, x, theView.GetProjection}\ni = thePolyThemes.Count\nneedsRefreshing = false\nwhile (i > 0) ' Process from bottom to top, so results are added to destination in the correct order\n i = i-1 \n theTheme = thePolyThemes.Get(i)\n theArgs.Set(0, theTheme)\n theNewTheme = av.run(\"Theme.PolyToPointByInterval\", theArgs)\n if (theNewTheme = NIL) then continue end\n '\n ' Make new theme attributes match the old ones.\n '\n if (x <= 0) then\n strQ = \"vertices \"\n else\n strQ = \"every\" ++ x.AsString ++ strUnits\n end\n theNewTheme.GetFTab.SetEditable(theTheme.GetFTab.IsEditable)\n theNewTheme.SetName(theTheme.GetName ++ \"(\" + strQ + \")\")\n theNewTheme.SetPassword(theTheme.GetPassword)\n theNewTheme.SetLocked(theTheme.IsLocked)\n theNewTheme.SetSuffixUsed(theTheme.IsSuffixUsed)\n theNewTheme.SetLegendVisible(theTheme.IsLegendVisible)\n theNewTheme.SetVisible(theTheme.IsVisible)\n if (theTheme.GetComments.Trim = \"\") then\n s = \"\"\n else\n s = theTheme.GetComm ents + NL\n end\n theNewTheme.SetComments(s + \"Converted from\" ++ theTheme.GetName ++ \n \"on\" ++ Date.Now.AsString ++ \"by\" ++ theTitle)\n theNewTheme.SetAOI(theTheme.ReturnAOI)\n theNewTheme.Invalidate(false)\n \n vueDest.AddTheme( theNewTheme )\n vueDest.GetWin.Invalidate\n vueDest.GetWin.Activate\n needsRefreshing = true\nend ' Processing active point themes\n\nif (needsRefreshing) then\n vueDest.GetWin.Close\n vueDest.GetWin.Open\nend\n' End of script \n" ) (Script.16 Name: "My Extension Install" SourceCode: "'DO NOT EDIT!!!\n\nif (av.getproject=nil) then return(nil) end\n\n\ntheDocs = SELF.get(0)\ntheControlList = SELF.get(1)\ntheMenuList = SELF.get(2)\ntheToolMenuList=SELF.Get(3)\ntheProject=Av.getproject\n\n\n'Add the Docs\n'\nfor each adoc in theDocs\n theProject.addDoc(adoc)\nend\n\n'Add the Controls\n'\nfor each totalControl in theControlList\n 'The Control list\n acontrol=totalControl.get(0)\n \n 'The physical control\n theControl = totalControl.get(1)\n \n 'The control Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n 'This finds the control set \n thecommand=\"av.getproject.findGUI(\"\"\"+aControl.get(0)+\"\"\").Get\"+acontrol.get(1)\n thescript1=Script.Make(thecommand)\n thecontrolset=thescript1.doit(\"\")\n \n 'Add the control to the control set\n theControlSet.Add(theControl,theCindex -1)\nend\n\n\n'Add the menus\nfor each totalcontrol in theMenuList\n \n 'The Control list\n acontrol=totalControl.get(0)\n mDoc=acontrol.get(0)\n mMenu=acontrol.get(1)\n mMenuItem=acontrol.get(2)\n\n 'The physical control\n theControl = totalControl.get(1)\n \n 'The control Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n theMbar=av.getproject.findGUI(mDoc).GetMenuBar\n themenu=theMbar.findbylabel(mMenu)\n if (themenu=NiL) then\n themenu=menu.make\n themenu.setlabel(mMenu)\n theMbar.add(themenu,999)\n end\n \n themenu.add(thecontrol, theCindex)\nend\n \n \n'Add the Tool Menus\n\nfor each totalControl in theToolMenuList\n 'The Control list\n acontrol=totalControl.get(0)\n \n 'The physical control\n theControl = totalControl.get(1)\n \n 'The c ontrol Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n 'This finds the control set \n thecommand=\"av.getproject.findGUI(\"\"\"+aControl.get(0)+\"\"\").Get\"+acontrol.get(1)\n thescript1=Script.Make(thecommand)\n thecontrolset=av.getproject.findGUI(aControl.get(0)).GetTool Bar\n \n 'Add the control to the control set\n theControlSet.Add(theControl,theCindex)\nend\n\n\nMsgBox.Info(\"Convert shapes to points by Quantitative Decisions.\" + NL +\n \"(c) 1996-2000. All rights reserved.\" + NL +\n \"Contact William Huber (610) 771-0606 for support.\", \"\")\n \nav.getproject.setmodified(true)\n\n\n'And the scripts add themselves\n" ) (Script.17 Name: "My Extension Uninstall" SourceCode: "'DO NOT EDIT!!!\n\n'The SELF is the Extension\n\ntheDocs = SELF.get(0)\ntheControlList = SELF.get(1)\ntheMenuList = SELF.get(2)\ntheToolMenuList=SELF.get(3)\ntheProject=Av.getproject\n\n\n'Add the Docs\n'\nfor each adoc in theDocs\n If (theProject.finddoc(adoc.getname)<>NIL) then \n theAnswer=msgbox.yesno(\"Remove the Document \"+adoc.getname+\"?\",\"Remove Document?\",TRUE)\n if (theAnswer=TRUE) then theProject.RemoveDoc(adoc) end\n end\nend\n\n'Removethe Controls\n'\nfor each totalControl in theControlList\n 'Get the control list from the Ext\n acontrol=totalControl.get(0)\n \n 'Get the physical Control\n theControl = totalControl.get(1)\n \n 'Get the Controls Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI for the Control\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n 'This sequence finds the appropiate control set\n thecommand= \"av.getproject.findGUI(\"\"\"+aControl.get(0)+\"\"\").Get\"+acontrol.get(1)\n thescript1=Script.Make(thecommand)\n thecontrolset=thescript1.doit(\"\")\n\n 'See if the control is in the set , if so remove it\n if (theControlSet.GetControls.find(theControl)<>NIL) then\n theControlSet.remove(theControl)\n if (thecontrol = \"ToolBar\") then\n theControlSet.selectdefault\n end\n end\nend\n\n\n'Remove the Menus\n'\nfor each totalcontrol in theMenuList\n \n 'The Control list\n acontrol=totalControl.get(0 )\n mDoc=acontrol.get(0)\n mMenu=acontrol.get(1)\n mMenuItem=acontrol.get(2)\n\n 'The physical control\n theControl = totalControl.get(1)\n \n 'The control Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n theMbar=av.getproject.findGUI(mDoc).GetMenuBar\n themenu=theMbar.findbylabel(mMenu)\n if (themenu=NiL) then\n MsgBox.Warning(\"The menu named \"+mMenu+\" is not here.\",\"Script Eror\")\n 'return(nil)\n else\n \n thething=themenu.getcontrols.find(thecontrol)\n if (thething<>NIL) then \n themenu.remove(thecontrol) \n end\n 'msgbox.info(themenu.GetControls.count.asstring,\"\")\n if (themenu.GetControls.count<1) then\n theMbar.remove(themenu)\n end\n end\nend\n \nfor each totalControl in theToolMenuList\n 'Get the control list from the Ext\n acontrol=totalControl.get(0)\n \n 'Get the physical Control\n theControl = totalControl.get(1)\n \n 'Get the Controls Index\n theCindex=totalControl.get(2)\n\n 'Find the DocGUI for the Control\n theControlDoc=av.getproject.findGUI(aControl.get(0))\n if (theControlDoc=NIL) then \n MsgBox.Warning(\"The GUI \"+aControl.get(0)+\" cannot be found in the current project.\",\"Script Eror\")\n return(nil)\n end\n \n 'This sequence finds the appropiate control set\n thecontrolset=av.getp roject.findGUI(aControl.get(0)).GetToolBar\n\n \n 'See if the control is in the set , if so remove it\n if (theControlSet.GetControls.find(theControl)<>NIL) then\n \n theControlSet.remove(theControl)\n theControlSet.selectdefault\n end\n\nend\n \n\n'And the scripts delete themselves\n\n\nav.getproject.setmodified(true)\n" )