I have a case class named EarthMap
which represents a mapping of the earth (in terms of longitude and latitude) onto a rectangular image. By default there is a one to one correspondence between pixels in the image and degrees on the Earths surface for example. I.e. an area of the earth corresponding to dx=1 degree longitude and dy=1 degree latitude corresponds to one pixel in the image.
The class also supports zoom windows (for clipping and scaling).
I’d like to extend the class to support cartography projections. For example Mercator projection and Peters projection.
This means that the class needs to know about a cartography projection function and inverse function. The question is from an API perspective, how should I specify this projection?
I have noticed that with EarthMap
being a case class, I can instantiate an instance using the syntax var em = EarthMap()
. However, the syntax var em = EarthMap(){var var1=100}
is marked as an error but var em = new EarthMap(){var var1=100}
is not marked as an error.
What is the logic and intuition of when I am allowed to instantiate anonymous subclasses such as new EarthMap(){...}
and which kinds of extensions and overrides I’m allowed to denote? Also in the past, I’ve shied away from subclasses of case classes, simply because I don’t understand the consequences such as unexpected changes in equality semantics.
For example, if EarthMap
has methods project
and invProject
, am I supposed to be able to override those methods in an anonymous subclass as follows? (BTW to my surprise it seems to work.)
case class EarthMap(...) {
def project(loc:Location) = (loc.lat -> loc.lon)
def invProject(lat:Double,lon:Double) = Location(lat,lon)
...
}
def main(argv: Array[String]): Unit = {
import math._
val em = new EarthMap() {
override def project(loc: Location):(Double,Double) = (90 * sin(toRadians(loc.lat)) -> loc.lon)
override def invProject(lat: Double, lon: Double):Location = Location(toDegrees(asin(lat / 90)), lon)
}
...
}
This seems on my naive attempt to work fine, but I’m skeptical. I don’t understand the difference between new EarthMap
and EarthMap()
. Isn’t the former skipping any extra initialization in the apply method of the object EarthMap
declaration?