diff --git a/README.md b/README.md index 261a07b..51acbbd 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ ## Overview -Version: 1.2.3 - -API Scaladoc: [GeoBase](http://xavierguihot.com/geobase/#com.geobase.GeoBase) +API Scaladoc: [GeoBase](http://xavierguihot.com/geobase/#com.geobase.GeoBase$) Scala wrapper around opentraveldata (geo/travel data). @@ -37,51 +35,65 @@ Inspired by [neobase](https://github.com/alexprengere/neobase) for python users. The full list of methods is available at -[GeoBase doc](http://xavierguihot.com/geobase/#com.geobase.GeoBase) +[GeoBase doc](http://xavierguihot.com/geobase/#com.geobase.GeoBase$) Here is a non-exhaustive list of available methods: ```scala import com.geobase.GeoBase -val geoBase = new GeoBase() - -assert(geoBase.city("CDG") == Success("PAR")) -assert(geoBase.country("CDG") == Success("FR")) -assert(geoBase.continent("JFK") == Success("NA")) -assert(geoBase.iataZone("LON") == Success("21")) -assert(geoBase.currency("NYC") == Success("USD")) -assert(geoBase.countryForAirline("AF") == Success("FR")) -assert(geoBase.timeZone("PAR") == Success("Europe/Paris")) -assert(geoBase.distanceBetween("PAR", "NCE") == Success(686)) -assert(geoBase.localDateToGMT("20160606_2227", "NYC") == Success("20160607_0227")) -assert(geoBase.gmtDateToLocal("20160607_0227", "NYC") == Success("20160606_2227")) -assert(geoBase.offsetForLocalDate("20171224", "NYC") == Success(-300)) -assert(geoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d)) -assert(geoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) == Success(CONTINENTAL)) -assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX"))) -assert(geoBase.nameOfAirline("AF") == Success("Air France")) +GeoBase.city("CDG") // Success("PAR") +GeoBase.country("CDG") // Success("FR") +GeoBase.continent("JFK") // Success("NA") +GeoBase.iataZone("LON") // Success("21") +GeoBase.currency("NYC") // Success("USD") +GeoBase.countryForAirline("AF") // Success("FR") +GeoBase.timeZone("PAR") // Success("Europe/Paris") +GeoBase.distanceBetween("PAR", "NCE") // Success(686) +GeoBase.localDateToGMT("20160606_2227", "NYC") // Success("20160607_0227") +GeoBase.gmtDateToLocal("20160607_0227", "NYC") // Success("20160606_2227") +GeoBase.offsetForLocalDate("20171224", "NYC") // Success(-300) +GeoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") // Success(7.5d) +GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) // Success(CONTINENTAL) +GeoBase.nearbyAirports("CDG", 50) // Success(List("LBG", "ORY", "VIY", "POX")) +GeoBase.nameOfAirline("AF") // Success("Air France") +``` + +These functions can also be called as attachments to Strings: + +```scala +import com.geobase.GeoBase.StringExtensions + +"CDG".city // Success("PAR") +"PAR".country // Success("FR") +"CDG".continent // Success("EU") +"CDG".iataZone // Success("21") +"JFK".currency // Success("USD") +"AF".name // Success("Air France") +"CDG".timeZone // Success("Europe/Paris") +"LON".distanceWith("NYC") // Success(5568) +"CDG".nearbyAirports(50) // Success(List("LBG", "ORY", "VIY", "POX")) ``` -Getters all have a return type embedded within the Try monade. Throwing +Getters all have a return type embedded within the Try monad. Throwing exceptions when one might request mappings for non existing locations, isn't -realy the idiomatic scala way, and simply embedding the result in the Option -monade doesn't give the user the possibility to understand what went wrong. -Thus the usage of the Try monade. +really the idiomatic scala way, and simply embedding the result in the Option +monad doesn't give the user the possibility to understand what went wrong. +Thus the usage of the Try monad. ## Including geobase to your dependencies: -With sbt, add these lines to your build.sbt: +With sbt: ```scala resolvers += "jitpack" at "https://jitpack.io" -libraryDependencies += "com.github.xavierguihot" % "geobase" % "v1.2.3" +libraryDependencies += "com.github.xavierguihot" % "geobase" % "2.0.0" ``` -With maven, add these lines to your pom.xml: +With maven: ```xml @@ -94,11 +106,11 @@ With maven, add these lines to your pom.xml: com.github.xavierguihot geobase - v1.2.3 + 2.0.0 ``` -With gradle, add these lines to your build.gradle: +With gradle: ```groovy allprojects { @@ -108,10 +120,13 @@ allprojects { } dependencies { - compile 'com.github.xavierguihot:geobase:v1.2.3' + compile 'com.github.xavierguihot:geobase:2.0.0' } ``` +For versions anterior to `2.0.0`, use prefix `v` in the version tag; for +instance `v1.0.0` + ## Building the project: diff --git a/build.sbt b/build.sbt index 6b47e8a..cc75a9e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ name := "geobase" -version := "1.2.3" +version := "2.0.0" scalaVersion := "2.11.12" @@ -31,8 +31,12 @@ scalafmtOnCompile := true val catsVersion = "1.0.1" val scalatestVersion = "3.0.4" +val sparkVersion = "2.1.0" +val sparkTestVersion = "2.1.0_0.8.0" libraryDependencies ++= Seq( - "org.typelevel" %% "cats-core" % catsVersion, - "org.scalatest" %% "scalatest" % scalatestVersion % "test" + "org.typelevel" %% "cats-core" % catsVersion, + "org.scalatest" %% "scalatest" % scalatestVersion % "test", + "org.apache.spark" %% "spark-core" % sparkVersion % "test", + "com.holdenkarau" %% "spark-testing-base" % sparkTestVersion % "test" ) diff --git a/docs/com/geobase/GeoBase$$StringExtensions.html b/docs/com/geobase/GeoBase$$StringExtensions.html new file mode 100644 index 0000000..ecb4c2e --- /dev/null +++ b/docs/com/geobase/GeoBase$$StringExtensions.html @@ -0,0 +1,495 @@ + + + + StringExtensions - com.geobase.GeoBase.StringExtensions + + + + + + + + + + + + + + + +
+ Class +

com.geobase.GeoBase

+

StringExtensions

Related Doc: + package GeoBase +

+ + Permalink + + +
+ +

+ + implicit final + class + + + StringExtensions extends AnyVal + +

+ +
+ Linear Supertypes +
AnyVal, Any
+
+ + +
+
+
+ Ordering +
    + +
  1. Alphabetic
  2. +
  3. By Inheritance
  4. +
+
+
+ Inherited
+
+
    +
  1. StringExtensions
  2. AnyVal
  3. Any
  4. +
+
+ +
    +
  1. Hide All
  2. +
  3. Show All
  4. +
+
+
+ Visibility +
  1. Public
  2. All
+
+
+ +
+
+
+

Instance Constructors

+
  1. + + +

    + + + new + + + StringExtensions(string: String) + +

    + + Permalink + + + +
+
+ + + + + +
+

Value Members

+
  1. + + +

    + + final + def + + + !=(arg0: Any): Boolean + +

    + + Permalink + + +
    Definition Classes
    Any
    +
  2. + + +

    + + final + def + + + ##(): Int + +

    + + Permalink + + +
    Definition Classes
    Any
    +
  3. + + +

    + + final + def + + + ==(arg0: Any): Boolean + +

    + + Permalink + + +
    Definition Classes
    Any
    +
  4. + + +

    + + final + def + + + asInstanceOf[T0]: T0 + +

    + + Permalink + + +
    Definition Classes
    Any
    +
  5. + + +

    + + + def + + + cities: Try[List[String]] + +

    + + Permalink + + +

    Returns the cities associated to the given airport.

    Returns the cities associated to the given airport.

    It sometimes happens that an airport is shared between cities. This +method, returns this list of cities (usually the list will only contain +one city).

    The city method returns the first city corresponding to the given +airport, which is by assumption the biggest corresponding city.

    assert("CDG".cities == Success(List("PAR")))
    +assert("AZA".cities == Success(List("PHX", "MSC")))
    +assert("?*#".cities == Failure(GeoBaseException: Unknown airport "?*#")
    returns

    the list of city codes corresponding to the given airport (for +instance List("PHX", "MSC")).

    +
  6. + + +

    + + + def + + + city: Try[String] + +

    + + Permalink + + +

    Returns the city associated to the given airport.

    Returns the city associated to the given airport.

    assert("CDG".city == Success("PAR"))
    +assert("?*#".city == Failure(GeoBaseException: Unknown airport "?*#")
    returns

    the city code corresponding to the given airport (for instance +PAR).

    +
  7. + + +

    + + + def + + + continent: Try[String] + +

    + + Permalink + + +

    Returns the continent associated to the given airport, city or country.

    Returns the continent associated to the given airport, city or country.

    Possible values: EU (Europe) - NA (North America) - SA (South Africa) - +AF (Africa) - AS (Asia) - AN (Antarctica) - OC (Oceania).

    assert("CDG".continent == Success("EU")) // location is an airport
    +assert("NYC".continent == Success("NA")) // location is a city
    +assert("CN".continent == Success("AS")) // location is a country
    +assert("?*#".continent == Failure(GeoBaseException: Unknown location "?*#"))
    returns

    the continent code corresponding to the given location (for +instance EU).

    +
  8. + + +

    + + + def + + + country: Try[String] + +

    + + Permalink + + +

    Returns the country associated to the given location (city or airport).

    Returns the country associated to the given location (city or airport).

    assert("PAR".country == Success("FR"))
    +assert("ORY".country == Success("FR"))
    +assert("?*#".country == Failure(GeoBaseException: Unknown location "?*#"))
    returns

    the country code corresponding to the given city or airport (for +instance FR).

    +
  9. + + +

    + + + def + + + currency: Try[String] + +

    + + Permalink + + +

    Returns the currency associated to the given location (airport, city or +country).

    Returns the currency associated to the given location (airport, city or +country).

    assert("JFK".currency == Success("USD"))
    +assert("FR".currency == Success("EUR"))
    +assert("?#".currency == Failure(GeoBaseException: Unknown country "#?"))
    returns

    the currency code corresponding to the given location (for +instance EUR).

    +
  10. + + +

    + + + def + + + distanceWith(location: String): Try[Int] + +

    + + Permalink + + +

    Returns the distance between two locations (airports/cities).

    Returns the distance between two locations (airports/cities).

    assert("ORY".distanceWith("NCE") == Success(674))
    +assert("PAR".distanceWith("NCE") == Success(686))
    +assert("PAR".distanceWith("~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    location

    an airport or city IATA code (for instance NCE) for +which to get the distance with the location this is called for.

    returns

    the distance rounded in km between locationA and locationB (for +instance 674 km).

    +
  11. + + +

    + + + def + + + getClass(): Class[_ <: AnyVal] + +

    + + Permalink + + +
    Definition Classes
    AnyVal → Any
    +
  12. + + +

    + + + def + + + iataZone: Try[String] + +

    + + Permalink + + +

    Returns the IATA zone associated to the given airport, city or country.

    Returns the IATA zone associated to the given airport, city or country.

    Possible values are 11, 12, 13, 21, 22, 23, 31, 32 or 33.

    assert("CDG".iataZone == Success("21"))
    +assert("NYC".iataZone == Success("11"))
    +assert("ZA".iataZone == Success("23"))
    +assert("?*#".iataZone == Failure(GeoBaseException: Unknown location "?*#"))
    returns

    the IATA zone code corresponding to the given location (for +instance 21).

    +
  13. + + +

    + + final + def + + + isInstanceOf[T0]: Boolean + +

    + + Permalink + + +
    Definition Classes
    Any
    +
  14. + + +

    + + + def + + + name: Try[String] + +

    + + Permalink + + +

    Returns the name associated to the given airline.

    Returns the name associated to the given airline.

    assert("AF".name == Success("Air France"))
    +assert("#?".name == Failure(GeoBaseException: Unknown airline "#?"))
    returns

    the name corresponding to the given airline (for instance +Air France).

    +
  15. + + +

    + + + def + + + nearbyAirports(radius: Int): Try[List[String]] + +

    + + Permalink + + +

    Returns the list of nearby airports (within the radius) for the given +airport or city.

    Returns the list of nearby airports (within the radius) for the given +airport or city.

    Find the list of nearby airports, within the requested radius. The list +is sorted starting from the closest airport.

    assert("CDG".nearbyAirports(50) == Success(List("LBG", "ORY", "VIY", "POX")))
    +assert("CDG".nearbyAirports(36) == Success(List("LBG", "ORY")))
    +assert("~#?".nearbyAirports(36)) == Failure(GeoBaseException: Unknown location \"~#?\""))
    radius

    the maximum distance (in km) for which an airport is +considered close.

    returns

    the sorted per increasing distance list nearby airports

    +
  16. + + +

    + + + val + + + string: String + +

    + + Permalink + + + +
  17. + + +

    + + + def + + + timeZone: Try[String] + +

    + + Permalink + + +

    Returns the time zone associated to the given airport or city.

    Returns the time zone associated to the given airport or city.

    assert("CDG".timeZone == Success("Europe/Paris"))
    +assert("BOS".timeZone == Success("America/New_York"))
    +assert("?*#".timeZone == Failure(GeoBaseException: Unknown location "?*#"))
    returns

    the time zone corresponding to the given location (for instance +Europe/Paris).

    +
  18. + + +

    + + + def + + + toString(): String + +

    + + Permalink + + +
    Definition Classes
    Any
    +
+
+ + + + +
+ +
+
+

Inherited from AnyVal

+
+

Inherited from Any

+
+ +
+ +
+
+

Ungrouped

+ +
+
+ +
+ +
+ + + + + + diff --git a/docs/com/geobase/GeoBase.html b/docs/com/geobase/GeoBase$.html similarity index 83% rename from docs/com/geobase/GeoBase.html rename to docs/com/geobase/GeoBase$.html index 75785f6..9d1b43f 100644 --- a/docs/com/geobase/GeoBase.html +++ b/docs/com/geobase/GeoBase$.html @@ -16,7 +16,7 @@ - +
- Class + Object

com.geobase

GeoBase

Related Doc: package geobase

- + Permalink @@ -42,31 +42,47 @@

GeoBase

Related Doc:

- class + object GeoBase extends Serializable

-

A facility to deal with travel/geographical data.

Provides geographical mappings at airport/city/country level mainly +

Provides geographical mappings at airport/city/country level mainly based on opentraveldata as well as other mappings (airlines, currencies, ...). This tool also provides classic time-oriented methods such as the computation of a trip duration.

Here are a few examples:

import com.geobase.GeoBase
 
-val geoBase = new GeoBase()
+GeoBase.city("CDG") // Success("PAR")
+GeoBase.country("CDG") // Success("FR")
+GeoBase.continent("JFK") // Success("NA")
+GeoBase.iataZone("LON") // Success("21")
+GeoBase.currency("NYC") // Success("USD")
+GeoBase.countryForAirline("AF") // Success("FR")
+GeoBase.timeZone("PAR") // Success("Europe/Paris")
+GeoBase.distanceBetween("PAR", "NCE") // Success(686)
+GeoBase.localDateToGMT("20160606_2227", "NYC") // Success("20160607_0227")
+GeoBase.gmtDateToLocal("20160607_0227", "NYC") // Success("20160606_2227")
+GeoBase.offsetForLocalDate("20171224", "NYC") // Success(-300)
+GeoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") // Success(7.5d)
+GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) // Success(CONTINENTAL)
+GeoBase.nearbyAirports("CDG", 50) // Success(List("LBG", "ORY", "VIY", "POX"))
+GeoBase.nameOfAirline("AF") // Success("Air France")

and by pimping String:

import com.geobase.GeoBase.StringExtensions
 
-assert(geoBase.city("CDG") == Success("PAR"))
-assert(geoBase.country("CDG") == Success("FR"))
-assert(geoBase.currency("NYC") == Success("USD"))
-assert(geoBase.countryForAirline("AF") == Success("FR"))
-assert(geoBase.distanceBetween("PAR", "NCE") == Success(686))
-assert(geoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d))
-assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX")))

The GeoBase object can be used within Spark jobs (in this case, don't forget -the possibility to broadcast GeoBase).

Opentraveldata is an accurate and maintained source of various travel -mappings. This scala wrapper around opentraveldata mostly uses this -file: +"CDG".city // Success("PAR") +"PAR".country // Success("FR") +"CDG".continent // Success("EU") +"CDG".iataZone // Success("21") +"JFK".currency // Success("USD") +"AF".name // Success("Air France") +"CDG".timeZone // Success("Europe/Paris") +"LON".distanceWith("NYC") // Success(5568) +"CDG".nearbyAirports(50) // Success(List("LBG", "ORY", "VIY", "POX"))

The GeoBase object can be used within Spark jobs (in this case, don't forget +to broadcast it.

Opentraveldata is an accurate and maintained source of various travel +mappings. This scala wrapper uses this file: + optd_por_public.csv.

Getters all have a return type embedded within the Try monad. Throwing exceptions as is when one might request mappings for non existing locations, isn't really the scala way, and simply embedding the result in the Option @@ -110,32 +126,32 @@

-
-

Instance Constructors

-
  1. - - + + +
    +

    Type Members

    +
    1. + +

      - - new + implicit final + class - GeoBase() + StringExtensions extends AnyVal

      - + Permalink -

      Creates a GeoBase object.

      +
    - -

    Value Members

    1. @@ -150,7 +166,7 @@

      !=(arg0: Any): Boolean

      - + Permalink @@ -167,7 +183,7 @@

      ##(): Int

      - + Permalink @@ -184,7 +200,7 @@

      ==(arg0: Any): Boolean

      - + Permalink @@ -201,7 +217,7 @@

      asInstanceOf[T0]: T0

      - + Permalink @@ -218,16 +234,16 @@

      cities(airport: String): Try[List[String]]

      - + Permalink

      Returns the cities associated to the given airport.

      Returns the cities associated to the given airport.

      It sometimes happens that an airport is shared between cities. This method, returns this list of cities (usually the list will only contain one city).

      The method city returns the first city corresponding to the given -airport, which is by assumption the biggest corresponding city.

      assert(geoBase.cities("CDG") == Success(List("PAR")))
      -assert(geoBase.cities("AZA") == Success(List("PHX", "MSC")))
      -assert(geoBase.cities("?*#") == Failure(GeoBaseException: Unknown airport "?*#")
      airport

      the airport IATA code (for instance AZA) for which to get +airport, which is by assumption the biggest corresponding city.

      assert(GeoBase.cities("CDG") == Success(List("PAR")))
      +assert(GeoBase.cities("AZA") == Success(List("PHX", "MSC")))
      +assert(GeoBase.cities("?*#") == Failure(GeoBaseException: Unknown airport "?*#")
      airport

      the airport IATA code (for instance AZA) for which to get the associated cities.

      returns

      the list of city codes corresponding to the given airport (for instance List("PHX", "MSC")).

  2. @@ -242,12 +258,12 @@

    city(airport: String): Try[String]

    - + Permalink -

    Returns the city associated to the given airport.

    Returns the city associated to the given airport.

    assert(geoBase.city("CDG") == Success("PAR"))
    -assert(geoBase.city("?*#") == Failure(GeoBaseException: Unknown airport "?*#")
    airport

    the airport IATA code (for instance CDG) for which to get +

    Returns the city associated to the given airport.

    Returns the city associated to the given airport.

    assert(GeoBase.city("CDG") == Success("PAR"))
    +assert(GeoBase.city("?*#") == Failure(GeoBaseException: Unknown airport "?*#")
    airport

    the airport IATA code (for instance CDG) for which to get the associated city.

    returns

    the city code corresponding to the given airport (for instance PAR).

  3. @@ -262,7 +278,7 @@

    clone(): AnyRef

    - + Permalink @@ -285,15 +301,15 @@

    continent(location: String): Try[String]

    - + Permalink

    Returns the continent associated to the given airport, city or country.

    Returns the continent associated to the given airport, city or country.

    Possible values: EU (Europe) - NA (North America) - SA (South Africa) - -AF (Africa) - AS (Asia) - AN (Antarctica) - OC (Oceania).

    assert(geoBase.continent("CDG") == Success("EU")) // location is an airport
    -assert(geoBase.continent("NYC") == Success("NA")) // location is a city
    -assert(geoBase.continent("CN") == Success("AS")) // location is a country
    -assert(geoBase.continent("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the country, city or airport IATA code (for instance PAR) +AF (Africa) - AS (Asia) - AN (Antarctica) - OC (Oceania).

    assert(GeoBase.continent("CDG") == Success("EU")) // location is an airport
    +assert(GeoBase.continent("NYC") == Success("NA")) // location is a city
    +assert(GeoBase.continent("CN") == Success("AS")) // location is a country
    +assert(GeoBase.continent("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the country, city or airport IATA code (for instance PAR) for which to get the associated continent.

    returns

    the continent code corresponding to the given location (for instance EU).

  • @@ -308,13 +324,13 @@

    country(location: String): Try[String]

    - + Permalink -

    Returns the country associated to the given location (city or airport).

    Returns the country associated to the given location (city or airport).

    assert(geoBase.country("PAR") == Success("FR"))
    -assert(geoBase.country("ORY") == Success("FR"))
    -assert(geoBase.country("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the location IATA code (city or airport - for instance +

    Returns the country associated to the given location (city or airport).

    Returns the country associated to the given location (city or airport).

    assert(GeoBase.country("PAR") == Success("FR"))
    +assert(GeoBase.country("ORY") == Success("FR"))
    +assert(GeoBase.country("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the location IATA code (city or airport - for instance PAR) for which to get the associated country.

    returns

    the country code corresponding to the given city or airport (for instance FR).

  • @@ -329,12 +345,12 @@

    countryForAirline(airline: String): Try[String]

    - + Permalink -

    Returns the country associated to the given airline.

    Returns the country associated to the given airline.

    assert(geoBase.countryForAirline("AF") == Success("FR"))
    -assert(geoBase.countryForAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
    airline

    the airline IATA code (for instance AF) for which to get +

    Returns the country associated to the given airline.

    Returns the country associated to the given airline.

    assert(GeoBase.countryForAirline("AF") == Success("FR"))
    +assert(GeoBase.countryForAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
    airline

    the airline IATA code (for instance AF) for which to get the associated country.

    returns

    the country code corresponding to the given airline (for instance FR).

  • @@ -349,15 +365,15 @@

    currency(location: String): Try[String]

    - + Permalink

    Returns the currency associated to the given location (airport, city or country).

    Returns the currency associated to the given location (airport, city or -country).

    assert(geoBase.currency("JFK") == Success("USD"))
    -assert(geoBase.currency("FR") == Success("EUR"))
    -assert(geoBase.currency("?#") == Failure(GeoBaseException: Unknown country "#?"))
    location

    the country, city or airport IATA code (for instance FR) +country).

    assert(GeoBase.currency("JFK") == Success("USD"))
    +assert(GeoBase.currency("FR") == Success("EUR"))
    +assert(GeoBase.currency("?#") == Failure(GeoBaseException: Unknown country "#?"))
    location

    the country, city or airport IATA code (for instance FR) for which to get the associated currency.

    returns

    the currency code corresponding to the given location (for instance EUR).

  • @@ -372,13 +388,13 @@

    distanceBetween(locationA: String, locationB: String): Try[Int]

    - + Permalink -

    Returns the distance between two locations (airports/cities).

    Returns the distance between two locations (airports/cities).

    assert(geoBase.distanceBetween("ORY", "NCE") == Success(674))
    -assert(geoBase.distanceBetween("PAR", "NCE") == Success(686))
    -assert(geoBase.distanceBetween("PAR", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    locationA

    an airport or city IATA code (for instance ORY) for which +

    Returns the distance between two locations (airports/cities).

    Returns the distance between two locations (airports/cities).

    assert(GeoBase.distanceBetween("ORY", "NCE") == Success(674))
    +assert(GeoBase.distanceBetween("PAR", "NCE") == Success(686))
    +assert(GeoBase.distanceBetween("PAR", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    locationA

    an airport or city IATA code (for instance ORY) for which to get the distance with locationB.

    locationB

    an airport or city IATA code (for instance NCE) for which to get the distance with locationA.

    returns

    the distance rounded in km between locationA and locationB (for instance 674 km).

    @@ -394,7 +410,7 @@

    eq(arg0: AnyRef): Boolean

    - + Permalink @@ -411,7 +427,7 @@

    equals(arg0: Any): Boolean

    - + Permalink @@ -428,7 +444,7 @@

    finalize(): Unit

    - + Permalink @@ -451,16 +467,16 @@

    geoType(locations: List[String]): Try[GeoType]

    - + Permalink

    Returns the geo type of a trip (domestic, continental or inter continental).

    Returns the geo type of a trip (domestic, continental or inter continental).

    Possible returned values: DOMESTIC, CONTINENTAL or INTER_CONTINENTAL.

    The distinction between continental and intercontinental is made based on -iata zones.

    assert(geoBase.geoType(List("CDG", "ORY")) == Success(DOMESTIC))
    -assert(geoBase.geoType(List("FR", "FR")) == Success(DOMESTIC))
    -assert(geoBase.geoType(List("FR", "PAR", "DUB")) == Success(CONTINENTAL))
    -assert(geoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) == Success(INTER_CONTINENTAL))
    -assert(geoBase.geoType(List("US", "bbb", "NCE", "aaa")) == Failure(GeoBaseException: Unknown locations \"bbb\", \"aaa\"))
    locations

    a list of cities/airports/countries representing the trip

    returns

    the type of the trip (a GeoType "enum" value, such as DOMESTIC)

    +iata zones.

    assert(GeoBase.geoType(List("CDG", "ORY")) == Success(DOMESTIC))
    +assert(GeoBase.geoType(List("FR", "FR")) == Success(DOMESTIC))
    +assert(GeoBase.geoType(List("FR", "PAR", "DUB")) == Success(CONTINENTAL))
    +assert(GeoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) == Success(INTER_CONTINENTAL))
    +assert(GeoBase.geoType(List("US", "bbb", "NCE", "aaa")) == Failure(GeoBaseException: Unknown locations \"bbb\", \"aaa\"))
    locations

    a list of cities/airports/countries representing the trip

    returns

    the type of the trip (a GeoType "enum" value, such as DOMESTIC)

  • @@ -473,7 +489,7 @@

    getClass(): Class[_]

    - + Permalink @@ -490,16 +506,16 @@

    gmtDateToLocal(gmtDate: String, location: String, format: String = "yyyyMMdd_HHmm"): Try[String]

    - + Permalink

    Transforms a GMT date into a local date for the given airport or city.

    Transforms a GMT date into a local date for the given airport or city.

    Here we bring more than just converting the GMT time to local. The additional value is the knowledge of the time zone thanks to opentraveldata. You don't need to know the time zone, just enter the -airport or the city as a parameter.

    assert(geoBase.gmtDateToLocal("20160606_1427", "NCE") == Success("20160606_1627"))
    -assert(geoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-06T22:27"))
    -assert(geoBase.gmtDateToLocal("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    gmtDate

    the GMT date

    location

    the airport or the city where this GMT date is to be +airport or the city as a parameter.

    assert(GeoBase.gmtDateToLocal("20160606_1427", "NCE") == Success("20160606_1627"))
    +assert(GeoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-06T22:27"))
    +assert(GeoBase.gmtDateToLocal("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    gmtDate

    the GMT date

    location

    the airport or the city where this GMT date is to be localized.

    format

    (default = "yyyyMMdd_HHmm") the format under which gmtDate is provided and the local date is returned.

    returns

    the local date associated to the GMT date under the requested format.

  • @@ -515,7 +531,7 @@

    hashCode(): Int

    - + Permalink @@ -532,14 +548,14 @@

    iataZone(location: String): Try[String]

    - + Permalink -

    Returns the IATA zone associated to the given airport, city or country.

    Returns the IATA zone associated to the given airport, city or country.

    Possible values are 11, 12, 13, 21, 22, 23, 31, 32 or 33.

    assert(geoBase.iataZone("CDG") == Success("21"))
    -assert(geoBase.iataZone("NYC") == Success("11"))
    -assert(geoBase.iataZone("ZA") == Success("23"))
    -assert(geoBase.iataZone("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the country, city or airport IATA code (for instance PAR) +

    Returns the IATA zone associated to the given airport, city or country.

    Returns the IATA zone associated to the given airport, city or country.

    Possible values are 11, 12, 13, 21, 22, 23, 31, 32 or 33.

    assert(GeoBase.iataZone("CDG") == Success("21"))
    +assert(GeoBase.iataZone("NYC") == Success("11"))
    +assert(GeoBase.iataZone("ZA") == Success("23"))
    +assert(GeoBase.iataZone("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the country, city or airport IATA code (for instance PAR) for which to get the associated IATA zone.

    returns

    the IATA zone code corresponding to the given location (for instance 21).

  • @@ -554,7 +570,7 @@

    isInstanceOf[T0]: Boolean

    - + Permalink @@ -571,16 +587,16 @@

    localDateToGMT(localDate: String, location: String, format: String = "yyyyMMdd_HHmm"): Try[String]

    - + Permalink

    Transforms a local date (at a given location) into a GMT date.

    Transforms a local date (at a given location) into a GMT date.

    Here we bring more than just converting the local time to GMT. The additional value is the knowledge of the time zone thanks to opentraveldata. You don't need to know the time zone, just enter the -airport or the city as a parameter.

    assert(geoBase.localDateToGMT("20160606_2227", "NYC") == Success("20160607_0227"))
    -assert(geoBase.localDateToGMT("2016-06-06T22:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-07T02:27"))
    -assert(geoBase.localDateToGMT("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    localDate

    the local date at the given location under the given +airport or the city as a parameter.

    assert(GeoBase.localDateToGMT("20160606_2227", "NYC") == Success("20160607_0227"))
    +assert(GeoBase.localDateToGMT("2016-06-06T22:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-07T02:27"))
    +assert(GeoBase.localDateToGMT("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    localDate

    the local date at the given location under the given format.

    location

    the airport or city where this local date applies

    format

    (default = "yyyyMMdd_HHmm") the format under which localDate is provided and the GMT date is returned.

    returns

    the GMT date associated to the local date under the requested format.

  • @@ -596,12 +612,12 @@

    nameOfAirline(airline: String): Try[String]

    - + Permalink -

    Returns the name associated to the given airline.

    Returns the name associated to the given airline.

    assert(geoBase.nameOfAirline("AF") == Success("Air France"))
    -assert(geoBase.nameOfAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
    airline

    the airline IATA code (for instance AF) for which to get +

    Returns the name associated to the given airline.

    Returns the name associated to the given airline.

    assert(GeoBase.nameOfAirline("AF") == Success("Air France"))
    +assert(GeoBase.nameOfAirline("#?") == Failure(GeoBaseException: Unknown airline "#?"))
    airline

    the airline IATA code (for instance AF) for which to get the associated airline name.

    returns

    the name corresponding to the given airline (for instance Air France).

  • @@ -616,7 +632,7 @@

    ne(arg0: AnyRef): Boolean

    - + Permalink @@ -633,16 +649,16 @@

    nearbyAirports(location: String, radius: Int): Try[List[String]]

    - + Permalink

    Returns the list of nearby airports (within the radius) for the given airport or city.

    Returns the list of nearby airports (within the radius) for the given airport or city.

    Find the list of nearby airports, within the requested radius. The list is -sorted starting from the closest airport.

    assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX")))
    -assert(geoBase.nearbyAirports("CDG", 36) == Success(List("LBG", "ORY")))
    -assert(geoBase.nearbyAirports("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\""))
    location

    the airport or city for which to find nearby airports

    radius

    the maximum distance (in km) for which an airport is +sorted starting from the closest airport.

    assert(GeoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX")))
    +assert(GeoBase.nearbyAirports("CDG", 36) == Success(List("LBG", "ORY")))
    +assert(GeoBase.nearbyAirports("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\""))
    location

    the airport or city for which to find nearby airports

    radius

    the maximum distance (in km) for which an airport is considered close.

    returns

    the sorted per increasing distance list nearby airports

  • @@ -656,7 +672,7 @@

    nearbyAirportsWithDetails(location: String, radius: Int): Try[List[(String, Int)]]

    - + Permalink @@ -664,9 +680,9 @@

    airport or city.

    Returns the list of nearby airports (within the radius) for the given airport or city.

    Find the list of nearby airports, within the requested radius. The list is sorted starting from the closest airport. This list is a tuple of -(airport/distance).

    assert(geoBase.nearbyAirportsWithDetails("CDG", 50) == Success(List(("LBG", 9), ("ORY", 35), ("VIY", 37), ("POX", 38))))
    -assert(geoBase.nearbyAirportsWithDetails("CDG", 36) == Success(List(("LBG", 9), ("ORY", 35))))
    -assert(geoBase.nearbyAirportsWithDetails("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\""))
    location

    the airport or city for which to find nearby airports.

    radius

    the maximum distance (in km) for which an airport is +(airport/distance).

    assert(GeoBase.nearbyAirportsWithDetails("CDG", 50) == Success(List(("LBG", 9), ("ORY", 35), ("VIY", 37), ("POX", 38))))
    +assert(GeoBase.nearbyAirportsWithDetails("CDG", 36) == Success(List(("LBG", 9), ("ORY", 35))))
    +assert(GeoBase.nearbyAirportsWithDetails("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\""))
    location

    the airport or city for which to find nearby airports.

    radius

    the maximum distance (in km) for which an airport is considered close.

    returns

    the sorted per increasing distance list of tuples (airport, distance).

  • @@ -681,7 +697,7 @@

    notify(): Unit

    - + Permalink @@ -698,7 +714,7 @@

    notifyAll(): Unit

    - + Permalink @@ -715,15 +731,15 @@

    offsetForLocalDate(localDate: String, location: String, format: String = "yyyyMMdd"): Try[Int]

    - + Permalink -

    Returns the offset in minutes for the given date at the given city/airport.

    Returns the offset in minutes for the given date at the given city/airport.

    assert(geoBase.offsetForLocalDate("20170712", "NCE") == Success(120))
    -assert(geoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") == Success(120))
    -assert(geoBase.offsetForLocalDate("20171224", "NCE") == Success(60))
    -assert(geoBase.offsetForLocalDate("20171224", "NYC") == Success(-300))
    -assert(geoBase.offsetForLocalDate("20171224", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    localDate

    the local date

    location

    the airport or the city where this local date applies

    format

    (default = "yyyyMMdd") the format under which localDate is +

    Returns the offset in minutes for the given date at the given city/airport.

    Returns the offset in minutes for the given date at the given city/airport.

    assert(GeoBase.offsetForLocalDate("20170712", "NCE") == Success(120))
    +assert(GeoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") == Success(120))
    +assert(GeoBase.offsetForLocalDate("20171224", "NCE") == Success(60))
    +assert(GeoBase.offsetForLocalDate("20171224", "NYC") == Success(-300))
    +assert(GeoBase.offsetForLocalDate("20171224", "~#?") == Failure(GeoBaseException: Unknown location "~#?"))
    localDate

    the local date

    location

    the airport or the city where this local date applies

    format

    (default = "yyyyMMdd") the format under which localDate is provided.

    returns

    the the offset in minutes for the given date at the given city/airport (can be negative).

  • @@ -738,7 +754,7 @@

    synchronized[T0](arg0: ⇒ T0): T0

    - + Permalink @@ -755,13 +771,13 @@

    timeZone(location: String): Try[String]

    - + Permalink -

    Returns the time zone associated to the given airport or city.

    Returns the time zone associated to the given airport or city.

    assert(geoBase.timeZone("CDG") == Success("Europe/Paris"))
    -assert(geoBase.timeZone("BOS") == Success("America/New_York"))
    -assert(geoBase.timeZone("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the city or airport IATA code (for instance PAR) for which +

    Returns the time zone associated to the given airport or city.

    Returns the time zone associated to the given airport or city.

    assert(GeoBase.timeZone("CDG") == Success("Europe/Paris"))
    +assert(GeoBase.timeZone("BOS") == Success("America/New_York"))
    +assert(GeoBase.timeZone("?*#") == Failure(GeoBaseException: Unknown location "?*#"))
    location

    the city or airport IATA code (for instance PAR) for which to get the associated time zone.

    returns

    the time zone corresponding to the given location (for instance Europe/Paris).

  • @@ -776,7 +792,7 @@

    toString(): String

    - + Permalink @@ -793,17 +809,17 @@

    tripDurationFromLocalDates(localDepartureDate: String, originLocation: String, localArrivalDate: String, destinationLocation: String, unit: Duration = HOURS, format: String = "yyyyMMdd_HHmm"): Try[Double]

    - + Permalink

    Returns the trip duration between two locations (airport or city).

    Returns the trip duration between two locations (airport or city).

    In the travel industry, the trip duration is synonym with elapsed flying time (EFT).

    This is meant to be used to compute the trip duration for a segment/bound for which we know the origin/destination airports/cities and the local -time. i.e. when we don't have gmt times.

    assert(geoBase.tripDurationFromLocalDates(
    +time. i.e. when we don't have gmt times.

    assert(GeoBase.tripDurationFromLocalDates(
       "20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d))
     
    -val computedTripDuration = geoBase.tripDurationFromLocalDates(
    +val computedTripDuration = GeoBase.tripDurationFromLocalDates(
       "2016-06-06T16:27", "CDG", "2016-06-06T17:57", "JFK",
       format = "yyyy-MM-dd'T'HH:mm", unit = MINUTES
     )
    @@ -826,7 +842,7 @@ 

    wait(): Unit

    - + Permalink @@ -849,7 +865,7 @@

    wait(arg0: Long, arg1: Int): Unit

    - + Permalink @@ -872,7 +888,7 @@

    wait(arg0: Long): Unit

    - + Permalink diff --git a/docs/com/geobase/package.html b/docs/com/geobase/package.html index 6667507..e174c32 100644 --- a/docs/com/geobase/package.html +++ b/docs/com/geobase/package.html @@ -64,42 +64,64 @@

    -
    -

    Type Members

    + + + + +
    +

    Value Members

    1. - +

      - class + object - GeoBase extends Serializable + GeoBase extends Serializable

      - + Permalink -

      A facility to deal with travel/geographical data.

      A facility to deal with travel/geographical data.

      Provides geographical mappings at airport/city/country level mainly +

      Provides geographical mappings at airport/city/country level mainly +based on +opentraveldata as well as other mappings (airlines, currencies, ...).

      Provides geographical mappings at airport/city/country level mainly based on opentraveldata as well as other mappings (airlines, currencies, ...). This tool also provides classic time-oriented methods such as the computation of a trip duration.

      Here are a few examples:

      import com.geobase.GeoBase
       
      -val geoBase = new GeoBase()
      -
      -assert(geoBase.city("CDG") == Success("PAR"))
      -assert(geoBase.country("CDG") == Success("FR"))
      -assert(geoBase.currency("NYC") == Success("USD"))
      -assert(geoBase.countryForAirline("AF") == Success("FR"))
      -assert(geoBase.distanceBetween("PAR", "NCE") == Success(686))
      -assert(geoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d))
      -assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX")))

      The GeoBase object can be used within Spark jobs (in this case, don't forget -the possibility to broadcast GeoBase).

      Opentraveldata is an accurate and maintained source of various travel -mappings. This scala wrapper around opentraveldata mostly uses this -file: +GeoBase.city("CDG") // Success("PAR") +GeoBase.country("CDG") // Success("FR") +GeoBase.continent("JFK") // Success("NA") +GeoBase.iataZone("LON") // Success("21") +GeoBase.currency("NYC") // Success("USD") +GeoBase.countryForAirline("AF") // Success("FR") +GeoBase.timeZone("PAR") // Success("Europe/Paris") +GeoBase.distanceBetween("PAR", "NCE") // Success(686) +GeoBase.localDateToGMT("20160606_2227", "NYC") // Success("20160607_0227") +GeoBase.gmtDateToLocal("20160607_0227", "NYC") // Success("20160606_2227") +GeoBase.offsetForLocalDate("20171224", "NYC") // Success(-300) +GeoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") // Success(7.5d) +GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) // Success(CONTINENTAL) +GeoBase.nearbyAirports("CDG", 50) // Success(List("LBG", "ORY", "VIY", "POX")) +GeoBase.nameOfAirline("AF") // Success("Air France")

    and by pimping String:

    import com.geobase.GeoBase.StringExtensions
    +
    +"CDG".city // Success("PAR")
    +"PAR".country // Success("FR")
    +"CDG".continent // Success("EU")
    +"CDG".iataZone // Success("21")
    +"JFK".currency // Success("USD")
    +"AF".name // Success("Air France")
    +"CDG".timeZone // Success("Europe/Paris")
    +"LON".distanceWith("NYC") // Success(5568)
    +"CDG".nearbyAirports(50) // Success(List("LBG", "ORY", "VIY", "POX"))

    The GeoBase object can be used within Spark jobs (in this case, don't forget +to broadcast it.

    Opentraveldata is an accurate and maintained source of various travel +mappings. This scala wrapper uses this file: + optd_por_public.csv.

    Getters all have a return type embedded within the Try monad. Throwing exceptions as is when one might request mappings for non existing locations, isn't really the scala way, and simply embedding the result in the Option @@ -107,14 +129,7 @@

    Thus the usage of the Try monad.

    Source GeoBase

    Since

    2016-05

    -
  • -
    - - - -
    -

    Value Members

    -
    1. +
    2. diff --git a/docs/index.html b/docs/index.html index 5addb5b..0e809c6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -25,7 +25,7 @@
      -
      #ABCDEFGHIJKLMNOPQRSTUVWXYZdeprecated
      +
      #ABCDEFGHIJKLMNOPQRSTUVWXYZdeprecated
      @@ -35,7 +35,7 @@
        1. com.geobase -
          1. (class)GeoBase
          +
          1. (object)
            GeoBase
          1. com.geobase.error
            1. (case class)GeoBaseException
            diff --git a/docs/index.js b/docs/index.js index cdcf88b..371c0c2 100644 --- a/docs/index.js +++ b/docs/index.js @@ -1 +1 @@ -Index.PACKAGES = {"com" : [], "com.geobase" : [{"class" : "com\/geobase\/GeoBase.html", "name" : "com.geobase.GeoBase"}], "com.geobase.error" : [{"case class" : "com\/geobase\/error\/GeoBaseException.html", "name" : "com.geobase.error.GeoBaseException"}], "com.geobase.model" : [{"object" : "com\/geobase\/model\/CONTINENTAL$.html", "name" : "com.geobase.model.CONTINENTAL"}, {"object" : "com\/geobase\/model\/DOMESTIC$.html", "name" : "com.geobase.model.DOMESTIC"}, {"trait" : "com\/geobase\/model\/Duration.html", "name" : "com.geobase.model.Duration"}, {"trait" : "com\/geobase\/model\/GeoType.html", "name" : "com.geobase.model.GeoType"}, {"object" : "com\/geobase\/model\/HOURS$.html", "name" : "com.geobase.model.HOURS"}, {"object" : "com\/geobase\/model\/INTER_CONTINENTAL$.html", "name" : "com.geobase.model.INTER_CONTINENTAL"}, {"object" : "com\/geobase\/model\/MINUTES$.html", "name" : "com.geobase.model.MINUTES"}]}; \ No newline at end of file +Index.PACKAGES = {"com" : [], "com.geobase" : [{"object" : "com\/geobase\/GeoBase$.html", "name" : "com.geobase.GeoBase"}], "com.geobase.error" : [{"case class" : "com\/geobase\/error\/GeoBaseException.html", "name" : "com.geobase.error.GeoBaseException"}], "com.geobase.model" : [{"object" : "com\/geobase\/model\/CONTINENTAL$.html", "name" : "com.geobase.model.CONTINENTAL"}, {"object" : "com\/geobase\/model\/DOMESTIC$.html", "name" : "com.geobase.model.DOMESTIC"}, {"trait" : "com\/geobase\/model\/Duration.html", "name" : "com.geobase.model.Duration"}, {"trait" : "com\/geobase\/model\/GeoType.html", "name" : "com.geobase.model.GeoType"}, {"object" : "com\/geobase\/model\/HOURS$.html", "name" : "com.geobase.model.HOURS"}, {"object" : "com\/geobase\/model\/INTER_CONTINENTAL$.html", "name" : "com.geobase.model.INTER_CONTINENTAL"}, {"object" : "com\/geobase\/model\/MINUTES$.html", "name" : "com.geobase.model.MINUTES"}]}; \ No newline at end of file diff --git a/docs/index/index-c.html b/docs/index/index-c.html index 7861c55..2a3a9cf 100644 --- a/docs/index/index-c.html +++ b/docs/index/index-c.html @@ -15,24 +15,24 @@
        cities
        - +
        city
        - +
        com
        continent
        - +
        country
        - +
        countryForAirline
        - +
        currency
        - +
        diff --git a/docs/index/index-d.html b/docs/index/index-d.html index b786a57..b63bc65 100644 --- a/docs/index/index-d.html +++ b/docs/index/index-d.html @@ -18,6 +18,9 @@
        distanceBetween
        - + +
        +
        distanceWith
        +
        diff --git a/docs/index/index-g.html b/docs/index/index-g.html index 7ed8807..3cdb6a1 100644 --- a/docs/index/index-g.html +++ b/docs/index/index-g.html @@ -21,12 +21,12 @@

      geoType
      - +
      geobase
      gmtDateToLocal
      - +
      diff --git a/docs/index/index-i.html b/docs/index/index-i.html index fef43b0..df63478 100644 --- a/docs/index/index-i.html +++ b/docs/index/index-i.html @@ -15,6 +15,6 @@
      iataZone
      - +
      diff --git a/docs/index/index-l.html b/docs/index/index-l.html index 6021bc1..95a782c 100644 --- a/docs/index/index-l.html +++ b/docs/index/index-l.html @@ -12,6 +12,6 @@
      localDateToGMT
      - +
      diff --git a/docs/index/index-n.html b/docs/index/index-n.html index c742b07..1a9086a 100644 --- a/docs/index/index-n.html +++ b/docs/index/index-n.html @@ -11,13 +11,16 @@
      +
      name
      + +
      nameOfAirline
      - +
      nearbyAirports
      - +
      nearbyAirportsWithDetails
      - +
      diff --git a/docs/index/index-o.html b/docs/index/index-o.html index a907210..e4bd004 100644 --- a/docs/index/index-o.html +++ b/docs/index/index-o.html @@ -12,6 +12,6 @@
      offsetForLocalDate
      - +
      diff --git a/docs/index/index-s.html b/docs/index/index-s.html new file mode 100644 index 0000000..d94039a --- /dev/null +++ b/docs/index/index-s.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + +
      +
      StringExtensions
      + +
      +
      string
      + +
      + diff --git a/docs/index/index-t.html b/docs/index/index-t.html index 8077f9f..54fba10 100644 --- a/docs/index/index-t.html +++ b/docs/index/index-t.html @@ -12,9 +12,9 @@
      timeZone
      - +
      tripDurationFromLocalDates
      - +
      diff --git a/src/main/scala/com/geobase/GeoBase.scala b/src/main/scala/com/geobase/GeoBase.scala index 52804e3..f947bb4 100644 --- a/src/main/scala/com/geobase/GeoBase.scala +++ b/src/main/scala/com/geobase/GeoBase.scala @@ -1,7 +1,7 @@ package com.geobase import com.geobase.load.Loader -import com.geobase.error.GeoBaseException +import com.geobase.error.{GeoBaseException => BGEx} import com.geobase.model.{Duration, HOURS} import com.geobase.model.{Airline, AirportOrCity, Country} import com.geobase.model.{GeoType, DOMESTIC, CONTINENTAL, INTER_CONTINENTAL} @@ -17,9 +17,7 @@ import math.{asin, cos, pow, round, sin, sqrt} import cats.implicits._ -/** A facility to '''deal with travel/geographical data'''. - * - * Provides '''geographical mappings''' at airport/city/country level mainly +/** Provides '''geographical mappings''' at airport/city/country level mainly * based on * opentraveldata as well as other mappings (airlines, currencies, ...). * This tool also provides classic time-oriented methods such as the @@ -30,23 +28,45 @@ import cats.implicits._ * {{{ * import com.geobase.GeoBase * - * val geoBase = new GeoBase() + * GeoBase.city("CDG") // Success("PAR") + * GeoBase.country("CDG") // Success("FR") + * GeoBase.continent("JFK") // Success("NA") + * GeoBase.iataZone("LON") // Success("21") + * GeoBase.currency("NYC") // Success("USD") + * GeoBase.countryForAirline("AF") // Success("FR") + * GeoBase.timeZone("PAR") // Success("Europe/Paris") + * GeoBase.distanceBetween("PAR", "NCE") // Success(686) + * GeoBase.localDateToGMT("20160606_2227", "NYC") // Success("20160607_0227") + * GeoBase.gmtDateToLocal("20160607_0227", "NYC") // Success("20160606_2227") + * GeoBase.offsetForLocalDate("20171224", "NYC") // Success(-300) + * GeoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") // Success(7.5d) + * GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) // Success(CONTINENTAL) + * GeoBase.nearbyAirports("CDG", 50) // Success(List("LBG", "ORY", "VIY", "POX")) + * GeoBase.nameOfAirline("AF") // Success("Air France") + * }}} + * + * and by pimping String: * - * assert(geoBase.city("CDG") == Success("PAR")) - * assert(geoBase.country("CDG") == Success("FR")) - * assert(geoBase.currency("NYC") == Success("USD")) - * assert(geoBase.countryForAirline("AF") == Success("FR")) - * assert(geoBase.distanceBetween("PAR", "NCE") == Success(686)) - * assert(geoBase.tripDurationFromLocalDates("20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d)) - * assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX"))) + * {{{ + * import com.geobase.GeoBase.StringExtensions + * + * "CDG".city // Success("PAR") + * "PAR".country // Success("FR") + * "CDG".continent // Success("EU") + * "CDG".iataZone // Success("21") + * "JFK".currency // Success("USD") + * "AF".name // Success("Air France") + * "CDG".timeZone // Success("Europe/Paris") + * "LON".distanceWith("NYC") // Success(5568) + * "CDG".nearbyAirports(50) // Success(List("LBG", "ORY", "VIY", "POX")) * }}} * * The GeoBase object can be used within Spark jobs (in this case, don't forget - * the possibility to '''broadcast GeoBase'''). + * to broadcast it. * * Opentraveldata is an accurate and maintained source of various travel - * mappings. This scala wrapper around opentraveldata mostly uses this - * file: + * mappings. This scala wrapper uses this file: + * * optd_por_public.csv. * * Getters all have a return type embedded within the Try monad. Throwing @@ -60,10 +80,8 @@ import cats.implicits._ * * @author Xavier Guihot * @since 2016-05 - * - * @constructor Creates a GeoBase object. */ -class GeoBase() extends Serializable { +object GeoBase extends Serializable { private lazy val airportsAndCities: Map[String, AirportOrCity] = Loader.loadAirportsAndCities() @@ -73,8 +91,8 @@ class GeoBase() extends Serializable { /** Returns the city associated to the given airport. * * {{{ - * assert(geoBase.city("CDG") == Success("PAR")) - * assert(geoBase.city("?*#") == Failure(GeoBaseException: Unknown airport "?*#") + * assert(GeoBase.city("CDG") == Success("PAR")) + * assert(GeoBase.city("?*#") == Failure(GeoBaseException: Unknown airport "?*#") * }}} * * @param airport the airport IATA code (for instance CDG) for which to get @@ -86,8 +104,7 @@ class GeoBase() extends Serializable { airportsAndCities .get(airport) .map(_.city) - .getOrElse( - Failure(GeoBaseException("Unknown airport \"" + airport + "\""))) + .getOrElse(Failure(BGEx("Unknown airport \"" + airport + "\""))) /** Returns the cities associated to the given airport. * @@ -99,9 +116,9 @@ class GeoBase() extends Serializable { * airport, which is by assumption the biggest corresponding city. * * {{{ - * assert(geoBase.cities("CDG") == Success(List("PAR"))) - * assert(geoBase.cities("AZA") == Success(List("PHX", "MSC"))) - * assert(geoBase.cities("?*#") == Failure(GeoBaseException: Unknown airport "?*#") + * assert(GeoBase.cities("CDG") == Success(List("PAR"))) + * assert(GeoBase.cities("AZA") == Success(List("PHX", "MSC"))) + * assert(GeoBase.cities("?*#") == Failure(GeoBaseException: Unknown airport "?*#") * }}} * * @param airport the airport IATA code (for instance AZA) for which to get @@ -113,15 +130,14 @@ class GeoBase() extends Serializable { airportsAndCities .get(airport) .map(_.cities) - .getOrElse( - Failure(GeoBaseException("Unknown airport \"" + airport + "\""))) + .getOrElse(Failure(BGEx("Unknown airport \"" + airport + "\""))) /** Returns the country associated to the given location (city or airport). * * {{{ - * assert(geoBase.country("PAR") == Success("FR")) - * assert(geoBase.country("ORY") == Success("FR")) - * assert(geoBase.country("?*#") == Failure(GeoBaseException: Unknown location "?*#")) + * assert(GeoBase.country("PAR") == Success("FR")) + * assert(GeoBase.country("ORY") == Success("FR")) + * assert(GeoBase.country("?*#") == Failure(GeoBaseException: Unknown location "?*#")) * }}} * * @param location the location IATA code (city or airport - for instance @@ -139,10 +155,9 @@ class GeoBase() extends Serializable { airportsAndCities .get(location) .map(_.country) - .getOrElse( - Failure(GeoBaseException("Unknown location \"" + location + "\""))) + .getOrElse(Failure(BGEx("Unknown location \"" + location + "\""))) - case _ => Failure(GeoBaseException("Unknown location \"" + location + "\"")) + case _ => Failure(BGEx("Unknown location \"" + location + "\"")) } /** Returns the continent associated to the given airport, city or country. @@ -151,10 +166,10 @@ class GeoBase() extends Serializable { * AF (Africa) - AS (Asia) - AN (Antarctica) - OC (Oceania). * * {{{ - * assert(geoBase.continent("CDG") == Success("EU")) // location is an airport - * assert(geoBase.continent("NYC") == Success("NA")) // location is a city - * assert(geoBase.continent("CN") == Success("AS")) // location is a country - * assert(geoBase.continent("?*#") == Failure(GeoBaseException: Unknown location "?*#")) + * assert(GeoBase.continent("CDG") == Success("EU")) // location is an airport + * assert(GeoBase.continent("NYC") == Success("NA")) // location is a city + * assert(GeoBase.continent("CN") == Success("AS")) // location is a country + * assert(GeoBase.continent("?*#") == Failure(GeoBaseException: Unknown location "?*#")) * }}} * * @param location the country, city or airport IATA code (for instance PAR) @@ -165,13 +180,12 @@ class GeoBase() extends Serializable { def continent(location: String): Try[String] = for { - country <- country(location) + country <- location.country continent <- countries .get(country) .map(_.continent) - .getOrElse( - Failure(GeoBaseException("Unknown country \"" + country + "\""))) + .getOrElse(Failure(BGEx("Unknown country \"" + country + "\""))) } yield continent @@ -180,10 +194,10 @@ class GeoBase() extends Serializable { * Possible values are 11, 12, 13, 21, 22, 23, 31, 32 or 33. * * {{{ - * assert(geoBase.iataZone("CDG") == Success("21")) - * assert(geoBase.iataZone("NYC") == Success("11")) - * assert(geoBase.iataZone("ZA") == Success("23")) - * assert(geoBase.iataZone("?*#") == Failure(GeoBaseException: Unknown location "?*#")) + * assert(GeoBase.iataZone("CDG") == Success("21")) + * assert(GeoBase.iataZone("NYC") == Success("11")) + * assert(GeoBase.iataZone("ZA") == Success("23")) + * assert(GeoBase.iataZone("?*#") == Failure(GeoBaseException: Unknown location "?*#")) * }}} * * @param location the country, city or airport IATA code (for instance PAR) @@ -194,13 +208,12 @@ class GeoBase() extends Serializable { def iataZone(location: String): Try[String] = for { - country <- country(location) + country <- location.country iataZone <- countries .get(country) .map(_.iataZone) - .getOrElse( - Failure(GeoBaseException("Unknown country \"" + country + "\""))) + .getOrElse(Failure(BGEx("Unknown country \"" + country + "\""))) } yield iataZone @@ -208,9 +221,9 @@ class GeoBase() extends Serializable { * country). * * {{{ - * assert(geoBase.currency("JFK") == Success("USD")) - * assert(geoBase.currency("FR") == Success("EUR")) - * assert(geoBase.currency("?#") == Failure(GeoBaseException: Unknown country "#?")) + * assert(GeoBase.currency("JFK") == Success("USD")) + * assert(GeoBase.currency("FR") == Success("EUR")) + * assert(GeoBase.currency("?#") == Failure(GeoBaseException: Unknown country "#?")) * }}} * * @param location the country, city or airport IATA code (for instance FR) @@ -221,21 +234,20 @@ class GeoBase() extends Serializable { def currency(location: String): Try[String] = for { - country <- country(location) + country <- location.country currency <- countries .get(country) .map(_.currency) - .getOrElse( - Failure(GeoBaseException("Unknown country \"" + country + "\""))) + .getOrElse(Failure(BGEx("Unknown country \"" + country + "\""))) } yield currency /** Returns the country associated to the given airline. * * {{{ - * assert(geoBase.countryForAirline("AF") == Success("FR")) - * assert(geoBase.countryForAirline("#?") == Failure(GeoBaseException: Unknown airline "#?")) + * assert(GeoBase.countryForAirline("AF") == Success("FR")) + * assert(GeoBase.countryForAirline("#?") == Failure(GeoBaseException: Unknown airline "#?")) * }}} * * @param airline the airline IATA code (for instance AF) for which to get @@ -247,14 +259,13 @@ class GeoBase() extends Serializable { airlines .get(airline) .map(_.country) - .getOrElse( - Failure(GeoBaseException("Unknown airline \"" + airline + "\""))) + .getOrElse(Failure(BGEx("Unknown airline \"" + airline + "\""))) /** Returns the name associated to the given airline. * * {{{ - * assert(geoBase.nameOfAirline("AF") == Success("Air France")) - * assert(geoBase.nameOfAirline("#?") == Failure(GeoBaseException: Unknown airline "#?")) + * assert(GeoBase.nameOfAirline("AF") == Success("Air France")) + * assert(GeoBase.nameOfAirline("#?") == Failure(GeoBaseException: Unknown airline "#?")) * }}} * * @param airline the airline IATA code (for instance AF) for which to get @@ -266,15 +277,14 @@ class GeoBase() extends Serializable { airlines .get(airline) .map(_.name) - .getOrElse( - Failure(GeoBaseException("Unknown airline \"" + airline + "\""))) + .getOrElse(Failure(BGEx("Unknown airline \"" + airline + "\""))) /** Returns the time zone associated to the given airport or city. * * {{{ - * assert(geoBase.timeZone("CDG") == Success("Europe/Paris")) - * assert(geoBase.timeZone("BOS") == Success("America/New_York")) - * assert(geoBase.timeZone("?*#") == Failure(GeoBaseException: Unknown location "?*#")) + * assert(GeoBase.timeZone("CDG") == Success("Europe/Paris")) + * assert(GeoBase.timeZone("BOS") == Success("America/New_York")) + * assert(GeoBase.timeZone("?*#") == Failure(GeoBaseException: Unknown location "?*#")) * }}} * * @param location the city or airport IATA code (for instance PAR) for which @@ -286,15 +296,14 @@ class GeoBase() extends Serializable { airportsAndCities .get(location) .map(_.timeZone) - .getOrElse( - Failure(GeoBaseException("Unknown location \"" + location + "\""))) + .getOrElse(Failure(BGEx("Unknown location \"" + location + "\""))) /** Returns the distance between two locations (airports/cities). * * {{{ - * assert(geoBase.distanceBetween("ORY", "NCE") == Success(674)) - * assert(geoBase.distanceBetween("PAR", "NCE") == Success(686)) - * assert(geoBase.distanceBetween("PAR", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) + * assert(GeoBase.distanceBetween("ORY", "NCE") == Success(674)) + * assert(GeoBase.distanceBetween("PAR", "NCE") == Success(686)) + * assert(GeoBase.distanceBetween("PAR", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) * }}} * * @param locationA an airport or city IATA code (for instance ORY) for which @@ -310,13 +319,11 @@ class GeoBase() extends Serializable { locationDetailsA <- airportsAndCities .get(locationA) .map(Success(_)) - .getOrElse( - Failure(GeoBaseException("Unknown location \"" + locationA + "\""))) + .getOrElse(Failure(BGEx("Unknown location \"" + locationA + "\""))) locationDetailsB <- airportsAndCities .get(locationB) .map(Success(_)) - .getOrElse( - Failure(GeoBaseException("Unknown location \"" + locationB + "\""))) + .getOrElse(Failure(BGEx("Unknown location \"" + locationB + "\""))) latA <- locationDetailsA.latitude lngA <- locationDetailsA.longitude @@ -340,9 +347,9 @@ class GeoBase() extends Serializable { * airport or the city as a parameter. * * {{{ - * assert(geoBase.localDateToGMT("20160606_2227", "NYC") == Success("20160607_0227")) - * assert(geoBase.localDateToGMT("2016-06-06T22:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-07T02:27")) - * assert(geoBase.localDateToGMT("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) + * assert(GeoBase.localDateToGMT("20160606_2227", "NYC") == Success("20160607_0227")) + * assert(GeoBase.localDateToGMT("2016-06-06T22:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-07T02:27")) + * assert(GeoBase.localDateToGMT("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) * }}} * * @param localDate the local date at the given location under the given @@ -374,11 +381,11 @@ class GeoBase() extends Serializable { /** Returns the offset in minutes for the given date at the given city/airport. * * {{{ - * assert(geoBase.offsetForLocalDate("20170712", "NCE") == Success(120)) - * assert(geoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") == Success(120)) - * assert(geoBase.offsetForLocalDate("20171224", "NCE") == Success(60)) - * assert(geoBase.offsetForLocalDate("20171224", "NYC") == Success(-300)) - * assert(geoBase.offsetForLocalDate("20171224", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) + * assert(GeoBase.offsetForLocalDate("20170712", "NCE") == Success(120)) + * assert(GeoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") == Success(120)) + * assert(GeoBase.offsetForLocalDate("20171224", "NCE") == Success(60)) + * assert(GeoBase.offsetForLocalDate("20171224", "NYC") == Success(-300)) + * assert(GeoBase.offsetForLocalDate("20171224", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) * }}} * * @param localDate the local date @@ -393,10 +400,10 @@ class GeoBase() extends Serializable { location: String, format: String = "yyyyMMdd" ): Try[Int] = - timeZone(location).map(timeZone => { + timeZone(location).map { timeZone => val dateTime = new SimpleDateFormat(format).parse(localDate).getTime TimeZone.getTimeZone(timeZone).getOffset(dateTime) / 60000 - }) + } /** Transforms a GMT date into a local date for the given airport or city. * @@ -406,9 +413,9 @@ class GeoBase() extends Serializable { * airport or the city as a parameter. * * {{{ - * assert(geoBase.gmtDateToLocal("20160606_1427", "NCE") == Success("20160606_1627")) - * assert(geoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-06T22:27")) - * assert(geoBase.gmtDateToLocal("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) + * assert(GeoBase.gmtDateToLocal("20160606_1427", "NCE") == Success("20160606_1627")) + * assert(GeoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") == Success("2016-06-06T22:27")) + * assert(GeoBase.gmtDateToLocal("20160606_2227", "~#?") == Failure(GeoBaseException: Unknown location "~#?")) * }}} * * @param gmtDate the GMT date @@ -447,10 +454,10 @@ class GeoBase() extends Serializable { * time. i.e. when we don't have gmt times. * * {{{ - * assert(geoBase.tripDurationFromLocalDates( + * assert(GeoBase.tripDurationFromLocalDates( * "20160606_1627", "CDG", "20160606_1757", "JFK") == Success(7.5d)) * - * val computedTripDuration = geoBase.tripDurationFromLocalDates( + * val computedTripDuration = GeoBase.tripDurationFromLocalDates( * "2016-06-06T16:27", "CDG", "2016-06-06T17:57", "JFK", * format = "yyyy-MM-dd'T'HH:mm", unit = MINUTES * ) @@ -486,7 +493,8 @@ class GeoBase() extends Serializable { gmtArrDate <- localDateToGMT( localArrivalDate, destinationLocation, - format) + format + ) tripDuration <- { @@ -499,7 +507,7 @@ class GeoBase() extends Serializable { if (tripDurationMillis < 0) Failure( - GeoBaseException( + BGEx( "The trip duration computed is negative (maybe you've " + "inverted departure/origin and arrival/destination)")) else @@ -518,11 +526,11 @@ class GeoBase() extends Serializable { * iata zones. * * {{{ - * assert(geoBase.geoType(List("CDG", "ORY")) == Success(DOMESTIC)) - * assert(geoBase.geoType(List("FR", "FR")) == Success(DOMESTIC)) - * assert(geoBase.geoType(List("FR", "PAR", "DUB")) == Success(CONTINENTAL)) - * assert(geoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) == Success(INTER_CONTINENTAL)) - * assert(geoBase.geoType(List("US", "bbb", "NCE", "aaa")) == Failure(GeoBaseException: Unknown locations \"bbb\", \"aaa\")) + * assert(GeoBase.geoType(List("CDG", "ORY")) == Success(DOMESTIC)) + * assert(GeoBase.geoType(List("FR", "FR")) == Success(DOMESTIC)) + * assert(GeoBase.geoType(List("FR", "PAR", "DUB")) == Success(CONTINENTAL)) + * assert(GeoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) == Success(INTER_CONTINENTAL)) + * assert(GeoBase.geoType(List("US", "bbb", "NCE", "aaa")) == Failure(GeoBaseException: Unknown locations \"bbb\", \"aaa\")) * }}} * * @param locations a list of cities/airports/countries representing the trip @@ -532,7 +540,8 @@ class GeoBase() extends Serializable { require( locations.length >= 2, - "at least 2 locations are needed to compute a geography type") + "at least 2 locations are needed to compute a geography type" + ) for { @@ -569,9 +578,9 @@ class GeoBase() extends Serializable { * sorted starting from the closest airport. * * {{{ - * assert(geoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX"))) - * assert(geoBase.nearbyAirports("CDG", 36) == Success(List("LBG", "ORY"))) - * assert(geoBase.nearbyAirports("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\"")) + * assert(GeoBase.nearbyAirports("CDG", 50) == Success(List("LBG", "ORY", "VIY", "POX"))) + * assert(GeoBase.nearbyAirports("CDG", 36) == Success(List("LBG", "ORY"))) + * assert(GeoBase.nearbyAirports("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\"")) * }}} * * @param location the airport or city for which to find nearby airports @@ -592,9 +601,9 @@ class GeoBase() extends Serializable { * (airport/distance). * * {{{ - * assert(geoBase.nearbyAirportsWithDetails("CDG", 50) == Success(List(("LBG", 9), ("ORY", 35), ("VIY", 37), ("POX", 38)))) - * assert(geoBase.nearbyAirportsWithDetails("CDG", 36) == Success(List(("LBG", 9), ("ORY", 35)))) - * assert(geoBase.nearbyAirportsWithDetails("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\"")) + * assert(GeoBase.nearbyAirportsWithDetails("CDG", 50) == Success(List(("LBG", 9), ("ORY", 35), ("VIY", 37), ("POX", 38)))) + * assert(GeoBase.nearbyAirportsWithDetails("CDG", 36) == Success(List(("LBG", 9), ("ORY", 35)))) + * assert(GeoBase.nearbyAirportsWithDetails("~#?", 36)) == Failure(GeoBaseException: Unknown location \"~#?\"")) * }}} * * @param location the airport or city for which to find nearby airports. @@ -627,6 +636,161 @@ class GeoBase() extends Serializable { Success(nearbyAirports.sortWith(_._2 < _._2)) // Sorted per increasing radius } else - Failure(GeoBaseException("Unknown location \"" + location + "\"")) + Failure(BGEx("Unknown location \"" + location + "\"")) + } + + implicit class StringExtensions(val string: String) extends AnyVal { + + /** Returns the city associated to the given airport. + * + * {{{ + * assert("CDG".city == Success("PAR")) + * assert("?*#".city == Failure(GeoBaseException: Unknown airport "?*#") + * }}} + * + * @return the city code corresponding to the given airport (for instance + * PAR). + */ + def city: Try[String] = GeoBase.city(string) + + /** Returns the cities associated to the given airport. + * + * It sometimes happens that an airport is shared between cities. This + * method, returns this list of cities (usually the list will only contain + * one city). + * + * The city method returns the first city corresponding to the given + * airport, which is by assumption the biggest corresponding city. + * + * {{{ + * assert("CDG".cities == Success(List("PAR"))) + * assert("AZA".cities == Success(List("PHX", "MSC"))) + * assert("?*#".cities == Failure(GeoBaseException: Unknown airport "?*#") + * }}} + * + * @return the list of city codes corresponding to the given airport (for + * instance List("PHX", "MSC")). + */ + def cities: Try[List[String]] = GeoBase.cities(string) + + /** Returns the country associated to the given location (city or airport). + * + * {{{ + * assert("PAR".country == Success("FR")) + * assert("ORY".country == Success("FR")) + * assert("?*#".country == Failure(GeoBaseException: Unknown location "?*#")) + * }}} + * + * @return the country code corresponding to the given city or airport (for + * instance FR). + */ + def country: Try[String] = GeoBase.country(string) + + /** Returns the continent associated to the given airport, city or country. + * + * Possible values: EU (Europe) - NA (North America) - SA (South Africa) - + * AF (Africa) - AS (Asia) - AN (Antarctica) - OC (Oceania). + * + * {{{ + * assert("CDG".continent == Success("EU")) // location is an airport + * assert("NYC".continent == Success("NA")) // location is a city + * assert("CN".continent == Success("AS")) // location is a country + * assert("?*#".continent == Failure(GeoBaseException: Unknown location "?*#")) + * }}} + * + * @return the continent code corresponding to the given location (for + * instance EU). + */ + def continent: Try[String] = GeoBase.continent(string) + + /** Returns the IATA zone associated to the given airport, city or country. + * + * Possible values are 11, 12, 13, 21, 22, 23, 31, 32 or 33. + * + * {{{ + * assert("CDG".iataZone == Success("21")) + * assert("NYC".iataZone == Success("11")) + * assert("ZA".iataZone == Success("23")) + * assert("?*#".iataZone == Failure(GeoBaseException: Unknown location "?*#")) + * }}} + * + * @return the IATA zone code corresponding to the given location (for + * instance 21). + */ + def iataZone: Try[String] = GeoBase.iataZone(string) + + /** Returns the currency associated to the given location (airport, city or + * country). + * + * {{{ + * assert("JFK".currency == Success("USD")) + * assert("FR".currency == Success("EUR")) + * assert("?#".currency == Failure(GeoBaseException: Unknown country "#?")) + * }}} + * + * @return the currency code corresponding to the given location (for + * instance EUR). + */ + def currency: Try[String] = GeoBase.currency(string) + + /** Returns the name associated to the given airline. + * + * {{{ + * assert("AF".name == Success("Air France")) + * assert("#?".name == Failure(GeoBaseException: Unknown airline "#?")) + * }}} + * + * @return the name corresponding to the given airline (for instance + * Air France). + */ + def name: Try[String] = GeoBase.nameOfAirline(string) + + /** Returns the time zone associated to the given airport or city. + * + * {{{ + * assert("CDG".timeZone == Success("Europe/Paris")) + * assert("BOS".timeZone == Success("America/New_York")) + * assert("?*#".timeZone == Failure(GeoBaseException: Unknown location "?*#")) + * }}} + * + * @return the time zone corresponding to the given location (for instance + * Europe/Paris). + */ + def timeZone: Try[String] = GeoBase.timeZone(string) + + /** Returns the distance between two locations (airports/cities). + * + * {{{ + * assert("ORY".distanceWith("NCE") == Success(674)) + * assert("PAR".distanceWith("NCE") == Success(686)) + * assert("PAR".distanceWith("~#?") == Failure(GeoBaseException: Unknown location "~#?")) + * }}} + * + * @param location an airport or city IATA code (for instance NCE) for + * which to get the distance with the location this is called for. + * @return the distance rounded in km between locationA and locationB (for + * instance 674 km). + */ + def distanceWith(location: String): Try[Int] = + GeoBase.distanceBetween(string, location) + + /** Returns the list of nearby airports (within the radius) for the given + * airport or city. + * + * Find the list of nearby airports, within the requested radius. The list + * is sorted starting from the closest airport. + * + * {{{ + * assert("CDG".nearbyAirports(50) == Success(List("LBG", "ORY", "VIY", "POX"))) + * assert("CDG".nearbyAirports(36) == Success(List("LBG", "ORY"))) + * assert("~#?".nearbyAirports(36)) == Failure(GeoBaseException: Unknown location \"~#?\"")) + * }}} + * + * @param radius the maximum distance (in km) for which an airport is + * considered close. + * @return the sorted per increasing distance list nearby airports + */ + def nearbyAirports(radius: Int): Try[List[String]] = + GeoBase.nearbyAirports(string, radius) } } diff --git a/src/main/scala/com/geobase/load/Loader.scala b/src/main/scala/com/geobase/load/Loader.scala index 3050d84..014ec3e 100644 --- a/src/main/scala/com/geobase/load/Loader.scala +++ b/src/main/scala/com/geobase/load/Loader.scala @@ -18,6 +18,8 @@ private[geobase] object Loader { */ def loadAirportsAndCities(): Map[String, AirportOrCity] = { + println("GeoBase: Loading airports and cities") + Source .fromURL(getClass.getResource("/optd_por_public.csv"), "UTF-8") .getLines() @@ -55,10 +57,12 @@ private[geobase] object Loader { def loadCountries(): Map[String, Country] = { + println("GeoBase: Loading countries") + Source .fromURL(getClass.getResource("/countries.csv")) .getLines() - .filter(!_.startsWith("#")) // Remove the header + .drop(1) // Remove the header .map(line => { val splitLine = line.split("\\^", -1) @@ -69,7 +73,8 @@ private[geobase] object Loader { countryCode = countryCode, currencyCode = splitLine(1), continentCode = splitLine(2), - iataZoneCode = splitLine(3)) + iataZoneCode = splitLine(3) + ) (countryCode, country) }) @@ -78,11 +83,13 @@ private[geobase] object Loader { def loadAirlines(): Map[String, Airline] = { + println("GeoBase: Loading airlines") + // Airline code to airline name: val airlineNames = Source .fromURL(getClass.getResource("/optd_airlines.csv")) .getLines() - .filter(!_.startsWith("pk^")) // Remove the header + .drop(1) // Remove the header .map(line => { val splitLine = line.split("\\^", -1) @@ -98,7 +105,7 @@ private[geobase] object Loader { val airlineCountries = Source .fromURL(getClass.getResource("/airlines.csv")) .getLines() - .filter(!_.startsWith("#")) // Remove the header + .drop(1) // Remove the header .map(line => { val splitLine = line.split("\\^", -1) diff --git a/src/main/scala/com/geobase/model/AirportOrCity.scala b/src/main/scala/com/geobase/model/AirportOrCity.scala index c2587c2..d2b506d 100644 --- a/src/main/scala/com/geobase/model/AirportOrCity.scala +++ b/src/main/scala/com/geobase/model/AirportOrCity.scala @@ -36,10 +36,7 @@ private[geobase] final case class AirportOrCity( def isAirport: Boolean = locationType == "A" - def city: Try[String] = cities match { - case Success(city :: _) => Success(city) - case Failure(exception) => Failure(exception) - } + def city: Try[String] = cities.map { case city :: _ => city } def cities: Try[List[String]] = cityCode.length match { diff --git a/src/test/scala/com/geobase/GeoBaseTest.scala b/src/test/scala/com/geobase/GeoBaseTest.scala index 9dad99e..d8d1331 100644 --- a/src/test/scala/com/geobase/GeoBaseTest.scala +++ b/src/test/scala/com/geobase/GeoBaseTest.scala @@ -1,5 +1,6 @@ package com.geobase +import com.geobase.GeoBase.StringExtensions import com.geobase.error.GeoBaseException import com.geobase.model.MINUTES import com.geobase.model.{DOMESTIC, CONTINENTAL, INTER_CONTINENTAL} @@ -8,247 +9,274 @@ import scala.util.Success import org.scalatest.FunSuite +import com.holdenkarau.spark.testing.SharedSparkContext + /** Testing facility for GeoBase. * * @author Xavier Guihot * @since 2016-05 */ -class GeoBaseTest extends FunSuite { - - private val geoBase = new GeoBase() +class GeoBaseTest extends FunSuite with SharedSparkContext { // Let's load data (loading is lazy) in order not to impact tests duration: - geoBase.city("ORY") - geoBase.continent("FR") - geoBase.countryForAirline("BA") + GeoBase.city("ORY") + GeoBase.continent("FR") + GeoBase.countryForAirline("BA") test("Airport to city") { // Basic cases: - assert(geoBase.city("ORY") === Success("PAR")) - assert(geoBase.city("CDG") === Success("PAR")) - assert(geoBase.city("JFK") === Success("NYC")) - assert(geoBase.city("NCE") === Success("NCE")) + assert(GeoBase.city("ORY") === Success("PAR")) + assert(GeoBase.city("CDG") === Success("PAR")) + assert(GeoBase.city("JFK") === Success("NYC")) + assert(GeoBase.city("NCE") === Success("NCE")) // Case where several cities are given for one airport: - assert(geoBase.city("AZA") === Success("PHX")) // PHX,MSC + assert(GeoBase.city("AZA") === Success("PHX")) // PHX,MSC // Unknown airport: val exceptionThrown = intercept[GeoBaseException] { - geoBase.city("...").get + GeoBase.city("...").get } assert(exceptionThrown.getMessage === "Unknown airport \"...\"") // A city as input will return the city itself: - assert(geoBase.city("PAR") === Success("PAR")) + assert(GeoBase.city("PAR") === Success("PAR")) + + // Pimped case: + assert("CDG".city === Success("PAR")) } test("Airport to cities") { // Basic cases: - assert(geoBase.cities("ORY") === Success(List("PAR"))) - assert(geoBase.cities("CDG") === Success(List("PAR"))) - assert(geoBase.cities("JFK") === Success(List("NYC"))) - assert(geoBase.cities("NCE") === Success(List("NCE"))) + assert(GeoBase.cities("ORY") === Success(List("PAR"))) + assert(GeoBase.cities("CDG") === Success(List("PAR"))) + assert(GeoBase.cities("JFK") === Success(List("NYC"))) + assert(GeoBase.cities("NCE") === Success(List("NCE"))) // Case where several cities are given for one airport: - assert(geoBase.cities("AZA") === Success(List("PHX", "MSC"))) + assert(GeoBase.cities("AZA") === Success(List("PHX", "MSC"))) // Unknown airport: val exceptionThrown = intercept[GeoBaseException] { - geoBase.cities("...").get + GeoBase.cities("...").get } assert(exceptionThrown.getMessage === "Unknown airport \"...\"") // A city as input will return the city itself: - assert(geoBase.cities("PAR") === Success(List("PAR"))) + assert(GeoBase.cities("PAR") === Success(List("PAR"))) + + // Pimped case: + assert("ORY".cities === Success(List("PAR"))) } test("Location to country") { - assert(geoBase.country("ORY") === Success("FR")) - assert(geoBase.country("CDG") === Success("FR")) - assert(geoBase.country("JFK") === Success("US")) - assert(geoBase.country("NCE") === Success("FR")) - assert(geoBase.country("PAR") === Success("FR")) - assert(geoBase.country("FR") === Success("FR")) + assert(GeoBase.country("ORY") === Success("FR")) + assert(GeoBase.country("CDG") === Success("FR")) + assert(GeoBase.country("JFK") === Success("US")) + assert(GeoBase.country("NCE") === Success("FR")) + assert(GeoBase.country("PAR") === Success("FR")) + assert(GeoBase.country("FR") === Success("FR")) // Unknown airport/city: var exceptionThrown = intercept[GeoBaseException] { - geoBase.country("...").get + GeoBase.country("...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") // Unknown country: - exceptionThrown = intercept[GeoBaseException] { geoBase.country("").get } + exceptionThrown = intercept[GeoBaseException] { GeoBase.country("").get } assert(exceptionThrown.getMessage === "Unknown location \"\"") + + // Pimped case: + assert("ORY".country === Success("FR")) } test("Location to continent") { // Various input location types (airport, city, country): - assert(geoBase.continent("ORY") === Success("EU")) - assert(geoBase.continent("LON") === Success("EU")) - assert(geoBase.continent("FR") === Success("EU")) - assert(geoBase.continent("JFK") === Success("NA")) - assert(geoBase.continent("AU") === Success("OC")) - assert(geoBase.continent("HK") === Success("AS")) - assert(geoBase.continent("BUE") === Success("SA")) - assert(geoBase.continent("AN") === Success("NA")) - assert(geoBase.continent("ZA") === Success("AF")) + assert(GeoBase.continent("ORY") === Success("EU")) + assert(GeoBase.continent("LON") === Success("EU")) + assert(GeoBase.continent("FR") === Success("EU")) + assert(GeoBase.continent("JFK") === Success("NA")) + assert(GeoBase.continent("AU") === Success("OC")) + assert(GeoBase.continent("HK") === Success("AS")) + assert(GeoBase.continent("BUE") === Success("SA")) + assert(GeoBase.continent("AN") === Success("NA")) + assert(GeoBase.continent("ZA") === Success("AF")) // Unknown location: val exceptionThrown = intercept[GeoBaseException] { - geoBase.continent("..").get + GeoBase.continent("..").get } assert(exceptionThrown.getMessage === "Unknown country \"..\"") + + // Pimped case: + assert("ORY".continent === Success("EU")) } test("Location to iata zone") { // Various input location types (airport, city, country): - assert(geoBase.iataZone("ORY") === Success("21")) - assert(geoBase.iataZone("LON") === Success("21")) - assert(geoBase.iataZone("FR") === Success("21")) - assert(geoBase.iataZone("JFK") === Success("11")) - assert(geoBase.iataZone("AU") === Success("32")) - assert(geoBase.iataZone("HK") === Success("31")) - assert(geoBase.iataZone("BUE") === Success("13")) - assert(geoBase.iataZone("ZA") === Success("23")) + assert(GeoBase.iataZone("ORY") === Success("21")) + assert(GeoBase.iataZone("LON") === Success("21")) + assert(GeoBase.iataZone("FR") === Success("21")) + assert(GeoBase.iataZone("JFK") === Success("11")) + assert(GeoBase.iataZone("AU") === Success("32")) + assert(GeoBase.iataZone("HK") === Success("31")) + assert(GeoBase.iataZone("BUE") === Success("13")) + assert(GeoBase.iataZone("ZA") === Success("23")) // Unknown location: val exceptionThrown = intercept[GeoBaseException] { - geoBase.iataZone("..").get + GeoBase.iataZone("..").get } assert(exceptionThrown.getMessage === "Unknown country \"..\"") + + // Pimped case: + assert("ORY".iataZone === Success("21")) } test("Location to currency") { // Various input location types (airport, city, country): - assert(geoBase.currency("PAR") === Success("EUR")) - assert(geoBase.currency("JFK") === Success("USD")) - assert(geoBase.currency("FR") === Success("EUR")) - assert(geoBase.currency("AU") === Success("AUD")) + assert(GeoBase.currency("PAR") === Success("EUR")) + assert(GeoBase.currency("JFK") === Success("USD")) + assert(GeoBase.currency("FR") === Success("EUR")) + assert(GeoBase.currency("AU") === Success("AUD")) // Unknown location: val exceptionThrown = intercept[GeoBaseException] { - geoBase.currency("..").get + GeoBase.currency("..").get } assert(exceptionThrown.getMessage === "Unknown country \"..\"") + + // Pimped case: + assert("PAR".currency === Success("EUR")) } test("Airline to country") { - assert(geoBase.countryForAirline("BA") === Success("GB")) - assert(geoBase.countryForAirline("AF") === Success("FR")) - assert(geoBase.countryForAirline("AA") === Success("US")) - assert(geoBase.countryForAirline("LH") === Success("DE")) + assert(GeoBase.countryForAirline("BA") === Success("GB")) + assert(GeoBase.countryForAirline("AF") === Success("FR")) + assert(GeoBase.countryForAirline("AA") === Success("US")) + assert(GeoBase.countryForAirline("LH") === Success("DE")) // Unknown airline: val exceptionThrown = intercept[GeoBaseException] { - geoBase.countryForAirline("..").get + GeoBase.countryForAirline("..").get } assert(exceptionThrown.getMessage === "Unknown airline \"..\"") } test("Airline to airline name") { - assert(geoBase.nameOfAirline("BA") === Success("British Airways")) - assert(geoBase.nameOfAirline("AF") === Success("Air France")) - assert(geoBase.nameOfAirline("AA") === Success("American Airlines")) - assert(geoBase.nameOfAirline("LH") === Success("Lufthansa")) - assert(geoBase.nameOfAirline("AH") === Success("Air Algerie")) + assert(GeoBase.nameOfAirline("BA") === Success("British Airways")) + assert(GeoBase.nameOfAirline("AF") === Success("Air France")) + assert(GeoBase.nameOfAirline("AA") === Success("American Airlines")) + assert(GeoBase.nameOfAirline("LH") === Success("Lufthansa")) + assert(GeoBase.nameOfAirline("AH") === Success("Air Algerie")) // Several names for this airline code: - assert(geoBase.nameOfAirline("5K") === Success("Hi Fly")) + assert(GeoBase.nameOfAirline("5K") === Success("Hi Fly")) // Unknown airline: val exceptionThrown = intercept[GeoBaseException] { - geoBase.nameOfAirline("..").get + GeoBase.nameOfAirline("..").get } assert(exceptionThrown.getMessage === "Unknown airline \"..\"") + + // Pimped case: + assert("BA".name === Success("British Airways")) } test("Location to time zone") { - assert(geoBase.timeZone("CDG") === Success("Europe/Paris")) - assert(geoBase.timeZone("PAR") === Success("Europe/Paris")) - assert(geoBase.timeZone("JFK") === Success("America/New_York")) - assert(geoBase.timeZone("NYC") === Success("America/New_York")) - assert(geoBase.timeZone("BOS") === Success("America/New_York")) - assert(geoBase.timeZone("LAX") === Success("America/Los_Angeles")) - assert(geoBase.timeZone("DUB") === Success("Europe/Dublin")) + assert(GeoBase.timeZone("CDG") === Success("Europe/Paris")) + assert(GeoBase.timeZone("PAR") === Success("Europe/Paris")) + assert(GeoBase.timeZone("JFK") === Success("America/New_York")) + assert(GeoBase.timeZone("NYC") === Success("America/New_York")) + assert(GeoBase.timeZone("BOS") === Success("America/New_York")) + assert(GeoBase.timeZone("LAX") === Success("America/Los_Angeles")) + assert(GeoBase.timeZone("DUB") === Success("Europe/Dublin")) // Unknown location: val exceptionThrown = intercept[GeoBaseException] { - geoBase.timeZone("...").get + GeoBase.timeZone("...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") + + // Pimped case: + assert("CDG".timeZone === Success("Europe/Paris")) } test("Distance between two locations") { - assert(geoBase.distanceBetween("ORY", "NCE") === Success(676)) - assert(geoBase.distanceBetween("NCE", "ORY") === Success(676)) + assert(GeoBase.distanceBetween("ORY", "NCE") === Success(676)) + assert(GeoBase.distanceBetween("NCE", "ORY") === Success(676)) - assert(geoBase.distanceBetween("ORY", "CDG") === Success(35)) + assert(GeoBase.distanceBetween("ORY", "CDG") === Success(35)) - assert(geoBase.distanceBetween("ORY", "ORY") === Success(0)) + assert(GeoBase.distanceBetween("ORY", "ORY") === Success(0)) // Unknown airport/city: var exceptionThrown = intercept[GeoBaseException] { - geoBase.distanceBetween("...", "CDG").get + GeoBase.distanceBetween("...", "CDG").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") exceptionThrown = intercept[GeoBaseException] { - geoBase.distanceBetween("CDG", "...").get + GeoBase.distanceBetween("CDG", "...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") + + // Pimped case: + assert("ORY".distanceWith("NCE") === Success(676)) } test("Geo Type from locations (domestic, conti., interconti.)") { - var computedGeoType = geoBase.geoType(List("CDG", "ORY")) + var computedGeoType = GeoBase.geoType(List("CDG", "ORY")) assert(computedGeoType === Success(DOMESTIC)) - computedGeoType = geoBase.geoType(List("CDG", "PAR")) + computedGeoType = GeoBase.geoType(List("CDG", "PAR")) assert(computedGeoType === Success(DOMESTIC)) - computedGeoType = geoBase.geoType(List("CDG", "NCE", "NCE", "TLS")) + computedGeoType = GeoBase.geoType(List("CDG", "NCE", "NCE", "TLS")) assert(computedGeoType === Success(DOMESTIC)) - computedGeoType = geoBase.geoType(List("CDG", "NCE", "NCE", "CDG")) + computedGeoType = GeoBase.geoType(List("CDG", "NCE", "NCE", "CDG")) assert(computedGeoType === Success(DOMESTIC)) - computedGeoType = geoBase.geoType(List("CDG", "FRA")) + computedGeoType = GeoBase.geoType(List("CDG", "FRA")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) + computedGeoType = GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("CDG", "TLS", "DUB", "FRA", "CDG")) + computedGeoType = GeoBase.geoType(List("CDG", "TLS", "DUB", "FRA", "CDG")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("CDG", "JFK")) + computedGeoType = GeoBase.geoType(List("CDG", "JFK")) assert(computedGeoType === Success(INTER_CONTINENTAL)) - computedGeoType = geoBase.geoType(List("PAR", "JFK")) + computedGeoType = GeoBase.geoType(List("PAR", "JFK")) assert(computedGeoType === Success(INTER_CONTINENTAL)) - computedGeoType = geoBase.geoType(List("PAR", "NYC")) + computedGeoType = GeoBase.geoType(List("PAR", "NYC")) assert(computedGeoType === Success(INTER_CONTINENTAL)) - computedGeoType = geoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) + computedGeoType = GeoBase.geoType(List("CDG", "TLS", "JFK", "MEX")) assert(computedGeoType === Success(INTER_CONTINENTAL)) - computedGeoType = geoBase.geoType(List("FR", "FR")) + computedGeoType = GeoBase.geoType(List("FR", "FR")) assert(computedGeoType === Success(DOMESTIC)) - computedGeoType = geoBase.geoType(List("FR", "FR", "DE")) + computedGeoType = GeoBase.geoType(List("FR", "FR", "DE")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("FR", "GB", "DE")) + computedGeoType = GeoBase.geoType(List("FR", "GB", "DE")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("FR", "PAR", "DUB")) + computedGeoType = GeoBase.geoType(List("FR", "PAR", "DUB")) assert(computedGeoType === Success(CONTINENTAL)) - computedGeoType = geoBase.geoType(List("US", "PAR", "DUB")) + computedGeoType = GeoBase.geoType(List("US", "PAR", "DUB")) assert(computedGeoType === Success(INTER_CONTINENTAL)) // Empty list of airports/cities: val invalidExceptionThrown = intercept[IllegalArgumentException] { - geoBase.geoType(List("CDG")).get + GeoBase.geoType(List("CDG")).get } val invalidExpectedMessage = "requirement failed: at least 2 locations are needed to compute a " + @@ -257,25 +285,25 @@ class GeoBaseTest extends FunSuite { // Unknown airport/city: var exceptionThrown = intercept[GeoBaseException] { - geoBase.geoType(List("CDG", "...")).get + GeoBase.geoType(List("CDG", "...")).get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") exceptionThrown = intercept[GeoBaseException] { - geoBase.geoType(List("US", "CDG", "NCE", "aaa")).get + GeoBase.geoType(List("US", "CDG", "NCE", "aaa")).get } assert(exceptionThrown.getMessage === "Unknown location \"aaa\"") exceptionThrown = intercept[GeoBaseException] { - geoBase.geoType(List("US", "bbb", "NCE", "aaa")).get + GeoBase.geoType(List("US", "bbb", "NCE", "aaa")).get } assert(exceptionThrown.getMessage === "Unknown location \"bbb\"") // Unknown IATA zone for a country: exceptionThrown = intercept[GeoBaseException] { - geoBase.geoType(List("FR", "XX")).get + GeoBase.geoType(List("FR", "XX")).get } assert(exceptionThrown.getMessage === "Unknown country \"XX\"") exceptionThrown = intercept[GeoBaseException] { - geoBase.geoType(List("FR", "XX", "..")).get + GeoBase.geoType(List("FR", "XX", "..")).get } assert(exceptionThrown.getMessage === "Unknown country \"XX\"") } @@ -283,52 +311,52 @@ class GeoBaseTest extends FunSuite { test("Local date to gmt date") { // 1: French summer time: - var gmtDate = geoBase.localDateToGMT("20160606_1627", "NCE") + var gmtDate = GeoBase.localDateToGMT("20160606_1627", "NCE") assert(gmtDate === Success("20160606_1427")) // 2: LON - gmtDate = geoBase.localDateToGMT("20160606_1527", "LON") + gmtDate = GeoBase.localDateToGMT("20160606_1527", "LON") assert(gmtDate === Success("20160606_1427")) // 3: NYC: - gmtDate = geoBase.localDateToGMT("20160606_1027", "JFK") + gmtDate = GeoBase.localDateToGMT("20160606_1027", "JFK") assert(gmtDate === Success("20160606_1427")) // 4: With a change of day: - gmtDate = geoBase.localDateToGMT("20160606_2227", "NYC") + gmtDate = GeoBase.localDateToGMT("20160606_2227", "NYC") assert(gmtDate === Success("20160607_0227")) // 5: French winter time: - gmtDate = geoBase.localDateToGMT("20160212_1627", "NCE") + gmtDate = GeoBase.localDateToGMT("20160212_1627", "NCE") assert(gmtDate === Success("20160212_1527")) // 6: Another format: - gmtDate = geoBase + gmtDate = GeoBase .localDateToGMT("2016-06-06T22:27", "NYC", "yyyy-MM-dd'T'HH:mm") assert(gmtDate === Success("2016-06-07T02:27")) // 7: With an invalid airport/city: val exceptionThrown = intercept[GeoBaseException] { - geoBase.localDateToGMT("20160212_1627", "...").get + GeoBase.localDateToGMT("20160212_1627", "...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") } test("Offset from local date") { - var offset = geoBase.offsetForLocalDate("20170712", "NCE") + var offset = GeoBase.offsetForLocalDate("20170712", "NCE") assert(offset === Success(120)) - offset = geoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") + offset = GeoBase.offsetForLocalDate("2017-07-12", "NCE", "yyyy-MM-dd") assert(offset === Success(120)) - offset = geoBase.offsetForLocalDate("20171224", "NCE") + offset = GeoBase.offsetForLocalDate("20171224", "NCE") assert(offset === Success(60)) - offset = geoBase.offsetForLocalDate("20171224", "NYC") + offset = GeoBase.offsetForLocalDate("20171224", "NYC") assert(offset === Success(-300)) val exceptionThrown = intercept[GeoBaseException] { - geoBase.offsetForLocalDate("20171224", "...").get + GeoBase.offsetForLocalDate("20171224", "...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") } @@ -336,33 +364,33 @@ class GeoBaseTest extends FunSuite { test("GMT date to local date") { // 1: French summer time: - var localDate = geoBase.gmtDateToLocal("20160606_1427", "NCE") + var localDate = GeoBase.gmtDateToLocal("20160606_1427", "NCE") assert(localDate === Success("20160606_1627")) // 2: LON - localDate = geoBase.gmtDateToLocal("20160606_1427", "LON") + localDate = GeoBase.gmtDateToLocal("20160606_1427", "LON") assert(localDate === Success("20160606_1527")) // 3: NYC: - localDate = geoBase.gmtDateToLocal("20160606_1427", "JFK") + localDate = GeoBase.gmtDateToLocal("20160606_1427", "JFK") assert(localDate === Success("20160606_1027")) // 4: With a change of day: - localDate = geoBase.gmtDateToLocal("20160607_0227", "NYC") + localDate = GeoBase.gmtDateToLocal("20160607_0227", "NYC") assert(localDate === Success("20160606_2227")) // 5: French winter time: - localDate = geoBase.gmtDateToLocal("20160212_1527", "NCE") + localDate = GeoBase.gmtDateToLocal("20160212_1527", "NCE") assert(localDate === Success("20160212_1627")) // 6: Another format: localDate = - geoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") + GeoBase.gmtDateToLocal("2016-06-07T02:27", "NYC", "yyyy-MM-dd'T'HH:mm") assert(localDate === Success("2016-06-06T22:27")) // 7: With an invalid airport/city: val exceptionThrown = intercept[GeoBaseException] { - geoBase.gmtDateToLocal("20160212_1627", "...").get + GeoBase.gmtDateToLocal("20160212_1627", "...").get } assert(exceptionThrown.getMessage === "Unknown location \"...\"") } @@ -370,7 +398,7 @@ class GeoBaseTest extends FunSuite { test("Trip duration between two local dates") { // 1: Origin = destination and departure time = arrival date: - var computedTripDuration = geoBase.tripDurationFromLocalDates( + var computedTripDuration = GeoBase.tripDurationFromLocalDates( "20160606_1627", "NCE", "20160606_1627", @@ -378,7 +406,7 @@ class GeoBaseTest extends FunSuite { assert(computedTripDuration === Success(0d)) // 2: Within same time zone: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "20160606_1627", "NCE", "20160606_1757", @@ -386,7 +414,7 @@ class GeoBaseTest extends FunSuite { assert(computedTripDuration === Success(1.5d)) // 3: With a different time zone: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "20160606_1627", "CDG", "20160606_1757", @@ -394,7 +422,7 @@ class GeoBaseTest extends FunSuite { assert(computedTripDuration === Success(7.5d)) // 4: With a different time zone and a change of date: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "20160606_2327", "CDG", "20160607_0057", @@ -403,7 +431,7 @@ class GeoBaseTest extends FunSuite { // 5: With an invalid origin city/airport: var exceptionThrown = intercept[GeoBaseException] { - geoBase + GeoBase .tripDurationFromLocalDates( "20160606_1627", "...", @@ -415,7 +443,7 @@ class GeoBaseTest extends FunSuite { // 6: A negative trip duration: exceptionThrown = intercept[GeoBaseException] { - geoBase + GeoBase .tripDurationFromLocalDates( "20160607_0057", "JFK", @@ -429,7 +457,7 @@ class GeoBaseTest extends FunSuite { assert(exceptionThrown.getMessage === expectedMessage) // 7: The trip duration in minutes: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "20160606_1627", "CDG", "20160606_1757", @@ -438,7 +466,7 @@ class GeoBaseTest extends FunSuite { assert(computedTripDuration === Success(450d)) // 8: With a specific format: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "2016-06-06T16:27", "CDG", "2016-06-06T17:57", @@ -447,7 +475,7 @@ class GeoBaseTest extends FunSuite { assert(computedTripDuration === Success(7.5d)) // 9: With a specific format and in minutes: - computedTripDuration = geoBase.tripDurationFromLocalDates( + computedTripDuration = GeoBase.tripDurationFromLocalDates( "2016-06-06T16:27", "CDG", "2016-06-06T17:57", @@ -461,23 +489,23 @@ class GeoBaseTest extends FunSuite { // 1: Invalid radius (negative): var exceptionThrown = intercept[IllegalArgumentException] { - geoBase.nearbyAirports("CDG", -50).get + GeoBase.nearbyAirports("CDG", -50).get } val expectedMessage = "requirement failed: radius must be strictly positive" assert(exceptionThrown.getMessage === expectedMessage) // 2: Invalid radius (zero): exceptionThrown = intercept[IllegalArgumentException] { - geoBase.nearbyAirports("CDG", 0).get + GeoBase.nearbyAirports("CDG", 0).get } assert(exceptionThrown.getMessage === expectedMessage) // 3: Normal use case: val expectedAirports = List("LBG", "CSF", "ORY", "VIY", "POX", "TNF") - assert(geoBase.nearbyAirports("CDG", 50) === Success(expectedAirports)) + assert(GeoBase.nearbyAirports("CDG", 50) === Success(expectedAirports)) // 4: Normal use case with the detail of distances: - val computedAirports = geoBase.nearbyAirportsWithDetails("CDG", 50) + val computedAirports = GeoBase.nearbyAirportsWithDetails("CDG", 50) val expectedAirportsWithDetails = List( ("LBG", 9), ("CSF", 27), @@ -489,15 +517,27 @@ class GeoBaseTest extends FunSuite { assert(computedAirports === Success(expectedAirportsWithDetails)) // 5: Closer radius: - assert(geoBase.nearbyAirports("CDG", 10) === Success(List("LBG"))) + assert(GeoBase.nearbyAirports("CDG", 10) === Success(List("LBG"))) // 6: No nearby airports: - assert(geoBase.nearbyAirports("CDG", 5) === Success(List())) + assert(GeoBase.nearbyAirports("CDG", 5) === Success(List())) // 7: Unknown location: val exceptionThrown2 = intercept[GeoBaseException] { - geoBase.nearbyAirports("...", 20).get + GeoBase.nearbyAirports("...", 20).get } assert(exceptionThrown2.getMessage === "Unknown location \"...\"") + + // 8: Pimped case: + assert("CDG".nearbyAirports(50) === Success(expectedAirports)) + } + + test("Check everything is Serializable") { + + val geoBaseBr = sc.broadcast(GeoBase) + + val airports = sc.parallelize(Array("ORY", "GAT"), 2) + val cities = airports.map(airport => geoBaseBr.value.city(airport)) + assert(cities.collect === Array(Success("PAR"), Success("GAT"))) } }