Copyright: Copyright (c) 1990-1998 ESRI, Inc.


Error message displayed when a topic is not found
Topic not available

Sorry, the topic you chose to display is not available in ArcView's help system.

To see ArcView's Help Contents, Index, and Find tabs, please click the Help Topics button.


ArcView Connect for R/3 Sample Extension
ArcView Connect for R/3

Description: This extension connects to SAP R/3 so you can  download information into text files. You can then bring the text files into ArcView GIS. It uses the RFC technology provided by SAP to connect to R/3 systems and makes calls to remote-enabled function modules. The extension comes with one standard function, "RFC_CUSTOMER_GET", which downloads customer information, including customer number, customer name, and customer address. The Visual Basic source code is provided under the $AVHOME\samples\ext\esrir3 directory so that you can integrate any other remote-enabled function module present in your R/3 system (including custom developed function modules). This extension is supported on Windows only.

Requires: an R/3 user account with the proper authorizations, an R/3 client, and R/3 application server information. Your Basis/System administrator for the R/3 system will be able to provide information regarding the requirements and available function modules for the R/3 system.

FileName: esrir3.avx

For more information, see Using the ArcView Connect for R/3 sample extension.


Using the ArcView Connect for R/3 sample extension

The ArcView Connect for R/3 sample extension allows you to initiate SAP R/3 function modules, download R/3 data into ArcView GIS for visualization and spatial analysis, and interact with SAP R/3 on a transactional basis. The extension allows for immediate use of R/3 standard functions, and provides a flexible tool for building custom applications that require ArcView GIS and SAP R/3 connectivity. Instructions for using the extension are presented below.

Before you can load the extension, you must first copy the esrir3.avx file from the $AVHOME\samples\ext\esrir3 directory to your $AVHOME\ext32 directory, or your temp directory.

To load the ArcView Connect for R/3 extension

1   Start ArcView GIS.

2   Make the project window active.

3   From the File menu, choose Extensions.

4   In the Extensions dialog, click the checkbox next to ArcView Connect for R/3.

5   Press OK.

To connect to R/3 and download data

1   From the Project dropdown menu, select the newly added menu option, SAP R/3 utility. This step will initialize the Visual Basic application.

2   The application has a single menu item, Configure. Fill in your R/3 client, user name, password, language preference, host name and system number. Press OK to save this information and dismiss the login information dialog box.

3   To login into R/3, your login information must be valid and completed. Press the Login button to initiate the connection to the R/3 database. After a connection is established, the application will have the "CUSTOMER ADDRESS" as the default R/3 information to download. You will also have the option of changing the name and location of the downloaded table. By default, your information will be saved in "c:\temp\esrir3setup.txt".

4   To download the information, press Retrieve. A message box will appear and the user can either continue or cancel the download. After a download is done, a window will appear to confirm it. (The downloaded data can then be used by any application that can take a tab-delimited text file.)

5   In ArcView, activate the project window and select the Table icon. Choose the Add button from the Project window and navigate to the location you specified in Step 3 to add the downloaded text table.

Notes

 ArcView can load the customer information as a table and the information can then be geocoded and displayed. See the ArcView GIS online help for further details.

 The R3Connect executable (esrir3.exe) uses the esrir3.dll for making connections to R/3. The same DLL can be used by other applications for direct connections to R/3 (e.g., direct connection from ArcView GIS via Avenue script).


esrir3.dll

/***********************************************************

* 	Exported Function Declarations

***********************************************************/

int Logon(char* Client, char* User, char* Password, char* Language, char* Destination,

char* HostName, char* Gateway, char* Service, int SystemNo)

int Logoff()

int InitializeFunction(char* FunctionName)

Int DestroyFunction()

Int SetImport(char* Parameter, char* Value)

int SetImportField(char* StructureName, char* Field, char* Value)

int AddTableRow(char* TableName)

int SetTableField(char* TableName, int RowNumber, char* ColumnName, char* Value)

int CallFunction()

const char* GetExport(char* Parameter)

const char* GetExportField(char* StructureName, char* Field)

const char* GetTableField(char* TableName, int RowNumber, char* ColumnName)

int DumpTableToText(char* TableName, char* FileName, int MaxFieldLength)

int EmptyTable(char* TableName)

/***********************************************************

*	Explanation of input parameters and return values

***********************************************************/

Logon

Input parameters:

Client:  	R/3 Client (ex. “001”)

User: 	R/3 user account

Password:	R/3 password for user account

Language:	R/3 available language (ex. “E”)

Destination:	Put a three-character identifier (ex. “DLL”)

HostName:	R/3 server name or IP address

Gateway:	R/3 gateway server if any.  If there is none, use the R/3 server name.

Service:	The name of the network service to use (ex. sapgw03).

SystemNo:	The R/3 system number.  Typically the digits associated with the network service (ex. 03).

Return value:

Success

1	Logon failed

Logoff

Input pramaters:

None

Retrun value:

0	Success

InitializeFunction

Input parameter:

FunctionName:	The name of the R/3 function module you want to execute remotely.

Note: This function module must be setup for remote calls.

Return value:

0	Success

2	R/3  not connected (use Logon to connect)

5	Function name not found

DestroyFunction

Input parameters:

None

Return value:

Success

SetImport

Input parameters:

Parameter: 	An import parameter name defined in the R/3 function module.

Value:	The value being set for the parameter.

Return value:

Success

Function is not initialized

Parameter not found

8	Parameter is a structure (Use SetImportField)

SetImportField

Input parameters:

StructureName:	An import paramater name defined as a structure within the R/3 function module.

Field:	A field name within the structure.

Value:	The value being set for the field of the structure.

Return value:

Success

3	Function is not initialized

6	Parameter not found

Parameter is a NOT structure (Use SetImport)

16 	field not found

AddTableRow

Input parameters:

TableName:	A table name defined in the R/3 function module.

Return value:

Success

3	Function is not initialized

7	Table not found

SetTableField

Input parameters:

TableName:	A table name defined in the R/3 function module.

RowNumber:	A row number within the table.

ColumnName:	A column name within the table.

Value:	The value being set for the cell in the table defined by RowNumber and ColumnName.

Return value:

Success

3	Function is not initialized

7	Table not found

14	Row out of bounds

Column is not defined

CallFunction

Input parameters:

None

Return Value:

0	Success

3	Function is not initialized

12	Execution failed

RFC exception

GetExport

Input parameters:

Parameter: 	An export parameter name defined in the R/3 function module.

Return value:

If successful, then the return value is the value of the parameter as a string.

"error: Function not initialized"

"error: Parameter not found"

"error: Parameter is not a structure"	(Use GetExportField)

GetExportField

Input parameters:

StructureName:	An export paramater name defined in the R/3 function module defined as a structure.

Field:	The field name within the structure.

Return value:

If successful, then the return value is the value of the field in the structure as a string.

"error: Function not initialized"

"error: Parameter not found"

"error: Parameter is a structure”	Use GetExport / _VBGetExport@4

“error: Field name is not defined”

GetTableField

Input parameters:

TableName:	A table name defined in the R/3 function module.

RowNumber:	A row number within the table.

ColumnName:	A column name with the table.

Return value:

If successful, the return value is the value of the cell (as a string) in the table defined by RowNumber and ColumnName.

"error: Function not initialized"

"error: Table not found"

"error: Table is empty"

"error: Row is out of bounds"

“error: Column name is not defined”

DumpTableToText

Input parameters:

TableName:	A table name defined in the R/3 function module.

FileName:	The filename and path to where the data is saved (ex. C:\temp\a.txt).

MaxFieldLength:	Maximum number of characters for a field or a cell.  Specify “0” for no limit, ex. textfile data matches R/3 data.

Return value:

0	Success

3	Function is not initialized

7	Table not found

10	File create failed

EmptyTable

Input parameters:

TableName:	A table name defined in the R/3 function module.

Return value:

0	Success

3	Function is not initialized

7	Table not found

How to use the functions together

1   Logon to R/3 using Logon.

2   Initialize the R/3 function module using InitializeFunction.

3   Set all required import parameters using SetImport and SetImportField.

4   Set all required tables. First append a row to the table using AddTableRow. Then, set the required fields of that row using SetTableField.

5   Call the function using CallFunction.

6   If the call is successful, access results through export parameters using GetExport or GetExportField, and/or through tables using GetTableField or DumpTableToText. The way results are sent back depend on how the function module is set up in R/3.

7   After using a function module, do some clean up. First empty the tables (if applicable) using EmptyTable, then free the memory structures the function uses using DestroyFunction. The latter frees the memory structures used by the remote call and does not destroy the function module in R/3. In addition, these are required clean up procedures before executing other function modules.


Datum Converter Sample Extension
Datum Converter

Description:  This extension contains two buttons on the view docGUI. One allows you to enter a point and then based on a from and to datum, it returns the transformed coordinates. The other button transforms the shapes of all active themes from one datum to another. See the description portion of each script to familiarize yourself with how each script works before running any of them. Cannot be used to convert between NAD27 and NAD83.

Requires:  The file datum.par, which exists in the $AVHOME/samples/ext folder.

FileName:  datum.avx


Extension Builder Sample Extension
Extension Builder

Description:   This is a very helpful extension that HELPS you to create your own extensions.  Before loading the extension builder construct a project that contains the scripts, documents, and GUI elements that you want your extension to contain.  The extension builder installs into your project three (3) scripts and then the extension automatically unloads itself.

To create your extension, you only need to edit the script called My Extension Make where you will specify your extension name, the file, the version and the objects to include in it.  At this point save your project, then you run this script to create your own extension!

Be sure to test your extension thoroughly by making a new project and then loading your extension and unloading your extension.

Requires:  A project that contains the scripts, controls, documents and other objects that you want to share through an extension.

FileName:  extbuild.avx


Named Extents Sample Extension
Named Extents

Description:   The Named Extents extension adds a new menu to specified DocGUIs that support Views. The new menu contains two choices:  Add Named Extent and Delete Named Extent.  You use these choices to make or remove extents you wish to keep.  When you arrive at an extent that you may wish to revisit, use the Add Named Extent choice to save  the extent with the name you specify. The new extent name appears in  the Named Extent menu.  To go to that extent, simply click on the choice labeled with the name. The named extents are saved with each individual  view. If you open a new view, there will be no named extents associated with it.

When you first install this extension in a project file, you will be prompted to select the View DocGUIs to install the extension in.

Requires:  This requires a View document.

FileName:  namedext.avx


Projector Sample Extension
Projector

Description:   Projector! adds a new button to your view DocGUI that allows you to create projected data sets from selected themes.

Requires:  You must have a DocGUI named View.

FileName:  prjctr.avx


Samples Browser Sample Extension
Samples Browser

Description:   This extension allows you to peruse, load and unload extensions in the Samples directory.  It installs a choice in the Project's File menu that sets the environment variable $USEREXT to $AVHOME/samples/ext, brings up the Extension dialog and then restores $USEREXT.  Use this choice to check out sample extensions and load/unload them to your system.

The extension also adds a choice to the Script menu in the Script DocGUI that allows you to load sample scripts to script editors. The saved names are  restored.

Copy this extension from the samples directory to your default $USEREXT directory to simplify access to other sample extensions

Requires:  Standard ArcView install so that the sample extensions are in the directory $AVHOME/samples/ext.

FileName:  seesmple.avx


Save field aliases with Table Sample Extension
Save field aliases with Table

Description:   This extension allows you to save the field alias information for your table document.   This information is saved in an ODB file.  Then when this extension is loaded,  you can add that dBASE file as a table or theme and the aliases will automatically be restored.

Requires:  No requirements. Extension replaces the system scripts Table.Properties, View.Add, Project.AddTable.

FileName:  tabelx.avx


Virtual Document Utilities Sample Extension
Virtual Document Utilities

Description:  The Virtual Document Utilities extension adds a menu to the Project user interface.  This menu contains tools that facilitate making associations between documents and DocGUIs. There are three kinds of tools: tools for accessing and modifying document/DocGUI relationships, tools for modifying how the documents are grouped in the project window, and tools to validate the associations between documents and DocGUIs.

Requires:  This extension requires the Project's DocGUI be named "Project".

FileName:  vdocutil.avx


Class Browser Sample Extension
Class Browser

Description:  This extension provides some tools for working with the list of requests in ArcView 3.0, the list of requests in ArcView 3.1, the list of changed requests in ArcView 3.0, and the list of changed requests in ArcView 3.1. This extension adds four table documents and a customized Table DocGUI for these table documents. The DocGUI includes a tool that brings up help for the selected line.

There is a known problem with the help tool. When you select a request with a non-alphabetic name (such as +, -, *), sometimes you will get the error "TOPIC NOT FOUND".

Requires:  Requires a standard installation of the samples. This extension expects the files avreq30.txt, chngreqs.txt, avreq31.txt, and chngreq31.txt to be in $AVHOME/samples/other.

FileName:  clsbrwsr.avx


Remember Saved Projects Sample Extension
Remember Saved Projects

Description:  This extension provides the "last saved" functionality common on windows applications. It maintains a list of the last four projects saved and allows you to go back to them simply by clicking on the appropriate choice in the Project's File menu.

This extension modifies the system scripts Project.Save, Project.SaveAs, Project.Open and Project.NewPart2. If your project or user default project also modifies any of these scripts, the extension will NOT work properly. The extension saves the last projects to an ODB file in your $HOME directory called default.l4.

You might want to make this extension part of your default environment. When you load this extension, hit the Make Default button in the extension dialog.

Requires:  A project DocGUI named "Project".

FileName:  last4.avx


Overview Sample Extension
Overview

Description:  The Overview extension adds two new choices to the View menu of selected View DocGUIs.  These choices allow you to create and control overview views.  The Overview view is a small view that displays the full extent of the current view and a rectangle outlining its current extent.  When you change the display extent of the current view, the graphic on the overview view changes with it. If you select the overview view, you can modify the rectangle to change the display extent of the current view.

Whenever you close a view with an associated overview, the overview closes.  When you open a view with an associated overview, the overview opens.  If your overview gets closed or lost among many other documents, you can restore it to the top by using the Display Overview choice in the View DocGUI's View menu.

The overview view has a much simplified user interface. It provides controls to change the extent rectangle and also to delete unwanted themes from the view.

Requires:  This requires at least one View DocGUI with a menu named View.

FileName:  overview.avx


Script Editor Utilities Sample Extension
Script Editor Utilities

Description:  This extension provides a number of utility functions for creating scripts. The extension adds a new menu to the Script DocGUI called Utilities.  It also includes a new button on the Script Editor's button bar and a popup menu.

Script Editor utilities provides the following functions:

•	An Avenue "command line" interface.

•	Numbering and unnumbering lines of code.

•	Moving a script to/from another editor.

•	Writing scripts to file and then restoring.

•	Validating that scripts are compiled and scripts on control events exist.

•	Inserting debug statements.

•	Changing the selected text.

•	Utility for clearing up the Script Editor window when it gets "garbled". Use F2 for a shortcut - its easier than resizing the document window! This utility was offered by Nis Schmidt through ESRI's WWW page.

Requires:  A script editor DocGUI named "Script" (the default).  The extension assumes that there are no other popup menus on the DocGUI.

FileName:  sedtools.avx


Port Project Utility Sample Extension
Port Project Utility

Description: This extension provides utilities that make it easier to move projects from machine to machine. It installs a menu called Port to the project's DocGUI. This menu has two choices: "Replace paths" and "Open projects". Replace paths substitutes environment variables for paths names. First, select a project file. The utility finds all the paths referenced in that project file and their subpaths. Select the file names to substitute with environment variables. The utility creates a new version of the project with the revised pathnames and an ODB file with the paths and associated environment variables. The ODB file is named like the new project file with a .env extension.

When you open a project with the Project Open option, if that project was created by the Replace paths option described above, you are given an opportunity to review and revise the required environment variables. If any environment variables reference non-existent directories, you will be prompted to correct the value. The utility then saves any revisions to the .env file for the next time.

If you open a project that has not been created by the Replace paths option, then the extension asks you to identify any associated environment variables and their paths. Hit cancel when you have specified all environment variables. It establishes the environment variables and creates an associated .env file.

Requires: Requires a project DocGUI named Project.

FileName: portproj.avx


Save and Load Graphic Labels Sample Extension
Save and Load Graphic Labels

Description: This extension adds two menu items to the Graphics menu in View GUIs. These tools allow graphic text labels to be saved to a file and then reloaded from a file. This will allow users to save graphic text labels out and share them with other users. There can be some shift in the label position where converting to and from a projected view.

Requires: A View DocGUI that contains a graphics menu.

FileName: gtext.avx


MGE Viewer Sample Extension
MGE Viewer

Description: This extension allows you to integrate data created in Intergraph's MGE software or Bentley's MicroStation GeoGraphics software. You can also use data in MicroStation design files linked directly to external tables; ArcView will manage the linkages for you. ArcView presents this data in a manner familiar to ArcView users while maintaining many tools and features of the native software. You can symbolize, query, and analyze the data just like you can any other spatial data, without first converting the data in shapefile format. This allows you to view the most up-to-date data within ArcView while the underlying data is constantly being updated in the native software. This extension is supported on Windows only.

Requires: a standard installation of the samples and is dependent on the CAD Reader extension.

FileName: MGEView.avx

For more information, see Using the MGE Viewer sample extension.


Using the MGE Viewer extension
Using the MGE Viewer sample extension

ArcView supports projects created in MGE, MicroStation GeoGraphics (MSG), and design files with associated database linkages. This extension allows you to view the most up-to-date data within ArcView, while the underlying data is constantly being updated in the native software.

Loading the MGE Viewer Extension

The MGE/MSG/MS support in ArcView is implemented as an extension. You must load the extension before you can add a project to your ArcView session.

To load the MGE Viewer extension

1   Make the project window active.

2   From the File menu, choose Extensions.

3   In the Extensions dialog, click the checkbox next to the MGE Viewer extension.

4   Press OK.

The MGE Viewer will automatically load the CAD Reader extension, which it requires. If you are not familiar with this extension, see the chapter called 'Working with CAD Drawings' in the Using ArcView GIS book.

How MGE data is organized

An MGE project, MicroStation Geographics project or set of design files linked to databases are made up of several parts. Each has a minimum of:

 A set of design files
 A set of tables (including one called MSCATALOG) in an external database (Oracle, Access, etc.)

It may also contain:

 A project file (typically with an MGE or PRJ extension)
 An index design file
 Other information used by the MicroStation based software that ArcView does not require

MGE and MicroStation GeoGraphics store project data in a directory tree and ArcView assumes that you have followed that organization. If you have not, you may wish to move files to their suggested location. If you do not, ArcView may not find everything it needs.

You will need to set an alias to point to your external database. This is the same process you would use to set up ArcView to look at any ODBC data. For example, if you were using an Oracle server you would need to set up a database alias.

Then you would need to define an ODBC connection.

See your database software manual or system administrator for help with this setup, if necessary.

Adding an MGE project to an ArcView project

The extension adds a new document type, an MGE view to your ArcView project.

To create an MGE view

1   Make the Project window active.

2   Scroll down below the Scripts icon until you see the MGE View icon.

3   Double click the icon, or highlight it and click the New button.

4   In the dialog that appears, choose either MGE Project File (if you have an MGE Project File in your MGE workspace) or MGE Workspace (if you don’t have an MGE project file in you workspace), and click OK.

5   If you chose the MGE Project File option in the previous step, use the dialog (that appears) to navigate to the directory that contains the project you wish to open, and click OK.

On the other hand, if you chose the MGE Workspace option in the previous step, you’ll be prompted to enter a full pathname to your MGE workspace (example: c: \projects\petro). Click OK.

6   The pull-down list in the next dialog presents all the database tables ArcView recognizes. Select the one to use for the project you are opening, and click OK. (It may or may not have the same name as the project.)

7   Log on to your database by keying in the correct user name and password.

8   An index map of the area in your project is presented.

By clicking a location, the polygons within that area will be highlighted and the corresponding DGN file names posted on the index map. If this is not the area of interest, click a new point and other files will be activated. This functionality parallels the Map Manager tools in other products.

In the Map Manager dialog, select the maps of interest (one or more) and press Apply. The requested information is added to a new view. If an index.dgn doesn’t exist in the \IDX directory under the MGE project, all the available design files are shown in the dialog box. Choose the desired files and press Apply.

9   Click Yes to convert to a shapefile or No to add them as CAD themes.

If you are converting to a shapefile, note the following: 1) it often takes awhile to merge all the themes into one shapefile, and 2) ArcView won't preserve CAD annotation.

Working with Categories and Features

ArcView organizes the categories it finds in the selected maps. Each category may be the source for up to four themes: one each for point, line, polygon and annotation features. Some maps will have all four themes, others will only have one. Each one is named with the name of the category and the feature type it presents. Thus, the webb5.lse design file, results in only two themes from the "wells" category: wells annotation and wells line. Each category may contain many features.

To see the features available for a category

1   Make a theme active.

2   Choose Split into Features from the MGE menu.

3   Select the features of interest from the dialog listbox.

4   Those features are split out and added as themes to the top of the view. Now each feature can be manipulated, symbolized and queried individually.

Working with MGE Tools

ArcView provides a set of special tools to work with your MicroStation based data.

Identify: The MGE Identify tool shows all feature types and external tables associated with that element.

The element of interest "flashes", then a detailed identify box is displayed. The element’s MicroStation properties are presented on the left: level, color, attribute linkages and related external table information is presented on the right: feature type, descriptive information.

MGE Table: The Open table command in the MGE menu presents the element’s CAD attribute table and associated tables external tables. Note that each element may have several feature tables linked to it. Use the table properties to turn off items in the table that you do not need.

MGE Feature Query: The MGE Feature Query command in the MGE menu provides an SQL query on features in the active theme. Clicking on one of the found records will cause the view to zoom in on and flash that element. (This is comparable to a "geo-locate" in some MicroStation based products.)


Multi-Theme Auto-Labeler Sample Extension
Multi-Theme Auto-Labeler

Description: This extension adds the "Multi-Theme Auto-Labeler" choice to your Theme menu. The extension gives you an interface for labeling more than one theme so that placement conflicts between labels will be resolved for all labels, regardless of what theme the label belongs to.

Requires: A View DocGUI that contains a Theme menu.

FileName: multmlab.avx

For instructions on how to use the tool, see Using the Multi-Theme Auto-Labeler sample extension.


Using the Multi-Theme Auto-labeler sample extension

To use the Multi-Theme Auto-Labeler tool, make the themes you want to label active, then choose Multi-Theme Auto-Labeler from the Theme menu. This will open the Multi-Theme Auto-Labeler dialog. Follow these steps to use the Multi-Theme Auto-Labeler dialog:

1	You will see your Active themes listed in the box on the upper left. You need to move these themes one at a time to the box on the right. To do this, select a theme on the left and click the Add to Job button. The goal of this step is to specify the priority for each theme in the labeling process. The labels for the first theme you add will be placed first, and thus, will have the highest likelihood of being well placed. Often, some of the features in the last themes you add will not get labeled (there will be additional discussion about overcoming this later).

2	Once you have prioritized your active themes by moving them to the Themes to be labeled box, you need to set their properties. Select a theme in the Themes to be labeled list and you will see the relevant properties become active in the lower two thirds of the Multi-Theme Auto-Labeler dialog.

3	Choose a label field for the selected theme. The default choice is the theme's current label field.

4	Choose whether the duplicate labels for this theme will be removed. With this option selected, ArcView will place only unique label strings. Thus, if your data contains features that have the same label, i.e., you have 40 lines that have the label 'Main St', only one line will receive a label.

5	Choose whether the labels will be scaled. When this is checked, your labels will maintain the same geographic extent when you change scales, otherwise, the label will retain the same text symbol size.

6	Choose the Font, Size, Style, and Color for the text symbol that will be used for the selected theme. If you choose a size of 0, then the features for this theme will be considered as obstacles for other themes during the labeling process, but will not be labeled themselves.

7	Choose whether to label just the features in the view. This option affects all themes, so you only need to set it once.

8	Choose whether to also place any overlapping labels. This option also affects all the themes in the view, so you only need to set it once.

9	If the selected theme is a line theme, then you can choose whether the labels will be placed on top, on, or below the line features.

10	Choose the importance of features. The Multi-Theme Auto-Labeler loads all the features into the labeling process before any labels are placed. This means that you can specify that some or all features should not be overwritten with labels. Your choices are: "Very High" which means that no labels will be placed on features of this theme; "High" which means that the labeling process will carefully search the area immediately around the feature that is to be labeled in order to find a location for a label that does not overlap a feature in this theme, but if no suitable location is found the label will be placed anyway; "Moderate" which means that a quick search will be done during the labeling process to locate an acceptable location for a label so that it does not overlap this feature, but if no suitable location is found the label will be placed anyway; and "Low" which means that these features will not be considered when placing labels.

11	Choose the importance of labels. While ArcView is labeling features, each new label becomes an obstacle that may prevent next or subsequent labels from being placed. You can assign the level of importance to labels such as described above for features.

12	Repeat steps 3-11 for each theme that is to be labeled. Then click OK. Until you have used this tool a few times, it is unlikely you will get the settings for your labeling job right the first time. The Multi-Theme Auto-Labeler tool remembers the settings you make for each theme, so you can remove less than optimal labels, quickly make alterations and try again.

Note	In general, if you are making a map that will be printed on paper, figure out what scale you will be producing the printed map, then zoom to that scale in your view before opening the Multi-Theme Auto-Labeler tool.

Tip	This project includes another sample script called "Graphic.ConvertGraphicTextToSplineText" which is included in the extension. Just load it in a script editor and run it with the view you have successfully used the Multi-Theme Auto-Labeler tool with to align those labels to your projection.


Point Dispersion Sample Extension
Point Dispersion

Description: This extension gives you a choice of how to disperse points that sit on top of each other. You can have them disperse as grapics only, or you can disperse them permanently in their shapefile.

Requires: A view containing at least one point theme. The Point Dispersion Extension is built with the Dialog Designer, so it must also be installed.

FileName: pntdisp.avx


Shapefile Description Sample Extension
Shapefile Description

Description: The Shapefile Description Dialog extension provides something similar to a DESCRIBE in ARC/INFO: it adds a button to the View GUI for displaying information about the first active shapefile theme, such as how many features it contains, how many are selected, and the format of the fields of its attribute table.

While this extension is called Shapefile Description, it also works on themes based on coverages and map libraries (Fthemes). Its button is enabled for Fthemes only.

Requires: The Shapefile Description button is disabled until you have an active feature theme in the view. The Shapefile Description extension is built with the Dialog Designer, so it must be installed.

FileName: shpdesc.avx


Accessing additional scripts

You can access additional Avenue scripts and sample extensions on the ESRI Web page. Connect to http://www.esri.com/arcview and follow the user connection links to the scripts area. ESRI maintains these scripts, developed by ESRI and users like you, in an online database. Scripts are available for all areas of ArcView GIS, including many that can be used with ArcView's optional extensions.


Color Calibration Layout

Description: This is a project file containing a layout document.  There are some graphics in this layout that you can use to calibrate your printer to your screen in order to improve the matching of colors.

Requires:

FileName: calibrat.apr


Comprehensive listing of Avenue requests

Description: This is a comma delimited text file that lists all the Avenue requests along with their class, superclass, return type, and argument list. You can easily load this file into an ArcView table document and then sort, search, and analyze!

For each request, the file contains fields for:  Class, Request, SuperClass, Return, Arguments, and Extension.

Class - the target class of the request

Request - the request name

Return - the class of the object returned by the request

SuperClass -  the superclass of the target class

Arguments - the argument list for this request

Extension - the name of the extension this request is part of or null if it is part of core ArcView

Requires:

Filename: avreq30.txt


Comprehensive listing of Avenue requests in ArcView 3.1

Description: This is a comma delimited text file that lists all the Avenue requests along with their class, superclass, return type, and argument list. You can easily load this file into an ArcView table document and then sort, search, and analyze!

This text file only includes the requests in core ArcView 3.1 and included extensions (i.e. Dialog Designer, CAD Reader, Digitizer, etc.). It does not include the requests in the optional analyst extensions (i.e. 3D Analyst, Spatial Analyst, Network Analyst, etc.)

For each request, the file contains fields for:  Class, Request, SuperClass, Return, Arguments, and Extension.

Class - the target class of the request

Request - the request name

Return - the class of the object returned by the request

SuperClass -  the superclass of the target class

Arguments - the argument list for this request

Extension - the name of the extension this request is part of or null if it is part of core ArcView

Requires:

Filename: avreq31.txt


How to use the samples

The samples library contains programs that you can use directly in your work or study to learn more about how ArcView works. There are three kinds of samples in the samples library: Avenue scripts, extensions, and other sample programs

Scripts

To use the sample scripts, first browse through the on-line help topics that describe the available scripts. The help topic about each script will tell you what it does and what you need to do in order to run it, such as having a particular type of document open in your ArcView session before you run the script. When you find a sample script you would like to use, there are two different ways you can load it into ArcView:

To load a sample script into ArcView by copying and pasting the source code from the on-line help

1	At the top of the help topic that describes the sample script, click the Source Code jump.

2	In the separate source code window that appears, choose Copy from Options (to copy all the source code), or select the lines of source code you want to use and then choose Copy from Options.

3	In ArcView's Project window, click the Scripts icon, then press New to create a new script.

4	Click the Paste button [image].

5	Compile and run the script.

To load a sample script into ArcView from the script's ASCII source code file

1	In the help topic that describes the sample script you want to load into ArcView, look at what file name the script has.

2	In ArcView's Project window, click the Scripts icon, then press New to create a new script.

3	Press the Load Text File button [image].

4	In the dialog that appears, navigate to the $AVHOME/samples/scripts directory in your ArcView installation. (This directory contains all the scripts in the samples library as ASCII files). Choose the  file name for the script you want to load. Press OK.

5	Compile and run the script.

Extensions

Extensions are add-on programs to ArcView that provide additional functionality. When you load an extension, ArcView's user interface changes to reflect the functionality in the extension. For example, new menus, menu items, buttons, and tools may appear. In addition to the extensions that come with ArcView, such as the CAD Reader extension, a number of sample extensions are provided in this samples library. These sample extensions provide useful functions for your work. Examining these sample extensions will also help you learn how to create your own extensions. You can find out about each sample extension by looking at its help topic. The extensions themselves are located in the $AVHOME/samples/ext directory in your ArcView installation.

To load a sample extension

To load extensions in ArcView you make the Project window active, and then choose Extensions from the File menu. The dialog that appears lists all the extensions available in the directory identified by the $AVEXT environment variable and in the directory identified by the $USEREXT environment variable (which defaults to $HOME). In order for the sample extensions to be listed in the Extensions dialog so you can load them, you can either copy the .avx file for the extension(s) you wish to load from $AVHOME/samples/ext to your $HOME directory, or you can set the USEREXT environment variable to $AVHOME/samples/ext with the following line of Avenue code:

system.SetEnvVar( "USEREXT", "$AVHOME/samples/ext")

Once you've done this, the sample extensions will be listed in the Extensions dialog the next time you open it. In that dialog, check the sample extension(s) you wish to load and press OK.

Tip    One of the sample extensions, seesmple.avx, adds a menu choice to the File menu (when the Project window is active) that makes it easy to browse and load the other sample extensions (it sets $USEREXT to $AVHOME/samples/ext for you and then displays the Extensions dialog). To load this extension, first copy it to your $HOME directory, then check it in the Extensions dialog.

To use the sample extensions to help learn how to create your own extensions

The $AVHOME/samples/ext directory contains the .avx file for each sample extension, along with a corresponding ArcView project file (.apr) file from which the extension file was built. You can use the project file to learn how the extension was built or you can create a "custom" version of the sample extension by modifying the scripts and objects in the project file. (The header file (.hdr) for each extension in  $AVHOME/samples/ext was used only to compile the help system, but you might find it useful for getting a quick description of what the extension does.)

Other sample programs and utilities

These samples include project files, Visual Basic examples, C files, etc. for you to use and examine. The on-line help for each of these samples includes directions on how to use it. Source code for these samples is provided in the $AVHOME/samples/other directory.


Listing of changed Avenue classes for ArcView 3.0

Description: This is a comma delimited text file that lists all the Avenue classes that have changed from ArcView 2.1 to 3.0. You can inspect this list to learn about new, changed, or removed Avenue classes in ArcView 3.0.

The file has four fields: Class, Request, Arguments, Return, Status, and Explanation.

Class - the class

SuperClass - the superclass

Status - either NEW or CHANGED

Explanation - a brief bit of information about the changes to the class. This field is populated for all CHANGED classes.  If the NEW class is part of an extension product, the explanation contains the name of the extension product.

Requires:

Filename: chngclas.txt


Listing of changed Avenue classes for ArcView 3.1

Description: This is a comma delimited text file that lists all the Avenue classes that have changed from ArcView 3.0 to 3.1. You can inspect this list to learn about new, changed, or removed Avenue classes in ArcView 3.1.

This text file only covers changes to classes in core ArcView 3.1 and included extensions (i.e. Dialog Designer, CAD Reader, Digitizer, etc.). It does not include changes to the optional analyst extensions (i.e. 3D Analyst, Spatial Analyst, Network Analyst, etc.)

The file has four fields: Class, Request, Arguments, Return, Status, and Explanation.

Class - the class

SuperClass - the superclass

Status - either NEW or CHANGED

Explanation - a brief bit of information about the changes to the class. This field is populated for all CHANGED classes.  If the NEW class is part of an extension product, the explanation contains the name of the extension product.

Requires:

Filename: chngclas31.txt


Listing of changed Avenue requests for ArcView 3.0

Description: This is a comma delimited text file that lists all the Avenue requests that have changed from ArcView 2.1 to 3.0. You can inspect this list to learn about new, changed, or removed Avenue requests in ArcView 3.0.

The file has six fields: Class, Request, Arguments, Return, Status, and Explanation.

Class - the target class of the request

Request - the request name

Return - the class of the object returned by the request

Arguments - the argument list for this request

Status - either NEW, CHANGED, or REMOVED

Explanation - a brief description indicating what was changed.

Requires:

Filename: chngreqs.txt


Listing of changed Avenue requests for ArcView 3.1

Description: This is a comma delimited text file that lists all the Avenue requests that have changed from ArcView 3.0 to 3.1. You can inspect this list to learn about new, changed, or removed Avenue requests in ArcView 3.1.

This text file only covers changes to requests in core ArcView 3.1 and included extensions (i.e. Dialog Designer, CAD Reader, Digitizer, etc.). It does not include changes to the optional analyst extensions (i.e. 3D Analyst, Spatial Analyst, Network Analyst, etc.)

The file has six fields: Class, Request, Arguments, Return, Status, and Explanation.

Class - the target class of the request

Request - the request name

Return - the class of the object returned by the request

Arguments - the argument list for this request

Status - either NEW, CHANGED, or REMOVED

Explanation - a brief description indicating what was changed.

Requires:

Filename: chngreq31.txt


Samples of DDE conectivity with MS Access
Samples of DDE connectivity with MS Access

Description: These samples are useful for several reasons.  First, Microsoft Access is a DDE client in most application.  Other reasons are peculiar to Microsoft Access, like it cannot have it's data change via a DDEPoke or similar from another application, DDEPoke to Access can ONLY send SQL query information to Access, when using Access as a DDE client the initial DDERequest or DDEExecute statement will not work--this is only on the first run of Access after start, if you duplicate the process the second time it will work (if coded  correctly).

Requires: Microsoft Access.

Filenames: ddewhite.txt


Use Microsoft Word's spell checker in ArcView

Description: This contains the necessary scripts and WordBasic macros to use Microsoft Word's spell checker in ArcView.  Instructions are included that give a step by step process for creating the necessary components in either Word 6.0 or Word 7.0.  Once you have completed the necessary setup in Word, you might create your own extension that contains a button or menu choice that invokes the spell checker.

This script works by creating a DDE connection to Word and then asked you for the word you wish to spell check.  The macros in word are executed and then one of three things will occur (1) a message is returned saying your word was correctly spelled, (2) a message containing the possible spellings for the word you entered is returned, or (3) if Word was unable to correct the spelling a message is returned saying that no alternate spelling could be found.

Requires:  Either Microsoft Word 6.0 or Word 7.0

Filename: spellchk.txt


Visual Basic Example Verify ArcView Exists

Description: Here is an example in Visual Basic of how to determine where ArcView has been installed. This may prove helpful in situations in which you have a VB client that must wake up ArcView. The VB code establishes a DDE conversation with the Windows Program Manager to get at the program group named, in this example, "ArcView 3.0."

Program Manager can provide information about its groups to an application. Applications can request this information from Program Manager by using the PROGMAN topic.

An application can use a group name as an item name to request information about the group. Program Manager provides this information in CF_TEXT format. The fields of group information are separated by commas. The first line of the information contains the group name (in quotation marks), the path of the group file, and the number of items in the group. Each subsequent line contains information about an item in the group, including the command line (in quotation marks), the default directory, the icon path, the position in the group, the icon index, the shortcut key (in numeric form), and the minimize flag.

In addition, an application can obtain a list of Program Manager groups by issuing a request for the Group item. Program Manager provides the list in CF_TEXT format. The list consists of group-name strings separated by carriage returns. Use of this capability is not illustrated here.

The example assumes you have added a text control and a command button control to a form in Visual Basic. In a complete app you probably wouldn't display the text control; more likely than not you'd set it to be invisible, but it's presented here to show what the LinkRequest returns.

Requires: The text control should have the following properties:

MultiLine       True

Scrollbars      3 - Both

FileName: vbexample.txt


WordBasic Extension Help Macro

Description: This is the WordBasic macro that was used to generate the help topics for the sample extensions and to finish generating the cnt file for the samples.hlp.  This script only creates help topics for the extensions and must be run after the scrpthlp.txt macro, which creates help topics for the sample scripts and creates to the samples.cnt.

The help for ArcView's samples was compiled using HCW 3.0, which is available from Microsoft's software library via ftp.  You will not find a script to generate the help topics for the "other" samples and the How to use the samples topic, since these were generated by hand rather than automatically.

The value of this macro is mainly to show you how this process was accomplished and that this macro may be of use to you in the event you want to add your own samples to your local ArcView help environment.

Requires: Microsoft Word 7.0

FileName: extthlp.txt


WordBasic Script Help Macro

Description: This is the WordBasic macro that was used to generate the help topics for the sample scripts and generate the cnt file for the samples.hlp. This script only creates help topics for the scripts and must be run before the exthlp.txt macro, which creates help topics for the sample extensions and adds to the samples.cnt.

The help for ArcView's samples was compiled using HCW 3.0, which is available from Microsoft's software library via ftp.  You will not find a script to generate the help topics for the "other" samples and the How to use the samples topic, since these were generated by hand rather than automatically.

The value of this macro is mainly to show you how this process was accomplished and that this macro may be of use to you in the event you want to add your own samples to your local ArcView help environment.

Requires: Microsoft Word 7.0

FileName: scrpthlp.txt


View.CalculateAcreage
Calculates acres for polygon shapes

Source Code

Description:  Calculates area and perimeter for polygon themes. If the View has been projected, the calculations are in projected units. Otherwise the calculations are in 'native' map units. The script processes the list of active themes to calculate area, acres, and perimeter.

The script will add the fields Area, Acres and Perimeter to polygon themes if they do not exist. If the fields exist, their values are recalculated. Rerun the script if you change the projection of the view.

The factor of 0.0002471 is used by default. Modify as necessary for your region.

Name:  View.CalculateAcreage

Requires:  A View with at least one active theme. You must have write access to the active theme(s).

Self:

Returns:

FileName:  calcacre.ave


View.CalculateAcreage (Sample Script)
'Calculates acres for polygon shapes

'

' Get the view and its projection if any.

'

theView = av.GetActiveDoc

thePrj = theView.GetProjection

if (thePrj.IsNull) then

  hasPrj = false

else

  hasPrj = true

end

'

' Get the list of active themes. If there aren't any, let the user know

' and exit.

'

theActivethemeList = theView.GetActivethemes

if (theActivethemeList.Count = 0) then

  MsgBox.Error("No active themes.","")

  Exit

end

'

' Loop through the list of active themes. If you can't edit the theme

' inform the user.

'

For Each thetheme in theActivethemeList

  theFTab = thetheme.GetFTab

  if (theFTab.CanEdit.Not) then

    MsgBox.Info("Cannot edit table for theme:"++thetheme.AsString,"")

    Continue

  end

  '

  ' Make the FTAB editable, and find out which type of feature it is.

  '

  theFTab.SetEditable(TRUE)

  theType = theFTab.FindField("shape").GetType

  if (theType = #FIELD_SHAPEPOLY) then

    '

    ' If it's polygonal check for the existence of the fields "Area" and

    ' Acre and Perimeter. If they do not exist, create them.

    '

    'AREA

    if (theFTab.FindField("Area") = nil) then

      theAreaField = Field.Make("Area",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({theAreaField})

    else

      ok = MsgBox.YesNo("Update Area for"++thetheme.getName+"?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      theAreaField = theFTab.FindField("Area")

    end

    'ACRE

    if(theFTab.FindField("Acres") = nil)then

      theAcresField = Field.Make("Acres",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({theAcresField})

    else

      ok = MsgBox.YesNo("Update Acres"++thetheme.getName+"?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      theAcresField = theFTab.FindField("Acres")

    end

    'PERIMETER

    if (theFTab.FindField("Perimeter") = nil) then

      thePerimeterField = Field.Make("Perimeter",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({thePerimeterField})

    else

      ok = MsgBox.YesNo("Update Perimeter"++thetheme.getName+"?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      thePerimeterField = theFTab.FindField("Perimeter")

    end

    '

    ' Loop through the FTAB and find the projected area and perimeter of each

    ' shape and set the field values appropriately.

    '

    theShape = theFTab.ReturnValue(theFTab.FindField("shape"),0)

    For Each rec in theFTab

      theFTab.QueryShape(rec,thePrj,theShape)

      theArea = theShape.ReturnArea

      theAcres = theArea*0.0002471

      thePerimeter = theShape.ReturnLength

      theFTab.SetValue(theAreaField,rec,theArea)

      theFTab.SetValue(theAcresField,rec,theAcres)

      theFTab.SetValue(thePerimeterField,rec,thePerimeter)

    end

  theFTab.SetEditable(FALSE)

  else

    MsgBox.Info("You must use this script on a polygon theme.",

      "View.CalculateAcreage")

    return Nil

  end

end


View.LabelAlongLines
Labels selected features with text groups along the path

Source Code

Description: When you use this button, you will be prompted with a Msgbox.MultiInput to enter a spacing coefficient, and a percentage along the features to begin placing the labels. The spacing coefficient controls how widely spaced the letters of the label will be. Three things affect the effectiveness of a spacing coefficent: the View's scale, the View's units, and the default text size. You can change the text size of the labels after placing them, which sometimes gives you a better result. This script checks to see if your spacing coefficent is close enough to use, and if it isn't, you will be prompted as to how to change it. The values for percentage along the line are 0 to 100 percent. All numbers less than 0 will be set to 0 and all numbers over 100 will be set to 100. The result of running this script is a graphic group of graphicText elements, where each element corresponds to a letter in the label for the feature.

Name: View.LabelAlongLines

Requires: Attach this script as a button in your View GUI. Make sure you have a line theme active with at least one selected feature, and  that the theme has a label field defined.

Self:

Returns:

FileName: contlab.ave


View.LabelAlongLines (Sample Script)
'Labels selected features with text groups along the path

v = av.GetActiveDoc

v.GetGraphics.UnSelectAll

t = v.GetActiveThemes.Get(0)

if (t.GetFTab.GetShapeClass.GetClassName <> "PolyLine") then

  return nil

end

aTP = t.GetTextPositioner

gg = Msgbox.MultiInput("Enter a Spacing & Positioning Information",
"Contoured Label Placer",{"Spacing Coefficient",
"Starting Point as % from Left"},{"10", "50"})

if (gg.count = 0) then

  return nil

end

if (gg.Get(0).IsNumber) then

  SpacingConstant = gg.Get(0).AsNumber

else

  Msgbox.Error ("The spacing coefficient must be a number","")

  return nil

end

if (gg.Get(1).IsNumber) then

  StartPos = gg.Get(1).AsNumber

  if (StartPos < 0) then

    StartPos = 0

  elseif (StartPos > 100) then

    StartPos = 100

  end

else

  Msgbox.Error ("The starting position must be a number","")

  return nil

end

aTS = GraphicText.Make("hhh",(0@0)).GetSymbol

v.GetDisplay.HookupSymbol(aTS)

aStr = nil

for each rec in t.GetFtab.GetSelection

  ls = t.GetFtab.ReturnValue(t.GetFtab.getFields.Get(0),rec)

  aStr = t.GetFtab.ReturnValueString(t.GetLabelField, rec)

  if (  (aStr = "") or (aStr = nil) or (ls.IsNull)  ) then

    continue

  end

  ds = ls.ReturnDensified(SpacingConstant)

  pn = ds.AsList

  n = pn.Get(0).Count

  sc = aStr.Count

  StartPt = (n*(StartPos/100)) - (sc/2)

  if (StartPt < 0) then

    StartPt = 0

  elseif (StartPt > n) then

    StartPt = ((n - 1) - aStr.Count)

  end

  if (StartPt < 1) then

    Msgbox.Warning("Your Spacing Coefficent was too large, try again.","")

    return nil

  elseif (StartPt > 500) then

    Msgbox.Warning("Your Spacing Coefficent was too small, try again.","")

    return nil

  end

  for each alet in 0..(sc - 1)

  aLetter = aStr.Middle(alet,1)

  aGT = GraphicText.Make(aLetter, (0@0))

  aGT.SetSymbol(aTS)

  aGT.SetDisplay (v.GetDisplay)

    aLin = PolyLine.Make({{(pn.Get(0).Get(StartPt + alet)),
        (pn.Get(0).Get(StartPt + alet + 1))}})

    aTP.calculate(aLin,aGT.GetExtent,1,nil)

    aGT.SetOrigin(aTP.GetOrigin)

    aGT.SetAngle(aTP.GetAngle)

    aGT.SetSelected(true)

    v.GetGraphics.AddBatch(aGT)

  end

  v.GetGraphics.GroupSelected

  v.GetGraphics.UnSelectAll

end

v.GetGraphics.EndBatch


Theme.ConvertDDtoDMS
Converts DecimalDegrees values to DegreesMinutesSeconds

Source Code

Description:  Converts DecimalDegrees values in a table to DegreesMinutesSeconds. A new field for the converted values is added to the table.

Values greater than 180 or less than -180 may not be converted correctly.

Name:  Theme.ConvertDDtoDMS

Requires:  The table must be editable (dBASE or INFO) and you must have write access to it. The table must contain a field with DD values (dd.dddd).

Self:

Returns:

FileName:  dd2dms.ave


Theme.ConvertDDtoDMS (Sample Script)
'Converts DecimalDegrees values to DegreesMinutesSeconds

' Get the list of tables in the project and let the user pick one

tabList = {}

for each i in av.GetProject.GetDocs

  if (i.Is(Table)) then

    tabList.Add(i)

  end

end

' Have the user pick the table to convert

tb = MsgBox.ChoiceAsString(tabList,

  "Choose the table which contains the values to convert:",

  "Convert DD to DMS")

if (tb = Nil) then

  return ""

end

tbv = tb.GetVTab

' Have the user pick the field with the DMS values

f = MsgBox.ChoiceAsString(tbv.GetFields,

  "Choose the field to convert from DD to DMS",

  "Select field")

if (f = Nil) then

  return ""

end

newFieldName = MsgBox.Input("Enter a name for the new field (up to 8 characters:",

  "Convert DD to DMS","DMS-X")

if (newFieldName = Nil) then

  return ""

end

' Make sure you can write to the table, and that the field doesn't already exist

if (tbv.CanEdit.Not) then

  MsgBox.Info("Cannot edit the table.","Convert DD to DMS")

  return ""

end

if (tbv.FindField(newFieldName).Is(Field)) then

  MsgBox.Info("A field with name"++newFieldName.asString++

    "already exists.","Convert DD to DMS")

  return ""

end

' If we can get this far, we can add the new field

tbv.SetEditable(true)

newf = Field.Make(newFieldName,#FIELD_CHAR,12,0)

tbv.AddFields({newf})

' Convert DMS to DD

for each r in tbv

  v = tbv.ReturnValueString(f, r)

  ' get the degrees

  d = v.asString.asTokens(".").Get(0)

  if (v.asString.asTokens(".").Count <> 2) then

    MsgBox.Info("Values in field"++f.asString++

      "appear to be in the incorrect format. Need DD (e.g.,12.3456).",

      "Convert DD values to DMS")

    tbv.RemoveFields({newf})

    tbv.SetEditable(false)

    return ""

  end

  dnum = d.asNumber.Abs

  v = v.asNumber.Abs

  ' convert decimal degrees to decimal seconds

  ds = v * 3600

  if (ds = 0) then

    dm = "00"

    dss = "00"

  else

    ' get the minutes

    dm = (ds - (dnum * 3600)) / 60

    dm = dm.Truncate

    ' get the seconds

    dss = ds - (dnum * 3600) - (dm * 60)

    dss = dss.Truncate

    if (dm = 0) then

      dm = "00"

    end

    if (dss = 0) then

      dss = "00"

    end

  end

  dd = (d.asString ++ dm.asString ++ dss.asString)

  tbv.SetValue(newf,r,dd)

end

' Stop editing the table

tbv.SetEditable(false)


Theme.ConvertDMStoDD
Converts DegreesMinutesSeconds values to DecimalDegrees

Source Code

Description: Converts DegreesMinutesSeconds values in a table to DecimalDegrees. A new field for the converted values is added to the table.

Values greater than 180 or less than -180 may not be converted correctly.

Name: Theme.ConvertDMStoDD

Requires: The table must be editable (dBASE or INFO) and you must have write access to it. The table must have a field in which the DMS values are stored in the format DDD MM SS.

Self:

Returns:

FileName: dms2dd.ave


Theme.ConvertDMStoDD (Sample Script)
'Converts DegreesMinutesSeconds values to DecimalDegrees

' Get the list of tables in the project and let the user pick one

tabList = {}

for each i in av.GetProject.GetDocs

  if (i.Is(Table)) then

    tabList.Add(i)

  end

end

' Have the user pick the table to convert

tb = MsgBox.ChoiceAsString(tabList,

  "Choose the table which contains the values to convert:",

  "Convert DMS values to DD")

if (tb = Nil) then

  return ""

end

tbv = tb.GetVTab

' Have the user pick the field with the DMS values

f = MsgBox.ChoiceAsString(tbv.GetFields,

  "Choose the field to convert from DMS to DD",

  "Select field")

if (f = Nil) then

  return ""

end

newFieldName = MsgBox.Input("Enter a name for the new field (up to 8 characters):",

  "Convert DMS values to DD","DD-X")

if (newFieldName = Nil) then

  return ""

end

' Make sure you can write to the table, and that the field doesn't already exist

if (tbv.CanEdit.Not) then

  MsgBox.Info("Cannot edit the table.","Convert DMS values to DD")

  return ""

end

if (tbv.FindField(newFieldName).Is(Field)) then

  MsgBox.Info("A field with name"++newFieldName.asString++

    "already exists.","Convert DMS values to DD")

  return ""

end

' If we can get this far, we can add the new field

tbv.SetEditable(true)

newf = Field.Make(newFieldName,#FIELD_DECIMAL,12,6)

tbv.AddFields({newf})

' Convert DMS to DD

for each r in tbv

  v = tbv.ReturnValueString(f, r)

  ' split the string into 3 parts: D M S

  it = v.AsTokens(" ")

  if (it.Count <> 3) then

    MsgBox.Info("Values in field"++f.asString++

      "appear to be in the incorrect format. Need DDD MM SS.",

      "Convert DMS to DD")

    tbv.RemoveFields({newf})

    tbv.SetEditable(false)

    return ""

  end

  ' Do the conversion

  ' degrees = degrees

  d  = it.Get(0)

  ' minutes/60

  m  = ((it.Get(1).asNumber) / 60)

  ' seconds/3600

  s  = ((it.Get(2).asNumber) / 3600)

  ms = (m + s)

  if (ms <> 0) then

      ms.SetFormat("dd.dddd")

      ms = ms.asString.asTokens(".").Get(1)

   end

  dms = (d + "." + ms.asString).asNumber

  dms.SetFormat("dd.dddd")

  tbv.SetValueNumber(newf,r,dms)

end

' Stop editing the table

tbv.SetEditable(false)


View.ExplodePolygons
Converts multi-part polygons to single-part polygons

Source Code

Description:  This script converts a polygon theme which may contain multi-part polygons into a new polygon shapefile which consists of single-part exploded polygons. It is currently setup to copy over only one field from the input FTab. You can modify it to do otherwise.

'You can simulate ARC/INFO Dissolve functionality in ArcView by first using the Table Summary function to merge your shapes by values in a chosen field. Then use this script to explode those multi-part polygons into individual shapes.

Name:  View.ExplodePolygons

Requires:  A view with one active polygon theme.

Self:

Returns:

FileName:  explode.ave


View.ExplodePolygons (Sample Script)
'Converts multi-part polygons to single-part polygons

theView = av.getactivedoc

if (theView.GetActiveThemes.Count < 1) then

  MsgBox.Error("You must have one polygon theme active in the View.",

               "Error")

  return nil

end

origTheme = theView.GetActiveThemes.Get(0)

origFtab = origTheme.GetFtab

origShpFld = origFtab.FindField("Shape")

if (origShpFld.GetType <> #FIELD_SHAPEPOLY) then

  MsgBox.Error("The active theme in the View must be a polygon theme.",

               "Error")

  return nil

end

origFldList = origFtab.GetFields.Clone

origFldList.RemoveObj(origShpFld)

origJoinFld = MsgBox.ChoiceAsString(origFldList,

                     "Choose join field","")

if (origJoinFld = nil) then

  return nil

end

newSFN = FileDialog.Put("*.shp".asfilename,"*.shp",

                        "New Exploded Shapefile")

if (newSFN = nil) then

  return nil

end

newFtab = Ftab.MakeNew(newSFN,Polygon)

newIDfld = Field.Make("theID",#FIELD_SHORT,8,0)

newJoinFld = origJoinFld.Clone

newFtab.AddFields({newIDfld, newjoinFld})

newShpFld = newFtab.FindField("Shape")

for each rec in origFtab

  origPolygon = origFtab.ReturnValue(origShpFld,rec)

  origJoinVal = origFtab.ReturnValue(origJoinFld,rec)

  if (origPolygon.AsList.Count < 2)

    then

      newRecNo = newFtab.AddRecord

      newFtab.SetValue(newShpFld,newRecNo,origPolygon)

      newFtab.SetValue(newJoinFld,newRecNo,origJoinVal)

      newFtab.SetValue(newIDfld,newRecNo,newRecNo)

  end

  if (origPolygon.AsList.Count > 1)

    then

      for each polyPiece in origPolygon.Explode

        newRecNo = newFtab.AddRecord

        newFtab.SetValue(newShpFld,newRecNo,polyPiece)

        newFtab.SetValue(newJoinFld,newRecNo,origJoinVal)

        newFtab.SetValue(newIDfld,newRecNo,newRecNo)

      end

   end

end

newTheme = Ftheme.Make(newFtab)

theView.AddTheme(newTheme)

newTheme.SetVisible(true)

' End of Script "explode.ave"


Project.ExtractScripts
Extracts script from project

Source Code

Description: This script extracts scripts from a user specified project. It

1.)  Prompts the user to select a project file from disk

2.)  Parses said project file for all SEd's and scripts

3.)  Presents all SEd and script names in a window, and prompts the user to select one

4.)  Inserts the script text into the active SEd window

Name: Project.ExtractScripts

Requires: To be launched from a button or menu in the SEd GUI. The successful execution of this script depends on the following assumptions:

a.)  A SEd or Script entry in a prject file is always declared by a line that begins with either:

"(SEd."  -or- "(Script."

This is the only instance in which a line  will begin with these key-strings.

b.)  The line after the SEd or Script declaration will ALWAYS be the "Name:" line, which will be TAB delimited.

c.)  Beginning w/ the SEd or Script declaration line, all lines are TAB delimited up to and including the "Source:" or "SourceCode:" line.

d.)  The source string for a SEd or Script (as it exists in the project file) will NEVER contain any TAB's.

Self:

Returns:

FileName: extscrpt.ave


Project.ExtractScripts (Sample Script)
'Extracts script from project

ThisScript = Script.The.GetName

TheTargetSEd  = av.GetActiveDoc

if (TheTargetSEd.Is(SEd).Not) then

  MsgBox.Info("This script must be launched from the SEd GUI...",ThisScript)

  exit

end

  ' a few pseudo-constants...

TAB_CHAR       = 9.AsChar

QUOTE_CHAR     = 34.AsChar

NEWLINE        = ""+nl+""

TheScriptDict = Dictionary.Make(10) ' all scripts will be stored in

                                    ' this dictionary...

'******** 1) Prompt the user to choose a project file from disk... ********

TheProjectFN = FileDialog.Show("*.apr",

                               "Project",

                               "Please select a project file...")

if (TheProjectFN = nil) then

  exit

end

'******** 2) Open the file and parse for SEd's and scripts... **************

TheLineFile = LineFile.Make(TheProjectFN, #FILE_PERM_READ)

av.ShowMsg("Parsing "+TheProjectFN.GetBaseName++"for Scripts and SEd's...")

NumLines = TheLineFile.GetSize

LineCount = 0

while (TheLineFile.IsAtEnd.Not)

  TheLineString = TheLineFile.ReadElt

  TheName = ""

  TheSource = ""

  LineCount = LineCount + 1

  av.SetStatus(100 * (LineCount / NumLines))

    ' is the line the first line of a SEd or Script

    ' entry?  if not, go back to the beginning of

    ' the loop...

  if ((TheLineString.Contains("(SEd.").Not) and

      (TheLineString.Contains("(Script.").Not)) then

    continue

  end

  if ((TheLineString.Left(5) = "(SEd.").Not) then

      ' halfway out the door...

    if (TheLineString.Count < 8) then

      continue

    end

    if ((TheLineString.Left(8) = "(Script.").Not) then

      continue

    end

  end

    ' the current line IS a SEd or Script entry

    ' declaration line; therefore, the next line

    ' must be the "Name:" line.  Read it and parse

    ' for "TheName"...

  TheLineString = TheLineFile.ReadElt

  LineCount = LineCount + 1

  if (TheLineString.AsTokens(TAB_CHAR).Get(0) <> "Name:") then

    MsgBox.Error("Cannot find script name...",ThisScript)

    TheLineFile.Close

    exit

  else

    TheName = TheLineString.AsTokens(TAB_CHAR).Get(1).UnQuote

  end

    ' The next line for which to search begins

    ' with either "Source:" or "SourceCode:", depending

    ' on whether we are dealing with a SEd or a Script.

    ' If we hit a ")", then there is no source code.

  while (TRUE)

    TheLineString = TheLineFile.ReadElt

    LineCount = LineCount + 1

    if (((TheLineString.AsTokens(TAB_CHAR).Get(0) =  "Source:")) or

        ((TheLineString.AsTokens(TAB_CHAR).Get(0) =  "SourceCode:")) or

        ((TheLineString.AsTokens(TAB_CHAR).Get(0) =  ")"))) then

       break

    end

  end ' WHILE (TRUE)

  if (TheLineString = ")") then ' there is no source string...

    continue                    ' "TheSource" defaults to ""

  else

    TheSource = TheLineString.AsTokens(TAB_CHAR).Get(1)

  end

    ' since the source string for a script may span

    ' several line-reads, check to see if

    ' "TheSource" is complete...If the string ends with

    ' a quote that is NOT preceded by a slash, it's complete.

    ' catenate lines from file till we hit the end of the

    ' source string...

  while (TRUE)

     if ((TheSource.Middle(TheSource.Count - 1,1) = QUOTE_CHAR) and

         (TheSource.Middle(TheSource.Count - 2,1) <> "\")) then

       break

     end

     TheSource = TheSource+TheLineFile.ReadElt

     LineCount = LineCount + 1

  end ' while (TRUE)

  TheScriptDict.Add(TheName,TheSource)

end ' while (TheTextFile.IsAtEnd.Not)

TheLineFile.Close

av.SetStatus(100)

av.ClearStatus

' ******** 3) Prompt the user to select a script *********

TheScriptList = TheScriptDict.ReturnKeys

TheScriptList.Sort(TRUE)

TheExtractName = MsgBox.ListAsString(TheScriptList,

                                     "Choose a script...",

                                     TheProjectFN.GetBaseName)

if (TheExtractName = nil) then

  exit

end

' ******** 4) Insert source into active SEd window... *****

TheExtractSource = TheScriptDict.Get(TheExtractName)

TheExtractSource = TheExtractSource.Substitute("\"+QUOTE_CHAR,QUOTE_CHAR)

TheExtractSource = TheExtractSource.Substitute("\n",NEWLINE)

TheExtractSource = TheExtractSource.Right(TheExtractSource.Count - 1)

TheExtractSource = TheExtractSource.Left(TheExtractSource.Count - 1)

TheTargetSEd.Insert(TheExtractSource)


Points.ConvertToPolyon
Convert a cluster of points to a polygon

Source Code

Description:  This script creates a polygon representing the connection of the outermost points from a cluster of graphic points.

Name:  Points.ConvertToPolygon

Requires:  The active view must have at least 3 graphic points.

Self:

Returns:

FileName:  pnt2poly.ave


Points.ConvertToPolyon (Sample Script)
'Convert a cluster of points to a polygon

v = av.GetActivedoc

pts = v.GetGraphics

if (pts.Count < 3) then

  msgbox.info("Please select at least 3 points to make polygon","")

  exit

end

dicX = dictionary.make(11)

dicY = dictionary.make(11)

listPoly = {}

for each pt in pts

  pt = pt.GetShape

  if (pt.Is(Point)) then

    dicX.Add(pt.GetX,pt)

    dicY.Add(pt.GetY,pt)

  end

end

if (dicX.Count < 3) then

  msgbox.info("Please have least 3 graphic points on view to make polygon","")

  exit

end

listX = dicX.ReturnKeys

listY = dicY.ReturnKeys

listX.Sort(true)

pt0 = dicX.Get(listX.Get(0))

listPoly.Add(pt0)

'msgbox.listasstring(listx,pt0.GetX.AsString,"")

listX.Remove(0)

for each X in listX

  pt = dicX.Get(X)

  if (pt.GetY < pt0.GetY) then

    pt0 = pt

    listPoly.Add(pt0)

'    msgbox.listasstring(listx,pt0.GetX.AsString,"")

  end

end

listY.Sort(true)

listY.Remove(0)

for each Y in listY

  pt = dicY.Get(Y)

    if (pt.GetX > pt0.GetX) then

    pt0 = pt

    listPoly.Add(pt0)

  end

end

listX.Sort(false)

listX.Remove(0)

for each X in listX

  pt = dicX.Get(X)

  if (pt.GetY > pt0.GetY) then

    pt0 = pt

    listPoly.Add(pt0)

  end

end

listY.Sort(false)

listY.Remove(0)

for each Y in listY

  pt = dicY.Get(Y)

    if (pt.GetX < pt0.GetX) then

    pt0 = pt

    listPoly.Add(pt0)

  end

end

listPoly.Add(listPoly.Get(0))

poly = polygon.make({listPoly})

v.GetGraphics.Add(GraphicShape.Make(poly))


Graphic.AddColorToColorPalette
Adds color from selected graphic to color palette

Source Code

Description:   Run this script from a button or menu choice in either a DocGUI that supports view or layout documents.  The idea behind this script is to allow you to create a custom color and then be able to add it to the color palette.  Since ArcView does not directly support this, this script is necessary.

Place a graphic in either a view or layout and then change its symbol's color to the custom color of your choosing.  Then while this graphic is selected, run this script.  The color you have assigned to the graphic will be captured and added to the current color palette.

Name:  Graphic.AddColorToColorPalette

Requires:  A single graphic must be selected. If the graphic is a polygon, rectangle or circle, the fill symbol must be solid or stipple, it cannot be transparent.

Self:

Returns:

FileName:  addcolor.ave


Graphic.AddColorToColorPalette (Sample Script)
'Adds color from selected graphic to color palette

theDoc = av.GetActiveDoc

if (theDoc.Is(View).Not) then

  if (theDoc.Is(Layout).Not) then

    Msgbox.Error("This script must be run for a view or layout","Aborting")

    return nil

  end

end

theGraphics = theDoc.GetGraphics

if(theGraphics.GetSelected.Count <> 1) then

  Msgbox.Error("You must have one and only one graphics selected","Aborting")

  return nil

end

theGraphic = theGraphics.GetSelected.Get(0)

theGraphic.SetSelected(false)

theColor = theGraphic.GetSymbol.GetColor.Clone

av.GetSymbolWin.Open

av.GetSymbolWin.SetPanel(#SYMBOLWIN_PANEL_COLOR)

av.GetSymbolWin.GetPalette.GetList(#PALETTE_LIST_COLOR).Add(theColor)

av.GetSymbolWin.RefreshPalette(#PALETTE_LIST_COLOR)

theGraphic.GetSymbol.SetColor(theColor.Clone)

theGraphic.Select


ADD2Shapefile
Converts ARC/INFO .ADD file to Shapefile

Source Code

Description:   Converts an ARC/INFO coverage with an .ADD (address) file, to a shapefile with address elements.  Only the address attributes are included in the conversion.  Add the coverage to a view and make it the active theme, then run this script.

Substitution and place name aliases for addresses are converted to shapefile records.  A new table is created to contain the address alias (.ADD) records.  All of the current "good" addresses are assumed to be in the .ADD file. It is also assumed that the structure or sort order of the .ADD file has not been changed from how ARC/INFO created it.

To export more or all the fields to the shapefile, modify the code below to make the fields visible (search for the SetVisible request).

Name:    ADD2Shapefile

Requires:  An ARC/INFO coverage that has an .ADD file created with ARC/INFO. Make sure the .ADD file is associated with the appropriate feature class for the theme. A view must be the current document, with the appropriate theme active. Include the following update script to disable the control when these preconditions are not met.

  theView = av.GetActiveDoc

  theThemes = theView.GetActiveThemes

  'Check for active themes,

  'theme based on A/I coverage, .ADD file exists.

  SELF.SetEnabled((0 < theThemes.Count)

  and (Coverage.Exists(theThemes.Get(0).GetSrcName.GetDataSource))

  and ((INFODir.Make(FileName.Merge(theThemes.Get(0).

  GetSrcName.GetFileName.ReturnDir.asstring,("info"))).ContainsFile

  (theThemes.Get(0).GetName+".add"))))

Self:

Returns:

FileName:  addconv.ave


ADD2Shapefile (Sample Script)
'Converts ARC/INFO .ADD file to Shapefile

aTheme = av.GetActiveDoc.GetActiveThemes.Get(0)

' get directory for INFO files

aDirectoryFileName = aTheme.GetSrcName.GetFileName.ReturnDir

aDirectoryFileName.MergePath("info")

' Get .add

addVTab = VTab.Make(FileName.Merge(aDirectoryFileName.AsString,

 aTheme.GetName+".add"),  TRUE,  FALSE)

' get FTab for input theme

aFTab = aTheme.GetFTab

' make only the Shape and <cover># fields visible

aFieldList = aFTab.GetFields

idFldName = aTheme.GetName+"#"

for each fld in aFieldList

  if ((fld.GetName<>"Shape") AND (fld.GetName<>idFldName)) then

    fld.SetVisible(FALSE)

  end

end

' prompt for new shapefile theme name

shpFN = FileDialog.Put((aTheme.GetName+".shp").AsFileName,

 "*.shp", "Name output Shape file")

if (shpFN=Nil) then

  msgBox.Error("Shape file name not entered. Exiting...","")

  return nil

end

' prompt for place name alias file name

aliasFN = FileDialog.Put(("alias.dbf").AsFileName,

 "*.dbf", "Name place name Alias file")

if (aliasFN=Nil) then

  msgBox.Info("Alias file name not entered. It won't be created.","Warning"

end

' copy the theme to the shapefile

shpFTab = aFTab.Export(shpFN, Shape, FALSE)

' make the theme fields visible again

for each fld in aFieldList

  fld.SetVisible(TRUE)

end

' make the address fields and add them to shapefile (names needed later)

LfAddFld       = Field.Make("L-f-add", #FIELD_LONG,  6,  0)

LtAddFld       = Field.Make("L-t-add", #FIELD_LONG,  6,  0)

RfAddFld       = Field.Make("R-f-add", #FIELD_LONG,  6,  0)

RtAddFld       = Field.Make("R-t-add", #FIELD_LONG,  6,  0)

LzoneFld       = Field.Make("L-Zone", #FIELD_CHAR,  15,  0)

RzoneFld       = Field.Make("R-Zone", #FIELD_CHAR,  15,  0)

UpdateFld      = Field.Make("Update", #FIELD_CHAR, 1, 0)

SubstShpNumFld = Field.Make("SubstShpNum",#FIELD_LONG,  6,  0)

PreDirFld      = addVTab.FindField("Pre.dir").Clone

StrNameFld     = addVTab.FindField("Street.name").Clone

StrTypeFld     = addVTab.FindField("Street.type").Clone

SufDirFld      = addVTab.FindField("Suf.dir").Clone

shpFTab.SetEditable(TRUE)

shpFTab.AddFields({LfAddFld,LtAddFld,RfAddFld,RtAddFld,PreDirFld,StrNameFld,

 StrTypeFld,SufDirFld,LzoneFld,RzoneFld,UpdateFld,SubstShpNumFld})

' iterate through .ADD records and update shapefile fields

' Note: the place name aliases are processed in a second pass to

' insure that the address has been updated in the shapefile first.

sideFld           = addVTab.FindField("Side")

parityFld         = addVTab.FindField("Parity")

idFld             = addVTab.FindField(idFldName)

add_fromFld       = addVTab.FindField("F-add")

add_toFld         = addVTab.FindField("T-add")

add_PreDirFld     = addVTab.FindField("Pre.dir")

add_StreetNameFld = addVTab.FindField("Street.name")

add_StreetTypeFld = addVTab.FindField("Street.type")

add_SufDirFld     = addVTab.FindField("Suf.dir")

add_ZoneFld       = addVTab.FindField("Zone")

shapeShpFld = shpFTab.FindField("Shape")

idShpFld    = shpFTab.FindField(aTheme.GetName+"_")

av.ShowStopButton

av.showMsg("Transferring .ADD data into shapefile...")

numRecs = addVTab.GetNumRecords

anyAliases = FALSE

for each rec in addVTab

  if ((rec mod 100) = 0) then

    doMore = av.setStatus((rec/numRecs)*100)

    if (not doMore) then

      break

    end

  end

  side   = addVTab.ReturnValueString(sideFld, rec)

  parity = addVTab.ReturnValueString(parityFld, rec)

  if (parity="A") then

    anyAliases = TRUE

    continue

  end

  ' Note: shapeRecNum contains the shapefile record number that gets updated.

  ' It defaults to the <cover># (number) from the .ADD file.  For the cases

  ' when a new or existing replacement record is to be updated, shapeRecNum

  ' is set after determining the appropriate shape record number. The variable,

  ' shapeFound indicates if the correct shape record is found.

  shapeRecNum  = (addVTab.ReturnValueNumber(idFld,rec)) - 1

  ' The Update field in the shapefile indicates the status

  ' of each shape record.

  ' Update = (blank) => record not updated (unseen)

  ' Update = "L"     => left from/to has been updated

  ' Update = "R"     => right from/to has been updated

  ' Update = "B"     => both right and left from/to have been updated

  update = shpFTab.ReturnValueString(UpdateFld,shapeRecNum)

  if ((update="B") OR ((update="L") and (side="L")) OR

     ((update="R") and (side="R"))) then  ' we need to process replacements

     shapeFound = FALSE

  else

    shapeFound = TRUE

  end

  ' look for the shapefile record number to be modified

  while (NOT shapeFound)

    ' if the current shape record does not have a value for SubstShpNum (field)

    ' then a record needs to be added for sure. Otherwise, look at the next

    ' substitution record to see if it is the one to be updated.

    substNum = shpFTab.ReturnValueNumber(SubstShpNumFld, shapeRecNum)

    if (substNum < 1) then

      prevRecNum = shapeRecNum

      shapeRecNum = shpFTab.AddRecord

      shpFTab.SetValueNumber(SubstShpNumFld, prevRecNum, shapeRecNum)

      shpFTab.SetValue(shapeShpFld, shapeRecNum,

       shpFTab.ReturnValue(shapeShpFld, prevRecNum))

      shpFTab.SetValue(idShpFld, shapeRecNum,

       shpFTab.ReturnValue(idShpFld, prevRecNum))

      shapeFound = TRUE

    else

      ' There is a substitution record, so now check if the given substitution

      ' record is the one to modify.  If so, set shapeRecNum to this

      ' substitution record number, otherwise, let the while loop iterate

      ' again.

      shapeRecNum = substNum

      update = shpFTab.ReturnValueString(UpdateFld,shapeRecNum)

      if ((update="B") OR ((update="L") and (side="L")) OR

         ((update="R") and (side="R"))) then  ' we need to process more replacements

        shapeFound = FALSE

      else

        shapeFound = TRUE

      end

    end

  end ' while NOT shapeFound

  ' now the correct shapefile record can be updated

  if (side="R" or parity.IsNull) then

    shpFTab.SetValueNumber(RfAddFld, shapeRecNum,addVTab.ReturnValueNumber

     (add_fromFld,rec))

    shpFTab.SetValueNumber(RtAddFld, shapeRecNum, addVTab.ReturnValueNumber

     (add_toFld,rec))

    shpFTab.SetValueString(RzoneFld, shapeRecNum, addVTab.ReturnValueString

     (add_ZoneFld,rec))

    if (update="L" or parity.IsNull) then

      shpFTab.SetValueString(UpdateFld, shapeRecNum, "B")

    else

      shpFTab.SetValueString(UpdateFld, shapeRecNum, "R")

    end

  end

  if (side="L" or parity.IsNull) then

    shpFTab.SetValueNumber(LfAddFld, shapeRecNum,

     addVTab.ReturnValueNumber(add_fromFld,rec))

    shpFTab.SetValueNumber(LtAddFld, shapeRecNum,

     addVTab.ReturnValueNumber(add_toFld,rec))

    shpFTab.SetValueString(LzoneFld, shapeRecNum,

     addVTab.ReturnValueString(add_ZoneFld,rec))

    if (update="R" or parity.IsNull) then

      shpFTab.SetValueString(UpdateFld, shapeRecNum, "B")

    else

      shpFTab.SetValueString(UpdateFld, shapeRecNum, "L")

    end

  end

  shpFTab.SetValueString(PreDirFld, shapeRecNum,

   addVTab.ReturnValueString(add_PreDirFld,rec))

  shpFTab.SetValueString(StrNameFld, shapeRecNum,

   addVTab.ReturnValueString(add_StreetNameFld,rec))

  shpFTab.SetValueString(StrTypeFld, shapeRecNum,

   addVTab.ReturnValueString(add_StreetTypeFld,rec))

  shpFTab.SetValueString(SufDirFld, shapeRecNum,

   addVTab.ReturnValueString(add_SufDirFld,rec))

end ' for each .add record, pass 1

av.clearStatus

' now get rid of the temporary fields created in the shape file

shpFTab.RemoveFields({UpdateFld,SubstShpNumFld})

' fill the alias table

if ((anyAliases=FALSE) OR (aliasFN=Nil)) then

  return nil

end

' make the alias table and add fields

aliasVTab = VTab.MakeNew(aliasFN, dBASE)

aliasAliasFld    = Field.Make("Alias", #FIELD_CHAR,  15,  0)

aliasAddressFld  = Field.Make("Address", #FIELD_CHAR,  45,  0)

aliasVTab.SetEditable(TRUE)

aliasVTab.AddFields({aliasAliasFld,aliasAddressFld})

av.ShowStopButton

av.showMsg("Filling Alias table from .ADD file...")

for each rec in addVTab

  if ((rec mod 100) = 0) then

    doMore = av.setStatus((rec/numRecs)*100)

    if (not doMore) then

      break

    end

  end

  side   = addVTab.ReturnValueString(sideFld, rec)

  parity = addVTab.ReturnValueString(parityFld, rec)

  if (parity<>"A") then  ' do nothing

    continue

  end

  aliasRecNum = aliasVTab.AddRecord

  ' Note: .ADD file alias records store the alias (place name) in the

  ' Street.name field.  The house number is in the T-add field.

  ' The <cover># field contains the record number of the shapefile that

  ' has the address that is aliased.

  shapeRecNum  = (addVTab.ReturnValueNumber(idFld,rec)) - 1

  aliasString = addVTab.ReturnValueString(add_StreetNameFld, rec)

  addressString = (addVTab.ReturnValueString(add_toFld, rec)

                ++ shpFTab.ReturnValueString(PreDirFld, shapeRecNum)

                ++ shpFTab.ReturnValueString(StrNameFld, shapeRecNum)

                ++ shpFTab.ReturnValueString(StrTypeFld, shapeRecNum)

                ++ shpFTab.ReturnValueString(SufDirFld, shapeRecNum))

  aliasVTab.SetValueString(aliasAliasFld, aliasRecNum, aliasString)

  aliasVTab.SetValueString(aliasAddressFld, aliasRecNum, addressString )

end


View.AddRecNumFieldToThemes
Adds a Recno attribute to all active FTabs

Source Code

Description:   Adds a Recno attribute to Ftab of all active themes, if it doesn't exist, and populates it.  If it already exists, the user is prompted as to whether they want it's values updated or not.

Name:    View.AddRecNumFieldToThemes

Requires:  At least one active theme that you can write to.

Self:

Returns:

FileName:  addrecno.ave


View.AddRecNumFieldToThemes (Sample Script)
'Adds a Recno attribute to all active FTabs

theView = av.GetActiveDoc

themesList = theView.GetActiveThemes

if (themesList.Count = 0) then

  MsgBox.Error("No active themes in view.","Aborting")

  return nil

end

for each atheme in themesList

  currentFtab = atheme.GetFtab

  addRecno = FALSE

  hasRecno = FALSE

  updateattr = FALSE

  for each attr in currentFtab.GetFields

    if (attr.AsString.UCase = "RECNO") then

      hasRecno = TRUE

      if (MsgBox.YesNo(atheme.AsString+" contains RECNO attribute."+nl+

          "Do you want to update it?","Update",FALSE)) then

        updateattr = TRUE

        break

      else

        break

      end

    end

  end

  numRecs = currentFTab.GetNumRecords

  if (hasRecno.Not) then

    addRecno = (MsgBox.YesNo("Add Record Number Attribute "+nl+

                "to "+atheme.AsString+"?","Query",TRUE))

    if (addRecno) then

      currentFtab.SetEditable(TRUE)

      recAttr = Field.Make("Recno",#FIELD_LONG,8,0)

      av.ShowMsg("Adding Recno Attribute to "+atheme.AsString+"...")

      currentFtab.AddFields({recAttr})

      av.ClearMsg

    end

  end

  if ((updateattr) or (addRecno)) then

    currentFtab.SetEditable(TRUE)

    recnoField = currentFtab.FindField("Recno")

    for each recNum in currentFtab

      recno = ( recNum + 1 ).SetFormat("d").AsString

      currentFtab.SetValue( recnoField, recNum, recno )

      av.ShowMsg("Populating Recno Attribute of "+atheme.AsString+"...")

      proceed = av.SetStatus((recNum / numRecs) * 100)

      if ( proceed.Not ) then

        av.ClearStatus

        av.ShowMsg( "Stopped" )

        return nil

      end

    end

    currentFtab.SetEditable(FALSE)

    av.SetStatus(100)

    av.ClearMsg

    av.ClearStatus

  end

end


Project.AddToolMenu
Adds a ToolMenu (pull-down tool) to a DocGUI

Source Code

Description:   Adds a ToolMenu to the docGUI chosen from the list of DocGUIs in the current project.  The user is prompted for the number of tools to place in the ToolMenu, and the ToolMenu is added to the ToolBar.  Use the Customize Dialog Box to specify the properties of the component tools and to move the ToolMenu to the desired location.

Name:    Project.AddToolMenu

Requires:

Self:

Returns:

FileName:  addtmenu.ave


Project.AddToolMenu (Sample Script)
'Adds a ToolMenu (pull-down tool) to a DocGUI

aToolMenu = ToolMenu.Make

controls = aToolMenu.GetControls

numTools = MsgBox.Input("Enter number of Tools in ToolMenu:",

  "ToolMenu", "5")

if ((numTools = NIL) OR (numTools.IsNumber.Not)) then

  return nil

else

  numTools = numTools.AsNumber

end

for each i in 1 .. numTools

  controls.Add(Tool.Make)

end

theGUIList = av.GetProject.GetGUIs

theGUI = MsgBox.Choice( theGUIList, "Choose DocGUI for ToolMenu:",

  "Add ToolMenu")

if (theGUI <> nil) then

  ok = MsgBox.YesNo("Are you sure you want to change:"+NL+

    theGUI.GetName+"?", "Add ToolMenu", TRUE )

  if (ok) then

    av.GetProject.FindGUI(theGUI.GetName).GetToolBar.Add(aToolMenu, -1)

  end

end


View.AddXYCoordToFTab
Adds X and Y coordinates of features to Attribute Table

Source Code

Description:   Adds two new fields, named X-coord and Y-coord, to the table of the first active theme in the TOC and fills the respective fields with the X,Y coordinates of the selected points (or all points if no selection is defined) in a point theme.  If instead the active theme is a polygon theme, then the X,Y coordinates of the polygon centroid are calculated. If the theme is projected, the output coordinates will also be projected.

Name:   View.AddXYCoordToFTab

Requires:  An active point or polygon theme. This script does minimal error checking and assumes that there is an active theme.

Self:

Returns:

FileName:  addxycoo.ave


View.AddXYCoordToFTab (Sample Script)
'Adds X and Y coordinates of features to Attribute Table

theView = av.GetActiveDoc

'must be global to work in Calc exp below

_theProjection = theView.GetProjection

project_flag = _theProjection.IsNull.Not  'true if projected

theTheme = theView.GetActiveThemes.Get(0)

'Check if point or polygon theme

if (((theTheme.GetSrcName.GetSubName = "point") or

    (theTheme.GetSrcName.GetSubName = "polygon")).Not) then

  MsgBox.Info("Active theme must be polygon or point theme","")

  return nil

end

'get the theme table and current edit state

theFTab = theTheme.GetFTab

theFields = theFTab.GetFields

edit_state = theFTab.IsEditable

'make sure table is editable and that fields can be added

if (theFtab.CanEdit) then

  theFTab.SetEditable(true)

  if ((theFTab.CanAddFields).Not) then

    MsgBox.Info("Can't add fields to the table."+NL+"Check write permission.",

    "Can't add X,Y coordinates")

    return nil

  end

else

  MsgBox.Info("Can't modify the feature table."+NL+

  "Check write permission.","Can't add X,Y coordinates")

  return nil

end

'Check if fields named "X-coord" and Y-coord" exist

x_exists = (theFTab.FindField("X-coord") = NIL).Not

y_exists = (theFtab.FindField("Y-coord") = NIL).Not

if (x_exists or y_exists) then

  if (MsgBox.YesNo("Overwrite existing fields?",

  "X-coord, Y-coord fields already exist", false)) then

    'if ok to overwrite, delete the fields as they may not be defined

    'as required by this script (eg., created from another script).

    if (x_exists) then

      theFTab.RemoveFields({theFTab.FindField("X-coord")})

    end

    if (y_exists) then

      theFTab.RemoveFields({theFTab.FindField("Y-coord")})

    end

  else

    return nil

  end  'if (MsgBox...)

end  'if

x = Field.Make ("X-coord",#FIELD_DECIMAL,18,5)

y = Field.Make ("Y-coord",#FIELD_DECIMAL,18,5)

theFTab.AddFields({x,y})

'Get point coordinates or polygon centroid coordinates

if (theTheme.GetSrcName.GetSubName = "point") then

  if (project_flag) then

    'Projection defined

    theFTab.Calculate("[Shape].ReturnProjected(_theProjection).GetX", x)

    theFTab.Calculate("[Shape].ReturnProjected(_theProjection).GetY", y)

  else

    'No projection defined

    theFTab.Calculate("[Shape].GetX", x)

    theFTab.Calculate("[Shape].GetY", y)

  end  'if

else  'polygon case

  if (project_flag) then

    theFTab.Calculate("[Shape].ReturnCenter.ReturnProjected(_theProjection).GetX", x)

    theFTab.Calculate("[Shape].ReturnCenter.ReturnProjected(_theProjection).GetY", y)

  else

    theFTab.Calculate("[Shape].ReturnCenter.GetX", x)

    theFTab.Calculate("[Shape].ReturnCenter.GetY", y)

  end  ' if

end

'Return editing state to pre-script running state

theFTab.SetEditable(edit_state)


ConnectToAIServer
Connects to an ARC/INFO Server

Source Code

Description:   Connects to an ARC/INFO server application by opening and reading the server information from an ARC/INFO connection file.  An ArcView RPCClient is created.

Remote Procedure Calls (RPC) allow client applications to initiate procedures in a server application across a network.  UNIX RPC servers are uniquely identified by a hostname (the name of the machine the server application is running on), a server id, and a version number.  An RPC client application uses this information to establish the RPC connection.

ARC/INFO servers may be created using the Arc Macro Language (AML) function [IACCONNECT], which can be used to create a connection file containing the hostname, server id, and version number.  The file is opened and read, creating an ArcView RPCClient using the information contained therein.

Name:    ConnectToAIServer

Requires:  Workstation ARC/INFO. This script will run under UNIX only.

Self:

Returns:

FileName:  aiconnct.ave


ConnectToAIServer (Sample Script)
'Connects to an ARC/INFO Server

'Get the ARC/INFO connection file

connectFile = FileDialog.Show( "*", "Select AI connection file:", "Connect")

if (connectFile = nil) then

  return nil

end

'Read the file

theFile = LineFile.Make( connectFile, #FILE_PERM_READ )

infoList = theFile.ReadElt.AsList

theFile.Close

'Check for file validity

if (infoList.count <> 3) then

  MsgBox.Error("Invalid ARC/INFO connection file.", "")

  return nil

end

'Get the server information from the file

hostname = infoList.Get(0)     ' the hostname of the machine

id       = infoList.Get(1)     ' the server id number

version  = infoList.Get(2)     ' the version number

'Use the information to connect

_aClient = RPCClient.Make( hostname, ("0x"+ID).AsNumber, version.AsNumber)

'Check and report if any problems

if ( _aClient.HasError ) then

  MsgBox.Info( _aClient.GetErrorMsg, "Error" )

  return nil

end

av.ShowMsg( "Connected to server at"++hostname++id++version)


View.AddShape
Creates GraphicShapes and Symbols for a View

Source Code

Description:   A graphic circle, 2 boxes, a line and point are created and added to the graphics list of the current view.  Different symbols are assigned to each graphic object.

Each View has a GraphicList which is a list of all the Graphics associated with a View.  The graphics on the GraphicList are persistent and will be saved with a View.  New graphics you create are added to the GraphicList.

To create graphic objects, the mathematical shape must be created first. GraphicShapes can then be created from these objects and added to the GraphicList.  Each graphic has a Symbol which determines how it will be drawn on the screen.  Subclasses of Symbol represent specific styles, such as solid fills, dashed lines, etc.

Name:    View.AddShape

Requires:  A view must be the active document.

Self:

Returns:

FileName:  addgshp.ave


View.AddShape  (Sample Script)
'Creates GraphicShapes and Symbols for a View

theView = av.GetActiveDoc

theDisplay = theView.GetDisplay

' Get the GraphicList for the View...

theGraphics = theView.GetGraphics

' Return the extent (the enclosing rect) of the View and the center

' point.  These locations and other calculated dimensions will be used

' to construct shapes...

theExtent = theDisplay.ReturnExtent

theCenter = theExtent.ReturnCenter

theLowerLeft = theExtent.ReturnOrigin

w = (theExtent.GetWidth) * 0.25

h = (theExtent.GetHeight) * 0.25

theUpperRight = (theLowerLeft.Getx + theExtent.GetWidth)@

  (theLowerLeft.Gety + theExtent.GetHeight)

offsetPoint = Point.Make(h, w)

' Create a hatched yellow circle with red outline centered in the display...

aCircle = Circle.Make(theCenter, w)

gCircle = GraphicShape.Make(aCircle)

aSymbol = VectorFill.Make

aSymbol.SetStyle(#VECTORFILL_STYLE_HATCH)

aSymbol.SetAngle(45)

aSymbol.SetColor(Color.GetYellow)

aSymbol.SetOLColor(Color.GetRed)

gCircle.SetSymbol(aSymbol)

theGraphics.Add(gCircle)

' Create a red and blue boxes with a green outline...

aBox = Rect.Make(theCenter, offsetPoint)

gBox = GraphicShape.Make(aBox)

aSymbol = RasterFill.Make

aSymbol.SetOLColor(Color.GetGreen)

aSymbol.setcolor(Color.GetBlue)

gBox.SetSymbol(aSymbol)

' Create a second box by cloning the first...

gBox2 = gBox.Clone

gBox2.GetSymbol.SetColor(Color.GetRed)

gBox2.SetOrigin(theLowerLeft)

theGraphics.Add(gBox)

theGraphics.Add(gBox2)

' Create a magenta line running diagonally from LL to UR....

aLine = Line.Make(theLowerLeft, theUpperRight)

gLine = GraphicShape.Make(aLine)

theSymbol = gLine.Getsymbol

thesymbol.SetSize(2)

theSymbol.SetColor(Color.GetMagenta)

theGraphics.Add(gLine)

' Create a red point at the center of the display...

aPoint = Point.Make(theCenter.GetX, theCenter.GetY)

gPoint = GraphicShape.Make(aPoint)

theSymbol = gPoint.GetSymbol

theSymbol.SetColor(Color.GetRed)

theSymbol.SetSize(8)

theGraphics.Add(gPoint)


View.AddTheme
Adds a theme to a view

Source Code

Description:   A sample script which demonstrates the procedure used to add a new theme to the current view, create a unique classification legend, and draw it.  In this example an ARC/INFO coverage containing polygon topology is added to the view.  A legend of unique classifications is created based on the 'Name' field found in the coverage feature attribute table and the theme is drawn.

Name:    View.AddTheme

Requires:  This is a sample script 'hardwired' for a specific data source. Edit the script to change source name and classification field.

Self:

Returns:

FileName:  addtheme.ave


View.AddTheme (Sample Script)
'Adds a theme to a view

' Create the SourceName...

theSrc = SrcName.Make("c:\full\path\to\data polygon")

' Use the SourceName to make a theme...

aTheme = Theme.Make(theSrc)

' Add the theme to the view...

theView.AddTheme(aTheme)

' Set a new name for the theme...

aTheme.SetName("California")

' Get the theme legend and create a unique classification...

leg = aTheme.GetLegend

theTable = aTheme.GetFTab

theField = theTable.FindField("name").GetAlias   ' the fieldname to classify on

leg.Unique(aTheme,theField)

' Update the legend in the view TOC...

aTheme.InvalidateLegend

' Draw the theme...

aTheme.SetVisible(true)


AIServer
Making and using an ArcView to ARC/INFO RPC connection

Source Code

Description:   Extablishes an RPC connection with an ARC/INFO server.  The ArcView client submits a task to ARC/INFO to perform the UNION of two polygon themes and then displays the results as a third theme in the view.

Remote Procedure Calls (RPC) allow client applications to initiate procedures in a server application across a network.  UNIX RPC servers are uniquely identified by a hostname (the name of the machine the server application is running on), a server id, and a version number.  An RPC client application uses this information to establish the RPC connection.

In this example the ArcView client will request that the ARC/INFO server perform a union of two polygon themes. ARC/INFO will inform the client when the service has been completed, the resulting data source will be added to the View as a new Theme.

Before running this script, you must establish the ARC/INFO server.  Do this by picking any machine on the network to run Arc, then type at the Arc prompt this command:

     Arc: &type [IACOPEN]

     Host: rhino Program no: 40000000 Version no: 1

     0

The hostname, program number, and version number are used by the ArcView clent to establish a connection.  If the second line is not zero, there has been an error in establishing the ARC/INFO server.  To shutdown the ARC/INFO server type:

     Arc: &type [IACCLOSE]

Important Notes: These AML functions are available at ARC/INFO Rev. 7.0 and newer.  This script should be run with a View as the active document and the View should have two active polygon themes which will be Union'ed.

Name:    AIServer

Requires:  RC/INFO Rev. 7.0 and a view with two active polygon themes. The hostname, program number, and version number of the ARC/INFO client may need to be changed. This script will run under UNIX only.

Self:

Returns:

FileName:  aiserver.ave


AIServer (Sample Script)
'Making and using an ArcView to ARC/INFO RPC connection

' The first thing to do is create an ArcView client which can talk to

' the existing ARC/INFO server. ArcView can have many clients all active

' at once. There is a many-to-one relationship from clients to servers.

' The information used to establish the connection is returned by the

' ARC/INFO [IACOPEN] AML function.

'

client = RPCClient.Make("rhino", 0x40000000, 1)

if (client.HasError) then

  MsgBox.Info(client.GetErrorMsg, "RPC Client Error")

  exit

end

outCov = FileDialog.Put("outcov".AsFileName, "*",

  "What is the UNION Output Coverage?")

if (outCov = Nil) then

  exit

end

theView = av.GetActiveDoc

tList   = theView.GetActiveThemes

'

' The following statement builds the UNION command. The logic assumes that

' there are two active polygon themes. You can insure that this is always

' the case by adding an update script which disables the custom button when

' two active polygon themes don't exist in the active view.

'

aiCommand =

  "UNION" ++

  tList.Get(0).GetSrcName.GetFileName.GetFullName ++

  tList.Get(1).GetSrcName.GetFileName.GetFullName ++

  outCov.GetFullName ++

  "# NOJOIN"

MsgBox.Report(aiCommand, "ARC/INFO Command String")

' This statement sends the UNION command to the waiting ARC/INFO server.

' The server returns control immediately to the client (this script), then

' starts to do the command. The client can track the progress

' of the command using the string which will be returned from the server.

' This string is called the job id.

'

' In more detail, triggering procedure number 1 on the ARC/INFO server

' starts a new job and returns its JobID. Triggering procedure number 2

' queries the ARC/INFO server for the status of an existing job specifed

' by a previously returned JobID.

'

JobID = client.Execute(1, aiCommand, String)

'

' Now the UNION command has started. We wait until it is finished. We can

' tell when its finished by triggering procedure number 2 and examining

' the return value. If that value is the string "DONE", then the command

' has finished.

'

busyWaiting = true

while (busyWaiting)

  if (client.Execute(2, JobID, String).Extract(0) = "DONE") then

    busyWaiting = false

  else

    System.Execute("sleep 5")

  end

end

client.Close

' The UNION command is finished and we have a new coverage whose name

' is specified by outCov. Lets turn that coverage into a new theme.

'

srcString = outCov.GetFullName++"polygon"

newSource = SrcName.Make(srcString)

newTheme    = Theme.Make(newSource)

' And add the new theme to the view and draw it.

'

theView.AddTheme(newTheme)

newTheme.SetActive(true)

newTheme.SetVisible(true)


Graphics.Align
Aligns selected graphics in a layout or view

Source Code

Description:   This script can be called from another script to align the selected graphic objects in a view or layout. The primary advantage of using this script over the alignment menu provided with ArcView's interface is that it allows the programmer to control the alignment, not the end user. The script can be called with the av.Run request.

Graphic points are handled as a special case. Currently, the origin of a point is its center, assumming the point has no extent. However a point does have a height and width, which is compensated for.

Name:    Graphics.Align

Requires:  A view or layout must be the active document. Assumes that some graphic elements are selected, however nothing will happen if zero or one element is selected.

Self:  "bottom", "top", "left", or "right".

Returns:

FileName:  aligngra.ave


Graphics.Align (Sample Script)
'Aligns selected graphics in a layout or view

alignment = SELF                        'Get alignment option passed in

theDoc = av.GetActiveDoc                'Must be View or Layout

gra_list = theDoc.GetGraphics           'Get Graphic list

extent = gra_list.ReturnSelectedExtent  'Get spatial extent of selected graphics

'Align BOTTOM

if (alignment = "bottom") then

  bottom = extent.GetBottom             'Get rectangle bottom coordinate

  for each g in gra_list.GetSelected    'Loop thru all selected graphics

    g.Invalidate                        'Erase current graphic location

    orig = g.GetOrigin                  'Get origin

    x = orig.GetX                       'Get x-coord of origin point

    if (g.GetShape.Is(Point)) then      'Handle points as special case

      half_height = 0.5 * g.GetBounds.GetHeight

      g.SetOrigin (x@(bottom + half_height))

    else

      'All other shapes

      g.SetOrigin (x@bottom)            'Set origin to new x,y coordinates

    end  'if

    g.Invalidate                        'Redraw graphic at new location

  end   'for

  return "bottom"                       'Return "bottom" to calling script

'Align TOP

elseif (alignment = "top") then

  top = extent.GetTop

  for each g in gra_list.GetSelected

    g.Invalidate

    height = g.GetBounds.GetHeight

    orig = g.GetOrigin

    x = orig.GetX

    if (g.GetShape.Is(Point)) then

      half_height = 0.5 * height

      g.SetOrigin (x@(top - half_height))

    else

      'y coordinate equals top - height of graphic object

      g.SetOrigin (x@(top - height))

    end  'if

    g.Invalidate

  end  'for

  return "top"

'Align LEFT

elseif (alignment = "left") then

  left = extent.GetLeft

  for each g in gra_list.GetSelected

    g.Invalidate

    orig = g.GetOrigin

    y = orig.GetY

    if (g.GetShape.Is(Point)) then

      half_width = 0.5 * g.GetBounds.GetWidth

      g.SetOrigin ((left + half_width)@y)

    else

      g.SetOrigin (left@y)

    end  'if

    g.Invalidate

  end  'for

  return "left"

'Align RIGHT

elseif (alignment = "right") then

  'Align RIGHT

  right = extent.GetRight

  for each g in gra_list.GetSelected

    g.Invalidate

    width = g.GetBounds.GetWidth

    orig = g.GetOrigin

    y = Orig.GetY

    if (g.GetShape.Is(Point)) then

      half_width = 0.5 * width

      g.SetOrigin ((right - half_width)@y)

    else

      'x coordinate equals right - width of graphic object

      g.SetOrigin ((right - width)@y)

    end  'if

    g.Invalidate

  end  'for

  return "right"

'Bad argument passed in

else

  return NIL

end  'if


Header.ScriptHeader
Defines the content of the script header

Source Code

Description:   Begin every sample script with the script header given below. The script header contains the following elements:

*Name is the script name this script should have when it is loaded into ArcView. The name should have an identifying prefix. (e.g. DocGUI.AddToolMenu, Project.DeleteEmbeddedScript, View.FindNearestFeatureTool) If this script runs only on an Apply event, include the suffix "Tool". If this script is an Update script, include the suffix "Update".

*Title identifies the purpose of the script and appears in the contents page. The script title maybe up to 50 characters long and may contain spaces to separate words. The title should accurately identify the utility of the script. The title must begin with a verb in third person tense and describe what the script does. For example,

+ Adds a ToolMenu to the current ToolBar.

+ Deletes the embedded script from the project.

+ Finds the nearest feature in the active theme to a user specified point.

You must specify the title.

*Topics names the categories under which this script will be listed in the contents page. You may specify more than one topic if necessary, but in most cases, the script should fall under one category. The topics that were used to compile the samples that came with ArcView 3.0 are:

TOPIC         Relates to these areas in ArcView

Project   = Project objects and Project files

Script    = Scripts and SEds

View      = View document

Image     = Image Themes

GeoData   = Data conversion and manipulation

Analysis  = Spatial and statistical analysis

Legend    = Creating or changing legends

Chart     = Chart document

Layout    = Layout document

Table     = Table document

Graphic   = Graphics and symbols

GUI       = DocGUIs and Virtual Documents

Geocod    = Geocoding

DBT       = DataBase Themes

Network   = Network Analyst Extension

Spatial   = Spatial Analyst Extension

Misc      = Other

*Description provides a complete discussion of what this script does and how it works. Describe any special algorithms or techniques employed by this script. You must provide some description of the script. The description can be any length.

*Requires details the conditions necessary for this script to run.

+ State the kind of document that must be active for this script to run, for example, the active document must be a view.

+ State the kind of event this script should be associated with if there are special conditions, for example, this script must be associated with an Apply event.

+ Identify required extensions, for example, you must load the spatial analyst before compiling this script.

+ Identify any required data or files or system conditions, and so forth.

+ Name update scripts or other scripts that should be used with this script.

If the script requires no special preconditions, you can leave this section blank. This section can be any length.

*Self describes the Self object required by this script. Scripts called by other scripts use the Self object to pass values. Scripts associated with events use the Self object to identify the object that initiated that event (e.g. an update script on a control, an open script on a document). If the script does not use the Self object, then leave this section empty. This section can be any length.

*Returns identifies the value returned by the script. Scripts that are called by other scripts may return a value to the calling script. Describe any return value in this section identifying its class and meaning. If the script does not return a value to a calling script, then leave this section empty. This section can be any length.

There are some general formatting limitations if you intend to use the Microsoft word template in the samples/other directory called scriptlib.dot. All headings must have their first letter capitalized, be followed by a colon, and then two spaces. The latter even if there is no text for the heading. The dash/hyphen character is reserved, so do not use it in the text. The dash/hyphen character is used to indicate that line wrapping is to be turned off, this is useful if you have a script of list within your description, requires, self, or returns sections.

Name:    Header.ScriptHeader

Requires:

Self:

Returns:

FileName:  avheader.ave


Header.ScriptHeader (Sample Script)
'Defines the content of the script header

' Name:

'

' Title:

'

' Topics:

'

' Description:

'

' Requires:

'

' Self:

'

' Returns:


View.BivariateLegend
Creates a bivariate legend for a theme

Source Code

Description:   Creates a bivariate legend for the topmost active theme in your view.  Specifically, it creates a new legend based on the you selecting two data attributes, the classification type for each attribute and the number of classes for the new legend.  You will then be prompted to choose a color ramp for the first attribute and then a size range for the second symbol.  The size range is the diameter of a point symbol, the width of a line symbol, and the width of the hatchures in the fill symbol.

Name:    View.BivariateLegend

Requires:  The active document must be a view, with an active feature theme.

Self:

Returns:

FileName:  bivarleg.ave


View.BivariateLegend (Sample Script)
'Creates a bivariate legend for a theme

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

theLegend = theTheme.GetLegend

theFTab = theTheme.GetFtab

ShapeType = theFTab.GetShapeClass.GetClassName

' Check to see if this may be a long process

nx = theTheme.GetFTab.GetNumRecords

if ((nx > 1500) and (nx < 5000)) then

  KeepGoing = Msgbox.YesNo ("Do you wish to continue?","This procedure may take several minutes",true)

  if (KeepGoing.not) then exit end

elseif (nx > 5000) then

  KeepGoing = Msgbox.YesNo ("This may take a long time. Do you wish to continue?","Time for coffee or maybe lunch",true)

  if (KeepGoing.not) then exit end

end

'Get a List of Fieldnames that can be used

ValidFields = {}

for each f in theFTab.GetFields

  if ( f.IsTypeNumber ) then

    ValidFields.Add(f)

  end

end

if (ValidFields.Count < 2) then

  Msgbox.Info("Could not continue because there are less than two valid fields","Will not work for"++theTHeme.GetName)

  exit

end

'Get the first field to be used in bivariate legend and ensure it is indexed

FirstField = Msgbox.Choice(ValidFields, "Choose first attribute:","Bivariate Map - Color Field")

if (FirstField = nil) then exit end

if (theFtab.IsFieldIndexed(FirstField) = false) then

  theFtab.CreateIndex(FirstField)

end

FirstFieldName = FirstField.GetAlias

'Get information about how to treat FirstField

cltype = {"Natural Breaks","Quantile","Equal Interval","Equal Area"}

ClassTypeFirstField = msgbox.ChoiceAsString(cltype,"Choose a classification type","Bivariate Map: "+FirstFieldName)

if (ClassTypeFirstField = nil) then exit end

'Get the second field to be used in bivariate legend and ensure it is indexed

ValidFields.RemoveObj(FirstField)

SecondField = Msgbox.Choice(ValidFields, "Choose second attribute:","Bivariate Map - Size Field")

if (SecondField = nil) then exit end

if (theFtab.IsFieldIndexed(SecondField) = false) then

  theFtab.CreateIndex(SecondField)

end

SecondFieldName = SecondField.GetName

ClassTypeSecondField = msgbox.ChoiceAsString(cltype,"Choose a classification type","Bivariate Map: "+SecondFieldName)

if (ClassTypeSecondField = nil) then exit end

numcl = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}

NumClasses = Msgbox.ChoiceAsString(numcl, "Choose number of classes:","Bivariate Map")

if (NumClasses = nil) then exit end

'Make Dummy legend to get initial size symbolization scheme

SecondDummyLegend = theTheme.GetLegend.Clone

if (ShapeType = "Polygon") then

  SecondDummyLegend.SetLegendType(#LEGEND_TYPE_COLOR)

else

  SecondDummyLegend.SetLegendType(#LEGEND_TYPE_SYMBOL)

end

theLegend.SetLegendType(#LEGEND_TYPE_COLOR)

if (ClassTypeFirstField = "Natural Breaks") then

  theLegend.Natural(theTheme,FirstField.GetName,NumClasses)

elseif (ClassTypeFirstField = "Quantile") then

  theLegend.Quantile(theTheme,FirstField.GetName,NumClasses)

elseif(ClassTypeFirstField = "Equal Interval") then

  theLegend.Interval(theTheme,FirstField.GetName,NumClasses)

elseif(ClassTypeFirstField = "Equal Area") then

  theLegend.Area(theTheme,FirstField.GetName,NumClasses)

end

if (ClassTypeSecondField = "Natural Breaks") then

  SecondDummyLegend.Natural(theTheme,SecondField.GetName,NumClasses)

elseif (ClassTypeSecondField = "Quantile") then

  SecondDummyLegend.Quantile(theTheme,SecondField.GetName,NumClasses)

elseif(ClassTypeSecondField = "Equal Interval") then

  SecondDummyLegend.Interval(theTheme,SecondField.GetName,NumClasses)

elseif(ClassTypeSecondField = "Equal Area") then

  SecondDummyLegend.Area(theTheme,SecondField.GetName,NumClasses)

end

theLegend.SetLegendType(#LEGEND_TYPE_COLOR)

'Get ColorRamp for colors

ColorRampsODB = ODB.Open("$AVHOME/etc/gc_ramps.odb".AsFileName)

RampNames = {}

for each r in 0..(ColorRampsODB.Count - 1)

  RampNames.Add(ColorRampsODB.Get(r).GetName)

end

ColorRampName = Msgbox.ChoiceAsString(RampNames,"Choose a color ramp for"++FirstFieldName,"Bivariate Mapper")

if (ColorRampName = nil) then

  exit

else

  rampidx = RampNames.Find(ColorRampName)

  ColorRamp = ColorRampsODB.Get(rampidx)

end

'Get Sizerange for Sizes

if ((ShapeType = "PolyLine") or (ShapeType = "Polygon")) then

  DefVals = {"0.2", "4"}

else

  DefVals = {"4","12"}

end

DefLabels = {"Minimum Size","Maximum Size"}

SizeRange = Msgbox.MultiInput("Enter values for size range for "+SecondFieldName,"Bivariate Mapper - Size Range",DefLabels,DefVals)

MinSize = SizeRange.Get(0)

MaxSize = SizeRange.Get(1)

if ((MinSize = nil) or (MinSize.IsNumber.Not) or (MaxSize = nil) or (MaxSize.IsNumber.Not)) then exit end

SmallSize = MinSize.AsNumber

LargeSize = MaxSize.AsNumber

if (SmallSize > LargeSize) then

  x = SmallSize.Clone

  SmallSize = LargeSize.Clone

  LargeSize = x

end

theTheme.SetName ( FirstFieldName++"|"++SecondFieldName )

Colors = theLegend.GetSymbols

Colors.RampSavedColors(ColorRamp)

'Do sizes independently and then individually apply them

Sizes = SecondDummyLegend.GetSymbols

SecondSizes = {}

if (ShapeType = "Polygon") then

  SecondSizes.Add(LargeSize)

  if (numClasses > 2) then

    theRange = LargeSize - SmallSize

    theInterval = theRange/NumClasses

    s = LargeSize - theInterval

    for each x in 0..(NumClasses -3)

      SecondSizes.Insert(s)

      s = s - theInterval

    end

  end

  SecondSizes.Insert(SmallSize)

  for each c in 0..(NumClasses - 1)

    newSym = VectorFill.Make

    newSym.SetStyle(#VECTORFILL_STYLE_HATCH)

    newSym.SetAngle(45)

    newSym.SetPenSize(SecondSizes.Get(c))

    oldSym = theLegend.GetSymbols.Get(c)

    oldFGColor = oldSym.GetColor

    newSym.SetBGColor(oldFGColor)

    newSym.SetWidth(5)

    newSym.SetHeight(5)

    theLegend.GetSymbols.Set(c,newSym)

    lb = theLegend.GetClassifications.Get(c).GetLabel

    l = SecondDummyLegend.GetClassifications.Get(c).GetLabel

    theLegend.GetClassifications.Get(c).SetLabel(lb++"|"++l)

  end

else ' Point, MultiPoint, or PolyLine

  Sizes.RampSizes(SmallSize, LargeSize)

  for each s in Sizes

    SecondSizes.Add(s.GetSize)

  end

  for each c in 0..(NumClasses - 1)

    s = SecondDummyLegend.GetSymbols.Get(c).GetSize

    theLegend.GetSymbols.Get(c).SetSize(s)

    lb = theLegend.GetClassifications.Get(c).GetLabel

    l = SecondDummyLegend.GetClassifications.Get(c).GetLabel

    theLegend.GetClassifications.Get(c).SetLabel(lb++"|"++l)

  end

end

theTheme.UpdateLegend


View.BivariateRegression
Performs Bivariate Regression and Makes Scatter Chart

Source Code

Description: This script, when executed from a button or menu item on the view GUI, will perform a bivariate regression analysis on the selected data of the active theme or all data in the active theme if no selection exists.  The result of this script is the coefficient of determination, or R squared.  Additionally the user may elect to make a scatterplot of the data.  Also of note in this script is that if there is a null value in the data set, that data record will not be analyzed, however, values of 0 or other dummy values will be included unless you screen for them.

Name: View.BivariateRegression

Requires:  A View must be the active document.  The view must contain at least one active theme. The following script can be used as an update script to enable the control which executes this script.

enabled = true

themeList = av.GetActiveDoc.GetActiveThemes

if ((themeList.count < 0) or (themeList.Get(0).Is(ITheme))) then

  enabled = false

end

Self.SetEnabled(Enabled)

Self:

Returns:

FileName: bvreg.ave


View.BivariateRegression (Sample Script)
'Performs Bivariate Regression and Makes Scatter Chart

'GET THE THEME, CHECK FOR SELECTION, GET INDEPENDENT AND DEPENDENT

'VARIABLE FIELDS

theView = av.GetActiveDoc

theFTheme = theView.GetActiveThemes.Get(0)

theFtab = theFtheme.GetFtab

flist = list.Make

for each f in theFtab.GetFields

  if (f.isTypeNumber = true) then

    flist.Add(f)

  end

end

if (flist.Count < 2) then

  exit

end

if (theFtab.GetSelection.Count = 0) then

  theFtab.GetSelection.SetAll

end

IV = Msgbox.Choice(flist,"Choose a field for your independent variable (X)",

  "Bivariate Regression")

flist.RemoveObj(IV)

DV = Msgbox.Choice(flist,"Choose a field for your dependent variable (Y)",

  "Bivariate Regression")

'GET THE MEANS OF EACH FOR THE INDEPENDENT AND DEPENDENT VARIABLE FIELDS

xsum = 0

ysum = 0

nn = 0

For each f in theFtab.GetSelection

  xret = (theFtab.ReturnValueNumber(IV,nn))

  yret = (theFtab.ReturnValueNumber(DV,nn))

  'Check for null values

  if ((xret.IsNull = true) or (yret.IsNull = true)) then

    Continue

  end

  xsum = xsum + xret

  ysum = ysum + yret

  nn = nn + 1

end

XBar = xsum / nn

YBar = ysum / nn

'GET THE a AND b VALUES FOR THE REGRESSION EQUATION

c1 = 0

c2 = 0

rn = 1

For each ff in theFtab.GetSelection

  xret = (theFtab.ReturnValueNumber(IV,ff))

  yret = (theFtab.ReturnValueNumber(DV,ff))

  'Check for Null Values

  if ((xret.IsNull = true) or (yret.IsNull = true)) then

    Continue

  end

  newc1 = ((xret - XBar)*(yret - YBar))

  newc2 = ((xret - XBar)*(xret - Xbar))

  c1 = c1 + newc1

  c2 = c2 + newc2

end

b = c1 / c2

a = YBar - (b*XBar)

'CALCULATE THE REGRESSION (explained) SUM OF SQUARED DEVIATIONS (RSS) &

'CALCULATE THE TOTAL SUM OF SQUARED DEVIATIONS (TSS)

RSS = 0

TSS = 0

For each s in theFTab.GetSelection

  yret = (theFtab.ReturnValueNumber(DV,s))

  xret = (theFtab.ReturnValueNumber(IV,s))

  'Check for null values

  if ((xret.IsNull = true) or (yret.IsNull = true)) then

    Continue

  end

  RSSi = ((a + (b * xret)) - YBar) * ((a + (b * xret)) - YBar)

  TSSi = (yret - YBar) * (yret - YBar)

  RSS = RSS + RSSi

  TSS = TSS + TSSi

end

'Calculate R-squared

Rs = RSS / TSS

'Report Results

Msgbox.Report("R-squared = "+Rs.AsString+nl+"a = "+a.AsString+nl+"b = "+b.AsString,"Bivariate Regression Results")

'MAKE SCATTERPLOT FROM DATA

if (Msgbox.YesNo("Would you like to create a scatterplot of your data?",

  "Bivariate Regression",true) = true) then

  'Make chart

  sp = Chart.make(theFtab,{IV,DV})

  sp.GetChartDisplay.SetType(#CHARTDISPLAY_XYSCATTER)

  sp.GetChartDisplay.SetStyle(#CHARTDISPLAY_VIEW_SIDEBYSIDE)

  sp.GetChartDisplay.SetMark(#CHARTDISPLAY_MARK_PLUS)

  'Add Ammenities to Chart

  sp.GetTitle.SetName("Scatter Plot for "+theFTheme.GetName.AsString++

    ": R-square = "+Rs.AsString)

  sp.GetXAxis.SetLabelVisible(true)

  sp.getYAxis.SetLabelVisible(true)

  sp.SetSeriesLabel(1,"a = "+a.AsString+", b = "+b.AsString)

  sp.GetChartLegend.SetLocation(#CHARTDISPLAY_LOC_RIGHT)

  'Get the Chart's windows, open it, and activate it.

  spwin = sp.GetWin

  spwin.open

  spwin.Activate

end


View.CalculateFeatureGeometry
Calculates feature geometry values

Source Code

Description:   Calculates area and perimeter for polygon themes and length for line themes. If the View has been projected the calculations are in projected meters. Otherwise the calculations are in 'native' map units. Modify the script to provide calculation in the current report units of the View. The script processes the list of active themes to calculate area and perimeter, or length, depending on the theme type.

The script will add the fields: Area and Perimeter to polygon themes, Length to line themes if they do not exist. If the fields exist their values will be recalculated. Rerun the script if you change the projection of the view.

Name:    View.CalculateFeatureGeometry

Requires:  A View with at least one active theme.  You must have write access to the active theme(s).

Self:

Returns:

FileName:  calcapl.ave


View.CalculateFeatureGeometry (Sample Script)
'Calculates feature geometry values

' Get the view and it's projection if any.

theView = av.GetActiveDoc

thePrj = theView.GetProjection

if (thePrj.IsNull) then

  hasPrj = false

else

  hasPrj = true

end

' Get the list of active themes. if there aren't any, let the user know

' and exit.

theActivethemeList = theView.GetActivethemes

if (theActivethemeList.Count = 0) then

  MsgBox.Error("No active themes.","")

  Exit

end

' Loop through the list of active themes. if you can't edit the theme

' inform the user.

For Each thetheme in theActivethemeList

  theFTab = thetheme.GetFTab

  if (theFTab.CanEdit.Not) then

    MsgBox.Info("Cannot edit table for theme:"++thetheme.AsString,"")

    Continue

  end

  ' Make the FTAB editable, and find out which type of feature it is.

  theFTab.SetEditable(TRUE)

  theType = theFTab.FindField("shape").GetType

  if (theType = #FIELD_SHAPEPOLY) then

    ' if it's polygonal, check for the existence of the fields "Area" and

    ' Perimeter. If they do not exist, create them.

    if (theFTab.FindField("Area") = nil) then

      theAreaField = Field.Make("Area",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({theAreaField})

    else

      ok = MsgBox.YesNo("Update Area?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      theAreaField = theFTab.FindField("Area")

    end

    if (theFTab.FindField("Perimeter") = nil) then

      thePerimeterField = Field.Make("Perimeter",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({thePerimeterField})

    else

      ok = MsgBox.YesNo("Update Perimeter?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      thePerimeterField = theFTab.FindField("Perimeter")

    end

    ' Loop through the FTAB and find the projected area and perimeter of each

    ' shape and set the field values appropriately.

    theShape = theFTab.ReturnValue(theFTab.FindField("shape"),0)

    For Each rec in theFTab

      theFTab.QueryShape(rec,thePrj,theShape)

      theArea = theShape.ReturnArea

      thePerimeter = theShape.ReturnLength

      theFTab.SetValue(theAreaField,rec,theArea)

      theFTab.SetValue(thePerimeterField,rec,thePerimeter)

    end

  elseif (theType = #FIELD_SHAPELINE) then

    ' if the data source is linear, check for the existence of the

    ' field "Length". If it doesn't exist, create it.

    if (theFTab.FindField("Length") = nil) then

      theLengthField = Field.Make("Length",#FIELD_DOUBLE,16,3)

      theFTab.AddFields({theLengthField})

    else

      ok = MsgBox.YesNo("Update Length?", "Calculate", true)

      if (ok.Not) then

        continue

      end

      theLengthField = theFTab.FindField("Length")

    end

    ' Loop through the FTAB and find the projected length of each shape

    ' and set the field values appropriately.

    theShape = theFTab.ReturnValue(theFTab.FindField("shape"),0)

    For Each rec in theFTab

      theFTab.QueryShape(rec,thePrj,theShape)

      theLength = theShape.ReturnLength

      theFTab.SetValue(theLengthField,rec,theLength)

    end

  end

  theFTab.SetEditable(FALSE)

end


View.CalculateDistance
Calculates distances from points in one theme to points in another

Source Code

Description:  This script will prompt you for two point themes in the active view.  The first is the point theme containing the selected points that you wish to calculate the distance FROM. The second is the point theme containing points that you wish to calculate the distance TO.

You will also be prompted for an identifying field in the FROM theme.  The value of this field will be used to name to distance field in the TO theme.

A distance field will be added to the TO theme for each point selected in the FROM theme.  This distance field will be populated with the distance between the selected From point and the To point.

If the view is projected, the distance will be returned in distance units.

Name:    View.CalculateDistance

Requires:  This script should be attached to a button in the view GUI.  To prepare to use this script:

    1. Add to your view two point themes.

    2. Determine which is to be theFromTheme and which is to be theToTheme.

    3. Determine which item is to be the identifying field.  This is most likely

       a field that contains a key number or name.

    4. Create a selected set of points in theFromTheme, if you like.

    5. Attach this script to a button inthe Veiw GUI, if you like.

Self:

Returns:

FileName:  calcdist.ave


View.CalculateDistance (Sample Script)
'Calculates distances from points in one theme to points in another

theThemeList = av.GetActiveDoc.GetThemes.Clone

thePrj = av.GetActiveDoc.GetProjection

'  Use these lines to hard-code the input parameters...

'theFromFtab = av.GetProject.FindDoc("View1").FindTheme("FromTheme").GETFTab

'theFromIDField = theFromFtab.FindField("Bnmb")

'theToTheme = av.GetProject.FindDoc("View1").FindTheme("ToTheme")

'theToFtab = theToTheme.GetFTab

'  Use these lines to prompt the user for input parameters...

theFromTheme = (MsgBox.List(theThemeList,"to calculate the distance FROM.","Please select a theme..."))

if (theFromTheme = nil) then exit end

theFromFtab = theFromTheme.GetFTab

theThemeList.RemoveObj(theFromTheme)

theToTheme = (MsgBox.List(theThemeList,"to calculate the distance TO.","Please select a theme..."))

if (theToTheme = nil) then exit end

theToFtab = theToTheme.GetFTab

theFromIDField = MsgBox.ListAsString(theFromFtab.GetFields,"containing the point identifier.","Please select a field...")

  if (theFromIDField = nil) then

    exit

  end

theFromShapeField = theFromFTab.FindField("Shape")

theToShapeField = theToFtab.FindField("Shape")

theToFtab.SetEditable(true)

for each f in theFromFtab.GetSelection

  theFromIDValue = theFromFtab.ReturnValueString(theFromIDField,f)

  theNewFieldName = "DistTo"+theFromIDValue

' If a distance field doesn't exist, add it...

  if (theToFtab.FindField(theNewFieldName) = nil) then

'   Choose the field size commensurate with the view's projection.

    if (thePrj.IsNil) then

      theDistanceField = field.make(theNewFieldName,#field_decimal,8,4)

    else

      theDistanceField = field.make(theNewFieldName,#field_decimal,8,2)

    end

    theToFtab.addfields({theDistanceField})

' If a distance field does exist, clear it...

  else

    theToFtab.Calculate("0",theToFtab.FindField(theNewFieldName))

    theDistanceField = theToFTab.FindField(theNewFieldName)

  end

' Get the point location you are measuring FROM.

' If the view is projected, get the the point location in projected units.

  theFromShape = theFromFTab.ReturnValue(theFromShapeField,f)

  if (thePrj.IsNull.Not) then

    theFromShape = theFromShape.ReturnProjected(thePrj)

  end

  for each t in theToFtab

    '  Get the point location you are measuring TO.

    '  Get it in projected units, if the view is projected.

    theToShape = theToFTab.ReturnValue(theToFtab.FindField("Shape"),t)

      if (thePrj.IsNull.Not) then

        theToShape = theToShape.ReturnProjected(thePrj)

      end

    ' Calculate the distance between the two points.

    ' Add the value to the output (TO) branch table.

    theDistance = theFromShape.Distance(theToShape)

    theToFtab.SetValue(theDistanceField,t,theDistance)

  end

end

theToFtab.SetEditable(false)

av.ShowMsg("Distance calculation complete")


View.CreateMenuForThemes
Creates a menu item with active themes as choices

Source Code

Description:   An example script which uses the list of currently active themes to create a new menu on the menu bar which contains choices for all the currently active themes.

In this example a new menu is added immediately before the Help menu, and contains the choices collected using theView.GetActiveThemes.  Several Properties for each control are specified.

Name:    View.CreateMenuForThemes

Requires:  A view as the active document

Self:

Returns:

FileName:  creatmnu.ave


View.CreateMenuForThemes (Sample Script)
'Creates a menu item with active themes as choices

theView = av.GetActiveDoc

' Get the list of active themes to be used for choices...

choiceList = theView.GetActiveThemes

if (choiceList.Count < 1) then

  MsgBox.Error("No active themes in view.  Unable to create menu.","")

  exit

end

' Find the position before the Help menu.  The Help menu is

' the last menu on the right...

newPositionIndex = av.GetActiveGui.GetMenuBar.GetControls.Count - 2

' Add the new menu and set the label property...

thePMenu = av.GetActiveGui.GetMenuBar.New( newPositionIndex )

thePMenu.SetLabel("&ActiveThemes")

' For each active theme, add a choice and set control properties...

index = -1

for each c in choiceList

  theChoice = thePmenu.New( index )

  theChoice.SetLabel( c.GetName )

  theChoice.SetClick( "Script 1" )

  theChoice.SetHelp( "Do something with"++c.GetName )

  theChoice.SetTag( c.GetName )

  index = index + 1

end


View.CreateStandardizedAddress
Standardizes address attributes in reference theme and save as shapefile

Source Code

Description:  Creates a shapefile that contains attributes of a selected street theme and additional standardized address fields from unparsed addresses.

Expects that the original attribute table of a street theme has house number ranges in four separate fields but the rest of the address information, such as prefix direction, prefix type, street name, street type, and suffix direction are not in separate fields. Since ArcView geocoding requires all address attributes stored in separate fields, you can use this script to standardize an unparsed address field and save the theme with the standardized result into a new theme.  The script parses a selected field that you want to standardize against a MatchKey and add the standardized results to the new shapefile.

Modify the field names of standardized address fields accordingly if you want to use some other names or avoid conflicts with existing field names in the selected street theme.

Name:  View.CreateStandardizedAddress

Requires:  An active View document containing an active theme with address information in the attribute table.

Self:

Returns:

FileName:  stanshpe.ave


View.CreateStandardizedAddress (Sample Script)
'Standardizes address attributes in reference theme and save as shapefile

theTable = av.GetActiveDoc

fnOutFile = FileDialog.Put(av.GetProject.MakeFileName("table", "dbf"),

  "*.dbf","Address Standardizer")

if (fnOutFile = nil) then

  exit

end

theVTab   = theTable.GetVTab

theFields = theVTab.GetFields

' Get the join field so the new table can be joined back to the original.

' This should contain unique values...

joinField = MsgBox.ChoiceAsString( theFields, "Choose join field:",

  "Address Standardizer" )

if (joinField = Nil) then

  exit

end

' Get the address field to parse...

addressField = MsgBox.ChoiceAsString( theFields, "Choose address field:",

  "Address Standardizer" )

if (addressField = Nil) then

  exit

end

outTable = VTab.MakeNew(fnOutFile, dBASE)

if (outTable.HasError) then

  MsgBox.Error("Error creating output Table.","")

  exit

end

' Create fields to hold information parsed from original table...

outFields = List.Make

outFields.Add(joinField.Clone)

outFields.Add(Field.Make("PRE_DIR", #FIELD_CHAR, 2, 2))    ' prefix direction

outFields.Add(Field.Make("PRE_TYPE", #FIELD_CHAR, 4, 4))   ' prefix type

outFields.Add(Field.Make("STREET_NAM", #FIELD_CHAR, 26, 26)) ' street name

outFields.Add(Field.Make("STREET_TYP", #FIELD_CHAR, 4, 4))   ' street type

outFields.Add(Field.Make("SUF_DIR", #FIELD_CHAR, 2, 2))    ' suffix direction

outTable.AddFields(outFields)

' Create the match key used against the original addresses...

key = MatchKey.Make("us_addr.stn")

outJN = outTable.FindField(joinField.GetName)

outPD = outTable.FindField("PRE_DIR")

outPT = outTable.FindField("PRE_TYPE")

outSN = outTable.FindField("STREET_NAM")

outST = outTable.FindField("STREET_TYP")

outSD = outTable.FindField("SUF_DIR")

numrecs = theVTab.GetNumRecords    ' only for status bar

av.ShowStopButton

' Read and standardize each address...

for each rec in theVTab

   proceed = av.setStatus((rec / numrecs) * 100)

   if (proceed.Not) then

     av.ShowMsg("Stopped")

     av.ClearStatus

     exit

   end

   ' Add a new empty record to output Table...

   recOutput = outTable.AddRecord

   ' Read record from original Table...

   address = theVTab.ReturnValue(addressField, rec)

   ' Set the address in the MatchKey with a dummy house number...

   key.SetKey("1"++address)

   ' Populate records in the output Table...

   outTable.SetValue(outJN, recOutput, theVTab.ReturnValue(joinField, rec))

   outTable.SetValue(outPD, recOutput, key.GetValue("PD"))

   outTable.SetValue(outPT, recOutput, key.GetValue("PT"))

   outTable.SetValue(outSN, recOutput, key.GetValue("SN"))

   outTable.SetValue(outST, recOutput, key.GetValue("ST"))

   outTable.SetValue(outSD, recOutput, key.GetValue("SD"))

end

av.ClearStatus

' Join new Table to original...

theVTab.Join(joinField, outTable, outJN)


Legend.CustomizeRamps
Customize Color Ramps and Schemes

Source Code

Description:   This script alters some files that are stored in your arcview/etc directory!  To avoid accidently wrecking your setup, copy all files with a .odb to a safe place.

Specifically, this script alters the files that contain the color ramps and color schemes that are used by the legend editor.  You can change the names of the color ramps, change parts of the color ramps, add color ramps, or delete color ramps.

Name:    Legend.CustomizeRamps

Requires:  Some options require nothing but others will require that a layout be the active document and possibly a specified number of graphics with particular symbols be present or that a graphic be selected.  Specifically:

Add a Ramp:  Requires a layout be the active document and that thirteen (13) rectangles be present.  The sequence the rectangles were made will determine the order that the color of their symbols are placed in your ramp, i.e., the first rectangle you make should have the first color you want to see in the ramp.  You cannot have any number of colors in a color ramp other than thirteen: it will not work in the legend editor.

Add a Scheme:  Requires a layout to be the active document and that at least one graphic be selected.

Change a chip in an existing ramp or scheme.  Expects a layout to be the active document and a single graphic is to be selected with its color being what you want to change the nth chip of a specified ramp or scheme.

Self:

Returns:

FileName:  custleg.ave


Legend.CustomizeRamps  (Sample Script)
'Customize Color Ramps and Schemes

Options = {"Change Name of a Color Ramp",

           "Change Name of a Color Scheme",

           "Add a Color Ramp",

           "Add a Color Scheme",

           "Delete a Color Ramp",

           "Delete a Color Scheme",

           "Change a chip in existing color ramp",

           "Change a chip in existing color scheme",

           "Add to a Color Scheme"}

Option = Msgbox.ChoiceAsString(Options,"Choose:","Legend Editor Customizer")

if (Option = nil) then exit end

'Change Name of Color Ramp

if (Option = "Change Name of a Color Ramp") then

  ramps = ODB.Open("$AVHOME/etc/gc_ramps.odb".AsFileName)

  rampNames = {}

  for each r in (0..(ramps.Count - 1))

    rampNames.Add(ramps.Get(r).GetName)

  end

  toChange = Msgbox.ChoiceAsString(rampNames,"Which ramp's name do you want to change","Change the name of a Color Ramp")

  if (toChange = nil) then exit end

  NewName = Msgbox.Input("Enter the new name:","Change the name of a Color Ramp","New Name")

  Rampidx = rampNames.Find(toChange)

  ramps.Get(Rampidx).SetName(NewName)

  ramps.Commit

'Change Name of a Color Scheme

elseif (Option = "Change Name of a Color Scheme") then

  schemes = ODB.Open("$AVHOME/etc/nc_ramps.odb".AsFileName)

  schemeNames = {}

  for each r in (0..(schemes.Count - 1))

    schemeNames.Add(schemes.Get(r).GetName)

  end

  toChange = Msgbox.ChoiceAsString(schemeNames,"Which ramp's name do you want to change","Change the name of a Color Scheme")

  if (toChange = nil) then exit end

  NewName = Msgbox.Input("Enter the new name:","Change the name of a Color Ramp","New Name")

  Schemeidx = schemeNames.Find(toChange)

  schemes.Get(Schemeidx).SetName(NewName)

  schemes.Commit

'Add a Color Ramp

elseif (Option = "Add a Color Ramp") then

  theLayout = av.GetActiveDoc

  if (theLayout.Is(Layout).Not) then

    Msgbox.Error("Requires that the active document be a layout","")

    exit

  end

  theGraphics = theLayout.GetGraphics

  if (theGraphics.Count < 13) then

    Msgbox.Error("Requires that there be at least 13 graphics in this layout","")

    exit

  end

  NewRamp = SymbolList.Make

  for each g in 0..12

     NewRamp.Add(theGraphics.Get(g).GetSymbol.GetColor)

  end

  NewRampName = Msgbox.Input("Enter a Name for your new ramp:","Add a Color Ramp","New Name")

  NewRamp.SetName(NewRampName)

  ramps = ODB.Open("$AVHOME/etc/gc_ramps.odb".AsFileName)

  ramps.Add(NewRamp)

  ramps.Commit

'Add a Color Scheme

elseif (Option = "Add a Color Scheme") then

  theLayout = av.GetActiveDoc

  if (theLayout.Is(Layout).Not) then

    Msgbox.Error("Requires that the active document be a layout","")

    exit

  end

  theGraphics = theLayout.GetGraphics

  NewScheme = SymbolList.Make

  for each g in theLayout.GetGraphics

    NewScheme.Add(g.GetSymbol.GetColor)

  end

  NewSchemeName = Msgbox.Input("Enter a Name for your new scheme:","Add a Color Scheme","New Name")

  NewScheme.SetName(NewSchemeName)

  schemes = ODB.Open("$AVHOME/etc/nc_ramps.odb".AsFileName)

  schemes.Add(NewScheme)

  schemes.Commit

'Delete a Color Ramp

elseif (Option = "Delete a Color Ramp") then

  ramps = ODB.Open("$AVHOME/etc/gc_ramps.odb".AsFileName)

  rampNames = {}

  clrRamps = {}

  for each r in (0..(ramps.Count - 1))

    rampNames.Add(ramps.Get(r).GetName)

    clrRamps.Add(ramps.Get(r))

  end

  toDelete = Msgbox.ChoiceAsString(rampNames,"Which ramp do you want to delete","Delete a Color Ramp")

  if (toDelete = nil) then exit end

  ramps.commit

  newRamps = ODB.Make("$AVHOME/etc/gc_ramps.odb".AsFileName)

  Rampidx = rampNames.Find(toDelete)

  rampNames.Remove(Rampidx)

  clrRamps.Remove(Rampidx)

  for each nr in (0..(rampNames.Count - 1))

    theRamp = SymbolList.FromList(clrRamps.Get(nr))

    theRamp.SetName(rampNames.Get(nr))

    newRamps.Add(theRamp)

  end

  newRamps.Commit

'Delete a Color Scheme

elseif (Option = "Delete a Color Scheme") then

  schemes = ODB.Open("$AVHOME/etc/nc_ramps.odb".AsFileName)

  schemeNames = {}

  theSchemes = {}

  for each s in (0..(schemes.count - 1))

    schemeNames.Add(schemes.Get(s).GetName)

    theSchemes.Add(schemes.Get(s))

  end

  toDelete = Msgbox.ChoiceAsString(schemeNames,"Which scheme do you want to delete","Delete a Color Scheme")

  if (toDelete = nil) then exit end

  schemes.Commit

  newSchemes = ODB.Make("$AVHOME/etc/nc_ramps.odb".AsFileName)

  Schemeidx = schemeNames.Find(toDelete)

  SchemeNames.Remove(Schemeidx)

  theSchemes.Remove(Schemeidx)

  for each ns in (0..(schemeNames.Count - 1))

    theScheme = SymbolList.FromList(theSchemes.Get(ns))

    theScheme.SetName(SchemeNames.Get(ns))

    newSchemes.Add(theScheme)

  end

  newSchemes.Commit

'Change a chip in existing color ramp

elseif (Option = "Change a chip in existing color ramp") then

  theLayout = av.GetActiveDoc

  if (theLayout.Is(Layout).Not) then

    Msgbox.Error("Requires that the active document be a layout","")

    exit

  end

  theGraphics = theLayout.GetGraphics

  if (theGraphics.GetSelected.Count <> 1) then

    Msgbox.Error("Requires that there be only one graphic selected","")

    exit

  end

  NewColor = theGraphics.GetSelected.Get(0).GetSymbol.GetColor

  ramps = ODB.Open("$AVHOME/etc/gc_ramps.odb".AsFileName)

  rampNames = {}

  for each r in (0..(ramps.Count - 1))

    rampNames.Add(ramps.Get(r).GetName)

  end

  toChange = Msgbox.ChoiceAsString(rampNames,"Which ramp has a color you want to change:","Change a color in a Color Ramp")

  if (toChange = nil) then exit end

  chipidx = Msgbox.ChoiceAsString({1,2,3,4,5,6,7,8,9,10,11,12,13},"Which color do you want to change:","Change a color in a Color Ramp")

  if (chipidx = nil) then exit end

  Rampidx = rampNames.Find(toChange)

  ramps.Get(Rampidx).Set((chipidx - 1),NewColor)

  ramps.Commit

'Change a chip in existing color scheme

elseif (Option = "Change a chip in existing color scheme") then

  theLayout = av.GetActiveDoc

  if (theLayout.Is(Layout).Not) then

    Msgbox.Error("Requires that the active document be a layout","")

    exit

  end

  theGraphics = theLayout.GetGraphics

  if (theGraphics.GetSelected.Count <> 1) then

    Msgbox.Error("Requires that there be only one graphic selected","")

    exit

  end

  NewColor = theGraphics.GetSelected.Get(0).GetSymbol.GetColor

  ramps = ODB.Open("$AVHOME/etc/nc_ramps.odb".AsFileName)

  rampNames = {}

  for each r in (0..(ramps.Count - 1))

    rampNames.Add(ramps.Get(r).GetName)

  end

  toChange = Msgbox.ChoiceAsString(rampNames,"Which ramp has a color you want to change:","Change a color in a Color Scheme")

  if (toChange = nil) then exit end

  Rampidx = rampNames.Find(toChange)

  rcount = ramps.Get(Rampidx).Count

  chips = {}

  for each nn in (0..(rcount - 1))

    chips.Add(nn + 1)

  end

  chipidx = Msgbox.ChoiceAsString(chips,"Which color do you want to change:","Change a color in a Color Ramp")

  if (chipidx = nil) then exit end

  ramps.Get(Rampidx).Set((chipidx - 1),NewColor)

  ramps.Commit

'Add to a Color Scheme

elseif (Option = "Add to a Color Scheme") then

  theLayout = av.GetActiveDoc

  if (theLayout.Is(Layout).Not) then

    Msgbox.Error("Requires that the active document be a layout","")

    exit

  end

  theGraphics = theLayout.GetGraphics

  if (theGraphics.GetSelected.Count < 1) then

    Msgbox.Error("Requires that there be at least one graphic be selected","")

    exit

  end

  NewColors = {}

  for each gg in theGraphics.GetSelected

    NewColors.Add( gg.GetSymbol.GetColor )

  end

  ramps = ODB.Open("$AVHOME/etc/nc_ramps.odb".AsFileName)

  rampNames = {}

  for each r in (0..(ramps.Count - 1))

    rampNames.Add(ramps.Get(r).GetName)

  end

  toChange = Msgbox.ChoiceAsString(rampNames,"Which scheme do you want to add to:","Add colors to a color scheme")

  if (toChange = nil) then exit end

  Rampidx = rampNames.Find(toChange)

  for each c in NewColors

    ramps.Get(Rampidx).Add(c)

  end

  ramps.Commit

end


View.ConvertPolylineToPolygon
Converts polylines in the active theme to polygons

Source Code

Description: Converts selected polylines to polygons to create a new shapefile.  If no features are currently selected all polylines will be processed.

If the polylines are not closed, i.e., the first and last points are not identical, the user may choose to automatically close all polylines. This option will move the last point to the first point.

Multi-part shapes are not currently supported.

Name: View.ConvertPolylineToPolygon

Requires: A View must be the active document, a polyline theme must be the active theme. Use the following as an update script:

Update script for control...

v = av.GetActiveDoc

t = v.GetActiveThemes.Get(0)

SELF.SetEnabled((t <> NIL) AND
  (t.GetFTab.FindField("shape").GetType = #FIELD_SHAPELINE))

Self:

Returns:

FileName: cvtplply.ave


View.ConvertPolylineToPolygon (Sample Script)
'Converts polylines in the active theme to polygons

theView    = av.GetActiveDoc

thmThemeIn = theView.GetActiveThemes.Get(0)

' 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

fnOutput.SetExtension("shp")

ftbOutput = FTab.MakeNew( fnOutput, POLYGON )

ftbOutput.AddFields({Field.Make("ID", #FIELD_LONG, 8, 0)})

' Polylines must close to create polygons. The choices presented to the

' Gentle User are to automatically 'snap' the last polyline vertex to

' the first, or to skip any unclosed polylines...

bForceClosure = MsgBox.YesNoCancel("Force closure on all features?",

  "Convert Polyline to Polygon","TRUE")

if (bForceClosure = NIL) then exit end

' Use selected shapes if there are any, otherwise iterate

' through the entire FTab...

if (thmThemeIn.GetFTab.GetSelection.Count > 0) then

  colToProcess = thmThemeIn.GetFTab.GetSelection

  nRecs = colToProcess.Count

else

  colToProcess = thmThemeIn.GetFTab

  nRecs = colToProcess.GetNumRecords

end

nCount = 0

nRecAdded = 0

fldShapeIn  = thmThemeIn.GetFTab.FindField("shape")

fldShapeOut = ftbOutput.FindField("shape")

fldIDOut    = ftbOutput.FindField("id")

for each r in colToProcess

  nCount = nCount + 1

  av.SetStatus((nCount / nRecs) * 100)

  shpIn = thmThemeIn.GetFTab.ReturnValue(fldShapeIn,r)

  if (shpIn.AsList.Count > 1) then

    MsgBox.Warning("Unable to convert multi-part shape at record"++

      nCount.AsString,"Convert Polyline to Polygon")

    continue

  end

  lstPoints = shpIn.AsList.Get(0)

  ptStart = lstPoints.Get(0)

  ptEnd   = lstPoints.Get((lstPoints.Count - 1))

  if (ptStart <> ptEnd) then

    if (bForceClosure) then  ' Force the close...

      lstPoints.Add(Point.Make(ptStart.GetX, ptStart.GetY))

                                            ' modified 9/97

    else

      continue

    end

  end

  shpNew = Polygon.Make({lstPoints})

  shpNew.Clean

  nRecNew = ftbOutput.AddRecord

  ftbOutput.SetValue(fldShapeOut,nRecNew,shpNew)

  ftbOutput.SetValue(fldIDOut,nRecNew,nCount)

  nRecAdded = nRecAdded + 1

end

av.SetStatus(100)

if (nRecAdded = 0) then

  MsgBox.Info("No closed polylines found. Unable to convert"++

    "polylines to polygons.", "Convert Polyline to Polygon")

  exit

else

  MsgBox.Info(nRecAdded.AsString++"shapes converted.",

    "Convert Polyline to Polygon")

end

if (MsgBox.YesNo("Add shapefile as theme to a view?",

  "Convert Polyline to Polygon", 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("<New View>")

vweAddTo = MsgBox.ListAsString( lstViews,"Add Theme to:",

  "Convert Polyline to Polygon" )

' Get the specified view, make the theme, and add it...

if (vweAddTo <> nil) then

  if (vweAddTo = "<New View>") then

    vweAddTo = View.Make

    vweAddTo.GetWin.Open

  end

  thmNew = FTheme.Make( ftbOutput )

  vweAddTo.AddTheme( thmNew )

  vweAddTo.GetWin.Activate

end


View.ConvertPolygonToPolyLine
Converts polygons in active theme to polylines

Source Code

Description:   Converts selected polygons to polylines to create a new shapefile.  If no features are currently selected all polygons will be processed.

Multi part shapes are not currently supported.

Name:    View.ConvertPolygonToPolyLine

Requires:  a View must be the active document, a polygon theme must be the active theme. Use the following as an update script:

Update script for control...

v = av.GetActiveDoc

t = v.GetActiveThemes.Get(0)

SELF.SetEnabled((t <> NIL) AND

  (t.GetFTab.FindField("shape").GetType = #FIELD_SHAPEPOLY))

Self:

Returns:

FileName:  cvtplypl.ave


View.ConvertPolygonToPolyLine  (Sample Script)
'Converts polygons in active theme to polylines

theView    = av.GetActiveDoc

thmThemeIn = theView.GetActiveThemes.Get(0)

' 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

fnOutput.SetExtension("shp")

ftbOutput = FTab.MakeNew( fnOutput, POLYLINE )

ftbOutput.AddFields({Field.Make("ID", #FIELD_LONG, 8, 0)})

' Use selected shapes if there are any, otherwise iterate

' through the entire FTab...

if (thmThemeIn.GetFTab.GetSelection.Count > 0) then

  colToProcess = thmThemeIn.GetFTab.GetSelection

  nRecs = colToProcess.Count

else

  colToProcess = thmThemeIn.GetFTab

  nRecs = colToProcess.GetNumRecords

end

nCount = 0

nRecsAdded = 0

fldShapeIn  = thmThemeIn.GetFTab.FindField("shape")

fldShapeOut = ftbOutput.FindField("shape")

fldIDOut    = ftbOutput.FindField("id")

for each r in colToProcess

  nCount = nCount + 1

  av.SetStatus((nCount / nRecs) * 100)

  shpIn = thmThemeIn.GetFTab.ReturnValue(fldShapeIn,r)

  if (shpIn.AsList.Count > 1) then

    MsgBox.Warning("Unable to convert multi-part shape at record"++

      nCount.AsString,"Convert Polyline to Polygon")

    continue

  end

  shpNew = Polyline.Make({shpIn.AsList.Get(0)})

  nRecNew = ftbOutput.AddRecord

  ftbOutput.SetValue(fldShapeOut,nRecNew,shpNew)

  ftbOutput.SetValue(fldIDOut,nRecNew,nCount)

  nRecsAdded = nRecsAdded + 1

end

av.SetStatus(100)

if (nRecsAdded = 0) then

  MsgBox.Error("Unable to convert polygons to polylines.",

  "Convert Polygon to Polyline")

  exit

else

  MsgBox.Info(nRecsAdded.AsString++"shapes converted.",

    "Convert Polyline to Polygon")

end

if (MsgBox.YesNo("Add shapefile as theme to a view?",

  "Convert Polygon to Polyline", 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("<New View>")

vweAddTo = MsgBox.ListAsString( lstViews,"Add Theme to:",

  "Convert Polyline to Polygon" )

' Get the specified view, make the theme, and add it...

if (vweAddTo <> nil) then

  if (vweAddTo = "<New View>") then

    vweAddTo = View.Make

    vweAddTo.GetWin.Open

  end

  thmNew = FTheme.Make( ftbOutput )

  vweAddTo.AddTheme( thmNew )

  vweAddTo.GetWin.Activate

end


DDECreateSpreadsheet
Use DDE to create a Spreadsheet in Excel

Source Code

Description:   Creates a DDE Conversation with Excel and populates an Excel spreadsheet using information from the specified fields for the selected rows in a Table.

DDE (Microsoft's Dynamic Data Exchange) provides a mechanism for transferring data between applications.  A DDE exchange is called a conversation.  In a conversation the client application initiates requests and the server application responds.  The conversation is identified by the server name and a topic name.  The server name is usually the name of the application itself.  Most applications support the system topic name.  The ArcView DDEClient can initiate one of several standard transactions; execute, request, and poke.

In this example the ArcView DDEClient establishes a conversation with an Excel server using the System topic.  The ArcView client uses Execute to create a new spreadsheet, Request to get information about the spreadsheet, and Poke to populate the spreadsheet with information from the selected rows using the contents of the specified fields.  Though this example uses Excel, other applications may have similar DDE functionality.

Name:    DDECreateSpreadsheet

Requires:  Windows only.  The active document must be a Table.

Self:

Returns:

FileName:  ddecress.ave


DDECreateSpreadsheet (Sample Script)
'Use DDE to create a Spreadsheet in Excel

theTable = av.GetActiveDoc

' Create the ArcView DDEClient.  This initiates the Excel conversation.

' Verify that there are no errors.

systemClient = DDEClient.Make( "Excel", "System")

if (systemClient.HasError) then

  MsgBox.error( systemClient.GetErrorMsg, "")

  return nil

end

' Create the new Excel worksheet

systemClient.Execute( "[NEW(1,0,FALSE)]")

' Get the name of the new worksheet.  Selection is an Excel item supported

' for the System topic.

selection = systemClient.Request( "Selection" )

spreadsheet = selection.Left( selection.IndexOf("!"))

' Ensure R1C1 format

systemClient.Execute( "[Workspace(,,TRUE)]" )

systemClient.Close

' Open a new conversation with the Excel spreadsheet as the topic

ssClient = ddeClient.Make( "Excel", spreadsheet )

' Get table information for later use

tableName = theTable.GetName

theVTab   = theTable.GetVTab

theFields = theVTab.GetFields

' Write the table name to the spreadsheet

row    = 1

column = 1

ssClient.Poke( "R"+row.AsString+"C"+column.AsString, tableName )

' Allow user to select fields of interest

fieldList = List.Make

while (true)

  aField = MsgBox.List( theFields, "Choose fields to write to Excel:"+NL+

    "(Cancel to stop)", "Excel")

  if (aField = Nil) then

     break

  end

  fieldList.Add( aField )

end

' Write chosen field names to the spreadsheet

row    = 2

column = 0

for each f in fieldList

  column = column + 1

  ssClient.Poke( "R"+row.AsString+"C"+column.AsString, f.GetName )

end

' Write the values for selected features to spreadsheet

for each rec in theVTab.GetSelection

  row    = row + 1

  column = 0

  for each f in fieldList

    column = column + 1

    if (f.IsTypeShape) then

      dataString = "Shape"

    else

       dataString = theVTab.ReturnValueString( f, rec)

    end

    ssClient.Poke( "R"+row.AsString+"C"+column.AsString, dataString )

  end

end

ssClient.Close


GetDDESystemItems
Demonstrates a DDE conversation with Excel

Source Code

Description:   A demonstration script which initiates a DDE conversation with Excel through Excel's System topic, and retrieves a list of valid items within the topic.  Information about the chosen item is returned.

DDE (Microsoft's Dynamic Data Exchange) provides a mechanism for transferring data between applications.  A DDE exchange is called a conversation.  In a conversation the client application initiates requests and the server application responds.  The conversation is identified by the server name and a topic name.  The server name is usually the name of the application itself.  Most applications support the system topic name.  The ArcView DDEClient can initiate one of several standard transactions; execute, request, and poke.

In this example the ArcView DDEClient establishes a connection with an Excel server.  The ArcView DDEClient uses Request to return a list of valid items for the System topic, and uses the chosen item in another Request to get additional information.

Name:    GetDDESystemItems

Requires:  Windows only.  Other applications that support DDE and a similar item to Excel's SysItems can be substituted by editing the script and changing the parameters for the DDE server name, DDE topic name, and the item.

Self:

Returns:

FileName:  ddesysit.ave


GetDDESystemItems (Sample Script)
'Demonstrates a DDE conversation with Excel

' Excel-specific parameters:

'

' "Excel" is the server name.

' "System" is the topic name.

' "SysItems" is one of the valid items in the Syste topic which

'     returns other valid items.

' Create the ArcView DDE client and check for problems

sysClient = DDEClient.Make( "Excel", "System" )

if ( sysClient.HasError ) then

  MsgBox.Error( sysClient.GetErrorMsg, "")

  return nil

end

' Get the list of supported items from Excel

items = sysClient.Request( "SysItems" )

' Select an item to query

item = MsgBox.ListAsString( items.AsList, "Select an item to query",

  "Query Excel Items")

if (item = nil) then

  return nil

end

' Make another request to the server for info about the chosen item

result = sysClient.Request( item )

' Display the results

Msgbox.Report( result.Translate( " "+tab, nl+nl), item )

sysClient.Close


Script.ReturnValueFromDict
Returns value from selected key in a dictionary

Source Code

Description:   Builds a list containing the keys from a dictionary, prompts the user to select one of the keys from the list, and returns the corresponding object from the dictionary.  Nil is returned if the user clicks Cancel or if an error is encountered.  The prompt string, title and sort are optional.

Usage: anObj = av.Run("DictionarySelect", {aDict, aPrompt, aTitle, true})

Name:    Script.ReturnValueFromDict

Requires:

Self:

   (0) - A dictionary

   (1) - A prompt String for the message box (optional)

   (2) - A title String for the message box ( optional)

   (3) - Boolean; true means sort the list of dictionary keys (optional)

Returns:

FileName:  dictsel.ave


Script.ReturnValueFromDict (Sample Script)
'Returns value from selected key in a dictionary

'  Make sure we got a valid list...

if (Self.Is(List).not) then

  Msgbox.Error("Argument is not a list.","")

  return(Nil)

end

' Count list elements....

if (Self.Count <> 4) then

  MsgBox.Error("Invalid number of List elements.","")

  return(Nil)

end

'  Make sure we got a loaded dictionary to choose from...

if (Self.Get(0).Is(Dictionary)) then

  theDict = Self.Get(0)

else

  MsgBox.Error("Invalid dictionary.","")

  return(nil)

end

if (theDict.Count < 1) then

  MsgBox.Error("Dictionary is empty.","")

  return(Nil)

end

'  Set default prompt and title if needed...

if (Self.Get(1).Is(String)) then

  thePrompt = Self.Get(1)

else

  thePrompt = ""

end

if (Self.Get(2).Is(String)) then

  theTitle = Self.Get(2)

else

  theTitle = ""

end

'  Build the choice list, and sort if necessary.

theList = theDict.ReturnKeys

if (Self.Get(3).Is(Boolean)) then

  if (Self.Get(3)) then

    theList.Sort(true)

  end

end

'  Get the user's choice, and retrieve the object from the dictionary...

theKey = Msgbox.ListAsString(theList, thePrompt, theTitle)

if (theKey = Nil) then

  return(Nil)

else

  theChoice = theDict.Get(theKey)

  return(theChoice)

end


View.CleanShape
Cleans and exports shapes of themes

Source Code

Description: Cleans the shapes of the active themes & exports to a new shapefile.

A symptom that your polygon shapefiles are "dirty" is if they shade the entire view window ("bleed") when you zoom in. However, dirty shapefiles will also produce odd effects with overlay requests, area calculations, spatial joins, etc.

This script is similar to the script used by Convert to Shapefile; however, this script runs slower because it takes time to clean each shape.

Name: View.CleanShape

Requires: The active document must be a view, with at least one active theme.

Self:

Returns:

FileName: expclean.ave


View.CleanShape (Sample Script)
'Cleans and exports shapes of themes.

theView = av.GetActiveDoc

for each t in theView.GetActiveThemes

    if (t.Is( FTHEME ).Not) then

      if (t.CanExportToFTab.Not) then

        continue

      end

    end

    if (t.Is (FTHEME).Not) then

      def = av.GetProject.MakeFileName("theme", "shp")

      def = FileDialog.Put(def, "*.shp", "Convert " + t.getName)

      if (def = NIL) then

        return NIL

      end

      anFTab = t.ExportToFTab(def)

    else

      tbl = t.GetFTab

      attribVis = FALSE

      for each f in tbl.GetFields

      if ((f.IsVisible) and not (f.IsTypeShape)) then

        attribVis = TRUE

        break

      end

    end

    shapeVis = tbl.FindField("Shape").IsVisible

    if ((attribVis and shapeVis).Not) then

      continue

    end

    def = av.GetProject.MakeFileName("theme", "shp")

    def = FileDialog.Put(def, "*.shp", "Convert " + t.getName)

    if (def = NIL) then

      return nil

    end

    shpfld = (tbl.FindField("Shape"))

    if (shpfld.IsVisible.Not) then

      shpfld.SetVisible(shpfld.IsVisible.Not)

      WasNotVisible = TRUE

    else

      WasNotVisible =FALSE

    end

    anFTab = tbl.ExportClean(def, tbl.GetSelection.Count > 0)

    if (WasNotVisible) then

      shpfld.SetVisible(FALSE)

    end

  end

  if (MsgBox.YesNo("Add shapefile as theme to the view?","Convert to Shapefile",true).Not) then

    continue

  end

  'create a theme and add it to the View

  fthm = FTheme.Make(anFTab)

  theView.AddTheme(fthm)

  'bring the View to the front

  theView.GetWin.Activate

end


View.EditSBImageLegend
Edits the legend for single band image theme

Source Code

Description:   Alters the legend for a single band image theme.  The legend will be changed so that the background color is transparent, allowing the overlay of rectified single band images on top of other data without hiding the background themes.

The script will work on single band images only.  See the commented sections for assigning other colors.

Name:    View.EditSBImageLegend

Requires:  The active theme in the view must be a single band ITheme.

Self:

Returns:

FileName:  edtimglg.ave


View.EditSBImageLegend (Sample Script)
'Edits the legend for single band image theme

' Locate the image theme, legend, and color map.

theITheme = av.GetActiveDoc.GetActiveThemes.Get(0)

theLegend = theITheme.GetLegend

theColorMap  = theLegend.GetColorMap

' Exit if not a single band image.

If (theLegend.Is(SingleBandLegend).Not) then

  exit

end

' Get the current color of the index of interest and set it to be

' transparent.  Transparency is a property of a color, not a color in itself.

theColor = theColorMap.Get(3)

theColor.SetTransparent(true)

' To create a 'blue line' image, i.e. blue on white background, comment

' the previous section and uncomment the following line:

' theColorMap.Set(1, Color.GetBlue)

' Update and refresh

theITheme.InvalidateLegend

theITheme.Invalidate(true)


Script.UseSystemEditorForScripts
Edits Avenue scripts in system editor

Source Code

Description:   Uses a system editor specified by the user to edit the current Script.  The contents of the active SEd are copied to a temporary file and opened with the specified system editor.  After the editor has been closed the contents of the temporary file are copied back to the SEd and compiled. The request SetScratch is used to ensure removal of the file.

Name:    Script.UseSystemEditorForScripts

Requires:  UNIX only. The line specifying 'editorStartup' must be edited to start the editor of choice on your platform.  Currently this script will start the vi editor by opening an xterm on a UNIX platform.

Self:

Returns:

FileName:  edtscrpt.ave


Script.UseSystemEditorForScripts (Sample Script)
'Edits Avenue scripts in system editor

editorStartup = "xterm -e vi"

theScript = av.GetActiveDoc

' Create a temporary file and write out the current script...

tmpScript = av.GetProject.GetWorkDir.MakeTmp( "script", "xxx" )

f = LineFile.Make(tmpScript, #FILE_PERM_WRITE)

if (f = Nil) then

  MsgBox.Error("Cannot open file:"++tmpScript.GetName, "")

  exit

end

f.WriteElt(theScript.GetSource)

f.Close

' Now, execute the system editor of choice using the new file

' just written...

fileToEdit = tmpScript.GetFullName

System.Execute( editorStartup++fileToEdit )

' When we are done using the system editor load the file just edited

' back into the SEd...

theScript.SelectAll

theScript.CutSelected

f = TextFile.Make( tmpScript, #FILE_PERM_READ )

theScript.Insert(f.Read(f.GetSize))

f.SetScratch(true)

f.Close

' Recompile the script

theScript.Compile


Project.EncryptProject
Encrypts and saves current project

Source Code

Description:   Encrypts the current project and saves to specified output file.  Project encryption will encrypt and embed all scripts within the project.  This is an irreversible action which hides customizations from subsequent project users.

Name:    Project.EncryptProject

Requires:

Self:

Returns:

FileName:  encprj.ave


Project.EncryptProject (Sample Script)
'Encrypts and saves current project

theProject = av.GetProject

'Since encryption is irreversible, make sure user has option to save

'the project prior to encryption...

saveCurrent = MsgBox.YesNoCancel("Save current project prior to encryption?",

  "Save Current Project", true)

if (saveCurrent = nil) then

  exit

elseif (saveCurrent) then

  av.Run("Project.SaveAs", nil)

end

defaultName = theProject.GetFileName

if (defaultName = nil) then

  defaultName = FileName.Make("$HOME").MakeTmp("proj", "apr")

end

theFName = FileDialog.Put(defaultName, "*.apr", "Encrypt Project As")

if (nil <> theFName) then

  theProject.SetFileName(theFName)

  theProject.EncryptScripts

  theProject.Save

  av.ShowMsg( "Encrypted project saved as '"+theFName.GetBaseName+"'")

end


Project.Encrypt&EmbedScript
Encrypts and Embeds a script into current project

Source Code

Description:   Encrypts and embeds the current script.  Encrypted scripts prevent examination of the source code.  Once a script is encrypted it cannot be decrypted.  The Script Editor (SEd) for the script is removed from the current project.

Name:    Project.Encrypt&EmbedScript

Requires:  av.GetActiveDoc must return a SEd.

Self:

Returns:

FileName:  encscrpt.ave


Project.Encrypt&EmbedScript (Sample Script)
'Encrypts and Embeds a script into current project

theSEd = av.GetActiveDoc

if (Not (theSEd.IsCompiled)) then

  MsgBox.Error("Script:"++theSEd.GetName++"is not compiled.", "")

  exit

end

'Are you sure?  Encrypting removes source code!

sure = MsgBox.YesNo( "Are you sure you want to encrypt and embed"++

  theSEd.GetName+"?", "Encrypt Script", FALSE )

if (Not sure) then

  exit

end

'Encrypt and Embed the script

theScript = EncryptedScript.MakeFromScript( theSEd.GetScript )

theScript.SetName( theSEd.GetName )

av.GetProject.AddScript( theScript )

'Remove the script editor

av.GetProject.RemoveDoc( theSEd )

av.ShowMsg("Script:"++theScript.GetName++"encrypted and embedded")


EventTransform
Transforms dynamic segmentation events from one route theme to another

Source Code

Description:   Transforms dynseg events from one route theme to another. Creates a new .dbf file as the output containing new measures for events.

Name:    EventTransform

Requires:  The active view must contain the from and to themes.

Self:

Returns:

FileName:  envtrans.ave


EventTransform (Sample Script)
'Transforms dynamic segmentation events from one route theme to another

themeList = av.GetActiveDoc.GetThemes

fromTheme = MsgBox.Choice( themeList, "Choose FROM Event Theme:","Event Transform" )

if (fromTheme = nil) then exit end

fromSrcName = fromTheme.GetSrcName

' make sure we have a DynName object

if ( Not (fromSrcName.Is(DynName) ) ) then

  MsgBox.Error("FROM theme does not contain events.","")

  exit

end

toTheme = MsgBox.Choice( themeList, "Choose To Route Theme:",

  "Event Transform" )

if (toTheme = nil) then exit end

toSrcName  = toTheme.GetSrcName

toSubName  = toSrcName.GetSubName

' make sure the TO theme is a route theme

if ( not (toSubName.Left(6) = "route.") ) then

  MsgBox.Error("TO theme is not a route system.","")

  exit

end

searchTol = 0.0002   ' hardwire the search tolerance for now

' Prompt user for output file name

outFN = av.GetProject.MakeFileName( "table", "dbf" )

outFN = FileDialog.Put ( outFN,  "*.dbf",  "Save Transformed Events As:")

if (outFN = nil) then

  exit

end

' Part 2 - Do the Transform

fromFTab   = fromSrcName.GetRouteSys

fromRoute  = fromSrcName.GetRatRouteId

evtVTab    = fromSrcName.GetEventTable

evtRoute   = fromSrcName.GetEventRouteId

evtFMeas   = fromSrcName.GetFromField

evtTMeas   = fromSrcName.GetToField

evtFields  = evtVTab.GetFields

toVTab     = toTheme.GetFTab

' Create the output table and copy the fields from the original event table

out = VTab.MakeNew(outFN, DBase)

out.SetEditable( out.IsEditable )

if (not (out.CanEdit)) then

  MsgBox.Error("Unable to edit output VTab", "")

  exit

end

' Look in TO theme vtab for a field named "Route".  If one is there use it,

' else prompt for field.

toRoute = toVTab.FindField("Route")

if (toRoute = Nil) then

  fldChoice = MsgBox.ChoiceAsString(toVTab.GetFields,

    "Select Route field from TO theme:", "Event Transform")

  if (fldChoice <> nil) then

    toRoute = fldChoice

  else

    MsgBox.Error( "Event Route Field Not Selected.", "" )

    exit

  end

end

' set up outfile field names

outFields = List.Make

for each inEvtFld in evtFields

  if (inEvtFld.GetAlias <> "Shape") then

    ' check for route field and set def as in TO theme

    aNewField = inEvtFld.Clone

    if (inEvtFld.GetAlias = evtRoute.GetAlias) then

       aNewField.Copy(toRoute)

       aNewField.SetAlias(evtRoute.GetAlias)   ' but name it the same

    end

    outFields.Add( aNewField )

  end

end

out.AddFields(outFields)

' name these for conveniance

route = out.FindField(evtRoute.GetAlias)

fmeas = out.FindField(evtFMeas.GetAlias)

numRecs = evtVTab.GetNumRecords

' There are three types of Dynseg events that can be transformed -

' Points/Line/Continuous - determine the type of event and transform.

'

' LINE events...

if (fromSrcName.IsLinear) then

  tmeas = out.FindField(evtTMeas.GetAlias)

  for each i in evtVTab

    av.SetStatus((i/numRecs)*100)

    rte = evtVTab.ReturnValue(evtRoute,i)

    ' Search the reference route system for event's route.

    found = false

    for each k in fromFTab

      refrte = fromFTab.ReturnValue(fromRoute, k)

      if (rte = refrte) then

        found = true

        rteidx = k

        break

      end

    end

    if (found.Not) then

      continue

    end

    fpnts = fromFTab.ReturnRouteMeasure

      ( rteidx, evtVTab.ReturnValue(evtFMeas, i) )

    tpnts = fromFTab.ReturnRouteMeasure

      ( rteidx, evtVTab.ReturnValue(evtTMeas, i) )

    ' Make sure we have points to process.  If not, skip this event.

    if ((fpnts.Count = 0) or (tpnts.Count = 0)) then

      continue

    end

    fl = List.Make

    for each p in fpnts

      tmp = toVTab.ReturnLocation(p, searchTol)

      fl = fl + tmp

    end

    tl = List.Make

    for each p in tpnts

      tmp = toVTab.ReturnLocation(p, searchTol)

      tl = tl + tmp

    end

    for each frec in 0..(fl.Count - 2) by 2

      frouteval = toVTab.ReturnValue(toRoute, fl.Get(frec))

      for each trec in 0..(tl.Count - 2) by 2

        ' Only output a new event record if the from measure's route and

        ' to measure's route are the same.  Otherwise, the event cannot

        ' be transformed.

        if (frouteval = toVTab.ReturnValue( toRoute, tl.Get(trec) )) then

           if (out.CanAddRecord) then

              rec = out.AddRecord

           else

              MsgBox.Error("Unable to add record to output table.", "")

              exit

           end

           ' set all fields

           for each fld in outFields

             out.SetValue(fld, rec, evtVTab.ReturnValue

               ( evtVTab.findField( fld.GetAlias ), i ) )

           end

           ' set the fields that are getting transformed

           out.SetValue(route, rec, frouteval)

           out.SetValue(fmeas, rec, fl.Get(frec+1))

           out.SetValue(tmeas, rec, tl.Get(trec+1))

        end

      end ' for each trec

    end ' for each frec

  end ' for each input event

  av.ClearStatus

  exit

end ' if line events

' POINT events

if (fromSrcName.IsPoint) then

  for each i in evtVTab

    av.SetStatus((i/numRecs)*100)

    rte = evtVTab.ReturnValue(evtRoute,i)

    ' Search the reference route system for event's route.

    found = false

    for each k in fromFTab

      refrte = fromFTab.ReturnValue(fromRoute, k)

      if (rte = refrte) then

        found = true

        rteidx = k

        break

      end

    end

    if (found.Not) then

      continue

    end

    fpnts = fromFTab.ReturnRouteMeasure

      ( rteidx, evtVTab.ReturnValue(evtFMeas, i) )

    ' Make sure we have points to process.  If not, skip this event.

    if (fpnts.Count = 0) then

      continue

    end

    fl = List.Make

    for each p in fpnts

      tmp = toVTab.ReturnLocation(p, searchTol)

      fl = fl + tmp

    end

    for each frec in 0..(fl.Count - 2) by 2

      frouteval = toVTab.ReturnValue(toRoute, fl.Get(frec))

      if (out.CanAddRecord) then

         rec = out.AddRecord

      else

         MsgBox.Error("Unable to add record to output table.", "")

         exit

      end

      ' set all fields

      for each fld in outFields

        out.SetValue(fld, rec, evtVTab.ReturnValue

          ( evtVTab.findField(fld.GetAlias), i) )

      end

      ' set the fields that are getting transformed

      out.SetValue(route, rec, frouteval)

      out.SetValue(fmeas, rec, fl.Get(frec+1))

    end ' for each frec

  end ' for each input event

  av.ClearStatus

  exit

end ' if point events

' CONTINUOUS events

if (fromSrcName.IsContinuous) then

  MsgBox.Info("EventTransform for Continuous event not implemented.", "")

  exit

end ' if continuous events


Layout.Export
Exports a layout file suitable for printing

Source Code

Description:   This script shows how you can create a printable file from a layout. In this form, this script mimics the request, aLayout.Export, which displays a dialog window allowing the ArcView user to select a filename and output format. Although this script also contains a similar user interface, you can easily change the code to hard code filenames and output formats to suit your needs.

Name:    Layout.Export

Requires:  A layout must be the active document

Self:

Returns:

FileName:  exptlay.ave


Layout.Export (Sample Script)
'Exports a layout file suitable for printing

theLayout = av.GetActiveDoc

theFormats = theLayout.GetDisplay.ReturnExportFormats

theFormat = MsgBox.ChoiceAsString(theFormats, "Select format:", "Export Formats")

if (theFormat <> nil) then

  theFN = MsgBox.Input("Enter file name:", "Export Filename", "temp.tmp").AsFileName

  theExportDisplay = theLayout.GetDisplay.ExportStartFN(theFN, theFormat)

  theExportDisplay.Invalidate(FALSE)

  theLayout.GetGraphics.SetDisplay(theExportDisplay)

  'Instead of drawing the entire layout, you could modify the

  'script by sending the draw request to individual graphics in

  'the graphic list, such as the selected graphics.

  theLayout.GetGraphics.Draw

  theLayout.GetGraphics.SetDisplay(theLayout.GetDisplay)

  theExportDisplay.ExportEnd

end


View.Export
Exports a View to file suitable for printing

Source Code

Description:   This script shows how you can create a printable file from a View. In this form, this script mimics the request, aView.ExportDisplay, which displays a dialog window allowing the ArcView user to select a filename and output format. Although this script also contains a similar user interface, you can easily change the code to hard code filenames and output formats to suit your needs.

Name:    View.Export

Requires:  A View must be the active document

Self:

Returns:

FileName:  exptview.ave


View.Export (Sample Script)
'Exports a View to file suitable for printing

theView = av.GetActiveDoc

theFormats = theView.GetDisplay.ReturnExportFormats

theFormat = MsgBox.ChoiceAsString(theFormats, "Select format:", "Export Formats")

if (theFormat <> nil) then

  theFN = MsgBox.Input("Enter file name:", "Export Filename", "temp.tmp").AsFileName

  theExportDisplay = theView.GetDisplay.ExportStartFN(theFN, theFormat)

  theExportDisplay.Invalidate(FALSE)

  theView.Draw(theExportDisplay)

  theExportDisplay.ExportEnd

end


View.FindNearestFeatureTool
Finds feature nearest to a point

Source Code

Description:   Finds the nearest feature in the active theme to the point entered interactively by the user.  Reports the distance and selects the feature.  Processes the currently selected features in the active theme within the minimum search tolerance. If no features are selected, all features within the search tolerance will be considered.

Name:    View.FindNearestFeatureTool

Requires:  a View must be the active document, at least one Theme in the View must be active.

Self:

Returns:

FileName:  findnear.ave


View.FindNearestFeatureTool (Sample Script)
'Finds feature nearest to a point

shpPoint = v.GetDisplay.ReturnUserPoint

if (t.GetFTab.GetSelection.Count = 0) then

  featuresToCheck = t.GetFTab

  total = t.GetFTab.GetNumRecords

else

  featuresToCheck = t.GetFTab.GetSelection

  total = featuresToCheck.Count

end

minRecord = 0

shpFld  = t.GetFTab.FindField("Shape")

counter = 0

' Find the closest feature to the point...

av.ShowMsg("Searching for closest feature...")

for each rec in featuresToCheck

  counter = counter + 1

  shpCurrent = t.GetFTab.ReturnValue(shpFld,rec)

  dist = shpCurrent.Distance(shpPoint)

  if (dist < minDistance) then

    minDistance  = dist

    minRecord   = rec.Clone

  end

  av.SetStatus((counter / total) * 100)

end

av.ClearStatus

av.ClearMsg

if (minRecord = 0) then

  MsgBox.Info("No features found with minimum search distance.",

    "Find Nearest Feature")

  exit

end

MsgBox.Info("Distance to closest feature:"++minDistance.AsString,

  "Find Nearest Feature")

t.GetFTab.GetSelection.Set(minRecord)

t.GetFTab.UpdateSelection


Table.FieldProperties
Displays field properties

Source Code

Description:   This example script uses some of the requests for a Field to get information about the currently selected field, and displays the collected information using MsgBox.Report.

Name:    Table.FieldProperties

Requires:  A table must be the active document, with an active field. You can use the system script, Table.SortUpdate, to disable the control that executes this script when no field is active.

Self:

Returns:

FileName:  fldprops.ave


Table.FieldProperties (Sample Script)
'Displays field properties

theField = av.GetActiveDoc.GetActiveField

fname = theField.GetName

falias = theField.GetAlias

ftype = theField.GetType

fwidth = theField.GetWidth

fprec = theField.GetPrecision

fstat = theField.GetStatus

fpwidth = theField.GetPixelWidth

feditable = theField.IsEditable

msgbox.Report("Name:  "+fname+NL+

              "Alias:  "+falias+NL+

              "Type:  "+ftype.asstring+NL+

              "Width:  "+fwidth.asstring+NL+

              "Precision:  "+fprec.asstring+NL+

              "Status:  "+fstat.asstring+NL+

              "Pixel Width:  "+fpwidth.asstring+NL+

              "Editable:  "+feditable.AsString,

              "Field Properties")


Script.FindString
Finds specified string a script

Source Code

Description:   Searches for the specified string and, when found, places the insert position (the window cursor position) at the string.

Name:    Script.FindString

Requires:  av.GetActiveDoc must be a SEd.

Self:

Returns:

FileName:  fndstrng.ave


Script.FindString (Sample Script)
'Finds specified string a script

theSEd = av.GetActiveDoc

theString = MsgBox.Input ("Search for:", "Search", "")

if (theString = nil) then

  exit

end

theOriginalPos = theSEd.ReturnInsertPos

wasFound = theSEd.Search (theString)

if (wasFound.Not) then

  ' restart search from the top of file

  theSEd.SetInsertPos (0)

  wasFound = theSEd.Search (theString)

end

if (wasFound) then

  theSEd.SetInsertPos(theSEd.ReturnInsertPos)

else

  theSEd.SetInsertPos(theOriginalPos)

end


View.GridMaker
Creates arbitrary grid(vector) shapefile

Source Code

Description:   This script is attached to a tool.  When you drag a rectangle with the tool, you are then prompted for how many rows and columns you want in the grid. Then you are asked for the name of a shapefile to create, and the grid is created. One attribute is added to this grid shape theme, a label, that is "A1 A2  B1 B2...." as you might see on an index map.  The labeling starts at the upper left. The grid is added to your current view as a theme called "Grid" with hollow fill pattern and thick (thickness 2) black lines.  You are prompted as to whether you want to label the grid. If you say yes, it will put the labels in the grid box using the current textsymbol.

Name:    View.GridMaker

Requires:

Self:

Returns:

FileName:  grdmaker.ave


View.GridMaker (Sample Script)
'Creates arbitrary grid(vector) shapefile

if (self.Is(Tool).Not) then

  System.Beep

  MsgBox.Error("This script must be run from a tool.","Error")

  exit

end

theView=av.GetActiveDoc

viewUnits=theView.GetDisplay.GetUnits

viewProj=theView.GetProjection

theRect=theView.ReturnUserRect

if (theRect=nil) then

  exit

end

llx=therect.getleft

lly=therect.getBottom

theWidth=therect.getwidth

theHeight=therect.getheight

rows=Msgbox.Input("How many rows (up/down):","hello","10")

if ((rows = nil) or (rows.asNumber < 1)) then

  MsgBox.Error("Must use more than one row.","Aborting")

  exit

end

cols=Msgbox.Input("How many columns:","Hello","10")

if ((cols =nil) or (cols.asNumber < 1)) then

  MsgBox.Error("Must use more than one column.","Aborting")

  exit

end

rows=rows.asnumber

cols=cols.asnumber

rsize=theheight/rows

csize=thewidth/cols

letters="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

newshpname=filedialog.Put("grid.shp".AsFilename,"*.shp","Grid file")

if (newshpname =nil) then

  exit

end

gridftab=Ftab.MakeNew(newshpname,POLYGON)

labelfield=Field.Make("Label",#FIELD_CHAR,6,0)

gridftab.SetEditable(true)

gridftab.Addfields({labelfield})

gridftab.SetEditable(True)

shpfield=gridftab.FindField("shape")

labfield=gridftab.FindField("label")

countup=0

sizer=rows*cols

av.setstatus(0)

Av.ShowMsg("Creating grid...")

for each r in 1..rows

  row_id=(rows-r+1).AsString

  for each c in 1..cols

    countup=countup+1

    av.setstatus(countup/sizer*100)

    if ((c/26) > 1) then

      col_prefix=letters.middle((c/26).floor-1,1)

    else

      col_prefix=""

    end

    if (c.Mod(26) = 0) then

      col_name=letters.Middle(25,1)

    else

      col_name=letters.Middle(c.Mod(26)-1,1)

    end

    col_id=col_prefix+col_name

   originx=llx+((c-1)*csize)

   originy=lly+((r-1)*rsize)

   size=csize@rsize

   origin=originx@originy

    rct=rect.make(origin,size)

    if (viewunits=#UNITS_LINEAR_METERS) then

      rct=rct.ReturnUnprojected(viewproj)

    end

    newrec=gridftab.AddRecord

    gridftab.SetValue(shpfield,newrec,rct.aspolygon)

    gridftab.SetValue(labfield,newrec,col_id+row_id)

  end

end

gridftab.SetEditable(false)

av.clearMsg

mytheme=ftheme.Make(gridftab)

mysym=av.GetSymbolWin.GetPalette.GetList(#PALETTE_LIST_FILL).Get(0)

mysym.setolwidth(2)

mytheme.GetLegend.GetSymbols.Set(0,mysym)

mytheme.SetName("Grid")

mytheme.SetActive(true)

myTheme.SetVisible(true)

theview.AddTheme(mytheme)

mytheme.Invalidate(true)

theview.GetDisplay.Flush

yn=MsgBox.YesNo("Label the grid?","Gridmaker",true)

if (yn) then

  for each thm in theView.GetThemes

    if (thm <> mytheme) then

      thm.SetActive(False)

    end

  end

  theView.LabelThemes(false)

end


Theme.GeneralizeFeatures
Removes unneeded vertices from selected features

Source Code

Description: Simplifies the shapes in a shapefile that is created from the selected features for each active polyline or polygon theme. This script is used to generalize, or weed out, vertices  that do not add to the desired level of detail in the definition of the shape geometry. A tolerance is specified to check whether or not vertices should be retained.

This script is a simple implementation of the Douglas - Peucker algorithm used in ARC/INFO and PC ARC/INFO. It should be used as a button in a View GUI.

A few thoughts to consider:

1. The script first creates a new shapefile for selected features of an active theme. The new shapefile is added to the view. The original theme is not changed.

2. This script will reduce the quality of the data. Any metadata for the themes should state that the data has been modified.

3. Results are very dependent on the polygon geometry. Shapes created from adjacent polygons may no longer be coincident. They may overlap, or leave a sliver. Proceed with caution.

4. Results are very dependent on the polyline geometry. While the shape endpoints are maintained, interior points may be eliminated. Other shapes in a network that may begin or end at an interior vertex may now be dangling. A complex shape may cross itself after being generalized. Proceed with caution.

5. The only check on the resulting geometry is to be sure a polygon has not collapsed completely by removing too many vertices. If so, the shape will revert to the original.

6. This script does not recalculate areas, perimeters, or lengths. They may have changed as the shapes are simplified. The View.CalculateFeatureGeometry (calcapl.ave) sample script can be used to update the values.

Name: Theme.GeneralizeFeatures

Requires: A View with at least one active polyline or polygon theme.

Self:

Returns:

FileName: genfeat.ave


Theme.GeneralizeFeatures (Sample Script)
'Removes unneeded vertices from selected features

' Get the view and its projection

theView = av.GetActiveDoc

thePrj = theView.GetProjection

if (thePrj.IsNull) then

  hasPrj = false

else

  hasPrj = true

  thePrj = theView.GetProjection

end

' Get active themes

theThemes = theView.GetActiveThemes

if (theThemes.Count < 1) then

  MsgBox.Error("Please make a polyline or polygon theme active","*** Error ***")

  exit

end

' Process each active theme

for each t in theThemes

  ' Check that the theme is of the correct type

  if (t.Is( FTHEME).Not) then

    MsgBox.Error (t.GetName++"is not a polyline or polygon theme","*** Error ***")

    continue

  end

  theClassName = t.GetFTab.GetShapeClass.GetClassName

  if ((theClassName = "Polygon").Not and (theClassName = "Polyline").Not) then

    MsgBox.Error (t.GetName++"is not a polyline or polygon theme","*** Error ***")

    continue

  end

  ' Get a tolerance in (distance units) to be used (must be > 0)

  theTol = 0

  theMUnits = theView.GetDisplay.GetUnits

  theDUnits = theView.GetDisplay.GetDistanceUnits

  theUStr = Units.GetFullUnitString(theDUnits).LCase

  while ((theTol <= 0) or (theTol.AsString.IsNumber).Not)

    theTol = MsgBox.Input("Positive tolerance value (in "+theUStr+

         ") for theme"++t.GetName,"Tolerance",theTol.AsString)

    if (theTol = NIL) then exit end

    if (theTol.IsNumber) then

      theTol = theTol.AsNumber

    end

  end

  theTol = Units.Convert(theTol,theDUnits,theMUnits)

  ' Get the name for a new theme, from View.Export script

  def = av.GetProject.MakeFileName("theme", "shp")

  def = FileDialog.Put(def, "*.shp", "New file for simplified "+ t.getName)

  if (def = NIL) then return nil end

  ' Create a new shapefile theme, from View.Export script

  tbl = t.GetFtab

  shpfld = (tbl.FindField("Shape"))

  if (shpfld.IsVisible.Not) then

    shpfld.SetVisible(shpfld.IsVisible.Not)

    WasNotVisible = TRUE

  else

    WasNotVisible =FALSE

  end

  ' This will only export the selected shapes, if any have been selected

  av.ShowMsg("Creating new shape file from"++ t.GetName)

  anFTab = tbl.Export(def, Shape, tbl.GetSelection.Count > 0)

  anFTab.SetEditable(true)

  if (WasNotVisible) then

    shpfld.SetVisible(FALSE)

  end

  ' Find the shape field

  theSField = anFTab.FindField("Shape")

  ' Set up status bar

  av.ShowMsg("Generalizing new shapes from theme"++ t.GetName)

  theSize = anFTab.GetNumRecords

  ' Initialize counters for reporting

  count = 0

  oldCount = 0

  newCount = 0

  ' Process each shape

  for each r in anFTab

    av.SetStatus(100*count/theSize)

    ' Retrieve shape

    if (theClassName = "Polygon") then

      theOShape = Polygon.MakeNull

    else

      theOShape = Polyline.MakeNull

    end

    anFTab.QueryShape(r,theView.GetProjection,theOShape)

    ' Make a list for collecting the new set of point lists

    theNShape = List.Make

    ' Process each list in the ListofListofPoints

    for each p in theOShape.AsList

      ' Make a list for collecting the vertices to keep

      theNList = List.Make

      oldCount = oldCount + p.Count

      ' Set up stack for holding a set of lists of form {index,point}

      theStack = Stack.Make

      ' Add first point to the list being assembled, and make it the anchor

      theAnchor = p.Get(0)

      if (hasPrj) then

        theNList.Add(theAnchor.ReturnUnProjected(thePrj))

      else

        theNList.Add(theAnchor)

      end

      aIndex = 0

      ' Add last point to stack

      fIndex = p.Count - 1

      theStack.Push({fIndex,p.Get(fIndex)})

      ' Process the points with the Douglas - Peucker approach

       while (theStack.IsEmpty.Not)

        ' Process from Anchor (beginning) to Floater (top of stack)

        fIndex = theStack.Top.Get(0)

        ' Create graphic shape for comparing distances

        theVect = Line.Make(theAnchor,theStack.Top.Get(1))

        ' Initialize values for comparison

        theMax = theTol

        mxIndex = 0

        ' Find distance

        for each i in (aIndex + 1) .. (fIndex - 1) ' process middle points

          dist = theVect.Distance(p.Get(i))

          ' Check against previous maximum

          if (dist >= theMax) then  ' this point is out of the tolerance

            theMax = dist

            mxIndex = i

          end

        end

        ' If a vertex is found outside the current tolerance corridor,

        ' push it onto the stack

        if (mxIndex > 0) then 'a new floater has been found

          theStack.Push({mxIndex,p.Get(mxIndex)})

        else  ' add floater to the list for the new shape and move forward

          if (hasPrj) then

            theNList.Add(theStack.Top.Get(1).ReturnUnProjected(thePrj))

          else

            theNList.Add(theStack.Top.Get(1))

          end

          ' Make the floater the new anchor

          theAnchor = theStack.Pop.Get(1)

          aIndex = fIndex

        end

      end

      ' Check for collapsed polygons

      if ((theNList.Count < 4) and (theClassName = "Polygon")) then

         ' Revert to original polygon

        if (hasPrj) then

          theNList = List.Make

          for each pt in p

            theNList.Add(pt.ReturnUnProjected(thePrj))

          end

        else

          theNList = p

        end

      end

      ' Finish up individual lists

      newCount = newCount + theNList.Count

      theNShape.Add(theNList)

    end

    ' Finish up the shape

    if (theClassName = "Polygon") then

      theNShape = Polygon.Make(theNShape)

    else

      theNShape = Polyline.Make(theNShape)

    end

    anFTab.SetValue(theSField, r, theNShape)

    count = count + 1

  end

  ' Clear status message

  av.ClearMsg

  av.ClearStatus

  ' Report on counts of old and new theme

  MsgBox.Info("The old theme with"++ oldCount.AsString ++

      "vertices has been generalized to"++

        newCount.AsString++"vertices","Results")

  ' Create a theme and add it to the View

  anFTab.SetEditable(false)

  fthm = FTheme.Make(anFTab)

  theView.AddTheme(fthm)

end

' Bring the View to the front

theView.GetWin.Activate


Geocode.LocateDialogBox
Create your own dialog box for locating an address

Source Code

Description:  This script allows you to create your own dialog box for locating an address. In addition to customizing the Locate dialog interface, this script addresses an issue of setting an offset distance for the geocoded event.

At the current design, the Locate dialog box always applies the MatchSource default offset. It is 0 (zero) for all applicable address styles in ArcView. You can change the MatchSource's default offset using the aMatchSource.SetDefOffSet request.

Alternatively, you can specify an active offset if you are working with a customized dialog box for locating an address. Below is a sample script which allows you to create a dialog box for getting an event address and locate it with an offset distance of 30. Please modify it as needed. You can still use the system's View.LocateUpdate as an update script if you want to create a new button.

Name:  Geocode.LocateDialogBox

Requires:  A View document must be active that contains an active matchable theme.

Self:

Returns:

FileName:  geolocte.ave


Geocode.LocateDialogBx (Sample Script)
'Create your own dialog box for locating an address

'Locate an address with an offset distance of 30.

theView = av.GetActiveDoc

if (theView.GetActiveThemes.Count <> 1) then

  Msgbox.Error("You must have one and only one active theme.","Aborting")

  exit

end

theTheme = theView.GetActiveThemes.Get(0)

aMatchSource = theTheme.GetMatchSource

aMatchSource.setoffset (30)

' Get and set an address to MatchKey key field.

address = MsgBox.Input("Enter an address","Locate Address","")

if ( address = nil ) then

  MsgBox.Info ("Cannot locate address", "Locate Address")

  exit

end

aMatchKey = MatchKey.Make( aMatchSource.GetStanRules )

aMatchKey.SetKey (address)

aMatchCase = MatchCase.Make( aMatchSource, aMatchKey )

aMatchPref = MatchPref.Make        ' Use default values.

aMatchSource.Openindex

' Search for candidates.

numCand = aMatchSource.Search( aMatchKey, 80, aMatchCase )

if ( numCand = 0 ) then

  MsgBox.Info( "Cannot locate address for "++address,"Locate Address" )

end

if ( numCand <> 0) then

  ' Score and get best candidate.

  aMatchCase.ScoreCandidates

  bestCand = aMatchCase.GetBestCand

  p=aMatchSource.GetPoint(bestCand)

  if (p <> NIL) then

    if (p.IsNull) then

      MsgBox.Info("Cannot locate address.", "Locate Address")

    else

      proj = theView.GetProjection

      pp = p.ReturnProjected(proj)

      g = GraphicShape.Make(pp)

      theView.GetGraphics.Add(g)

      ext = theView.GetDisplay.ReturnExtent

      if (not(pp.IsContainedIn(theView.GetDisplay.ReturnExtent))) then

        theView.GetDisplay.PanTo(pp)

      end

      exit

    end

  end

end


Geocode.Table
Geocodes addresses in a Table to a matchable Theme

Source Code

Description:   Geocodes addresses found in a table to a matchable theme.It is assumed that the addresses and theme use US style addresses. The script can be modified to support other address styles. Geocoding results are reported and the new theme is added to the current View and drawn.

Name:    Geocode.Table

Requires:  The active document must be a View.

Self:

Returns:

FileName:  geocode.ave


Geocode.Table (Sample Script)
'Geocodes addresses in a Table to a matchable Theme

' Collect information used to create the new geocoded point theme.

' The theme to match against, the table containing addresses, and the

' name of the field containing address information are passed from the

' calling script...

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

addressVTab = av.GetProject.FindDoc( "customrs.dbf" ).GetVTab

addressField = addressVTab.FindField("Address")

zipField = addressVTab.FindField("Zip")    ' this field is required if the address style requires a zone

' Get the matchable feature source and double check that it is valid...

aMatchSource  = theTheme.GetMatchSource

if (aMatchSource = Nil) then

  MsgBox.Error("Theme"++theTheme.GetName++"is not matchable.","")

  exit

end

' Specify the output point shapefile that will be created from the

' matched addresses...

' Specify the output point shapefile for the geocoding result...

aGeoName = GeoName.Make(aMatchSource, addressVTab, addressField, zipField)

fnOutFile = FileDialog.Put(av.GetProject.MakeFileName("theme", "shp"),

  "*.shp","Output Shapefile")

if (fnOutFile = nil) then

  exit

else

  aGeoName.SetFileName(fnOutFile)

end

' Create a match key based on the standardization rules for the

' MatchSource. Use the aMatchKey.AllowIntersections request to

' supporting street intersection standardization.

aMatchKey  = MatchKey.Make(aMatchSource.GetStanRules)

aMatchKey.AllowIntersections(aMatchSource.GetXStanRules, aMatchSource.GetXDelimiter)

' Create a new match case.  A match case is comprised of a list of

' candidate records and information describing how well the candidates

' match the key.  The MatchCase will be populated with candidates later...

aMatchCase = MatchCase.Make( aMatchSource, aMatchKey )

aMatchCase.AllowIntersections(aMatchSource, aMatchKey)

' Create a new match preference which will be used to access various

' geocoding preferences, such as spelling weight, minimum acceptable

' score, etc...

aMatchPref = MatchPref.Make

' Create a new theme feature table.  For every address record there

' will be a record in the FTab.  These are currently unmatched, i.e.

' the shape field is empty and the status is 'U' for unmatched.  We

' must match an address to populate the shape field and toggle the status

' to 'M' for matched, something we do in the next step...

' aMatchSource.InitGeoTheme request will open the geocoding index.

aGeoTheme = aMatchSource.InitGeoTheme( aGeoName )

geoThemeVTab = aGeoTheme

addrGeoThemeField = geoThemeVTab.FindField("Address")

zipGeoThemeField = geoThemeVTab.FindField("Zip")

' Populate the feature table by matching addresses to the matchable

' Theme.  This places a point in the FTab's shape field for and sets

' the status to M (matched) for each match...

numrecs    = geoThemeVTab.GetNumRecords

numMatched = 0

av.ShowMsg("Matching Addresses...")

for each i in geoThemeVTab.GetDefBitMap

  av.SetStatus((i / numrecs) * 100)

  ' Get an address...

  aMatchKey.SetKey( geoThemeVTab.ReturnValueString(addrGeoThemeField, i ))

  aMatchKey.SetZoneKey( geoThemeVTab.ReturnValueString(zipGeoThemeField, i))

  ' Find candidates for the address...

  numCand = aMatchSource.Search( aMatchKey, 70, aMatchCase)

  ' If there are no candidates, continue on to the next addresss.  This

  ' will be an unmatched record.  If candidates are found, take the best

  ' candidate and see if it exceeds the minimum specified match score.

  ' If it does write it, otherwise write unmatch.

  ' If there are no candidates, WriteUnMatch and continue to the next addresss.

  if (numCand = 0) then   ' No candidates

    aMatchSource.WriteUnMatch(i, aMatchKey)

  else                    ' We have at least one candidate...

    aMatchCase.ScoreCandidates

    cand      = aMatchCase.GetBestCand

    candScore = cand.GetScore

    minScore  = aMatchPref.GetPrefVal( #MATCHPREF_MINMATCHSCORE )

    ' If the min required match score is exceeded - write it!

    ' If the min is not met then the cand is not written and the record

    ' will remain unmatched...

    if ( candScore >= minScore ) then

      aMatchSource.WriteMatch( i, aMatchKey, cand )

      numMatched = numMatched + 1

    end

  end

end

av.ClearMsg

av.ClearStatus

aMatchSource.EndMatch

' Report the results of the geocoding...

MsgBox.Info("Total records processed:"++numrecs.AsString+NL+

  "Total addresses matched:"++numMatched.AsString, "Geocoding Results")

' Add the new theme to the view and draw it...

newTheme = Theme.Make( aGeoName )

theView.AddTheme( newTheme )

newTheme.SetVisible( true )


Table.GetUniqueValues
Gets unique values for specified field

Source Code

Description:   Returns a list of unique field values for the selected rows in the specified table.  Functionally similar to the ARC/INFO AML function [GETUNIQUE].

The script will process the selected rows in the VTab, if any, or will process all records in the VTab if there are no selected rows.

The user provides the VTab or FTab and a Field.  The script returns a unique list of values for the specified Field sorted in ascending order. The unique values are returned as a list of strings.  If an error occurs Nil is returned.

Example use; allow the user to select from a unique list of State names from the active Table:

     theTable = av.GetActiveDoc

     theField = theTable.GetVTab.FindField("State_Name")

     theList  = av.Run("GetUnique", {theTable.GetVTab, theField})

     c = MsgBox.ChoiceAsString(theList, "Choose a State:", "Choice")

Name:    Table.GetUniqueValues

Requires:  The calling script must provide list containing two elements; the VTab (or FTab) and a Field.

Self:

Returns:

FileName:  getuniq.ave


Table.GetUniqueValues (Sample Script)
'Gets unique values for specified field

' Cursory check to see if appropriate parameters have been passed...

if ((SELF = nil) or (SELF.Is(List).Not) or (SELF.Count < 2)) then

  return(Nil)

end

theVTab = SELF.Get(0)

theField = SELF.Get(1)

uniqueList = List.Make

' Build list of field contents...

if (theVTab.GetSelection.Count = 0) then

  theSet = theVTab

else

  theSet = theVTab.GetSelection

end

for each rec in theSet

  uniqueList.Add(theVTab.ReturnValueString(theField, rec))

end

' Check for errors, remove duplicates, and sort...

if (uniqueList.Count > 0) then

  uniqueList.RemoveDuplicates

  uniqueList.Sort(true)

  return(uniqueList)

else

  return(Nil)

end


GPS2Shape
Converts ASCII GPS output to shapefile

Source Code

Description:   Reads coordinate information from the specified file, prompts the user for the output shapefile type (line, point, polygon), and creates the shapefile.  In the case of polygons the first point is used to close the polygon.

Many GPS devices include software which can produce output in various ASCII formats.  This script assumes that the file will containing comma delimited coordinates in the format:

     station_id, x_coordinate, y_coordinate

     station_id, x_coordinate, y_coordinate

The script assumes that each record in the input file is a data record, i.e. there is no header.  Coordinates are read until the end of file is reached or until the string "END" is found.  Modify the code to support different file formats.  This script does not support any specific GPS output format in particular.  It is an example script that can be modified for the exact ASCII output format required.

Name:    GPS2Shape

Requires:  Input file containing coordinate information.

Self:

Returns:

FileName:  gps2shp.ave


GPS2Shape (Sample Script)
'Converts ASCII GPS output to shapefile

' Choose the GPS file to convert to shapefile...

gpsName = FileDialog.Show("*.*","GPS File","Select GPS File to Convert")

if (gpsName = nil) then

  exit

end

gpsFile  = LineFile.Make(gpsName, #FILE_PERM_READ)

totalRecs = gpsFile.GetSize

' Specify the output shapefile...

defaultName    = FileName.Make("$HOME").MakeTmp("shape","shp")

shpName  = FileDialog.Put( defaultName,"*.shp","Output Shape File" )

if (shpName = nil) then

  exit

end

shpName.SetExtension("shp")

' Specify which kind of shapefile to create and make the new FTab...

type = MsgBox.ChoiceAsString({"Point", "Line", "Polygon"},

  "Convert GPS locations to:", "GPS Convert" )

if (type = Nil) then

  exit

end

if (type = "Point") then

  shpFTab = Ftab.MakeNew(shpName,Point)

elseif (type = "Line") then

  shpFTab = FTab.MakeNew(shpName, Polyline)

elseif (type = "Polygon") then

  shpFTab = FTab.MakeNew(shpName, Polygon)

end

fields = List.Make

fields.Add(Field.Make("Station", #FIELD_SHORT, 4, 0))

shpFTab.AddFields(fields)

shpField = shpFTab.FindField("Shape")

idField  = shpFTab.FindField("Station")

gpsRec = 0

av.ShowStopButton

av.ShowMsg("Converting"++gpsName.GetBaseName+"...")

' If the user has chosen 'Point' then the FTab is written here in the

' while loop.  Otherwise if 'Line' or 'Polygon' has been chosen we

' collect coordinates in the loop for writing to the FTab later...

if ((type = "Line") or (type = "Polygon")) then

  pointList = List.Make

end

while (true)

  buf = gpsFile.ReadElt

  if (buf = Nil) then

    break

  end

  if (buf = "END") then

    break

  end

  gpsTokens = buf.AsTokens(",")

  if (type = "Point") then          ' write points to FTab...

    theID = gpsTokens.Get(0)

    thePoint = gpsTokens.Get(1).trim.AsNumber@gpsTokens.Get(2).trim.AsNumber

    rec = shpFTab.AddRecord

    shpFTab.SetValueNumber( idField, rec, theID.trim.AsNumber )

    shpFTab.SetValue( shpField, rec, thePoint )

  elseif (type = "Line") then       ' collect points defining line...

    thePoint = gpsTokens.Get(1).trim.AsNumber@gpsTokens.Get(2).trim.AsNumber

    pointList.Add( thePoint )

  elseif (type = "Polygon") then    ' collect points defining polygon...

    thePoint = gpsTokens.Get(1).trim.AsNumber@gpsTokens.Get(2).trim.AsNumber

    pointList.Add( thePoint )

  end

  gpsRec = gpsRec + 1

  progress = (gpsRec / totalRecs) * 100

  proceed = av.SetStatus( progress )

  if (proceed.Not) then

    av.ClearStatus

    av.ShowMsg( "Stopped" )

    exit

  end

end

' If Line or Polygon we still need to create FTab...

if (type = "Line") then

  rec = shpFTab.AddRecord

  shpFTab.SetValueNumber( idField, rec, 1 )

  pl = Polyline.Make( {pointList} )

  shpFTab.SetValue( shpField, rec, pl )

elseif (type = "Polygon") then

  rec = shpFTab.AddRecord

  shpFTab.SetValueNumber( idField, rec, 1 )

  ' Add first point to end of list to close the polygon...

  startPoint = pointList.Get(0)

  pointList.Add( startPoint )

  pl = Polygon.Make( {pointList} )

  shpFTab.SetValue( shpField, rec, pl )

end

av.ClearStatus

av.ClearMsg

shpFTab.Flush

MsgBox.Info( gpsRec.AsString++"records converted." ,"Conversion Completed" )


Graphic.ClipFromGraphic
Extract and clip features by graphics

Source Code

Description:   Using the selected graphics this script will extract all features of the active theme and clip their boundary to the graphic.  All theme attributes are extracted as well.

Name:    Graphic.ClipFromGraphic

Requires:  An update script which enables this only if a theme is active and poly graphic shapes are selected.

Self:

Returns:

FileName:  grafclip.ave


Graphic.ClipFromGraphic (Sample Script)
'Extract and clip features by graphics

theView=av.getactiveDoc

themelist=theView.getthemes

if (TheView.getactiveThemes.count=0) then exit end

SRCTheme=TheView.getactiveThemes.get(0)

theGraphics=theView.getGraphics

if (theGraphics.Hasselected.Not) then

 msgbox.error("No selected graphics","Error")

 exit

end

theselGraphics = theGraphics.getselected

' Specify the output shapefile...

outFName = av.GetProject.MakeFileName("theme", "shp")

outFName = FileDialog.Put(outFName, "*.shp", "Output Clipped Shapefile")

if (outFName = Nil) then

  exit

end

shapeType = SRCTheme.GetFTab.FindField("Shape").GetType

if (shapeType = #FIELD_SHAPELINE) then

  outClass = POLYLINE

elseif (shapeType = #FIELD_SHAPEMULTIPOINT) then

  outClass = MULTIPOINT

elseif (shapeType = #FIELD_SHAPEPOINT) then

  outClass = POINT

elseif (shapeType = #FIELD_SHAPEPOLY) then

  outClass = POLYGON

else

  MsgBox.Error("Invalid shape field type.", "Clip Theme")

  exit

end

'-------------------------------------------------------

'Set the variables

'-------------------------------------------------------

OutputFTab = FTab.MakeNew( outFName, outClass )

SRCfields = List.Make

for each f in SRCTheme.GetFTab.GetFields

  if (f.GetName = "Shape") then

    continue

  else

    fCopy = f.Clone

    SRCfields.Add(fCopy)

  end

end

'-------------------------------------------------------

'add the fields to the output file

'-------------------------------------------------------

if (SRCFields.Count > 0) then

 OutputFTab.AddFields( SRCFields )

end

outshpfld = OutputFtab.findfield("Shape")

Theme1 = SRCTheme

ftab1=Theme1.getftab

shpfld1=ftab1.findfield("Shape")

therecs1 = ftab1.getselection

theoldsel = ftab1.getselection.clone

 if (therecs1.count=0) then

   therecs1=ftab1

 end

OutputFtab.seteditable(False)

OutputFtab.seteditable(True)

acount=0    'A counter variable

'-------------------------------------------------------

'Start processing each record in the selected overaly polys

'-------------------------------------------------------

for each arec2 in theselgraphics

 'get the polygon shape and select all records within that shape

 theSRCshape1 = arec2.getshape

 if (theView.getprojection.isNull) then

  theSRCshape = arec2.getshape

 else

  theSRCshape = arec2.getshape.returnunprojected(theview.getprojection)

 end

Theme1.SelectbyShapes({theSRCshape1}, #VTAB_SELTYPE_NEW)

ftab1.updateselection

 'For each selected record

recordCount = 0

for each Selrec in ftab1.getselection

recordcount=recordcount +1

av.showmsg("Spliting Shapes...")

av.setstatus((recordCount / ftab1.getselection.count) * 100)

'Get the shape of the record

    SelectedShape = ftab1.returnvalue(shpfld1,Selrec)

'If the output is a line

    if (outshpfld.getType = #FIELD_SHAPELINE) then

'If the line is wholely within the polygon (no intersection) then

     msgbox.report(selectedshape.asstring,"")

       if (SelectedShape.iscontainedin(theSRCShape)) then

         alineshp = SelectedShape

 msgbox.info("contains","")

'Else split the line using the polygon

       else

          alineshp = SelectedShape.LineIntersection(theSRCshape)

       end

'Add the new record

          theoutrec=outputftab.addrecord

'Set the shape value

          outputFtab.SetValue(outshpfld,theoutrec,alineshp)

'Set the field values

             for each afield in SRCfields

               oldfield=ftab1.findfield(afield.getname)

               oldvalue=ftab1.returnvalue(oldfield,selrec)

               outputftab.setValue(afield, theoutrec, oldvalue)

             end

 'This enters into the polygon loop

 else

       shpIntersect = SelectedShape.ReturnIntersection(theSRCshape.aspolygon)

       if (shpintersect.isempty) then

         continue

       end

       'theview.getgraphics.add(graphicshape.make(shpintersect.returnprojected(theview.getprojection)))

        theoutrec=outputftab.addrecord

        outputFtab.SetValue(outshpfld,theoutrec,shpIntersect)

       for each afield in SRCfields

         oldfield=ftab1.findfield(afield.getname)

         oldvalue=ftab1.returnvalue(oldfield,selrec)

         outputftab.setValue(afield, theoutrec, oldvalue)

       end

      end

     ' acount=acount+1

      av.purgeobjects

   end

end 'ends the for each on arec1

'Set editing OFF

Outputftab.seteditable(false)

theview.getgraphics.endbatch

ftab1.setselection(theoldsel)

ftab1.updateselection

if (MsgBox.YesNo("Add shapefile as theme to a view?",

  "Clip Theme", true).Not) then

  exit

end

' Create a list of views and allow the user to choose which view to

' add the new theme to...

viewList = {}

for each d in av.GetProject.GetDocs

  if (d.Is(View)) then

    viewList.Add( d )

  end

end

' Include a choice for a new view...

viewList.Add("<New View>")

addToView = MsgBox.ListAsString( viewList,"Add Theme to:", "Clip Theme" )

' Get the specified view, make the theme, and add it...

if (addToView <> nil) then

  if (addToView = "<New View>") then

    addToView = View.Make

    addToView.GetWin.Open

  end

  mergeTheme = FTheme.Make( OutputFTab )

  addToView.AddTheme( mergeTheme )

  ' Bring the View to the front...

  addToView.GetWin.Activate

end

av.clearstatus


View.Graticule
Creates Graticules, Tics, and Labels for a View

Source Code

Description:   This script offers several options for placing graticules and tics on a View.  You may specify the interval between each graticule line or between each tic mark.

Name:    View.Graticule

Requires:  The View must be projected.

Self:

Returns:

FileName:  gratview.ave


View.Graticule (Sample Script)
'Creates Graticules, Tics, and Labels for a View

theView = av.getactivedoc

theGraphics = theView.GetGraphics

' get view projection information

thisPrj=theView.GetProjection

if (thisPrj.IsNull) then

  MsgBox.Error("The view must be projected."+NL+

               "Unable to create graticule.","")

  exit

end

theChoice = MsgBox.ListAsString({

  "Lat-Long Labels Only",

  "Lat-Long Graticule with Labels",

  "XY Grid with Labels",

  "Lat-Long Labels & XY Grid",

  "All Graticules and grids" },

  "Select Graticule/Grid Type:","")

if (theChoice = "Lat-Long Labels Only") then

  doLatLongs = true

  doGraticule = false

  doXYGrid = false

elseif (theChoice = "Lat-Long Graticule with Labels") then

  doLatLongs = true

  doGraticule = true

  doXYGrid = false

elseif (theChoice = "XY Grid with Labels") then

  doLatLongs = false

  doGraticule = false

  doXYGrid = true

elseif (theChoice = "Lat-Long Labels & XY Grid") then

  doLatLongs = true

  doGraticule = false

  doXYGrid = true

elseif (theChoice = "All Graticules and grids") then

  doLatLongs = true

  doGraticule = true

  doXYGrid = true

else

  exit

end

' Display window (in inches)

' XY window

xyRect = theView.GetDisplay.ReturnVisExtent

xyOrigin = xyrect.ReturnOrigin

xySize = xyrect.ReturnSize

dOrigin = xyOrigin

dSize = xyrect.returnsize

' This is how to translate a point from map coords to page coords

'aPt = dOrigin + ( ((p - xyOrigin) / xySize) * dSize)

xMin = xyOrigin.GetX

yMin = xyOrigin.GetY

xMax = xMin + xySize.GetX

yMax = yMin + xySize.GetY

if ( doLatLongs ) then

  'work out the lat/long graticule

  'get the lat/long limits of the boundary

  point1=Point.Make(xMin,yMin)

  point2=Point.Make(xMax,yMin)

  point3=Point.Make(xMax,yMax)

  point4=Point.Make(xMin,yMax)

  point5=Point.Make((xMin+(xMax-xMin)/2),yMin)

  point6=Point.Make(xMax,(yMin+(yMax-yMin)/2))

  point7=Point.Make((xMin+(xMax-xMin)/2),yMax)

  point8=Point.Make(xMin,(yMin+(yMax-yMin)/2))

  'unproject the limits

  thisPrj.UnProjectPt(point1)

  thisPrj.UnProjectPt(point2)

  thisPrj.UnProjectPt(point3)

  thisPrj.UnProjectPt(point4)

  thisPrj.UnProjectPt(point5)

  thisPrj.UnProjectPt(point6)

  thisPrj.UnProjectPt(point7)

  thisPrj.UnProjectPt(point8)

  'find the min/max lat/long limits based on user input

  '  the limits are the nearest multiple of the graticule spacing

  '  inside of the user rectangle

  minlon=(Point1.GetX)Min(Point4.GetX)Min(Point8.GetX)Max(-180)

  minlat=(Point1.GetY)Min(Point2.GetY)Min(Point5.GetY)Max(-90)

  maxlon=(Point2.GetX)Max(Point3.GetX)Max(Point6.GetX)Min(180)

  maxlat=(Point3.GetY)Max(Point4.GetY)Max(Point7.GetY)Min(90)

  minLength = (maxlon-minlon) Min (maxlat-minlat)

  llIntervals = { 60,30,20,10,5,2,1,0.5,0.3333333333,0.25,0.1666666666,

    0.08333333333,0.03333333333,0.01666666666 }

  rawInterval = minLength / 3   ' 3 is the default number of lines

  theInterval = llIntervals.Get( llIntervals.Count - 1 )

  for each val in llIntervals

    if (rawInterval >= val) then

       theInterval = val

       break

    end

  end

  deg=theInterval.Abs.Truncate

  t= ( theInterval.Abs - deg ) * 60

  minute=t.Truncate

  sec= (t-minute) * 60

  sec= sec.Truncate

'  degList= {"Longitude interval","Latitude interval"}

'  degDef = {theInterval.AsString,theInterval.AsString}

  degList = {"Degrees","Minutes","Seconds"}

  degDef = { deg.AsString, minute.AsString, sec.AsString }

  degIntList=MsgBox.MultiInput( "Specify Latitude/Longitude Interval",

    "",degList,degDef)

  if (degIntList.Count = 0) then

    exit

  end

'  latInterval = degIntList.Get(1).AsNumber

'  lonInterval = degIntList.Get(0).AsNumber

  lonInterval = degIntList.Get(0).AsNumber +

    ( degIntList.Get(1).AsNumber / 60) +

    ( degIntList.Get(2).AsNumber / 3600)

  latInterval = lonInterval

end

'if metres was selected, prompt for the metres intervals

if ( doXYGrid ) then

  minLength = xySize.GetX Min xySize.GetY

  xyIntervals = { 20000000,10000000,5000000,2000000,1000000,500000,200000,

    100000,50000,20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1 }

  rawInterval = minLength / 4   ' 4 is the default number of lines

  theInterval = xyIntervals.Get( xyIntervals.Count - 1 )

  for each val in xyIntervals

    if (rawInterval >= val) then

       theInterval = val

       break

    end

  end

'  metresList = {"Easting interval","Northing Interval"}

'  metresDef = {theInterval.AsString,theInterval.AsString}

'  metresIntList=MsgBox.MultiInput("Specify Metres Intervals:",

'  "Metres Graticule", metresList, metresDef)

'  if (metresIntList.Count = 0) then

'    exit

'  end

   metresInt = MsgBox.Input( "Specify XY Grid Interval (in meters)", "",

     theInterval.AsString )

   if ( metresInt = nil ) then

     exit

   end

'  gratdx=metresIntList.Get(0).AsNumber

'  gratdy=metresIntList.Get(1).AsNumber

   gratdx = metresInt.AsNumber

   gratdy = gratdx

  'get the metres limits of the graticule, based on user input

  '  the limits are the nearest multiple of the graticule spacing

  '  inside of the user rectangle

  gratxs=(xMin/gratdx).Floor * gratdx - gratdx

  gratys=(yMin/gratdy).Floor * gratdy - gratdy

  gratxe=(xMax/gratdx).Ceiling * gratdx + gratdx

  gratye=(yMax/gratdy).Ceiling * gratdy + gratdy

end

' Add the graticule(s) and labels as graphic objects

' Make some symbols that don't yet exist

geolfont=Font.MakeStandard(#FONT_TIME)

geolSymbol=TextSymbol.Make

geolSymbol.SetFont(geolfont)

geolSymbol.SetColor(Color.GetBlack)

geolsymbol.SetSize(10)

theView.getDisplay.HookUpSymbol(geolsymbol)

xyfont=Font.MakeStandard(#FONT_COUR)

xySymbol=TextSymbol.Make

xySymbol.SetFont(xyfont)

xySymbol.SetColor(Color.GetBlack)

xysymbol.SetSize(8)

theView.getDisplay.HookUpSymbol(xysymbol)

blackLine=Symbol.Make(#SYMBOL_PEN)

blackLine.SetColor(Color.GetBlack)

theView.getDisplay.HookUpSymbol(blackLine)

thickblackLine=Symbol.Make(#SYMBOL_PEN)

thickblackLine.SetColor(Color.GetBlack)

thickblackLine.SetSize(2)

theView.getDisplay.HookUpSymbol(thickBlackLine)

gratLine=Symbol.Make(#SYMBOL_PEN)

gratLine.SetColor(Color.GetBlack)

gratLine.SetSize(0.01)

theView.getDisplay.HookUpSymbol(gratLine)

' Draw the border ...

dRect = Rect.Make( dOrigin, dSize )

theBorder = GraphicShape.Make( dRect)

theGraphics.Add( theBorder )

theBorder.SetSymbol(thickblackline)

'Draw the lat/long graticule, with labels all around

' Collect graticule lines clipped to the window

if ( doLatLongs ) then

  if ( latInterval < 2 ) then

    latStart = (minlat - latInterval).Floor

    latEnd = (maxlat + latInterval).Ceiling

  else    ' If latInterval is "big" generate lats from the world

    latStart = -90

    latEnd = 90

  end

  if ( lonInterval < 2 ) then

    lonStart = (minlon - lonInterval).Floor

    lonEnd = (maxlon + lonInterval).Ceiling

  else    ' If lonInterval is "big" generate lons from the world

    lonStart = -180

    lonEnd = 180

  end

  latList = {}

  for each lat in latStart .. latEnd by latInterval

    aLine = Line.Make( lonStart@lat, lonEnd@lat )

    prjLine = aLine.ReturnProjected( thisPrj ).ReturnClipped( xyRect )

    if ( prjLine <> nil ) then

      latList = latList.Add( {lat, prjLine} )

    end

  end

  lonList = {}

  for each lon in lonStart .. lonEnd by lonInterval

    aLine = Line.Make( lon@latStart, lon@latEnd )

    prjLine = aLine.ReturnProjected( thisPrj ).ReturnClipped( xyRect )

    if ( prjLine <> nil ) then

      lonList = lonList.Add( {lon, prjLine} )

    end

  end

  for each aList in latList

    lat = aList.Get(0)

    prjLine = aList.Get(1)

    if ( doGraticule ) then

      gPolyLine = {}

      for each ptList in prjLine.AsList

        gPtList = {}

        for each aPt in ptList

          thePt = dOrigin + ( ((aPt - xyOrigin) / xySize) * dSize)

          gPtList = gPtList.Add( thePt )

        end

        gPolyLine = gPolyLine.Add( gPtList )

      end

      theGratLine = GraphicShape.Make( PolyLine.Make(gPolyLine) )

      thegratLine.setobjecttag("theGratLine")

      theGraphics.Addbatch( theGratLine )

      theGratLine.SetSymbol( gratLine )

    end

    for each ptList in prjLine.AsList

      for each endPt in { ptList.Get(0), ptList.Get(ptList.Count-1) }

        ' Make a latitude label

        deg=lat.Abs.Truncate

        labelString = deg.AsString+"°"

        t = ( lat.Abs - deg ) * 60

        minute=t.Truncate

        if ( (t - minute) >= 0.9998 ) then

          minute = minute + 1

        end

        if ( minute > 0 ) then

           labelString = labelString+minute.AsString+"'"

        end

        if ( (t - minute) > 0.0002 ) then

          sec= (t-minute) * 60

          sec= sec.Truncate

          labelString=deg.AsString++minute.AsString+"'"+sec.AsString

          if(sec<1) then

            labelString=deg.AsString++minute.AsString+"'00"

          end

        end

  ' ... put latitude label

        aPt = dOrigin + ( ((endPt - xyOrigin) / xySize) * dSize)

        mygText=GraphicText.Make(labelString,aPt)

        mygText.setobjecttag("mygText")

        theGraphics.Addbatch(mygText)

        mygText.SetSymbol(geolsymbol)

        gpoint2 = GraphicShape.Make(aPt)

        tph=TextPositioner.Make(gpoint2.GetClass)

        if ( aPt.GetX = dRect.GetLeft ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) )

          theGratLine.setobjecttag("theGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt - (0.1@0))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(90)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_LEFT)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

        elseif ( aPt.GetX = dRect.GetRight ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) )

          theGratLine.setobjecttag("theGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt + (0.1@0))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(-90)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_RIGHT)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

        elseif ( aPt.GetY = dRect.GetBottom ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt-(0@0.05), aPt ) )

          theGratLine.setobjecttag("theGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt)

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(0)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_BELOW)

        elseif ( aPt.GetY = dRect.GetTop ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt+(0@0.05), aPt ) )

          theGratLine.setobjecttag("theGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt + (0@0.1))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(0)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ABOVE)

        end

        tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

        mygText.SetOrigin(tph.GetOrigin)

        mygText.Invalidate

      end

    end

  end

  for each aList in lonList

    lon = aList.Get(0)

    prjLine = aList.Get(1)

    if ( doGraticule ) then

      gPolyLine = {}

      for each ptList in prjLine.AsList

        gPtList = {}

        for each aPt in ptList

          thePt = dOrigin + ( ((aPt - xyOrigin) / xySize) * dSize)

          gPtList = gPtList.Add( thePt )

        end

        gPolyLine = gPolyLine.Add( gPtList )

      end

      theGratLine = GraphicShape.Make( PolyLine.Make(gPolyLine) )

      thegratline.setobjecttag("ThegratLine")

      theGraphics.Addbatch( theGratLine )

      theGratLine.SetSymbol( gratLine )

    end

    for each ptList in prjLine.AsList

      for each endPt in { ptList.Get(0), ptList.Get(ptList.Count-1) }

        ' Make a longitude label

        deg=lon.Abs.Truncate

        labelString = deg.AsString+"°"

        t= ( lon.Abs - deg ) * 60

        minute=t.Truncate

        if ( (t - minute) >= 0.9998 ) then

          minute = minute + 1

        end

        if ( minute > 0 ) then

           labelString = labelString+minute.AsString+"'"

        end

        if ( (t - minute) > 0.0002 ) then

          sec= (t-minute) * 60

          sec= sec.Truncate

          labelString=deg.AsString++minute.AsString+"'"+sec.AsString

          if(sec<1) then

            labelString=deg.AsString++minute.AsString+"'00"

          end

        end

  ' ... put longitude label

        aPt = dOrigin + ( ((endPt - xyOrigin) / xySize) * dSize)

        mygText=GraphicText.Make(labelString,aPt)

        mygText.setobjecttag("mygtext")

        theGraphics.Addbatch(mygText)

        mygText.SetSymbol(geolsymbol)

        if ( aPt.GetX = dRect.GetLeft ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) )

          theGratLine.setobjecttag("TheGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt - (0.1@0))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(90)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_LEFT)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

        elseif ( aPt.GetX = dRect.GetRight ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) )

          theGratLine.setobjecttag("TheGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt + (0.1@0))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(-90)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_RIGHT)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

        elseif ( aPt.GetY = dRect.GetBottom ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt-(0@0.05), aPt ) )

          theGratLine.setobjecttag("TheGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt)

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(0)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_BELOW)

        elseif ( aPt.GetY = dRect.GetTop ) then

          theGratLine = GraphicShape.Make( Line.Make( aPt+(0@0.05), aPt ) )

          theGratLine.setobjecttag("TheGratLine")

          theGraphics.Addbatch( theGratLine )

          theGratLine.SetSymbol( gratLine )

          gPoint2 = GraphicShape.Make(aPt + (0@0.1))

          tph=TextPositioner.Make(gPoint2.GetClass)

          mygText.SetAngle(0)

          tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

          tph.setVAlign(#TEXTPOSITIONER_VALIGN_ABOVE)

        end

        tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

        mygText.SetOrigin(tph.GetOrigin)

        mygText.Invalidate

      end

    end   ' of foreach in prjLine

  end   ' of foreach in lonList

end   ' of if (doLatLongs)

if ( doXYGrid ) then

'Draw metres graticule as lines, with coordinates all around

' vertical lines

  xoffset = 0.0625@0

  yoffset = 0@0.0625

  for each x in gratxs .. gratxe by gratdx

    if ( (x < xMin) or (x > xMax) ) then

      continue

    end

    for each y in gratys .. gratye by gratdy

      if ( (y < yMin) or (y > yMax) ) then

        continue

      end

      aPt = dOrigin + ( ((x@y - xyOrigin) / xySize) * dSize)

      aPolyLine = PolyLine.Make( {

        { aPt-xoffset, aPt+xoffset, aPt, aPt-yoffset, aPt+yoffset } } )

      ggLine = aPolyLine.ReturnClipped( dRect )

      gLine = GraphicShape.Make( ggLine )

      gline.setobjecttag("gline")

      theGraphics.Addbatch( gLine )

      gLine.SetSymbol(blackline)

    end

  end

  for each x in gratxs .. gratxe by gratdx

    if ( (x < xMin) or (x > xMax) ) then

       continue

    end

' put easting label at ymax

    aPt = dOrigin + ( ((Point.Make(x,yMax) - xyOrigin) / xySize) * dSize)

    gLine = GraphicShape.Make( Line.Make( aPt, aPt-(0@0.05) ) )

    gline.setobjecttag("gline")

      theGraphics.Addbatch( gLine )

    gLine.SetSymbol( blackLine )

    aPt = aPt + Point.Make(0,0.02)

    mygText=GraphicText.Make(x.SetFormat("dddddd").AsString, aPt)

    mygText.setobjecttag("mygText")

    theGraphics.Addbatch(mygText)

    mygText.SetSymbol(xySymbol)

    gPoint2 = GraphicShape.Make(aPt)

    tph=TextPositioner.Make(gPoint2.GetClass)

    tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

    tph.setVAlign(#TEXTPOSITIONER_VALIGN_TOP)

    tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

    mygText.SetOrigin(tph.GetOrigin)

    mygText.Invalidate

' put easting label at ymin

    aPt = dOrigin + ( ((Point.Make(x,yMin) - xyOrigin) / xySize) * dSize)

    gLine = GraphicShape.Make( Line.Make( aPt, aPt+(0@0.05) ) )

    gLine.setobjecttag("gLine")

    theGraphics.Addbatch( gLine )

    gLine.SetSymbol( blackLine )

    mygText=GraphicText.Make(x.SetFormat("dddddd").AsString, aPt)

    mygText.setobjecttag("mygText")

    theGraphics.Addbatch(mygText)

    mygText.SetSymbol(xySymbol)

    gPoint2 = GraphicShape.Make(aPt + (0@0.02))

    tph=TextPositioner.Make(gPoint2.GetClass)

    tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER)

    tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

    tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

    mygText.SetOrigin(tph.GetOrigin)

    mygText.Invalidate

  end  ' of for each x

  for each y in gratys .. gratye by gratdy

' horizontal lines

    if ( (y < yMin) or (y > yMax) ) then

       continue

    end

' put northing label at xmin

    aPt = dOrigin + ( ((Point.Make(xMin,y) - xyOrigin) / xySize) * dSize)

    gLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) )

    gLine.setobjecttag("gLine")

    theGraphics.Addbatch( gLine )

    gLine.SetSymbol( blackLine )

    aPt = aPt - Point.Make(0.02,0)

    mygText=GraphicText.Make(y.SetFormat("ddddddd").AsString, aPt )

    mygtext.setobjecttag("mygtext")

    theGraphics.Addbatch(mygText)

    mygText.SetSymbol(xySymbol)

    mygText.SetAngle(90)

    gPoint2 = GraphicShape.Make(aPt)

    tph=TextPositioner.Make(gPoint2.GetClass)

    tph.setHAlign(#TEXTPOSITIONER_HALIGN_BEFORE)

    tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

    tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

    mygText.SetOrigin(tph.GetOrigin)

    mygText.Invalidate

' put northing label at xmax

    aPt = dOrigin + ( ((Point.Make(xMax,y) - xyOrigin) / xySize) * dSize)

    gLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) )

    gLine.setobjecttag("gLine")

    theGraphics.Addbatch( gLine )

    gLine.SetSymbol( blackLine )

    aPt = aPt + Point.Make(0.02,0)

    mygText=GraphicText.Make(y.SetFormat("ddddddd").AsString, aPt)

    mygtext.setobjecttag("mygtext")

    theGraphics.Addbatch(mygText)

    mygText.SetSymbol(xySymbol)

    mygText.SetAngle(-90)

    gPoint2 = GraphicShape.Make(aPt)

    tph=TextPositioner.Make(gPoint2.GetClass)

    tph.setHAlign(#TEXTPOSITIONER_HALIGN_AFTER)

    tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON)

    tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil)

    mygText.SetOrigin(tph.GetOrigin)

    mygText.Invalidate

  end   ' of foreach y

end   ' of if (doXYGrid)

thegraphics.endbatch

for each agraphic in thegraphics

 agraphic.setselected(false)

end

if (nil<>thegraphics.findbyobjecttag("mygText")) then

  for each agraphic in thegraphics.findallbyobjecttag("mygtext")

    agraphic.setselected(true)

    agraphic.setobjecttag(nil)

  end

  thegraphics.groupselected

  for each agraphic in thegraphics

   agraphic.setselected(false)

  end

end

if (nil<>thegraphics.findbyobjecttag("theGratLine")) then

    for each agraphic in thegraphics.findallbyobjecttag("theGratline")

      agraphic.setselected(true)

      agraphic.setobjecttag(nil)

    end

    thegraphics.groupselected

    for each agraphic in thegraphics

     agraphic.setselected(false)

    end

end

if (nil<>thegraphics.findbyobjecttag("gline")) then

    for each agraphic in thegraphics.findallbyobjecttag("gline")

      agraphic.setselected(true)

      agraphic.setobjecttag(nil)

    end

    thegraphics.groupselected

    for each agraphic in thegraphics

     agraphic.setselected(false)

    end

end

theGraphics.Invalidate


Layout.SimplifyLegendByTheme
Simplifies a legendframe and groups by theme

Source Code

Description:   This script breaks a Legend Frame into Graphic Groups organized by the original themes.  The name of the theme is assigned to each graphic group, for further manipulation, if desired. If the theme has been classified, the graphic group for each theme is also subgrouped and each subgroup named by classification label.

This script is used in preparation for deleting a legend entry that is obvious, such as a theme showing the 48 states.  A selected set of theme groups can be respaced using the Align menu choice, or a single theme group can be ungrouped to the individual classification subgroups for rearranging to suit the spacing constraints on the layout document.

This script depends on the graphic elements being added to the legend in the order consistently used in ArcView 2.1.  This may change in future releases.

This script should be used with a button on the Layout GUI, or it could be called from a script that automates a layout creation.

Name:    Layout.SimplifyLegendByTheme

Requires:  A layout document with a selected legendframe.

Self:

Returns:

FileName:  grplegbt.ave


Layout.SimplifyLegendByTheme (Sample Script)
'Simplifies a legendframe and groups by theme

' Check that a single legend frame has been selected

theLayout = av.GetActiveDoc

theFList = theLayout.GetGraphics.GetSelected

if (theFList.Count <> 1) then

  MsgBox.Error("Please select a single legend frame1.","*** Error ***")

  exit

end

if (theFList.Get(0).GetClass.GetClassName <> "LegendFrame") then

  MsgBox.Error("Please select a single legend frame.","*** Error ***")

  exit

end

' Find the matching View and Legend

theLFrame = theFList.Get(0)

theViewFrame = theLFrame.GetViewFrame

if (theViewFrame = nil) then ' No view attached to legend

  MsgBox.Error("This is an empty legend frame","*** Error ***")

  exit

end

theView = theViewFrame.GetView

theThemes = theView.GetVisibleThemes

if (theThemes.Count < 1) then ' No visible themes

  MsgBox.Error("No visible themes in this legend.","*** Error ***")

  exit

end

' Create a list of theme names for later reference

theTNameList = List.Make

for each t in theThemes

  if (t.GetClass.GetClassName = "FTheme") then

    tName = t.GetName

    theLeg = t.GetLegend

    if (theLeg.GetLegendType <> #LEGEND_TYPE_SIMPLE) then

      if (t.IsSuffixUsed) then ' concatenate the field name

        tName = tName++"by"++theLeg.GetField.GetName

      end

    end

    theTNameList.Add(tName)

  end

end

' Simplify the legend frame

theLayout.GetGraphics.SimplifySelection

' First, process the legend graphics into subgroups:

'   these subgroups will be either theme names,

'   theme names with graphic, or a classification with graphic

theGList = theLayout.GetGraphics.GetSelected.Clone

theLayout.GetGraphics.UnselectAll

theSubGroupList = List.Make

for each i in 0 .. (theGList.Count - 1)

  theGList.Get(i).SetSelected(true)  ' Select the graphic

' If it is a graphic text, then assemble a subgroup -

'   any associated graphic immediately precedes it in the list

  if (theGList.Get(i).GetClass.GetClassName = "GraphicText") then

    theText = theGList.Get(i).GetText

    theLayout.GetGraphics.GroupSelected

    theSubGroup = theLayout.GetGraphics.GetSelected.Get(0)

    theSubGroup.SetName(theText)

    theSubGroupList.Add(theSubGroup)

    theSubGroup.Unselect

  end

end

' Second, assemble the subgroups into theme groups

theGroupList = List.Make

' Initialize for the first entry

theTName = theSubGroupList.Get(0).GetName

theSubGroupList.Get(0).SetSelected(true)

' Process the rest of the subgroups

for each i in 1 .. (theSubGroupList.Count - 1)

  theName = theSubGroupList.Get(i).GetName

  if (theTNameList.FindByValue(theName) > -1) then ' this is a new theme

    ' Group the previous one

    theLayout.GetGraphics.GroupSelected

    theGroup = theLayout.GetGraphics.GetSelected.Get(0)

    theGroup.SetName(theTName)

    theGroup.Unselect

    theGroupList.Add(theGroup)

    theTName = theSubGroupList.Get(i).GetName

  end

  ' Select the current subgroup

  theSubGroupList.Get(i).SetSelected(true)

end

' Finish up by grouping the last theme

theLayout.GetGraphics.GroupSelected

theGroup = theLayout.GetGraphics.GetSelected.Get(0)

theGroup.SetName(theTName)

theGroup.Unselect

theGroupList.Add(theGroup)

' Select the new groups, in anticipation of further manipulation

for each g in theGroupList

  g.SetSelected(true)

end

theLayout.GetGraphics.Invalidate


View.HighlightSelectedGraphics
Highlights selected graphics on a View document

Source Code

Description:   Highlights the selected graphic on a View document with the project's current selection color.  Can be installed as the apply event for a Tool in the View docGUI. Useful when the View has a large list of graphic objects, and the selection handles are not sufficient for indicating the current selection.

When the graphic is selected, the color will be changed to the current project selection color.  The color of unselected graphics will be changed to the unselected color specified in the script below. Note that the color of selected graphic polygons will not change, since by default ArcView uses a transparent symbol.

Name:    View.HighlightSelectedGraphics

Requires:  Must be the apply script for a tool in the View docGUI.

Self:

Returns:

FileName:  hiselgra.ave


View.HighlightSelectedGraphics (Sample Script)
'Highlights selected graphics on a View document

' Set selection color and non-selection color...

clrSelected   = av.GetProject.GetSelColor

clrUnselected = Color.GetBlack

' Select a graphic

v = av.GetActiveDoc

v.Select

lstGraphics = v.GetGraphics

if (lstGraphics.HasSelected.Not) then

  exit

end

' Change color appropriately...

for each g in lstGraphics

  if (g.IsSelected) then

    g.GetSymbol.SetColor(clrSelected)

    g.Invalidate

  else

    g.GetSymbol.SetColor(clrUnselected)

    g.Invalidate

  end

end


Table.Histogram
Displays a histogram for selected field in table

Source Code

Description:   Generates a histogram for the selected field in a Table. A new Chart document is created to display the histogram.  A temporary file is created to store interval counts and other information used to create the histogram.

Should be associated with the Click property of a button on the Table DocGUI.  An update script should be associated with the control to ensure that this script can only be executed when a numeric field is selected.

Name:    Table.Histogram

Requires:  A Table must be the active document.

Self:

Returns:

FileName:  histogrm.ave


Table.Histogram (Sample Script)
'Displays a histogram for selected field in table

' Gather information from the current Document

theTable = av.GetActiveDoc

vt = theTable.GetVTab

theField = theTable.GetActiveField

' Get the number of intervals for the histogram

numString = MsgBox.Input("Enter number of intervals:","Histogram","10")

if ((numString = Nil) or (numString.IsNumber.Not)) then

  exit

end

numIntervals = numString.AsNumber

' Create a temporary VTab to hold interval counts

tempVTab   = VTab.MakeNew(Filename.GetTmpDir.MakeTmp("histo","dbf"), dBASE)

labelField = Field.Make("Range", #FIELD_CHAR, 28, 0)

countField = Field.Make("Count", #FIELD_LONG, 12, 0)

tempVTab.AddFields( {labelField, countField} )

numReads = 0

' Determine number of records to process

if (vt.GetSelection.Count = 0) then

  iter = vt

  n = vt.GetNumRecords

else

  iter = vt.GetSelection

  n = iter.Count

end

maxNumReads = n * 2

' Loop through records once to get Min and Max values

minimum = Nil

maximum = Nil

for each rec in iter

  numReads = numReads + 1

  av.SetStatus(numReads / maxNumReads * 100)

  curval = vt.ReturnValueNumber(theField, rec)

  if (minimum = NIL) then  'first time through

    minimum = curval

    maximum = curval

  else

    minimum = minimum Min curval

    maximum = maximum Max curval

  end

end

' Calculate the interval size

intervalSize = (maximum - minimum) / numIntervals

' Populate the VTab with interval labels, initializing interval counts to 0

for each i in 0..(numIntervals-1)

  rec = tempVTab.AddRecord

  tempVTab.SetValueString(labelField, rec,

    (minimum + (i * intervalSize)).AsString++" - "++

    (minimum + ((i + 1) * intervalSize)).AsString)

  tempVTab.SetValueNumber(countField, rec, 0)

end

' Loop through records again, incrementing the appropriate counter based

' on the interval in which the value falls

for each rec in iter

  numReads = numReads + 1

  av.SetStatus(numReads / maxNumReads * 100)

  curval = vt.ReturnValueNumber(theField, rec)

  index = ((curval - minimum) / intervalSize).Floor

  if (index = numIntervals) then

    index = numIntervals - 1

  end

  tempVTab.SetValueNumber(countField, index, tempVTab.ReturnValuenumber

    (countField, index) + 1)

end

' Make a Chart document and display it

newChart = Chart.make(tempVTab, {countField})

newChart.SetRecordLabelField(labelField)

newChart.GetTitle.SetName("Histogram of"++theField.GetName)

av.GetProject.AddDoc(newChart)

newChart.GetWin.Open


View.RedefineImageExtent
Redefines the extent of an image theme

Source Code

Description: Sets an image map extent to the user specified rectangle. This allows the 'moving' of images to a new coordinate space on the View.

Name: View.RedefineImageExtent

Requires: Must be installed as the apply event for a tool.  The following update script can be used to control the availability of the tool:

  theView = av.GetActiveDoc

  SELF.SetEnabled((theView.GetActiveThemes.Count > 0) AND
    (theView.GetActiveThemes.Get(0).Is(ITheme)))

Self:

Returns:

FileName: imgext.ave


View.RedefineImageExtent (Sample Script)
'Redefines the extent of an image theme

theView  = av.GetActiveDoc

thmImage = theView.GetActiveThemes.Get(0)

' If active theme isn't an image, tell user and exit

if (thmImage.Is(ITheme).Not) then

  MsgBox.Info("The active theme must be an image", "View.RedefineImageExtent")

  return nil

end

r = theView.ReturnUserRect

if (r <> NIL) then

  thmImage.GetImgSrc.SetMapExtent(r)

  thmImage.Invalidate(TRUE)

end


View.IdentifyLinked
Replaces Identify Tool with smarter version for links

Source Code

Description:   When this is used in conjunction with (after) the View.One2Many script this tool will effectively replace the identify tool. The result of using this tool instead of the identify tool will be that when you identify a feature whose FTab has links to it will be to see the values in the linked tables

Name:    View.IdentifyLinked

Requires:  t should be attached to a tool (apply) in the view and use the View.TabularThemesUpdate

Self:

Returns:

FileName:  idlinked.ave


View.IdentifyLinked (Sample Script)
'Replaces Identify Tool with smarter version for links

'Tool to replace the ID tool, but handles linked tables too. Links

'have to be set up with View.SetOneToMany

theView = av.GetActiveDoc

found = FALSE

p = theView.GetDisplay.ReturnUserPoint

for each t in theView.GetActiveThemes

  if (t.Is( FTHEME )) then

    v = t.GetFTab

    if (v.IsLinked) then

      oneBitMap = v.GetSelection

      oneBitMap.ClearAll

      theObjTags = t.GetObjectTag

      if ((theObjTags = nil) or (theObjTags.Count < 3)) then

         MsgBox.Error("Please set the links up for this theme first"

                      +NL+"with the special button in the View document.", "No one-to-many on active theme:"++t.GetName)

         exit

      end

      manyTableName = theObjTags.Get(0)

      manyTable = av.GetProject.FindDoc(manyTableName)

      manyVTab = manyTable.GetVTab

      fm = theObjTags.Get(1)

      manyBitMap = manyVTab.GetSelection

      keepSelected = theObjTags.Get(2)

    end

    recs = t.FindByPoint(p)

    for each rec in recs

      found = TRUE

      if (v.IsLinked) then

         oneBitMap.Set(rec)

         v.UpdateSelection

         manyVTab.UpdateSelection

      end

      idlabel = t.GetName++"-"

      f = t.GetLabelField

      if (f = NIL) then

        idlabel = idlabel++rec.SetFormat("d").AsString

      else

        idlabel = idlabel++v.ReturnValueString(f,rec)

      end

      v.Identify(rec, idlabel)

    end

    if ((v.IsLinked) and (recs.count > 0)) then

       recs = manyVTab.GetSelection

       for each rec in recs

          idlabel = manyVTab.GetName++"-"

          idlabel = idlabel++manyVTab.ReturnValueString(fm,rec)

          manyVTab.Identify(rec, idlabel)

       end

    end

  end

  if ((v.IsLinked) and (keepSelected.Not)) then

     oneBitMap.ClearAll

     manyBitMap.ClearAll

  end

end

if (not found) then

  System.Beep

end


View.CreateImageCatalog
Creates image catalog from image themes in view

Source Code

Description:   Takes all the images in a selected view and creates a dBASE table on disk which can be used as an Image Catalog. If the view contains feature themes, they are skipped over. If the view is not the active document, you are presented with a list of all the views in the project. The dBASE file is added to the project for review. The new image catalog is added to the same view as the images.

Name:    View.CreateImageCatalog

Requires:  A view with some georeferenced image themes. The script assumes the images are already "tiled" (appear side by side when viewed individually). It is up to you to ensure that the view does not already contain image catalogs.

Self:

Returns:

FileName:  imgcat.ave


View.CreateImageCatalog (Sample Script)
'Creates image catalog from image themes in view

theView = av.GetActiveDoc

dl = {}

if (theView.Is(View).Not) then

  for each d in av.GetProject.GetDocs

    if (d.Is(View)) then

      dl.Add(d)

    end

  end

  theView = MsgBox.ListAsString(dl,"Create image catalog from:", "Create image catalog")

end

theIC = FileDialog.Put("imgcat.dbf".AsFilename, "*.dbf","Save image catalog")

if (theIC = nil) then return nil end

theVTab = VTab.MakeNew(theIC,dBASE)

theTable = Table.Make(theVTab)

f1 = Field.Make("IMAGE",#FIELD_CHAR,75,0)

f2 = Field.Make("XMIN",#FIELD_DECIMAL,20,8)

f3 = Field.Make("YMIN",#FIELD_DECIMAL,20,8)

f4 = Field.Make("XMAX",#FIELD_DECIMAL,20,8)

f5 = Field.Make("YMAX",#FIELD_DECIMAL,20,8)

theVTab.AddFields({f1,f2,f3,f4,f5})

for each i in theView.GetThemes

  if (i.Is(ITheme).Not) then continue end

  rec = theVTab.AddRecord

  theVTab.SetValue(f1, rec, i.GetImgSrc.GetSrcName.GetDataSource)

  theVTab.SetValue(f2, rec, i.GetImgSrc.ReturnExtent.GetLeft)

  theVTab.SetValue(f3, rec, i.GetImgSrc.ReturnExtent.GetBottom)

  theVTab.SetValue(f4, rec, i.GetImgSrc.ReturnExtent.GetRight)

  theVTab.SetValue(f5, rec, i.GetImgSrc.ReturnExtent.GetTop)

end

theTable.GetWin.Open

catTheme = ITheme.Make(ImgSrc.Make(SrcName.Make(theIC.AsString)))

theView.AddTheme(catTheme)


Script.MakeScriptFromFile
Imports text from file into new SEd document(s)

Source Code

Description:   Creates a new SEd from the specified source file(s) and adds the new SEd to the project.  Checks for a Name specified in the header and if found sets the SEd name to the header name, otherwise uses the basename of the source file.  Uses the ArcView standard header.

To optimize performance for scripts which don't use the standard header, only the first <n> lines in the file are searched to find the name.  The number of lines to search is specified as the lineSearchLimit.

Name:    Script.MakeScriptFromFile

Requires:

Self:

Returns:

FileName:  imscript.ave


Script.MakeScriptFromFile (Sample Script)
'Imports text from file into new SEd document(s)

' Only search the first few lines in the header for the script name...

lineSearchLimit = 5

aveFileNameList = FileDialog.ReturnFiles( {"*.ave", "*.txt"}, {"Script (*.ave)",

  "Text File (*.txt)"}, "Load Scripts",0 )

if ( aveFileNameList.Count < 1 ) then

  exit

end

total = aveFileNameList.Count

counter = 0

for each aveFileName in aveFileNameList

  counter = counter + 1

  lineCount = 0

  av.ShowMsg( aveFileName.GetBaseName )

  aveFile = LineFile.Make( aveFileName, #FILE_PERM_READ )

  ' Search the file for a Name entry in the header...

  hasName  = false

  done     = false

  While ( done.Not )

    theString = aveFile.ReadElt

    lineCount = lineCount + 1

    if ( theString = nil ) then

      done = true

    elseif ( theString.Contains( "Name:" )) then

      sedName = theString.Substitute( "Name:", "").BasicTrim( "' "," " )

      if ( sedName <> "" ) then

        hasName = true

      end

      done = true

    elseif( lineCount = lineSearchLimit ) then

      done = true

    else

      continue

    end

  end

  ' Load the entire contents of the script file into a list...

  stringList = List.Make

  aveFile.GotoBeg

  aveFile.Read( stringList, aveFile.GetSize )

  aveFile.Close

  ' Convert the list of strings to a long source string...

  sourceString = nil

  for each s in stringList

    if ( sourceString = nil ) then

      sourceString = s

    else

      sourceString = sourceString + nl + s

    end

  end

  ' Make new SEd from the source string....

  if ( hasName.Not ) then

    sedName = aveFileName.GetBaseName

  end

  theSEd = SEd.MakeFromSource( sourceString, sedName )

  av.GetProject.AddDOC( theSEd )

  theSEd.GetWin.Open

  av.SetStatus( (counter/total) * 100 )

end

av.ClearStatus

av.ClearMsg


Table.JoinOrLink
Joins or Links two tables

Source Code

Description:   Shows how to Join or Link two tables. Both Join and Link require the specification of a common field from each table (common in value, not name) upon which the operation will be performed.

A Join assumes a one to one condition, i.e. there is a one to one relationship between the two tables based upon the contents of the Join field.  The fields of both Tables will merge into a single document.

A Link is used when there is a one to many relationship.  The Tables are not merged, but selecting a row in the origin Table will select multiple records in the linked Table.

Name:    Table.JoinOrLink

Requires:  This example script includes references to data which must be edited and changed before using.

Self:

Returns:

FileName:  jnlnktbl.ave


Table.JoinOrLink (Sample Script)
'Joins or Links two tables

' Find the table and join field for the first table....

tab1 = av.GetProject.FindDoc("Parcels")

vtab1 = tab1.GetVTab

field1 = vtab1.FindField("Code")

' Find the table and join field for the second table...

tab2 = av.GetProject.FindDoc("Assessor")

vtab2 = tab2.GetVtab

field2 = vtab2.FindField("Code")

' Now perform the join....

vtab1.Join( field1, vtab2, field2)

'' For Link, uncomment the line below and comment the line above...

' vtab1.Link( field1, vtab2, field2)


View.LabelOnlyFeaturesBiggerThanLabels
Labels only features whose labels are smaller than their own extents

Source Code

Description:   If the GraphicText is wider than the width of the feature it is labeling, then the label will not be placed.  This is a slight derivation of the auto-labeling script that was shipped with ArcView 2.0

Name:    View.LabelOnlyFeaturesBiggerThanLabels

Requires:

Self:

Returns:

FileName:  labwthin.ave


View.LabelOnlyFeaturesBiggerThanLabels (Sample Script)
'Labels only features whose labels are smaller than their own extents

av.ShowMsg("Labeling themes...")

av.ShowStopButton

av.SetStatus(0)

theView = av.GetActiveDoc

theGraphics = theView.GetGraphics

thePrj = theView.GetProjection

cancelled = false

numThemes = theView.GetThemes.Count

themeNum = 0

for each theTheme in theView.GetThemes

  ' Check if theme is a candidate for labeling

  if (theTheme.Is(FTheme).Not) then continue end

  theField = theTheme.GetLabelField

  theTxPos = theTheme.GetTextPositioner

  if ((theTheme.IsActive and theTheme.IsVisible and (theField <> nil) and (theTxPos <> nil)).not ) then

    continue

  end

  ' Create labels for the Theme.  If there is a selection, label selected

  ' features.  Otherwise label all features.  Add labels to the View's

  ' graphics list and attach them to the Theme.

  av.ShowMsg("Labeling"+theTheme.GetName+"...")

  theThemeGraphics = theTheme.GetGraphics

  theVTab = theTheme.GetFTab

  theShape = theVTab.GetShapeClass.MakeNull

  if(theVTab.GetSelection.Count = 0) then

    recs = theVTab

    numRecs = recs.GetNumRecords

  else

    recs = theVTab.GetSelection

    numRecs = recs.Count

  end

  recNum = 1

  for each rec in recs

    t = theVtab.ReturnValueString(theField, rec)

    if (t.IsNull) then continue end

    label = GraphicText.Make(t, 0@0)

    label.SetDisplay(theView.GetDisplay)

    label.SetSelected(true)

    theVTab.QueryShape(rec, thePrj,theShape)

    if (theShape.IsNull) then continue end

    theSymSize = theTheme.ReturnSymbolSize(rec)

    'This next if condition is really the only difference between this and the original script.

    if ((theShape.ReturnExtent.GetWidth > label.GetBounds.GetWidth) or (theShape.Is(Point)))then

      theTxPos.Calculate(theShape, label.GetExtent, theSymSize, nil)

      label.SetOrigin(theTxPos.GetOrigin)

      label.SetAngle(theTxPos.GetAngle)

      if (theTheme.GetFixedSizeText = true) then

        label.SetFixedSize(true)

      end

      theGraphics.AddBatch(label)

      theThemeGraphics.Add(label)

    end

    n = themeNum * numRecs + recNum

    d = numThemes * numRecs

    cancelled = av.SetStatus(100 * (n / d)).not

    if (cancelled = true) then

      break

    end

    recNum = recNum + 1

  end

  if (cancelled = true) then

    break

  end

  themeNum = themeNum + 1

end

theGraphics.EndBatch

av.SetStatus(100)

av.ClearMsg


View.HotLinkImage
Hotlinks an image to display in a View

Source Code

Description:   A hotlink script that can be used in place of Link.ImageFile to display an image as a theme in a View document rather than in an ImageWin. Some images will display faster and have better display quality when displayed as themes in Views.

The View TOC is automatically hidden and locked when the View displaying the hotlinked image is opened. When the image View is closed, it will be automatically removed from the project.

A new docGUI, comprised of only the controls that are appropriate for viewing the image (such as pan, zoom, etc.) may be created and assigned to the image View by uncommenting the lines of code as indicated in the body of the script.  Create a new docGUI by cloning an existing docGUI and modifying with the Customize Dialog Box.  See docGUI in the Avenue Help for further information, or use the sample script called GUIManager.

Name:    View.HotLinkImage

Requires:

Self:  the chosen feature. Must be the full pathname to a raster file format supported by the View document.

Returns:

FileName:  lnkimgvw.ave


View.HotLinkImage (Sample Script)
'Hotlinks an image to display in a View

theVal = SELF

if (Not (theVal.IsNull)) then

  if (File.Exists(theVal.AsFileName)) then

    srcImage = SrcName.Make(theVal)

    t = Theme.Make(srcImage)

    t.SetVisible(TRUE)

    v = View.Make

    v.AddTheme(t)

    v.SetTOCWidth(0)

    v.SetTOCUnresizable(TRUE)

    v.SetName(theVal.AsFileName.GetBaseName)

    if (av.FindScript("View.CloseImageView") = NIL) then

      s = Script.Make("av.GetProject.RemoveDoc(SELF)")

      s.SetName("View.CloseImageView")

      av.GetProject.AddScript(s)

    end

    v.SetCloseScript("View.CloseImageView")

    '' If you've created a special GUI for this document,

    '' activate here using something like the following...

    ' v.SetGUI("aNewGUIName")

    ' av.FindGUI(v.GetGUI).Activate

    v.GetWin.Open

  else

    MsgBox.Warning("File "+theVal+" not found.","Hot Link")

  end

end


Graphics.MakeRGBColors
Create Colors from a RGB list

Source Code

Description:   This script loads a RGB color list and creates colors in the color palette from these values.  The RGB should be in the format: RED , GREEN , BLUE, e.g. 255,255,255.

Name:    Graphics.MakeRGBColors

Requires:  A prepared RGB color list in ASCII format

Self:

Returns:

FileName:  makergb.ave


Graphics.MakeRGBColors (Sample Script)
'Create Colors from a RGB list

sw = av.GetSymbolWin

sw.Open

p = sw.GetPalette

plc = p.GetList(#PALETTE_LIST_COLOR)

  'To automate the process with a file:

colornam = FileDialog.Show("*.*","Color File","Select Color File to Convert")

if (colornam = nil) then

  exit

end

colorFile  = LineFile.Make(colornam, #FILE_PERM_READ)

totalRecs = colorFile.GetSize

while (true)

    buf = colorFile.ReadElt

    if (buf = Nil) then

      break

    end

    if (buf = "END") then

      break

    end

    colorTokens = buf.AsTokens(",")

    theID = colorTokens.Get(0)

    thered = colorTokens.Get(1).AsNumber

    thegreen=colorTokens.Get(2).AsNumber

    theblue= colorTokens.Get(3).AsNumber

    rgbl={thered,thegreen,theblue}

    x = color.Make

    x.SetRGBList(rgbl)

    plc.Add(x)

end

  p.SetList(#PALETTE_LIST_COLOR, plc)

  sw.RefreshPalette(#PALETTE_LIST_COLOR)

  sw.SetPanel(#SYMBOLWIN_PANEL_COLOR)


Geocode.MatchCoordinate
Matches an address record to a coordinate

Source Code

Description:   This tool begins execution by providing a list of unmatched addresses in the active geocoded theme. Select one of the addresses in the list then specify a location with the cursor. This will create a point on the specified location and link it to the appropriate record in the feature table. This changes the AV_STATUS value for the record from U to C.

Name:    Geocode.MatchCoordinate

Requires:  a View must be the active document. There must be an active geocoded theme and at least one record where the AV_STATUS value = U. Install this script as the Apply script for a tool.

NOTE: Commented following the main body of this script are the required Click and Update scripts for the tool.  These must be installed in order for this script to function properly.

Self:

Returns:

FileName:  matchcoo.ave


Geocode.MatchCoordinate (Sample Script)
'Matches an address record to a coordinate

aView = av.GetActiveDoc

record = SELF.GetObjectTag.Get(0)

aTheme = SELF.GetObjectTag.Get(1)

' get FTab for theme

aFTab = aTheme.GetFTab

' get point

pt = aView.GetDisplay.ReturnUserPoint

' start editing...

aView.SetEditableTheme(aTheme)

aField = aFTab.FindField("shape")

aFTab.SetValue(aField, record, pt)

aField = aFTab.FindField("Av_status")

aFTab.SetValue(aField, record, "C")

' stop editing...

aView.SetEditableTheme(Nil)

' leave updated record selected

selection = aFTab.GetSelection

selection.ClearAll

selection.Set(record)

aFTab.UpdateSelection

' redraw

aTheme.Invalidate(TRUE)

av.GetActiveGui.GetToolbar.SelectDefault

'---------------------------------------------------------------------------

' Name: MatchAddressToCoordinate - CLICK script

'

' Use the following as a click script to provide the list of unmatched

' addresses:

'

'  ' get view

'  aView = av.GetActiveDoc

'

'  ' get active theme

'  aTheme = av.GetActiveDoc.GetActiveThemes.Get(0)

'

'  ' get FTab for theme

'  aFTab = aTheme.GetFTab

'  aFtab.RememberSelection

'

'  expr = "[av_status] ="++"""U"""

'  aFtab.Query(expr,aFTab.GetSelection,#VTAB_SELTYPE_NEW)

'  aFTab.UpdateSelection

'

'  lstUnmatched = {}

'  aField = aFTab.FindField("av_add")

'  for each record in aFTab.GetSelection

'    lstUnmatched.Add(record.AsString+":"++

'    (aFtab.ReturnValueString(aField,record)))

'  end

'

'  a = MsgBox.ListAsString(lstUnmatched,"Select an address to match",

'      "Unmatched addresses")

'

'  if (a = nil) then

'    aFtab.SetSelection(aFtab.GetlastSelection)

'    aFtab.UpdateSelection

'    av.GetActiveGui.GetToolbar.SelectDefault

'    exit

'  end

'

'  lstTokens = a.AsTokens(":")

'  record = lstTokens.Get(0)

'

'  SELF.SetObjectTag({record.AsNumber,aTheme})

'

'  MsgBox.Info("Point to location to match chosen address:", "Match Address")

'

'---------------------------------------------------------------------------

'---------------------------------------------------------------------------

' Name: MatchAddressToCoordinate - UPDATE script

'

' Use the following as an update script to enable the tool when appropriate:

'

'  ' get active theme

'  if ( av.GetActiveDoc.GetActiveThemes.Count = 0 ) then

'    SELF.SetEnabled(FALSE)

'    exit

'  end

'  aTheme = av.GetActiveDoc.GetActiveThemes.Get(0)

'

'  if (aTheme.Is(ITheme)) then

'    SELF.SetEnabled(FALSE)

'    exit

'  end

'

'  ' get FTab for theme

'  aFTab = aTheme.GetFTab

'

'  ' the FTab should be a geocoded FTab

'  if ( not ( aFTab.IsGeocoded ) ) then

'    SELF.SetEnabled(FALSE)

'    exit

'  end

'

'  SELF.SetEnabled(TRUE)

'---------------------------------------------------------------------------


MIF2SHP Converter
Converts MapInfo Interchange Format (*.MIF) to ArcView shapefile format

Source Code

Description:   Imports a .MIF and its corresponding .MID (if exists) and creates a native ArcView shapefile.

The script is split up into two parts. The first part reads through the .MIF file. It senses these components:

    Delimiter = delimiter for MID attributes

    Columns   = the column definitions

    Point     = a point feature

    Region    = a region feature

    PLine     = a polyline feature

    Line      = a line feature

The results go into an FTab which gets created when the first geometric feature is encountered. Until then, the field definitions which are encountered are kept in a list.

As geometric features are encountered, records are added to the FTab. After the file is read, the attribute values are read from the .MID file. See notes included below.

Name:    MIF2SHP Converter

Requires:

Self:

Returns:

FileName:  mif2shp.ave


MIF2SHP Converter (Sample Script)
'Converts MapInfo Interchange Format (*.MIF) to ArcView shapefile format

' Set up the filenames

mif_name = FileDialog.Show("*.mif", "MapInfo Interchange", "Import MIF")

if (mif_name = nil) then

  exit

end

mid_name = mif_name.clone

mid_name.SetExtension("mid")

if (mid_name.IsFile.Not) then

  ok = MsgBox.YesNo( "MID file not found, convert anyway?",

    "Convert MIF to Shapefile", true )

  if (ok) then

    hasMID = false

  else

    exit

  end

else

  hasMID = true

end

' Create the output object

'

out_name = mif_name.clone

out_name.SetExtension("shp")

out_name = FileDialog.Put( out_name, "*.shp", "Output Shapefile")

if (out_name = nil) then

  exit

end

' Create the input objects

'

av.ShowMsg("Opening files...")

mif_file = LineFile.Make(mif_name, #FILE_PERM_READ)

if ( hasMID ) then

  mid_file = LineFile.Make(mid_name, #FILE_PERM_READ)

end

tbl     = nil

fields  = list.Make

total   = mif_file.GetSize

counter = 0

av.ShowStopButton

' read the MIF file, looking for Delimiter, Columns, or features

'

av.ShowMsg( "Reading MIF..." )

while (mif_file.IsAtEnd.Not)

  counter = counter + 1

  proceed = av.SetStatus( (counter / total) * 100 )

  if ( proceed.Not ) then

    av.ClearStatus

    av.ShowMsg( "Stopped" )

    exit

  end

  buf = mif_file.ReadElt

  if ( buf = nil ) then

    break

  elseif ( buf.Left(9) = "Delimiter" ) then

    delimiter = buf.Extract(1).Middle(1, 1)

  elseif ( buf.Left(7) = "Columns" ) then

    for each i in 1..( buf.Extract(1).AsNumber )

      buf = mif_file.ReadElt

      counter = counter + 1

      proceed = av.SetStatus( (counter / total) * 100 )

      if ( proceed.Not ) then

        av.ClearStatus

        av.ShowMsg("Stopped")

        exit

      end

      ' parse the column definition

      buf = buf.Substitute(9.AsChar," ")  'Remove tabs and extra spaces

      buf = buf.Trim

      tokens = buf.AsTokens(" (),")

      if (tokens.Get(1) = "Decimal") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_DECIMAL,

                   tokens.Get(2).AsNumber, tokens.Get(3).AsNumber))

      elseif (tokens.Get(1) = "Logical") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_LOGICAL, 1, 0))

      elseif (tokens.Get(1) = "Smallint") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_DECIMAL, 4, 0))

      elseif (tokens.Get(1) = "Integer") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_DECIMAL, 8, 0))

      elseif (tokens.Get(1) = "Float") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_FLOAT, 4, 0))

      elseif (tokens.Get(1) = "Char") then

        fields.Add(Field.Make(tokens.Get(0), #FIELD_CHAR,

                   tokens.Get(2).AsNumber, 0))

      end

    end

  elseif ( buf.Left(6) = "Region" ) then

     if ( tbl = nil ) then    ' create the tbl?

       tbl = Ftab.MakeNew( out_name, Polygon )

       tbl.AddFields( fields )

       shape_field = tbl.FindField( "Shape" )

     end

     ' read the region, adds a record, sets the polygon

     ' number of polygons in the region

     npolys = buf.Extract(1).AsNumber

     pl = list.make

     for each j in 1..npolys

       pts = List.Make

       npts = mif_file.ReadElt.Trim.AsNumber

       for each i in 0..( npts - 1 )

         buf = mif_file.ReadElt

         counter = counter + 1

         proceed = av.SetStatus( (counter / total) * 100 )

         if ( proceed.Not ) then

           av.ClearStatus

           av.ShowMsg( "Stopped" )

           exit

         end

         pts.Add(Point.Make(buf.Extract(0).AsNumber, buf.Extract(1).AsNumber))

       end

       'add the poly to the list

      	pn = Polygon.Make( {pts} )

      	pl.Add( pn )

     end

     for each j in 1..( npolys - 1 ) by 1

       'merge the next polygon with the previous one

       pl.Set( 0, pl.Get(0).ReturnMerged(pl.Get(j)) )

     end

     tbl.SetValue( shape_field, tbl.AddRecord, pl.Get(0) )

  elseif ( buf.Left(5) = "PLine" ) then

     if ( tbl = nil ) then    ' create the tbl?

       tbl = Ftab.MakeNew( out_name, PolyLine )

       tbl.AddFields( fields )

       shape_field = tbl.FindField( "Shape" )

     end

     ' read the pline, adds a record, sets the pline

     '

     pts = List.Make

     npts = buf.Extract(1).AsNumber

     for each i in 0..( npts - 1 )

       counter = counter + 1

       proceed = av.SetStatus( (counter / total) * 100 )

       if (proceed.Not) then

         av.ClearStatus

         av.ShowMsg( "Stopped" )

         exit

       end

       buf = mif_file.ReadElt

       pts.Add(Point.Make( buf.Extract(0).AsNumber, buf.Extract(1).AsNumber) )

     end

     tbl.SetValue( shape_field, tbl.AddRecord, PolyLine.Make({pts}) )

  elseif ( buf.Left(4) = "Line" ) then

     if ( tbl = nil ) then    ' create the tbl?

       tbl = Ftab.MakeNew( out_name, PolyLine )

       tbl.AddFields( fields )

       shape_field = tbl.FindField( "Shape" )

     end

     ' add a line

     '

     pts = List.Make

     pts.Add(Point.Make(buf.Extract(1).AsNumber, buf.Extract(2).AsNumber))

     pts.Add(Point.Make(buf.Extract(3).AsNumber, buf.Extract(4).AsNumber))

     tbl.SetValue(shape_field, tbl.AddRecord, PolyLine.Make({pts}))

  elseif ( buf.Left(5) = "Point" ) then

     if (tbl = nil) then    ' create the tbl?

       tbl = Ftab.MakeNew( out_name, Point )

       tbl.AddFields( fields )

       shape_field = tbl.FindField( "Shape" )

     end

     ' add a point

     '

     pt = Point.Make(buf.Extract(1).AsNumber, buf.Extract(2).AsNumber)

     tbl.SetValue( shape_field, tbl.AddRecord, pt )

  end

end

av.ClearStatus

if (( hasMID ) and ( tbl <> Nil )) then

'

'

'  Read the MID file    - attribute values

'

'  Notes - the file can contain ",," to denote a null value. The AsTokens

'  request does not deal with this properly, so we substitute ", ," before

'  using AsTokens.

'

'  Our tokenizer may get messed up by an attribute value that contains

'  the delimiter. These values are quoted, so the result is an extra

'  entry in the vals list. We can sense this by looking for a quote

'  as the first character in the val entry, and if we find such a case

'  we get the next entry and concat them (along with the delimiter which

'  was stripped off).

'

  av.ShowMsg( "Reading MID..." )

  total = tbl.GetNumRecords

  counter = 0

  for each rec in tbl

    counter = counter + 1

    proceed = av.SetStatus( ( counter / total) * 100 )

    if ( proceed.Not ) then

      av.ClearStatus

      av.ShowMsg( "Stopped" )

      exit

    end

    buf = mid_file.ReadElt

    ' Fix made for the case where there were blank values

    ' at the beginning of record of the .mid.

    if (buf.Left(1) = delimiter) then       '<-- NEW LINE

      buf = """"+buf                        '<-- NEW LINE

    end                                     '<-- NEW LINE

    if (buf.Right(1) = delimiter) then      '<-- NEW LINE

      buf = buf+""""                        '<-- NEW LINE

    end                                     '<-- NEW LINE

    vals = buf.Substitute( ",,", ", ," ).AsTokens( delimiter )

    walker = 0

    for each i in 0..( fields.Count - 1 )

      val = vals.Get( walker )

      if (val.IsQuoted) then

        val = val.Unquote

      end

      keepwalking = true

      while (keepwalking)

        if ( val.Left(1) = """" ) then

          walker = walker + 1

          val = val + delimiter + vals.Get( walker )

          if (val.IsQuoted) then

            val = val.Unquote

          end

        else

          keepwalking = false

        end

      end

      tbl.SetValueString( fields.Get(i), rec, val )

      walker = walker + 1

    end

  end

end

av.ClearStatus

if (tbl = Nil) then

  MsgBox.Error( "No features found in"++mif_file.asstring, "Error")

else

  tbl.Flush

end

av.ShowMsg("Converted"++mif_file.asstring++"to"++out_name.AsString)


Graphics.MakePens
Makes pen symbols

Source Code

Description:   This script creates two new views, named Pens and Composite Pen, into which different line symbols are drawn. Using the appropriate requests, the line symbols are modified.

Name:    Graphics.MakePens

Requires:

Self:

Returns:

FileName:  mkpensym.ave


Graphics.MakePens (Sample Script)
'Makes pen symbols

'Make some pens

v1 = VectorPenDiamond.Make

v2 = VectorPenDot.Make

v3 = VectorPenHollow.Make

v4 = VectorPenHash.Make

v5 = VectorPenScallop.Make

v6 = VectorPenScrub.Make

v7 = VectorPenSlant.Make

v8 = VectorPenZigZag.Make

b1 = BasicPen.Make

'Make a View and draw some lines to apply the symbols to

myView = View.Make

myView.SetName("Pens")

myDisplay = myView.GetDisplay

for each x in 0..8

  'Define two points to make a line

  p1 = (x@0)

  p2 = (x@8)

  aLine = Line.Make(p1,p2)

  myLine = GraphicShape.Make(aLine)

  myView.GetGraphics.Add(myLine)

end

'open the view

myView.GetWin.Activate

'Enlarge display extent slightly

r = myView.ReturnExtent

myDisplay.SetExtent(r.Scale(1.1))

'Set Symbol Properties change the arguments and see the affects

colorlist = {Color.GetRed,Color.GetMagenta,Color.GetBlue,

             Color.GetCyan,Color.GetGray,color.GetGreen,

             Color.GetBlack,Color.Getblue,Color.GetRed}

anIndex = 0

'Change the parameters of each line symbol

for each l in {v1,v2,v3,v4,v5,v6,v7,v8,b1}

  myColor = colorlist.Get(anIndex)

  c = myColor.Clone               'Copy the color

  l.SetColor(c)                   'Apply color to line symbol

  l.SetSize(10)                   'Set the line width

  if (anIndex <> 8) then

    'These methods do not work for BasicPen subclass, which

    'is the 8th element in the list

    l.SetInterval(14)

    l.SetAltSize(2)

    l.SetFlip(true)

  end

  myView.GetGraphics.Get(anIndex).SetSymbol(l)

  anIndex = anIndex + 1

end

myView.Invalidate

'Make a new View and draw a line that is a composite pen symbol

myView2 = View.Make

myView2.SetName("Composite Pen")

myDisplay2 = myView2.GetDisplay

p1 = (0@0)

p2 = (8@0)

aLine = Line.Make(p1,p2)

myline = GraphicShape.Make(aLine)

myView2.GetGraphics.Add(myLine)

myView2.GetWin.Activate

r = myView2.ReturnExtent

myDisplay2.SetExtent(r.Scale(1.1))

'Change the symbols added to

mySymList = SymbolList.Make

mySymList.Add(b1)

mySymList.Add(v3)

myCompositePen = CompositePen.Make(mySymList)

myView2.GetGraphics.Get(0).SetSymbol(myCompositePen)

myView2.Invalidate


View.MergeThemesClick
Merges Active Themes Click

Source Code

Description:   Merges the active themes into a single theme.  A new shapefile is created which combines the shapes and attributes of the active themes.  The themes to be merged should have the same set of attributes (fields).  Only the fields from the first active theme are preserved in the output theme.

Associate this script with a new control.  Use the corresponding update script to enable the control and ensure that preconditions are met for proper script execution.

Name:    View.MergeThemesClick

Requires:  Merge Themes Update (mrgthmup.ave)

Self:

Returns:

FileName:  mrgthmcl.ave


View.MergeThemesClick (Sample Script)
'Merges Active Themes Click

theView   = av.GetActiveDoc

themesToMerge = theView.GetActiveThemes

' Specify the output shapefile...

outFName = av.GetProject.MakeFileName("theme", "shp")

outFName = FileDialog.Put(outFName, "*.shp", "Output Merged Shapefile")

if (outFName = Nil) then

  exit

end

' Create the list of fields used for the output theme.  The fields

' are taken from the first active theme only, it is assumed that

' other themes have an identical set of fields.  If this is not the

' case the themes will still be merged, however fields not found in

' other themes will be empty...

fieldList = List.Make

for each f in themesToMerge.Get(0).GetFTab.GetFields

  if (f.GetName = "Shape") then

    continue

  else

    fCopy = f.Clone

    fieldList.Add(fCopy)

  end

end

' Get the class of new FTab to create, create the new FTab and

' add fields that we've gathered from the input themes....

shapeType = themesToMerge.Get(0).GetFTab.FindField("Shape").GetType

if (shapeType = #FIELD_SHAPELINE) then

  outClass = POLYLINE

elseif (shapeType = #FIELD_SHAPEMULTIPOINT) then

  outClass = MULTIPOINT

elseif (shapeType = #FIELD_SHAPEPOINT) then

  outClass = POINT

elseif (shapeType = #FIELD_SHAPEPOLY) then

  outClass = POLYGON

else

  MsgBox.Error("Invalid shape field type.", "Merge Themes")

  exit

end

mergeFTab = FTab.MakeNew( outFName, outClass )

if (fieldList.Count > 0) then

  mergeFTab.AddFields( fieldList )

end

' Populate the new FTab from the FTabs of the input themes...

for each t in themesToMerge

  av.ShowMsg( "Merging"++t.GetName )

  inFTab  = t.GetFTab

  if (inFTab.GetSelection.Count = 0) then

    theRecordsToMerge = inFTab

    numRecs = inFTab.GetNumRecords

  else

    theRecordsToMerge = inFTab.GetSelection

    numRecs = theRecordsToMerge.Count

  end

  for each rec in theRecordsToMerge

    av.SetStatus( (rec / numRecs) * 100 )

    newRec   = mergeFTab.AddRecord

    inField  = inFTab.FindField( "Shape" )

    outField = mergeFTab.FindField( "Shape" )

    mergeFTab.SetValue( outField, newrec, inFTab.ReturnValue( inField, rec ))

    if (fieldList.Count > 0) then

      for each f in fieldList

        fName    = f.GetName

        inField  = inFTab.FindField( fName )

        ' Skip field if not found in inFTab...

        if ( inField <> Nil ) then

          outField = mergeFTab.FindField( fName )

          aValue    = inFTab.ReturnValue( inField, rec )

          mergeFTab.SetValue( outField, newRec, aValue )

        end

      end   ' for each f

    end   ' if count

  end   ' for each rec

end   ' for each t

av.ClearMsg

av.ClearStatus

if (MsgBox.YesNo("Add shapefile as theme to a view?",

  "Merge Themes", true).Not) then

  exit

end

' Create a list of views and allow the user to choose which view to

' add the new theme to...

viewList = {}

for each d in av.GetProject.GetDocs

  if (d.Is(View)) then

    viewList.Add( d )

  end

end

' Include a choice for a new view...

viewList.Add("<New View>")

addToView = MsgBox.ListAsString( viewList,"Add Theme to:", "Merge Themes" )

' Get the specified view, make the theme, and add it...

if (addToView <> nil) then

  if (addToView = "<New View>") then

    addToView = View.Make

    addToView.GetWin.Open

  end

  mergeTheme = FTheme.Make( mergeFTab )

  addToView.AddTheme( mergeTheme )

  ' Bring the View to the front...

  addToView.GetWin.Activate

end


View.MergeThemesUpdate
Merges Active Themes Update

Source Code

Description:   Used to enable/disable a control for the execution of MergeThemesClick (mrgthmcl.ave).  Will ensure that there are at least two active themes and that the feature types are the same.

Name:    View.MergeThemesUpdate

Requires:  Merge Themes Click

Self:

Returns:

FileName:  mrgthmup.ave


View.MergeThemesUpdate (Sample Script)
'Merges Active Themes Update

theView   = av.GetActiveDoc

theThemes = theView.GetActiveThemes

if (theThemes.Count < 2) then

  SELF.SetEnabled(false)

  exit

end

' Themes must have matching shape types for merging.  Using the first

' active theme verify that this is the case...

checkType  = theThemes.Get(0).GetFtab.FindField("Shape").GetType

for each i in 1 .. (theThemes.Count - 1)

  t = theThemes.Get(i)

  if (checkType <> t.GetFTab.FindField("Shape").GetType) then

    SELF.SetEnabled(false)

    exit

  end

end

SELF.SetEnabled(true)


Geocode.MultiMatch
Geocode to several matchable themes simultaneously

Source Code

Description:   This script implements "drop-back geocoding".  For example, if you want to first attempt to match to a street address, then, if the first match fails, match to the county field instead.  If the match is made to a polygon, the centroid point will be the geocoded point.  The event data to be matched will be geocoded to themes in the order they appear (selected) in the view.

Name:   Geocode.MultiMatch

Requires:  One or more matchable themes be active in a view

Self:

Returns:

FileName:  multmtch.ave


Geocode.MultiMatch (Sample Script)
'Geocode to several matchable themes simultaneously

'======== part 1 - setup and get user input ================

'

' get the view

'

v = av.GetActiveDoc

if (not (v.Is(View))) then

  msgBox.Error("Please select a View and Select Matchable Themes first.","")

  exit

end

' make a list of matchable themes

'

mtList = {}

for each t in v.GetActiveThemes

  if (t.IsMatchable) then

     mtList.Add(t)

  end

end

if (mtList.count=0) then

  msgBox.Error("Please setup Theme Properties for geocoding and select the Themes.","")

  exit

end

' get the table to be geocoded

'

docList = av.GetProject.GetDocs

tblList = {}

for each d in docList

  if (d.Is(Table)) then

    tblList.Add(d)

  end

end

if (tblList.count=0) then

   msgBox.Error("Please add a Table to the project.","")

  exit

end

tbl = msgBox.ChoiceAsString(tblList,"Select table to geocode:","Get Table")

if (tbl=nil) then

  exit

end

' make a list of fields for the table

'

tblVTab   = tbl.GetVTab

tblFields = tblVTab.GetFields

' get the fields to match for each matchable theme

'

mfldList1 = {}

mfldList2 = {}

for each mt in mtList

  prompt1=""

  prompt2=""

  msrce   = mt.GetMatchSource

  style   = msrce.GetName

  mFields = msrce.GetMatchFields

  if (style="Single Field") then

    prompt1 = "Select the Single Field for matching to Theme:"++mt.GetName

    prompt2 = ""

  end

  if (style="Zip+4") then

    prompt1 = "Select the Zip Field for matching to Theme:"++mt.GetName

    prompt2 = "Select the Zip+4 Field for matching to Theme:"++mt.GetName

  end

  if (prompt1="") then  ' must have an address type of style

    prompt1 = "Select the Address Field for matching to Theme:"++mt.GetName

    if (msrce.HasZone) then

       prompt2 = "Select the Zone Field for matching to Theme:"++mt.GetName

    end

  end

  ' get the address field

  fld1 = msgBox.ChoiceAsString(tblFields,prompt1,"Select Match Fields")

  if (fld1=nil) then exit end

  ' get the zone field if needed

  if (prompt2<>"") then

    fld2 = msgBox.ChoiceAsString(tblFields,prompt2,"Select Match Fields")

    if (fld2=nil) then exit end

  else

    fld2 = nil

  end

  mfldList1.Add(fld1)

  mfldList2.Add(fld2)

end ' for each mt (matchable theme)

' make the output FTab, get name

'

outFN = av.GetProject.GetWorkDir.Clone

outFN = outFN.MakeTmp("Theme","shp")

outFN = FileDialog.Put(outFN,"shp","Name the Output Geocoded Theme")

outFT = FTab.MakeNew(outFN,Point)

outFldList = {}

for each f in tblFields

  nf = f.Clone

  outFldList.Add(nf)

end

outFldList.Add(Field.Make("Av_mtheme",#FIELD_CHAR,20,0))

outFldList.Add(Field.Make("Av_status",#FIELD_CHAR,1,0))

outFldList.Add(Field.Make("Av_score",#FIELD_SHORT,3,0))

outFT.AddFields(outFldList)

shpField = outFT.FindField("Shape")

mthField = outFT.FindField("Av_mtheme")

staField = outFT.FindField("Av_status")

scoField = outFT.FindField("Av_score")

tFields = tblVTab.GetFields   ' list needs to be built again?

av.ShowMsg("Initializing output theme...")

count = tblVTab.GetNumRecords

av.ShowStopButton

for each r in tblVTab

    doMore = av.SetStatus((r/count)*100)

    if (not doMore) then

      exit

    end

    orec = outFT.AddRecord

    outFT.SetValue(shpField,orec,Point.MakeNULL)

    outFT.SetValueString(mthField,orec,"")

    outFT.SetValueString(staField,orec,"U")

    outFT.SetValueNumber(scoField,orec,0)

    for each tf in tFields

      outField = outFT.FindField(tf.GetName)

      tv = tblVTab.ReturnValue(tf,r)

      outFT.SetValue(outField,orec,tv)

    end

end

av.ClearStatus

av.ShowMsg("")

'======== part 2 - do the matching ================

mtIndex = 0

for each mt in mtList

  av.ShowMsg("Matching to"++mt.GetName)

  av.ShowStopButton

  ' make the objects needed for geocoding

  '

  aMatchSrc  = mt.GetMatchSource

  aMatchSrc.OpenIndex

  aMatchKey  = MatchKey.Make(aMatchSrc.GetStanRules)

  aMatchCase = MatchCase.Make(aMatchSrc, aMatchKey)

  mField1 = outFT.FindField(mfldList1.Get(mtIndex).GetName)

  mField2 = outFT.FindField(mfldList2.Get(mtIndex).GetName)

  for each rec in outFT

    if (outFT.ReturnValueString(staField,rec)<>"U") then

      continue

    end

    doMore = av.SetStatus((rec/count)*100)

    if (not doMore) then

      exit

    end

    ' Standardize and match address

    '

    aMatchKey.SetKey(outFT.ReturnValue(mField1,rec))

    if (aMatchSrc.HasZone) then

      aMatchKey.SetZoneKey(outFT.ReturnValue(mField2,rec))

    end

    numCand = aMatchSrc.Search( aMatchKey, 80, aMatchCase )

    if (numCand = 0) then

      'MsgBox.Info( "No match for"++address, "No Match ")

      continue

    end

    ' Find the best candidate

    aMatchCase.ScoreCandidates

    bestCand = aMatchCase.GetBestCand

    ' Get location and write to the output file

    locPoint = aMatchSrc.GetPoint( bestCand )

    ' if we got this far, there was a match

    outFT.SetValue(shpField,rec,locPoint)

    outFT.SetValueString(mthField,rec,mt.GetName)

    outFT.SetValueString(staField,rec,"M")

    outFT.SetValueNumber(scoField,rec,bestCand.GetScore)

  end ' for each rec

  aMatchSrc.EndMatch

  mtIndex = mtIndex + 1

  av.ClearStatus

  av.ShowMsg("")

end ' for each matchable theme

'======== part 3 - add theme to a view ================

'

' Create a list of views and allow the user to choose which view to

' add the new theme to...

viewList = {}

for each d in av.GetProject.GetDocs

  if (d.Is(View)) then

    viewList.Add( d )

  end

end

' Include a choice for a new view...

viewList.Add("<New View>")

addToView = MsgBox.ListAsString( viewList,"Add Theme to:", "Merge Themes" )

' Get the specified view, make the theme, and add it...

if (addToView <> nil) then

  if (addToView = "<New View>") then

    addToView = View.Make

    addToView.GetWin.Open

  end

  mergeTheme = FTheme.Make( outFT )

  addToView.AddTheme( mergeTheme )

  ' Bring the View to the front...

  addToView.GetWin.Activate

end


Graphics.RepositionGraphic
Moves and centers a graphic

Source Code

Description:   Moves and centers the graphic to the specified coordinate. The graphic is centered on the input coordinate.  Expects a string to be passed from the calling program containing the x coordinate, y coordinate, and name of the graphic object.  The graphic object must be uniquely identifiable by its name.  Use the SetName request to set the name of the graphic to any string.

Can be used to update the locations of uniquely named graphic objects from external programs via DDE or RPC.

Name:    Graphics.RepositionGraphic

Requires:

Self:

Returns:

FileName:  mvgra2pt.ave


Graphics.RepositionGraphic (Sample Script)
'Moves and centers a graphic

' Parsing is expecting a string with the 3 pieces of information needed,

' if information is passed as a list, then change appropriately...

'

strX = SELF.Extract(0)           ' the x coordinate to move to

strY = SELF.Extract(1)           ' the y coordinate to move to

strIdentifier = SELF.Extract(2)  ' the unique name of the graphic object

if ((strX.IsNumber) and (strY.IsNumber)) then

  av.ShowMsg("Location:"++strX++strY)

  x = strX.AsNumber

  y = strY.AsNumber

  ' Locate the graphic object that must be moved using the name...

  '

  grToMove = av.GetActiveDoc.GetGraphics.FindByName( strIdentifier )

  ' The graphic should be centered on the new point...

  '

  ptGraphicExtent = grToMove.GetExtent

  xOffset = ptGraphicExtent.GetX / 2

  yOffset = ptGraphicExtent.GetY / 2

  pt = grToMove.GetOrigin

  pt.SetX(x - xOffset)

  pt.SetY(y - yOffset)

  ' Invalidate and move graphic object...

  '

  grToMove.Invalidate

  grToMove.SetOrigin(pt)

  grToMove.Invalidate

end


ImageLegend.SetNDVIColor
Sets the color map of an ImageTheme to a NDVI file

Source Code

Description:   Using the contents of an NDVI color file, this script resets the colormap for an image theme.

Name:    ImageLegend.SetNDVIColor

Requires:

Self:

Returns:

FileName:  ndvipal.ave


ImageLegend.SetNDVIColor (Sample Script)
'Sets the color map of an ImageTheme to a NDVI file

'Processes comma delimted 256 line color file for image color map

TheView = av.GetActiveDoc

MySingleBandImageTheme = TheView.GetActiveThemes.Get(0)

SBL = MySingleBandImageTheme.GetLegend

TheImageColorMap = SBL.GetColorMap

ColorFileName = "c:/idrisiw/exe/ndviAV.csv".AsFileName

if (File.Exists(ColorFileName).not) then

  Msgbox.Error("Colors Filename is not valid","")

  exit

end

ColorFile = LineFile.Make(ColorFileName,#FILE_PERM_READ)

if (colorFile.GetSize <> 256) then

  Msgbox.error("Incorrect number of lines in the colors file","")

  exit

end

for each c in 0..255

  colorspec = ColorFile.ReadElt       'Reads each successive line in file

  shades = colorspec.AsTokens(",")    'Assumes format you show below

  red = shades.Get(0).Trim.AsNumber   'The Trim gets rid of extra spaces

  green = shades.Get(1).Trim.AsNumber

  blue = shades.Get(2).Trim.AsNumber

  TheColor = Color.Make               'Make a new color

  TheColor.SetRGBList({red,green,blue})

  TheImageColorMap.Set(c,TheColor)

end

ColorFile.Close

TheView.Invalidate


View.SpatialNearestNeighbor
Perform Spatial Nearest Neighbor Analysis

Source Code

Description:   Create a new tool in a ViewDocGUI with this script as the Apply script.  To use this you must have an active theme.  Just drag a rectangle around the features you wish to conduct a spatial nearest neighbor analysis of.  The wait cursor will appear and then a messagebox will tell you the R value and how many features were accounted for in the analyis.  R values relate how clustered or dispersed points (or centroids of polygons and polylines) are within the rectangle you specified.  An R value of 0 (zero), indicates an intensely clustered pattern, while an R value of 1 indicates a random distribution, and an R value of 2 (or higher) indicates strongly dispersed or organized pattern.

Name:    View.SpatialNearestNeighbor

Requires:  The active document must be a view, with an active feature theme.

Self:

Returns:

FileName:  nearest.ave


View.SpatialNearestNeighbor (Sample Script)
'Perform Spatial Nearest Neighbor Analysis

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

theFTab = theTheme.GetFTab

theExts = theView.GetDisplay.ReturnUserRect

  xrect = theExts.GetWidth

  yrect = theExts.GetHeight

  area = xrect * yrect

  low = xrect * yrect

Shp = theFTab.FindField("Shape")

td = 0

n = 0

av.UseWaitCursor

For each rec in theFTab

  Val = theFTab.ReturnValue(Shp,rec)

  if (Val.Is(Point)) then

    xz = Val.GetX

    yz = Val.GetY

    if (theExts.Contains(Val).Not) then continue end

  elseif ((Val.Is(Polygon)) or (Val.Is(PolyLine))) then

    c = Val.ReturnCenter

    xz = c.GetX

    yz = c.GetY

    if (theExts.Contains(Val).Not) then continue end

  end

  n = n + 1

  For each z2 in theFTab

    Valn = theFTab.ReturnValue(Shp,z2)

    if (Valn.Is(Point)) then

      xn = Valn.GetX

      yn = Valn.GetY

      if (theExts.Contains(Valn).Not) then continue end

    elseif ((Valn.Is(Polygon)) or (Val.Is(PolyLine))) then

      c = Valn.ReturnCenter

      xn = c.GetX

      yn = c.GetY

      if (theExts.Contains(Valn).Not) then continue end

    end

    d = (((xz - xn) * (xz - xn)) + ((yz -yn ) * (yz - yn))).sqrt

    if (d > 0) then

      if (d < low) then

        low = d

      end

    end

  end

  td = td + low

end

Re = (1) / (2*((n/area).sqrt))

Ra = td / n

R = Ra / Re

theRect = GraphicShape.Make(theExts)

theRect.SetDisplay(theView.GetDisplay)

theRect.Draw

MsgBox.Info("The R value ="++R.AsString++"where n = "+n.AsString,"Result")


Layout.NestedPieChartLegend
Creates nested legend for piecharts with size field

Source Code

Description:   If you have a pie chart legend in a view, make it the active theme and then make a layout and then a viewframe with that view.  Use this script as a tool.  When you click in the layout display, the location will become the lower left origin for a graphic group that will contain a legend for your piechart legend.

Name:    Layout.NestedPieChartLegend

Requires:  Layout.NestedPieChartLegendUpdate as the update script

Self:

Returns:

FileName:  npcl.ave


Layout.NestedPieChartLegend (Sample Script)
'Creates nested legend for piecharts with size field

Script.The.SetNumberFormat("d.ddddddddddd")

TransC = Color.Make

TransC.SetTransparent(true)

'Exponentiate radius to .5718 power to visually scale to human perception.

'See ArcPlot Spotsize command for discussion or "Thematic Maps"

'by David Cuff and Mark Mattson

theLayout = av.GetActiveDoc

theViewFrame = theLayout.GetGraphics.GetSelected.Get(0)

theView = theViewFrame.GetView

theViewFrame.SetSelected(false)

theTheme = theView.GetActiveThemes.Get(0)

lGraphics = theLayout.GetGraphics

theLegend = theTheme.GetLegend

theDisplay = theLayout.GetDisplay

theFTab = theTheme.GetFTab

Legend_Origin = theDisplay.ReturnUserPoint

'************************************************************

'Construct top half of legend

'************************************************************

GenericPieSym = theLegend.GetSymbols.Get(0)

MinRad = GenericPieSym.GetMinSize

MaxRad = GenericPieSym.GetMaxSize

MinValue = GenericPieSym.GetMinValue

MaxValue = GenericPieSym.GetMaxValue

MaxSize = MaxRad/72

MinSize = MinRad/72

SizeRange = MaxSize - MinSize

ValueRange= MaxValue - MinValue

'Number of circles desired in legend

legend_circles = Msgbox.ChoiceAsString({"2","3","4","5","6"},

                               "Choose the number of circles to be in your legend",

                               "Sized PieChart Legend").AsNumber

if (legend_circles = nil) then exit end

'Point size of text used in legend

'Figure out number format

Numforms = {"d,ddd,ddd",

             "ddd,ddd",

              "dd,ddd",

               "d,ddd",

                 "ddd",

                  "dd",

                   "d",

                   "d.d",

                   "d.dd",

                   "d.ddd",

                   "d.dddd",

                   "d.ddddd",

                   "d.dddddd"}

Value_Label_Format = Msgbox.ChoiceAsString(Numforms,"Choose a Number format for your labels:","Number Formats")

if (Value_Label_Format = nil) then exit end

MinValue.SetFormat(Value_Label_Format)

MaxValue.SetFormat(Value_Label_Format)

Value_Label_Strings = {}

Legend_Intervals = {}

if (legend_circles = 3) then

  ValueInterval = ValueRange/2

  vs1 = (MinValue + ValueInterval).SetFormat(Value_Label_Format).AsString

  Value_Label_Strings.Add(vs1)

  Augmentor = SizeRange/2

  Legend_Intervals.Add(MinSize + Augmentor)

elseif (legend_circles = 4) then

  ValueInterval = ValueRange/3

  Value_Label_Strings.Add((MinValue + ValueInterval).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*2)).SetFormat(Value_Label_Format).AsString)

  Augmentor = SizeRange/3

  Legend_Intervals.Add(MinSize + Augmentor)

  Legend_Intervals.Add(MinSize + (Augmentor*2))

elseif (legend_circles = 5) then

  ValueInterval = ValueRange/4

  Value_Label_Strings.Add((MinValue + ValueInterval).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*2)).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*3)).SetFormat(Value_Label_Format).AsString)

  Augmentor = SizeRange/4

  Legend_Intervals.Add(MinSize + Augmentor)

  Legend_Intervals.Add(MinSize + (Augmentor*2))

  Legend_Intervals.Add(MinSize + (Augmentor*3))

elseif (legend_circles = 6) then

  ValueInterval = ValueRange/5

  Value_Label_Strings.Add((MinValue + ValueInterval).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*2)).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*3)).SetFormat(Value_Label_Format).AsString)

  Value_Label_Strings.Add((MinValue + (ValueInterval*4)).SetFormat(Value_Label_Format).AsString)

  Augmentor = SizeRange/5

  Legend_Intervals.Add(MinSize + Augmentor)

  Legend_Intervals.Add(MinSize + (Augmentor*2))

  Legend_Intervals.Add(MinSize + (Augmentor*3))

  Legend_Intervals.Add(MinSize + (Augmentor*4))

end

Legend_Intervals.Add(MaxSize)

Legend_Intervals.Insert(MinSize)

Value_Label_Strings.Add(MaxValue.AsString)

Value_Label_Strings.Insert(MinValue.AsString)

text_sym = av.GetSymbolWin.ReturnCurrentSymbol(#SYMBOL_TEXT).clone

text_sym.SetSize(18)

BGRect = Rect.Make(Legend_Origin,(((MaxSize) * 5)@((MaxSize) * 3.25)))

BGRectSym = RasterFill.Make

BGRectSym.SetStyle(#RASTERFILL_STYLE_OPAQUESTIPPLE)

BGRectSym.SetColor(Transc)

BGRectSym.SetBGColor(Color.GetWhite)

BGRectangle = GraphicShape.make(BGRect)

BGRectangle.SetSymbol(BGRectSym)

lgraphics.Add(BGRectangle)

BGRectangle.SetSelected(true)

LegendTitle = GraphicText.Make(theTheme.GetName,(0@0))

LegendTitle.SetSymbols(SymbolList.FromList({text_sym.Clone}))

lgraphics.Add(LegendTitle)

LTWd = LegendTitle.GetExtent.GetX/2

TextOrigin = BGRect.ReturnCenter + (-LTWd@(((BGRect.GetHeight)/2) *0.625 ))

LegendTitle.SetOrigin(TextOrigin)

LegendTitle.SetSelected(true)

ScaleCircSym = Rasterfill.Make

ScaleCircSym.SetStyle(#RASTERFILL_STYLE_EMPTY)

ScaleCircSym.SetOLWidth(0.5)

ValueLabelSym = text_sym.Clone

ValueLabelSym.SetSize(10)

LeaderSym = BasicPen.Make

LeaderSym.SetSize(0.1)

DkGray = Color.Make

DkGray.SetRGBList({150,150,150})

LeaderSym.SetColor(DkGray)

'Make and add the circles that are tangent at 270 degree point

Counter = 0

for each rad in Legend_Intervals

  aCirc = Circle.Make((BGRect.ReturnOrigin + ((MaxSize * 1.25)@((MaxSize*0.25) + rad))), rad)

  GSCirc = GraphicShape.Make(aCirc)

  GSCirc.SetSymbol(ScaleCircSym)

  aLeader = Line.Make((BGRect.ReturnOrigin + ((MaxSize * 1.25)@((MaxSize*0.25) + (Rad*2)))),

                      (BGRect.ReturnOrigin + ((MaxSize * 2.75)@((MaxSize*0.25) + (Rad*2)))))

  GSLeader = GraphicShape.Make(aLeader)

  GSLeader.SetSymbol(LeaderSym)

  aLabel = GraphicText.Make(Value_Label_Strings.Get(Counter),

                             (BGRect.ReturnOrigin + ((MaxSize * 2.8)@((MaxSize*0.1) + (Rad*2)))  ))

  aLabel.SetSymbols(SymbolList.FromList({ValueLabelSym}))

  lGraphics.Add(aLabel)

  lGraphics.Add(GSLeader)

  lGraphics.Add(GSCirc)

  aLabel.SetSelected(true)

  GSLeader.SetSelected(true)

  GSCirc.SetSelected(true)

  Counter = Counter + 1

end

theLayout.GetGraphics.GroupSelected

theLayout.GetGraphics.Invalidate


Layout.NestedPieChartLegendUpdate
Update script for Layout.NestedPieChartLegend

Source Code

Description:   This is the update script for Layout.NestedPieChartLegend

Name:    Layout.NestedPieChartLegendUpdate

Requires:

Self:

Returns:

FileName:  npclup.ave


Layout.NestedPieChartLegendUpdate (Sample Script)
'Update script for Layout.NestedPieChartLegend

enabled = true

theLayout = av.GetActiveDoc

if (theLayout.GetGraphics.GetSelected.Count <> 0) then

  theViewFrame = av.GetActiveDoc.GetGraphics.GetSelected.Get(0)

  if (theViewFrame.Is(ViewFrame)) then

    theView = theViewFrame.GetView

    if (theView.GetActiveThemes.Count <> 1) then

      enabled = false

    end

    theTheme = theView.GetActiveThemes.Get(0)

    if (theTheme.IsActive and (theTheme.CanLabel) and (theTheme.GetLabelField <> NIL)) then

      theLegend = theTheme.GetLegend

      if ((theLegend.GetLegendType <> #LEGEND_TYPE_CHART) or

          (theLegend.GetSymbol(theLegend.ReturnFieldNames,false).Is(PieChartSymbol).Not)) then

         enabled = false

      end

    else

      enabled = false

    end

  end

else

  enabled = false

end

Self.SetEnabled(enabled)


View.SetOneToMany
Sets up OneToMany relationships for tables linked to themes

Source Code

Description:   It sets up a OneToMany from the feature attribute table of the first active FTheme in the view, to a user selected 'many' table. This method has to be used in preference to the standard "user interface" method, as it sets up variables for the ID function.

To set up a OneToMany link from a theme's attribute table to a 'many' table (both assumed to be in the project already), first activate the theme in the view. Then select the button to create the one-to-many relationship (i.e.

the button which runs View.SetOneToMany). This will ask the user to select:

(1) The link-field (key) in the theme's attribute table

(2) The 'many' table

(3) The link-field (key) in the 'many' table

(4) Whether the records are to remain selected after the ID

The user will see the normal ID window for the 'one' record, and if there are any 'many' records related to that 'one', then they will be also added to the ID window.

If the user has nominated in the setup that the records are to remain selected, then they will be in the 'one' and the 'many' tables.

At this point the user may use the View.IdentifyLinked tool to identify features. The IdentifyLinked tool will show the record from the 'one' table and then show any additional records from the 'many' table.  If the user has nominated in the set-up that the records are to remain selected, then they will be in the 'one'

and the 'many' tables.

Name:    View.SetOneToMany

Requires:  Should be placed on a DocGUI that supports Views as the click event for a button.  Use the View.TabularThemesUpdate as the update event

Self:

Returns:

FileName:  one2many.ave


View.SetOneToMany (Sample Script)
'Sets up OneToMany relationships for tables linked to themes

'Because we need to know which table is linked to which in the

'one-to-many identify tool, we'll set up the links here, and

'set the object tag of the 'one' table to the name of its

'linked table

allActive = av.GetActiveDoc.GetActiveThemes

if (allActive.Count < 1 ) then

   MsgBox.Error("Set a 'Feature Theme' active", "Works on first active Feature Theme")

   exit

end

theFTheme = allActive.Get(0)

if (theFTheme.Is(FTheme).Not) then

   MsgBox.Error("Set a 'Feature Theme' active", "Works on first active Feature Theme")

   exit

end

theFTheme.EditTable

theTable = av.GetActiveDoc

theTableName = theTable.GetName

theTable.GetWin.Close

'Get a list of all tables in the project

fullList = av.GetProject.GetDocs

tableList = {}

for each d in fullList

   if (d.Is(Table)) then

      tableList.Add(d)

   end

end

tableList.RemoveObj(theTable)

if (tableList.Count < 1) then

   MsgBox.Error("There are no other tables in the project", "No Tables")

   exit

end

oneTable = av.GetProject.FindDoc(theTableName)

if (oneTable = nil) then exit end

allFields = oneTable.GetVTab.GetFields

oneField = MsgBox.ListAsString(allFields, "Select key field in"++oneTable.GetName, "Key field")

if (oneField = nil) then exit end

manyTable = MsgBox.ListAsString(tableList, "Select the 'many' table for the link", "'Many' Table")

if (manyTable = nil) then exit end

allFields = manyTable.GetVTab.GetFields

manyField = MsgBox.ListAsString(allFields, "Select key field in"++manyTable.GetName, "Key field")

if (manyField = nil) then exit end

if ((oneField.GetType) <> (manyField.GetType)) then

   MsgBox.Error ("For a link, fields have to be the same type", "Not same type")

   exit

end

idLabelField = MsgBox.ListAsString(allFields, "Select ID label in"++manyTable.GetName, "Key field")

if (idLabelField = nil) then exit end

oneTable.GetVTab.Link(oneField, manyTable.GetVTab, manyField)

keepSelected = MsgBox.MiniYesNo("Do you want to keep records selected after the Identify",TRUE)

theFTheme.SetObjectTag({manyTable.GetName,idLabelField, keepSelected})

' Note.... to expand this for multiple 1-many's, just add to this ObjectTag.

' However a preferable method would be a public request to return the current

' links a file has.


View.SortTOC
Sort order of TOC by type of theme

Source Code

Description: The order of themes in a view's table of contents is rearranged so that image themes are drawn first, followed by regions, polygons, routes, lines, text, and point themes.

Theme types, and the order they are sorted in, are found in the list called theTypes. Change this list to suit specific ordering needs..

Name:  :  View.SortTOC

Requires:  A View, containing themes, must be the active document.

Self:

Returns:

FileName:  ordertoc.ave


View.SortTOC (Sample Script)
'Sort order of TOC by type of theme

aView = av.GetActiveDoc      'Get the View

theThemes = aView.GetThemes  'Get the themes

if (theThemes = NIL) then

  exit

end

' Theme types. Change the order of this list to change the display

' order in the TOC; images, and anything else not included in the list,

' are included in "other" category.

'

theTypes = {"point","multipoint","labelpoint","node","annotation","arc",

            "multiline","route","polygon","poly","region"}

' Use a Dictionary to store themes of various types

'

aDictionary = Dictionary.Make(theTypes.Count + 1)

for each type in theTypes

  aDictionary.Add (type,{})

end

aDictionary.Add("other",{})  ' Store types not in theTypes, eg images

' Sort themes by type

'

for each thm in theThemes

  aKey = thm.GetSrcName.GetSubName

  if (theTypes.FindByValue(aKey) >= 0) then

    ' Get list out of dictionary and add theme to list

    aValue = aDictionary.Get(aKey) + {thm}

    aDictionary.Set(aKey,aValue)

  else

    ' Regions and routes are handled separately because their SubName

    ' also contains another component besides the word "region" or "route".

    type = "other"  'Set default

    if (aKey.Contains("region")) then

      type = "region"

    end  'if

    if (aKey.Contains("route")) then

      type = "route"

    end  'if

    aValue = aDictionary.Get(type) + {thm}

    aDictionary.Set(type, aValue)

  end  'else

end  'for

' Reorder the TOC by rebuilding the TOC list

'

theThemes.Empty

for each type in theTypes

  theThemes.Merge(aDictionary.Get(type))

end

theThemes.Merge(aDictionary.Get("other"))

' Refresh TOC and View

'

aView.InvalidateTOC(nil)

aView.Invalidate


View.pcARCEDITTheme
Opens Active Theme in pcARCEDIT

Source Code

Description:   Uses the currently active theme and launches pcARCEDIT through the WEDIT shell macro.  The editcoverage, drawenvironment, and editfeature are supplied by the active theme.

Once editing is completed the user must rebuild topology.  After quitting ARCEDIT the user is returned to ArcView.

Name:    View.pcARCEDITTheme

Requires:  pcARC/INFO Rev. 3.4.2 with Windows Extensions.

Self:

Returns:

FileName:  pcarced.ave


View.pcARCEDITTheme (Sample Script)
'Opens Active Theme in pcARCEDIT

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

' Get the name of the coverage and check to make sure it isn't a

' workstation coverage...

'

theCover = theTheme.GetSrcName.GetFileName.GetFullName

if (coverage.isINFO(theCover)) then

  msgbox.Error("Theme source is not a PC ARC/INFO coverage."+NL+

    "Unable to edit source.","")

  exit

end

' Get the feature class and convert to ARCEDIT terms

'

theFeature = theTheme.GetSrcName.GetSubName

if (theFeature = "point") then

  theFeature = "Labels"

end

if (theFeature = "polygon") then

  theFeature = "Labels"

end

' Tell the user which coverage was selected and verify

'

ok = MsgBox.YesNo("Are you sure you want to edit"+NL+theCover, "Edit", true)

if (Not ok) then

  exit

end

' This request closes the Ftab so ARCEDIT can save the coverage after editing

'

theTheme.GetFtab.Deactivate

theTheme.SetVisible(false)

'Create the SML file that passes the parameters to ARCEDIT

'

smlName = FN.Make("c:\arcexe\utool\T$edit.sml")

txtFile = TextFile.Make(smlName, #FILE_PERM_WRITE)

'Create the line that is written to the file

'Make all launching parameter changes here.

'

OutputLine = "disp 4"+cr+nl+"editcov "+theCover+cr+nl+

  "drawe all"+cr+nl+"editf "+theFeature

OutputLine = OutputLine +cr+nl+ "draw" +cr+nl+ "@WEDIT"

q = OutputLine.Count

'Write the stuff to the file

'

txtFile.Write(OutputLine,q)

txtFile.Close

'Execute the whole thing

System.Execute("c:\arcexe\cmd\arcx.bat arceditw t$edit.sml")


View.RandomSelection
Selects a percentage of a theme's features randomly

Source Code

Description:   This script will create a random selection of features based on a percentage of the total number of features (for example: a random sample of 5% of the counties in the USA coverage).

Name:    View.RandomSelection

Requires:  A View document with at least one active theme.

Self:

Returns:

FileName:  randsel.ave


View.RandomSelection (Sample Script)
'Selects a percentage of a theme's features randomly

theView = av.GetActiveDoc

theDisplay = theView.GetDisplay

ThemeList = av.GetActiveDoc.GetActiveThemes

if (ThemeList.Count <> 1) Then

 msgbox.Error("You must have one and only one active theme","Select Random Sample is aborting")

 exit

end

theTheme = ThemeList.Get(0)

theFtab = theTheme.GetFtab

theBitMap = theFtab.GetSelection

theBitMap.ClearAll

TotalRecs = theFtab.GetNumRecords

PercentSelect = MsgBox.Input("Enter the percentage of Total Population:","Select Random Sample","10")

if ((PercentSelect = NIL) or (PercentSelect.IsNumber.Not)) then exit end

if((PercentSelect.AsNumber > 99) or (PercentSelect.AsNumber < 1)) then

  Msgbox.Error("You must enter a number between 0 and 100","Select Random Sample is aborting")

  exit

end

selectnumber = (PercentSelect.AsNumber/100 * TotalRecs).Truncate

if ( Msgbox.YesNo("Do you require an exact sample percentage?","Select Random Sample",TRUE) ) then

 setbits = 0

 while (setbits < selectnumber )

  newnumber = Number.MakeRandom ( 0,  totalrecs)

  theBitMap.Set(newnumber)

  setbits = theBitmap.Count

 end

else

 for each n in 1..selectnumber

  newnumber = Number.MakeRandom ( 0,  totalrecs)

  theBitMap.Set(newnumber)

 end

end

theDisplay.Invalidate(True)


View.LegendRasterToVector
Changes legend from RasterFill to VectorFill

Source Code

Description:   Legends can use symbols of several types.  The default type is a legend that uses solid fill symbols (class RasterFill).  This script provides an example which demonstrates creating hatched symbols (class VectorFill) and setting symbol properties such as color and angle.

Existing symbols in the legend are returned as a list using aLegend.GetSymbols.  The list of symbols is a reference (not a copy) of of symbols in the legend.  Because it is a reference, new symbols can replace existing symbols in the list using the List request Set.

Note that after the legend is modified InvalidateLegend is used to update the TOC of the View.  aTheme.Invalidate is used to redraw the theme using the new legend.

Name:    View.LegendRasterToVector

Requires:  The active theme must have a legend using fill symbols.

Self:

Returns:

FileName:  rasveclg.ave


View.LegendRasterToVector (Sample Script)
'Changes legend from RasterFill to VectorFill

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

theLegend = theTheme.GetLegend

symbList = theLegend.GetSymbols

idx = 0

for each s in symbList

  newSymbol = VectorFill.Make

  newSymbol.SetStyle(#VECTORFILL_STYLE_HATCH)

  newSymbol.SetAngle(45)

  newSymbol.SetColor(s.GetColor)

  newSymbol.SetOLColor(s.GetOLColor)

  symbList.Set(idx, newSymbol)

  idx = idx + 1

end

theTheme.InvalidateLegend

theTheme.Invalidate(true)


File.FindRepString
Finds and replaces string in a file

Source Code

Description:   Searches for the specified string in the file and replaces it with another string.  Can be used to change UNIX, DOS or Macintosh pathname specifications found in project (*.apr) files for use on other platforms. May also be use to replace paths with system environment variables (e.g. $DATA_HOME).

Name:    File.FindRepString

Requires:

Self:

Returns:

FileName:  replstr.ave


File.FindRepString (Sample Script)
'Finds and replaces string in a file

' Get file to change...

'

fileNameIn = FileDialog.Show("*.*", "File (*.*)", "Select File to Change")

if ( fileNameIn = nil ) then

  exit

end

' Create new default output name and get output file...

'

tempName     = fileNameIn.GetBaseName.AsTokens(".").Get(0)

tempExt      = fileNameIn.GetExtension

tempDir      = fileNameIn.ReturnDir.AsString

defName      = FN.Make(tempDir).MakeTmp(tempName,tempExt)

fileNameOut  = FileDialog.Put(defName, "*."+tempExt, "Save Changed File As")

if (fileNameOut = nil) then

  exit

end

' Solicit for search/replace strings...

'

searchString = MsgBox.Input("Enter string to change:","Replace String","")

if (searchString = nil) then

  exit

end

replaceString = MsgBox.Input("Enter string to substitute:","Replace String","")

if (replaceString = nil) then

  exit

end

' Perform substitutions...

' Output file is opened CLEARMODIFY since the user may have chosen to

' overwrite the original file.

'

fileIn = LineFile.Make( fileNameIn, #FILE_PERM_READ )

fileOut = LineFile.Make( fileNameOut, #FILE_PERM_CLEARMODIFY )

numChanges  = 0

counter     = 0

total       = fileIn.GetSize

done        = false

av.ShowStopButton

av.ShowMsg("Searching...")

while (done.not)

  counter = counter + 1

  proceed = av.SetStatus( (counter / total) * 100 )

  if (proceed.Not) then

    av.ClearStatus

    av.ShowMsg("Stopped")

    exit

  end

  theString = fileIn.ReadElt

  if ( theString <> nil ) then

    if ( theString.Contains( searchString ) ) then

      numChanges = numChanges + 1

      newString = theString.Substitute( searchString, replaceString )

    else

      newString = theString

    end

    fileOut.WriteElt( newString )

  else

    done = true

  end

end

av.ClearStatus

' Close and report results...

'

fileIn.Close

fileOut.Close

MsgBox.Info("File:"++fileNameOut.AsString++"created."+NL+

             numChanges.AsString++"substitution(s) made.","")


Project.ReplaceSystemScript
Replaces a script with script in active SEd

Source Code

Description:   Replaces the specified script chosen using the Script Manager with the script associated with the active SEd.  Can be used to override scripts such as Project.Button1 (the script which executes when you click the first button in the Project Window).

The existing script is not 'overwritten'; a new script with the same name as the old script will be found first, and therefore will be executed in place of the original.  The new script has the same name as the old, but is in upper case, therefore making it easy to identify for removal to restore the default functionality.  Remove a script from the Script Manager using the sample script RemoveScript.

Name:    Project.ReplaceSystemScript

Requires:  the active document must be a SEd.

Self:

Returns:

FileName:  repscrpt.ave


Project.ReplaceSystemScript (Sample Script)
'Replaces a script with script in active SEd

theSEd = av.GetActiveDoc

if (NOT (theSEd.IsCompiled)) then

  MsgBox.Error(theSEd.GetName++"is not compiled.",

  "Override Project Script")

  exit

end

s = ScriptMgr.Show

if (s = NIL) then exit end

if (MsgBox.YesNo("Are you sure you want to override " +

  s.GetName + "?", "Override Script", True)) then

  sNew = theSEd.GetScript

  sNew.SetName(s.GetName.UCase)

  av.GetProject.GetScripts.Set(sNew)

  'Remove the script editor

  av.GetProject.RemoveDoc( theSEd )

  'Report success

  av.ShowMsg(s.GetName++"overridden.")

end


Project.ReturnDoc
Returns a document of a specific class

Source Code

Description:   This script is a workaround for the problem of using either the GetActiveDoc or FindDoc request in that there is no way of specifying a particular class of document.  If you use the FindDoc request, and two documents contain that name, there is no way to guarantee that you will get the one you want.

Name:    Project.ReturnDoc

Requires:  Requires to be sent a list containing both the document name and the document type that you are searching for.  To run this use syntax similar to the following: returnDoc = av.run( "Project.ReturnDoc", { "Atlanta", "View" } )

Self:

Returns:

FileName:  retrndoc.ave


Project.ReturnDoc (Sample Script)
'Returns a document of a specific class

' Get the docName and docClasstype from the SELF variable.  These are strings.

docName = SELF.Get(0)

classType = SELF.Get(1)

' Get a list of all documents in the project.

theProject = av.GetProject

projDocList = theProject.getDocs

' Loop through each document and check its class.  When the correct document is found

' return that document to the calling project.

for each returnDoc in projDocList

  if (returnDoc.AsString = docName) then

    docClass = returnDoc.GetClass.GetClassName

    if (docClass = classType) then

      Return returnDoc

    end

  end

end

' If we get to here we did not find the requested document.  So we will simply

' return a Nil

Return Nil


View.ReverseGeocode
Finds the address for the specified point location

Source Code

Description:  Converts an x,y location to the nearest address. The location can be taken from a mouse click, or from an external source such as a GPS device.

The nearest feature in the address theme will be used to derive the address. A large search tolerance may increase the number of candidate features but will increase processing time to find the nearest feature.

This sample script consists of two parts. Use CallReverseGeocode (part 2) as the apply script of a tool on the view GUI. ReverseGeocode (part 1) needs to be copied in the same project as that CallReverseGeocode runs.

Name:    View.ReverseGeocode

Requires:  A theme containing address information must be active. The house number range fields must be numeric fields.

Self:  a List containing the following elements:

(0)  aPoint  =  XY location to convert to an address

(1)  aTheme  =  theme containing address attributes

(2)  aTol  =  search radius for features with addresses

(3)  lfa  =  left from address range field name

(4)  rfa  =  right from address range field name

(5)  lta  =  left to address range field name

(6)  rta  =  right to address range field name

(7)  addr  =  the street name field

(8)  type  =  the street type field name

Returns:  a String containing the address, or message if address not found.

FileName:  revgeoc.ave


View.ReverseGeocode (Sample Script)
'Finds the address for the specified point location

'Part 1: ReverseGeocode

' Get parameters

aPoint  = self.get(0)

aTheme  = self.get(1)

theFTab = aTheme.GetFTab

aTol    = self.get(2)

lfa     = theFTab.FindField(self.get(3))

rfa     = theFTab.FindField(self.get(4))

lta     = theFTab.FindField(self.get(5))

rta     = theFTab.FindField(self.get(6))

addr    = theFTab.FindField(self.get(7))

type    = theFTab.FindField(self.get(8))

' Create circle based on the search tolerance and find candidate features.

aCircle = Circle.Make(aPoint,aTol)

theFTab.SelectByPolygon(aCircle.AsPolygon,#VTAB_SELTYPE_NEW)

selBitmap = theFTab.GetSelection

if (selBitmap.count = 0) then

  return("Address not found.")

end

' Find the closest feature.

minDist = 9999999999

minRec  = 0

for each rec in selBitmap

  currShape = theFTab.ReturnValue(theFTab.FindField("Shape"),rec)

  dist = currShape.Distance(aPoint)

  if (dist < minDist) then

    minDist  = dist

    minRec   = rec.Clone

    minShape = currShape

  end

end

' Find percentage along the line for the point

perLine = minShape.PointPosition (aPoint)

if (theFTab.ReturnValue(lfa,minRec) < theFTab.ReturnValue(rfa,minRec)) then

  lowNum = theFTab.ReturnValue(lfa,minRec)

else

  lowNum = theFTab.ReturnValue(rfa,minRec)

end

if (theFTab.ReturnValue(lta,minRec) < theFTab.ReturnValue(rta,minRec)) then

  highNum = theFTab.ReturnValue(lta,minRec)

else

  highNum = theFTab.ReturnValue(rta,minRec)

end

' Compute the approximate address

aa = lowNum + ((highNum - lowNum) * (perLine/100))

aa.SetFormat( "dd" )

' Clear the Bitmap's selection

SelBitmap.ClearAll

aTheme.GetFTab.UpdateSelection

return(aa.asString++theFTab.ReturnValueString(addr,minRec))

'---------------------------------------------------------

'---------------------------------------------------------

' Part 2: CallReverseGeocode

' Example script that calls ReverseGeocode.

' Use with the Apply event on a Tool

'

aView  = av.GetActiveDoc

aTheme = aView.GetActiveThemes.Get(0)

theFTab = aTheme.getFTab

aPoint = aView.GetDisplay.ReturnUserPoint

' Draw the point on the display...

d = aView.GetDisplay

d.BeginClip

d.DrawPoint(aPoint,Symbol.Make(#SYMBOL_MARKER))

d.EndClip

d.Flush

aTol   = (aView.GetDisplay.ReturnExtent.GetWidth)/50

'Add field names to these lists if your attribute tables contain address

'fields with different names. This script can then be used for themes with

'fields named differently.

lfaList = {"L-f-add", "L_f_add", "L_add_from"}

rfaList = {"R-f-add", "R_f_add", "R_add_from"}

ltaList = {"L-t-add", "L_t_add", "L_add_to"}

rtaList = {"R-t-add", "R_t_add", "R_add_to"}

addrList = {"Fname", "Street_nam", "St_name"}

typeList = {"Ftype", "Street_typ", "St_typ"}

for each n in 0..(lfaList.Count-1)

 lfa = theFTab.FindField(lfaList.Get(n))

 if (lfa <> nil) then

   break

 end

end

for each n in 0..(rfaList.Count-1)

 rfa = theFTab.FindField(rfaList.Get(n))

  if (rfa <> nil) then

    break

 end

end

'

for each n in 0..(ltaList.Count-1)

 lta = theFTab.FindField(ltaList.Get(n))

 if (lta <> nil) then

   break

 end

end

for each n in 0..(rtaList.Count-1)

 rta = theFTab.FindField(rtaList.Get(n))

 if (rta <> nil) then

   break

 end

end

for each n in 0..(addrList.Count-1)

 addr = theFTab.FindField(addrList.Get(n))

 if (addr <> nil) then

   break

 end

end

for each n in 0..(typeList.Count-1)

 type = theFTab.FindField(typeList.Get(n)) if (type <> nil) then

   break

 end

end

address =

av.run("ReverseGeocode",{aPoint,aTheme,aTol,lfa.GetName,rfa.GetName,

  lta.GetName,rta.GetName,addr.GetName,type.GetName})

msgBox.Info(address,"Address")


MakeRGBColorPalette
Makes new color palette based on RGB values in file

Source Code

Description:   This script reads RGB values from a text file and then writes them into a new palettes file (.avp).  The RGB file must be a comma delimited text file where each line contains three values, e.g., 255,255,255.  Make certain there are no blank lines at the end of the RGB file.

Name:    MakeRGBColorPalette

Requires:

Self:

Returns:

FileName:  rgb2avp.ave


MakeRGBColorPalette  (Sample Script)
'Makes new color palette based on RGB values in file

rgb_name = FileDialog.Show("*.*", "All Files", "RGB2AVP Convert")

if (rgb_name = nil) then exit end

outfile = FileDialog.Put("mycolors.avp".AsFileName,"*.avp","New palette file")

rgb_file = LineFile.Make(rgb_name, #FILE_PERM_READ)

num_syms = rgb_file.GetSize

newPalette = Palette.Make

for each s in 1..num_Syms

  buf = rgb_file.ReadElt

  if (buf = nil) then

    continue

  else

    tokens = buf.AsTokens(",")

    r = tokens.Get(0).AsNumber

    g = tokens.Get(1).AsNumber

    b = tokens.Get(2).AsNumber

    nc = Color.Make

    nc.SetRGBList({r,g,b})

    newPalette.GetList(#PALETTE_LIST_COLOR).Add(nc)

  end

end

newPalette.SaveToFile(#PALETTE_LIST_COLOR,outfile)

rgb_file.close


Graphics.RGBDictionary
Makes an RGB NameDictionary

Source Code

Description:   Creates and returns a dictionary of RGB values for the X Window System color name database.  The ASCII color name is the dictionary key, the value for each key is a list of numbers; the RGB values for the named color.

The Color class in ArcView supports the specification of colors using RGB values.  This dictionary can be used to retrieve the RGB values for a specified color by creating a script as follows:

     rgbDictionary = av.Run("RGBColorNameDictionary", nil)

     plumRGBList = rgbDictionary.Get("plum")

or this script can be modified to return the RGB values directly.

Name:    Graphics.RGBDictionary

Requires:

Self:

Returns:

FileName:  rgbdict.ave


Graphics.RGBDictionary (Sample Script)
'Makes an RGB NameDictionary

RGB_Dictionary = Dictionary.Make(738)

RGB_Dictionary.Add( "medium violet red", { 199, 21, 133 } )

RGB_Dictionary.Add( "light steel blue", { 176, 196, 222 } )

RGB_Dictionary.Add( "paleturquoise4", { 102, 139, 139 } )

RGB_Dictionary.Add( "mediumpurple2", { 159, 121, 238 } )

RGB_Dictionary.Add( "lightskyblue3", { 141, 182, 205 } )

RGB_Dictionary.Add( "springgreen2", { 0, 238, 118 } )

RGB_Dictionary.Add( "light salmon", { 255, 160, 122 } )

RGB_Dictionary.Add( "yellowgreen", { 154, 205, 50 } )

RGB_Dictionary.Add( "darkorchid2", { 178, 58, 238 } )

RGB_Dictionary.Add( "aquamarine4", { 69, 139, 116 } )

RGB_Dictionary.Add( "slateblue4", { 71, 60, 139 } )

RGB_Dictionary.Add( "slateblue1", { 131, 111, 255 } )

RGB_Dictionary.Add( "olivedrab1", { 192, 255, 62 } )

RGB_Dictionary.Add( "goldenrod4", { 139, 105, 20 } )

RGB_Dictionary.Add( "goldenrod3", { 205, 155, 29 } )

RGB_Dictionary.Add( "cadetblue2", { 142, 229, 238 } )

RGB_Dictionary.Add( "burlywood1", { 255, 211, 155 } )

RGB_Dictionary.Add( "slategrey", { 112, 128, 144 } )

RGB_Dictionary.Add( "mistyrose", { 255, 228, 225 } )

RGB_Dictionary.Add( "limegreen", { 50, 205, 50 } )

RGB_Dictionary.Add( "lightcyan", { 224, 255, 255 } )

RGB_Dictionary.Add( "goldenrod", { 218, 165, 32 } )

RGB_Dictionary.Add( "gainsboro", { 220, 220, 220 } )

RGB_Dictionary.Add( "skyblue1", { 135, 206, 255 } )

RGB_Dictionary.Add( "honeydew", { 240, 255, 240 } )

RGB_Dictionary.Add( "yellow2", { 238, 238, 0 } )

RGB_Dictionary.Add( "tomato3", { 205, 79, 57 } )

RGB_Dictionary.Add( "skyblue", { 135, 206, 235 } )

RGB_Dictionary.Add( "purple4", { 85, 26, 139 } )

RGB_Dictionary.Add( "orange3", { 205, 133, 0 } )

RGB_Dictionary.Add( "bisque3", { 205, 183, 158 } )

RGB_Dictionary.Add( "bisque2", { 238, 213, 183 } )

RGB_Dictionary.Add( "grey34", { 87, 87, 87 } )

RGB_Dictionary.Add( "gray99", { 252, 252, 252 } )

RGB_Dictionary.Add( "gray63", { 161, 161, 161 } )

RGB_Dictionary.Add( "gray44", { 112, 112, 112 } )

RGB_Dictionary.Add( "gray37", { 94, 94, 94 } )

RGB_Dictionary.Add( "gray33", { 84, 84, 84 } )

RGB_Dictionary.Add( "gray26", { 66, 66, 66 } )

RGB_Dictionary.Add( "azure1", { 240, 255, 255 } )

RGB_Dictionary.Add( "snow4", { 139, 137, 137 } )

RGB_Dictionary.Add( "peru", { 205, 133, 63 } )

RGB_Dictionary.Add( "pale violet red", { 219, 112, 147 } )

RGB_Dictionary.Add( "lightgoldenrod4", { 139, 129, 76 } )

RGB_Dictionary.Add( "mediumseagreen", { 60, 179, 113 } )

RGB_Dictionary.Add( "lavender blush", { 255, 240, 245 } )

RGB_Dictionary.Add( "mediumorchid2", { 209, 95, 238 } )

RGB_Dictionary.Add( "lightskyblue1", { 176, 226, 255 } )

RGB_Dictionary.Add( "darkslateblue", { 72, 61, 139 } )

RGB_Dictionary.Add( "midnightblue", { 25, 25, 112 } )

RGB_Dictionary.Add( "lightsalmon1", { 255, 160, 122 } )

RGB_Dictionary.Add( "lemonchiffon", { 255, 250, 205 } )

RGB_Dictionary.Add( "green yellow", { 173, 255, 47 } )

RGB_Dictionary.Add( "lightsalmon", { 255, 160, 122 } )

RGB_Dictionary.Add( "light coral", { 240, 128, 128 } )

RGB_Dictionary.Add( "dodgerblue3", { 24, 116, 205 } )

RGB_Dictionary.Add( "darkorange4", { 139, 69, 0 } )

RGB_Dictionary.Add( "slate blue", { 106, 90, 205 } )

RGB_Dictionary.Add( "royalblue4", { 39, 64, 139 } )

RGB_Dictionary.Add( "orange red", { 255, 69, 0 } )

RGB_Dictionary.Add( "lime green", { 50, 205, 50 } )

RGB_Dictionary.Add( "light cyan", { 224, 255, 255 } )

RGB_Dictionary.Add( "darkviolet", { 148, 0, 211 } )

RGB_Dictionary.Add( "darksalmon", { 233, 150, 122 } )

RGB_Dictionary.Add( "darkorange", { 255, 140, 0 } )

RGB_Dictionary.Add( "cadet blue", { 95, 158, 160 } )

RGB_Dictionary.Add( "deep pink", { 255, 20, 147 } )

RGB_Dictionary.Add( "magenta2", { 238, 0, 238 } )

RGB_Dictionary.Add( "sienna4", { 139, 71, 38 } )

RGB_Dictionary.Add( "khaki2", { 238, 230, 133 } )

RGB_Dictionary.Add( "grey75", { 191, 191, 191 } )

RGB_Dictionary.Add( "grey74", { 189, 189, 189 } )

RGB_Dictionary.Add( "grey73", { 186, 186, 186 } )

RGB_Dictionary.Add( "grey69", { 176, 176, 176 } )

RGB_Dictionary.Add( "grey68", { 173, 173, 173 } )

RGB_Dictionary.Add( "grey35", { 89, 89, 89 } )

RGB_Dictionary.Add( "grey13", { 33, 33, 33 } )

RGB_Dictionary.Add( "gray90", { 229, 229, 229 } )

RGB_Dictionary.Add( "gray81", { 207, 207, 207 } )

RGB_Dictionary.Add( "gray55", { 140, 140, 140 } )

RGB_Dictionary.Add( "gray51", { 130, 130, 130 } )

RGB_Dictionary.Add( "gray31", { 79, 79, 79 } )

RGB_Dictionary.Add( "snow2", { 238, 233, 233 } )

RGB_Dictionary.Add( "pink3", { 205, 145, 158 } )

RGB_Dictionary.Add( "grey7", { 18, 18, 18 } )

RGB_Dictionary.Add( "gray1", { 3, 3, 3 } )

RGB_Dictionary.Add( "red4", { 139, 0, 0 } )

RGB_Dictionary.Add( "red3", { 205, 0, 0 } )

RGB_Dictionary.Add( "tan", { 210, 180, 140 } )

RGB_Dictionary.Add( "red", { 255, 0, 0 } )

RGB_Dictionary.Add( "mediumvioletred", { 199, 21, 133 } )

RGB_Dictionary.Add( "lightslategrey", { 119, 136, 153 } )

RGB_Dictionary.Add( "lightskyblue", { 135, 206, 250 } )

RGB_Dictionary.Add( "lightsalmon4", { 139, 87, 66 } )

RGB_Dictionary.Add( "forestgreen", { 34, 139, 34 } )

RGB_Dictionary.Add( "dodgerblue4", { 16, 78, 139 } )

RGB_Dictionary.Add( "dark orchid", { 153, 50, 204 } )

RGB_Dictionary.Add( "rosy brown", { 188, 143, 143 } )

RGB_Dictionary.Add( "peachpuff3", { 205, 175, 149 } )

RGB_Dictionary.Add( "palegreen3", { 124, 205, 124 } )

RGB_Dictionary.Add( "orangered2", { 238, 64, 0 } )

RGB_Dictionary.Add( "lightcyan4", { 122, 139, 139 } )

RGB_Dictionary.Add( "indianred4", { 139, 58, 58 } )

RGB_Dictionary.Add( "indianred3", { 205, 85, 85 } )

RGB_Dictionary.Add( "navyblue", { 0, 0, 128 } )

RGB_Dictionary.Add( "dim grey", { 105, 105, 105 } )

RGB_Dictionary.Add( "deeppink", { 255, 20, 147 } )

RGB_Dictionary.Add( "salmon4", { 139, 76, 57 } )

RGB_Dictionary.Add( "salmon3", { 205, 112, 84 } )

RGB_Dictionary.Add( "grey77", { 196, 196, 196 } )

RGB_Dictionary.Add( "gray57", { 145, 145, 145 } )

RGB_Dictionary.Add( "gray11", { 28, 28, 28 } )

RGB_Dictionary.Add( "plum3", { 205, 150, 205 } )

RGB_Dictionary.Add( "gray9", { 23, 23, 23 } )

RGB_Dictionary.Add( "gray8", { 20, 20, 20 } )

RGB_Dictionary.Add( "blue4", { 0, 0, 139 } )

RGB_Dictionary.Add( "beige", { 245, 245, 220 } )

RGB_Dictionary.Add( "light goldenrod yellow", { 250, 250, 210 } )

RGB_Dictionary.Add( "lavenderblush4", { 139, 131, 134 } )

RGB_Dictionary.Add( "dark turquoise", { 0, 206, 209 } )

RGB_Dictionary.Add( "darkturquoise", { 0, 206, 209 } )

RGB_Dictionary.Add( "darkslategrey", { 47, 79, 79 } )

RGB_Dictionary.Add( "lightsalmon3", { 205, 129, 98 } )

RGB_Dictionary.Add( "rosybrown4", { 139, 105, 105 } )

RGB_Dictionary.Add( "misty rose", { 255, 228, 225 } )

RGB_Dictionary.Add( "seagreen2", { 78, 238, 148 } )

RGB_Dictionary.Add( "indianred", { 205, 92, 92 } )

RGB_Dictionary.Add( "deeppink1", { 255, 20, 147 } )

RGB_Dictionary.Add( "lavender", { 230, 230, 250 } )

RGB_Dictionary.Add( "oldlace", { 253, 245, 230 } )

RGB_Dictionary.Add( "grey78", { 199, 199, 199 } )

RGB_Dictionary.Add( "grey54", { 138, 138, 138 } )

RGB_Dictionary.Add( "grey45", { 115, 115, 115 } )

RGB_Dictionary.Add( "grey21", { 54, 54, 54 } )

RGB_Dictionary.Add( "gray97", { 247, 247, 247 } )

RGB_Dictionary.Add( "gray96", { 245, 245, 245 } )

RGB_Dictionary.Add( "gray95", { 242, 242, 242 } )

RGB_Dictionary.Add( "gray88", { 224, 224, 224 } )

RGB_Dictionary.Add( "gray87", { 222, 222, 222 } )

RGB_Dictionary.Add( "gray86", { 219, 219, 219 } )

RGB_Dictionary.Add( "gray70", { 179, 179, 179 } )

RGB_Dictionary.Add( "gray38", { 97, 97, 97 } )

RGB_Dictionary.Add( "gray12", { 31, 31, 31 } )

RGB_Dictionary.Add( "linen", { 250, 240, 230 } )

RGB_Dictionary.Add( "medium turquoise", { 72, 209, 204 } )

RGB_Dictionary.Add( "dark slate blue", { 72, 61, 139 } )

RGB_Dictionary.Add( "lemonchiffon4", { 139, 137, 112 } )

RGB_Dictionary.Add( "darkseagreen1", { 193, 255, 193 } )

RGB_Dictionary.Add( "antiquewhite3", { 205, 192, 176 } )

RGB_Dictionary.Add( "mediumorchid", { 186, 85, 211 } )

RGB_Dictionary.Add( "springgreen", { 0, 255, 127 } )

RGB_Dictionary.Add( "turquoise4", { 0, 134, 139 } )

RGB_Dictionary.Add( "steelblue3", { 79, 148, 205 } )

RGB_Dictionary.Add( "mistyrose2", { 238, 213, 210 } )

RGB_Dictionary.Add( "lightcyan2", { 209, 238, 238 } )

RGB_Dictionary.Add( "indian red", { 205, 92, 92 } )

RGB_Dictionary.Add( "firebrick2", { 238, 44, 44 } )

RGB_Dictionary.Add( "royalblue", { 65, 105, 225 } )

RGB_Dictionary.Add( "cadetblue", { 95, 158, 160 } )

RGB_Dictionary.Add( "skyblue3", { 108, 166, 205 } )

RGB_Dictionary.Add( "yellow3", { 205, 205, 0 } )

RGB_Dictionary.Add( "salmon1", { 255, 140, 105 } )

RGB_Dictionary.Add( "orange4", { 139, 90, 0 } )

RGB_Dictionary.Add( "hotpink", { 255, 105, 180 } )

RGB_Dictionary.Add( "grey90", { 229, 229, 229 } )

RGB_Dictionary.Add( "gray56", { 143, 143, 143 } )

RGB_Dictionary.Add( "gray39", { 99, 99, 99 } )

RGB_Dictionary.Add( "gray18", { 46, 46, 46 } )

RGB_Dictionary.Add( "gray14", { 36, 36, 36 } )

RGB_Dictionary.Add( "plum4", { 139, 102, 139 } )

RGB_Dictionary.Add( "grey6", { 15, 15, 15 } )

RGB_Dictionary.Add( "gray6", { 15, 15, 15 } )

RGB_Dictionary.Add( "gold3", { 205, 173, 0 } )

RGB_Dictionary.Add( "gold1", { 255, 215, 0 } )

RGB_Dictionary.Add( "blue2", { 0, 0, 238 } )

RGB_Dictionary.Add( "tan2", { 238, 154, 73 } )

RGB_Dictionary.Add( "cyan", { 0, 255, 255 } )

RGB_Dictionary.Add( "mediumspringgreen", { 0, 250, 154 } )

RGB_Dictionary.Add( "darkolivegreen2", { 188, 238, 104 } )

RGB_Dictionary.Add( "pale goldenrod", { 238, 232, 170 } )

RGB_Dictionary.Add( "lightsteelblue", { 176, 196, 222 } )

RGB_Dictionary.Add( "sandy brown", { 244, 164, 96 } )

RGB_Dictionary.Add( "papaya whip", { 255, 239, 213 } )

RGB_Dictionary.Add( "chartreuse3", { 102, 205, 0 } )

RGB_Dictionary.Add( "violetred4", { 139, 34, 82 } )

RGB_Dictionary.Add( "royalblue2", { 67, 110, 238 } )

RGB_Dictionary.Add( "royalblue1", { 72, 118, 255 } )

RGB_Dictionary.Add( "papayawhip", { 255, 239, 213 } )

RGB_Dictionary.Add( "mistyrose3", { 205, 183, 181 } )

RGB_Dictionary.Add( "lightcyan1", { 224, 255, 255 } )

RGB_Dictionary.Add( "aquamarine", { 127, 255, 212 } )

RGB_Dictionary.Add( "skyblue4", { 74, 112, 139 } )

RGB_Dictionary.Add( "hotpink4", { 139, 58, 98 } )

RGB_Dictionary.Add( "hotpink3", { 205, 96, 144 } )

RGB_Dictionary.Add( "hotpink2", { 238, 106, 167 } )

RGB_Dictionary.Add( "dimgray", { 105, 105, 105 } )

RGB_Dictionary.Add( "tomato", { 255, 99, 71 } )

RGB_Dictionary.Add( "grey66", { 168, 168, 168 } )

RGB_Dictionary.Add( "grey65", { 166, 166, 166 } )

RGB_Dictionary.Add( "grey64", { 163, 163, 163 } )

RGB_Dictionary.Add( "grey33", { 84, 84, 84 } )

RGB_Dictionary.Add( "grey27", { 69, 69, 69 } )

RGB_Dictionary.Add( "gray76", { 194, 194, 194 } )

RGB_Dictionary.Add( "gray69", { 176, 176, 176 } )

RGB_Dictionary.Add( "gray68", { 173, 173, 173 } )

RGB_Dictionary.Add( "grey0", { 0, 0, 0 } )

RGB_Dictionary.Add( "azure", { 240, 255, 255 } )

RGB_Dictionary.Add( "medium spring green", { 0, 250, 154 } )

RGB_Dictionary.Add( "darkgoldenrod4", { 139, 101, 8 } )

RGB_Dictionary.Add( "darkgoldenrod3", { 205, 149, 12 } )

RGB_Dictionary.Add( "darkgoldenrod2", { 238, 173, 14 } )

RGB_Dictionary.Add( "darkgoldenrod", { 184, 134, 11 } )

RGB_Dictionary.Add( "saddle brown", { 139, 69, 19 } )

RGB_Dictionary.Add( "lightsalmon2", { 238, 149, 114 } )

RGB_Dictionary.Add( "deepskyblue4", { 0, 104, 139 } )

RGB_Dictionary.Add( "deepskyblue3", { 0, 154, 205 } )

RGB_Dictionary.Add( "deepskyblue2", { 0, 178, 238 } )

RGB_Dictionary.Add( "deepskyblue", { 0, 191, 255 } )

RGB_Dictionary.Add( "darkorange1", { 255, 127, 0 } )

RGB_Dictionary.Add( "violetred3", { 205, 50, 120 } )

RGB_Dictionary.Add( "violetred2", { 238, 58, 140 } )

RGB_Dictionary.Add( "violetred1", { 255, 62, 150 } )

RGB_Dictionary.Add( "slateblue3", { 105, 89, 205 } )

RGB_Dictionary.Add( "slateblue2", { 122, 103, 238 } )

RGB_Dictionary.Add( "olive drab", { 107, 142, 35 } )

RGB_Dictionary.Add( "indianred1", { 255, 106, 106 } )

RGB_Dictionary.Add( "firebrick1", { 255, 48, 48 } )

RGB_Dictionary.Add( "cadetblue4", { 83, 134, 139 } )

RGB_Dictionary.Add( "violetred", { 208, 32, 144 } )

RGB_Dictionary.Add( "rosybrown", { 188, 143, 143 } )

RGB_Dictionary.Add( "navy blue", { 0, 0, 128 } )

RGB_Dictionary.Add( "firebrick", { 178, 34, 34 } )

RGB_Dictionary.Add( "grey100", { 255, 255, 255 } )

RGB_Dictionary.Add( "wheat4", { 139, 126, 102 } )

RGB_Dictionary.Add( "grey79", { 201, 201, 201 } )

RGB_Dictionary.Add( "grey76", { 194, 194, 194 } )

RGB_Dictionary.Add( "grey61", { 156, 156, 156 } )

RGB_Dictionary.Add( "gray93", { 237, 237, 237 } )

RGB_Dictionary.Add( "gray84", { 214, 214, 214 } )

RGB_Dictionary.Add( "gray65", { 166, 166, 166 } )

RGB_Dictionary.Add( "gray36", { 92, 92, 92 } )

RGB_Dictionary.Add( "gray32", { 82, 82, 82 } )

RGB_Dictionary.Add( "gray13", { 33, 33, 33 } )

RGB_Dictionary.Add( "gray10", { 26, 26, 26 } )

RGB_Dictionary.Add( "azure3", { 193, 205, 205 } )

RGB_Dictionary.Add( "snow1", { 255, 250, 250 } )

RGB_Dictionary.Add( "tan1", { 255, 165, 79 } )

RGB_Dictionary.Add( "light slate gray", { 119, 136, 153 } )

RGB_Dictionary.Add( "darkolivegreen1", { 202, 255, 112 } )

RGB_Dictionary.Add( "cornflower blue", { 100, 149, 237 } )

RGB_Dictionary.Add( "blanched almond", { 255, 235, 205 } )

RGB_Dictionary.Add( "lavenderblush3", { 205, 193, 197 } )

RGB_Dictionary.Add( "lavenderblush2", { 238, 224, 229 } )

RGB_Dictionary.Add( "lavenderblush1", { 255, 240, 245 } )

RGB_Dictionary.Add( "darkolivegreen", { 85, 107, 47 } )

RGB_Dictionary.Add( "lavenderblush", { 255, 240, 245 } )

RGB_Dictionary.Add( "aquamarine2", { 118, 238, 198 } )

RGB_Dictionary.Add( "violet red", { 208, 32, 144 } )

RGB_Dictionary.Add( "olivedrab2", { 179, 238, 58 } )

RGB_Dictionary.Add( "mistyrose4", { 139, 125, 123 } )

RGB_Dictionary.Add( "mistyrose1", { 255, 228, 225 } )

RGB_Dictionary.Add( "lightcyan3", { 180, 205, 205 } )

RGB_Dictionary.Add( "lightcoral", { 240, 128, 128 } )

RGB_Dictionary.Add( "chartreuse", { 127, 255, 0 } )

RGB_Dictionary.Add( "peachpuff", { 255, 218, 185 } )

RGB_Dictionary.Add( "palegreen", { 152, 251, 152 } )

RGB_Dictionary.Add( "mintcream", { 245, 255, 250 } )

RGB_Dictionary.Add( "skyblue2", { 126, 192, 238 } )

RGB_Dictionary.Add( "moccasin", { 255, 228, 181 } )

RGB_Dictionary.Add( "tomato1", { 255, 99, 71 } )

RGB_Dictionary.Add( "orchid3", { 205, 105, 201 } )

RGB_Dictionary.Add( "maroon3", { 205, 41, 144 } )

RGB_Dictionary.Add( "salmon", { 250, 128, 114 } )

RGB_Dictionary.Add( "grey81", { 207, 207, 207 } )

RGB_Dictionary.Add( "grey62", { 158, 158, 158 } )

RGB_Dictionary.Add( "grey39", { 99, 99, 99 } )

RGB_Dictionary.Add( "grey38", { 97, 97, 97 } )

RGB_Dictionary.Add( "grey37", { 94, 94, 94 } )

RGB_Dictionary.Add( "gray92", { 235, 235, 235 } )

RGB_Dictionary.Add( "gray83", { 212, 212, 212 } )

RGB_Dictionary.Add( "gray66", { 168, 168, 168 } )

RGB_Dictionary.Add( "gray54", { 138, 138, 138 } )

RGB_Dictionary.Add( "gray50", { 127, 127, 127 } )

RGB_Dictionary.Add( "gray30", { 77, 77, 77 } )

RGB_Dictionary.Add( "gray19", { 48, 48, 48 } )

RGB_Dictionary.Add( "gray15", { 38, 38, 38 } )

RGB_Dictionary.Add( "azure4", { 131, 139, 139 } )

RGB_Dictionary.Add( "grey3", { 8, 8, 8 } )

RGB_Dictionary.Add( "tan3", { 205, 133, 63 } )

RGB_Dictionary.Add( "pink", { 255, 192, 203 } )

RGB_Dictionary.Add( "gray", { 192, 192, 192 } )

RGB_Dictionary.Add( "blue", { 0, 0, 255 } )

RGB_Dictionary.Add( "lightsteelblue2", { 188, 210, 238 } )

RGB_Dictionary.Add( "lightsteelblue1", { 202, 225, 255 } )

RGB_Dictionary.Add( "light sea green", { 32, 178, 170 } )

RGB_Dictionary.Add( "lightslategray", { 119, 136, 153 } )

RGB_Dictionary.Add( "lemonchiffon2", { 238, 233, 191 } )

RGB_Dictionary.Add( "springgreen1", { 0, 255, 127 } )

RGB_Dictionary.Add( "greenyellow", { 173, 255, 47 } )

RGB_Dictionary.Add( "chartreuse2", { 118, 238, 0 } )

RGB_Dictionary.Add( "slate grey", { 112, 128, 144 } )

RGB_Dictionary.Add( "royalblue3", { 58, 95, 205 } )

RGB_Dictionary.Add( "powderblue", { 176, 224, 230 } )

RGB_Dictionary.Add( "peachpuff2", { 238, 203, 173 } )

RGB_Dictionary.Add( "palegreen2", { 144, 238, 144 } )

RGB_Dictionary.Add( "mint cream", { 245, 255, 250 } )

RGB_Dictionary.Add( "slateblue", { 106, 90, 205 } )

RGB_Dictionary.Add( "seashell2", { 238, 229, 222 } )

RGB_Dictionary.Add( "deeppink2", { 238, 18, 137 } )

RGB_Dictionary.Add( "darkkhaki", { 189, 183, 107 } )

RGB_Dictionary.Add( "maroon4", { 139, 28, 98 } )

RGB_Dictionary.Add( "sienna", { 160, 82, 45 } )

RGB_Dictionary.Add( "grey71", { 181, 181, 181 } )

RGB_Dictionary.Add( "grey67", { 171, 171, 171 } )

RGB_Dictionary.Add( "grey18", { 46, 46, 46 } )

RGB_Dictionary.Add( "gray59", { 150, 150, 150 } )

RGB_Dictionary.Add( "gray43", { 110, 110, 110 } )

RGB_Dictionary.Add( "gray25", { 64, 64, 64 } )

RGB_Dictionary.Add( "bisque", { 255, 228, 196 } )

RGB_Dictionary.Add( "red1", { 255, 0, 0 } )

RGB_Dictionary.Add( "mediumslateblue", { 123, 104, 238 } )

RGB_Dictionary.Add( "lightgoldenrod1", { 255, 236, 139 } )

RGB_Dictionary.Add( "light goldenrod", { 238, 221, 130 } )

RGB_Dictionary.Add( "paleturquoise3", { 150, 205, 205 } )

RGB_Dictionary.Add( "lightskyblue4", { 96, 123, 139 } )

RGB_Dictionary.Add( "spring green", { 0, 255, 127 } )

RGB_Dictionary.Add( "light yellow", { 255, 255, 224 } )

RGB_Dictionary.Add( "white smoke", { 245, 245, 245 } )

RGB_Dictionary.Add( "medium blue", { 0, 0, 205 } )

RGB_Dictionary.Add( "ghost white", { 248, 248, 255 } )

RGB_Dictionary.Add( "steelblue4", { 54, 100, 139 } )

RGB_Dictionary.Add( "rosybrown3", { 205, 155, 155 } )

RGB_Dictionary.Add( "peachpuff1", { 255, 218, 185 } )

RGB_Dictionary.Add( "palegreen1", { 154, 255, 154 } )

RGB_Dictionary.Add( "blueviolet", { 138, 43, 226 } )

RGB_Dictionary.Add( "seashell4", { 139, 134, 130 } )

RGB_Dictionary.Add( "sienna3", { 205, 104, 57 } )

RGB_Dictionary.Add( "grey40", { 102, 102, 102 } )

RGB_Dictionary.Add( "gray91", { 232, 232, 232 } )

RGB_Dictionary.Add( "gray82", { 209, 209, 209 } )

RGB_Dictionary.Add( "gray5", { 13, 13, 13 } )

RGB_Dictionary.Add( "cyan2", { 0, 238, 238 } )

RGB_Dictionary.Add( "cyan1", { 0, 255, 255 } )

RGB_Dictionary.Add( "blue1", { 0, 0, 255 } )

RGB_Dictionary.Add( "snow", { 255, 250, 250 } )

RGB_Dictionary.Add( "lightgoldenrod2", { 238, 220, 130 } )

RGB_Dictionary.Add( "lightslateblue", { 132, 112, 255 } )

RGB_Dictionary.Add( "mediumorchid3", { 180, 82, 205 } )

RGB_Dictionary.Add( "darkseagreen4", { 105, 139, 105 } )

RGB_Dictionary.Add( "springgreen3", { 0, 205, 102 } )

RGB_Dictionary.Add( "forest green", { 34, 139, 34 } )

RGB_Dictionary.Add( "slategray4", { 108, 123, 139 } )

RGB_Dictionary.Add( "slategray3", { 159, 182, 205 } )

RGB_Dictionary.Add( "slategray2", { 185, 211, 238 } )

RGB_Dictionary.Add( "royal blue", { 65, 105, 225 } )

RGB_Dictionary.Add( "peachpuff4", { 139, 119, 101 } )

RGB_Dictionary.Add( "palegreen4", { 84, 139, 84 } )

RGB_Dictionary.Add( "pale green", { 152, 251, 152 } )

RGB_Dictionary.Add( "orangered3", { 205, 55, 0 } )

RGB_Dictionary.Add( "goldenrod1", { 255, 193, 37 } )

RGB_Dictionary.Add( "ghostwhite", { 248, 248, 255 } )

RGB_Dictionary.Add( "firebrick4", { 139, 26, 26 } )

RGB_Dictionary.Add( "firebrick3", { 205, 38, 38 } )

RGB_Dictionary.Add( "cadetblue3", { 122, 197, 205 } )

RGB_Dictionary.Add( "slategray", { 112, 128, 144 } )

RGB_Dictionary.Add( "seashell3", { 205, 197, 191 } )

RGB_Dictionary.Add( "honeydew3", { 193, 205, 193 } )

RGB_Dictionary.Add( "cornsilk4", { 139, 136, 120 } )

RGB_Dictionary.Add( "cornsilk2", { 238, 232, 205 } )

RGB_Dictionary.Add( "purple1", { 155, 48, 255 } )

RGB_Dictionary.Add( "dimgrey", { 105, 105, 105 } )

RGB_Dictionary.Add( "khaki1", { 255, 246, 143 } )

RGB_Dictionary.Add( "ivory3", { 205, 205, 193 } )

RGB_Dictionary.Add( "grey70", { 179, 179, 179 } )

RGB_Dictionary.Add( "grey60", { 153, 153, 153 } )

RGB_Dictionary.Add( "grey32", { 82, 82, 82 } )

RGB_Dictionary.Add( "grey22", { 56, 56, 56 } )

RGB_Dictionary.Add( "grey12", { 31, 31, 31 } )

RGB_Dictionary.Add( "gray98", { 250, 250, 250 } )

RGB_Dictionary.Add( "gray89", { 227, 227, 227 } )

RGB_Dictionary.Add( "gray71", { 181, 181, 181 } )

RGB_Dictionary.Add( "gray64", { 163, 163, 163 } )

RGB_Dictionary.Add( "gray60", { 153, 153, 153 } )

RGB_Dictionary.Add( "gray49", { 125, 125, 125 } )

RGB_Dictionary.Add( "azure2", { 224, 238, 238 } )

RGB_Dictionary.Add( "gray3", { 8, 8, 8 } )

RGB_Dictionary.Add( "paleturquoise1", { 187, 255, 255 } )

RGB_Dictionary.Add( "mediumpurple1", { 171, 130, 255 } )

RGB_Dictionary.Add( "medium purple", { 147, 112, 219 } )

RGB_Dictionary.Add( "lemonchiffon1", { 255, 250, 205 } )

RGB_Dictionary.Add( "deep sky blue", { 0, 191, 255 } )

RGB_Dictionary.Add( "navajowhite3", { 205, 179, 139 } )

RGB_Dictionary.Add( "darkorchid1", { 191, 62, 255 } )

RGB_Dictionary.Add( "dark orange", { 255, 140, 0 } )

RGB_Dictionary.Add( "goldenrod2", { 238, 180, 34 } )

RGB_Dictionary.Add( "dark khaki", { 189, 183, 107 } )

RGB_Dictionary.Add( "chocolate2", { 238, 118, 33 } )

RGB_Dictionary.Add( "burlywood2", { 238, 197, 145 } )

RGB_Dictionary.Add( "honeydew1", { 240, 255, 240 } )

RGB_Dictionary.Add( "darkgreen", { 0, 100, 0 } )

RGB_Dictionary.Add( "thistle3", { 205, 181, 205 } )

RGB_Dictionary.Add( "thistle2", { 238, 210, 238 } )

RGB_Dictionary.Add( "thistle1", { 255, 225, 255 } )

RGB_Dictionary.Add( "thistle", { 216, 191, 216 } )

RGB_Dictionary.Add( "maroon2", { 238, 48, 167 } )

RGB_Dictionary.Add( "maroon1", { 255, 52, 179 } )

RGB_Dictionary.Add( "grey53", { 135, 135, 135 } )

RGB_Dictionary.Add( "grey44", { 112, 112, 112 } )

RGB_Dictionary.Add( "grey25", { 64, 64, 64 } )

RGB_Dictionary.Add( "gray74", { 189, 189, 189 } )

RGB_Dictionary.Add( "gray45", { 115, 115, 115 } )

RGB_Dictionary.Add( "gray41", { 105, 105, 105 } )

RGB_Dictionary.Add( "gray35", { 89, 89, 89 } )

RGB_Dictionary.Add( "gray27", { 69, 69, 69 } )

RGB_Dictionary.Add( "gray23", { 59, 59, 59 } )

RGB_Dictionary.Add( "gray16", { 41, 41, 41 } )

RGB_Dictionary.Add( "brown4", { 139, 35, 35 } )

RGB_Dictionary.Add( "wheat", { 245, 222, 179 } )

RGB_Dictionary.Add( "coral", { 255, 127, 80 } )

RGB_Dictionary.Add( "tan4", { 139, 90, 43 } )

RGB_Dictionary.Add( "lightgoldenrodyellow", { 250, 250, 210 } )

RGB_Dictionary.Add( "light slate blue", { 132, 112, 255 } )

RGB_Dictionary.Add( "dark olive green", { 85, 107, 47 } )

RGB_Dictionary.Add( "dark slate gray", { 47, 79, 79 } )

RGB_Dictionary.Add( "palevioletred3", { 205, 104, 137 } )

RGB_Dictionary.Add( "mediumpurple4", { 93, 71, 139 } )

RGB_Dictionary.Add( "mediumpurple3", { 137, 104, 205 } )

RGB_Dictionary.Add( "saddlebrown", { 139, 69, 19 } )

RGB_Dictionary.Add( "powder blue", { 176, 224, 230 } )

RGB_Dictionary.Add( "darkorchid4", { 104, 34, 139 } )

RGB_Dictionary.Add( "darkorchid3", { 154, 50, 205 } )

RGB_Dictionary.Add( "peach puff", { 255, 218, 185 } )

RGB_Dictionary.Add( "olivedrab4", { 105, 139, 34 } )

RGB_Dictionary.Add( "lightblue4", { 104, 131, 139 } )

RGB_Dictionary.Add( "lightpink", { 255, 182, 193 } )

RGB_Dictionary.Add( "lightgray", { 211, 211, 211 } )

RGB_Dictionary.Add( "honeydew2", { 224, 238, 224 } )

RGB_Dictionary.Add( "cornsilk1", { 255, 248, 220 } )

RGB_Dictionary.Add( "old lace", { 253, 245, 230 } )

RGB_Dictionary.Add( "sienna1", { 255, 130, 71 } )

RGB_Dictionary.Add( "bisque4", { 139, 125, 107 } )

RGB_Dictionary.Add( "orchid", { 218, 112, 214 } )

RGB_Dictionary.Add( "khaki3", { 205, 198, 115 } )

RGB_Dictionary.Add( "grey84", { 214, 214, 214 } )

RGB_Dictionary.Add( "grey83", { 212, 212, 212 } )

RGB_Dictionary.Add( "grey82", { 209, 209, 209 } )

RGB_Dictionary.Add( "grey72", { 184, 184, 184 } )

RGB_Dictionary.Add( "grey52", { 133, 133, 133 } )

RGB_Dictionary.Add( "grey43", { 110, 110, 110 } )

RGB_Dictionary.Add( "grey26", { 66, 66, 66 } )

RGB_Dictionary.Add( "grey14", { 36, 36, 36 } )

RGB_Dictionary.Add( "grey10", { 26, 26, 26 } )

RGB_Dictionary.Add( "gray75", { 191, 191, 191 } )

RGB_Dictionary.Add( "gray53", { 135, 135, 135 } )

RGB_Dictionary.Add( "gray21", { 54, 54, 54 } )

RGB_Dictionary.Add( "gray20", { 51, 51, 51 } )

RGB_Dictionary.Add( "brown3", { 205, 51, 51 } )

RGB_Dictionary.Add( "grey8", { 20, 20, 20 } )

RGB_Dictionary.Add( "red2", { 238, 0, 0 } )

RGB_Dictionary.Add( "navy", { 0, 0, 128 } )

RGB_Dictionary.Add( "grey", { 192, 192, 192 } )

RGB_Dictionary.Add( "gold", { 255, 215, 0 } )

RGB_Dictionary.Add( "mediumaquamarine", { 102, 205, 170 } )

RGB_Dictionary.Add( "lightgoldenrod", { 238, 221, 130 } )

RGB_Dictionary.Add( "darkslategray4", { 82, 139, 139 } )

RGB_Dictionary.Add( "darkseagreen3", { 155, 205, 155 } )

RGB_Dictionary.Add( "darkseagreen2", { 180, 238, 180 } )

RGB_Dictionary.Add( "antiquewhite4", { 139, 131, 120 } )

RGB_Dictionary.Add( "antique white", { 250, 235, 215 } )

RGB_Dictionary.Add( "springgreen4", { 0, 139, 69 } )

RGB_Dictionary.Add( "lightyellow4", { 139, 139, 122 } )

RGB_Dictionary.Add( "floral white", { 255, 250, 240 } )

RGB_Dictionary.Add( "aquamarine1", { 127, 255, 212 } )

RGB_Dictionary.Add( "turquoise3", { 0, 197, 205 } )

RGB_Dictionary.Add( "steelblue2", { 92, 172, 238 } )

RGB_Dictionary.Add( "rosybrown2", { 238, 180, 180 } )

RGB_Dictionary.Add( "light pink", { 255, 182, 193 } )

RGB_Dictionary.Add( "light gray", { 211, 211, 211 } )

RGB_Dictionary.Add( "indianred2", { 238, 99, 99 } )

RGB_Dictionary.Add( "dodgerblue", { 30, 144, 255 } )

RGB_Dictionary.Add( "dark green", { 0, 100, 0 } )

RGB_Dictionary.Add( "seagreen1", { 84, 255, 159 } )

RGB_Dictionary.Add( "deeppink4", { 139, 10, 80 } )

RGB_Dictionary.Add( "aliceblue", { 240, 248, 255 } )

RGB_Dictionary.Add( "magenta1", { 255, 0, 255 } )

RGB_Dictionary.Add( "hot pink", { 255, 105, 180 } )

RGB_Dictionary.Add( "sienna2", { 238, 121, 66 } )

RGB_Dictionary.Add( "orchid1", { 255, 131, 250 } )

RGB_Dictionary.Add( "gray100", { 255, 255, 255 } )

RGB_Dictionary.Add( "grey97", { 247, 247, 247 } )

RGB_Dictionary.Add( "grey94", { 240, 240, 240 } )

RGB_Dictionary.Add( "grey87", { 222, 222, 222 } )

RGB_Dictionary.Add( "grey86", { 219, 219, 219 } )

RGB_Dictionary.Add( "grey51", { 130, 130, 130 } )

RGB_Dictionary.Add( "grey42", { 107, 107, 107 } )

RGB_Dictionary.Add( "grey19", { 48, 48, 48 } )

RGB_Dictionary.Add( "gray94", { 240, 240, 240 } )

RGB_Dictionary.Add( "gray85", { 217, 217, 217 } )

RGB_Dictionary.Add( "gray61", { 156, 156, 156 } )

RGB_Dictionary.Add( "brown2", { 238, 59, 59 } )

RGB_Dictionary.Add( "khaki", { 240, 230, 140 } )

RGB_Dictionary.Add( "grey1", { 3, 3, 3 } )

RGB_Dictionary.Add( "gold4", { 139, 117, 0 } )

RGB_Dictionary.Add( "mediumorchid4", { 122, 55, 139 } )

RGB_Dictionary.Add( "lightyellow2", { 238, 238, 209 } )

RGB_Dictionary.Add( "dark violet", { 148, 0, 211 } )

RGB_Dictionary.Add( "dark salmon", { 233, 150, 122 } )

RGB_Dictionary.Add( "turquoise1", { 0, 245, 255 } )

RGB_Dictionary.Add( "lightpink1", { 255, 174, 185 } )

RGB_Dictionary.Add( "lightblue2", { 178, 223, 238 } )

RGB_Dictionary.Add( "lightblue1", { 191, 239, 255 } )

RGB_Dictionary.Add( "deeppink3", { 205, 16, 118 } )

RGB_Dictionary.Add( "hotpink1", { 255, 110, 180 } )

RGB_Dictionary.Add( "yellow4", { 139, 139, 0 } )

RGB_Dictionary.Add( "grey89", { 227, 227, 227 } )

RGB_Dictionary.Add( "grey63", { 161, 161, 161 } )

RGB_Dictionary.Add( "grey58", { 148, 148, 148 } )

RGB_Dictionary.Add( "grey49", { 125, 125, 125 } )

RGB_Dictionary.Add( "grey31", { 79, 79, 79 } )

RGB_Dictionary.Add( "grey24", { 61, 61, 61 } )

RGB_Dictionary.Add( "grey20", { 51, 51, 51 } )

RGB_Dictionary.Add( "gray73", { 186, 186, 186 } )

RGB_Dictionary.Add( "gray67", { 171, 171, 171 } )

RGB_Dictionary.Add( "coral3", { 205, 91, 69 } )

RGB_Dictionary.Add( "ivory", { 255, 255, 240 } )

RGB_Dictionary.Add( "gray4", { 10, 10, 10 } )

RGB_Dictionary.Add( "gray2", { 5, 5, 5 } )

RGB_Dictionary.Add( "medium slate blue", { 123, 104, 238 } )

RGB_Dictionary.Add( "medium sea green", { 60, 179, 113 } )

RGB_Dictionary.Add( "dark slate grey", { 47, 79, 79 } )

RGB_Dictionary.Add( "pale turquoise", { 175, 238, 238 } )

RGB_Dictionary.Add( "paleturquoise", { 175, 238, 238 } )

RGB_Dictionary.Add( "antiquewhite2", { 238, 223, 204 } )

RGB_Dictionary.Add( "chartreuse1", { 127, 255, 0 } )

RGB_Dictionary.Add( "sandybrown", { 244, 164, 96 } )

RGB_Dictionary.Add( "orangered1", { 255, 69, 0 } )

RGB_Dictionary.Add( "light grey", { 211, 211, 211 } )

RGB_Dictionary.Add( "seagreen4", { 46, 139, 87 } )

RGB_Dictionary.Add( "seagreen3", { 67, 205, 128 } )

RGB_Dictionary.Add( "lightblue", { 173, 216, 230 } )

RGB_Dictionary.Add( "burlywood", { 222, 184, 135 } )

RGB_Dictionary.Add( "seashell", { 255, 245, 238 } )

RGB_Dictionary.Add( "dim gray", { 105, 105, 105 } )

RGB_Dictionary.Add( "yellow", { 255, 255, 0 } )

RGB_Dictionary.Add( "purple", { 160, 32, 240 } )

RGB_Dictionary.Add( "orange", { 255, 165, 0 } )

RGB_Dictionary.Add( "ivory4", { 139, 139, 131 } )

RGB_Dictionary.Add( "grey99", { 252, 252, 252 } )

RGB_Dictionary.Add( "green4", { 0, 139, 0 } )

RGB_Dictionary.Add( "green1", { 0, 255, 0 } )

RGB_Dictionary.Add( "coral2", { 238, 106, 80 } )

RGB_Dictionary.Add( "plum2", { 238, 174, 238 } )

RGB_Dictionary.Add( "pink4", { 139, 99, 108 } )

RGB_Dictionary.Add( "gold2", { 238, 201, 0 } )

RGB_Dictionary.Add( "medium aquamarine", { 102, 205, 170 } )

RGB_Dictionary.Add( "light slate grey", { 119, 136, 153 } )

RGB_Dictionary.Add( "lightgoldenrod3", { 205, 190, 112 } )

RGB_Dictionary.Add( "darkolivegreen3", { 162, 205, 90 } )

RGB_Dictionary.Add( "darkgoldenrod1", { 255, 185, 15 } )

RGB_Dictionary.Add( "dark goldenrod", { 184, 134, 11 } )

RGB_Dictionary.Add( "medium orchid", { 186, 85, 211 } )

RGB_Dictionary.Add( "lemon chiffon", { 255, 250, 205 } )

RGB_Dictionary.Add( "navajowhite4", { 139, 121, 94 } )

RGB_Dictionary.Add( "deepskyblue1", { 0, 191, 255 } )

RGB_Dictionary.Add( "lightyellow", { 255, 255, 224 } )

RGB_Dictionary.Add( "floralwhite", { 255, 250, 240 } )

RGB_Dictionary.Add( "dodger blue", { 30, 144, 255 } )

RGB_Dictionary.Add( "mediumblue", { 0, 0, 205 } )

RGB_Dictionary.Add( "chocolate4", { 139, 69, 19 } )

RGB_Dictionary.Add( "chocolate3", { 205, 102, 29 } )

RGB_Dictionary.Add( "burlywood4", { 139, 115, 85 } )

RGB_Dictionary.Add( "turquoise", { 64, 224, 208 } )

RGB_Dictionary.Add( "steelblue", { 70, 130, 180 } )

RGB_Dictionary.Add( "sea green", { 46, 139, 87 } )

RGB_Dictionary.Add( "lawngreen", { 124, 252, 0 } )

RGB_Dictionary.Add( "honeydew4", { 131, 139, 131 } )

RGB_Dictionary.Add( "seagreen", { 46, 139, 87 } )

RGB_Dictionary.Add( "orchid4", { 139, 71, 137 } )

RGB_Dictionary.Add( "wheat1", { 255, 231, 186 } )

RGB_Dictionary.Add( "violet", { 238, 130, 238 } )

RGB_Dictionary.Add( "ivory1", { 255, 255, 240 } )

RGB_Dictionary.Add( "grey88", { 224, 224, 224 } )

RGB_Dictionary.Add( "grey85", { 217, 217, 217 } )

RGB_Dictionary.Add( "grey57", { 145, 145, 145 } )

RGB_Dictionary.Add( "grey56", { 143, 143, 143 } )

RGB_Dictionary.Add( "grey55", { 140, 140, 140 } )

RGB_Dictionary.Add( "grey48", { 122, 122, 122 } )

RGB_Dictionary.Add( "grey47", { 120, 120, 120 } )

RGB_Dictionary.Add( "grey46", { 117, 117, 117 } )

RGB_Dictionary.Add( "grey30", { 77, 77, 77 } )

RGB_Dictionary.Add( "grey17", { 43, 43, 43 } )

RGB_Dictionary.Add( "gray47", { 120, 120, 120 } )

RGB_Dictionary.Add( "gray29", { 74, 74, 74 } )

RGB_Dictionary.Add( "pink2", { 238, 169, 184 } )

RGB_Dictionary.Add( "grey5", { 13, 13, 13 } )

RGB_Dictionary.Add( "grey4", { 10, 10, 10 } )

RGB_Dictionary.Add( "green", { 0, 255, 0 } )

RGB_Dictionary.Add( "gray0", { 0, 0, 0 } )

RGB_Dictionary.Add( "brown", { 165, 42, 42 } )

RGB_Dictionary.Add( "lightsteelblue4", { 110, 123, 139 } )

RGB_Dictionary.Add( "darkolivegreen4", { 110, 139, 61 } )

RGB_Dictionary.Add( "palevioletred4", { 139, 71, 93 } )

RGB_Dictionary.Add( "light sky blue", { 135, 206, 250 } )

RGB_Dictionary.Add( "darkslategray3", { 121, 205, 205 } )

RGB_Dictionary.Add( "darkslategray2", { 141, 238, 238 } )

RGB_Dictionary.Add( "darkslategray1", { 151, 255, 255 } )

RGB_Dictionary.Add( "palegoldenrod", { 238, 232, 170 } )

RGB_Dictionary.Add( "midnight blue", { 25, 25, 112 } )

RGB_Dictionary.Add( "yellow green", { 154, 205, 50 } )

RGB_Dictionary.Add( "darkseagreen", { 143, 188, 143 } )

RGB_Dictionary.Add( "antiquewhite", { 250, 235, 215 } )

RGB_Dictionary.Add( "chartreuse4", { 69, 139, 0 } )

RGB_Dictionary.Add( "steel blue", { 70, 130, 180 } )

RGB_Dictionary.Add( "olivedrab3", { 154, 205, 50 } )

RGB_Dictionary.Add( "lightpink2", { 238, 162, 173 } )

RGB_Dictionary.Add( "orangered", { 255, 69, 0 } )

RGB_Dictionary.Add( "thistle4", { 139, 123, 139 } )

RGB_Dictionary.Add( "sky blue", { 135, 206, 235 } )

RGB_Dictionary.Add( "orchid2", { 238, 122, 233 } )

RGB_Dictionary.Add( "grey36", { 92, 92, 92 } )

RGB_Dictionary.Add( "grey29", { 74, 74, 74 } )

RGB_Dictionary.Add( "grey28", { 71, 71, 71 } )

RGB_Dictionary.Add( "gray79", { 201, 201, 201 } )

RGB_Dictionary.Add( "gray78", { 199, 199, 199 } )

RGB_Dictionary.Add( "gray77", { 196, 196, 196 } )

RGB_Dictionary.Add( "coral4", { 139, 62, 47 } )

RGB_Dictionary.Add( "coral1", { 255, 114, 86 } )

RGB_Dictionary.Add( "plum1", { 255, 187, 255 } )

RGB_Dictionary.Add( "grey9", { 23, 23, 23 } )

RGB_Dictionary.Add( "blanchedalmond", { 255, 235, 205 } )

RGB_Dictionary.Add( "lightseagreen", { 32, 178, 170 } )

RGB_Dictionary.Add( "lemonchiffon3", { 205, 201, 165 } )

RGB_Dictionary.Add( "darkslategray", { 47, 79, 79 } )

RGB_Dictionary.Add( "darkorange2", { 238, 118, 0 } )

RGB_Dictionary.Add( "rosybrown1", { 255, 193, 193 } )

RGB_Dictionary.Add( "cornsilk", { 255, 248, 220 } )

RGB_Dictionary.Add( "salmon2", { 238, 130, 98 } )

RGB_Dictionary.Add( "ivory2", { 238, 238, 224 } )

RGB_Dictionary.Add( "grey93", { 237, 237, 237 } )

RGB_Dictionary.Add( "grey92", { 235, 235, 235 } )

RGB_Dictionary.Add( "grey91", { 232, 232, 232 } )

RGB_Dictionary.Add( "grey16", { 41, 41, 41 } )

RGB_Dictionary.Add( "gray48", { 122, 122, 122 } )

RGB_Dictionary.Add( "gray17", { 43, 43, 43 } )

RGB_Dictionary.Add( "pink1", { 255, 181, 197 } )

RGB_Dictionary.Add( "grey2", { 5, 5, 5 } )

RGB_Dictionary.Add( "gray7", { 18, 18, 18 } )

RGB_Dictionary.Add( "cyan4", { 0, 139, 139 } )

RGB_Dictionary.Add( "blue3", { 0, 0, 205 } )

RGB_Dictionary.Add( "plum", { 221, 160, 221 } )

RGB_Dictionary.Add( "cornflowerblue", { 100, 149, 237 } )

RGB_Dictionary.Add( "lightskyblue2", { 164, 211, 238 } )

RGB_Dictionary.Add( "antiquewhite1", { 255, 239, 219 } )

RGB_Dictionary.Add( "navajowhite2", { 238, 207, 161 } )

RGB_Dictionary.Add( "navajowhite1", { 255, 222, 173 } )

RGB_Dictionary.Add( "lightyellow3", { 205, 205, 180 } )

RGB_Dictionary.Add( "navajowhite", { 255, 222, 173 } )

RGB_Dictionary.Add( "darkorange3", { 205, 102, 0 } )

RGB_Dictionary.Add( "whitesmoke", { 245, 245, 245 } )

RGB_Dictionary.Add( "turquoise2", { 0, 229, 238 } )

RGB_Dictionary.Add( "steelblue1", { 99, 184, 255 } )

RGB_Dictionary.Add( "lightpink4", { 139, 95, 101 } )

RGB_Dictionary.Add( "lightblue3", { 154, 192, 205 } )

RGB_Dictionary.Add( "lawn green", { 124, 252, 0 } )

RGB_Dictionary.Add( "chocolate1", { 255, 127, 36 } )

RGB_Dictionary.Add( "alice blue", { 240, 248, 255 } )

RGB_Dictionary.Add( "olivedrab", { 107, 142, 35 } )

RGB_Dictionary.Add( "lightgrey", { 211, 211, 211 } )

RGB_Dictionary.Add( "chocolate", { 210, 105, 30 } )

RGB_Dictionary.Add( "magenta4", { 139, 0, 139 } )

RGB_Dictionary.Add( "magenta3", { 205, 0, 205 } )

RGB_Dictionary.Add( "yellow1", { 255, 255, 0 } )

RGB_Dictionary.Add( "purple3", { 125, 38, 205 } )

RGB_Dictionary.Add( "purple2", { 145, 44, 238 } )

RGB_Dictionary.Add( "orange2", { 238, 154, 0 } )

RGB_Dictionary.Add( "orange1", { 255, 165, 0 } )

RGB_Dictionary.Add( "magenta", { 255, 0, 255 } )

RGB_Dictionary.Add( "bisque1", { 255, 228, 196 } )

RGB_Dictionary.Add( "wheat2", { 238, 216, 174 } )

RGB_Dictionary.Add( "maroon", { 176, 48, 96 } )

RGB_Dictionary.Add( "khaki4", { 139, 134, 78 } )

RGB_Dictionary.Add( "grey96", { 245, 245, 245 } )

RGB_Dictionary.Add( "grey95", { 242, 242, 242 } )

RGB_Dictionary.Add( "grey80", { 204, 204, 204 } )

RGB_Dictionary.Add( "grey50", { 127, 127, 127 } )

RGB_Dictionary.Add( "grey41", { 105, 105, 105 } )

RGB_Dictionary.Add( "grey15", { 38, 38, 38 } )

RGB_Dictionary.Add( "grey11", { 28, 28, 28 } )

RGB_Dictionary.Add( "gray80", { 204, 204, 204 } )

RGB_Dictionary.Add( "gray58", { 148, 148, 148 } )

RGB_Dictionary.Add( "gray40", { 102, 102, 102 } )

RGB_Dictionary.Add( "gray34", { 87, 87, 87 } )

RGB_Dictionary.Add( "gray22", { 56, 56, 56 } )

RGB_Dictionary.Add( "brown1", { 255, 64, 64 } )

RGB_Dictionary.Add( "snow3", { 205, 201, 201 } )

RGB_Dictionary.Add( "mediumturquoise", { 72, 209, 204 } )

RGB_Dictionary.Add( "lightsteelblue3", { 162, 181, 205 } )

RGB_Dictionary.Add( "palevioletred2", { 238, 121, 159 } )

RGB_Dictionary.Add( "palevioletred1", { 255, 130, 171 } )

RGB_Dictionary.Add( "paleturquoise2", { 174, 238, 238 } )

RGB_Dictionary.Add( "dark sea green", { 143, 188, 143 } )

RGB_Dictionary.Add( "palevioletred", { 219, 112, 147 } )

RGB_Dictionary.Add( "mediumorchid1", { 224, 102, 255 } )

RGB_Dictionary.Add( "navajo white", { 255, 222, 173 } )

RGB_Dictionary.Add( "mediumpurple", { 147, 112, 219 } )

RGB_Dictionary.Add( "lightyellow1", { 255, 255, 224 } )

RGB_Dictionary.Add( "dodgerblue2", { 28, 134, 238 } )

RGB_Dictionary.Add( "dodgerblue1", { 30, 144, 255 } )

RGB_Dictionary.Add( "blue violet", { 138, 43, 226 } )

RGB_Dictionary.Add( "aquamarine3", { 102, 205, 170 } )

RGB_Dictionary.Add( "slategray1", { 198, 226, 255 } )

RGB_Dictionary.Add( "slate gray", { 112, 128, 144 } )

RGB_Dictionary.Add( "orangered4", { 139, 37, 0 } )

RGB_Dictionary.Add( "lightpink3", { 205, 140, 149 } )

RGB_Dictionary.Add( "light blue", { 173, 216, 230 } )

RGB_Dictionary.Add( "darkorchid", { 153, 50, 204 } )

RGB_Dictionary.Add( "cadetblue1", { 152, 245, 255 } )

RGB_Dictionary.Add( "burlywood3", { 205, 170, 125 } )

RGB_Dictionary.Add( "seashell1", { 255, 245, 238 } )

RGB_Dictionary.Add( "cornsilk3", { 205, 200, 177 } )

RGB_Dictionary.Add( "tomato4", { 139, 54, 38 } )

RGB_Dictionary.Add( "tomato2", { 238, 92, 66 } )

RGB_Dictionary.Add( "wheat3", { 205, 186, 150 } )

RGB_Dictionary.Add( "grey98", { 250, 250, 250 } )

RGB_Dictionary.Add( "grey59", { 150, 150, 150 } )

RGB_Dictionary.Add( "grey23", { 59, 59, 59 } )

RGB_Dictionary.Add( "green3", { 0, 205, 0 } )

RGB_Dictionary.Add( "green2", { 0, 238, 0 } )

RGB_Dictionary.Add( "gray72", { 184, 184, 184 } )

RGB_Dictionary.Add( "gray62", { 158, 158, 158 } )

RGB_Dictionary.Add( "gray52", { 133, 133, 133 } )

RGB_Dictionary.Add( "gray46", { 117, 117, 117 } )

RGB_Dictionary.Add( "gray42", { 107, 107, 107 } )

RGB_Dictionary.Add( "gray28", { 71, 71, 71 } )

RGB_Dictionary.Add( "gray24", { 61, 61, 61 } )

RGB_Dictionary.Add( "white", { 255, 255, 255 } )

RGB_Dictionary.Add( "cyan3", { 0, 205, 205 } )

RGB_Dictionary.Add( "black", { 0, 0, 0 } )

return( RGB_Dictionary )


Layout.RoundScaleBarInterval
Rounds the interval of selected scale bars

Source Code

Description:   Rounds the scale bar interval to the nearest interval as specified in an interval range. The interval range is essentially a list of numbers the interval can be set to. The range can be modified as necessary.

The interval range is controlled through a variable called "int_range". Through this variable, you define the range of possible intervals the current interval can be rounded to.  In this sample script, int_range = {{3,1},{2,2},{1,4}}. This sets the interval range as 1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5...9. For each list, {a,b}, "a" is the leftmost non-zero digit of the interval, and "b" is the number

of fractions to break the interval into.

The script finds the leftmost non-zero digit of the interval and places a decimal point after it. Then it rounds the interval to the nearest value as specified in the interval range. For example, given an interval of 1589, this number is converted to 1.589.  1.589 is greater than 1 (of {1,b}) but less than 2 (of {2,b}). This means the 4th fraction ({a,4}) of 1, or 0.25 sets the interval range to 1, 1.25, 1.5, 1.75. 1.589 will be rounded to 1.5, or specifically, 1589 will be rounded to 1500.

Here are some other int_range values to help you understand the relationship.

  int_range = {{3,1},{1,4}} yields   1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 4, 5...9

  int_range = {{3,2},{1,4}} yields  1, 1.25, 1.5, 1,75, 2, 2.25, 2.5, 2.75, 3, 3.5, 4, 4.5...8.5, 9

  int_range {{1,2}} yields  1, 1.5, 2, 2.5, 3, 3.5, 4...8, 8.5, 9

Name:    Layout.RoundScaleBarInterval

Requires:  A layout must be the active document, with one or more scale bars selected.

Self:

Returns:

FileName:  rndscale.ave


Layout.RoundScaleBarInterval (Sample Script)
'Rounds the interval of selected scale bars

'Sets interval range. "a" in {a,b} must be in descending order

int_range = {{3,1},{2,2},{1,4}}

alayout = av.GetActiveDoc

'Get list of selected graphic elements (should be scale bars)

theScaleBars = aLayout.GetGraphics.GetSelected

for each ScaleBar in theScaleBars

  if (ScaleBar.Is(ScaleBarFrame)) then

    'the selected object is a scale bar.

    x = ScaleBar.GetInterval

    'Puts a decimal point after the leftmost non-zero digit

    if (x < 1) then

      theLog = x.Log(10).Floor

    else

      theLog = x.Log(10).Truncate

    end  'if

    x2 = x / (10^(theLog))

    'Rounds the scale bar interval value to scaled value defined by 'int_range'

    for each c in int_range

      if (x2.Abs > c.Get(0)) then

        y = (c.Get(1) * x2).round * 10.^(theLog) / c.Get(1)

        break

      end  'if

    end  'for

    'Sets the interval value back to scale bar

    ScaleBar.SetInterval(y)

    ScaleBar.Invalidate

  end  'if

end  'for


Project.SaveAllScripts
Saves all scripts to current working directory

Source Code

Description:   Writes all scripts in the current project to the working directory.  The default filename will be the name of the SEd in the project.  Blanks in the name are substituted.  The user may optionally choose to enforce unique 8.3 compliant filenames.  Otherwise, a warning is displayed if the file already exists.

Name:    Project.SaveAllScripts

Requires:

Self:

Returns:

FileName:  savscrpt.ave


Project.SaveAllScripts (Sample Script)
'Saves all scripts to current working directory

' If the scripts are to be saved elsewhere, change the following lines...

'

saveDir = av.GetProject.GetWorkDir

saveDirStr = av.GetProject.GetWorkDir.GetFullName

if (File.Exists(saveDir).Not) then

  MsgBox.Error("Working directory:"++saveDirStr++"does not exist", "")

  exit

end

theScriptList = List.Make

for each d in av.GetProject.GetDocs

  if (d.Is(SEd)) then

    theScriptList.Add(d)

  end

end

ok = MsgBox.YesNo("Are you sure you want to write all scripts to:"+NL+

  saveDirStr+"?", "Save Scripts", true)

if (ok.Not) then

  exit

end

' Loop through write each script to a system file...

'

enforce = MsgBox.YesNoCancel("Create 8.3 unique file names?",

  "Save Scripts", true)

if (enforce = Nil) then

  exit

end

for each scriptName in theScriptList

  '

  ' Substitute blanks and make lower case.

  ' Optionally use MakeTmp to enforce 8.3 compliance and uniqueness.

  '

  theFile = scriptName.AsString.LCase.Substitute(" ","_")

  if (enforce) then

    theFile = scriptName.AsString.LCase.Substitute("","_")

    outFile = FN.Make(saveDirStr).MakeTmp(theFile, "ave")

  else

    theFile = scriptName.AsString.LCase.Substitute(" ","_")

    outFile = FileName.Merge(saveDirStr, theFile)

    outFile.SetExtension("ave")

    if (outFile.IsFile) then

      ok = MsgBox.YesNoCancel("Overwrite"++outFile.GetFullName+"?",

        "Save Scripts", true)

      if (ok = Nil) then

        exit

      elseif (Not ok) then

        continue

      end

    end

  end

  lf = LineFile.Make(outFile, #FILE_PERM_WRITE)

  if (lf <> nil) then

    lf.WriteElt(scriptName.GetScript.AsString)

    lf.Close

  else

    MsgBox.Warning("Unable to write:"++outFile.GetFullName,"")

  end

end

av.ShowMsg("Scripts written to:"++saveDirStr)


Script.FindReplace
Finds & replaces aString in a SEd document

Source Code

Description:   Prompts the user for a string to search for and its replacement string.  The search will begin at the current cursor insert point.  If the script is executed from a control the object tag of the control is used to store the previous find/replace parameters.

Name:    Script.FindReplace

Requires:  av.GetActiveDoc must be a SEd.

Self:

Returns:

FileName:  sedfndrp.ave


Script.FindReplace (Sample Script)
'Finds & replaces aString in a SEd document

theSEd = av.GetActiveDoc

save = nil

SEdSearchString     = theSEd.GetSearchString

SEdReplaceString    = ""

SEdReplacePrompt    = "No"

'Get last values if possible

if (SELF.Is(Ctrl)) then

  save = SELF.GetObjectTag

  if (save <> nil) then

    SEdSearchString   = save.Get(0)

    SEdReplaceString  = save.Get(1)

    SEdReplacePrompt  = save.Get(2)

  end

end

'Get search string, replace string and prompt option

Strings = MsgBox.MultiInput( "", "Find/Replace",

  { "Search for:", "Replace with:", "Prompt (Y/N):" },

  { SEdSearchString, SEdReplaceString, SEdReplacePrompt } )

if ( Strings.Count < 1 ) then

  exit

end

SEdSearchString   = Strings.Get( 0 )

SEdReplaceString  = Strings.Get( 1 )

SEdReplacePrompt  = Strings.Get( 2 )

if (SEdReplacePrompt.Contains("y")) then

  SEdReplacePrompt = "Yes"

end

'Save current insert position

savePosition = theSEd.ReturnInsertPos

if (savePosition <> 0) then

  atBeg = FALSE

end

theSEd.SetInsertPos(0)

'Find each search string

changeIt = TRUE

stringFound = FALSE

found = theSEd.Search(SEdSearchString)

if (atBeg.Not) then

  theSEd.SetInsertPos(0)

  found = theSEd.Search(SEdSearchString)

end

while (found)

  stringFound = TRUE

  theSEd.GetWin.Invalidate

  if (SEdReplacePrompt = "Yes") then

    changeIt = MsgBox.YesNoCancel( "Replace: "++SEdSearchString+NL+

      "with: "++SEdReplaceString, "Find/Replace", TRUE)

    if (changeIt = nil) then

      break

    end

  end

  'Replace it

  if (changeIt) then

    theSEd.CutSelected

    theSEd.Insert( SEdReplaceString )

  end

  found = theSEd.Search( SEdSearchString )

end

'Save to the object tag

if (SELF.Is( Ctrl )) then

  SELF.SetObjectTag({SEdSearchString, SEdReplaceString, SEdReplacePrompt})

end

'Restore cursor position in text if string not found

if (stringFound.Not) then

  theSEd.SetInsertPos(savePosition)

end


View.SelectByCircle
Selects features in active theme using a circle

Source Code

Description:   Allows the user to specify the size circle to select features in the current active theme and creates an on screen report of information from the selected field.

Provides an example of creating shapes and drawing them temporarily on the view Display using display clipping.  The shape is symbolized using a programmer specified symbol.  The shape will appear on the Display until the Display is refreshed.  A report is generated and displayed using MsgBox.Report.

Name:    View.SelectByCircle

Requires:  The active document must be a view containing an active theme. This script must be executed from a tool apply event.

Self:

Returns:

FileName:  selbycir.ave


View.SelectByCircle (Sample Script)
'Selects features in active theme using a circle

theView = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

if (theTheme = nil) then

  MsgBox.Warning("No active themes in view.","")

  exit

end

theFtab = theTheme.GetFTab

' Create a list of possible radius specifications for the selection

' circle.  Modify for appropriate units, scales, etc. for other views.

' Let the user choose one...

'

radiusList = { 10, 100, 150, 300, 500, 1000 }

r = MsgBox.ChoiceAsString( radiusList, "Choose selection radius:",

  "Select By Circle" )

if (r = nil) then

  exit

end

' Create the circle from the specified radius, create a symbol to be used

' to display the circle and draw it...

'

pt = theView.GetDisplay.ReturnUserPoint   ' Center point of circle...

c = Circle.Make(pt, r)

s = RasterFill.Make                       ' Create symbol...

s.SetColor(Color.GetRed)

s.SetOLColor(Color.GetBlue)

theDisplay = theView.GetDisplay

theDisplay.BeginClip                ' Start clipping for drawing...

theDisplay.DrawCircle(c, s)         ' Draw the circle with the symbol...

theDisplay.EndClip                  ' End clipping...

' Select features using the shape...

'

theTheme.SelectByShapes({c}, #VTAB_SELTYPE_NEW)

' Allow user to specify fields in report...

'

fList = theTheme.GetFTab.GetFields

theField = MsgBox.ChoiceAsString( fList, "Select field for report.",

  theView.GetName++"Report" )

if (theField = nil) then

  exit

end

' Create on-screen report from user-specified field...

'

themeReport = theTheme.GetName++"Report"+NL

for each rec in theFTab.GetSelection

  theInfo = theFTab.ReturnValue(theField, rec).AsString

    themeReport = themeReport+NL+theInfo

  end

MsgBox.Report( themeReport, "Report for"++theTheme.GetName )

' Clear the selection bitmap and flush the display...

'

theFTab.GetSelection.ClearAll

theDisplay.Flush


View.ShapeToGenerate
Exports active theme to ARC/INFO export format

Source Code

Description:   Exports the active themes to ARC/INFO Export (Generate) format files.  Each active theme will require the user to specify an output file name.  The format of the export file with be either POINT, LINE, or POLYGON depending upon the type of Shape Field found in the Theme FTab (the Enum Type FieldEnum).

The user will be prompted for the field from which to create IDs in the generate file.  If <None> is selected the ID for the feature will be set to the current FTab record number.

In the case of overlapping polygons, the data should be further converted into an ARC/INFO region coverage with the REGIONCLASS command.  ArcView polygon shapes may need to be modeled in ARC/INFO as regions to handle the case of polygons with multiple parts.

Following conversion of the generate file to an ARC/INFO coverage the Theme's FTab can be exported to an INFO file that can be joined to the coverage Feature Attribute Table (FAT) to restore all attributes as found in the original Theme.  Consult ARC/INFO command documentation for JOINITEM and related commands.

When creating polygon format Generate files the AUTO keyword is used along with the feature ID to indicate that labels will be automatically created when coverages are imported using ARC/INFO Generate.  Consult the ARC/INFO Generate documentation for additional options and discussion.

Name:    View.ShapeToGenerate

Requires:  A View must be the active document.

Self:

Returns:

FileName:  shp2gen.ave


View.ShapeToGenerate (Sample Script)
'Exports active theme to ARC/INFO export format

' View should be the Active Document

'

theView = av.GetActiveDoc

' Establish output precision...

'

Script.The.SetNumberFormat( "d.dddddd" )

for each t in theView.GetActiveThemes

  defaultName    = FN.Make("$HOME").MakeTmp(t.GetName.LCase,"gen")

  ungenFileName  = FileDialog.Put( defaultName,"*.gen","Export"++t.GetName )

  if (ungenFileName = nil) then

    exit

  else

    exportFile = LineFile.Make(ungenFileName, #FILE_PERM_WRITE)

  end

  ' The ARC/INFO generate format uses the ID number of the feature

  ' in the export file to provide a means for joining attributes.

  ' When the generate file is converted to an ARC/INFO coverage the ID

  ' as found in the generate file will be used as the ID in the coverage

  ' feature attribute table (the .AAT or .PAT).  Allow the user to specify

  ' the ID field to use or default to the record number....

  '

  fieldList = t.GetFTab.GetFields.Clone

  fieldList.Insert( "<None>" )

  idField = MsgBox.ChoiceAsString( fieldList,

    "Select ID field for export file:","Choose ID Field" )

  if ( idField = nil ) then

    exit

  elseif ( idField = "<None>" ) then

    useID = false

  else

    useID = true

  end

  theFTab     = t.GetFTab

  shapeField  = theFTab.FindField( "Shape" )

  shapeType   = shapeField.GetType

  numRecs     = theFTab.GetNumRecords

  av.ShowStopButton

  av.ShowMsg( "Exporting"++t.GetName+"..." )

  for each recNum in theFTab

    currentShape = theFTab.ReturnValue( shapeField, recNum )

    if ( useID ) then

      id =theFTab.ReturnValueString( idField, recNum )

    else

      id = (recNum + 1).SetFormat("d").AsString

    end

    if (shapeType = #FIELD_SHAPEPOINT) then

      ' ARC/INFO POINT format export file...

      '

      Xvalue = currentShape.GetX.AsString

      Yvalue = currentShape.GetY.AsString

      outputLine = id+", "+Xvalue+", "+Yvalue

      exportFile.WriteElt( outputLine )

    elseif (shapeType = #FIELD_SHAPEMULTIPOINT) then

      ' ARC/INFO POINT format export file...

      '

      pointList = currentShape.AsList

      for each pt in pointList

        Xvalue = pt.GetX.AsString

        Yvalue = pt.GetY.AsString

        outputLine = id+", "+Xvalue+", "+Yvalue

        exportFile.WriteElt( outputLine )

      end

    elseif (shapeType = #FIELD_SHAPELINE) then

      ' ARC/INFO LINE format export file...

      '

      exportFile.WriteElt( id )

      shapeList = currentShape.AsList

      for each shapePart in shapeList

        for each xyPoint in shapePart

          outputLine = xyPoint.GetX.AsString+", "

            +xyPoint.GetY.AsString

          exportFile.WriteElt( outputLine )

        end

        exportFile.WriteElt( "END" )

      end

    elseif (shapeType = #FIELD_SHAPEPOLY) then

      ' ARC/INFO POLYGON format export file...

      '

      exportFile.WriteElt( id++"AUTO" )  'automatic label generation flag...

      shapeList = currentShape.AsList

      for each shapePart in shapeList

        for each xyPoint in shapePart

          outputLine = xyPoint.GetX.AsString+", "

            +xyPoint.GetY.AsString

          exportFile.WriteElt( outputLine )

        end

        exportFile.WriteElt( "END" )

      end

    end

    progress = (recNum / numRecs) * 100

    proceed = av.SetStatus( progress )

    if ( proceed.Not ) then

      av.ClearStatus

      av.ShowMsg( "Stopped" )

      exit

    end

  end

  exportFile.WriteElt( "END" )

  exportFile.Close

  av.ClearStatus

  av.ClearMsg

end


View.SpiderDiagram
Create spider diagrams

Source Code

Description:   Creates spider diagrams based on liner distances between the points contained in two point themes.  The Output is a new (spider) theme with distances stored in the FTAB.

Name:    View.SpiderDiagram

Requires:

Self:

Returns:

FileName:  spider.ave


View.SpiderDiagram (Sample Script)
'Create spider diagrams

v = av.GetActiveDoc

themeList = v.GetThemes

c = Msgbox.Choice (themeList, "Select a Theme to use for Centers.", "Select a Theme")

p = Msgbox.Choice (themeList, "Select a Theme to use for points.", "Select a Theme")

Tp = v.FindTheme(p.AsString)

Tc = v.FindTheme(c.AsString)

Proj = v.GetProjection

TpFTab = Tp.GetFTab

TcFTab = Tc.GetFTab

ShpFldP = Tp.GetFTab.FindField("Shape")

ShpFldC = Tc.GetFTab.FindField("Shape")

counter = 0

total = Tp.GetFTab.GetNumRecords

PointList = {}

DistanceList = {}

for each r in TpFTab

  MinDistance = 999999999

  counter = counter+1

  shpP = Tp.GetFTab.ReturnValue(ShpFldP, r)

  Proj.Projectpt(shpP)

  for each s in TcFTab

    shpC = Tc.GetFTab.ReturnValue(ShpFldC, s)

    Proj.Projectpt(shpC)

    dist = shpC.Distance(shpP)

    if (dist < MinDistance) then

      MinDistance = dist

      MinRecord = s.clone

    end

  end

    shpC = Tc.GetFTab.ReturnValue(ShpFldC, MinRecord)

    Proj.Projectpt(shpC)

    PointList.Add(shpC)

    PointList.Add(shpP)

    DistanceList.Add(MinDistance)

  av.SetStatus((counter/total) * 100)

end

'make a new theme

class = PolyLine

def = av.GetProject.MakeFileName("theme", "shp")

def = FileDialog.Put(def, "*.shp", "New Theme")

if (def <> nil) then

  tbl = FTab.MakeNew(def, class)

  fld = Field.Make("ID", #FIELD_DECIMAL, 8, 0)

  fld2 = Field.Make("Distance", #FIELD_DOUBLE, 8, 0)

  fld.SetVisible( FALSE )

  tbl.AddFields({fld})

  SpiderTheme = FTheme.Make(tbl)

  v.AddTheme(SpiderTheme)

  SpiderTheme.SetActive(TRUE)

  SpiderTheme.SetVisible(FALSE)

  v.SetEditableTheme(SpiderTheme)

  av.GetProject.SetModified(true)

end

themeList = v.GetThemes

themeList.Shuffle( themeList.Get(0), (themeList.Count - 1))

v.InvalidateTOC ( nil )

'Draw the spider diagrams

counter = 0

ln = PointList.Count

for each num in 1..ln by 2

  counter = counter+2

  av.SetStatus((counter/ln) * 100)

  shpC = PointList.get(num-1)

  shpP = PointList.get(num)

  spiderline = PolyLine.make( {{shpC, shpP}} )

  theTheme = v.GetEditableTheme

if (spiderline <> nil) then

  if (SpiderTheme <> nil) then

    if (Proj.IsNull.Not) then

      spiderline = spiderline.ReturnUnprojected(Proj)

    end

    theField = SpiderTheme.GetFTab.FindField("Shape")

    rec = SpiderTheme.GetFTab.AddRecord

    SpiderTheme.GetFTab.SetValue(theField, rec, spiderline)

    SpiderTheme.GetFTab.GetSelection.ClearAll

    SpiderTheme.GetFTab.GetSelection.Set(rec)

    SpiderTheme.GetFTab.UpdateSelection

  else

    gl = GraphicShape.Make(spiderline)

    v.GetGraphics.UnselectAll

    gl.SetSelected(TRUE)

    v.GetGraphics.Add(gl)

  end

  av.GetProject.SetModified(true)

end

end '(FOR)

'Add the distance field and distances to the FTab

'SpiderTheme = v.FindTheme(SpiderTheme.AsString)

theFTab = SpiderTheme.GetFTab

f1 = Field.Make ("Distance",#FIELD_FLOAT,12,2)

theFTab.SetEditable(true)

theFTab.AddFields ({f1})

DistanceFld = theFTab.FindField("Distance")

for each r in theFTab

  Dist = DistanceList.get(r)

  theFTab.SetValue (DistanceFld,r,Dist)

end

theFTab.SetEditable(false)

SpiderTheme.SetVisible(true)


Data.CreateSpatialIndex
Spatial Index Creator

Source Code

Description:   This script processes a specified directory tree creating spatial index files for every coverage and shapefile found in the tree.

Name:    Data.CreateSpatialIndex

Requires:

Self:

Returns:

FileName:  spidx.ave


Data.CreateSpatialIndex (Sample Script)
'Spatial Index Creator

'Starting location

pathin1=msgbox.input("Enter starting directory","Index all Features","c:\temp")

if (pathin1 = NIL) then

  exit

end

pathin=pathin1.asfilename

choice1=msgbox.miniyesno("Build a view with all features?",FALSE)

l={pathin}

if (choice1=TRUE) then

  thev=view.make

  thev.setname("All Features")

end

i=0

'Builds a list of all directories

av.ShowMsg("Traversing directories...")

while (i<l.Count)

  av.SetStatus((i/l.Count)*100)

  l.Merge(l.Get(i).Read(""))

  i=i+1

end

av.ClearStatus

av.clearmsg

av.usewaitcursor

av.showstopbutton

c1=0

'In each direcory get the list of SHP files / coverages and index them

for each p in l

av.showmsg("Processing files")

c1=c1+1

proceed=av.setstatus((c1/l.count)*100)

  if ( proceed.Not ) then

    av.ClearStatus

    av.ShowMsg( "Stopped" )

    exit

  end

  for each s in p.read("*.shp")

      if (s.isDir=true) then

       continue

      end

    'msgbox.info(s.asstring,"")

    p2=srcname.make(s.asstring)

    fthm=theme.make(p2)

    ftabin=FTab.Make(p2)

    theshapef=ftabin.findfield("shape")

      if (ftabin.IsFieldIndexed(theshapef)=FALSE) then

          ftabin.createindex(theshapef)

      end

      if (choice1=TRUE) then

        thev.addtheme(fthm)

      end

    av.showstopbutton

    av.showmsg("Processing files in ..."+p.asstring)

  for each time1 in 1..1200

  end

    proceed=av.setstatus((c1/l.count)*100)

      if ( proceed.Not ) then

        av.ClearStatus

        av.ShowMsg( "Stopped" )

        exit

      end

  end

  for each s in Coverage.ReturnSrcNames(p.GetName)

    p2=s

    fthm=theme.make(p2)

    ftabin=FTab.Make(p2)

    theshapef=ftabin.findfield("shape")

      if (ftabin.IsFieldIndexed(theshapef)=FALSE) then

          ftabin.createindex(theshapef)

      end

      if (choice1=TRUE) then

        thev.addtheme(fthm)

      end

    av.showstopbutton

    av.showmsg("Processing files in ..."+p.asstring)

  for each time1 in 1..1200

  end

    proceed=av.setstatus((c1/l.count)*100)

      if ( proceed.Not ) then

        av.ClearStatus

        av.ShowMsg( "Stopped" )

        exit

      end

  end

end

av.clearstatus

av.clearmsg


Project.SubstitutePath
Changes pathnames in project files

Source Code

Description:   By running this script you can change the paths to data locations within an ArcView project file.  The reason you would do this is to be able to move your data and/or your project to other disks or directories and avoid having to go through the project repair process. The premise behind this script is the use of an environment variable which is dynamic in the sense that it will always point to the location of the root of your data directory.

Interaction with the user goes like this:

   1.  Ask for the environment variable in question and confirm its value.

   2.  Ask what directory we are looking for in the projectfile path strings.

   3.  Ask what project file is to be edited.

   4.  Ask for an output file name for the edited project file.

Lines are also provided to hard-code these parameters.

The script will look for path strings, parse the given directory from the string, and substitute the address preceeding it with the value of the environment variable.

For example, if the environment variable value is '/pv1/newstuff' and the directory we are locating is 'work' then a pathname in the project file such as this:

Path:	"/sta3/april/work/bowne/data703/info/soil2polycl.patpoly"

will become this

Path:	"/pv1/newstuff/work/bowne/data703/info/soil2polycl.patpoly"

Name:    Project.SubstitutePath

Requires:

Self:

Returns:

FileName:  subpath.ave


Project.SubstitutePath (Sample Script)
'Changes pathnames in project files

' Get the environment variable and make sure that it is set.

'    Use this line to hard-code the name of the environment varialbe

     locale = System.GetEnvVar("AV2HOME")

'    Use this line to prompt the user for the name of the environment variable

     theEnvString = MsgBox.Input("Please enter name of environment variable.","Do not include the $ or %s.","MYDATA")

     if (theEnvString <>nil) then

       theUCaseString = theEnvString.Ucase

       locale = system.GetEnvVar(theUCaseString)

     else

       exit

     end

  if (Locale = nil) then

    MsgBox.Info( theUCaseString++"is not set." , "The location of the data cannot be established.")

    exit

  end

  confirmed = MsgBox.YesNo(theUCaseString++"is..."++Locale,"Is this correct?",true)

  if (confirmed.not) then

    exit

  end

' Open a file to read

'  If you want to hard-code it.

'RFileName = FN.Make("/beavis1/april/projects/test.apr")

'RFile = LineFile.Make ( RFileName, #FILE_PERM_READ )

'  If you want the user to select it.

RFileName = FileWin.Show("*.apr","*.apr","Project to Edit")

RFile = LineFile.Make ( RFileName, #FILE_PERM_READ )

if ( RFile = nil) then

  MsgBox.Info("No project selected to edit.","EXITING PROGRAM")

  exit

  end

' Open a file to write

'  If you want to hardcode it.

'WFileName = FN.Make("/beavis1/april/projects/output.apr")

'WFile = LineFile.Make ( WFileName, #FILE_PERM_WRITE )

'  If you want the user to select the location

WFileName = FileWin.Put("Output.apr".AsFileName,"*.apr","Project to Create")

WFile = LineFile.Make ( WFileName, #FILE_PERM_WRITE )

if ( WFile = nil) then

  MsgBox.Info("No project selected to create.","EXITING PROGRAM")

  exit

  end

'  Use this line if you would like to prompt the user for the directory.

  theDirectory = MsgBox.Input("What directory are we locating?","","work")

' Find a line that identifies the data location and

' extract the location of the AV2DATA directory.

while ( RFile.IsAtEnd.Not)

  buf = RFile.ReadElt

  if ( buf.Contains("Path:") ) then

    path = buf.extract(1)

    ' Use this line to hard-code the directory we are locating.

    'i = path.IndexOf ( "work" )

    ' Use this line if you have prompted the user.

    i = path.IndexOf (theDirectory)

    DPath = path.middle ( 1, i - 2 )

    MsgBox.Info(dPath,"")

    Rfile.GoToBeg

    break

    end

end

  if (DPath = nil) then

  MsgBox.Info ("There are no themes in this project"+nl+"from the AV2DATA directory.","NO THEMES!")

    exit

    end

' Step through the file and substitute the existing location of the data directory

' with the value of the MYDATA environment variable.

while ( RFile.IsAtEnd.Not )

  buf = RFile.ReadElt

  if (buf = nil) then

    break

    end

  buf = buf.substitute (DPath,Locale)

  WFile.WriteELT(buf)

end

Rfile.Close

WFile.Close


Layout.SymbolDump
Dumps symbols from palette to layout

Source Code

Description:   This script allows you to dump the contents of a symbol palette into a layout.  Specifically graphics of the appropriate sort are generated and symbolized with a symbol from the palette, there will be one graphic per symbol.  This script handles text symbol a bit differently, if the text does not fit in one layout, multiple layouts will be created to accomodate additional symbols

Name:    Layout.SymbolDump

Requires:

Self:

Returns:

FileName:  symdump.ave


Layout.SymbolDump (Sample Script)
'Dumps symbols from palette to layout

thePalette = av.GetSymbolWin.GetPalette

symTypes = {"Color", "Fill","Marker", "Pen", "Text"}

symType = Msgbox.ChoiceAsString(symTypes, "Choose a symbol type:", "ArcView Symbol Dump")

if (symType = nil) then

  return nil

elseif (symType = "Color") then

  thePaletteList = thePalette.GetList(#PALETTE_LIST_COLOR)

  numPages = (thePaletteList.Count / 60).Ceiling

elseif (symType = "Fill") then

  thePaletteList = thePalette.GetList(#PALETTE_LIST_FILL)

  numPages = (thePaletteList.Count / 60).Ceiling

elseif (symType = "Marker") then

  thePaletteList = thePalette.GetList(#PALETTE_LIST_MARKER)

  numPages = (thePaletteList.Count / 60).Ceiling

elseif (symType = "Pen") then

  thePaletteList = thePalette.GetList(#PALETTE_LIST_PEN)

  numPages = (thePaletteList.Count / 60).Ceiling

elseif (symType = "Text") then

  fontMgr = FontManager.The

  fontList = fontMgr.ReturnFamilies

  totalLines = 0

  for each f in fontList

    totalLines = totalLines + fontMgr.ReturnStyles(f).Count

  end

  numPages = (totalLines / 32).Ceiling

end

pageCount = 0

symNum = 0

MakeNewPage = true

xp = 0

While (pageCount < numPages)

  if (MakeNewPage) then

    theLayout = Layout.Make

    pageCount = pageCount + 1

  end

  MakeNewPage = false

  theLayout.GetWin.open

  theLayout.SetName(symType.UCase+((pageCount).AsString))

  dis = theLayout.GetDisplay

  dis.SetPageSize(8.5@11)

  dis.SetMarginVisible(FALSE)

  gl = theLayout.GetGraphics

  'Make a bounding box

  boundX = (750 - (8.50 / 2))

  boundY = (750 + (11.00 / 2))

  bboundX = (750 + (8.50 / 2))

  bboundY = (750 - (11.00 / 2))

  boundBox = Rect.MakeXY(boundX, boundY, bboundX, BBoundY)

  gBoundBox = GraphicShape.Make(boundBox)

  gl.AddBatch(gboundBox)

  'Make framing box

  topX = (750 - (8.50 / 2)) + 0.50

  topY = (750 + (11.00 / 2)) - 0.50

  botX = (750 + (8.50 / 2)) - 0.50

  botY = (750 - (11.00 / 2)) + 0.50

  box = Rect.MakeXY(topX, topY, botX, botY)

  gbox = GraphicShape.Make(box)

  gl.AddBatch(gbox)

  if (symType = "Text") then

    dy = 0.25 'Y distance change

  else

    dx = 1.25 'X distance change

    dy = 0.99 'Y distance change

  end

  originX = 750 - (8.50 / 2)

  originY = 750 + (11.00 / 2)

  if (symType = "TEXT") then

    lineCount = 0

    x = originX + 0.75

    y = originY - 1.50

    'Set and add title.

    tX = x + 3.0

    tY = originY - 0.75

    tPt = (tX@tY)

    gtPt = GraphicText.Make("FONTS", tPt)

    gl.AddBatch(gtPt)

    ft = (x@y)

    pt = ft + (5@0) - (0@2)

    t = GraphicText.Make("abcdef ABCDEF  1234567890 !@#$%^&*[]{}<>;:,.?", pt)

    for each f in xp..((fontlist.count) - 1)

      ft = (x@y)

      fam = GraphicText.Make(fontlist.Get(f), ft )

      theLayout.GetGraphics.AddBatch(fam)

      for each style in fontMgr.ReturnStyles(fontlist.Get(f))

        ft = (x@y)

        nextText =  t.clone

        nextText.SetOrigin(ft + (2@0))

        nextText.GetSymbol.SetFont(Font.Make(fontlist.Get(f),style))

        gl.AddBatch(nextText)

        lineCount = LineCount + 1

        y = y - dy

      end

      y = y - 0.10

      xp = xp + 1

      if (LineCount >= 28) then

        MakeNewPage = true

        break

      end

    end

  else

    x = originX + 0.75

    y = originY - 1.3

    tX = x + 3.0

    tY = originY - 0.75

    tPt = (tX@tY)

    gtPt = GraphicText.Make(symType+"s", tPt)

    gl.AddBatch(gtPt)

    'Create rectangle

    xMin = x

    yMin = y

    xMax = x + 0.75

    yMax = y + 0.5

    r = Rect.MakeXY(xMin, yMin, xMax, yMax)

    gr = GraphicShape.Make(r)

    if (symType = "COLOR") then

      for each ROW in 1..10

        for each COLUMN in 0..5

          nextRec = gr.Clone

          nextRec.SetSymbol(av.GetSymbolWin.GetPalette.GetList(#PALETTE_LIST_FILL).Get(1).Clone)

          nextRec.GetSymbol.SetColor(thePaletteList.GET(symNum).Clone)

          offsetPt = (x@y)

          nextRec.setOrigin(offsetPt)

          pt = offsetPt + (0.25@0) - (0@0.25)

          t = GraphicText.Make(symNum.AsString, pt)

          gl.UnselectAll

          theLayout.GetGraphics.AddBatch(nextRec)

          theLayout.GetGraphics.AddBatch(t)

          x = x + dx

          symNum = symNum + 1

          if (symNum = thePaletteList.Count) then exit end

        end   'for each COLUMN

        x = originX + 0.75

        y = y - dy

      end   'for each ROW

      if (symNum < ((thePaletteList.Count) - 1)  ) then

        MakeNewPage = true

      end

    elseif (symType = "FILL") then

      for each ROW in 1..10

        for each COLUMN in 0..5

          nextRec = gr.clone

          nextRec.setSymbol(thePaletteList.Get(SymNum))

          offsetPt = (x@y)

          nextRec.setOrigin(offsetPt)

          pt = offsetPt + (0.25@0) - (0@0.25)

          t = GraphicText.Make(symNum.AsString, pt)

          gl.UnselectAll

          theLayout.GetGraphics.AddBatch(nextRec)

          theLayout.GetGraphics.AddBatch(t)

          x = x + dx

          symNum = symNum + 1

          if (symNum = thePaletteList.Count) then exit end

        end   'for each COLUMN

        x = originX + 0.75

        y = y - dy

      end   'for each ROW

      if (symNum < ((thePaletteList.Count) - 1)  ) then

        MakeNewPage = true

      end

    elseif (symType = "PEN") then

      xLn1 = x

      yLn1 = y

      xLn2 = x + 0.25

      yLn2 = y + 0.45

      xLn3 = x + 0.50

      yLn3 = y + 0.05

      xLn4 = x + 0.75

      yLn4 = y + 0.45

      l = PolyLine.Make({{xLn1 @ yLn1, xLn2 @ yLn2}, {xLn2 @ yLn2, xLn3 @ yLn3},{xLn3 @ yLn3, xLn4 @ yLn4}})

      gLine = GraphicShape.Make(l)

      for each ROW in 1..10

        for each COLUMN in 0..5

          nextRec = gr.clone

          nextLine = gLine.clone

          nextLine.setSymbol(thePaletteList.Get(symNum))

          nextRec.setSymbol(thePaletteList.Get(0))

          offsetPt = (x@y)

          nextRec.setOrigin(offsetPt)

          nextLine.setOrigin(offsetPt)

          pt = offsetPt + (0.25@0) - (0@0.25)

          t = GraphicText.Make(symNum.AsString, pt)

          gl.UnselectAll

          gl.AddBatch(nextRec)

          gl.AddBatch(nextLine)

          gl.AddBatch(t)

          x = x + dx

          symNum = symNum + 1

          if (symNum = thePaletteList.Count) then exit end

        end  'for each COLUMN

        x = originX + 0.75

        y = y - dy

      end   'for each ROW

      if (symNum < ((thePaletteList.Count) - 1)  ) then

        MakeNewPage = true

      end

    elseif (symType = "MARKER") then

      l = (x@y) + (0.3@0.25)

      gPoint = GraphicShape.Make(l)

      for each ROW in 1..10

        for each COLUMN in 0..5

          nextRec = gr.clone

          nextPoint = gPoint.clone

          nextPoint.setSymbol(thePaletteList.Get(symNum))

          nextPoint.GetSymbol.SetSize(30)

          offsetPt = (x@y)

          nextRec.setOrigin(offsetPt)

          secondPt = (x@y) + (0.3@0.25)

          nextPoint.setOrigin(secondPt)

          pt = offsetPt + (0.25@0) - (0@0.25)

          t = GraphicText.Make(symNum.AsString, pt)

          gl.UnselectAll

          gl.AddBatch(nextRec)

          gl.AddBatch(nextPoint)

          gl.Addbatch(t)

          x = x + dx

          symNum = symNum + 1

          if (symNum = thePaletteList.Count) then exit end

        end 'for each COLUMN

        x = originX + 0.75

        y = y - dy

      end  'for each ROW

      if (symNum < ((thePaletteList.Count) - 1)  ) then

        MakeNewPage = true

      end

    end  'PerSymType

  end  'Per Page

end  'While

gl.UnSelectAll

av.GetProject.SetModified(true)

gl.EndBatch


View.SetTOCFont
Sets the TOC Font

Source Code

Description:  This interactive script allows you to change the font family, style, and size used in a View's TOC. This script can be attached to a click event on a control in the View's DocGUI. Note that the font changes are applied to ALL views currently in the project, and any views created after the script is run.

The font changes are NOT maintained between ArcView sessions.  You could store the text symbol as an object tag on the project, and restore the symbol when the project is first opened. Adding this request to the bottom of this script will store the text symbol as an object tag on the project:

   av.GetProject.SetObjectTag(TOCFont)

Restore the symbol by getting the object tag and issuing the request, TOC.SetDefaultSymbol(aSymbol). Include this in a startup script, or in an script run by the user. When using this method views must be reopened to see the TOC drawn with the new font.

Name:    View.SetTOCFont

Requires:  A View must be the active document.

Self:

Returns:

FileName:  tocfont.ave


View.SetTOCFont (Sample Script)
'Sets the TOC Font

theFM = FontManager.The

theFontlist = theFM.ReturnFamilies

theFont = msgbox.ListAsString (theFontlist,"Select a Font", "Set TOC Font")

if (theFont = nil) then

 exit

end

theStyles = theFM.ReturnStyles (theFont)

theStyle = msgbox.ListAsString (theStyles,"Select a Font Style","Set TOC Font")

if (theStyle = nil) then exit end

theSize = msgbox.input("Enter a Font Size","Set TOC Font","12")

if (theSize = nil) then exit end

TOCFont = TextSymbol.Make

TOCFont.SetFont (NFont.Make(TheFont.AsString,TheStyle.AsString))

TOCFont.SetSize( theSize.AsNumber )

'Set the TOC default text symbol

TOC.SetDefaultSymbol(TOCFont)

' To see the new font, re-open all views.

allDocs = av.GetProject.GetDocs

for each v in allDocs

  if (v.is(View) and (v.GetWin.IsOpen)) then

    'only open views already open or iconized

    v.GetWin.Close

    v.GetWin.Open

  end

end


Table.CreateNewTable
Creates a new Table using MultiInput dialog box

Source Code

Description:   An example script which demonstrates creating a Table from user inputs.  An empty Table is created and MsgBox.MultiInput is used to prompt the user for information to add to the Table.

The input form will be presented until the user clicks cancel.  After clicking cancel the new Table document will be added to the project and opened.

The default ID in the dialog box is incremented for each record, as is the record number displayed in the dialog box title.  Note that while no validation is possible in the dialog box itself, the numeric value for the ID field is verified before it is written to the table.  If the value entered was not numeric, a default value is used.

Name:    Table.CreateNewTable

Requires:

Self:

Returns:

FileName:  tblinput.ave


Table.CreateNewTable (Sample Script)
'Creates a new Table using MultiInput dialog box

' Create fields which will be added to the table...

f1  =  Field.Make( "ID",#FIELD_SHORT, 5, 0 )

f2  =  Field.Make( "Name",#FIELD_CHAR, 15, 0 )

f3  =  Field.Make( "City",#FIELD_CHAR, 15, 0 )

f4  =  Field.Make( "State",#FIELD_CHAR, 15, 0 )

f5  =  Field.Make( "County",#FIELD_CHAR, 15, 0 )

f6  =  Field.Make( "Software",#FIELD_CHAR, 15, 0 )

f7  =  Field.Make( "Language",#FIELD_CHAR, 15, 0 )

f8  =  Field.Make( "Company",#FIELD_CHAR, 15, 0 )

' Create a new Table...

myFile = FileDialog.Put( "test.dbf".asfilename, "*.dbf", "Output File")

if (myFile = nil) then

  exit

end

theVTab = VTab.MakeNew(myFile,dbase)

myTable = Table.Make(theVtab)

' Add Fields to the Table...

theVTab.AddFields( {f1,f2,f3,f4,f5,f6,f7,f8} )

' Populate table using MultiInput...

i = 0

defaultID = 20000

while(true)       ' Endless loop - user clicks cancel to exit...

  i = i + 1

  defaultID = defaultID + 1

  l = MsgBox.MultiInput("Enter information (Cancel to end input):",

      "Add Record:"++i.AsString,

      { "Your ID:", "Your Name:", "City:", "State:", "County:", "Software:",

        "Language:", "Company:" },

      { defaultID.AsString, "Allison Arcview", "Redlands", "California",

        "San Bernardino", "ArcView", "Avenue", "ESRI" })

  ' Check to see if the user clicked cancel to end input...

  if (l.count < 1) then

    break

  end

  ' Write the records to the table...

  rec = theVTab.AddRecord

  ' Validate numeric input for the ID field...

  if (l.get(0).IsNumber.Not) then

    MsgBox.Warning( "Invalid ID - Using default ID number.","")

    theVtab.SetValue( f1, rec, defaultID )

  else

    theVTab.SetValue( f1, rec, l.Get( 0 ).AsNumber )

  end

  theVTab.SetValue( f2, rec, l.Get( 1 ) )

  theVTab.SetValue( f3, rec, l.Get( 2 ) )

  theVTab.SetValue( f4, rec, l.Get( 3 ) )

  theVTab.SetValue( f5, rec, l.Get( 4 ) )

  theVTab.SetValue( f6, rec, l.Get( 5 ) )

  theVTab.SetValue( f7, rec, l.Get( 6 ) )

  theVTab.SetValue( f8, rec, l.Get( 7 ) )

end

myTable.GetWin.Open


Labeling.CreateTextMasks
Creates text masks for a theme's labels

Source Code

Description:   Adds a text mask polygon for each piece of GraphicText associated with a theme.  Use the symbol window to customize the text masks.

Name:    Labeling.CreateTextMasks

Requires:

Self:

Returns:

FileName:  textmask.ave


Labeling.CreateTextMasks (Sample Script)
'Creates text masks for a theme's labels

theView = av.GetActiveDoc

theView.GetGraphics.UnSelectAll

tmlist = {}

for each t in theView.GetActiveThemes

  gs = t.GetGraphics

  for each g in gs

    if(g.Is(graphicText)) then

      br = g.GetBounds.Clone

      bg = GraphicShape.Make(br)

      bg.SetObjectTag(t.GetName)

      tmlist.Add(bg)

    end

  end

end

tmFill = RasterFill.Make

tmFill.SetStyle(#RASTERFILL_STYLE_STIPPLE)

tmFill.SetColor(Color.GetWhite)

for each tm in tmlist

  ThemeName = tm.GetObjectTag

  tmHeight = tm.GetShape.GetHeight

  tmWidth = tm.GetShape.GetWidth

  tm.GetShape.SetOrigin(tm.GetOrigin - ((tmHeight/5)@(tmHeight/5)))

  tm.GetShape.SetSize(tmWidth@tmHeight + ((tmHeight/2.5)@(tmHeight/5)))

  theView.FindTheme(ThemeName).GetGraphics.Add(tm)

  theView.GetGraphics.AddBatch(tm)

  tm.SetSymbol(tmFill)

  tm.SetSelected(true)

end

theView.GetGraphics.MoveSelectedToBack

theView.GetGraphics.EndBatch

theView.GetGraphics.Invalidate


Graphics.ShapetoGraphic
Shape to Graphic Convertor

Source Code

Description:   This script creates a graphic for each selected record of the active theme.  If no selection is made, then graphics will be made for all features.

Name:    Graphics.ShapetoGraphic

Requires:  A View with one active theme

Self:

Returns:

FileName:  thm2gphx.ave


Graphics.ShapetoGraphic (Sample Script)
'Shape to Graphic Convertor

theview       = av.getactivedoc

theGraphics   = theview.GetGraphics

theProjection = theView.GetProjection

if ( (theView.GetActiveThemes.Count=0) or (theView.GetActiveThemes.Get(0).Is(ITheme)) ) then

 msgbox.error("An Active Feature Theme is Required","Exiting")

 return(nil)

end

theFtab = theView.GetActiveThemes.Get(0).GetFTab

unselectAll = false

if (theFTab.GetSelection.Count = 0) then

  theFtab.GetSelection.SetAll

  theFtab.UpdateSelection

  unselectAll = true

end

theBit   = theFtab.GetSelection

theShapeField = theFtab.FindField("Shape")

for each x in theBit

  aShape = theFtab.ReturnValue(theShapeField, x)

  if (theProjection.IsNull) then

    aGraphic = GraphicShape.Make(aShape.ReturnProjected(theProjection))

  else

    aGraphic = GraphicShape.Make(aShape)

  end

  if (aShape.Is(Polygon)) then

    aSolidFill = RasterFill.Make

    aSolidFill.SetStyle(#RASTERFILL_STYLE_SOLID)

    aGraphic.SetSymbol(aSolidFill)

  end

  aGraphic.GetSymbol.SetColor(Color.GetGreen)

  theGraphics.addbatch(aGraphic)

end

if (unselectAll) then

  theFtab.GetSelection.ClearAll

  theFtab.UpdateSelection

end

thegraphics.endbatch

theGraphics.Invalidate


Theme.Histogram
Creates a histogram for the active theme

Source Code

Description:   Generates a histogram for the active theme in the current view. A new Chart document is created to display the histogram. A temporary file is created to store interval counts and other information used to create the histogram. The color scheme used to create the chart will be the same as the legend of the active theme, i.e. there is direct correlation between the theme classification colors and chart colors.

Should be associated with the Click property of a button on the View DocGUI.  An update script should be associated with the control to ensure that this script can only be executed when there is at least one active theme.

Name:    Theme.Histogram

Requires:  A View with an active theme.  The theme must be classified.

Self:

Returns:

FileName:  thmhisto.ave


Theme.Histogram (Sample Script)
'Creates a histogram for the active theme

theView=av.GetActiveDoc

theTheme=theView.GetActiveThemes.Get(0)

' Get the components of the Legend that will be used to create the chart...

'

theLegend=theTheme.GetLegend

theSymbols=theLegend.GetSymbols

theClasses=theLegend.GetClassifications

theFieldName=theLegend.GetFieldNames.Get(0)

theVTab=theTheme.GetFTab

theField = theVTab.FindField(theFieldName)

' Create the new data file for the histogram...

'

outFName = av.GetProject.MakeFileName( theTheme.GetName, "dbf")

outFName = FileDialog.Put( outFName, "*.dbf", "Output Histogram File" )

if (outFName = Nil) then

  exit

end

newVTab=VTab.MakeNew( outFName, dBASE )

labelf=Field.Make( "Label", #FIELD_CHAR, 20, 0 )

countf=Field.Make( "Count", #FIELD_DECIMAL, 10, 0)

newVTab.AddFields( {labelf, countf} )

' Loop through the classes recording the ranges.

'

countlist = {}

for each c in theClasses

  countlist.Add(0)

end

numClasses = theClasses.Count

' Loop through the records recording which class they fall in.

'

for each rec in theVTab

  v = theVTab.ReturnValue(theField,rec)

  for each i in 0..(numClasses - 1)

    if (theClasses.Get(i).Contains(v)) then

      countlist.Set(i,countlist.Get(i)+1)

      break

    end

  end

end

' Loop through the classes writing the information to disk.

'

maxcount=0

for each i in 0..(numClasses-1)

  rec=newVTab.AddRecord

  newVTab.SetValue(labelf,rec,theClasses.Get(i).GetLabel)

  newVTab.SetValue(countf,rec,countlist.Get(i))

  maxcount=maxcount max countlist.Get(i)

end

' Create a chart and match the colors to the legend.

'

newChart=Chart.Make(newVTab,{countf})

newChart.SetRecordLabelField(labelf)

for each i in 0..(numClasses-1)

  newChart.GetChartDisplay.SetSeriesColor(i,theSymbols.Get(i).GetColor)

end

newChart.GetTitle.SetName("Histogram of"++theTheme.GetName)

newChart.GetYAxis.SetBoundsUsed(true)

newChart.GetYAxis.SetBoundsMin(0)

newChart.GetYAxis.SetBoundsMax(maxcount)

newChart.GetWin.Open


View.ThresholdTOC
Tells you if theme isn't in display threshold

Source Code

Description:   If a theme is outside the display threshold, ">>" and "<<" will appear around the theme's name to indicate that it does not appear in the view because it is outside the display threshold set for the theme. If the theme's name is preceded by ">>", this means the view's scale denominator is larger than the theme's maximum threshold; if the the theme's name is preceded by "<<", the view's scale denominator is smaller than the theme's minimum threshold.

You could add this script to the end of all the View Zoom controls (ZoomIn tool, button, and menu choice, ZoomOut tool, button and menu choice, ZoomToFullExtent, etc.) so that you can always know the status of the display.

Name:    View.ThresholdTOC

Requires:  The active document must be a view and the Map Units should be set for that  view. If they are not, a message will display.

Self:

Returns:

FileName:  thrshtoc.ave


View.ThresholdTOC   (Sample Script)
'Tells you if theme isn't in display threshold

theView = av.GetActiveDoc

theScale = theView.ReturnScale

if (theScale = 0) then

  MsgBox.Info("The Map Units of the view are not set.", "Threshold helper")

  return NIL

end

for each t in theView.GetThemes

  n = t.GetName

  n1 = n.BasicTrim(">> ", " <<")

  n2 = n1.BasicTrim("<< ", " >>")

  nNew = n2

  maxThres = t.GetThreshold.GetMaximum

  minThres = t.GetThreshold.GetMinimum

  if (( theScale >=  maxThres ) and ( maxThres <> 0 )) then

    t.SetName(">>"++nNew++"<<")

    elseif (( theScale <= minThres ) and ( minThres <> 0 )) then

    t.SetName("<<"++nNew++">>")

    else

    t.SetName(nNew)

  end

end


Table.ReportInfo
Reports on a table's structure

Source Code

Description:   Working off a table document this script reports on the structure of the table

Name:    Table.ReportInfo

Requires:  The active document must be a table.

Self:

Returns:

FileName:  tinfo.ave


Table.ReportInfo (Sample Script)
'Reports on a table's structure

atbl=av.getactivedoc

if(atbl.is(table).not) then

 msgbox.error("A table document must be active.","Error")

 exit

end

theVTab1 = atbl.getvtab

theBitMap1 = theVTab1.GetSelection

fList = theVTab1.GetFields

atab=tab+tab+tab+tab

totalchar = "Alias"+atab+"Type"+atab+"Width"+atab+"Decimal"

totalchar=totalchar+nl+"---------------------------------------------------------------------"

longname=0

for each afld in flist

 aname=afld.getalias

 if (aname.count > longname) then

   longname=aname.count

 end

end

for each subitem in flist

  aspace=" "

  itList = subitem.gettype

  itPrecision=subitem.getPrecision

  itwidth=subitem.getwidth

  aname=subitem.getalias

  compilation=aname+","+atab+itlist.asString+","+atab+itWidth.asString+","

    +atab+itPrecision.asString

  totalchar=totalchar +nl+ compilation

end

MsgBox.report(totalchar, "Items from "+atbl.getname.asstring)


Project.ToggleCtrlVisibility
Toggles the visibility of Controls

Source Code

Description:   Toggles the visibility of all buttons and tools in the current document's graphical user interface (DocGUI).  This script should be installed as the click property for a menu item.

After the first execution, the menu item label will automatically change from 'Controls Visible' to 'Controls Invisible' along with the current visible status of the controls.  Though this sample script only toggles control visibility, any control property can be changed using Avenue.

Name:    Project.ToggleCtrlVisibility

Requires:  Must be installed as click event for any Menu Item.

Self:

Returns:

FileName:  togctrls.ave


Project.ToggleCtrlVisibility (Sample Script)
'Toggles the visibility of Controls

if (Self.GetLabel = "&Controls Invisible") then

  Self.SetLabel("&Controls Visible")

  for each c in av.GetActiveGui.GetButtonBar.GetControls

    c.SetVisible(false)

  end

  for each c in av.GetActiveGui.GetToolBar.GetControls

    c.SetVisible(false)

  end

else

  Self.SetLabel("&Controls Invisible")

  for each c in av.GetActiveGui.GetButtonBar.GetControls

    c.SetVisible(true)

  end

  for each c in av.GetActiveGui.GetToolBar.GetControls

    c.SetVisible(true)

  end

end


View.WorldDataBaseToShape
Converts World Data Base (WDB) line files to ArcView Shapefiles

Source Code

Description:   Converts line features from World Data Base (WDB) file to ArcView Shapefile

Name:    View.WorldDataBaseToShape

Requires:

Self:

Returns:

FileName:  wdb2shp.ave


View.WorldDataBaseToShape (Sample Script)
'Converts World Data Base (WDB) line files to ArcView Shapefiles

theView = av.GetActiveDoc

' Prompt the user for a data file...

' Create a line file

wdbFN = FileDialog.Show( "*.*","Text File (*.*)","Import")

if ( wdbFN = nil ) then

  exit

end

wdbDataFile = LineFile.Make( wdbFN, #FILE_PERM_READ)

tempName     = wdbFN.GetBaseName.AsTokens(".").Get(0)

tempDir      = wdbFN.ReturnDir.AsString

defName      = FN.Make( tempDir ).MakeTmp( tempName, "shp" )

theShapeFN  = FileDialog.Put(defName, "*.shp", "Convert to Shapefile" )

if ( theShapeFN = nil ) then

  exit

end

' Check to make sure (beyond a reasonable doubt)

' that the file is a valid WDB file...

buffer = wdbDataFile.ReadElt

if (wdbDataFile.IsAtEnd) then

  MsgBox.Error( "Empty data file."+NL+"Halting conversion.", "" )

  exit

end

if (buffer = nil) then

  MsgBox.Error(" Not a valid WDB file."+NL+"Halting conversion", "" )

  exit

end

if (buffer.Middle(0,7).IsNumber.Not) then

  MsgBox.Error( "Not a valid WDB file."+NL+"Halting conversion", "")

  exit

end

' If we have made it to here, assume that the file is a valid WDB file.

' Create the FTab from the new shape file...

numLines = wdbDataFile.GetSize

theFTab = FTab.MakeNew( theShapeFN, polyline )

theRecNumField = Field.Make( "Record Number", #FIELD_SHORT, 5, 0 )

theRankField = Field.Make( "rank", #FIELD_SHORT, 5, 0 )

theIDField = Field.Make( "ID", #FIELD_CHAR, 10, 0 )

theFTab.AddFields( {theRecNumField, theRankField, theIDField} )

theShapeField = theFTab.FindField( "Shape" )

theRecNumField = theFTab.FindField( "Record Number" )

theTypeField = theFTab.FindField( "rank" )

theIDField = theFTab.FindField( "ID" )

' This is the loop which reads the file line-by-line.  Remember that the

' first record has already been read (to make sure the file is valid);

' therefore, we will start by evaluating that line.

' There's an outside loop, which reads the record header.  The inside loop

' then reads the vertices for the line feature.

' This block of code does some nominal checks.  Some of these checks will be

' redundant for the first line.

av.ShowMsg( "Converting..." )

av.ShowStopButton

recNum = 1

lineCounter = 1

while(TRUE)

  ' Every line read by the outside loop should be a record header line.

  ' It will contain information about the feature.

  if ( wdbDataFile.IsAtEnd ) then

    break

  end

  rank = buffer.Middle(7,2).Trim

  if ( rank = nil ) then

    MsgBox.Error( "Unexpected format at line"++lineCounter.AsString+":"+NL+

      " No Line rank.", "" )

    av.ClearMsg

    av.ClearStatus

    exit

  end

  if ( rank.IsNumber.Not ) then

    MsgBox.Info( "Unexpected format at line"++lineCounter.AsString+":"+NL+

      " Line rank is non-integer.", "" )

    av.ClearMsg

    av.ClearStatus

    exit

  end

  rank = rank.AsNumber

  numVertices = buffer.Middle(9,6).Trim

  if ( numVertices = nil ) then

    MsgBox.Error( "Unexpected format at line"++lineCounter.AsString+":"+NL+

      " No Vertex Number.", "" )

    av.ClearMsg

    av.ClearStatus

    exit

  end

  if ( numVertices.IsNumber.Not ) then

    MsgBox.Info( "Unexpected format at line"++lineCounter.AsString+":"+NL+

      " Vertex number not numeric.", "" )

    av.ClearMsg

    av.ClearStatus

    exit

  end

  numVertices = numVertices.AsNumber

  ID = buffer.Middle(15,5).Trim

  ' Now we're ready to loop through the vertices...

  pointList = List.Make

  for each i in 1..numVertices

      if ( wdbDataFile.IsAtEnd ) then

         MsgBox.Warning( "Unexpected end of file at line:"

           ++lineCounter.AsString+".", "" )

         break

      end

      buffer = wdbDataFile.ReadElt

      lineCounter = lineCounter + 1

      lat1 = buffer.Middle(0,2).Substitute(" ","0").AsNumber

      lat2 = buffer.Middle(2,2).Substitute(" ","0").AsNumber

      lat3 = buffer.Middle(4,2).Substitute(" ","0").AsNumber

      dir  = buffer.Middle(6,1)

      yCoord = (lat1 + (lat2 / 60) + (lat3 / 3600))

      if (dir.UCase = "S") then

        yCoord = yCoord.Negate

      end

      rest = buffer.Right(buffer.Count - 8)

      long1 = rest.Middle(0,2).Substitute(" ","0").AsNumber

      long2 = rest.Middle(2,2).Substitute(" ","0").AsNumber

      long3 = rest.Middle(4,2).Substitute(" ","0").AsNumber

      dir   = rest.Middle(6,1)

      xCoord = ( long1 + (long2 / 60) + (long3 / 3600) )

      if ( dir.UCase = "W" ) then

        xCoord = xCoord.Negate

      end

      thePoint = Point.Make( xCoord,yCoord )

      pointList.Add( thePoint )

  end

  thePolyLine = PolyLine.Make( {pointList} )

  theRecord = theFTab.AddRecord

  theFTab.SetValue( theRecNumField, theRecord, recNum )

  theFTab.SetValue( theShapeField, theRecord, thePolyLine )

  theFTab.SetValueString( theIDField, theRecord, ID )

  theFTab.SetValue( theRankField, theRecord, rank )

  buffer = wdbDataFile.ReadElt

  lineCounter = lineCounter + 1

  proceed = av.SetStatus((lineCounter / numLines) * 100)

  if ( proceed.Not ) then

    av.ClearStatus

    av.ShowMsg( "Stopped" )

    exit

  end

  recNum = recNum + 1

end

av.ClearMsg

av.ClearStatus

theFTab.Flush


View.XYCoordDump
Creates a file with coordinate information from user

Source Code

Description:   Creates a comma delimited textfile containing a unique ID, x and y coordinates, and user input information.  The coordinate information is taken from the location on the View chosen with the mouse.

The Object Tag of the tool executing this script is used to store the current point id number.  The number is retrieved at the time of execution, incremented, and written to the file, ensuring a unique ID number. Additional attributes concerning the location are input by the user, and all information is written to the specified file.

The features described in the file, by their xy coordinates, may be added as a theme.  First import the textfile as a Table, then use the Table as an XY event source.

The points appear temporarilly and are not saved as part of the GraphicList of the display.  See the section commented in the body of the script below to add points as Graphics to the GraphicList.

Name:    View.XYCoordDump

Requires:  The script must be executed from the apply event on a tool in a DocGUI that supports view documents.

Self:

Returns:

FileName:  wrxyinfo.ave


View.XYCoordDump (Sample Script)
'Creates a file with coordinate information from user

theView = av.GetActiveDoc

theFile = ("wrxyinfo.txt".AsFileName)

' Create the file and write header if it does not exist, otherwise

' open it for append, and initialize the point id...

' The object tag field of Self (the control this script is executed from)

' is used to store the ID number.

'

if (theFile.IsFile.Not) then

  lf = LineFile.Make(theFile,#FILE_PERM_APPEND)

  lf.WriteElt("ID,XCoord,YCoord,Info")

  SELF.SetObjectTag(0)

  id = SELF.GetObjectTag + 1

else

  lf = LineFile.Make(theFile,#FILE_PERM_APPEND)

  if (SELF.GetObjectTag = nil) then

    SELF.SetObjectTag(0)

  end

  id = SELF.GetObjectTag + 1

end

' Get the point from the user...

pt = theView.GetDisplay.ReturnUserPoint

' Create a symbol for the point...

s = BasicMarker.Make

s.SetStyle(#BASICMARKER_STYLE_PATTERN)

s.SetColor(Color.GetRed)

' Draw the point on the display...

d = theView.GetDisplay

d.BeginClip

d.DrawPoint(pt,s)

d.EndClip

d.Flush

'' To include the point as a Graphic on the GraphicList, comment the

'' previous section and uncomment the section immediately following...

' gp = GraphicShape.Make(pt)

' theView.GetGraphics.Add(gp)

' Get additional attribute information from the user...

theInfo = MsgBox.Input("Enter information about the location:","Information","")

if (theInfo.AsString = "nil") then

  theInfo = " "

end

' Get the x and y values...

x = pt.GetX

y = pt.GetY

' Set the precision for the coordinate values...

x.SetFormat( "d.dddddd" )

y.SetFormat( "d.dddddd" )

' Build the string which will be written to the file...

filestring = id.AsString+","+x.AsString+","+y.AsString+","+theInfo

' Write the string to the file, close the file, and save the ID number...

lf.WriteElt(filestring)

lf.close

SELF.SetObjectTag(id)


Table.MakeFromExcel
Creates a new table document from an Excel spreadsheet

Source Code

Description:   This script allows you to create a table document using the data contained in a Microsoft Excel Spreadsheet.  Start Excel and open the spreadsheet that you want to use in ArcView, then run this script.  A new table will be created by using DDE to talk to Excel.  This script doesn't handle boolean fields, doesn't handle non-contiguous (a column without a field name), always assumes dates are of the format MM/dd/yy, and always writes a file called "C:\TEMP\EXCEL.DBF".

Name:    Table.MakeFromExcel

Requires:  Microsoft Excel is running and a selection exists.  The first row in the Excel spreadsheet contains column contains field names.  The second and subsequent rows contain data.  You have a directory called "C:\TEMP" that you can write to.

Self:

Returns:

FileName:  xls2tbl.ave


Table.MakeFromExcel (Sample Script)
'Creates a new table document from an Excel spreadsheet

sysClient = DDEClient.Make( "Excel","System")

if (sysClient.HasError) then

  MsgBox.error( sysClient.GetErrorMsg, "")

  exit

  ' if you want to start Excel instead, use the following two lines instead of the two above

  ' system.execute("c:\msoffice\excel\excel.exe <path>\<book_name>.xls")

  ' sysClient = DDEClient.Make("Excel","System")

end

v= vtab.makenew("C:\temp\excel.dbf".AsFileName, dBase)

fldlst = {}

fulltopic = sysClient.Request("selection") 'returns [BookN]SheetN!RnCn:RnCn

sysClient.Close

topiclist=fulltopic.AsTokens("!:")

sheetname = topiclist.get(0)

startrange = topiclist.get(1)

endrange = topiclist.get(2)

startrow = startrange.AsTokens("RC").Get(0).AsNumber

startcol = startrange.AsTokens("RC").Get(1).AsNumber

endrow = endrange.AsTokens("RC").Get(0).AsNumber

endcol = endrange.AsTokens("RC").Get(1).AsNumber

sheet = DDEClient.Make( "Excel", sheetname )

for each column_num in startcol..endcol

  column_name = sheet.request( "R"+startrow.AsString+"C"+column_num.AsString )

  val = sheet.request( "R"+(startrow+1).AsString+"C"+column_num.AsString )

  if ((val.Trim.IsNumber) and (val.Trim.Contains("."))) then

    decimal_places = (val.trim.count - val.trim.IndexOf(".")) - 1

    f = field.make(column_name.trim,#FIELD_DECIMAL,12,decimal_places)

  elseif (val.Trim.IsNumber) then

    f = field.make(column_name.trim,#FIELD_DECIMAL,12,0)

  elseif (val.Trim.Contains("/")) then

    f = field.make(column_name.trim,#FIELD_DATE,8,0)

  else

    f = field.make(column_name.trim,#FIELD_CHAR,val.count+5,0)

    ' adding 5 to the length of the first string value of the column is arbitrary

    ' set it to whatever accommodates your data best

  end

  fldlst.add(f)

end

v.AddFields(fldlst)

for each row in (startrow+1)..endrow

   i = 0

   newRec = v.AddRecord

   for each col in startcol..endcol

     if (fldlst.get(i).GetType=#FIELD_CHAR) then

        v.setvalue(fldlst.get(i),newRec,sheet.request( "R"+row.AsString+"C"+col.AsString ).trim )

     elseif (fldlst.get(i).GetType=#FIELD_DECIMAL) then

        v.SetValue(fldlst.get(i),newRec,sheet.request( "R"+row.AsString+"C"+col.AsString ))

     else (fldlst.get(i).GetType=#FIELD_DATE)

        the_date = date.make(sheet.request( "R"+row.AsString+"C"+col.AsString ).trim,"MM/dd/yy")

        v.setvalue(fldlst.get(i),newRec,the_date)

     end

     i = i + 1

   end

end

table.make(v)

sheet.Close


View.ShiftFeatures
Shifts XY coordinates for the features of a theme

Source Code

Description:   Shifts features in the current active Theme in the input X and Y distance. A new theme is created as a result of the shift.  Only the selected features will be moved.  If there are no selected features then all features in the theme will be moved. The units of the xy shift are the same units as the unprojected source geometry.

Name:    View.ShiftFeatures

Requires:  A View with one active Theme.

Self:

Returns:

FileName:  xyshift.ave


View.ShiftFeatures (Sample Script)
'Shifts XY coordinates for the features of a theme

theView  = av.GetActiveDoc

theTheme = theView.GetActiveThemes.Get(0)

' Specify the output shapefile...

'

defaultName  = FN.Make("$HOME").MakeTmp("theme","shp")

shpFileName  = FileDialog.Put( defaultName,"*.shp","Output Shape File" )

if (shpFileName = Nil) then

  exit

end

' Ensure a .shp extension...

shpFileName.SetExtension("shp")

' Get the x and y shift parameters from the user...

'

xShift = MsgBox.Input( "Enter X shift:", "XY Shift", "0.0" )

if ((xShift = Nil) or (xShift.IsNumber.Not)) then

  exit

end

yShift = MsgBox.Input( "Enter Y shift:", "XY Shift", "0.0" )

if ((yShift = Nil) or (yShift.IsNumber.Not)) then

  exit

end

' Create the appropriate kind of FTab...

'

shapeType = theTheme.GetFtab.FindField("Shape").GetType

if (shapeType = #FIELD_SHAPELINE) then

  outFTab = FTab.MakeNew( shpFileName, Polyline )

elseif (shapeType = #FIELD_SHAPEMULTIPOINT) then

  outFTab = FTab.MakeNew( shpFileName, Multipoint )

elseif (shapeType = #FIELD_SHAPEPOINT) then

  outFTab = FTab.MakeNew( shpFileName, Point )

elseif (shapeType = #FIELD_SHAPEPOLY) then

  outFTab = FTab.MakeNew( shpFileName, Polygon )

end

inShapeField = theTheme.GetFtab.FindField("Shape")

outShapeField = outFTab.FindField("Shape")

' Clone the fields in the inFTab for inclusion in the outFTab...

'

inFTab = theTheme.GetFTab

inFieldList  = inFTab.GetFields

outFieldList = inFieldList.DeepClone

outFieldList.Remove(0)  ' omit the shape field...

outFTab.AddFields( outFieldList )

' If there are no selected features, apply the XY shift to all,

' otherwise just apply the shift to the selected features...

'

if (inFTab.GetSelection.Count = 0) then

    theRecordsToShift = inFTab

    numRecs = inFTab.GetNumRecords

  else

    theRecordsToShift = inFTab.GetSelection

    numRecs = theRecordsToShift.Count

  end

for each rec in theRecordsToShift

  theShape = theTheme.GetFtab.ReturnValue( inShapeField, rec )

  newShape = theShape.Move(xShift.AsNumber, yShift.AsNumber)

  newRec   = outFtab.AddRecord

  outFTab.SetValue( outShapeField, newRec, newShape )

  ' Copy the rest of the attributes for this record.  The inFieldList

  ' and outFieldList are offset by 1 since the inFieldList includes

  ' the shape field, the outFieldList does not.  The lists are used

  ' to traverse the fields since field name properties may change when

  ' the .dbf file is created, i.e. FNODE# may become FNODE_, etc...

  '

  fieldPtr = 0

  for each fOut in outFieldList

    fieldPtr = fieldPtr + 1

    fIn  = inFieldList.Get( fieldPtr )

    outFTab.SetValue( fOut, newRec, inFTab.ReturnValue( fIn, rec ) )

  end

end

outFtab.Flush

' Allow the user to add the new shapefile as a theme to a View of choice.

'

if (MsgBox.YesNo("Add shapefile as theme to a view?",

  "XY Shift", true).Not) then

  exit

end

' Create a list of views and allow the user to choose which view to

' add the new theme to...

viewList = {}

for each d in av.GetProject.GetDocs

  if (d.Is(View)) then

    viewList.Add( d )

  end

end

' Include a choice for a new view...

viewList.Add("<New View>")

addToView = MsgBox.ListAsString( viewList,"Add Theme to:", "XY Shift" )

' Get the specified view, make the theme, and add it...

if (addToView <> nil) then

  if (addToView = "<New View>") then

    addToView = View.Make

    addToView.GetWin.Open

  end

  shiftedTheme = FTheme.Make( outFTab )

  addToView.AddTheme( shiftedTheme )

  ' Bring the View to the front...

  addToView.GetWin.Activate

end


Places a graphic of a table you specify into a layout

Source Code

Description:  Use the tool with this script attached as the apply event to drag a rectangle in a layout.  You will be prompted to choose which table you want to make the representation of and which fields to show.  The script will populatate rows with cell values of those fields until the bottom of the rectangle you specified is reached.  If you choose more fields than would fit within the width of the rectangle, those will be included.

This script gets around several annoying limitations in ArcView's TableFrame graphic:

1) 	With this script you can make a table that is wider than 80 text columns. (Great for landscape docs).

2) 	You change the font of this table.

3) 	Since this table is graphicgroup, you can ungroup it and change the symbols for individual parts.

4) 	This table will always print correctly - on some printers printing directly from the table doc & from table frames, there were gross formating errors

5) 	You can resize this table and the text just gets resized, rather than including more data like the tableframe does.

This script cannot produce the representation of the table if it is sorted - you will get the unsorted version.  Additionally, since this representation is just a dumb graphic, it does not automatically update itself in any way, shape, or form.

Additionally, you can use the symbol window to change the button color by using the foreground, change the table background by using the background color, or change the text and outline color as well. If you want to highlight a particular column, ungroup the graphic table and then you can select the column by clicking on its border, then change its background color or text color by using background or text from the color palette.

Name:  Layout.GraphicTable

Requires:  Place this script as the apply event for a tool in your Layout GUI.  There must be at least one table document in the current project.

Self:

Returns:

FileName:  gtable.ave


Layout.GraphicTable (Sample Script)
'Places a graphic of a table you specify into a layout

theLayout = av.GetActiveDoc

gl = theLayout.GetGraphics

bRect = theLayout.ReturnUserRect

if (bRect.GetWidth < 0.1) then

  return nil

end

if (System.IsShiftKeyDown) then

  SelectedOnly = true

else

  SelectedOnly = false

end

TableDocNames = {}

for each d in av.GetProject.GetDocs

  if(d.Is(Table)) then

    TableDocNames.Add(d.GetName)

  end

end

if (TableDocNames.Count = 0) then

  Msgbox.Error("You must have a table document in the Project","Duh!")

  return nil

end

gl.UnSelectAll

TableName = Msgbox.ChoiceAsString(TableDocNames,"Choose a table:","Smart Table")

if (TableName = nil) then

  return nil

end

theTable = av.GetProject.FindDoc(TableName)

theVTab = theTable.GetVTab

theFieldNames = {}

for each f in theVTab.GetFields

  if (f.IsTypeShape.Not) then

    theFieldNames.Add(f.GetAlias)

  end

end

FieldsToShow = Msgbox.MultiListAsString(theFieldNames,"Choose the Fields to Show","Smart Table")

if (FieldsToShow = nil) then return nil end

if (FieldsToShow.Count = 0) then

  return nil

end

bc = Color.Make

bc.SetRGBList({255,255,225})

ftbf = RasterFill.Make

ftbf.SetStyle(#RASTERFILL_STYLE_SOLID)

ftbf.SetColor(bc)

bRectO = bRect.ReturnOrigin

bRectH = bRect.GetHeight

bRectW = bRect.GetWidth

bRectT = bRect.GetTop

brectB = bRect.GetBottom

bRectR = bRect.GetRight

HeightLeft = bRect.GetHeight

tbo = bRectO + (0@bRectH)

cspace = 0

for each f in FieldsToShow

  'Make Field Title

  fl = GraphicText.Make(f,(tbo +(0.1@0)) )

  fl.GetSymbol.SetSize(12)

  fl.SetDisplay(theLayout.GetDisplay)

  tbo = tbo - (0@(fl.GetBounds.GetHeight + 0.05))

  fl.SetSelected(true)

  gl.AddBatch(fl)

  HeightLeft = HeightLeft - fl.GetBounds.GetHeight - 0.05

  HbarHeight = HeightLeft

  'Now do the column of values

  if (SelectedOnly) then

    theBitmap = theVTab.GetSelection

  else

    ResetSelection = false

    if (theVTab.GetSelection.Count <> 0) then

      theVTab.RememberSelection

      theVTab.GetSelection.SetAll

      theVtab.UpdateSelection

      ResetSelection = true

    end

    theBitmap = theVTab.GetDefBitmap

  end

  counter = -1

  ColStr = ""

  vst = GraphicText.Make(ColStr,(0@0))

  vst.SetDisplay(theLayout.GetDisplay)

  vst.GetSymbol.SetSize(10)

  While (HeightLeft <> 0)

    rec = theBitmap.GetNextSet(counter)

    counter = rec

    ValStr = theVTab.ReturnValueString(theVTab.FindField(f),rec)

    ColStr = ColStr + ValStr

    vst.SetText(ColStr)

    'Check to see if column has exceeded Height

    if (HeightLeft < vst.GetBounds.GetHeight) then

      HeightLeft = 0

    end

    if (theBitmap.GetNextSet(counter) = -1) then

      HeightLeft = 0

    end

    ColStr = ColStr + nl

  end

  vst.SetOrigin(tbo - (0@(vst.getBounds.GetHeight)) )

  'Check to see if the Column is wider than the Title

  if (fl.GetBounds.GetWidth > vst.GetBounds.GetWidth) then

    'Title is wider, so move column

    if (theVTab.FindField(f).IsTypeNumber) then

      vst.SetAlignment(#TEXTCOMPOSER_JUST_RIGHT)

      vst.GetBounds.Move((fl.GetBounds.GetWidth - vst.GetBounds.GetWidth + 0.1),0.1)

      gl.AddBatch(vst)

    elseif(theVTab.FindField(f).IsTypeString) then

      vst.SetAlignment(#TEXTCOMPOSER_JUST_LEFT)

      vst.GetBounds.Move(0.1,0.1)

      gl.AddBatch(vst)

    end

  else

    'Column is wider so move  & justify title

    if (theVTab.FindField(f).IsTypeNumber) then

      vst.SetAlignment(#TEXTCOMPOSER_JUST_RIGHT)

      vst.GetBounds.Move(0.1, 0.1)

      gl.AddBatch(vst)

    elseif (theVTab.FindField(f).IsTypeString) then

      vst.SetAlignment(#TEXTCOMPOSER_JUST_LEFT)

      vst.GetBounds.Move(0.1, 0.1)

      gl.AddBatch(vst)

    end

    fl.GetBounds.Move( ( (vst.GetBounds.GetWidth - fl.GetBounds.GetWidth) /2 ) ,0)

  end

  vst.SetSelected(true)

  cbr = gl.ReturnSelectedExtent.clone

  cbr.ExpandBy(0.05)

  cbp = GraphicShape.Make(cbr)

  cbp.GetSymbol.SetOLWidth(0.1)

  gl.AddBatch(cbp)

  cbp.SetSelected(true)

  gl.GroupSelected

  gl.GetSelected.Get(0).SetObjectTag("col")

  cspace = cspace + gl.ReturnSelectedExtent.GetWidth

  gl.UnSelectAll

  HeightLeft = bRectH

  tbo = bRectO + (cspace@bRectH)

end

for each g in gl.FindAllByObjectTag("col")

  g.SetSelected(true)

end

se = gl.ReturnSelectedExtent

seO = se.ReturnOrigin

ftr = Rect.Make(SeO + (0@(se.GetHeight - 0.275)),(se.GetWidth@0.275))

coltits = {}

for each g in gl.FindAllByObjectTag("col")

  colTitleRect = ftr.IntersectWith(g.GetBounds.Clone)

  coltits.Add(colTitleRect)

  g.SetSelected(false)

end

tc = Color.Make

tc.SetTransParent(true)

for each ftr in coltits

  bp = ftr.Clone.InsetBy(0.0125)

  bpd = Polygon.Make({{ftr.ReturnOrigin,(ftr.GetRight@ftr.GetBottom),(ftr.GetRight@ftr.GetTop),(bp.GetRight@bp.GetTop),(bp.GetLeft@bp.GetBottom),ftr.ReturnOrigin}})

  bpl = Polygon.Make({{ftr.ReturnOrigin,(bp.ReturnOrigin),(bp.GetRight@bp.GetTop),(ftr.GetRight@ftr.GetTop),(ftr.GetLeft@ftr.GetTop),ftr.ReturnOrigin}})

  gbp = GraphicShape.Make(bp)

  gbpd = GraphicShape.Make(bpd)

  gbpl = GraphicShape.Make(bpl)

  gbp.SetSymbol(ftbf.Clone)

  gbpd.SetSymbol(ftbf.Clone)

  gbpl.SetSymbol(ftbf.Clone)

  lg = Color.Make

  lg.SetRGBList({220,220,220})

  dg = Color.Make

  dg.SetRGBList({120,120,120})

  gbpd.GetSymbol.SetColor(dg.Clone)

  gbpl.GetSymbol.SetColor(lg.Clone)

  gbpl.GetSymbol.SetOLWidth(0)

  gbpd.GetSymbol.SetOLWidth(0)

  gbpl.GetSymbol.SetColorLock(true)

  gbpd.GetSymbol.SetColorLock(true)

  gbp.GetSymbol.SetOLWidth(0)

  gbpl.GetSymbol.SetOLColor(tc.Clone)

  gbpd.GetSymbol.SetOLColor(tc.Clone)

  gbp.GetSymbol.SetOLColor(tc.Clone)

  gl.AddBatch(gbpd)

  gl.AddBatch(gbpl)

  gl.AddBatch(gbp)

  gbpd.SetSelected(true)

  gbpl.SetSelected(true)

  gbp.SetSelected(True)

end

gl.GroupSelected

gl.MoveSelectedToBack

gl.GetSelected.Get(0).SetObjectTag("buttons")

gl.UnSelectAll

for each g in gl.FindAllByObjectTag("col")

  g.SetSelected(true)

  gl.MoveSelectedToFront

end

gl.FindByObjectTag("buttons").SetSelected(true)

NeatRect = gl.ReturnSelectedExtent.Clone

nrgs = GraphicShape.Make(NeatRect)

nrgs.GetSymbol.SetOLWidth(0.6)

theLayout.GetGraphics.AddBatch(nrgs)

gl.UnSelectAll

bp = GraphicShape.Make(NeatRect)

bw = Color.GetWhite

bpf = RasterFill.Make

bpf.SetStyle(#RASTERFILL_STYLE_OPAQUESTIPPLE)

bp.SetSymbol(bpf)

bp.GetSymbol.SetColor(tc.Clone)

bp.GetSymbol.SetBGColor(Color.GetWhite)

theLayout.GetGraphics.AddBatch(bp)

bp.SetSelected(True)

gl.MoveSelectedToBack

if (ResetSelection) then

  LastSel = theVTab.GetLastSelection.Clone

  theVTab.SetSelection(LastSel)

  theVTab.UpdateSelection

end

for each g in gl.FindAllByObjectTag("col")

  g.SetSelected(true)

end

gl.FindByObjectTag("buttons").SetSelected(true)

nrgs.SetSelected(true)

gl.GroupSelected

theLayout.GetGraphics.EndBatch


View.ShowDD2
Displays decimal degree values in the status bar of a projected view

Source Code

Description:  Displays decimal degree coordinates in a view's status bar as you move the cursor around.

Name:  View.ShowDD2

Requires:  A projected view. There must be an Apply event on a view's tool bar.

This file contains TWO scripts - one is called recursively by the other, so you must be careful that you give the scripts the proper names.

Directions:

1. Copy this file into a script editor, and call the script View.ShowDD2.
2. Copy the Script 1 section below into a new script editor, and call the script View.ShowDD1.
3. Uncomment the 3 lines of code in View.ShowDD1.
4. Create a new tool on a View's tool bar, and make View.ShowDD2 its Click event script.
5. Make the new tool active, then click once inside the view to activate. To deactivate, make any non-view the active document.

How it works: When you use the new tool on a view, View.ShowDD2 verifies that the window is a View, then runs View.ShowDD1, which reports the unprojected coordinates in the View's status bar. View.ShowDD2 recursively calls View.ShowDD1. These scripts loop twice per second which returns the cursor position as the mouse scrolls across the View.

Self:

Returns:

FileName:  showdd.ave


View.ShowDD2 (Sample Script)
'Displays decimal degree values in the status bar of a projected view

'

'Script 1 - copy this into a script called View.ShowDD1

'and uncomment the next 3 lines:

'if (av.GetActiveDoc.GetClass.GetClassName = "View") then

'  av.DelayedRun("View.ShowDD2", nil, 0.5)

'end

'

'

'Script 2 - call this script View.ShowDD2:

'

theDoc = av.GetActiveDoc

thePoint = theDoc.GetDisplay.ReturnUserPoint

theDDPoint = thePoint.ReturnUnprojected(theDoc.GetProjection)

theLon = theDDPoint.GetX.SetFormat("dd.dddd")

theLat = theDDPoint.GetY.SetFormat("dd.dddd")

theMsg = " Position = "+theLon.AsString+", "+theLat.AsString

av.ShowMsg(theMsg)

System.RefreshWindows

av.Run("View.ShowDD1", nil)


View.SelectPoint
Shows the number of selected features in the status bar

Source Code

Description: Replaces the system View.SelectPoint script. Just open up a new script, load this script in, and rename the script "View.SelectPoint". Then when you select features on a view, the number of selected features will appear in the status bar. Works with multiple themes, too.

Name: View.SelectPoint

Requires: At least one theme in a view.

Self:

Returns: At least one theme in a view.

FileName: showsel.ave


View.SelectPoint (Sample Script)
'Shows the number of selected features in the status bar

theView = av.GetActiveDoc

r = theView.ReturnUserRect

theThemes = theView.GetActiveThemes

if (r.IsNull) then

  p = theView.GetDisplay.ReturnUserPoint

  if (System.IsShiftKeyDown) then

    op = #VTAB_SELTYPE_XOR

  else

    op = #VTAB_SELTYPE_NEW

  end

  for each t in theThemes

    if (t.CanSelect) then

      t.SelectByPoint(p, op)

      ' Next two lines were added to show number selected (also see below)

      n = t.GetFTab.GetNumSelRecords

      av.ShowMsg("Number of"++t.GetName++"features selected:"++n.asString)

    end

  end

else

  if (System.IsShiftKeyDown) then

    op = #VTAB_SELTYPE_OR

  else

    op = #VTAB_SELTYPE_NEW

  end

  for each t in theThemes

    if (t.CanSelect) then

      t.SelectByRect(r, op)

      ' Next two lines were added to show number selected

      n = t.GetFTab.GetNumSelRecords

      av.ShowMsg("Number of"++t.GetName++"features selected:"++n.asString)

    end

  end

end

av.GetProject.SetModified(true)


View.ConvertTo2DShape
Converts 3D shapefile to 2D shapefile

Source Code

Description: This script converts a 3D shape theme (may contain M) into a 2D shape file and then askes the user if or not to load the converted 2D shape file into the view.

Name: View.ConvertTo2DShape

Requires: The active document must be a view, with at least one active 3D shape theme.

Self:

Returns:

FileName: xyz2xy.ave


View.ConvertTo2DShape (Sample Script)
'Converts 3D shapefile to 2D shapefile

theView = av.GetActiveDoc

theDocName = theView.GetClass.GetClassName

for each t in theView.GetActiveThemes

  if (t.Is(FTheme)) then

    theInFTab = t.GetFTab

    if (theInFTab.GetShapeClass.GetClassName = "MultiPatch") then

      continue

    end

    theShape = theInFTab.GetShapeClass.MakeNull

    fl = {}

    for each f in theInFTab.GetFields

      if (f.IsVisible and f.IsTypeNumber) then

        fl.Add(f)

      end

    end

    outFields = {}

    for each f in theInFTab.GetFields

      if (f.IsVisible and f.IsTypeShape.Not) then

        outFields.Add(f.Clone)

      end

    end

    ' get output name

    def = av.GetProject.GetWorkDir.MakeTmp("thm","shp")

    def = SourceManager.PutDataSet(ftab, "Output Shapefile Name :"

     ++ t.GetName, def, true)

    if (def = NIL) then

      continue

    end

    thePrj = Prj.MakeNull

    inClass = theInFTab.GetShapeClass

    if (inClass.IsSubclassOf(PointM)) then

      outClass = Point

    elseif (inClass.IsSubclassOf(LineM)) then

      outClass = Line

    elseif (inClass.IsSubclassOf(RectM)) then

      outClass = Rect

    elseif (inClass.IsSubclassOf(PolygonM)) then

      outClass = Polygon

    elseif (inClass.IsSubclassOf(PolyLineM)) then

      outClass = PolyLine

    elseif (inClass.IsSubclassOf(MultiPointM)) then

      outClass = MultiPoint

    else

      MsgBox.Info("This is not a 3D shape file.","")

      continue

    end

    theOutFTab = FTab.MakeNew(def, outClass)

    theOutFTab.SetEditable(TRUE)

    theOutFTab.AddFields(outFields)

    theBitMap = theInFTab.GetSelection

    if (theBitMap.Count = 0) then

      theBitMap.SetAll

      unsetBitmap = TRUE 'reset flag for end of loop

    else

      unsetBitmap = FALSE

    end

    shapeField = theOutFTab.FindField("Shape")

    done = FALSE

    offset = -1

    while (not done)

      recNum = theBitmap.GetNextSet(offset)

      offset = recNum

      if (recNum <> -1) then

        if (theInFTab.QueryShape(recNum, thePrj, theShape)) then

          rec = theOutFTab.AddRecord

          theOutFTab.SetValue(shapeField, rec, theShape)

          for each f in outFields

            inField = theInFTab.FindField(f.GetAlias)

            attVal = theInFTab.ReturnValue(inField, recNum)

            theOutFTab.SetValue(f, rec, attVal)

          end

        end

      else

        done = TRUE

      end

    end

    theOutFTab.Flush

    theOutFTab.SetEditable(FALSE)

    if (unsetBitmap) then

      theBitmap.ClearAll

    end

    if (MsgBox.YesNo("Add 2D shapefile as theme to the"

     ++ theDocName + "?","Convert to 2D Shapefile :"

      ++ t.GetName,TRUE).Not) then

      continue

    end

    'create a theme and add it to the View

    fthm = FTheme.Make(theOutFTab)

    theView.AddTheme(fthm)

  end

end

' bring the View to the front

theView.GetWin.Activate