Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.FileInputStream
- import java.util.Locale
- import scala.io.Source.fromInputStream
- import java.io._
- import freemarker.template.{Template, TemplateExceptionHandler, Configuration}
- import org.apache.commons.dbcp.BasicDataSource
- import org.scala_tools.javautils.Implicits._
- val DB_USER = "root"
- val DB_PASSWORD = ""
- val DB_URL = "jdbc:mysql://localhost:3306/fooDB"
- case class CountyIncome(state:String, county:String, agi:Double,totalReturns:Double,averageReturn:Double) {
- def getAvgIncomeDisplay:String = {
- county + ", " + state + " " + "$%,2.2f".format(averageReturn*1000)
- }
- }
- case class LLPoint(lat:Double, lon:Double)
- case class KMLPlacemark(name:String, styleId:String, points:List[LLPoint], extrude:Int) {
- def jPoints:java.util.List[LLPoint] = {
- points.asJava
- }
- }
- case object TemplateBuilder {
- val fmEngine = getBaseFMConfig
- def getBaseFMConfig = {
- val fmConfig = new Configuration
- fmConfig.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
- fmConfig.setLocale(Locale.US)
- fmConfig.setURLEscapingCharset("UTF-8")
- fmConfig.setNumberFormat("#########################");
- fmConfig
- }
- def processTemplate(templateStr: String, model: java.util.Map[String, AnyRef]): String = {
- val t = new Template("name", new StringReader(templateStr), fmEngine)
- return processFMTemplate(t, model)
- }
- private def processFMTemplate(fmTemplate: Template, model: java.util.Map[String, AnyRef]): String = {
- val sw = new StringWriter
- fmTemplate.process(model, sw)
- sw.toString
- }
- }
- case class KMLStyle(id:String, color:String) {
- def getJID:java.lang.String = {
- id
- }
- def getJColor:java.lang.String = {
- color
- }
- }
- // 0 is highest rank
- /**
- * <color>
- Color and opacity (alpha) values are expressed in hexadecimal notation. The range of values for any one color is 0 to 255 (00 to ff).
- For alpha, 00 is fully transparent and ff is fully opaque. The order of expression is aabbggrr, where aa=alpha (00 to ff); bb=blue (00 to ff);
- gg=green (00 to ff); rr=red (00 to ff). For example, if you want to apply a blue color with 50 percent opacity to an overlay,
- you would specify the following: <color>7fff0000</color>, where alpha=0x7f, blue=0xff, green=0x00, and red=0x00.
- */
- def getColorFromRank(rank:Int, lowestRank:Int):Int = {
- // BLUE, GREEN, RED
- val opacity = 0xbf000000
- val lowRankColor = 0x000000FF
- val lowRankColorIncrement = 257
- val middleColor = 0x00ffffff
- val highRankColor = 0x0000ff00
- // let's use green as highest, white middle, red worst
- // rank / lowestRank == x / 255; 255*rank = low*x, x=255*rank/low
- rank match {
- case redRank:Int if (rank >= lowestRank/2) => {
- val colorScale = 255*(redRank-(lowestRank/2)) / (lowestRank/2)
- val increment = 0x000101ff - 0x000000ff
- (0x7f0000ff + (increment * colorScale)) | (opacity)
- }
- case greenRank:Int if (greenRank < lowestRank/2) => {
- // 00ff00 is the best, ffffff is worst, in this range
- // 00ff00 == 0, ffffff = lowRank / 2 OR
- // 00ff00
- // 01ff01
- // rank / lowRank/2 == x / 255; rank*255 == lowRank/2*x; x= rank*255 / lowRank/2
- val colorScale = 255*greenRank / (lowestRank/2)
- val increment = 0x01ff01 - 0x00ff00
- (0x0000ff00 + (increment * colorScale)) | (opacity)
- }
- }
- }
- /**
- * Given a county income, determine it's color for display in a map
- */
- def colorizeCounty( t:(Int,CountyIncome),lowRank:Int ):(Int,CountyIncome,Int) = {
- (t._1,t._2,getColorFromRank(t._1,lowRank))
- }
- def getDataSource(user:String, pass:String, url:String):BasicDataSource = {
- val ds = new BasicDataSource()
- ds.setDriverClassName("com.mysql.jdbc.Driver")
- ds.setUsername(user)
- ds.setPassword(pass)
- ds.setUrl(url)
- return ds
- }
- def getCountyPoints(county:CountyIncome):List[LLPoint] = {
- if (county.county.length <= 0) {
- return List[LLPoint]()
- }
- //println("getting points for " + county.county + " and " + county.state)
- val con = getDataSource(DB_USER, DB_PASSWORD, DB_URL).getConnection
- val rset = con.createStatement.executeQuery("select latitude,longitude from counties where state=\"%s\" and county=\"%s\"".format(county.state,county.county))
- val pointList = new scala.collection.mutable.ListBuffer[LLPoint]()
- while (rset.next) {
- pointList += new LLPoint(rset.getDouble(1), rset.getDouble(2))
- }
- con.close
- //println("found point count " + pointList.size)
- return pointList.toList
- }
- def getFileAsString(name:String):String = {
- fromInputStream(new java.io.FileInputStream((new java.io.File(name)))).getLines.mkString
- }
- // ------------------------------------------------------------------------------------
- //
- // SCRIPT STARTS HERE
- //
- // ------------------------------------------------------------------------------------
- // open the file containing county income data
- if (argv.size < 1) {
- println("scala income.scala <name of csv file>")
- System.exit(1)
- }
- val incomeFile = new java.io.File("countyincome07.csv")
- val incomeSource = fromInputStream(new FileInputStream(incomeFile))
- // build a list of CountyIncome objects
- val incomeList = incomeSource.getLines.toList.tail.flatMap(line => {
- val parts = line.split(',')
- parts.size match {
- case x if x >= 7 => List(new CountyIncome(parts(2).replace("\"",""), parts(3).replace("\"","").replace(" County","").trim, parts(6).toDouble, parts(4).toDouble, parts(6).toDouble / parts(4).toDouble))
- case _ => List()
- }
- })
- //val sortedIncomeList = incomeList.sort((L,R) => L.averageReturn > R.averageReturn).filter(x => x.state == "MO")
- val sortedIncomeList = incomeList.sort((L,R) => L.averageReturn > R.averageReturn)
- //println("sorted income list size " + sortedIncomeList.size)
- val rankedIncomeList = (1 to 5000).toList.zip(sortedIncomeList)
- val coloredRankedList = rankedIncomeList.map(x => colorizeCounty(x,rankedIncomeList.size))
- //println("colored list size " + coloredRankedList.size)
- // build a list of styles with id and color, for the top of the KML
- val styleList = coloredRankedList.map(tup => KMLStyle("color_"+"%08X".format(tup._3), ""+"%08X".format(tup._3))).removeDuplicates
- //println("styleList size " + styleList.size)
- // build a list of placemarks for each county
- val placemarks = coloredRankedList.map(tup => {
- System.err.println("working on rank " + tup._1)
- KMLPlacemark(tup._2.county + "," + tup._2.state,"color_"+"%08X".format(tup._3), getCountyPoints(tup._2), tup._1*1000)
- })
- // now, using freemarker, build the KML
- val fmModel = Map[String,AnyRef]("placemarks" -> placemarks.asJava, "styles" -> styleList.asJava)
- val finalResult = TemplateBuilder.processTemplate(getFileAsString("incomeTemplate.ftl"), fmModel.asJava)
- println(finalResult)
- //rankedIncomeList.filter(x => x._2.state == "CO" || x._2.state == "MO").foreach(x => println(x._1 + " " + x._2.getAvgIncomeDisplay))
Add Comment
Please, Sign In to add comment