' Name: View.Graticule ' ' Title: Creates Graticules, Tics, and Labels for a View ' ' Topics: Views, Graphics ' ' Description: This script offers several options for placing graticules ' and tics on a View. You may specify the interval between each ' graticule line or between each tic mark. ' ' Requires: The View must be projected. ' ' Self: ' ' Returns: theView = av.getactivedoc theGraphics = theView.GetGraphics ' get view projection information thisPrj=theView.GetProjection if (thisPrj.IsNull) then MsgBox.Error("The view must be projected."+NL+ "Unable to create graticule.","") exit end theChoice = MsgBox.ListAsString({ "Lat-Long Labels Only", "Lat-Long Graticule with Labels", "XY Grid with Labels", "Lat-Long Labels & XY Grid", "All Graticules and grids" }, "Select Graticule/Grid Type:","") if (theChoice = "Lat-Long Labels Only") then doLatLongs = true doGraticule = false doXYGrid = false elseif (theChoice = "Lat-Long Graticule with Labels") then doLatLongs = true doGraticule = true doXYGrid = false elseif (theChoice = "XY Grid with Labels") then doLatLongs = false doGraticule = false doXYGrid = true elseif (theChoice = "Lat-Long Labels & XY Grid") then doLatLongs = true doGraticule = false doXYGrid = true elseif (theChoice = "All Graticules and grids") then doLatLongs = true doGraticule = true doXYGrid = true else exit end ' Display window (in inches) ' XY window xyRect = theView.GetDisplay.ReturnVisExtent xyOrigin = xyrect.ReturnOrigin xySize = xyrect.ReturnSize dOrigin = xyOrigin dSize = xyrect.returnsize ' This is how to translate a point from map coords to page coords 'aPt = dOrigin + ( ((p - xyOrigin) / xySize) * dSize) xMin = xyOrigin.GetX yMin = xyOrigin.GetY xMax = xMin + xySize.GetX yMax = yMin + xySize.GetY if ( doLatLongs ) then 'work out the lat/long graticule 'get the lat/long limits of the boundary point1=Point.Make(xMin,yMin) point2=Point.Make(xMax,yMin) point3=Point.Make(xMax,yMax) point4=Point.Make(xMin,yMax) point5=Point.Make((xMin+(xMax-xMin)/2),yMin) point6=Point.Make(xMax,(yMin+(yMax-yMin)/2)) point7=Point.Make((xMin+(xMax-xMin)/2),yMax) point8=Point.Make(xMin,(yMin+(yMax-yMin)/2)) 'unproject the limits thisPrj.UnProjectPt(point1) thisPrj.UnProjectPt(point2) thisPrj.UnProjectPt(point3) thisPrj.UnProjectPt(point4) thisPrj.UnProjectPt(point5) thisPrj.UnProjectPt(point6) thisPrj.UnProjectPt(point7) thisPrj.UnProjectPt(point8) 'find the min/max lat/long limits based on user input ' the limits are the nearest multiple of the graticule spacing ' inside of the user rectangle minlon=(Point1.GetX)Min(Point4.GetX)Min(Point8.GetX)Max(-180) minlat=(Point1.GetY)Min(Point2.GetY)Min(Point5.GetY)Max(-90) maxlon=(Point2.GetX)Max(Point3.GetX)Max(Point6.GetX)Min(180) maxlat=(Point3.GetY)Max(Point4.GetY)Max(Point7.GetY)Min(90) minLength = (maxlon-minlon) Min (maxlat-minlat) llIntervals = { 60,30,20,10,5,2,1,0.5,0.3333333333,0.25,0.1666666666, 0.08333333333,0.03333333333,0.01666666666 } rawInterval = minLength / 3 ' 3 is the default number of lines theInterval = llIntervals.Get( llIntervals.Count - 1 ) for each val in llIntervals if (rawInterval >= val) then theInterval = val break end end deg=theInterval.Abs.Truncate t= ( theInterval.Abs - deg ) * 60 minute=t.Truncate sec= (t-minute) * 60 sec= sec.Truncate ' degList= {"Longitude interval","Latitude interval"} ' degDef = {theInterval.AsString,theInterval.AsString} degList = {"Degrees","Minutes","Seconds"} degDef = { deg.AsString, minute.AsString, sec.AsString } degIntList=MsgBox.MultiInput( "Specify Latitude/Longitude Interval", "",degList,degDef) if (degIntList.Count = 0) then exit end ' latInterval = degIntList.Get(1).AsNumber ' lonInterval = degIntList.Get(0).AsNumber lonInterval = degIntList.Get(0).AsNumber + ( degIntList.Get(1).AsNumber / 60) + ( degIntList.Get(2).AsNumber / 3600) latInterval = lonInterval end 'if metres was selected, prompt for the metres intervals if ( doXYGrid ) then minLength = xySize.GetX Min xySize.GetY xyIntervals = { 20000000,10000000,5000000,2000000,1000000,500000,200000, 100000,50000,20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1 } rawInterval = minLength / 4 ' 4 is the default number of lines theInterval = xyIntervals.Get( xyIntervals.Count - 1 ) for each val in xyIntervals if (rawInterval >= val) then theInterval = val break end end ' metresList = {"Easting interval","Northing Interval"} ' metresDef = {theInterval.AsString,theInterval.AsString} ' metresIntList=MsgBox.MultiInput("Specify Metres Intervals:", ' "Metres Graticule", metresList, metresDef) ' if (metresIntList.Count = 0) then ' exit ' end metresInt = MsgBox.Input( "Specify XY Grid Interval (in meters)", "", theInterval.AsString ) if ( metresInt = nil ) then exit end ' gratdx=metresIntList.Get(0).AsNumber ' gratdy=metresIntList.Get(1).AsNumber gratdx = metresInt.AsNumber gratdy = gratdx 'get the metres limits of the graticule, based on user input ' the limits are the nearest multiple of the graticule spacing ' inside of the user rectangle gratxs=(xMin/gratdx).Floor * gratdx - gratdx gratys=(yMin/gratdy).Floor * gratdy - gratdy gratxe=(xMax/gratdx).Ceiling * gratdx + gratdx gratye=(yMax/gratdy).Ceiling * gratdy + gratdy end ' Add the graticule(s) and labels as graphic objects ' Make some symbols that don't yet exist geolfont=Font.MakeStandard(#FONT_TIME) geolSymbol=TextSymbol.Make geolSymbol.SetFont(geolfont) geolSymbol.SetColor(Color.GetBlack) geolsymbol.SetSize(10) theView.getDisplay.HookUpSymbol(geolsymbol) xyfont=Font.MakeStandard(#FONT_COUR) xySymbol=TextSymbol.Make xySymbol.SetFont(xyfont) xySymbol.SetColor(Color.GetBlack) xysymbol.SetSize(8) theView.getDisplay.HookUpSymbol(xysymbol) blackLine=Symbol.Make(#SYMBOL_PEN) blackLine.SetColor(Color.GetBlack) theView.getDisplay.HookUpSymbol(blackLine) thickblackLine=Symbol.Make(#SYMBOL_PEN) thickblackLine.SetColor(Color.GetBlack) thickblackLine.SetSize(2) theView.getDisplay.HookUpSymbol(thickBlackLine) gratLine=Symbol.Make(#SYMBOL_PEN) gratLine.SetColor(Color.GetBlack) gratLine.SetSize(0.01) theView.getDisplay.HookUpSymbol(gratLine) ' Draw the border ... dRect = Rect.Make( dOrigin, dSize ) theBorder = GraphicShape.Make( dRect) theGraphics.Add( theBorder ) theBorder.SetSymbol(thickblackline) 'Draw the lat/long graticule, with labels all around ' Collect graticule lines clipped to the window if ( doLatLongs ) then if ( latInterval < 2 ) then latStart = (minlat - latInterval).Floor latEnd = (maxlat + latInterval).Ceiling else ' If latInterval is "big" generate lats from the world latStart = -90 latEnd = 90 end if ( lonInterval < 2 ) then lonStart = (minlon - lonInterval).Floor lonEnd = (maxlon + lonInterval).Ceiling else ' If lonInterval is "big" generate lons from the world lonStart = -180 lonEnd = 180 end latList = {} for each lat in latStart .. latEnd by latInterval aLine = Line.Make( lonStart@lat, lonEnd@lat ) prjLine = aLine.ReturnProjected( thisPrj ).ReturnClipped( xyRect ) if ( prjLine <> nil ) then latList = latList.Add( {lat, prjLine} ) end end lonList = {} for each lon in lonStart .. lonEnd by lonInterval aLine = Line.Make( lon@latStart, lon@latEnd ) prjLine = aLine.ReturnProjected( thisPrj ).ReturnClipped( xyRect ) if ( prjLine <> nil ) then lonList = lonList.Add( {lon, prjLine} ) end end for each aList in latList lat = aList.Get(0) prjLine = aList.Get(1) if ( doGraticule ) then gPolyLine = {} for each ptList in prjLine.AsList gPtList = {} for each aPt in ptList thePt = dOrigin + ( ((aPt - xyOrigin) / xySize) * dSize) gPtList = gPtList.Add( thePt ) end gPolyLine = gPolyLine.Add( gPtList ) end theGratLine = GraphicShape.Make( PolyLine.Make(gPolyLine) ) thegratLine.setobjecttag("theGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) end for each ptList in prjLine.AsList for each endPt in { ptList.Get(0), ptList.Get(ptList.Count-1) } ' Make a latitude label deg=lat.Abs.Truncate labelString = deg.AsString+"—" t = ( lat.Abs - deg ) * 60 minute=t.Truncate if ( (t - minute) >= 0.9998 ) then minute = minute + 1 end if ( minute > 0 ) then labelString = labelString+minute.AsString+"'" end if ( (t - minute) > 0.0002 ) then sec= (t-minute) * 60 sec= sec.Truncate labelString=deg.AsString++minute.AsString+"'"+sec.AsString if(sec<1) then labelString=deg.AsString++minute.AsString+"'00" end end ' ... put latitude label aPt = dOrigin + ( ((endPt - xyOrigin) / xySize) * dSize) mygText=GraphicText.Make(labelString,aPt) mygText.setobjecttag("mygText") theGraphics.Addbatch(mygText) mygText.SetSymbol(geolsymbol) gpoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gpoint2.GetClass) if ( aPt.GetX = dRect.GetLeft ) then theGratLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) ) theGratLine.setobjecttag("theGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt - (0.1@0)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(90) tph.setHAlign(#TEXTPOSITIONER_HALIGN_LEFT) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) elseif ( aPt.GetX = dRect.GetRight ) then theGratLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) ) theGratLine.setobjecttag("theGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt + (0.1@0)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(-90) tph.setHAlign(#TEXTPOSITIONER_HALIGN_RIGHT) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) elseif ( aPt.GetY = dRect.GetBottom ) then theGratLine = GraphicShape.Make( Line.Make( aPt-(0@0.05), aPt ) ) theGratLine.setobjecttag("theGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(0) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_BELOW) elseif ( aPt.GetY = dRect.GetTop ) then theGratLine = GraphicShape.Make( Line.Make( aPt+(0@0.05), aPt ) ) theGratLine.setobjecttag("theGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt + (0@0.1)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(0) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ABOVE) end tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate end end end for each aList in lonList lon = aList.Get(0) prjLine = aList.Get(1) if ( doGraticule ) then gPolyLine = {} for each ptList in prjLine.AsList gPtList = {} for each aPt in ptList thePt = dOrigin + ( ((aPt - xyOrigin) / xySize) * dSize) gPtList = gPtList.Add( thePt ) end gPolyLine = gPolyLine.Add( gPtList ) end theGratLine = GraphicShape.Make( PolyLine.Make(gPolyLine) ) thegratline.setobjecttag("ThegratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) end for each ptList in prjLine.AsList for each endPt in { ptList.Get(0), ptList.Get(ptList.Count-1) } ' Make a longitude label deg=lon.Abs.Truncate labelString = deg.AsString+"—" t= ( lon.Abs - deg ) * 60 minute=t.Truncate if ( (t - minute) >= 0.9998 ) then minute = minute + 1 end if ( minute > 0 ) then labelString = labelString+minute.AsString+"'" end if ( (t - minute) > 0.0002 ) then sec= (t-minute) * 60 sec= sec.Truncate labelString=deg.AsString++minute.AsString+"'"+sec.AsString if(sec<1) then labelString=deg.AsString++minute.AsString+"'00" end end ' ... put longitude label aPt = dOrigin + ( ((endPt - xyOrigin) / xySize) * dSize) mygText=GraphicText.Make(labelString,aPt) mygText.setobjecttag("mygtext") theGraphics.Addbatch(mygText) mygText.SetSymbol(geolsymbol) if ( aPt.GetX = dRect.GetLeft ) then theGratLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) ) theGratLine.setobjecttag("TheGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt - (0.1@0)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(90) tph.setHAlign(#TEXTPOSITIONER_HALIGN_LEFT) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) elseif ( aPt.GetX = dRect.GetRight ) then theGratLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) ) theGratLine.setobjecttag("TheGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt + (0.1@0)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(-90) tph.setHAlign(#TEXTPOSITIONER_HALIGN_RIGHT) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) elseif ( aPt.GetY = dRect.GetBottom ) then theGratLine = GraphicShape.Make( Line.Make( aPt-(0@0.05), aPt ) ) theGratLine.setobjecttag("TheGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(0) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_BELOW) elseif ( aPt.GetY = dRect.GetTop ) then theGratLine = GraphicShape.Make( Line.Make( aPt+(0@0.05), aPt ) ) theGratLine.setobjecttag("TheGratLine") theGraphics.Addbatch( theGratLine ) theGratLine.SetSymbol( gratLine ) gPoint2 = GraphicShape.Make(aPt + (0@0.1)) tph=TextPositioner.Make(gPoint2.GetClass) mygText.SetAngle(0) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ABOVE) end tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate end end ' of foreach in prjLine end ' of foreach in lonList end ' of if (doLatLongs) if ( doXYGrid ) then 'Draw metres graticule as lines, with coordinates all around ' vertical lines xoffset = 0.0625@0 yoffset = 0@0.0625 for each x in gratxs .. gratxe by gratdx if ( (x < xMin) or (x > xMax) ) then continue end for each y in gratys .. gratye by gratdy if ( (y < yMin) or (y > yMax) ) then continue end aPt = dOrigin + ( ((x@y - xyOrigin) / xySize) * dSize) aPolyLine = PolyLine.Make( { { aPt-xoffset, aPt+xoffset, aPt, aPt-yoffset, aPt+yoffset } } ) ggLine = aPolyLine.ReturnClipped( dRect ) gLine = GraphicShape.Make( ggLine ) gline.setobjecttag("gline") theGraphics.Addbatch( gLine ) gLine.SetSymbol(blackline) end end for each x in gratxs .. gratxe by gratdx if ( (x < xMin) or (x > xMax) ) then continue end ' put easting label at ymax aPt = dOrigin + ( ((Point.Make(x,yMax) - xyOrigin) / xySize) * dSize) gLine = GraphicShape.Make( Line.Make( aPt, aPt-(0@0.05) ) ) gline.setobjecttag("gline") theGraphics.Addbatch( gLine ) gLine.SetSymbol( blackLine ) aPt = aPt + Point.Make(0,0.02) mygText=GraphicText.Make(x.SetFormat("dddddd").AsString, aPt) mygText.setobjecttag("mygText") theGraphics.Addbatch(mygText) mygText.SetSymbol(xySymbol) gPoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gPoint2.GetClass) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_TOP) tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate ' put easting label at ymin aPt = dOrigin + ( ((Point.Make(x,yMin) - xyOrigin) / xySize) * dSize) gLine = GraphicShape.Make( Line.Make( aPt, aPt+(0@0.05) ) ) gLine.setobjecttag("gLine") theGraphics.Addbatch( gLine ) gLine.SetSymbol( blackLine ) mygText=GraphicText.Make(x.SetFormat("dddddd").AsString, aPt) mygText.setobjecttag("mygText") theGraphics.Addbatch(mygText) mygText.SetSymbol(xySymbol) gPoint2 = GraphicShape.Make(aPt + (0@0.02)) tph=TextPositioner.Make(gPoint2.GetClass) tph.setHAlign(#TEXTPOSITIONER_HALIGN_CENTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate end ' of for each x for each y in gratys .. gratye by gratdy ' horizontal lines if ( (y < yMin) or (y > yMax) ) then continue end ' put northing label at xmin aPt = dOrigin + ( ((Point.Make(xMin,y) - xyOrigin) / xySize) * dSize) gLine = GraphicShape.Make( Line.Make( aPt+(0.05@0), aPt ) ) gLine.setobjecttag("gLine") theGraphics.Addbatch( gLine ) gLine.SetSymbol( blackLine ) aPt = aPt - Point.Make(0.02,0) mygText=GraphicText.Make(y.SetFormat("ddddddd").AsString, aPt ) mygtext.setobjecttag("mygtext") theGraphics.Addbatch(mygText) mygText.SetSymbol(xySymbol) mygText.SetAngle(90) gPoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gPoint2.GetClass) tph.setHAlign(#TEXTPOSITIONER_HALIGN_BEFORE) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate ' put northing label at xmax aPt = dOrigin + ( ((Point.Make(xMax,y) - xyOrigin) / xySize) * dSize) gLine = GraphicShape.Make( Line.Make( aPt-(0.05@0), aPt ) ) gLine.setobjecttag("gLine") theGraphics.Addbatch( gLine ) gLine.SetSymbol( blackLine ) aPt = aPt + Point.Make(0.02,0) mygText=GraphicText.Make(y.SetFormat("ddddddd").AsString, aPt) mygtext.setobjecttag("mygtext") theGraphics.Addbatch(mygText) mygText.SetSymbol(xySymbol) mygText.SetAngle(-90) gPoint2 = GraphicShape.Make(aPt) tph=TextPositioner.Make(gPoint2.GetClass) tph.setHAlign(#TEXTPOSITIONER_HALIGN_AFTER) tph.setVAlign(#TEXTPOSITIONER_VALIGN_ON) tph.Calculate(gPoint2.GetShape,mygText.GetExtent,0,nil) mygText.SetOrigin(tph.GetOrigin) mygText.Invalidate end ' of foreach y end ' of if (doXYGrid) thegraphics.endbatch for each agraphic in thegraphics agraphic.setselected(false) end if (nil<>thegraphics.findbyobjecttag("mygText")) then for each agraphic in thegraphics.findallbyobjecttag("mygtext") agraphic.setselected(true) agraphic.setobjecttag(nil) end thegraphics.groupselected for each agraphic in thegraphics agraphic.setselected(false) end end if (nil<>thegraphics.findbyobjecttag("theGratLine")) then for each agraphic in thegraphics.findallbyobjecttag("theGratline") agraphic.setselected(true) agraphic.setobjecttag(nil) end thegraphics.groupselected for each agraphic in thegraphics agraphic.setselected(false) end end if (nil<>thegraphics.findbyobjecttag("gline")) then for each agraphic in thegraphics.findallbyobjecttag("gline") agraphic.setselected(true) agraphic.setobjecttag(nil) end thegraphics.groupselected for each agraphic in thegraphics agraphic.setselected(false) end end theGraphics.Invalidate