greatCircleMap.frink

Download or view greatCircleMap.frink in plain text format


/** This program demonstrates the use of the country polygons in
    Country.frink to draw a map of the world.  It can be readily altered to
    draw the map in your favorite projection. */


use Country.frink
use geometry.frink
use navigation.frink

g = new graphics
g.stroke[3]

g.color[.8,.9,1]
g.fillEllipseCenter[0, 0, 2 pi earthradius / km , 2 pi earthradius / km]

myLat = 40 degrees North
myLong = 105 degrees West
//myLat = 20.57 degrees South   // Tonga volcano
//myLong = 175.38 degrees West

// Iterate through all countries.
for [code, country] = Country.getCountryList[]
{
   cc = new color[randomFloat[.2,.9], randomFloat[.2,.9], randomFloat[.2,.9], .8]
   firstPolygon = true
   for poly = country.borders  // Iterate through polygons in a country.
   {
      p = new filledPolygon   // This polygon is the filled country
      po = new polygon        // This is the outline of the country

      // Some countries consist of many polygons.  Only label the first one
      // (which is sorted in Country.frink to be the largest.)
      if firstPolygon
      {
         transformedPolygon = new array
         untransformedPolygon = new array
      }
      
      for [long, lat] = poly  // Iterate through points in polygon
      {
         [x,y] = latLongToXY[myLat, myLong, lat degree, long degree]
         p.addPoint[x, y]
         po.addPoint[x, y]

         if firstPolygon
         {
            transformedPolygon.push[[x,y]]
            untransformedPolygon.push[[lat, long]]
         }
      }

      // Draw filled countries
      g.color[cc]
      g.add[p]

      // Draw country outlines
      g.color[0.2,0.2,0.2,.8]
      g.add[po]

      // Draw country names.
      // This now centers names in the nontransformed polygons.
      if firstPolygon
      {
         area = polygonArea[transformedPolygon]
         [cxu, cyu] = polygonCentroid[untransformedPolygon]
         [cx, cy] = latLongToXY[myLat, myLong, cxu degree, cyu degree]
         g.color[0,0,0]
         
         // Do some contortions to try and size the country name
         longestWord = max[map[getFunction["length",1],
                                split[%r/\s+/, country.name]]]
         countryName = country.name =~ %s/\s+/\n/g   // Wrap country name
         g.font["SansSerif", "bold", 6 (sqrt[area] / longestWord)^(0.7)]
         g.text[countryName, cx, cy, arctan[cx,cy] + 180 deg]
         firstPolygon = false
      }
   }
}

// Draw distance circles
g.stroke[6]
g.color[0,0,0]
for distance = 0 km to pi earthradius step 1000 miles
   g.drawEllipseCenter[0, 0, 2 distance / km, 2 distance / km]

// Draw bearing lines
g.font["SansSerif", "bold", 600]
for bearing = 0 degrees to 359 degrees step 10 degrees
{
   x =  pi earthradius sin[bearing] / km
   y = -pi earthradius cos[bearing] / km
   g.line[0, 0, x, y]
   g.text[round[bearing/deg] /* + "\u00B0"*/, x , y, "center", "baseline", -bearing]
}

g.stroke[18]
// Draw single degree ticks
for bearing = 0 to 359
{
   x1 =  pi earthradius sin[bearing degrees] / km
   y1 = -pi earthradius cos[bearing degrees] / km
   x2 =  12000 miles sin[bearing degrees] / km
   y2 = -12000 miles cos[bearing degrees] / km
   g.line[x1, y1, x2, y2]
}

g.show[1]
g.write["greatCircle.svg", 1000, 1000]
g.write["greatCircle.png", 1000, 1000]

latLongToXY[myLat, myLong, lat, long] :=
{
   [distance, bearing] = earthDistanceAndBearing[myLat, myLong, lat, long]
   
   d1 = distance / km
   y = -d1 cos[bearing]
   x = d1 sin[bearing]
   return [x,y]
}


Download or view greatCircleMap.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 19967 days, 3 hours, 27 minutes ago.