Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HAI-3355 Add haittojenhallintasuunnitelma from hankealue to the PDF #925

Open
wants to merge 1 commit into
base: HAI-3354/hhs-to-pdf
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import com.lowagie.text.Image
import com.lowagie.text.ImgTemplate
import com.lowagie.text.Paragraph
import com.lowagie.text.Phrase
import com.lowagie.text.Rectangle
import com.lowagie.text.pdf.PdfPCell
import com.lowagie.text.pdf.PdfPTable
import fi.hel.haitaton.hanke.domain.Haittojenhallintatyyppi
import fi.hel.haitaton.hanke.domain.Hanke
import fi.hel.haitaton.hanke.domain.SavedHankealue
import fi.hel.haitaton.hanke.hakemus.KaivuilmoitusAlue
import fi.hel.haitaton.hanke.hakemus.KaivuilmoitusData
import fi.hel.haitaton.hanke.tormaystarkastelu.Autoliikenneluokittelu
import fi.hel.haitaton.hanke.tormaystarkastelu.TormaystarkasteluTulos
import java.awt.Color
import java.time.ZonedDateTime
import org.springframework.stereotype.Component

Expand Down Expand Up @@ -77,105 +81,164 @@ class HaittojenhallintasuunnitelmaPdfEncoder(private val mapGenerator: MapGenera
val worstIndexes = kaivuilmoitusalue.worstCasesInTormaystarkastelut()

document.section(hankealue.nimi) {
row("Toimet työalueiden haittojen hallintaan, ${hankealue.nimi}", toimetTitle())
row("", nuisanceScore(worstIndexes?.liikennehaittaindeksi?.indeksi))
hankealueRow(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could all these sections be in separate functions in order to shorten the formatPdf function?

hankealue,
hankealue.tormaystarkasteluTulos?.liikennehaittaindeksi?.indeksi,
Haittojenhallintatyyppi.YLEINEN,
"Toimet työalueiden haittojen hallintaan, ${hankealue.nimi}",
)

row(toimetTitle())
row(nuisanceScore(worstIndexes?.liikennehaittaindeksi?.indeksi))
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[Haittojenhallintatyyppi.YLEINEN]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}

document.section(null) {
row(
"Linja-autojen paikallisliikenne, ${hankealue.nimi}",
map(kaivuilmoitusalue, hankealue) { it?.linjaautoliikenneindeksi },
)
row("", toimetTitle())
row("", nuisanceScore(worstIndexes?.linjaautoliikenneindeksi))

hankealueRow(
hankealue,
hankealue.tormaystarkasteluTulos?.linjaautoliikenneindeksi,
Haittojenhallintatyyppi.LINJAAUTOLIIKENNE,
)
emptyRow()

row(toimetTitle())
row(nuisanceScore(worstIndexes?.linjaautoliikenneindeksi))
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[
Haittojenhallintatyyppi.LINJAAUTOLIIKENNE]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}

document.section(null) {
row(
"Autoliikenteen ruuhkautuminen, ${hankealue.nimi}",
map(kaivuilmoitusalue, hankealue) { it?.autoliikenne?.indeksi },
)
row("", toimetTitle())
row("", autoliikennehaitat(worstIndexes?.autoliikenne))

hankealueRow(
hankealue,
hankealue.tormaystarkasteluTulos?.autoliikenne?.indeksi,
Haittojenhallintatyyppi.AUTOLIIKENNE,
)
emptyRow()

row(toimetTitle())
row(autoliikennehaitat(worstIndexes?.autoliikenne))
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[
Haittojenhallintatyyppi.AUTOLIIKENNE]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}

document.section(null) {
row(
"Pyöräliikenteen merkittävyys, ${hankealue.nimi}",
map(kaivuilmoitusalue, hankealue) { it?.pyoraliikenneindeksi },
)
row("", toimetTitle())
row("", nuisanceScore(worstIndexes?.pyoraliikenneindeksi))

hankealueRow(
hankealue,
hankealue.tormaystarkasteluTulos?.pyoraliikenneindeksi,
Haittojenhallintatyyppi.PYORALIIKENNE,
)
emptyRow()

row(toimetTitle())
row(nuisanceScore(worstIndexes?.pyoraliikenneindeksi))
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[
Haittojenhallintatyyppi.PYORALIIKENNE]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}

document.section(null) {
row(
"Raitioliikenne, ${hankealue.nimi}",
map(kaivuilmoitusalue, hankealue) { it?.raitioliikenneindeksi },
)
row("", toimetTitle())
row("", nuisanceScore(worstIndexes?.raitioliikenneindeksi))

hankealueRow(
hankealue,
hankealue.tormaystarkasteluTulos?.raitioliikenneindeksi,
Haittojenhallintatyyppi.RAITIOLIIKENNE,
)
emptyRow()

row(toimetTitle())
row(nuisanceScore(worstIndexes?.raitioliikenneindeksi))
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[
Haittojenhallintatyyppi.RAITIOLIIKENNE]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}

document.section(null) {
row(
hankealueRow(
hankealue,
null,
Haittojenhallintatyyppi.MUUT,
"Muut haittojenhallintatoimet, ${hankealue.nimi}",
muutHaitat(kaivuilmoitusalue),
)
row("", toimetTitle())

row(muutHaitat(kaivuilmoitusalue))
row(toimetTitle())
val toimet =
kaivuilmoitusalue.haittojenhallintasuunnitelma[Haittojenhallintatyyppi.MUUT]
row("", toimet(toimet))
row("", "")
row(toimet(toimet))
emptyRow()
}
}
}

private fun toimetTitle(): Phrase =
Phrase("Toimet työalueiden haittojen hallintaan", toimetFont)
private fun PdfPTable.hankealueRow(
hankealue: SavedHankealue,
indeksi: Float?,
ryhma: Haittojenhallintatyyppi,
rowTitle: String? = null,
) {
if (rowTitle != null) {
addCell(Phrase(rowTitle, rowHeaderFont))
} else {
addCell(defaultCell)
}

private fun nuisanceScore(
index: Int?,
title: String = "Työalueen haittaindeksi",
color: NuisanceColor? = null,
): Paragraph = nuisanceScore(index?.toFloat(), title, color)

private fun nuisanceScore(
index: Float?,
title: String = "Työalueen haittaindeksi",
color: NuisanceColor? = null,
): Paragraph {
val p = Paragraph(title, blackNuisanceFont)
val horizontalSpacer = Chunk(" ", blackNuisanceFont)
p.add(horizontalSpacer)
p.add(indexChunk(index, color))
return p
val hankealueCell = PdfPCell(defaultCell)
hankealueCell.border = Rectangle.BOX
hankealueCell.borderWidth = pxToPt(1)
hankealueCell.borderColor = Color.BLACK
hankealueCell.backgroundColor = HANKEALUE_COLOR
hankealueCell.setPadding(pxToPt(16))
hankealueCell.isUseBorderPadding = false
hankealueCell.paddingTop = pxToPt(0)

hankealueCell.addElement(Phrase("Hankealueen haittojen hallinta", toimetFont))
hankealueCell.addElement(Phrase(pxToPt(16), Chunk.NEWLINE))

indeksi?.let {
hankealueCell.addElement(nuisanceScore(it, "Hankealueen haittaindeksi"))
hankealueCell.addElement(Phrase(pxToPt(16), Chunk.NEWLINE))
}

hankealueCell.addElement(toimet(hankealue.haittojenhallintasuunnitelma?.get(ryhma)))

addCell(hankealueCell)
}

private fun toimetTitle(): Phrase =
Phrase("Toimet työalueiden haittojen hallintaan", toimetFont)

private fun toimet(toimet: String?): Paragraph {
val kuvaus =
toimet?.ifBlank { null } ?: "Haitaton ei ole tunnistanut hankealueelta tätä kohderyhmää"
Expand All @@ -197,7 +260,7 @@ class HaittojenhallintasuunnitelmaPdfEncoder(private val mapGenerator: MapGenera
p.add(nuisanceScore(haitat?.kaistapituushaitta, "Autoliikenteen kaistavaikutusten pituus"))
p.add(Chunk.NEWLINE)

p.add(nuisanceScore(haitat?.haitanKesto, "Työn kesto"))
p.add(nuisanceScore(haitat?.haitanKesto?.toFloat(), "Työn kesto"))
p.spacingAfter = 0f

return p
Expand Down Expand Up @@ -259,5 +322,7 @@ class HaittojenhallintasuunnitelmaPdfEncoder(private val mapGenerator: MapGenera

const val COLUMN_MAP_WIDTH = 860
const val COLUMN_MAP_HEIGHT = 304

val HANKEALUE_COLOR = Color(0xFF, 0xF4, 0xD4)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ fun PdfPTable.row(key: String, value: String?) {
this.addCell(Phrase(value ?: "<Tyhjä>", textFont))
}

fun PdfPTable.row(key: String, value: Phrase) {
this.addCell(Phrase("$key ", rowHeaderFont))
fun PdfPTable.row(value: Phrase) {
this.addCell(defaultCell)
this.addCell(value)
}

Expand All @@ -95,6 +95,11 @@ fun PdfPTable.row(key: String, image: Image) {
this.addCell(image)
}

fun PdfPTable.emptyRow() {
this.addCell("")
this.addCell("")
}

fun PdfPTable.rowIfNotBlank(title: String, content: String?) {
if (!content.isNullOrBlank()) {
row(title, content)
Expand Down Expand Up @@ -162,6 +167,18 @@ fun loadLocationIcon(writer: PdfWriter): ImgTemplate {
return ImgTemplate(template)
}

fun nuisanceScore(
index: Number?,
title: String = "Työalueen haittaindeksi",
color: NuisanceColor? = null,
): Paragraph {
val p = Paragraph(title, blackNuisanceFont)
val horizontalSpacer = Chunk(" ", blackNuisanceFont)
p.add(horizontalSpacer)
p.add(indexChunk(index?.toFloat(), color))
return p
}

fun indexChunk(index: Float?, color: NuisanceColor? = null): Chunk {
val formatted =
if (index == null) "-"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package fi.hel.haitaton.hanke.pdf

import java.net.URI
import java.net.URL
import org.geotools.http.HTTPClientFinder
import org.geotools.http.LoggingHTTPClient
import org.geotools.ows.wms.WebMapServer
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
Expand All @@ -16,6 +18,8 @@ class WmsConfiguration(

@Bean
fun wms(): WebMapServer {
return WebMapServer(url)
val httpClient = LoggingHTTPClient(HTTPClientFinder.createClient())
httpClient.isTryGzip = true
return WebMapServer(url, httpClient)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,39 @@ class HaittojenhallintasuunnitelmaPdfEncoderTest {
inner class CreatePdf {
private val hankealueId = 414
private val hankealueNimi = "Nimi hankealueelle"
private val hankealue = HankealueFactory.create(id = hankealueId, nimi = hankealueNimi)
private val hankealueenHaittojenhallintasuunnitelma =
mapOf(
Haittojenhallintatyyppi.YLEINEN to "Hankealueen yleiset toimet",
Haittojenhallintatyyppi.AUTOLIIKENNE to "Hankealueen autoilun toimet",
Haittojenhallintatyyppi.PYORALIIKENNE to "Hankealueen pyöräilyn toimet",
Haittojenhallintatyyppi.RAITIOLIIKENNE to "Hankealueen ratikoiden toimet",
Haittojenhallintatyyppi.LINJAAUTOLIIKENNE to "Hankealueen bussien toimet",
Haittojenhallintatyyppi.MUUT to "Hankealueen muut toimet",
)
private val hankealue =
HankealueFactory.create(
id = hankealueId,
nimi = hankealueNimi,
haittojenhallintasuunnitelma = hankealueenHaittojenhallintasuunnitelma,
)

private val hankealueId2 = 5256
private val hankealueNimi2 = "Nimi toiselle hankealueelle"
private val hankealue2 = HankealueFactory.create(id = hankealueId2, nimi = hankealueNimi2)
private val hankealueenHaittojenhallintasuunnitelma2 =
mapOf(
Haittojenhallintatyyppi.YLEINEN to "Toisen hankealueen toimet yleisesti",
Haittojenhallintatyyppi.AUTOLIIKENNE to "Toisen hankealueen toimet autoilulle",
Haittojenhallintatyyppi.PYORALIIKENNE to "Toisen hankealueen toimet pyörille",
Haittojenhallintatyyppi.RAITIOLIIKENNE to "Toisen hankealueen toimet ratikoille",
Haittojenhallintatyyppi.LINJAAUTOLIIKENNE to "Toisen hankealueen toimet busseille",
Haittojenhallintatyyppi.MUUT to "Toisen hankealueen toimet muille",
)
private val hankealue2 =
HankealueFactory.create(
id = hankealueId2,
nimi = hankealueNimi2,
haittojenhallintasuunnitelma = hankealueenHaittojenhallintasuunnitelma2,
)

private val hankealueet = listOf(hankealue, hankealue2)
private val hanke =
Expand Down Expand Up @@ -230,21 +258,7 @@ class HaittojenhallintasuunnitelmaPdfEncoderTest {
contains("Raitioliikenne, $hankealueNimi2")
contains("Muut haittojenhallintatoimet, $hankealueNimi2")
}
verifySequence {
val hakemusalueet1 = listOf(hakemusalue)
val hankealueet1 = listOf(hankealue)
mapGenerator.mapWithAreas(hakemusalueet, hankealueet, 2220, 800, any())
mapGenerator.mapWithAreas(hakemusalueet1, hankealueet1, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet1, hankealueet1, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet1, hankealueet1, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet1, hankealueet1, 1720, 608, any())
val hakemusalueet2 = listOf(hakemusalue2)
val hankealueet2 = listOf(hankealue2)
mapGenerator.mapWithAreas(hakemusalueet2, hankealueet2, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet2, hankealueet2, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet2, hankealueet2, 1720, 608, any())
mapGenerator.mapWithAreas(hakemusalueet2, hankealueet2, 1720, 608, any())
}
verifyGeneratorCalls()
}

@Test
Expand All @@ -266,6 +280,25 @@ class HaittojenhallintasuunnitelmaPdfEncoderTest {
contains(haittojenhallintasuunnitelma2[Haittojenhallintatyyppi.PYORALIIKENNE]!!)
contains("Haitaton ei ole tunnistanut hankealueelta tätä kohderyhmää")
}
verifyGeneratorCalls()
}

@Test
fun `contains texts from haittojenhallintasuunnitelma for hankealue when hankealue matches with hakemusalue`() {
val hakemusData =
HakemusFactory.createKaivuilmoitusData(areas = listOf(hakemusalue, hakemusalue2))

val pdfData = haittojenhallintasuunnitelmaPdfEncoder.createPdf(hanke, hakemusData, 614f)

assertThat(getPdfAsText(pdfData).replace("\\s+".toRegex(), " "))
.contains(
hankealueenHaittojenhallintasuunnitelma.map { it.value } +
hankealueenHaittojenhallintasuunnitelma2.map { it.value }
)
verifyGeneratorCalls()
}

private fun verifyGeneratorCalls() {
verifySequence {
val hakemusalueet1 = listOf(hakemusalue)
val hankealueet1 = listOf(hankealue)
Expand Down
Loading