@@ -607,12 +607,13 @@ class Translator(val baseURL: Option[java.net.URL]) {
607
607
for (name <- typenames) yield (name, rules filter isForTypename(name) map stripTypenames)
608
608
609
609
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))
614
615
615
- for ((_, group) <- flattenByZ (zGroups.flatten )) {
616
+ for ((_, group) <- orderedRuns (zGroups)) {
616
617
val fts = styles.createFeatureTypeStyle
617
618
typename.foreach { t => fts.featureTypeNames.add(new NameImpl (t)) }
618
619
for ((rule, syms) <- group if ! syms.isEmpty) {
@@ -656,13 +657,34 @@ class Translator(val baseURL: Option[java.net.URL]) {
656
657
return sld
657
658
}
658
659
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)
664
679
}
665
680
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))
666
688
667
689
private def groupByZ (syms : Seq [(Double , Symbolizer )])
668
690
: Seq [(Double , Seq [Symbolizer ])] = {
0 commit comments