What imports are needed to locate the implicit evidence to compile a call to GeoJson.parse from GeoTrellis?
geotrellis.vector.io.json.Geometry uses spray.json to parse, and must be able to locate a JsonReader or JsonFormats instance, templated to WithCrs and Geometry classes.
The evidence is defined within FeatureFormats; but how can the snippet below use it?
The following does not resolve the evidence:
Import everything in the geotrellis.vector.io.json.* package
Import the Implicits specifically import geotrellis.vector.io.json.Implicits
Import FeatureFormats directly import geotrellis.vector.io.json.FeatureFormats
Ensure the correct imports, especially no imports of com.vividsolutions.jts.Geometry which would mask the target object
Here's the code in question
import geotrellis.vector.Geometry
import geotrellis.proj4.CRS
import geotrellis.vector.io.json.*
import geotrellis.vector.io.json.{GeoJson, WithCrs}
import org.json4s.{DefaultFormats, Formats}
import scala.util.{Failure, Success, Try}
val exampleQueryJson =
"""
|{
| "type": "Polygon",
| "crs": {
| "type": "name",
| "properties": {
| "name": "EPSG:4326"
| }
| },
| "coordinates": [
| [
| [....]
| ]
| ]
|}
""".stripMargin
class GeometryReader extends FeatureFormats {
implicit val jsonFormats: Formats = DefaultFormats
}
object GeometryReader {
def parseGeometry(request: String): Geometry = {
GeoJson.parse[Geometry](request)
}
}
val g = GeometryReader.parseGeometry(exampleQueryJson)
The compile error shows the inability to find the right evidence given what's currently available
[error] /path/redacted/GeometryReader.scala:19: Cannot find JsonReader or JsonFormat type class for geotrellis.vector.io.json.WithCrs[geotrellis.vector.Geometry]
[error] val geometryWithCrs: WithCrs[Geometry] = GeoJson.parse[WithCrs[Geometry]](request)
[error] ^
[error] /path/redacted/GeometryReader.scala:25: Cannot find JsonReader or JsonFormat type class for geotrellis.vector.Geometry
[error] Try(GeoJson.parse[Geometry](request)) match {
[error] ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed
Short answer: Add
import geotrellis.vector.io._
The creators of this library made use of package objects to publish these implicits. The package object (source code below) extends g.io.json.Implicits, and that brings them into scope.
https://github.com/locationtech/geotrellis/blob/master/vector/src/main/scala/geotrellis/vector/io/package.scala
More about package objects:
https://www.scala-lang.org/docu/files/packageobjects/packageobjects.html
Related
I have below code.
import enumeratum.{Enum, EnumEntry}
sealed abstract class AppEnvironment extends EnumEntry
object AppEnvironment extends Enum[AppEnvironment] {
case object Local extends AppEnvironment
case object Testing extends AppEnvironment
case object Production extends AppEnvironment
override val values: Vector[AppEnvironment] =
findValues.toVector
}
import java.net.InetAddress
import ciris.Secret
import eu.timepit.refined.types.net.UserPortNumber
import scala.concurrent.duration.Duration
final case class ApiConfig(
host: InetAddress,
port: UserPortNumber,
apiKey: Secret[ApiKey],
timeout: Duration
)
import java.net.InetAddress
import cats.Show
import cats.derived._
import cats.implicits._
import ciris.Secret
import ciris.cats._
import enumeratum.EnumEntry
import eu.timepit.refined.auto._
import eu.timepit.refined.cats._
import eu.timepit.refined.types.net.UserPortNumber
import eu.timepit.refined.types.string.NonEmptyString
import is.cir.example.domain.config.AppEnvironment.{Local, Production, Testing}
import scala.concurrent.duration._
final case class Config(
appName: NonEmptyString,
environment: AppEnvironment,
api: ApiConfig
)
object Config {
import cats.implicits._
implicit val showConfig: Show[Config] = {
implicit val showInetAddress: Show[InetAddress] =
Show.fromToString
implicit def showEnumEntry[E <: EnumEntry]: Show[E] =
Show.show(_.entryName)
semi.show
}
}
I have to add the scalac option -Ypartial-unification in build.sbt to resolve another issue after adding I get another exception which was not happening earlier(without the flag).
The error is -
[error] /Users/rajkumar.natarajan/Documents/Coding/OS/ciris-example/src/main/scala/is/cir/example/domain/config/Config.scala:38:10: type mismatch;
[error] found : cats.Show[shapeless.CNil]
[error] required: cats.Show[is.cir.example.domain.config.Config]
[error] semi.show
[error] ^
[error] one error found
How can I resolve this error?
You should call it specifying type parameter
semi.show[Config]
At least error message is different then
Error:(82, 14) diverging implicit expansion for type cats.derived.MkShow[is.cir.example.domain.config.Config]
starting with value tagRefType in object RefType
semi.show[Config]
You can try to play with your Show instances. In order to have a Show for "bigger" case class you should have Show for "smaller" ones.
implicitly[Show[Config]]
implicitly[Show[AppEnvironment]]
implicitly[Show[AppEnvironment.Local.type]]
//...
implicitly[Show[ApiConfig]]
implicitly[Show[InetAddress]]
//...
I have a model, containing a list as a member variable, that I am trying to serialize using Circe in Scale.
The model in question -
case class Order(id: Long, tableId: Long, items: List[Item]) {
}
object Order {
implicit val encoder: Encoder[Order] = deriveEncoder[Order]
implicit val decoder: Decoder[Order] = deriveDecoder[Order]
}
Also, the Item class -
case class Item(id: Long, name: String, serving: String) {
}
object Item {
implicit val encoder: Encoder[Item] = deriveEncoder[Item]
implicit val decoder: Decoder[Item] = deriveDecoder[Item]
}
I am using Circe's semi-auto encoder feature. However, when trying to read data from the database using quill, I am encountering this exception -
[error] /Users/in-rmoitra/Projects/PetProjects/Restrofit-Backend/src/main/scala/models/repository/OrderRepository.scala:17:69: exception during macro expansion:
[error] scala.reflect.macros.TypecheckException: Can't find implicit `Decoder[List[models.Item]]`. Please, do one of the following things:
[error] 1. ensure that implicit `Decoder[List[models.Item]]` is provided and there are no other conflicting implicits;
[error] 2. make `List[models.Item]` `Embedded` case class or `AnyVal`.
[error]
[error] at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$3(Typers.scala:32)
[error] at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$2(Typers.scala:26)
[error] at scala.reflect.macros.contexts.Typers.doTypecheck$1(Typers.scala:25)
[error] at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$7(Typers.scala:38)
[error] at scala.reflect.internal.Trees.wrappingIntoTerm(Trees.scala:1731)
[error] at scala.reflect.internal.Trees.wrappingIntoTerm$(Trees.scala:1728)
[error] at scala.reflect.internal.SymbolTable.wrappingIntoTerm(SymbolTable.scala:18)
[error] at scala.reflect.macros.contexts.Typers.typecheck(Typers.scala:38)
[error] at scala.reflect.macros.contexts.Typers.typecheck$(Typers.scala:20)
[error] at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
[error] at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
[error] at io.getquill.context.QueryMacro.expandQueryWithMeta(QueryMacro.scala:41)
[error] at io.getquill.context.QueryMacro.expandQuery(QueryMacro.scala:20)
[error] at io.getquill.context.QueryMacro.runQuery(QueryMacro.scala:12)
[error] val ordersFuture: Future[List[(Order, (OrderItem, Item))]] = run(query)
From my limited knowledge of Circe and what I already looked up, the docs say that you do not need to create a decoder for List[A] if you already have a decoder for [A].
It would be great if someone could throw light on what seems to be happening here.
Your Circe code is fine. If you execute
println(
parse("""
|{ "id" : 1,
| "tableId" : 2,
| "items" : [
| { "id": 3,
| "name" : "a",
| "serving" : "b"
| },
| { "id": 4,
| "name" : "c",
| "serving" : "d"
| }
| ]
|}
""".stripMargin)
.flatMap(json => json.as[Order])
)
you'll get
Right(Order(1,2,List(Item(3,a,b), Item(4,c,d))))
So the trouble is in your Quill code.
And don't confuse io.circe.Decoder and io.getquill.context.jdbc.Decoders#Decoder.
https://getquill.io/#extending-quill-custom-encoding
`exception during macro expansion: [error] scala.reflect.macros.TypecheckException` when using quill
UPDATED: Method is returning type ANY rather than type Future[string]. Require return of type String.
I'm making a http request using the play.ws library 2.6. This was previously done with a curl request but this only uses basic authentication.
Below is my code and I'm trying to return a json string from this function to be deserialised in another method.
import java.io.{File, InputStream}
import java.nio.file.Paths
import javax.inject._
import org.apache.commons.io.FileUtils
import play.api._
import play.api.http.HttpEntity
import play.api.libs.ws._
import play.api.mvc._
import play.api.Play.current
import scala.collection.mutable.ListBuffer
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import sys.process._
#Singleton
class BuildService #Inject() (
ws: WSClient,
ec: ExecutionContext,
config: Configuration) {
def bbApiRequest(requestUrl: String, timeout: FiniteDuration):
Future[String] = {
val request = ws
.url(requestUrl)
.withAuth(
"user",
"pw1234",
WSAuthScheme.BASIC)
.get()
Await.result(request, timeout)
val returner = request.map(_.json)
} // <-- line 72 in below error points here.
}
When run it produces the error:
[error] C:\my_path\app\services\BuildService.scala:72: type mismatch;
[error] found : Unit
[error] required: scala.concurrent.Future[String]
[error] }
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[info] Compiling 1 Scala source to C:\my_path\restapi\target\scala-
2.12\classes...
[error] C:\my_path\restapi\app\services\BuildService.scala:72: type
mismatch;
[error] found : Unit
[error] required: scala.concurrent.Future[String]
[error] }
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
I'm trying to get ideally:
A string return (case class and json method to unpack a string)
Synchronous request (if async I'll need to wait to complete to progress application)
Secure (allows use of tokens for verification)
Appreciate any help!
Here is the function I use:
// first work with Futures the Play Controller will support that!
def bbApiRequest(requestUrl: String): Future[String] = {
// call the webservice with basic authentication
wsClient.url(requestUrl)
.withAuth("tester", "pwd123", WSAuthScheme.BASIC)
.get()
.map(checkStatus) // function that evaluates the HTTP Status
.map(_.json) // get the json
.map(Json.prettyPrint) // get it as string
}
I would create a case class directly like:
.map(jsValue => handleJson(jsValue.validate[YourModel])) // or create a model of it (instead) instead of .map(Json.prettyPrint)
Edit
Here an example of checkStatus:
protected def checkStatus(resp: WSResponse): WSResponse = {
resp.status match {
case Status.OK => resp
case Status.NOT_FOUND => throw WebNotFoundException()
case Status.FORBIDDEN | Status.UNAUTHORIZED => throw WebAccessForbiddenException()
case Status.NOT_ACCEPTABLE => throw WebNotAcceptableException()
case _ => throw WebBadStatusException(resp.status + " - " + resp.statusText.toString)
}
}
The Exception are created by myself.
The authorization can also be inputs into the function or retrieved from environment variables within the method (much easier to manage).
Simply needed to use .body on the Await call, which converts the output to generic type string.
package utils
import javax.inject._
import play.api._
import play.api.http.HttpEntity
import play.api.libs.ws._
import play.api.mvc._
import play.api.Play.current
import scala.collection.mutable.ListBuffer
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import sys.process._
#Singleton
class HTTPRequest #Inject() (
ws: WSClient,
ec: ExecutionContext,
config: Configuration) {
def bbApiRequest(requestUrl: String, timeout: FiniteDuration) = {
val request = ws
.url(requestUrl)
.withAuth(
"user",
"PW123",
WSAuthScheme.BASIC)
.get()
Await.result(request, timeout).body
}
}
I'm trying to create a function to check if a string is a date. However, the following function got the error.
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import java.sql._
import scala.util.{Success, Try}
def validateDate(date: String): Boolean = {
val df = new java.text.SimpleDateFormat("yyyyMMdd")
val test = Try[Date](df.parse(date))
test match {
case Success(_) => true
case _ => false
}
}
Error:
[error] C:\Users\user1\IdeaProjects\sqlServer\src\main\scala\main.scala:14: type mismatch;
[error] found : java.util.Date
[error] required: java.sql.Date
[error] val test = Try[Date](df.parse(date))
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed May 17, 2017 1:19:33 PM
Is there a simpler way to validate if a string is a date without create a function?
The function is used to validate the command line argument.
if (args.length != 2 || validateDate(args(0))) { .... }
Try[Date](df.parse(date)) You are not interested in type here because you ignore it. So simply omit type parameter. Try(df.parse(date)).
Your function could be shorter. Try(df.parse(date)).isSuccess instead pattern matching.
If your environment contains java 8 then use java.time package always.
import scala.util.Try
import java.time.LocalDate
import java.time.format.DateTimeFormatter
// Move creation of formatter out of function to reduce short lived objects allocation.
val df = DateTimeFormatter.ofPattern("yyyy MM dd")
def datebleStr(s: String): Boolean = Try(LocalDate.parse(s,df)).isSuccess
use this: import java.util.Date
I copied the instructions on the JSON formatting Guide found here: http://www.scalatra.org/2.2/guides/formats/json.html
Below is MyScalatraServlet.scala file with all of the code I embedded to test out JSON formatting:
package net.example.testapp
import org.scalatra._
import scalate.ScalateSupport
// JSON-related libraries
import org.json4s.{DefaultFormats, Formats}
// JSON handling support from Scalatra
import org.scalatra.json._
class MyScalatraServlet extends TestAppStack with JacksonJsonSupport {
get("/") {
FlowerData.all
}
}
// Sets up automatic case class to JSON output serialization, required by
// the JValueResult trait.
protected implicit val jsonFormats: Formats = DefaultFormats
case class Flower(slug: String, name: String)
object FlowerData {
/**
* Some fake flowers data so we can simulate retrievals.
*/
var all = List(
Flower("yellow-tulip", "Yellow Tulip"),
Flower("red-rose", "Red Rose"),
Flower("black-rose", "Black Rose"))
}
It seems the compiler does not like the following line:
protected implicit val jsonFormats: Formats = DefaultFormats
Here's the error message:
[error] /Users/test/test-app/src/main/scala/net/example/testapp/MyScalatraServlet.scala:22: expected start of definition
[error] protected implicit val jsonFormats: Formats = DefaultFormats
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 2 s, completed Jun 17, 2013 4:04:34 PM
>
Your val jsonFormats is just kinda floating there, not tied to a class or anything. A val needs to be defined as part of another construct like a trait, class or object. Try moving it inside of that servlet class, just before the call to get("/")