TNTmips

HOME

FREE PRODUCTS
  TNTlite
  TNTatlas
  TNTsim3D

DOWNLOADS
  Release Version
  Development Version
  FTP
  Language Kits
  Sample Geodata
  Reseller Resources
  Promotional

DOCUMENTATION
  Tutorials
  Technical Guides
  Quick Guides

SITE MAP


PropFinder.sml


## PropFinder.sml
##	21 April 2004

## Tool script that creates a dialog to conduct property searches
## by address and by property owner for the Lincoln property database.
## The tool also provides three alternative left-mouse button actions:
## 1) zoom in to the mouse location, 2) zoom out from the mouse location
## and 3) select property parcel and show that property's page on the 
## county assessor's website. 

## Results of address or name searches are shown on the Result List
## tabbed panel.  If only one match is found the property polygon is
## automatically highlighted and the view window recenters on that
## property polygon.  If more than one match is found, the user
## should select an entry from the list and press the View Property button
## to highlight and recenter on the associated parcel polygon. In either
## case, if the highlighted polygon is already in the view, the view is not 
## redrawn.  The View Assessor's Website Data button on the same panel shows 
## the selected property's page on the county assessor's website.

## Randy Smith, MicroImages, Inc.

## Requires TNTmips v 7.0, 14 April 2004 or later


# The following symbols are predefined
#    class GRE_VIEW View            {use to access the view the tool script is attached to}
#    class GRE_GROUP Group          {use to access the group being viewed if the script is run from a group view}
#    class GRE_LAYOUT Layout        {use to access the layout being viewed if the script is run from a layout view}
#    numeric ToolIsActive           Will be 0 if tool is inactive or 1 if tool is active
#
# The following values are also predefined and are valid when the various On...()
# functions are called which deal with pointer and keyboard events.
#    numeric PointerX            Pointer X coordinate within view in pixels
#    numeric PointerY            Pointer Y coordinate within view in pixels
#    numeric ShiftPressed        1 if  key being pressed or 0 if not
#    numeric CtrlPressed         1 if  key being pressed or 0 if not
#    numeric LeftButtonPressed   1 if left pointer button pressed or 0 if not
#    numeric RightButtonPressed  1 if right pointer button pressed or 0 if not
#    numeric MiddleButtonPressed 1 if middle pointer button pressed or 0 if not

########################################
### Global variable declarations
########################################

class GRE_GROUP activeGroup;
class GRE_LAYER_VECTOR parcelLayer;
class GRE_LAYER_RASTER orthoLayer;
class VECTOR parcelVector;
class	RASTER orthoRaster;
class GRE_VECTOR_POLYS parcelPolys;
class TRANSPARM pTransparm;				## coordinate transformation parameters from screen to parcel layer
class TRANSPARM lvTransparm;				## coordinate transformation parameters from parcel layer to view
class RECT polyExtents, viewExtents;	## extents of polygon and view in screen coordinates

numeric searchmode;				# 1 if address search, 0 if name search
numeric prevsearchmode;			# mode for last search
numeric zoomChanged;				# 1 if zoom has changed since last redraw, otherwise 0

numeric i;							# element number counter for polygon loop
numeric count;						# counter for number of property polygons found
numeric numPolys;					# number of polygons in parcel vector
numeric matchRecList[1];		# array to hold record numbers for records matching search
numeric propsArray[1];			# array to hold element numbers of polygons found
numeric listcount;				# number of items in result list in dialog

string xmlfile$;
class XMLDOC dlgdoc, listdlgdoc;			# class instances for XML documents with dialog specifications
class XMLNODE dlgnode, listdlgnode;		# class instance for node in the XML document corresponding
													# to the dialog
class GUI_DLG dlgwin;						# class instance for the GUI dialog 
numeric errXML;								# error value to check ingest of dialog specification

numeric prevMulti;							# flag for previous search result type: 1 = multiple, 0 = other

string prevname$;			# string variable to store owner name for comparison before next search
string prevaddress$;		# string variable to store address for comparison before next search

class GUI_FORMDATA settings;  # structure to hold values retrieved from main search dialog

## handles for dialog controls, needed to clear/reset values on close
class GUI_LAYOUT_BOOK panels;
class GUI_CTRL_EDIT_NUMBER editAddNum;
class GUI_CTRL_EDIT_STRING editStreet, editLname, editFname, editMid;
class GUI_CTRL_COMBOBOX prefixCombo, streetTypeCombo;
class GUI_CTRL_EDIT_STRING statusText, searchText;
class GUI_FORM_RADIOGROUP zoomSetting, mouseSetting;
class GUI_CTRL_LISTBOX propList;
class GUI_CTRL_PUSHBUTTON viewProperty, viewData;

##################################################################################
# The following script functions will be called (if used in the script) when
# the appropriate action or event occurs as described in the comments before each.
# To use a function, uncomment the lines containing the 'func' definition
# and ending brace '}' by removing the leftmost '#' on the line and add the
# function code between the two lines.
##################################################################################

##################################################################################
#### procedure called the first time the tool is activated.
#### If the tool implements a dialog it should be created (but not displayed) here.
##################################################################################
proc OnInitialize () 
	{
	searchmode = 1;		# set default search mode to address search
	prevMulti = 0;			# reinitialize flag for previous search result type

	#######################################################################################
	### get screen pixel size and compute map scale for 1X view of orthophoto layer 
	### (ortho cell size = 0.3 m = 3000 mm); scale at 1X = cell size (mm) / pixel size (mm)
	#######################################################################################
	numeric pixelSize = View.PixelSizeMillimeters;	# screen pixel size in millimeters

	numeric scale1X = 300 / pixelSize;

	### get handles for the parcel vector layer in the View and its polygon element set
	####################################################################################
	activeGroup = Layout.ActiveGroup;
	parcelLayer = activeGroup.GetLayerByName("Parcels");
	parcelLayer.NoFillWhenHighlight = 1;	 # don't fill highlighted polygons with highlight color
	parcelPolys = parcelLayer.Poly;

	### get the parcel vector object in parcelLayer so its database can be accessed
	###############################################################################
	DispGetVectorFromLayer(parcelVector, parcelLayer);
	numPolys = NumVectorPolys(parcelVector);

	### get TRANSPARM from parcel layer object coordinates to View coordinates
	### to be used with left mouse button zoom function
	###########################################################################
	lvTransparm = View.GetTransLayerToView(parcelLayer);

	###############################################
	#### specification in XML for main query dialog
	###############################################
	local string xml$ = '
	
	
		
	  		
				
					
						
							
								Zoom In to Location
								Zoom Out from Location
								View Assessor's Website Data
							
						
						
							
								Zoom to Property
								Zoom to Block
								Zoom to Neighborhood
								Keep Current Scale
							
						
					
				
	      	
					
	        			
	        				
	        	  				
	        	  			
	        	  			
	        			    
	        			
	        				
	        	  			
								Any	       	   
								None
	       	   			E
	            			W
	            			N
	            			S
	            			NW
	            			SW
	        	  			
	        	  			
	        	  			            
						
        				
        					
        		  			
        					
     	   	  			                 
     	   			     
     	   			
     	   	  			
      	  	  			
								Any
            				AVE
              				BLVD
              				CIR
              				CT
              				DR
              				LN
              				RD
              				ST
              				BAY
             				BND
             				BYP
              				HOLW
              				HWY
              				MALL
              				PKWY
              				PL
              				PLZ
              				PP
              				TER
              				TRL
              				VAL
      	    			
      	    			
      	    			
      				
      			
  				
				
					
						
							
							
						
						
							
							
						
						
							
							
						
					
				
				
					
						
						
					
					
					
					
						
						
						
					
				
			
			
				
				
			
			
				
				
				
				
			
		
	';


	################################################################
	### parse XML text for main search dialog into memory;
	### return an error code (number < 0) if there are syntax errors
	################################################################
	errXML = dlgdoc.Parse(xml$);

	if (errXML < 0)
		{
		PopupError(errXML);
		Exit();
		}

	##########################################################
	# get the dialog element from the parsed XML document and
	# show error message if the dialog element can't be found
	##########################################################
	dlgnode = dlgdoc.GetElementByID("pSearch");

	if (dlgnode == 0)
		{
		PopupMessage("Could not find dialog node in XML document");
		Exit();
		}

	##########################################################
	# Set the XML dialog element as the source for the GUI_DLG
	# class instance we are using for the dialog window.
	##########################################################
	dlgwin.SetXMLNode(dlgnode);
	dlgwin.CreateModeless(View.InfoForm);		### create as modeless dialog with
															### View window status line as parent

	################################################################################
	### get handles for dialog controls using their ID's in the dialog specification
	################################################################################
	statusText = dlgwin.GetCtrlByID("statusText");
	searchText = dlgwin.GetCtrlByID("searchText");
	zoomSetting = dlgwin.GetCtrlByID("zoomSetting");
	mouseSetting = dlgwin.GetCtrlByID("mouseSetting");
	propList = dlgwin.GetCtrlByID("propList");
	panels = dlgwin.GetPaneByID("panels");
	viewProperty = dlgwin.GetCtrlByID("viewProperty");
	viewData = dlgwin.GetCtrlByID("viewData");

	### address controls
	editAddNum = dlgwin.GetCtrlByID("addnumfld");
	prefixCombo = dlgwin.GetCtrlByID("comboPrefix");
	editStreet = dlgwin.GetCtrlByID("streetnamefld");
	streetTypeCombo = dlgwin.GetCtrlByID("comboType");

	### name controls
	editLname = dlgwin.GetCtrlByID("lastnamefld");
	editFname = dlgwin.GetCtrlByID("firstnamefld");
	editMid = dlgwin.GetCtrlByID("midintfld");

	} # end of OnInitialize


#############################################################################
### Called when tool is activated.
### If the tool implements a dialog it should be "managed" (displayed) here.
#############################################################################
proc OnActivate () {
	panels.SetActivePage(0);	### set Settings panel to be active (on top)
	dlgwin.Open();
	zoomChanged = 1;
	}  # end of OnActivate

############################################################################
### Called when tool is deactivated (usually when switching to another tool).
### If the tool implements a dialog it should be "unmanaged" (hidden) here.
############################################################################
proc OnDeactivate () {

	### clear/reset controls on main search dialog to default states
	statusText.ClearValue(0);
	editAddNum.ClearValue(0);
	prefixCombo.SetSelectedItemIndex(0);
	editStreet.ClearValue(0);
	streetTypeCombo.SetSelectedItemIndex(0);

	editLname.ClearValue(0);
	editFname.ClearValue(0);
	editMid.ClearValue(0);

	if (propList.GetCount() > 0) then		### clear property list
		propList.DeleteAllItems();

	dlgwin.Close(0);		# close search dialog without notifying, so OnClose()
								# will not be called (allows user to switch tools without
								# having OnClose() override by setting the default tool 

 }  # end of OnDeactivate

#############################################################################
### procedure called when Help button on dialog is pressed
#############################################################################
proc OnHelp ()
	{
	local string url$;
	url$ = "file://" + _context.ScriptDir + "/" + "help.htm";

	RunAssociatedApplication(url$);

	}

##############################################################
### procedure called when the Address Search page is activated
##############################################################
proc OnAddressActive ()
	{
	searchmode = 1;
	statusText.ClearValue(0);
	editAddNum.SetFocus();
	}	# end of OnAddressActive

############################################################
### procedure called when the Name Search page is activated
############################################################
proc OnNameActive ()
	{
	searchmode = 0;
	statusText.ClearValue(0);
	editLname.SetFocus();
	}	# end of OnNameActive

###########################################################
### Called when user presses 'left' pointer/mouse button.
###########################################################
proc OnLeftButtonPress () 
	{
	local string mouseSetting$;
	local class POINT2D clickPt;		### coordinates for click position

	### get setting for left mouse button mode from dialog
	mouseSetting$ = mouseSetting.GetValueStr();

	### get cursor position in screen coordinates 
	clickPt.x = PointerX;
	clickPt.y = PointerY;

	### get TRANSPARM from screen coordinates to parcel vector layer coordinates
	### for current view position and transform point to layer coordinates
	############################################################################
	pTransparm = View.GetTransLayerToScreen(parcelLayer, 1);
	clickPt = pTransparm.ConvertPoint2DFwd(clickPt);

	if (mouseSetting$ == "navigate")		### select polygon and go to its page on Assesor's website
		{
		local numeric polynum;			### element number of the polygon clicked on
		local string url$;				### string containing the URL to pass to the browser

		### find the polygon clicked on and highlight it in the view
		polynum = FindClosestPoly(parcelVector, clickPt.x, clickPt.y, GetLastUsedGeorefObject(parcelVector) );
		parcelPolys.HighlightSingle(polynum); 

		url$ = parcelVector.poly[polynum].ca123103.P_I_D$;

		RunAssociatedApplication(url$);
		}

	else if (mouseSetting$ == "zoomIn")		### zoom in to cursor position
		{
		### convert click point from vector layer to view coordinates
		### using TRANSPARM computed when tool is initialized
		#############################################################
		clickPt = lvTransparm.ConvertPoint2DFwd(clickPt);

		View.DisableRedraw = 1;
		View.Center = clickPt;			### recenter View on click point
		View.ZoomIn(2,1);					### zoom in 2X
		View.DisableRedraw = 0;
		View.Redraw();						### redraw view
		}

	else if (mouseSetting$ == "zoomOut")		### zoom out from cursor position
		{
		### convert click point from vector layer to view coordinates
		### using TRANSPARM computed when tool is initialized
		#############################################################
		clickPt = lvTransparm.ConvertPoint2DFwd(clickPt);

		View.DisableRedraw = 1;
		View.Center = clickPt;			### recenter View on click point
		View.ZoomOut(2,1);				### zoom out 2X
		View.DisableRedraw = 0;
		View.Redraw();						### redraw view
		}
	}  # end of OnLeftButtonPress

###########################################################
### procedure called when zoom setting is changed in dialog
###########################################################
proc OnZoomChanged ()
	{
	zoomChanged = 1; 
	}	# end of OnZoomChanged

##########################################################################
### procedure to highlight, pan, and zoom to the selected property polygon
##########################################################################
proc DoZoom (numeric element)
	{
	local numeric vwScale;
	local string zoom$;

	#######################################################
	### check if highlighted polygon is already in the view
	#######################################################

	### get extents of highlighted polygon from Internal database table as min and max points
	local CLASS POINT2D minPt, maxPt;
	minPt.x = parcelVector.poly[element].Internal.MinX;
	minPt.y = parcelVector.poly[element].Internal.MinY;
	maxPt.x = parcelVector.poly[element].Internal.MaxX;
	maxPt.y = parcelVector.poly[element].Internal.MaxY;

	### set up RECT from polygon extents
	polyExtents.pt1 = minPt;
	polyExtents.pt2 = maxPt;

	### get extents of View in screen coordinates
	### upper left corner of view pane = 0,0, so lower right coordinates = width, height
	local CLASS POINT2D UpLeft, LowRight;
	LowRight.x = View.Width;
	LowRight.y = View.Height;

	### set up RECT from view extents in screen coordinates
	viewExtents.pt1 = UpLeft;
	viewExtents.pt2 = LowRight;

	if (zoomChanged == 0)	### zoom setting hasn't been changed; don't need to check it
		{

		#################################################################################
		### get TRANSPARM from screen coordinates to parcel vector layer coordinates for
		### current view position and convert extents RECT to layer coordinates
		#################################################################################
		pTransparm = View.GetTransLayerToScreen(parcelLayer, 1);
		viewExtents = pTransparm.ConvertRectFwd(viewExtents);

		###############################################################################
		### check if parcel polygon is in the current view  
		###############################################################
		if (viewExtents.ContainsRect(polyExtents) )	### don't need to redraw view 
			{
			View.SetMessage("");			### clear View window message line and status bar
			View.StatusBarClear();
			}

		else
			{
			View.DisableRedraw = 1;

			#################################################################################
			### if parcel polygon won't fit in view at this scale, then zoom to polygon extents
			### before redrawing.
			#################################################################################
			if ( (polyExtents.GetHeight() > viewExtents.GetHeight() ) ||  
				(polyExtents.GetWidth() > viewExtents.GetWidth() )	)
				{
				parcelLayer.ZoomToActiveElement();
				parcelLayer.UnhighlightAllElements();	### needed to force redraw
				zoomChanged = 1;
				}

			else	# parcel polygon fits in view; pan to polygon and set current map scale
				{
				vwScale = View.CurrentMapScale;			# get current view scale
				parcelLayer.ZoomToActiveElement();		# zooms to polygon extents, changing view scale
				View.CurrentMapScale = vwScale;			# reset previous view scale
				parcelLayer.UnhighlightAllElements();	# needed to force redraw
				}

			###################################################################
			### re-enable redraw, redraw the view, and highlight the polygon
			###################################################################
			View.DisableRedraw = 0;
			ViewRedraw(View);
			parcelPolys.HighlightSingle(element);
			}
		} # end (if zoomChanged == 0)


	else  ### zoom setting has changed
		{
		### get current setting for Zoom radiogroup
		zoom$ = zoomSetting.GetValueStr();
		View.DisableRedraw = 1;	 

		if (zoom$ == "property")		## zoom to 1X but don't redraw yet
			{
			vwScale = scale1X;
			}

		else			### set vwScale value from Zoom radiogroup setting
			{
			if (zoom$ == "current") then
				vwScale = ViewGetMapScale(View);

			else if (zoom$ == "block") then
				vwScale = 3200;

			else if (zoom$ == "neighborhd") then
				vwScale = 8000;
			}

		### Set View scale, zoom / recenter on active polygon but don't redraw yet
		parcelLayer.ZoomToActiveElement();
		ViewSetMapScale(View, vwScale);
		parcelLayer.UnhighlightAllElements();

		#####################################################################################
		### get TRANSPARM from screen coordinates to parcel vector layer coordinates for the
		### new view position and view scale and convert extents RECT to layer coordinates
		#####################################################################################
		pTransparm = View.GetTransLayerToScreen(parcelLayer, 1);
		viewExtents = pTransparm.ConvertRectFwd(viewExtents);

		##################################################################################
		### if parcel polygon won't fit in view at new zoom, then zoom to polygon extents
		### before redrawing.
		###################################################################################
		if ( (polyExtents.GetHeight() > viewExtents.GetHeight() ) ||  
			(polyExtents.GetWidth() > viewExtents.GetWidth() )	)
			{
			parcelPolys.HighlightSingle(element);
			parcelLayer.ZoomToActiveElement();
			parcelLayer.UnhighlightAllElements();
			zoomChanged = 1;
			}

		else
			zoomChanged = 0;

		##################################################################
		### re-enable redraw, redraw the view, and highlight the polygon
		##################################################################
		View.DisableRedraw = 0;
		ViewRedraw(View);
		parcelPolys.HighlightSingle(element);

		}	# end else zoom setting has changed

	}	# end of DoZoom

#################################################################
### procedure to get owner name and address string for parcel
#################################################################
func string GetPropString (numeric propNum)
	{
	local string name$, num$, dir$, stname$, type$, aptnum$, sub$;
	local string liststr$;

	name$ = parcelVector.poly[propNum].ca123103.OWNER$;
	num$ = parcelVector.poly[propNum].ca123103.SIT_ST_NUM$;
	dir$ = parcelVector.poly[propNum].ca123103.SIT_ST_DIR$;
	stname$ = parcelVector.poly[propNum].ca123103.SIT_ST_NAM$;
	type$ = parcelVector.poly[propNum].ca123103.SIT_ST_TYP$;
	sub$ = parcelVector.poly[propNum].ca123103.SIT_ST_SUB$;
	aptnum$ = parcelVector.poly[propNum].ca123103.SIT_APT_NU$;

	liststr$ = sprintf( "%s: %s %s %s %s %s%s", name$, num$, dir$, stname$, type$, sub$, aptnum$ );

	return liststr$;
	}	# end of GetPropString

#################################################################
### procedure called when search finds no matching parcel polygon
#################################################################
proc OnFoundNone ()
	{
	View.SetMessage("");			### clear View window message and status bar (no redraw will occur
	View.StatusBarClear();		### to do this automatically)
	View.NoBlankScreen = 1;		### don't redraw things that don't need to be redrawn
	parcelLayer.UnhighlightAllElements();		### unhighlight any currently highlighted parcel polygons
	View.NoBlankScreen = 0;
	viewProperty.SetEnabled(0);					### disable the View Property push-button
	viewData.SetEnabled(0);							### disable the View Assessor's Website Data button

	### update Search Result field in dialog
	statusText.SetValue("No properties found matching these criteria", 0);
	}	# end of OnFoundNone

#####################################################################################
### procedure called when one or more property polygons meet the search criteria.
#####################################################################################
proc OnFound (numeric propCount)
	{
	if (propList.GetCount() > 0 ) then		### clear property list
		propList.DeleteAllItems();

	local string liststr$;
	local numeric j, k, propNum;

	for j = 1 to propCount 
		{
		liststr$ = GetPropString(propsArray[j]);		### get name / address string for parcel
		propList.AddItem(liststr$);						### add this string to the list
		}	# end of for j = 1 to propCount

	if (propCount == 1)	### only one parcel polygon found
		{
		statusText.SetValue("One property found.", 0);		### update status field in dialog

		propList.SetSelectedItemIndex(0);			### set the single list item to be selected

		viewProperty.SetEnabled(0);					### disable the View Property push-button
		viewData.SetEnabled(1);							### enable the View Assessor's Website Data button

		propNum = propsArray[1];
		parcelPolys.HighlightSingle(propNum);		### highlight element to make it active in view
		DoZoom(propNum);									### pan / zoom to highlighted element
		}

	else			### more than one polygon found
		{
		View.NoBlankScreen = 1;							### don't redraw entire view
		parcelLayer.UnhighlightAllElements(1);		### unhighlight any currently highlighted parcel polygon
		View.NoblankScreen = 0;

		statusText.SetValue( sprintf("%d properties found.", propCount) , 0);		### update status field in dialog

		View.SetMessage("");				## blank the View status message and bar
		View.StatusBarClear();

		viewProperty.SetEnabled(0);	### enable the View Property push-button
		viewData.SetEnabled(0);			### enable the View Assessor's Website Data button
		}

		panels.SetActivePage(3);	### set Result List panel to be active (on top)
	}

####################################################################
### procedure called when a property is selected in the Result List
####################################################################
proc OnPropListSelect ()
	{
	viewData.SetEnabled(1);
	viewProperty.SetEnabled(1);
	}

######################################################################################
### procedure called when the View Polygon button on the Result List panel is pressed.
######################################################################################
proc OnViewPoly ()
	{
	local numeric propNumber;		# polyon element number of property selected from the Property List

	### get the value from the property list (string) and convert to number (polygon element number)
	propNumber = propsArray[propList.GetSelectedItemIndex() + 1];

	View.DisableRedraw = 1;
	parcelPolys.HighlightSingle(propNumber);		### highlight element to make it active in view
	View.DisableRedraw = 0;
	DoZoom(propNumber);									### pan / zoom to highlighted element

	}

############################################################
### procedure called when View Assessor's Website Data
### button on dialog is pressed
############################################################
proc OnViewData ()
	{
	local numeric propNumber;		# polyon element number of property selected from the Property List
	local string url$;

	### get the value from the property list (string) and convert to number (polygon element number)
	propNumber = propsArray[propList.GetSelectedItemIndex() + 1];

	url$ = parcelVector.poly[propNumber].ca123103.P_I_D$;

	RunAssociatedApplication(url$);
	}

#######################################################################
### procedure called to update status on dialog and view for new search
#######################################################################
proc OnNewSearch()
	{
	statusText.ClearValue(0);				## clear search status field on dialog

	if (propList.GetCount() > 0) then
		propList.DeleteAllItems();				### clear property list

	### Set message at bottom of View window
	View.SetMessage("Searching for properties...");
	}

#############################################################################
### procedure to get element numbers of polygons attached to matching records
### and take action depending on whether 0, 1, or >1 elements found
#############################################################################
proc GetPolygons ()
	{
	######################################################################
	### We now have a list of records.  Find the elements that have those
	### records attached.
	######################################################################
	if (searchmode == 1) then
		count = TableGetRecordListElementList(parcelVector.poly.ParcelAddress, matchRecList, count, propsArray);

	else if (searchmode == 0) then
		count = TableGetRecordListElementList(parcelVector.poly.OwnerName, matchRecList, count, propsArray);

	if (count == 0)				### no properties found
		{
		OnFoundNone();
		}

	else								### one or more properties found
		{
		OnFound(count);
		}

	}	# end of GetPolygons

#################################################################
# called when Search button on Property Search dialog is pressed
#################################################################
proc OnSearch ()
	{

	### get control settings (values) from dialog and store in GUI_FORMDATA
	settings = dlgwin.GetValues();
	local numeric possibleRecList[1];
	local numeric numRecords, record;

	#############################################
	### address search; components of address are 
	### in separate fields in the database
	#############################################
	if (searchmode == 1)
		{

		##############################################
		### declare local string variables for address
		##############################################
		local string addnum$;			# address number as string
		local string streetname$;		# street name
		local string prefix$;			# street direction prefix (e.g. "S", "W")
		local string prefixtext$;		# text for street prefix in search text shown in dialog
		local string streettype$;		# street type (e.g. "ST", "RD");
		local string streettypetext$;	# text for street type in search text shown in dialog
		local string fulladdress$;		# full address
		local numeric streetasnum;		# number returned from street name string (0 if not numbered street)

		#######################################
		### read address values from formdata;
		#######################################

		### get address number and convert to string (to match database)
		addnum$ = NumToStr( int( settings.GetValueNum("addnumfld") ) );

		if (addnum$ == "0") then
			addnum$ = "";

		### get street direction prefix
		prefix$ = settings.GetValueStr("comboPrefix");
		if (prefix$ == "NONE") then
			prefix$ = "";

		### get street name and change to upper case (to match database);
		### remove suffixes such as "nd" and "st" following the number
		### in name of numbered street; 
		streetname$ = toupper$(settings.GetValueStr("streetnamefld") );
		streetasnum = StrToNum(streetname$);	# returns number at beginning of string or 0 if none
		if ( streetasnum > 0) then
			streetname$ = NumToStr(streetasnum);	# convert street number back to string

		### get street type setting
		streettype$ = settings.GetValueStr("comboType");

		###########################################################################################
		### concatenate address components to full address string, omitting empty strings
		##########################################################################################
		if (prefix$ == "ANY") then
			prefixtext$ = "\"Any\"";
		else
			prefixtext$ = prefix$;

		if (streettype$ == "ANY") then
			streettypetext$ = "\"Any\"";
		else
			streettypetext$ = streettype$;

		if (prefix$ == "") then
			fulladdress$ = sprintf("%s %s %s", addnum$, streetname$, streettypetext$);
		else
			fulladdress$ = sprintf("%s %s %s %s", addnum$, prefixtext$, streetname$, streettypetext$);

		#########################################################
		### don't search if no number and street name are entered
		#########################################################
		if ( (addnum$ == "") && (streetname$ == "") )
			{
			statusText.SetValue("Please enter an address number and street.", 0);
			}

		#################################################################################
		### if full address is same as previous, abort search and reshow previous results 
		#################################################################################
		else if ( (fulladdress$ == prevaddress$) && (prevsearchmode == 1) )
			if (count == 0) then
				OnFoundNone();
			else
				OnFound(count);

		################################
		### otherwise do address search
		################################
		else {
			prevsearchmode = 1;
			
			## record current address for comparison on next search
			prevaddress$ = fulladdress$;

			OnNewSearch();
			searchText.SetValue(fulladdress$, 0);

			###################################
			### search through parcel polygons
			###################################
			count = 0;									### reinitialize polygon counter
			ResizeArrayClear(matchRecList, 0);	### reinitialize array holding numbers of matching records
			ResizeArrayClear(propsArray, 0);		### reinitialize array holding found polygon numbers
				
			##############################################################################
			### Narrow down the search from 99,000 records to just the records that
			### match the requested SIT_ST_NUM value using a function that takes advantage
			### of an index on the selected field to speed the search
			##############################################################################
			numRecords = TableKeyFieldLookupList(parcelVector.poly.ParcelAddress, "SIT_ST_NUM", addnum$, possibleRecList);

			######################################################################
			### search through the returned set of records for those that match all
			### components of the requested address
			######################################################################
			for i = 1 to numRecords 
				{
				View.SetStatusBar(i, numRecords);		### update View window's status bar
				record = possibleRecList[i];

				if ( (parcelVector.poly.ParcelAddress[@record].SIT_ST_NUM$ == addnum$) &&
					  (parcelVector.poly.ParcelAddress[@record].SIT_ST_NAM$ == streetname$) )
					{
					if ((prefix$ == "ANY") ||
						 (parcelVector.poly.ParcelAddress[@record].SIT_ST_DIR$ == prefix$) )
						{
						if ((streettype$ == "ANY") ||
							 (parcelVector.poly.ParcelAddress[@record].SIT_ST_TYP$ == streettype$))
							{
							count = count + 1;
							ResizeArrayPreserve(matchRecList, count + 1);		### increase array size for polygon found
							matchRecList[count] = record;								### add polygon number to array
							}
						}
					}
				}

			### call procedure to get polygons corresponding to matching records
			GetPolygons();

			} # end else [new search]
		}	# end if (searchmode == 1)

	####################################################################
	### owner name search; entire name(s) is in single field in database
	####################################################################
	else if (searchmode == 0)
		{

		# string variables for owner name components from form
		local string lastname$, firstname$, middle$;
		local string firstmid$;		# concatenation of first name and middle initial
		local string fullname$;		# full name string (last, firstmid)
		local numeric firstmidlength;		# length of concatenated first name / middle initial
		local numeric numTokens;	# number of tokens in owner name (delimited by space)
		local numeric j;				# counter for looping through tokens in name
		local numeric name_in;		# flag indicating entered first name / middle initial begins one of the name tokens

		local class STRINGLIST tokenList;	# stringlist containing tokens from name

		############################################################
		### read name values from formdata and set all to upper case
		############################################################
		lastname$ = toupper$(settings.GetValueStr("lastnamefld") );
		firstname$ = toupper$(settings.GetValueStr("firstnamefld") );
		middle$ = toupper$(settings.GetValueStr("midintfld") );

		### concatenate middle initial with first name
		if (middle$ <> "") then
			firstmid$ = sprintf("%s %s", firstname$, middle$);
		else
			firstmid$ = firstname$;

		firstmidlength = strlen(firstmid$);		### get length of string to use later in search

		### concatenate lastname and firstmid to use to display search text
		fullname$ = sprintf("%s, %s", lastname$, firstmid$);

		######################################################
		### don't search if no owner name is entered in dialog
		######################################################
		if (fullname$ == ", ")
			{
			statusText.SetValue("Please enter an owner name.", 0);
			}

		#######################################################################
		### if name is same as previous, abort search and show previous results 
		#######################################################################
		else if ( (fullname$ == prevname$) && (prevsearchmode == 0) )
			if (count == 0) then
				OnFoundNone();
			else
				OnFound(count); 

		#############################
		### otherwise do new search
		#############################
		else
			{

			prevsearchmode = 0;

			### record name string for comparison on next search
			prevname$ = fullname$;
			searchText.SetValue(fullname$, 0);

			OnNewSearch();

			####################################
			### search through parcel polygons
			####################################
			count = 0;									### reinitialize polygon counter
			ResizeArrayClear(matchRecList, 0);	### reinitialize array holding numbers of matching records
			ResizeArrayClear(propsArray, 0);		### reinitialize array holding found polygon numbers;

			###############################################################################
			### Narrow down the search from 99,000 records to just the records in which
			### the OWNER string begins with the requested last name.  Uses a function 
			### that takes advantage of an index on the selected field to speed the search
			###############################################################################
			numRecords = TableKeyFieldLookupList(parcelVector.poly.OwnerName, "OWNER", lastname$, possibleRecList, "StartsWith" );

			###########################################################################
			### Now search the returned records for those with a match to the
			### requested name
			###########################################################################
			for i = 1 to numRecords
				{
				local numeric name_in = 0;
				View.SetStatusBar(i, numRecords);	### update View window's status bar
				record = possibleRecList[i];

				### get owner name string from database
				local string name$ = parcelVector.poly.OwnerName[@record].OWNER$;
				local class STRING teststr$;

				if ( GetToken(name$, ",", 1) == lastname$)	### check for exact match with last name (not just starts with)
					{
					numTokens = NumberTokens(name$, ",&");		### number of tokens in owner name with "," and "&" as delimiters

					for j = 2 to numTokens			### loop through tokens following last name
						{
						teststr$ = GetToken(name$, ",&", j);
						teststr$.remove(0, 0);						### remove leading space from test string

						if ( left$( teststr$, firstmidlength) == firstmid$) then
							name_in = 1;
						}
					}

				if (name_in == 1)
					{
					count = count + 1;
					ResizeArrayPreserve(matchRecList, count + 1);		### increase array size for polygon found
					matchRecList[count] = record;								### add polygon number to array
					}
				}

			### call procedure to get polygons corresponding to matching records
			GetPolygons();

			}	# end else do new search
		}	# end else if (searchmode == 0)
	}	# end OnSearch

###################################################################
### called when the Property Search dialog is closed by the Cancel,
### OK, or X Windows "X" button
###################################################################
proc OnClose()
	{
	dlgwin.Close(1);
	View.SetDefaultTool();		# switch to default tool on the View tool bar
	}








Back Home ©MicroImages, Inc. 2008 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

9 May 2008

page update: 14 Aug 07