Skip to content

Commit 6de30b6

Browse files
committed
Refactor the rule grouping code a bit
1 parent 80f87f1 commit 6de30b6

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

geocss/src/main/scala/Translator.scala

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,13 @@ class Translator(val baseURL: Option[java.net.URL]) {
607607
for (name <- typenames) yield (name, rules filter isForTypename(name) map stripTypenames)
608608

609609
for ((typename, overlays) <- styleRules) {
610-
val zGroups: Seq[Seq[(Double, Rule, Seq[gt.Symbolizer])]] =
611-
for (rule <- cascading2exclusive(overlays)) yield
612-
for ((z, syms) <- groupByZ(symbolize(rule))) yield
613-
(z, rule, syms)
610+
val zGroups: Seq[(Double, (Rule, Seq[gt.Symbolizer]))] =
611+
for {
612+
rule <- cascading2exclusive(overlays)
613+
(z, syms) <- groupByZ(symbolize(rule))
614+
} yield (z, (rule, syms))
614615

615-
for ((_, group) <- flattenByZ(zGroups.flatten)) {
616+
for ((_, group) <- orderedRuns(zGroups)) {
616617
val fts = styles.createFeatureTypeStyle
617618
typename.foreach { t => fts.featureTypeNames.add(new NameImpl(t)) }
618619
for ((rule, syms) <- group if !syms.isEmpty) {
@@ -656,13 +657,34 @@ class Translator(val baseURL: Option[java.net.URL]) {
656657
return sld
657658
}
658659

659-
private def flattenByZ[R, S](zGroups: Seq[(Double, R, Seq[S])])
660-
: Seq[(Double, Seq[(R, Seq[S])])]
661-
= {
662-
val zFlattened = zGroups map { case (z, r, s) => (z, (r, s)) }
663-
(zFlattened groupBy(_._1) mapValues(_ map (_._2)) toSeq).sortBy(_._1)
660+
/**
661+
* Order-preserving grouping of pairs by the first item in the tuple
662+
* "runs" as in run-length encoding.
663+
*/
664+
private def runs[K, V](xs: Seq[(K,V)]): Seq[(K,Seq[V])] = {
665+
type In = Seq[(K,V)]
666+
type Out = Seq[(K,Seq[V])]
667+
668+
@annotation.tailrec
669+
def recurse(xs: In, accum: Out): Out =
670+
xs match {
671+
case Seq() => accum
672+
case Seq(x, _*) =>
673+
val (in, out) = xs.span(_._1 == x._1)
674+
val in0 = (x._1, (in map (_._2)))
675+
recurse(out, accum :+ in0)
676+
}
677+
678+
recurse(xs, Seq.empty)
664679
}
665680

681+
/**
682+
* Sort, then find runs in the sorted results
683+
*
684+
* @see runs
685+
*/
686+
private def orderedRuns[K : Ordering, V] (xs: Seq[(K, V)]) : Seq[(K, Seq[V])] =
687+
runs(xs sortBy(_._1))
666688

667689
private def groupByZ(syms: Seq[(Double, Symbolizer)])
668690
: Seq[(Double, Seq[Symbolizer])] = {

0 commit comments

Comments
 (0)