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 19963 days, 20 hours, 43 minutes ago.