Skip to content

Commit 033ee8f

Browse files
author
James McClain
committed
Unit Tests For Time Series Capability
1 parent 1188461 commit 033ee8f

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2017 Azavea
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package geotrellis.spark.costdistance
18+
19+
import geotrellis.proj4.LatLng
20+
import geotrellis.raster._
21+
import geotrellis.spark._
22+
import geotrellis.spark.testkit.TestEnvironment
23+
import geotrellis.spark.tiling.LayoutDefinition
24+
import geotrellis.vector._
25+
26+
import org.apache.spark.rdd.RDD
27+
28+
import org.scalatest._
29+
30+
31+
class RDDTimeSeriesMethodsSpec extends FunSpec
32+
with Matchers
33+
with TestEnvironment {
34+
35+
val rdd = {
36+
val tile1 = IntConstantNoDataArrayTile(Array.fill[Int](25)(1), 5, 5)
37+
val tile2 = IntConstantNoDataArrayTile(Array.fill[Int](25)(2), 5, 5)
38+
val tile3 = IntConstantNoDataArrayTile(Array.fill[Int](25)(3), 5, 5)
39+
val tile4 = IntConstantNoDataArrayTile(Array.fill[Int](25)(4), 5, 5)
40+
val extent = Extent(0, 0, 10, 5)
41+
val gridExtent = GridExtent(extent, 1, 1) // 10×5 pixels
42+
val layoutDefinition = LayoutDefinition(gridExtent, 10, 5)
43+
val bounds = Bounds(SpaceTimeKey(0, 0, 0), SpaceTimeKey(1, 0, 1))
44+
val tileLayerMetadata = TileLayerMetadata(
45+
IntConstantNoDataCellType,
46+
layoutDefinition,
47+
extent,
48+
LatLng,
49+
bounds
50+
)
51+
val list: List[(SpaceTimeKey, Tile)] = List(
52+
(SpaceTimeKey(0, 0, 0), tile1),
53+
(SpaceTimeKey(1, 0, 0), tile2),
54+
(SpaceTimeKey(0, 0, 1), tile3),
55+
(SpaceTimeKey(1, 0, 1), tile4)
56+
)
57+
ContextRDD(sc.parallelize(list), tileLayerMetadata)
58+
}
59+
60+
val polygon = MultiPolygon(Polygon(
61+
Point(-100,-100),
62+
Point(+100,-100),
63+
Point(+100,+100),
64+
Point(-100,+100),
65+
Point(-100,-100)
66+
))
67+
68+
describe("Time Series Extentension Methods") {
69+
70+
it("Mean") {
71+
val expected = List(1.5, 3.5)
72+
val actual = rdd.meanSeries(polygon).map({ case (_, x) => x })
73+
actual should be (expected)
74+
}
75+
76+
it("Min") {
77+
val expected = List(1.0, 3.0)
78+
val actual = rdd.minSeries(polygon).map({ case (_, x) => x })
79+
actual should be (expected)
80+
}
81+
82+
it("Max") {
83+
val expected = List(2.0, 4.0)
84+
val actual = rdd.maxSeries(polygon).map({ case (_, x) => x })
85+
actual should be (expected)
86+
}
87+
88+
it("Histogram") {
89+
val expected = List(Some(1.0), Some(3.0))
90+
val actual = rdd.histogramSeries(polygon).map({ case (_, x) => x.minValue() })
91+
actual should be (expected)
92+
}
93+
94+
it("Sum") {
95+
val expected = List(25.0*(1+2), 25.0*(3+4))
96+
val actual = rdd.sumSeries(polygon).map({ case (_, x) => x })
97+
actual should be (expected)
98+
}
99+
100+
}
101+
102+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright 2017 Azavea
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package geotrellis.spark.timeseries
18+
19+
import geotrellis.proj4.LatLng
20+
import geotrellis.raster._
21+
import geotrellis.spark._
22+
import geotrellis.spark.testkit.TestEnvironment
23+
import geotrellis.spark.tiling.LayoutDefinition
24+
import geotrellis.vector._
25+
26+
import org.scalatest._
27+
28+
29+
object TimeSeriesSpecFunctions {
30+
31+
def projection(tile: Tile): Set[Int] =
32+
tile.toArray.toSet.filter(_ > 0)
33+
34+
def reduction(left: Set[Int], right: Set[Int]): Set[Int] =
35+
left ++ right
36+
}
37+
38+
class TimeSeriesSpec extends FunSpec
39+
with Matchers
40+
with TestEnvironment {
41+
42+
val rdd = {
43+
val tile1 = IntArrayTile(Array.fill[Int](25)(1), 5, 5)
44+
val tile2 = IntArrayTile(Array.fill[Int](25)(2), 5, 5)
45+
val tile3 = IntArrayTile(Array.fill[Int](25)(3), 5, 5)
46+
val tile4 = IntArrayTile(Array.fill[Int](25)(4), 5, 5)
47+
val extent = Extent(0, 0, 10, 5)
48+
val gridExtent = GridExtent(extent, 1, 1) // 10×5 pixels
49+
val layoutDefinition = LayoutDefinition(gridExtent, 10, 5)
50+
val bounds = Bounds(SpaceTimeKey(0, 0, 0), SpaceTimeKey(1, 0, 1))
51+
val tileLayerMetadata = TileLayerMetadata(
52+
IntConstantNoDataCellType,
53+
layoutDefinition,
54+
extent,
55+
LatLng,
56+
bounds
57+
)
58+
val list: List[(SpaceTimeKey, Tile)] = List(
59+
(SpaceTimeKey(0, 0, 0), tile1),
60+
(SpaceTimeKey(1, 0, 0), tile2),
61+
(SpaceTimeKey(0, 0, 1), tile3),
62+
(SpaceTimeKey(1, 0, 1), tile4)
63+
)
64+
ContextRDD(sc.parallelize(list), tileLayerMetadata)
65+
}
66+
67+
describe("Time Series Capability") {
68+
69+
it("Should handle queries within tile boundaries") {
70+
val polygon = MultiPolygon(Polygon(
71+
Point(0,0),
72+
Point(4,0),
73+
Point(4,4),
74+
Point(0,4),
75+
Point(0,0)
76+
))
77+
78+
val expected = List(Set(1), Set(3))
79+
val actual =
80+
TimeSeries(
81+
rdd,
82+
TimeSeriesSpecFunctions.projection,
83+
TimeSeriesSpecFunctions.reduction,
84+
List(polygon)
85+
)
86+
.collect()
87+
.toList
88+
.map({ case (_, s) => s })
89+
90+
actual should be (expected)
91+
}
92+
93+
it("Should handle queries across tile boundaries") {
94+
val polygon = MultiPolygon(Polygon(
95+
Point(0,0),
96+
Point(11,0),
97+
Point(11,5),
98+
Point(0,5),
99+
Point(0,0)
100+
))
101+
102+
val expected = List(Set(1,2), Set(3,4))
103+
val actual =
104+
TimeSeries(
105+
rdd,
106+
TimeSeriesSpecFunctions.projection,
107+
TimeSeriesSpecFunctions.reduction,
108+
List(polygon)
109+
)
110+
.collect()
111+
.toList
112+
.map({ case (_, s) => s })
113+
114+
actual should be (expected)
115+
}
116+
117+
}
118+
119+
}

0 commit comments

Comments
 (0)