/3.0 (Extension.1 Name: "Projector!" FirstRootClassName: "Butn" Roots: 2 Roots: 4 Version: 30 About: "Projector! extension allows conversion of data between map projections (v.3a)." InstallScript: 5 UninstallScript: 6 ExtVersion: 1 ) (Butn.2 Help: "Change projection//Changes projection of active themes (shift-Click for help)" Tag: "Projector!" Icon: 3 Click: "Projector!" ) (AVIcon.3 Name: "NorthArrow" Res: "Icons.NorthArrow" ) (Script.4 Name: "Projector!" SourceCode: "' Name: Projector!\n'\n' Headline: Allows user to project themes from one projection \n' to another, using any projections ArcView supports. User must \n' know the input and output projection and units. \n'\n' Self: \n'\n' Returns:\n'\n' Description: Projects active fthemes in current view to \n' new shape files in any projection that ArcView supports, \n' projecting into units of feet, meters or decimal degrees. \n' The user must know the units (and projection) of the input \n' theme(s), and will be asked for the outpu t units and projection.\n'\n' If neither input or output projection is geographic, \n' then the user must have 2x the amount of space of the original \n' shape file, as this script writes a temporary shapefile in geographic\n' coordinates, projects that to the output projection and \n' deletes the temporary files (much faster than stepping through records).\n'\n' Attach this as the click script to a control in a View GUI.\n'\n' Topics: Conversion, Themes\n'\n' Search Keys: Project, projections, theme, units, convert\n'\n ' Requires: Fthemes in a view with the map units set, and a \n' knowledge of the projection of the themes.\n'===========================================================\n\n'check for shift key, if shift key is down pop up instructions\n\n'explain script, pops up a message with\n'info about how to use\n\nif (System.IsShiftKeyDown) then\n message =\n \"To use the projection tool you must know the map units and projection\"++\n \"of the datasets being projected. You will be prompted for the output units and projectio n.\"+nl+nl+\n \"Brief Instructions:\"+nl+nl+\n \"1. Add some themes to the view.\"+nl+nl+\n \"2. Set the map units appropriately in the View Properties window.\"+nl+nl+\n \"3. Make the theme(s) you wish to project active.\"+nl+nl+\n \"4. Press this button. You will be prompted for certain information\"++\n \"which may include the input projection, the output units and the\"++\n \"output projection.\"+nl+nl+\n \"5. You will be asked if you want to recalculate area, perimeter and length fields.\"+nl+nl +\n \"WARNING - If the field to be recalculated is not large enough to hold the new \"+\n \"(calculated) number, the value put in that field will be incorrect.\"+nl+nl+\n \n \"6. You will be asked if you want to add the projected theme(s) to a view.\"+nl+nl+\n \"7. You will be asked for output shapefile names for each theme to be projected.\"+nl\n \n msgbox.report(message,\"Projector! Instructions\")\n return nil\nend\n\n\n\n'get the active document, which should be a view\n\ntheView=av.GetActiveDoc\n\nif (th eView.Is(View).Not) then\n MsgBox.Error(\"This script must be run from a view. Exiting\",\"Error\")\n return nil\nend\n\n'Get the current source units and make sure they are not unknown\n\nsourceunits = av.getactivedoc.getdisplay.getunits\n\nif (sourceunits = #UNITS_LINEAR_UNKNOWN) then\n MsgBox.Error(\"View units must be set before projecting. Stopping.\",\n \"Error!\")\n return nil\nend\n\n\n'build a list of fthemes from the active theme list, we will project these\nthms=List.Make\nfor each t in theView.GetActive Themes\n if (t.Is(Ftheme)) then\n thms.Add(t)\n end\nend\n\n'if no themes active let the user know and quit\n\nif (thms.Count = 0) then\n System.Beep\n MsgBox.Error(\"Please make at least one feature theme active!\",\"Error\")\n return nil\nend\n\n \n'Get the projection of the view\n\nmyprj=av.getactivedoc.getprojection\n\n'Try to figure out if the source data is geographic \n' If our Prj.AsString <> \"\" then we have a projection and we are\n' geographic, or if our sourceunits are set to decimal degrees withou t\n' a projection we are too\n\ninputgeographic =((myprj.AsString <> \"\") or\n ((sourceunits = #UNITS_LINEAR_DEGREES) and (myprj.AsString = \"\")))\n\n'If not, then let user pick input and output\n\nif (inputgeographic.Not) then\n\n Msgbox.Info(\"Please select the input projection\"++\n \"in the next dialog box\",\"Projector!\")\n \n 'Pop up dialog box, to get input projection\n 'and check for cancel button (nil)\n \n inputPrj = ProjectionDialog.Show(theView,sourceunits)\n if (inputPrj.IsNull) then\n retur n nil\n end\n \n 'Pop up dialog box, to get output projection\n 'and check for cancel button (nil)\n \nelse 'your input projection is geographic\n sourceunits = #UNITS_LINEAR_DEGREES\nend\n\nunitslist1 = {\"meters\",\"feet\",\"decimal degrees\",\"miles\",\"kilometers\",\"yards\",\n \"centimeters\",\"inches\",\"millimeters\"}\n\nunitslist2 = {#UNITS_LINEAR_METERS, #UNITS_LINEAR_FEET,\n #UNITS_LINEAR_DEGREES, #UNITS_LINEAR_MILES,\n #UNITS_LINEAR_KILOMETERS, #UNITS_LINEAR_YARDS,\n #UNIT S_LINEAR_CENTIMETERS, #UNITS_LINEAR_INCHES,\n #UNITS_LINEAR_MILLIMETERS}\n \noutputunits = MsgBox.ChoiceAsString(unitslist1,\n \"Please pick output units\",\"Projector!\")\n\n\nif (outputunits = nil) then\n return nil\nelse \n outunits = unitslist2.Get(unitslist1.FindByValue(outputunits))\nend\n\n'get the output projection, using the dialog box and check for cancel (nil)\nif (outputunits = \"decimal degrees\") then\n outputPrj = prj.MakeNull\n outputPrj.SetDescription(\"Geo graphic\")\n outputgeographic = true\nelse\n outputPrj = ProjectionDialog.Show(theView,outunits)\nend\n\nif (outputPrj = nil) then\n return nil\nend\n\n'check to see if they are the same. If so, exit\n \nif ((inputgeographic.Not) and ((outputPrj = inputPrj) and (sourceunits = outunits))) then\n MsgBox.Error(\"Input projection same as output projection.\",\"Error\")\n return nil\nend\n\n\n'check to see if output projection is geographic. If it is, we won't need\n'to do as much work below\n\noutputgeographic = outputPrj.ReturnD escription.Contains(\"Geographic\")\n\n'if both input and output are geographic, quit here\n\nif (inputgeographic and outputgeographic) then\n MsgBox.Error(\"Both input and output are geographic. Stopping.\",\"Error\")\n return nil\nend\n\n'check to see if we want to recalculate area, perimeter, length fields\n\nrecalc = Msgbox.YesNo(\"Recalculate area, perimeter and length fields\"++\n \"(if present) using\"++outputunits+\"?\",\"Projector!\",true)\n \n'check to see if we want to put results into a view\n \nif (MsgB ox.YesNo(\"Add projected shapefile(s) as theme(s) to a view?\",\n \"Projector!\",true)) then\n 'make a list of views\n viewlist = List.Make\n for each d in av.GetProject.GetDocs\n if (d.Is(View)) then\n viewlist.Add(d)\n end\n end 'for each d\n \n 'provide a choice for a new view\n viewlist.Add(\"\")\n \n AddToView = MsgBox.ListAsString(viewlist,\"Add Theme to:\", \n \"Projector!\")\n \n if (AddToView <> nil) then\n if (AddToView = \"\") then\n AddToView = View.Make\n AddToView.GetWin.Open\n end\n end\nelse 'don't add to view\n AddtoView = nil\nend\n\n\n\n'step through each active theme\n\nFor each thm in thms\n \n 'get a filename for the new shapefile\n \n defname = Filename.GetCWD.MakeTmp(\"theme\",\"shp\")\n outputfile = FileDialog.Put(defname,\"*.shp\",\"Project \"+thm.GetName)\n \n 'if Canceled, then skip this theme\n \n if (outputfile = nil) then\n continue\n end\n \n 'now export the ftab (selected records only), \n \n thmftab = thm.GetFtab\n sha petype = thmftab.FindField(\"Shape\").GetType\n \n if (outputgeographic) then\n newFtab = thmFtab.ExportUnprojected(outputfile,inputPrj,\n thmFtab.GetSelection.Count >0)\n elseif (inputgeographic) then\n newFtab = thmFtab.ExportProjected(outputfile,outputPrj,\n thmFtab.GetSelection.Count > 0)\n else 'need to go to geographic, then to something else\n 'make a temporary shape file\n tempshape = Filename.GetCWD.MakeTmp(\"xxprj\",\"shp\")\n tempftab = thmFtab.ExportUnpr ojected(tempshape,\n inputPrj,thmFtab.GetSelection.Count >0)\n newFtab = tempFtab.ExportProjected(outputfile,outputPrj,false)\n \n 'now clean up\n tempftab.DeActivate\n tempftab = nil\n av.PurgeObjects\n tempshpname = tempshape.GetBaseName.AsTokens(\".\").Get(0)\n tempshpdir = tempshape.GetFullName.Clone.AsFilename\n tempshpdir.Stripfile\n filesToDelete = tempshpdir.Readfiles(tempshpname+\".*\")\n \n for each f in filesToDelete\n File.Delete(f)\n end\n end\n \n 'r ecalculate area, perim, length fields if asked to\n \n if (recalc) then\n \n 'find the fields we need to recalculate\n newareafield = newftab.Findfield(\"Area\")\n newperimfield = newftab.Findfield(\"Perimeter\")\n newlengthfield = newftab.Findfield(\"Length\")\n \n newftab.SetEditable(True)\n if (shapetype = #FIELD_SHAPEPOLY) then\n if (newareafield <> nil) then\n newftab.Calculate(\"[Shape].ReturnArea\",newareafield)\n end\n if (newperimfield <> nil) then\n newftab.Calculat e(\"[Shape].ReturnLength\",newperimfield)\n end\n elseif (shapetype = #FIELD_SHAPELINE) then\n if (newlengthfield <> nil) then\n newftab.Calculate(\"[Shape].ReturnLength\",newlengthfield)\n end\n end\n newftab.SetEditable(false)\n end 'if recalc\n \n if (addtoView <> nil) then\n 'create a theme and add it to the specifiedView\n fthm = FTheme.Make(newFTab)\n AddToView.AddTheme(fthm)\n 'put this theme in the same order as it was in the original view\n newplace = AddtoView. GetThemes.Count\n AddToView.GetThemes.Shuffle(fthm,newplace)\n end\n \nend 'for each thm\n\nif (addtoView <> nil) then\n\n 'if view units aren't set, then set them\n if (AddtoView.GetDisplay.GetUnits = #UNITS_LINEAR_UNKNOWN) then\n AddtoView.GetDisplay.SetUnits(outunits)\n end\n \n 'bring the View to the front\n\n AddToView.InvalidateTOC(nil)\n AddToView.GetWin.Activate\nend" ) (Script.5 Name: "Projector!.Install" SourceCode: "' Make sure there is a project\nif (av.GetProject = nil) then\n return nil\nend\n\n' Add button to View GUI\nviewgui = av.getproject.findgui(\"View\")\n\nif (viewgui = nil) then\n MsgBox.Error(\"Cannot find View GUI. Stopping.\",\"Error\")\n return nil\nend\n\nbuttons = viewgui.getbuttonbar\nprjbutton = self.Get(0)\nbuttons.add(prjbutton,999)\n\n\n" ) (Script.6 Name: "Projector!.Uninstall" SourceCode: "' Make sure there is a project\nif (av.GetProject = nil) then\n return nil\nend\n\n' don't bother uninstalling on close\nif (av.GetProject.IsClosing) then\n return nil\nend\n\n' Remove button from View GUI\nviewgui = av.getproject.findgui(\"View\")\nif (viewgui = nil) then\n return nil\nend\nviewgui.getbuttonbar.Remove(self.Get(0))\n\n\n\n\n" )