Skip to content
This repository was archived by the owner on Jan 8, 2020. It is now read-only.
Open
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,9 @@ object AddressInterpolator {
val s = feature.values.getOrElse(s"${pre}FROMHN", "0")
val e = feature.values.getOrElse(s"${pre}TOHN", "0")

val start = s match {
case "" => 0
case _ => toInt(s.toString).getOrElse(0)
}
val end = e match {
case "" => 0
case _ => toInt(e.toString).getOrElse(0)
}
val start = toInt(s.toString).getOrElse(0)

val end = toInt(e.toString).getOrElse(0)

AddressRange(start, end)
}
Expand Down Expand Up @@ -98,18 +93,12 @@ object AddressInterpolator {
private def rangeIsEven(f: Feature, isLeft: Boolean): Boolean = {
val prefix = if (isLeft) "L" else "R"
val fromEven = f.values.getOrElse(s"${prefix}FROMHN", 0)
val fromRange = fromEven match {
case "" => 0
case _ => toInt(fromEven.toString).getOrElse(0)
}
val fromIsEven = fromEven != "" && fromRange % 2 == 0
val fromRange = toInt(fromEven.toString).getOrElse(0)
val fromIsEven = fromRange != None && fromRange % 2 == 0

val toEven = f.values.getOrElse(s"${prefix}TOHN", 0)
val toRange = fromEven match {
case "" => 0
case _ => toInt(toEven.toString).getOrElse(0)
}
val toIsEven = toEven != "" && toRange % 2 == 0
val toRange = toInt(toEven.toString).getOrElse(0)
val toIsEven = toRange != None && toRange % 2 == 0
fromIsEven || toIsEven
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ object SearchUtils {
if (isNumeric(s)) {
Some(s.toInt)
} else {
if (s.contains("-")) {
Some(s.substring(0, s.indexOf("-")).toInt)
if (s.contains(".")) {
Some(s.substring(0, s.indexOf(".")).toInt)
} else if (s.contains("-")) {
Some(s.substring(0, s.indexOf("-", 1)).toInt)
} else if (s == "None") {
None
} else if (s == "") {
None
} else {
Some(s.replaceAll("[^\\d]", "").toInt)
}
Expand All @@ -28,6 +32,6 @@ object SearchUtils {
}

def isNumeric(str: String): Boolean = {
str.matches("-?\\d+(\\.\\d+)?")
str.matches("-?\\d+")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package grasshopper.geocoder.search.census

import org.scalatest.{ PropSpec, MustMatchers, PrivateMethodTester }
import org.scalatest.prop.PropertyChecks
import grasshopper.geocoder.search.census.AddressInterpolator._
import grasshopper.model.census.AddressRange
import feature._

class AddressInterpolatorSpec extends PropSpec with MustMatchers with PropertyChecks with PrivateMethodTester with NumericGenerators {

property("calculateDistance must always be positive") {
forAll(positive, positive) { (start, stop) =>
val range = new AddressRange(start, stop)
val calculateDistance = PrivateMethod[Double]('calculateDistance)
AddressInterpolator invokePrivate calculateDistance(range) mustBe >=(0.0)
}
}

val testField = new Field("test", StringType())
val testSchema = new Schema(Iterable(testField, testField))

property("for rangeIsEven left even is even") {
forAll(even, even) { (x, y) =>
val range = Map("LFROMHN" -> x, "LTOHN" -> y)
val evenFeature = new Feature(1, testSchema, range)
val rangeIsEven = PrivateMethod[Boolean]('rangeIsEven)
AddressInterpolator invokePrivate rangeIsEven(evenFeature, true) mustBe true
}
}

property("for rangeIsEven left odd is odd") {
forAll(odd, odd) { (x, y) =>
whenever(x != 0 && y != 0) {
val range = Map("LFROMHN" -> x, "LTOHN" -> y)
val oddFeature = new Feature(1, testSchema, range)
val rangeIsEven = PrivateMethod[Boolean]('rangeIsEven)
AddressInterpolator invokePrivate rangeIsEven(oddFeature, true) mustBe false
}
}
}

property("for rangeIsEven right even is even") {
forAll(even, even) { (x, y) =>
val range = Map("RFROMHN" -> x, "RTOHN" -> y)
val evenFeature = new Feature(1, testSchema, range)
val rangeIsEven = PrivateMethod[Boolean]('rangeIsEven)
AddressInterpolator invokePrivate rangeIsEven(evenFeature, false) mustBe true
}
}

property("for rangeIsEven right odd is odd") {
forAll(odd, odd) { (x, y) =>
whenever(x != 0 && y != 0) {
val range = Map("RFROMHN" -> x, "RTOHN" -> y)
val oddFeature = new Feature(1, testSchema, range)
val rangeIsEven = PrivateMethod[Boolean]('rangeIsEven)
AddressInterpolator invokePrivate rangeIsEven(oddFeature, false) mustBe false
}
}
}

property("for calculateAddressRange left even, right odd") {
forAll(odd, odd, even, even, digits) { (r1, r2, l1, l2, a) =>
whenever(r1 != 0 && r2 != 0) {
val range = Map("RFROMHN" -> r1, "RTOHN" -> r2, "LFROMHN" -> l1, "LTOHN" -> l2)
val feature = new Feature(1, testSchema, range)
if (a % 2 == 0) calculateAddressRange(feature, a) mustBe (AddressRange(l1, l2))
else calculateAddressRange(feature, a) mustBe (AddressRange(r1, r2))
}
}
}

property("for calculateAddressRange left odd, right even") {
forAll(even, even, odd, odd, digits) { (r1, r2, l1, l2, a) =>
whenever(l1 != 0 && l2 != 0) {
val range = Map("RFROMHN" -> r1, "RTOHN" -> r2, "LFROMHN" -> l1, "LTOHN" -> l2)
val feature = new Feature(1, testSchema, range)
if (a % 2 == 0) calculateAddressRange(feature, a) mustBe (AddressRange(r1, r2))
else calculateAddressRange(feature, a) mustBe (AddressRange(l1, l2))
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package grasshopper.geocoder.search.census

import org.scalacheck.Gen

trait NumericGenerators {

def digits: Gen[Int] = {
for {
n <- Gen.choose(-10000, 10000)
} yield n
}

def positive: Gen[Int] = {
for {
n <- Gen.choose(0, 10000)
} yield n
}

def even: Gen[Int] = {
for {
n <- Gen.choose(-10000, 10000)
} yield n * 2
}

def odd: Gen[Int] = {
for {
n <- Gen.choose(-10000, 10000)
} yield n * 2 - 1
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package grasshopper.geocoder.search.census

import org.scalatest.{ PropSpec, MustMatchers }
import org.scalatest.prop.PropertyChecks
import grasshopper.geocoder.search.census.SearchUtils._

class SearchUtilsSpec extends PropSpec with MustMatchers with PropertyChecks with NumericGenerators {

property("digits are parsed into Ints") {
forAll(digits) { n =>
toInt(n.toString) mustBe Some(n)
}
}

property("decimals are parsed into Ints") {
forAll(digits, positive) { (x, y) =>
val numString = x.toString + "." + y.toString
toInt(numString) mustBe Some(x)
}
}

property("hyphens are parsed into Ints") {
forAll(digits, positive) { (x, y) =>
val numString = x.toString + "-" + y.toString
toInt(numString) mustBe Some(x)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package grasshopper.geocoder.search.census

import org.scalatest.{ MustMatchers, FlatSpec }
import grasshopper.geocoder.search.census.AddressInterpolator._
import grasshopper.model.census.AddressRange
import feature._
import geometry._

class InterpolateSpec extends FlatSpec with MustMatchers {

"A correct point" must "be found on the right side of a horizontal line" in {
val values: Map[String, Any] = Map(
"geometry" -> read("LINESTRING (0 0, 100 0)"),
"FULLNAME" -> "999 Main Street",
"RFROMHN" -> 1,
"RTOHN" -> 101,
"LFROMHN" -> 0,
"LTOHN" -> 100,
"ZIPR" -> "19041",
"ZIPL" -> "19041",
"STATE" -> "CA"
)

val addressField = Field("address", StringType())
val geomField = Field("geometry", GeometryType())
val numberField = Field("number", IntType())
val schema = Schema(geomField, addressField, numberField)
val feature = Feature(schema, values)
val addressNumber = 25
val addressRange = AddressRange(0, 100)

val newFeature = interpolate(feature, addressRange, addressNumber)

newFeature.geometry mustBe ((25, .0001))

}

}
2 changes: 1 addition & 1 deletion project/Version.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object Version {
val config = "1.3.0"
val akka = "2.4.4"
val scalaTest = "3.0.0-M15"
val scalaCheck = "1.13.0"
val scalaCheck = "1.12.5"
val elasticsearch = "2.2.0"
val jts = "1.13"
val scale = "0.0.2"
Expand Down