GeoTrellis sublibraries and types are used heavily throughout vectorpipe
,
particularly its vector
and vectortile
packages.
RDD
usage is fairly prevalent, so knowledge of Spark internals may help
you, depending on your task.
The Functional Programming library that adds certain necessities missing
from vanilla Scala. This is not at all necessary for using vectorpipe
,
but is used here and there within its internal machinery.
Knowledge of how OpenStreetMap data is formatted will help you immensely. Terms:
- Element
- Node
- Way
- Relation
- SBT
- Apache Spark (a local install on your machine)
- Jekyll (if editing the microsite)
Otherwise, all Scala dependencies (including compilers) will be automatically downloaded by sbt.
When contributing code changes to vectorpipe
, bear in mind that we make a
few stylistic choices in order to minimize code complexity:
- Code mechanics relevant to the workings of the library but irrelevant to the
user should be relegated to a module under
vectorpipe.*.internal
, where the*
is whatever parent module you’re working in. - Type aliases live in package objects:
package vectorpipe
package object foo {
type Bar = Int
}
- Typeclass instances live in the companion object of the class they’re for:
import cats._
case class Foo[T](t: T)
object Foo {
implicit val fooFunctor: Functor[Foo] = new Functor[Foo] {
def map[A, B](fa: Foo[A])(f: A => B): Foo[B] = ???
}
}
This is to give immediate “visibility” of instances to their corresponding
types. Just by importing Foo
, you have access to all its instances without
having to think about them. This decreases import
confusion.
case class Foo[T](t: T) {
def bar(a: Int): Bar = ???
// avoid
def bar(a: Int, b: Int): Bar = ???
}
We avoid default arguments:
case class Foo[T](t: T) {
// avoid
def bar(a: Int, b: Option[Int] = None): Bar = ???
}
Since this is method overloading in disguise.
We avoid throwing Exceptions:
/* Surely this function will obey its contract... */
def innocent(path: String): Foo
sbt> innocent("/wrong/file/path/or/bad/data.txt")
java.lang.YouCouldntHaveForeseenThisException
Exceptions were intentionally left out of new languages like Golang, Rust, and Elm.
In Scala, we can use vanilla Try
and Either
, or EitherT
from Cats or ScalaZ
to model potential errors:
def innocent(path: String): Either[String, Foo]
/* "Mixing Contexts", i.e. the ability to run concurrently and to fail safely */
def innocentIO(path: String): EitherT[Future, String, Foo]
We avoid classes that don’t represent data:
class Fooifizer(val bestArg: Type) {
def work(arg: Type): Unit = { ??? }
}
Instead, we call a spade a spade and write a stand-alone function:
/* Put this in an appropriate companion object, or the package object */
def fooifize(bestArg: Type, arg: Type): Unit = { ??? }
We avoid .apply
returning a type other than the parent object:
object Foo {
// avoid
def apply(...): Bar = ...
}
// Or else you can write code like:
val x = Foo(...) // hard to know what x's type is.
We avoid implicit conversions:
case class Foo(...)
case class Bar(...) {
def bar: ??? = ...
}
object Foo {
// avoid
implicit def foo2Bar(foo: Foo): Bar = ...
}
// Or else you can write code like:
val x = Foo(...).bar // where did `bar` come from?
Typeclasses should be implemented via the implicit-val-within-companion-object pattern.
All content files can be found in src/main/tut/
. After making your desired
changes, you can confirm them by running the following in sbt:
sbt> makeMicrosite
This will build the site as well as compile every Scala example. If something about the API has changed and the examples are no longer valid, these docs will fail to build. This is a good thing! Just make the appropriate extra changes and rebuild.
To view your built site locally, navigate to target/site/
and run jekyll
serve
. Be careful: The main content of the site will be visible at
127.0.0.1:4000/vectorpipe/. Without
the vectorpipe
on the end, you won’t see anything.
If you have write permission to the main VectorPipe repo on Github, then your updated microsite can be published to https://geotrellis.github.io/vectorpipe/ via:
sbt> publishMicrosite
Provided you have permissions to publish to Azavea’s Bintray, all that’s necessary to proceed is:
sbt> publish
in your SBT shell.