Serializes points

This commit is contained in:
Julien Lengrand-Lambert
2022-07-08 09:53:21 +02:00
parent ac86da3381
commit ce0c60bd34
13 changed files with 132 additions and 195 deletions

View File

@@ -6,6 +6,7 @@ val exposedVersion: String by project
plugins {
application
kotlin("jvm") version "1.7.0"
kotlin("plugin.serialization") version "1.6.21"
}
@@ -33,6 +34,8 @@ dependencies {
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
implementation("org.postgresql:postgresql:42.3.6")
implementation("net.postgis:postgis-jdbc:2021.1.0")

View File

@@ -1,29 +0,0 @@
<svg
width="244px"
height="244px"
viewBox="0 0 244 244"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#9B00FF" offset="0%"></stop>
<stop stop-color="#0077FF" offset="100%"></stop>
</linearGradient>
</defs>
<g
id="Page-1"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
>
<path
d="M205.639259,176.936244 C207.430887,174.217233 209.093339,171.405629 210.617884,168.510161 M215.112174,158.724316 C216.385153,155.50304 217.495621,152.199852 218.433474,148.824851 M220.655293,138.874185 C221.231935,135.482212 221.637704,132.03207 221.863435,128.532919 M222,118.131039 C221.860539,114.466419 221.523806,110.85231 221.000113,107.299021 M218.885321,96.8583653 C218.001583,93.4468963 216.942225,90.1061026 215.717466,86.8461994 M211.549484,77.3039459 C209.957339,74.1238901 208.200597,71.0404957 206.290425,68.0649233 M200.180513,59.5598295 C181.848457,36.6639805 153.655709,22 122.036748,22 C66.7879774,22 22,66.771525 22,122 C22,177.228475 66.7879774,222 122.036748,222 C152.914668,222 180.52509,208.015313 198.875424,186.036326"
id="Shape"
stroke="url(#linearGradient-1)"
stroke-width="42.0804674"
></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,80 +0,0 @@
import { LitElement, html, css } from 'lit';
import { property } from 'lit/decorators.js';
const logo = new URL('../../assets/open-wc-logo.svg', import.meta.url).href;
export class PluckrApp extends LitElement {
@property({ type: String }) title = 'My app';
static styles = css`
:host {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
font-size: calc(10px + 2vmin);
color: #1a2b42;
max-width: 960px;
margin: 0 auto;
text-align: center;
background-color: var(--pluckr-app-background-color);
}
main {
flex-grow: 1;
}
.logo {
margin-top: 36px;
animation: app-logo-spin infinite 20s linear;
}
@keyframes app-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.app-footer {
font-size: calc(12px + 0.5vmin);
align-items: center;
}
.app-footer a {
margin-left: 5px;
}
`;
render() {
return html`
<main>
<div class="logo"><img alt="open-wc logo" src=${logo} /></div>
<h1>${this.title}</h1>
<p>Edit <code>src/PluckrApp.ts</code> and save to reload.</p>
<a
class="app-link"
href="https://open-wc.org/guides/developing-components/code-examples"
target="_blank"
rel="noopener noreferrer"
>
Code examples
</a>
</main>
<p class="app-footer">
🚽 Made with love by
<a
target="_blank"
rel="noopener noreferrer"
href="https://github.com/open-wc"
>open-wc</a
>.
</p>
`;
}
}

View File

@@ -1,3 +1,35 @@
import { PluckrApp } from './PluckrApp.js';
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
customElements.define('pluckr-app', PluckrApp);
@customElement('pluckr-app')
export class PluckrApp extends LitElement {
@property({ type: String }) title = 'My app';
static styles = css`
:host {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
font-size: calc(10px + 2vmin);
color: #1a2b42;
max-width: 960px;
margin: 0 auto;
text-align: center;
background-color: var(--pluckr-app-background-color);
}
main {
flex-grow: 1;
}
`;
render() {
return html`
<main>
<h1>${this.title}</h1>
</main>
`;
}
}

View File

@@ -0,0 +1,56 @@
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import net.postgis.jdbc.geometry.Point
import nl.lengrand.pluckr.Trees
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
@Serializable
data class Tree(
val id: Int? = null,
val name: String,
val description: String?,
@Serializable(with = PointSerializer::class)
val location : Point
)
object PointSerializer : KSerializer<Point> {
override val descriptor = PrimitiveSerialDescriptor("Point", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): Point {
return Point(decoder.decodeString())
}
override fun serialize(encoder: Encoder, value: Point) {
encoder.encodeString(value.toString())
}
}
private fun fromRow(it: ResultRow): Tree {
return Tree(it[Trees.id], it[Trees.name], it[Trees.description], it[Trees.location])
}
class Controller(private val database: Database) {
fun getTrees() : ArrayList<Tree> {
println("CALLED")
val trees : ArrayList<Tree> = arrayListOf()
transaction(database){
Trees.selectAll().map { trees.add(fromRow(it)) }
}
println(trees)
return trees
}
}

View File

@@ -1,10 +1,13 @@
package nl.lengrand.pluckr
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.metrics.micrometer.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.contentnegotiation.*
import kotlinx.serialization.json.Json
import net.postgis.jdbc.geometry.Point
import nl.lengrand.pluckr.plugins.*
import org.jetbrains.exposed.sql.*
@@ -14,6 +17,12 @@ fun Application.myapp(){
val database = initDb()
install(ContentNegotiation){
json(Json {
prettyPrint = true
isLenient = true
})
}
install(CallLogging)
install(MicrometerMetrics)
@@ -52,7 +61,7 @@ fun main() {
embeddedServer(
Netty,
module = Application::myapp,
port = 8080,
port = 9090,
host = "0.0.0.0")
.start(wait = true)
}

View File

@@ -10,10 +10,13 @@ import org.jetbrains.exposed.sql.Column
import org.jetbrains.exposed.sql.ColumnType
import org.jetbrains.exposed.sql.Table
object Trees : IntIdTable() {
object Trees : Table() {
val id = integer("id").autoIncrement()
val name = varchar("name", 100)
val description = text("description")
val location = point("location")
override val primaryKey = PrimaryKey(id) // name is optional here
}
fun Table.point(name: String, srid: Int = 4326): Column<Point>
@@ -33,10 +36,10 @@ private class PointColumnType(val srid: Int = 4326): ColumnType() {
}
}
class Tree(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<Tree>(Trees)
var name by Trees.name
var description by Trees.description
var location by Trees.location
}
//class Tree(id: EntityID<Int>) : IntEntity(id) {
// companion object : IntEntityClass<Tree>(Trees)
//
// var name by Trees.name
// var description by Trees.description
// var location by Trees.location
//}

View File

@@ -1,25 +1,32 @@
package nl.lengrand.pluckr.plugins
import Controller
import io.ktor.server.routing.*
import io.ktor.server.application.*
import io.ktor.server.http.content.*
import io.ktor.server.response.*
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.transactions.transaction
fun Application.configureRouting(database: Database) {
val controller = Controller(database)
// Starting point for a Ktor app:
routing {
static("/") {
staticBasePackage = "dist"
defaultResource("index.html")
resources(".")
get("/trees") {
call.respond(controller.getTrees())
}
get("/hello") {
call.respondText("Hello the World!")
}
}
routing {
// static("/") {
// staticBasePackage = "dist"
// defaultResource("index.html")
// resources(".")
// }
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
<svg
width="244px"
height="244px"
viewBox="0 0 244 244"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#9B00FF" offset="0%"></stop>
<stop stop-color="#0077FF" offset="100%"></stop>
</linearGradient>
</defs>
<g
id="Page-1"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
>
<path
d="M205.639259,176.936244 C207.430887,174.217233 209.093339,171.405629 210.617884,168.510161 M215.112174,158.724316 C216.385153,155.50304 217.495621,152.199852 218.433474,148.824851 M220.655293,138.874185 C221.231935,135.482212 221.637704,132.03207 221.863435,128.532919 M222,118.131039 C221.860539,114.466419 221.523806,110.85231 221.000113,107.299021 M218.885321,96.8583653 C218.001583,93.4468963 216.942225,90.1061026 215.717466,86.8461994 M211.549484,77.3039459 C209.957339,74.1238901 208.200597,71.0404957 206.290425,68.0649233 M200.180513,59.5598295 C181.848457,36.6639805 153.655709,22 122.036748,22 C66.7879774,22 22,66.771525 22,122 C22,177.228475 66.7879774,222 122.036748,222 C152.914668,222 180.52509,208.015313 198.875424,186.036326"
id="Shape"
stroke="url(#linearGradient-1)"
stroke-width="42.0804674"
></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="Description" content="Put your description here."><base href="/"><style>body,html{margin:0;padding:0;font-family:sans-serif;background-color:#ededed}</style><title>pluckr-app</title></head><body><pluckr-app></pluckr-app><script type="module" src="./566ffb82.js"></script><script inject-service-worker="">"serviceWorker"in navigator&&window.addEventListener("load",(function(){navigator.serviceWorker.register("sw.js").then((function(){console.log('ServiceWorker registered from "sw.js".')})).catch((function(e){console.log("ServiceWorker registration failed: ",e)}))}))</script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="Description" content="Put your description here."><base href="/"><style>body,html{margin:0;padding:0;font-family:sans-serif;background-color:#ededed}</style><title>pluckr-app</title></head><body><pluckr-app></pluckr-app><script type="module" src="./2722f596.js"></script><script inject-service-worker="">"serviceWorker"in navigator&&window.addEventListener("load",(function(){navigator.serviceWorker.register("sw.js").then((function(){console.log('ServiceWorker registered from "sw.js".')})).catch((function(e){console.log("ServiceWorker registration failed: ",e)}))}))</script></body></html>

View File

@@ -1,2 +1,2 @@
if(!self.define){let e,t={};const i=(i,n)=>(i=new URL(i+".js",n).href,t[i]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=t,document.head.appendChild(e)}else e=i,importScripts(i),t()})).then((()=>{let e=t[i];if(!e)throw new Error(`Module ${i} didnt register its module`);return e})));self.define=(n,o)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(t[r])return;let s={};const l=e=>i(e,r),c={module:{uri:r},exports:s,require:l};t[r]=Promise.all(n.map((e=>c[e]||l(e)))).then((e=>(o(...e),s)))}}define(["./workbox-2266476f"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"566ffb82.js",revision:"186b5ed7eabaef626f004fd1db2a8a69"},{url:"index.html",revision:"508c7b3c698de5e8cc1ba3976005cbad"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
if(!self.define){let e,t={};const i=(i,n)=>(i=new URL(i+".js",n).href,t[i]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=t,document.head.appendChild(e)}else e=i,importScripts(i),t()})).then((()=>{let e=t[i];if(!e)throw new Error(`Module ${i} didnt register its module`);return e})));self.define=(n,o)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(t[r])return;let s={};const l=e=>i(e,r),f={module:{uri:r},exports:s,require:l};t[r]=Promise.all(n.map((e=>f[e]||l(e)))).then((e=>(o(...e),s)))}}define(["./workbox-2266476f"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"2722f596.js",revision:"8ce3bf82f431564098d054ed2792250d"},{url:"index.html",revision:"cea8e24c26f2dd07ebcf554120f94673"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
//# sourceMappingURL=sw.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"sw.js","sources":["../../../../../../../../private/var/folders/4b/jjn7wslx5fl1r5npk147_9b80000gn/T/23d22037cbe6f8dc8db70020678a981c/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"566ffb82.js\",\n \"revision\": \"186b5ed7eabaef626f004fd1db2a8a69\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"508c7b3c698de5e8cc1ba3976005cbad\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,qCAEb,IAE0BC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
{"version":3,"file":"sw.js","sources":["../../../../../../../../private/var/folders/4b/jjn7wslx5fl1r5npk147_9b80000gn/T/1891e144a4ec80f40d0033007409695b/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/julienlengrand-lambert/Developer/pluckr/src/main/js/pluckr-app/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"2722f596.js\",\n \"revision\": \"8ce3bf82f431564098d054ed2792250d\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"cea8e24c26f2dd07ebcf554120f94673\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,qCAEb,IAE0BC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}