How can I determine where points are most dense on my pin map via MapViewer automation?

This article contains a sample script for determining the average distance between point for each area on a map.

To run this script:

  1. Copy the script below, or click here to download the BAS file: Density_of_Points.BAS.
  2. In a Windows Explorer window, navigate to C:\Program Files\Golden Software\MapViewer 8\Scripter.
  3. Double click on Scripter.exe to launch Scripter.
  4. Press Ctrl+A to select all of the existing lines then press Delete.
  5. If you copied this script, press Ctrl+V to paste it into Scripter. If you downloaded it, click File | Open, select the BAS file from your downloads directory, and click Open.
  6. Click Script | Run to run the script.


' Density_of_Points.BAS
' Copyright (C) Golden Software Inc. 1992-2018
' This script demonstrates how to determine the average distance between pin map points for each area
Sub Main

'Clears the Immediate pane so you can run this script many times in a row without cluttering up your Immediate pane.

'Initializes MapViewer
 Dim mvapp, Plot, Wks, WksRange, WksRange0, Stats, Stats0 As Object
 Set mvapp = CreateObject("MapViewer.Application")
 mvapp.Visible = True
 Set Plot = mvapp.Documents.Add(mvDocPlot)

 'Initializes arrays that we'll save different information to. For the ptpid and areapids, instead of 1000 use the maximum number of points that is in any of your areas.
 Dim avgdist () As Double
 Dim ptpid(1000) As Variant
 Dim areapids(1000) As Variant

'Sets the file path for input files
 InPath$ = mvapp.ApplicationFolder + "\Samples\"

'Create a base map
 Set BaseMap = Plot.CreateBaseMap(FileName:= InPath$+"us48alb.gsb", Options:= "PrimaryIDField=2, SecondaryIDField=1")

'Create a pin map
 Set PinMap = Plot.CreatePinMap( DataFileName:=InPath$+"uscity.dat", LocatingMethod:= mvPinLocCoordinates, PIDCol:=2, XCol:=3, YCol:=4)

'Selects all the points and swaps the PID and SID
Plot.Layers.Item(1).Shapes.SelectByType(Area:=False, Point:=True)
Set Selection0 = Plot.Layers.Item(1).Selection
Selection0.RedefineAttributes2(SIDField:=mvAttribTypePID, PIDField:=mvAttribTypeWksCol, HyperlinkField:=mvAttribTypeHyperlink, PIDCol:=1)

'Finds and saves the number of boundaries on Layer #1
Set Selection = Plot.Layers.Item(1).Selection

'Sets the surface distance units of the plot. These are the units the distance will be reported in.
Plot.DistanceUnits = mvDistUnitMiles

'Stores the number of objects on the layer as the variable "NumObj"
NumObj = Selection.Count

'Creates an array that stores the average length for each area
ReDim avgdist(NumObj-1)

'Writes the boundary PIDs to an array for printing later
 For j=0 To NumObj-1
	If Plot.Layers(1).Selection.Item(j+1).Type = mvShapeArea Then
	End If
 Next j

'Initializes an array index counter

'Loop through all boundary objects on Layer #1
For i = 1 To Plot.Layers(1).Shapes.Count

		'Only perform the steps below if the object is an area
		If Plot.Layers(1).Shapes.Item(i).Type = mvShapeArea Then

			'Deselects everything on the layer

			'Selects the first boundary object

			'Performs a query to create a new layer with the points that fall within the selected area
			Plot.Query(Verb:=mvQueryVerbCreateLayer, Region:=mvQuerySelArea, Point:=True, Area:=False)

			'Activates the new layer so the tabulated distance calculation will only use the points on that one layer.
			Set newLayer = Plot.Layers(Plot.Layers.Count)

			'Selects all the points on the new layer

			'Loops through the objects on the new layer. If the object is a point, write the point's PID to the array.
			'This array will be used for the tabulated distance calculation.
			For j=0 To newLayer.Selection.Count-1
				If newLayer.Selection.Item(j+1).Type = mvShapePoint Then
				End If
			Next j

			'Performs Tabulated Distance with the selected points
			Plot.TabulatedDistance(pHorizontalPIDs:=ptpid(), pVerticalPIDs:=ptpid(), SearchPIDInAllLayers:=False)

			'Initializes the sum of the distances to 0.
			sum = 0

			'Initializes the worksheet to the last worksheet view that was opened
			Set Wks = mvapp.Documents.Item(mvapp.Documents.Count)

			'Stores the number of rows
			Set WksRange0 = Wks.Columns(Col1:=2, Col2:=2)
			Set Stats0 = WksRange0.Statistics(Flags:=wksStatsCount)
			numrow = Stats0.Count()

			'Loops through the columns and calculatse the sum of the entries in that column, then adds those sums
			For j=1 To newLayer.Selection.Count
				Set WksRange = Wks.Columns(Col1:=j+1, Col2:=j+1)
				Set Stats = WksRange.Statistics(Flags:=wksStatsSum)
				sum = sum + Stats.Sum()
			Next j

			'Calculates the number of cells that went into the sum calculation
			count = (numrow*numrow-numrow)/2

			'Calculates the average (sum/count) distance for the area. If the count is 0, the average is set to 0 to avoid dividing by 0.
			If count=0 Then
				avgdist(n) = 0
				avgdist(n) = (sum/2)/count
			End If

			'Prints out the average distance and the PID for each area
			Debug.Print "Average distance between points in "+Str(areapids(n))+" = "+Str(avgdist(n))+" mi."

			'Increments the array index counter by 1

			'Deselects the current active layer and resets the active layer to the first layer

		End If

Next i

End Sub


Updated May 22, 2018

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request


Please sign in to leave a comment.