home products news downloads documentation support gallery online maps resellers search
TNTmips Downloads Menu

HOME

CONTACT US

CURRENT RELEASE
  TNT 2013

DEVELOPMENT VERSION
  TNT 2014

TNTmips Pro
PRIOR RELEASES
  TNT 2012

FREE SOFTWARE
  TNTmips Free
  TNTatlas
  TNTsdk

MORE DOWNLOADS
  HASP Key Driver
  Screen Recorder
  TNT Language Kits
  Sample Geodata
  TNT Scripts

DOCUMENTATION
  TNTmips Tutorials
  Tutorial Datasets
  Technical Guides
  Scripts
  Quick Guides

MORE INFO
  Download FAQs
  FTP
  Download Managers
  Find Reseller

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. 2013 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

25 March 2009

page update: 26 May 11