greatCircleMap.frink

View or download greatCircleMap.frink in plain text format


/** This program demonstrates the use of the country polygons in
    Countries.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

// 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 Countries.frink to be the largest.)
      if firstPolygon
         transformedPolygon = 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]]
      }

      // 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.
      if firstPolygon
      {
         area = polygonArea[transformedPolygon]
         [cx, cy] = polygonCentroid[transformedPolygon]
         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]
}


View or download 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 17989 days, 12 hours, 19 minutes ago.