Repository navigation
ColorMap => String - #1512
ColorMap => String#1512
Conversation
- Fairly hacky, but demonstrates it's possible.
|
To test: sbt
project raster
console
import geotrellis.raster.render.ColorMap
val m = ColorMap.fromString("23:cc00ccff;30:aa00aaff;120:ff0000ff").get
ColorMap.breaksString(m.breaksMap) |
| private lazy val orderedColors: Vector[Int] = orderedBreaks.map(breaksToColors(_)) | ||
| lazy val colors = orderedColors | ||
| lazy val breaksMap = breaksToColors | ||
| lazy val breaksMapDouble = Map.empty[Double,Int] |
There was a problem hiding this comment.
Why do we need a breaks map? Can't we just implement this functionality as the toString method?
|
Really, the best thing would be for trait ColorMap[T] extends Serializable { ... }And then duplicate code between def breaksString: String = {
breaksMap // was `breaksToColors` passed in as an argument
.toStream
.map({ case (k,v) => s"${k}:${Integer.toHexString(v)}"})
.mkString(";")
}The huge downside of this would be that client code would have to care about the parameterized @lossyrob why I'm not in favour of just defining the read . show == idand other "pretty printing" functions are given obvious names. |
|
Another trip-up: the user-level API doesn't expose |
|
Your hitting up against the need for us not to abstract over I'm not sure "it not being good form in Haskell" is a good reason to avoid using the method that's there, defined as returning a string representation of the object. One could argue that the string representation of a color map that you are concocting is actually a good representation for a user trying to read what the color map is; however, even if we wanted to differentiate between a "show" |
That was more of an explanation as to my natural want to avoid that pattern, not necessarily that we should do it that way "cause Haskell". The question becomes, where do we want the isomorphism? Between re: my last comment. |
|
Gotcha. Yeah I think the argument could be made though that we would want to avoid using |
|
Meaning the actual definition of |
|
More to do with why we can't do
and be generic on T. But code duplication in this case might be tough to avoid, since the code to deal with doubles and ints will look the same (but not with the cached version of int, which you mentioned above). |
| new IntCachedColorMap(orderedColors, ch, options) | ||
| } | ||
|
|
||
| lazy val breaksString: String = { |
There was a problem hiding this comment.
Why lazy val for this and the other one?
There was a problem hiding this comment.
For the same reason that orderedColors is lazy, so that these potentially unneeded values aren't calculated upon ColorMap instantiation.
There was a problem hiding this comment.
I wasn't thinking vals...why not defs? Is there ever a reason to hold them in memory after calculation (e.g. its an expensive operation that will be reused many times to justify the instance footprint)?
There was a problem hiding this comment.
I can't see it being called over and over for one instance of a ColorMap. I suppose the GC behaviour for these are:
val: Eagerly evaluate, keep in memorylazy val: Lazily evaluate, and then keep in memorydef: Lazily evaluate, don't keep in memory
If so, then perhaps it's best as a def.
|
Good to go, @lossyrob . |
TODO
breaksStringinto trait and inheritIntCachedColorMapMotivation
When using the
renderoutput module in the ETL process, one must provide abreaksargument, or all tiles will be rendered grayscale. Example:--output render -O encoding=png path=file:///home/colin/tiles/{name}/{z}-{x}-{y}.png breaks="23:cc00ccff;30:aa00aaff;120:ff0000ff"The problem is that for datasets which don't have well-defined colour breaks ahead of time like
nlcd, there's no way to know what your break string should be for input into ETL. AColorMapobject can be created easily givenRDD.colorBreaksand then rendered to a PNG within Scala code, but there is no way to know whatStringwould represent thatColorMapfrom the outside. This chicken-and-egg problem requires a greater fix to how ETL accepts breaks information from the outside, but this is a start.