Created
December 29, 2013 07:57
-
-
Save hideshi/8168448 to your computer and use it in GitHub Desktop.
This is a parser for METAR which is a format for weather information. See also: http://d.hatena.ne.jp/hideshi_o/20130105/1357376552
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.util.parsing.combinator.RegexParsers | |
abstract class Bulletin | |
case class MetarBulletin ( | |
icao:String | |
,datetime:String | |
,windDirection:String | |
,windSpeed:String | |
,windShift:String | |
,visibility:String | |
,rvr:List[String] | |
,weather:String | |
,cloud:List[String] | |
,temperature:String | |
,airPressure:String | |
,significant:String | |
,remarks:List[String] | |
) extends Bulletin | |
class MetarParser extends RegexParsers { | |
def parse(data:String) = parseAll(all, data) | |
def all:Parser[MetarBulletin] = { | |
icao ~ datetime ~ wind ~ opt(windShift) ~ visibility ~ rep(rvr) ~ weather ~ rep(cloud) ~ temperature ~ airPressure ~ opt(significant) ~ """(RMK)?""".r ~ opt(rep(remarks)) ^^ { | |
case icao ~ datetime ~ wind ~ windShift ~ visibility ~ rvr ~ weather ~ cloud ~ temperature ~ airPressure ~ significant ~ rmk ~ remarks => | |
MetarBulletin( | |
icao | |
,datetime | |
,wind._1 | |
,wind._2 | |
,windShift.getOrElse("") | |
,visibility | |
,rvr | |
,weather | |
,cloud | |
,temperature | |
,airPressure | |
,significant.getOrElse("") | |
,remarks.getOrElse(List()) | |
) | |
} | |
} | |
def icao:Parser[String] = { | |
"""[A-Z]{4}""".r | |
} | |
def datetime:Parser[String] = { | |
"""[0-9]{6}Z""".r | |
} | |
def wind:Parser[(String, String)] = { | |
"""([0-9]{3}|VRB)[0-9]{2}KT""".r ^^ { | |
case wind:String => wind.splitAt(3) | |
} | |
} | |
def windShift:Parser[String] = { | |
"""[0-9]{3}V[0-9]{3}""".r | |
} | |
def visibility:Parser[String] = { | |
"""[0-9]{4}""".r | |
} | |
def rvr:Parser[String] = { | |
"""R[0-9]{2}/P[0-9]{4}[UN]""".r | |
} | |
def weather:Parser[String] = { | |
"""[+-]?(TS|SH|FZ|BC|MI|PR)?(RA|SN|DZ|SG|GR|GS|IC|PL)?(BA|FG|SA|FU|DU|HZ|VA)?""".r | |
} | |
def cloud:Parser[String] = { | |
"""(FEW|SCT|BKN|OVC)([0-9]{3}|[/]{3})(CB)?""".r | |
} | |
def temperature:Parser[String] = { | |
"""M?[0-9]{2}/M?[0-9]{2}""".r | |
} | |
def airPressure:Parser[String] = { | |
"""Q[0-9]{4}""".r | |
} | |
def significant:Parser[String] = { | |
"""(NOSIG|BECMG|TEMPO|WS)(\s[0-9]{5}KT)?""".r | |
} | |
def remarks:Parser[String] = { | |
"""[A-Z0-9]+""".r | |
} | |
} | |
val bulletin = List( | |
"RJCC 030810Z 21010KT 140V260 9999 SHRA FEW025 BKN030 FEW030CB 07/03 Q1001 RMK 1CU025 6CU030 2CB030 A2957 CB OHD MOV" | |
,"RJAA 050800Z 08003KT 9999 FEW030 BKN/// 04/M02 Q1019 BECMG 04005KT RMK 1CU030 A3009" | |
,"RJAA 050730Z 10004KT 050V130 9999 FEW030 SCT040 BKN/// 04/M02 Q1019 NOSIG RMK 1CU030 3SC040 A3009" | |
,"RJAA 050700Z 12004KT 070V160 9999 FEW030 BKN040 BKN/// 05/M02 Q1019 NOSIG RMK 1CU030 5SC040 A3010" | |
,"RJAA 050630Z VRB02KT 9999 FEW030 BKN040 BKN/// 05/M03 Q1019 BECMG 09005KT RMK 1CU030 5SC040 A3009" | |
,"RJAA 050600Z 06003KT 350V100 9999 FEW030 BKN/// 05/M03 Q1018 BECMG 07005KT RMK 1CU030 A3008" | |
,"RJAA 050530Z 01003KT 310V040 9999 FEW030 SCT050 BKN/// 05/M03 Q1018 NOSIG" | |
,"RJAA 050500Z 03004KT 350V070 9999 FEW030 SCT060 BKN/// 05/M04 Q1018 NOSIG RMK 1CU030 3SC060 A3008" | |
,"RJAA 050430Z 01004KT 330V050 9999 FEW030 BKN060 BKN/// 05/M04 Q1019 NOSIG RMK 1CU030 5SC060 A3009" | |
,"RJAA 050400Z 01004KT 310V060 9999 FEW030 BKN060 BKN/// 05/M04 Q1019 NOSIG RMK 1CU030 5SC060 A3010" | |
,"RJAA 050330Z 02004KT 340V070 9999 FEW030 BKN060 BKN/// 05/M05 Q1020 BECMG 07005KT RMK 1CU030 5SC060 A3012" | |
,"RJAA 050300Z 03006KT 350V070 9999 FEW030 BKN060 BKN/// 04/M05 Q1020 NOSIG RMK 1CU030 5SC060 A3013" | |
,"RJAA 050230Z 36007KT 320V040 9999 FEW030 BKN070 BKN/// 04/M06 Q1021 NOSIG" | |
,"RJBB 050800Z VRB02KT 9999 FEW030 BKN160 BKN/// 05/M06 Q1020 NOSIG" | |
,"RJBB 050730Z VRB02KT 9999 FEW030 SCT160 BKN/// 05/M06 Q1020 NOSIG" | |
,"RJBB 050700Z 07003KT 050V110 9999 FEW030 BKN/// 05/M06 Q1020 NOSIG" | |
,"RJBB 050630Z VRB01KT 9999 FEW025 BKN/// 05/M07 Q1020 NOSIG" | |
,"RJBB 050600Z VRB02KT 9999 FEW025 BKN/// 05/M07 Q1020 NOSIG" | |
,"RJBB 050530Z VRB02KT 9999 FEW020 BKN/// 05/M08 Q1020 NOSIG" | |
,"RJBB 050500Z 33003KT 260V070 9999 FEW020 SCT150 BKN/// 05/M08 Q1020 BECMG 28005KT" | |
,"RJBB 050430Z 35005KT 300V060 9999 FEW020 SCT160 BKN/// 05/M07 Q1020 BECMG 28005KT" | |
,"RJBB 050400Z 01004KT 330V060 9999 FEW020 SCT160 BKN/// 05/M08 Q1020 BECMG 28005KT" | |
,"RJBB 050330Z VRB02KT 9999 FEW020 SCT160 BKN/// 05/M08 Q1021 BECMG 28005KT" | |
,"RJBB 050300Z VRB02KT 9999 FEW020 SCT160 BKN/// 05/M08 Q1021 BECMG 28005KT" | |
,"RJBB 050230Z VRB02KT 9999 FEW020 SCT160 BKN/// 05/M08 Q1022 NOSIG" | |
,"RJAH 050800Z 05003KT 9999 FEW030 BKN040 BKN/// 02/M04 Q1018" | |
,"RJAH 050700Z 05005KT 9999 FEW030 BKN050 BKN210 04/M04 Q1018" | |
,"RJAH 050600Z 06005KT 9999 FEW030 BKN060 BKN240 05/M04 Q1018" | |
,"RJAH 050500Z 03004KT 350V070 9999 FEW030 BKN070 BKN240 05/M06 Q1018" | |
,"RJAH 050400Z 06004KT 020V110 9999 FEW030 BKN060 BKN240 05/M07 Q1019" | |
,"RJAH 050342Z 06005KT 020V100 9999 FEW030 BKN050 BKN240 05/M07 Q1019 RMK 1CU030 5SC050 A3011" | |
,"RJAH 050300Z 01005KT 320V070 9999 FEW030 SCT050 BKN240 04/M08 Q1020" | |
,"RJCC 050800Z 14004KT 9999 FEW030 M03/M10 Q1015 RMK 1CU030 A2998" | |
,"RJCC 050730Z 14004KT 9999 FEW030 M04/M10 Q1015 RMK 1CU030 A2999" | |
,"RJCC 050700Z 15005KT 120V180 9999 FEW030 M02/M11 Q1015 RMK 1CU030 A2999" | |
,"RJCC 050630Z 19008KT 9999 FEW030 SCT050 M03/M10 Q1016 RMK 1CU030 3CU050 A3000" | |
,"RJCC 050600Z 11008KT 9999 FEW030 M02/M10 Q1016 RMK 2CU030 A3000" | |
,"RJCC 050530Z 14009KT 9999 FEW030 M03/M10 Q1016 RMK 2CU030 A3000" | |
,"RJCC 050500Z 13009KT 9999 FEW030 M03/M10 Q1016 RMK 2CU030 A3001" | |
,"RJCC 050430Z 13008KT 9999 FEW030 M03/M10 Q1016 RMK 2CU030 A3002" | |
,"RJCC 050400Z 15007KT 9999 FEW030 M03/M10 Q1016 RMK 1CU030 A3002" | |
,"RJCC 050330Z 14009KT 9999 FEW030 M03/M11 Q1017 RMK 1CU030 A3004" | |
,"RJCC 050300Z 13009KT 9999 FEW030 SCT040 M04/M11 Q1017 RMK 1CU030 3CU040 A3005" | |
,"RJCC 050230Z 14008KT 9999 FEW030 M05/M12 Q1018 RMK 1CU030 A3007" | |
,"RJGG 050800Z 04004KT 350V080 9999 FEW030 04/M04 Q1019 NOSIG" | |
,"RJGG 050730Z 02006KT 9999 FEW030 04/M04 Q1020 NOSIG" | |
,"RJGG 050700Z 36007KT 9999 FEW030 SCT/// 05/M05 Q1019 NOSIG" | |
,"RJGG 050630Z 01007KT 9999 FEW030 BKN/// 05/M04 Q1019 NOSIG" | |
,"RJGG 050600Z 35006KT 320V030 9999 FEW030 BKN/// 05/M04 Q1019 NOSIG" | |
,"RJGG 050530Z 34006KT 9999 FEW030 BKN/// 05/M04 Q1019 NOSIG" | |
,"RJGG 050500Z 32006KT 9999 FEW030 BKN/// 05/M03 Q1019 NOSIG" | |
,"RJGG 050430Z 33005KT 290V010 9999 FEW030 BKN/// 04/M05 Q1019 NOSIG" | |
,"RJGG 050400Z 34007KT 9999 FEW030 BKN/// 04/M04 Q1020 NOSIG" | |
,"RJGG 050330Z 33008KT 9999 FEW030 SCT150 BKN/// 04/M03 Q1020 NOSIG" | |
,"RJGG 050300Z 34007KT 9999 FEW030 SCT160 BKN/// 04/M04 Q1021 NOSIG" | |
,"RJGG 050230Z 36006KT 330V030 9999 FEW030 SCT160 BKN/// 03/M04 Q1021 NOSIG" | |
) | |
val parser = new MetarParser | |
bulletin.map(parser.parse(_)).foreach(println(_)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment