' Name: JuanitaPieGraphicsShape
'
' Title: Draw sector-pie graphical symbols from water quality data
'
' Topics: Views
'
' Description: Reads median chemical data from a file created outside
' ArcView, and plots Juanita Pie symbols at the monitoring points based on compliance
' with water quality guidelines. Originally an AML written by Juanita Moolman
' Institute for Water Quality Studies, Department of Water and Sanitation
' Private Bag X313 PRETORIA South Africa 0001
' MoolmanJ@dwaf.gov.za - Reworked for Avenue.
'
' Author: Michael Silberbauer 2001-03-12
'
' Requires: A View, a data file
'
' Self:
'
' Results:
' -----------------------------------------------------------------------------
theView = av.GetActiveDoc
theDisplay = theView.GetDisplay
thePrj = theView.GetProjection
' Get the GraphicList for the View...
theGraphics = theView.GetGraphics
' Return the extent (the enclosing rectangle) of the View:
theMapExtent = theView.GetDisplay.ReturnVisExtent
' Extract the dimensions of the View from the extent:
'+----------------------------+x2m,y2m
'| |
'| |
'| |
'| |ywm
'| |
'| |
'| |
'+----------------------------+
'x1m,y1m xwm
theLowerLeft = theMapExtent.ReturnOrigin
x1m = theLowerLeft.Getx
y1m = theLowerLeft.Gety
xwm = theMapExtent.GetWidth
ywm = theMapExtent.GetHeight
x2m = x1m+xwm
y2m = y1m+ywm
theUpperRight = x2m@y2m
y = 1
x = y*(xwm/ywm)
theDiagonal = ((x^2)+(y^2)).sqrt
'Scale = theDiagonal / 100
Scale = (x2m-x1m)/50
UseTypeList = ({"Domestic_Health","Domestic_Salts","Irrigation"})
UseMissing = MsgBox.YesNo("Use incomplete records (can be very cluttered) ?","JuanitaPie: Missing Records",FALSE)
LblSymbol = MsgBox.YesNo("Label symbols with variable names (only for key) ?","JuanitaPie: Label Symbols",FALSE)
IDSymbol = MsgBox.YesNo("Label symbols with station names ?","JuanitaPie: ID Symbols",FALSE)
UseType = MsgBox.ListAsString(UseTypeList,"Please choose a use type","Juanita Pie: Choose use type")
if (UseType="Domestic_Health") then
' Allocate colours to the various components:
theColourDict = Dictionary.Make(256)
theColourDict.Add("medpH",{1,2,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medNO3(N)",{2,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medNH4(N)",{3,1,3,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medFluoride",{4,1,8,000,000,255,000,255,000,255,255,000,255,000,000,220,000,000,190,000,000,155,000,000,125,000,000,255,000,255})
theColourDict.Add("medTDS",{5,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medTurbidity",{6,1,3,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
'Set constants (type 1 quality decreases with concentration
' type 2 quality is best in the middle range)
'Use Dictionary (Keys: constituent, type of quality (e.g 2=pH or 1=other),
' number of breakpoints, breakpoints)
UseVariables = Dictionary.Make(256)
UseVariables.Add("medpH",{1,2,4,4.0,6.0,9.0,11.0})
UseVariables.Add("medNO3(N)",{2,1,4,3.0,6.0,10.0,20.0})
UseVariables.Add("medNH4(N)",{3,1,3,1.0,2.0,10.0})
UseVariables.Add("medFluoride",{4,1,8,1.0,1.5,3.5,4.0,6.0,8.0,100,2000})
UseVariables.Add("medTDS",{5,1,4,450,1000,2000,3000})
UseVariables.Add("medTurbidity",{6,1,3,1.0,5.0,10.0})
end
if (UseType="Domestic_Salts") then
' Allocate colours to the various components:
theColourDict = Dictionary.Make(256)
theColourDict.Add("medChloride",{1,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medSulphate",{2,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medMagnesium",{3,1,6,000,000,255,000,255,000,255,255,000,255,000,000,220,000,000,190,000,000,255,000,255})
theColourDict.Add("medCalcium",{4,1,2,000,000,255,255,000,000,255,000,255})
theColourDict.Add("medSodium",{5,1,6,000,000,255,000,255,000,255,255,000,255,000,000,220,000,000,190,000,000,255,000,255})
theColourDict.Add("medPotassium",{6,1,3,000,000,255,255,255,000,255,000,000,255,000,255})
'Set constants (type 1 quality decreases with concentration
' type 2 quality is best in the middle range)
'Use Dictionary (Keys: constituent, type of quality (e.g 2=pH or 1=other),
' number of breakpoints, breakpoints)
UseVariables = Dictionary.Make(256)
UseVariables.Add("medChloride",{1,1,4,100,200,600,1200})
UseVariables.Add("medSulphate",{2,1,4,200,400,600,1000})
UseVariables.Add("medMagnesium",{3,1,6,30,50,70,100,200,400})
UseVariables.Add("medCalcium",{4,1,2,32,80})
UseVariables.Add("medSodium",{5,1,6,100,200,400,600,1000,5000})
UseVariables.Add("medPotassium",{6,1,3,50,100,400})
end
if (UseType=nil) then
MsgBox.Info("Nothing selected","Juanita Pies EXIT")
return nil
end
if (UseType="Irrigation") then
' Allocate colours to the various components:
theColourDict = Dictionary.Make(256)
theColourDict.Add("medSAR",{1,1,3,000,000,255,000,255,000,255,000,000,255,000,255})
theColourDict.Add("medChloride",{2,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medConductivity",{3,1,4,000,000,255,000,255,000,255,255,000,255,000,000,255,000,255})
theColourDict.Add("medBoron",{4,1,6,000,000,255,000,255,000,255,255,000,255,000,000,220,000,000,190,000,000,255,000,255})
theColourDict.Add("medpH",{5,3,2,000,000,255,255,000,000,255,000,255})
'Set constants (type 1 quality decreases with concentration
' type 2 quality is best in the middle range)
'Use Dictionary (Keys: constituent, type of quality (e.g 2=pH or 1=other),
' number of breakpoints, breakpoints)
UseVariables = Dictionary.Make(256)
UseVariables.Add("medSAR",{1,1,3,2,8,15})
UseVariables.Add("medChloride",{2,1,4,100,175,350,700})
UseVariables.Add("medConductivity",{3,1,4,40,90,270,540})
UseVariables.Add("medBoron",{4,1,6,0.5,1,2,4,6,15})
UseVariables.Add("medpH",{5,3,2,6.5,8.4})
end
if (UseType=nil) then
MsgBox.Info("Nothing selected","Juanita Pies EXIT")
return nil
end
UseKeys = UseVariables.ReturnKeys
nPetals = 0
for each key in UseKeys
nPetals = nPetals+1
end
pi = Number.GetPi
angrad = pi/180
Radius = 1
theProject = av.getProject
if (LblSymbol) then
theTable = theProject.FindDoc("keydata.txt")
theTable = theProject.FindDoc("keytestdata.txt")
else
theTable = theProject.FindDoc("olifants_data.txt")
end
theVTab = theTable.getVTab
numrecs = theVTab.GetNumRecords
FieldList = theVTab.GetFields
shortlist = List.Make
for each fieldname in FieldList
if (fieldname.asString.Left(3)="med") then
shortlist.Add(fieldname)
'MsgBox.Info( fieldname.AsString, "FIELD" )
end
end
'selfields = MsgBox.MultiListAsString( shortlist, "Choose fields (Shift to select many)", "SELECT FIELDS TO PLOT" )
'if( selfields = nil ) then
' MsgBox.Info( "NO FIELDS SELECTED", "Stopping execution" )
' return nil
'else
' nPetals = selfields.count
' MsgBox.Info( nPetals.AsString, "Number of petals" )
'end
av.ShowStopButton
av.ShowMsg("Starting process...")
for each record in theVTab
'for each record in 1 .. 10
theField = theVtab.FindField("Station")
station = theVtab.ReturnValue(theField,record)
theField = theVtab.FindField("Latitude")
lat = theVtab.ReturnValue(theField,record)
theField = theVtab.FindField("Longitude")
lon = theVtab.ReturnValue(theField,record)
theField = theVtab.FindField("Station")
station = theVtab.ReturnValue(theField,record)
theGraphicGroup = GraphicGroup.Make
geopoint = Point.Make(lon,lat)
prjpoint = geopoint.ReturnProjected(thePrj)
xSymbol = prjpoint.GetX
ySymbol = prjpoint.GetY
ItemsList = List.Make
ClassList = List.Make
SeqnsList = List.Make
ValueList = List.Make
classtring = station
Valid = true
if (UseMissing.Not) then
'Check that all the values required for the symbol are available:
for each fieldname in FieldList
if (fieldname.asString.Left(3)="med") then
for each key in UseKeys
if (fieldname.asString=key.AsString) then
keyList = UseVariables.Get(key)
theField = theVTab.FindField(key)
theValue = theVtab.ReturnValue(theField,record)
if (theValue<0) then
Valid = false
end
end
end
end
end
end
if (Valid) then
for each fieldname in FieldList
if (fieldname.asString.Left(3)="med") then
for each key in UseKeys
if (fieldname.asString=key.AsString) then
keyList = UseVariables.Get(key)
theField = theVTab.FindField(key)
theValue = theVtab.ReturnValue(theField,record)
seqnum = keyList.Get(0)
type = keyList.Get(1)
ncuts = keyList.Get(2)
ncutsn = ncuts+2
if (theValue<0) then
'Set the class to "missing" (-1):
class = -1
end
'Match the value to the cutpoints:
if (type=1) then
if (theValue>=0) then
class = 0
end
class = ncuts
for each ncut in ncutsn..3 by -1 'why must arrays start at 0?!
cutpoint = keyList.Get(ncut)
if (theValue<cutpoint) then
class = ncut-3
end
end
end
if (type=2) then ' the tricky case of domestic pH:
if (theValue>=0) then
class = 0
end
cutpoint1 = keyList.Get(4)
cutpoint2 = keyList.Get(5)
if ((theValue>cutpoint1) and (theValue<cutpoint2)) then
class = 0
end
cutpoint3 = keyList.Get(3)
cutpoint4 = keyList.Get(6)
if ((theValue>cutpoint3) and (theValue<=cutpoint1)) then
class = 1
end
if ((theValue>=cutpoint2) and (theValue<cutpoint4)) then
class = 1
end
if ((theValue<=cutpoint3) or (theValue>=cutpoint4)) then
class = 2
end
end
if (type=3) then ' the tricky case of agricultural pH:
if (theValue>=0) then
class = 0
end
cutpoint1 = keyList.Get(3)
cutpoint2 = keyList.Get(4)
if ((theValue>cutpoint1) and (theValue<cutpoint2)) then
class = 0
end
if ((theValue<=cutpoint1) or (theValue>=cutpoint2)) then
class = 1
end
end
if (class>0) then
'MsgBox.Info( key.AsString++"="++class.AsString++"("++theValue.AsString++")", station )
end
if (theValue<0) then
'Set the class to "missing" (-1):
class = -1
end
classtring = classtring++key.AsString++"="++class.AsString
ClassList.Add(class)
ItemsList.Add(key)
SeqnsList.Add(seqnum)
ValueList.Add(theValue)
end
end
end
end
nowDate = Date.Now
nowDate.SetFormat("yyyy-MM-dd")
nowTime = Date.Now
nowTime.SetFormat("hhhh:m:s")
dtStamp = nowDate.asString++" "++nowTime.AsString
av.SetStatus(100*(record/numrecs))
av.ShowMsg(dtStamp++record.AsString++classtring)
' Calculate the dimensions of the Juanita pie diagram:
XCentre = 0.0
YCentre = 0.0
PetAngle = 360/nPetals
TotalArea = pi*Radius^2
SegmentArea = TotalArea/nPetals
'Calculate a constant base area:
BaseArea = SegmentArea/4
BaseRadius = (BaseArea/pi).sqrt
xcirc = (XCentre*Scale)+xSymbol
ycirc = (YCentre*Scale)+ySymbol
RadiusCirc = BaseRadius*Scale
aCircle = Circle.Make(xcirc@ycirc,RadiusCirc)
gCircle = GraphicShape.Make(aCircle)
aSymbol = RasterFill.Make
aSymbol.SetColor(Color.GetWhite)
aSymbol.SetOLColor(Color.GetBlack)
gCircle.SetSymbol(aSymbol)
gCircle.SetObjectTag("JuanitaPie")
theGraphicGroup.Add(gCircle)
Petal = 0
for each ClassValue in ClassList
Petal = Petal+1
if (ClassValue>=0) then
Item = ItemsList.Get(Petal-1)
Value_item = ValueList.Get(Petal-1)
AngNum = SeqnsList.Get(Petal-1)
NumClasses = UseVariables.Get(Item).Get(2)
Type = UseVariables.Get(Item).Get(1)
SeqNum = UseVariables.Get(Item).Get(0)
'
if (ClassValue=0) then
ItmArea = BaseArea
ItmRadius = BaseRadius
else
ItmArea = (SegmentArea-BaseArea)*((ClassValue+1)/(NumClasses/Type))
ItmArea = BaseArea+ItmArea
ItmRadius = (ItmArea/pi).sqrt
end
StartAngle = SeqNum*PetAngle
'MsgBox.Info( Value_item.AsString++"Class"++ClassValue.AsString,Petal.AsString++Item.AsString++StartAngle.AsString++"?" )
AngList = List.Make
nvs = 4
for each nv in 0..nvs
AngList.Add(StartAngle+(PetAngle*(nv/nvs)))
end
theVtxList = List.Make
theVtxList.Add(xcirc@ycirc)
for each angvalue in AngList
theVtxX = ItmRadius*(angrad*angvalue).cos
xv = (theVtxX*Scale)+xSymbol
theVtxY = ItmRadius*(angrad*angvalue).sin
yv = (theVtxY*Scale)+ySymbol
theVtxList.Add(xv@yv)
end
theVtxList.Add(xcirc@ycirc)
mPol = polygon.Make({theVtxList})
gmPol = GraphicShape.Make(mPol)
aSym = RasterFill.Make
ColIndx1 = (ClassValue+1)*3
ColIndx2 = ColIndx1+1
ColIndx3 = ColIndx1+2
Rval1 = theColourDict.Get(Item).Get(ColIndx1)
Rval2 = theColourDict.Get(Item).Get(ColIndx2)
Rval3 = theColourDict.Get(Item).Get(ColIndx3)
aCol = Color.Make
aCol.SetRGBList({Rval1,Rval2,Rval3})
aSym.SetColor(aCol)
gmPol.SetSymbol(aSym)
theGraphicGroup.Add(gmPol)
if (LblSymbol) then
ItemText = GraphicText.Make(Item,theVtxList.Get((theVtxList.Count/2).round-1))
ItemAngle = StartAngle+(PetAngle*0.5)
if ((ItemAngle<270) and (ItemAngle>90)) then
ItemAngle = ItemAngle+180
end
if (ItemAngle>360) then
ItemAngle = ItemAngle-360
end
ItemText.SetAngle(ItemAngle)
ItemText.SetObjectTag("JuanitaPie")
ItemSymbol = ItemText.ReturnSymbols.Get(0)
ItemSymbol.SetSize(10)
theGraphics.Add(ItemText)
end
'theGraphics.Invalidate
end
end
if (IDSymbol) then
IDText = GraphicText.Make(station.AsString.Left(6),xcirc@ycirc)
IDTextSymbol = IDText.ReturnSymbols.Get(0)
IDTextSymbol.SetSize(4)
theGraphicGroup.Add(IDText)
end
theGraphicGroup.SetObjectTag("JuanitaPie")
theGraphics.Add(theGraphicGroup)
theGraphics.Invalidate
end
end
av.ClearMsg
av.ClearStatus
theGraphics.Invalidate