def test_opdatering_punktinformation(firedb, sag, punkt):
    pit = firedb.hent_punktinformationtype("IDENT:landsnr")

    pi1 = PunktInformation(infotype=pit, punkt=punkt, tekst="K-12-1231")
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Testindsættelse af punktinfo")],
            eventtype=EventType.PUNKTINFO_TILFOEJET,
            punktinformationer=[pi1],
        )
    )

    pi2 = PunktInformation(infotype=pit, punkt=punkt, tekst="K-22-2231")
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Testindsættelse af punktinfo")],
            eventtype=EventType.PUNKTINFO_TILFOEJET,
            punktinformationer=[pi2],
        )
    )

    infotyper = (
        firedb.session.query(PunktInformation)
        .filter(
            PunktInformation.infotypeid == pit.infotypeid,
            PunktInformation.punktid == punkt.id,
        )
        .all()
    )

    assert len(infotyper) == 2
    assert infotyper[0].registreringtil == infotyper[1].registreringfra
    assert infotyper[0].sagseventtilid == infotyper[1].sagseventfraid
Beispiel #2
0
def test_afregistrering_sagseventinfo(firedb: FireDb, sagsevent: Sagsevent):
    """
    Test trigger sagseventinfo_bi_trg - Automatisk afrestrering af tidligere sagseventinfo.
    """
    si1 = SagseventInfo(sagsevent=sagsevent, beskrivelse="Første udgave")

    firedb.session.add(si1)
    firedb.session.commit()

    si2 = SagseventInfo(sagsevent=sagsevent, beskrivelse="Første udgave")
    firedb.session.add(si1)
    firedb.session.commit()

    assert si1.registreringtil == si2.registreringfra
    assert si2.registreringtil is None
Beispiel #3
0
def test_indset_flere_observationer(firedb: FireDb, sag: Sag, punkt: Punkt):
    obstype = firedb.session.query(ObservationsType).first()

    sagsevent = Sagsevent(sag=sag, id=uuid(), eventtype=EventType.OBSERVATION_INDSAT)
    sagseventtekst = "Ilægning af flere observationer"
    sagseventinfo = SagseventInfo(beskrivelse=sagseventtekst)
    sagsevent.sagseventinfos.append(sagseventinfo)

    obs1 = Observation(
        antal=0,
        observationstype=obstype,
        observationstidspunkt=dt.datetime.utcnow(),
        opstillingspunkt=punkt,
        value1=0,
        value2=0,
        value3=0,
        value4=0,
        value5=0,
        value6=0,
        value7=0,
        value8=0,
    )

    obs2 = Observation(
        antal=0,
        observationstype=obstype,
        observationstidspunkt=dt.datetime.utcnow(),
        opstillingspunkt=punkt,
        value1=0,
        value2=0,
        value3=0,
        value4=0,
        value5=0,
        value6=0,
        value7=0,
        value8=0,
    )

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.OBSERVATION_INDSAT,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Testindsættelse af flere observationer")
            ],
            observationer=[obs1, obs2],
        )
    )
Beispiel #4
0
def test_grafik_unikke_filnavne(firedb: FireDb, sag: Sag, sagsevent: Sagsevent):
    """Test at der ikke kan oprettes filnavnedupletter"""
    filnavn = f"{fire.uuid()}.png"
    sagsevent.eventtype = EventType.PUNKT_OPRETTET
    p1 = Punkt(sagsevent=sagsevent)
    p2 = Punkt(sagsevent=sagsevent)

    g1 = Grafik(
        punkt=p1,
        filnavn=filnavn,
        mimetype="image/png",
        type="skitse",
        grafik=b"\xf3\xf5\xf8\x98",
    )

    g2 = Grafik(
        punkt=p2,
        filnavn=filnavn,
        mimetype="image/png",
        type="skitse",
        grafik=b"\xf3\xf5\xf8\x98",
    )

    with pytest.raises(DatabaseError):
        firedb.indset_sagsevent(
            Sagsevent(
                sag=sag,
                sagseventinfos=[
                    SagseventInfo(beskrivelse="Test fejl ved filnavnduplet")
                ],
                eventtype=EventType.GRAFIK_INDSAT,
                grafikker=[g1, g2],
            )
        )
    firedb.session.rollback()
Beispiel #5
0
 def fabrik():
     e0 = Sagsevent(
         sag=sag,
         eventtype=EventType.KOMMENTAR,
         sagseventinfos=[SagseventInfo(beskrivelse="test")],
     )
     firedb.session.add(e0)
     return e0
Beispiel #6
0
def test_indset_beregning(
    firedb: FireDb,
    sag: Sag,
    sagsevent: Sagsevent,
    punkt: Punkt,
    srid: Srid,
    observationstype: ObservationsType,
):
    o0 = Observation(
        sagsevent=sagsevent,
        observationstidspunkt=func.current_timestamp(),
        observationstype=observationstype,
        opstillingspunkt=punkt,
    )

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Testindsættelse af observation")
            ],
            eventtype=EventType.OBSERVATION_INDSAT,
            observationer=[o0],
        ))
    beregning = Beregning()
    beregning.observationer.append(o0)
    koordinat = Koordinat(srid=srid,
                          punkt=punkt,
                          x=0,
                          y=0,
                          z=0,
                          sx=0,
                          sy=0,
                          sz=0)
    beregning.koordinater.append(koordinat)

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.KOORDINAT_BEREGNET,
            sagseventinfos=[SagseventInfo(beskrivelse="Testberegning")],
            beregninger=[beregning],
            koordinater=beregning.koordinater,
        ))

    assert koordinat.objektid is not None
def test_indset_punktinformation(firedb, sag, punkt, punktinformationtype):
    pi = PunktInformation(infotype=punktinformationtype, punkt=punkt)
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Testindsættelse af punktinfo")],
            eventtype=EventType.PUNKTINFO_TILFOEJET,
            punktinformationer=[pi],
        )
    )
Beispiel #8
0
def punkt(uuid: str, sagsbehandler, **kwargs) -> None:
    """
    Luk et punkt i FIRE databasen.

    Se `punkt_hjælp` for yderligere information.
    """
    db = fire.cli.firedb
    sag = Sag(
        id=fire.uuid(),
        sagsinfos=[
            Sagsinfo(
                behandler=sagsbehandler,
                beskrivelse="Lukning af objekt med 'fire luk'",
                aktiv="true",
            )
        ],
    )
    db.session.add(sag)
    db.session.flush()
    sagsevent = Sagsevent(
        sag=sag,
        eventtype=EventType.PUNKT_NEDLAGT,
        sagseventinfos=[
            SagseventInfo(beskrivelse=f"'fire luk punkt {uuid}"),
        ],
    )

    try:
        punkt = db.hent_punkt(uuid)
    except NoResultFound:
        fire.cli.print(f"Punkt med UUID {uuid} ikke fundet!")
        raise SystemExit

    try:
        # Indsæt alle objekter i denne session
        db.luk_punkt(punkt, sagsevent, commit=False)
        db.session.flush()
        db.luk_sag(sag, commit=False)
        db.session.flush()
    except DatabaseError as e:
        # rul tilbage hvis databasen smider en exception
        db.session.rollback()
        fire.cli.print(f"Der opstod en fejl - punkt id {uuid} IKKE lukket!")
        print(e)
    else:
        tekst = f"Er du sikker på at du vil lukke punktet {punkt.ident} ({uuid})?"
        spørgsmål = f"{STOP}\n\n" + click.style(tekst, bg="red", fg="white")
        spørgsmål += "\n\n\nLukning af punktet KAN IKKE rulles tilbage. Denne ændring er irreversibel,\n"
        spørgsmål += "tænkt dig grundigt om inden du siger ja."
        if bekræft(spørgsmål):
            db.session.commit()
            fire.cli.print(f"Punkt {punkt.ident} ({uuid} lukket!")
        else:
            db.session.rollback()
            fire.cli.print(f"Punkt {punkt.ident} ({uuid} IKKE lukket!")
Beispiel #9
0
def test_indset_sagsevent(firedb: FireDb, sag: Sag):
    sagseventinfo = SagseventInfo(beskrivelse="Testing testing")
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.KOMMENTAR,
            sagseventinfos=[sagseventinfo],
        ))

    s = firedb.hent_sag(sag.id)
    assert s.sagsevents[0].sagseventinfos[0].beskrivelse == "Testing testing"
Beispiel #10
0
def test_grafik_opdatering(firedb: FireDb, sag: Sag, punkt: Punkt):
    """Test at et nyt Grafik-objekt erstatter et gammelt korrekt"""
    filnavn = f"{fire.uuid()}.png"
    g1 = Grafik(
        punkt=punkt,
        filnavn=filnavn,
        mimetype="image/png",
        type="skitse",
        grafik=b"\xf3\xf5\xf8\x98",
    )

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Testindsættelse af grafik")],
            eventtype=EventType.GRAFIK_INDSAT,
            grafikker=[g1],
        )
    )

    g2 = Grafik(
        punkt=punkt,
        filnavn=filnavn,
        mimetype="image/png",
        type="skitse",
        grafik=b"\xf3\xf5\xf8\x99",
    )

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Opdatering af grafik")],
            eventtype=EventType.GRAFIK_INDSAT,
            grafikker=[g2],
        )
    )

    assert g1.registreringtil == g2.registreringfra
    assert g1.sagseventtilid == g2.sagseventfraid
Beispiel #11
0
def luk_sag(projektnavn: str, **kwargs) -> None:
    """Luk sag i databasen"""
    er_projekt_okay(projektnavn)
    sag = find_sag(projektnavn)

    # Find sagsmateriale og zip det for let indlæsning i databasen
    sagsmaterialer = [f"{projektnavn}.xlsx"]
    filoversigt = find_faneblad(projektnavn, "Filoversigt", arkdef.FILOVERSIGT)
    sagsmaterialer.extend(list(filoversigt["Filnavn"]))
    zipped = BytesIO()
    with ZipFile(zipped, "w") as zipobj:
        for fil in sagsmaterialer:
            zipobj.write(fil)

    # Tilføj materiale til sagsevent
    sagsevent = Sagsevent(
        sag=sag,
        eventtype=EventType.KOMMENTAR,
        sagseventinfos=[
            SagseventInfo(
                beskrivelse=f"Sagsmateriale for {projektnavn}",
                materialer=[
                    SagseventInfoMateriale(materiale=zipped.getvalue())
                ],
            ),
        ],
    )
    fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)

    fire.cli.firedb.luk_sag(sag, commit=False)
    try:
        # Indsæt alle objekter i denne session
        fire.cli.firedb.session.flush()
    except:
        # rul tilbage hvis databasen smider en exception
        fire.cli.firedb.session.rollback()
        fire.cli.print(
            f"Der opstod en fejl - sag {sag.id} for '{projektnavn}' IKKE lukket!"
        )
    else:
        spørgsmål = click.style(
            f"Er du sikker på at du vil lukke sagen {projektnavn}?",
            bg="red",
            fg="white",
        )
        if bekræft(spørgsmål):
            fire.cli.firedb.session.commit()
            fire.cli.print(f"Sag {sag.id} for '{projektnavn}' lukket!")
        else:
            fire.cli.firedb.session.rollback()
            fire.cli.print(f"Sag {sag.id} for '{projektnavn}' IKKE lukket!")
def add_coordinates(sag, koordinater, beskrivelse):
    """
    Tilføj koordinater og dertilhørende sagsevent til sag
    """
    sagseventinfo = SagseventInfo(beskrivelse=beskrivelse)
    sagsevent = Sagsevent(
        id=str(uuid.uuid4()),
        sag=sag,
        eventtype=EventType.KOORDINAT_BEREGNET,
        sagseventinfos=[sagseventinfo],
        koordinater=koordinater,
    )
    print("add_coordinates: " + beskrivelse)
    firedb.indset_sagsevent(sagsevent)
Beispiel #13
0
def test_indset_punkt(firedb: FireDb, sag: Sag):
    p = Punkt()
    go = GeometriObjekt()
    go.geometri = Point([1, 1])
    p.geometriobjekter.append(go)

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Testindsættelse af et punkt")
            ],
            eventtype=EventType.PUNKT_OPRETTET,
            punkter=[p],
        ))
Beispiel #14
0
def test_indset_sagsevent_materiale(firedb: FireDb, sag: Sag):

    blob = os.urandom(1000)

    sagseventinfo = SagseventInfo(
        beskrivelse="Testing testing",
        materialer=[SagseventInfoMateriale(materiale=blob)],
    )
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.KOMMENTAR,
            sagseventinfos=[sagseventinfo],
        ))

    s = firedb.hent_sag(sag.id)
    assert s.sagsevents[0].sagseventinfos[0].materialer[0].materiale == blob
Beispiel #15
0
def main():
    infotype = firedb.hent_punktinformationtype(ATTRIBUT)
    if infotype is None:
        firedb.indset_punktinformationtype(
            PunktInformationType(
                name=ATTRIBUT,
                anvendelse=fire.api.model.PunktInformationTypeAnvendelse.TEKST,
                beskrivelse="Fundamentalpunkt i referencesystemet angivet i TEKST",
            )
        )
        infotype = firedb.hent_punktinformationtype(ATTRIBUT)

    print(infotype)

    sagsinfo = Sagsinfo(
        aktiv="true",
        behandler="Kristian Evers",
        beskrivelse=sagsbeskrivelse
    )
    sagid = str(uuid.uuid4())
    firedb.indset_sag(Sag(id=sagid, sagsinfos=[sagsinfo]))
    sag =  firedb.hent_sag(sagid)

    punktinformationer =  []

    for srid, identer in PUNKTER.items():
        for ident in identer:
            try:
                punkt = firedb.hent_punkt(ident)
            except NoResultFound:
                print(f'fejl: {ident}')
                continue
            pi = PunktInformation(infotype=infotype, punkt=punkt, tekst=srid)
            punktinformationer.append(pi)

    sagseventinfo = SagseventInfo(beskrivelse=f"Indsættelse af {ATTRIBUT} attributter")
    sagsevent = Sagsevent(
        id=str(uuid.uuid4()),
        sag=sag,
        eventtype=fire.api.model.EventType.PUNKTINFO_TILFOEJET,
        sagseventinfos=[sagseventinfo],
        punktinformationer=punktinformationer,
    )
    firedb.indset_sagsevent(sagsevent)
Beispiel #16
0
def main():

    firedb.indset_punktinformationtype(
        PunktInformationType(
            name=ATTRIBUT,
            anvendelse=fire.api.model.PunktInformationTypeAnvendelse.FLAG,
            beskrivelse="Punkter i den oprindelige DVR90-udjævning",
        ))
    infotype = firedb.hent_punktinformationtype(ATTRIBUT)

    sagsinfo = Sagsinfo(aktiv="true",
                        behandler="Kristian Evers",
                        beskrivelse=sagsbeskrivelse)
    sagid = str(uuid.uuid4())
    firedb.indset_sag(Sag(id=sagid, sagsinfos=[sagsinfo]))
    sag = firedb.hent_sag(sagid)

    with open(POINT_FILE) as f:
        punkter = [punkt.strip() for punkt in f.readlines()]

        punktinformationer = []
        # interaktion med databasen er pokkers langsomt, vis fremdrift
        with click.progressbar(punkter, label="Punkter") as punkter_progress:
            for ident in punkter_progress:
                try:
                    punkt = get_punkt(ident)
                except sqlalchemy.orm.exc.NoResultFound:
                    print(f"Ident ikke fundet: {ident}")
                    continue

                pi = PunktInformation(infotype=infotype, punkt=punkt)
                punktinformationer.append(pi)

    sagseventinfo = SagseventInfo(
        beskrivelse=f"Indsættelse af {ATTRIBUT} attibutter")
    sagsevent = Sagsevent(
        id=str(uuid.uuid4()),
        sag=sag,
        eventtype=fire.api.model.EventType.PUNKTINFO_TILFOEJET,
        sagseventinfos=[sagseventinfo],
        punktinformationer=punktinformationer,
    )
    firedb.indset_sagsevent(sagsevent)
Beispiel #17
0
def test_grafik(firedb: FireDb, sag: Sag, punkt: Punkt):
    """Test oprettelse af et Grafik objekt)"""
    filnavn = f"{fire.uuid()}.png"

    with open(PNG, "rb") as f:
        g = Grafik(
            punkt=punkt,
            grafik=f.read(),
            type="skitse",
            mimetype="image/png",
            filnavn=filnavn,
        )

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Testindsættelse af grafik")],
            eventtype=EventType.GRAFIK_INDSAT,
            grafikker=[g],
        )
    )
Beispiel #18
0
def test_geometriobjekt_afregistrering(firedb: FireDb, sag: Sag):
    """
    Test at forudgående geometrier afregistreres korrekt ved indsættelse af ny.
    """

    p = firedb.hent_punkt("SKEJ")
    n = len(p.geometriobjekter)
    go = GeometriObjekt()
    go.geometri = Point([10.17983, 56.18759])
    go.punkt = p

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[SagseventInfo(beskrivelse="Opdater geometri")],
            eventtype=EventType.PUNKT_OPRETTET,
            geometriobjekter=[go],
        ))

    geom = p.geometriobjekter
    assert n + 1 == len(p.geometriobjekter)
    assert geom[-2].registreringtil == geom[-1].registreringfra
    assert geom[-2].sagseventtilid == geom[-1].sagseventfraid
Beispiel #19
0
def indsæt(
    ident: str, sti: Path, type: str, filnavn: str, sagsbehandler, **kwargs
) -> None:
    r"""
    Indsæt grafik i databasen.

    EKSEMPLER

    Indsæt skitse fra PNG-fil:

        > fire grafik indsæt K-01-01234 K-01-01234.png

    Anvend andet filnavn i databasen:

        > fire grafik indsæt G.M.902 IMG_5234.jpg --filnavn aarhus_domkirke.jpg

    Eksplicer grafiktype og filnavn:

        > fire grafik indsæt K-01-012345 C:\tmp\skitse.png --type skitse --filnavn K-01-012345.png

    """
    db = fire.cli.firedb
    try:
        g = db.hent_grafik(filnavn)
    except NoResultFound:
        g = None

    if g:
        if ident not in g.punkt.identer:
            raise SystemExit(
                f"Kan ikke indsætte {filnavn} på {ident},"
                " allerede regisreret på {g.punkt.ident}"
            )

    punkt = db.hent_punkt(ident)
    if not filnavn:
        filnavn = sti.name

    for grafik in punkt.grafikker:
        if grafik.filnavn == filnavn:
            spørgsmål = f"Grafik med filnavn {filnavn} allerede tilknyttet {punkt.ident} - vil du overskrive det?"
            if bekræft(spørgsmål, gentag=False):
                break
            else:
                raise SystemExit

    # sagshåndtering
    sag = Sag(
        id=fire.uuid(),
        sagsinfos=[
            Sagsinfo(
                aktiv="true",
                behandler=sagsbehandler,
                beskrivelse="Indsættelse af ny grafik med 'fire grafik'",
            )
        ],
    )
    db.indset_sag(sag, commit=False)
    try:
        fire.cli.firedb.session.flush()
    except Exception as ex:
        fire.cli.firedb.session.rollback()
        raise SystemExit(ex)

    # opret grafik
    grafik = Grafik.fra_fil(punkt, sti)
    grafik.type = type
    grafik.filnavn = filnavn

    sagsevent = Sagsevent(
        sag=sag,
        eventtype=EventType.GRAFIK_INDSAT,
        sagseventinfos=[
            SagseventInfo(
                beskrivelse=f"Grafik {filnavn} indsættes på punkt {punkt.ident}"
            )
        ],
        grafikker=[grafik],
    )
    db.indset_sagsevent(sagsevent, commit=False)
    db.luk_sag(sag, commit=False)
    try:
        # Indsæt alle objekter i denne session
        fire.cli.firedb.session.flush()
    except Exception as e:
        # rul tilbage hvis databasen smider en exception
        fire.cli.firedb.session.rollback()
        fire.cli.print(f"Der opstod en fejl - fil {filnavn} IKKE indsat!")
    else:
        spørgsmål = click.style(
            f"Er du sikker på at du vil tilknytte grafikken {filnavn} til {punkt.ident}?",
            bg="red",
            fg="white",
        )
        if bekræft(spørgsmål):
            fire.cli.firedb.session.commit()
            fire.cli.print(f"fil {filnavn} tilknyttet {punkt.ident}!")
        else:
            fire.cli.firedb.session.rollback()
            fire.cli.print(f"fil {filnavn} IKKE tilknyttet {punkt.ident}!")
Beispiel #20
0
def slet(filnavn: str, sagsbehandler: str, **kwargs) -> None:
    """
    Slet en grafik fra databasen.

    Grafikken identificeres ud fra sit filnavn. Filnavnet på en grafik kan findes ved
    opslag med ``fire info punkt <ident>``.
    """
    db = fire.cli.firedb

    try:
        grafik = db.hent_grafik(filnavn)
    except NoResultFound:
        raise SystemExit(f"Fandt ikke {filnavn}!")

    punkt = grafik.punkt

    # sagshåndtering
    sag = Sag(
        id=fire.uuid(),
        sagsinfos=[
            Sagsinfo(
                aktiv="true",
                behandler=sagsbehandler,
                beskrivelse="Afregistrering af grafik med `fire grafik slet`",
            )
        ],
    )
    db.indset_sag(sag, commit=False)
    try:
        fire.cli.firedb.session.flush()
    except Exception as ex:
        fire.cli.firedb.session.rollback()
        raise SystemExit(ex)

    sagsevent = Sagsevent(
        sag=sag,
        sagseventinfos=[
            SagseventInfo(
                beskrivelse=f"Grafik {filnavn} for {punkt.ident} afregistreret"
            )
        ],
    )
    db.luk_grafik(grafik, sagsevent, commit=False)
    db.luk_sag(sag, commit=False)
    try:
        # Indsæt alle objekter i denne session
        fire.cli.firedb.session.flush()
    except Exception as e:
        # rul tilbage hvis databasen smider en exception
        fire.cli.firedb.session.rollback()
        fire.cli.print(f"Der opstod en fejl - fil {filnavn} IKKE slettet!")
    else:
        spørgsmål = click.style(
            f"Er du sikker på at du vil slettet grafikken {filnavn} tilhørende {punkt.ident}?",
            bg="red",
            fg="white",
        )
        if bekræft(spørgsmål):
            fire.cli.firedb.session.commit()
            fire.cli.print(f"fil {filnavn} slettet fra {punkt.ident}!")
        else:
            fire.cli.firedb.session.rollback()
            fire.cli.print(f"fil {filnavn} IKKE slettet fra {punkt.ident}!")
Beispiel #21
0
def ilæg_nye_koter(projektnavn: str, sagsbehandler: str, **kwargs) -> None:
    """Registrer nyberegnede koter i databasen"""
    sag = find_sag(projektnavn)
    sagsgang = find_sagsgang(projektnavn)

    sag = find_sag(projektnavn)
    sagsgang = find_sagsgang(projektnavn)

    fire.cli.print(f"Sags/projekt-navn: {projektnavn}  ({sag.id})")
    fire.cli.print(f"Sagsbehandler:     {sagsbehandler}")

    punktoversigt = find_faneblad(projektnavn, "Endelig beregning",
                                  ARKDEF_PUNKTOVERSIGT)
    ny_punktoversigt = punktoversigt[0:0]

    DVR90 = fire.cli.firedb.hent_srid("EPSG:5799")
    registreringstidspunkt = func.current_timestamp()
    tid = gyldighedstidspunkt(projektnavn)

    # Generer sagsevent
    sagsevent = Sagsevent(sag=sag,
                          id=uuid(),
                          eventtype=EventType.KOORDINAT_BEREGNET)

    til_registrering = []
    opdaterede_punkter = []
    for punktdata in punktoversigt.to_dict(orient="records"):
        # Blanklinje, tilbageholdt, eller allerede registreret?
        if (pd.isna(punktdata["Ny kote"]) or punktdata["uuid"] != ""
                or punktdata["Udelad publikation"] == "x"):
            ny_punktoversigt = ny_punktoversigt.append(punktdata,
                                                       ignore_index=True)
            continue

        punkt = fire.cli.firedb.hent_punkt(punktdata["Punkt"])
        opdaterede_punkter.append(punkt)
        punktdata["uuid"] = sagsevent.id

        kote = Koordinat(
            srid=DVR90,
            punkt=punkt,
            t=tid,
            z=punktdata["Ny kote"],
            sz=punktdata["Ny σ"],
        )

        til_registrering.append(kote)
        ny_punktoversigt = ny_punktoversigt.append(punktdata,
                                                   ignore_index=True)

    if 0 == len(til_registrering):
        fire.cli.print("Ingen koter at registrere!", fg="yellow", bold=True)
        return

    # Vi vil ikke have alt for lange sagseventtekster (bl.a. fordi Oracle ikke
    # kan lide lange tekststrenge), så vi indsætter udeladelsesprikker hvis vi
    # opdaterer mere end 10 punkter ad gangen
    n = len(opdaterede_punkter)
    punktnavne = [p.ident for p in opdaterede_punkter]
    if n > 10:
        punktnavne[9] = "..."
        punktnavne[10] = punktnavne[-1]
        punktnavne = punktnavne[0:10]
    sagseventtekst = f"Opdatering af DVR90 kote til {', '.join(punktnavne)}"
    with open(f"{projektnavn}-resultat-endelig.html") as html:
        clob = "".join(html.readlines())
    sagseventinfo = SagseventInfo(
        beskrivelse=sagseventtekst,
        htmler=[SagseventInfoHtml(html=clob)],
    )
    sagsevent.sagseventinfos.append(sagseventinfo)
    sagsevent.koordinater = til_registrering
    fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)

    # Generer dokumentation til fanebladet "Sagsgang"
    # Variablen "registreringstidspunkt" har værdien "CURRENT_TIMESTAMP"
    # som udvirker mikrosekundmagi når den bliver skrevet til databasen,
    # men ikke er meget informativ for en menneskelig læser her i regne-
    # arkenes prosaiske verden. Derfor benytter vi pd.Timestamp.now(),
    # som ikke har mikrosekundmagi over sig, men som kan læses og giver
    # mening, selv om den ikke bliver eksakt sammenfaldende med det
    # tidsstempel hændelsen får i databasen. Det lever vi med.
    sagsgangslinje = {
        "Dato": pd.Timestamp.now(),
        "Hvem": sagsbehandler,
        "Hændelse": "Koteberegning",
        "Tekst": sagseventtekst,
        "uuid": sagsevent.id,
    }
    sagsgang = sagsgang.append(sagsgangslinje, ignore_index=True)

    fire.cli.print(sagseventtekst, fg="yellow", bold=True)
    fire.cli.print(f"Ialt {n} koter")

    try:
        fire.cli.firedb.session.flush()
    except Exception as ex:
        # rul tilbage hvis databasen smider en exception
        fire.cli.firedb.session.rollback()
        fire.cli.print(
            f"Der opstod en fejl - koter for '{projektnavn}' IKKE indlæst!")
        fire.cli.print(f"Mulig årsag: {ex}")
    else:
        spørgsmål = click.style("Du indsætter nu ", fg="white", bg="red")
        spørgsmål += click.style(f"{len(til_registrering)} kote(r) ",
                                 fg="white",
                                 bg="red",
                                 bold=True)
        spørgsmål += click.style(f"i ", fg="white", bg="red")
        spørgsmål += click.style(f"{fire.cli.firedb.db}",
                                 fg="white",
                                 bg="red",
                                 bold=True)
        spørgsmål += click.style("-databasen - er du sikker?",
                                 fg="white",
                                 bg="red")

        if bekræft(spørgsmål):
            fire.cli.firedb.session.commit()

            # Skriv resultater til resultatregneark
            resultater = {"Sagsgang": sagsgang, "Resultat": ny_punktoversigt}
            if skriv_ark(projektnavn, resultater):
                fire.cli.print(
                    f"Koter registreret. Resultater skrevet til '{projektnavn}.xlsx'"
                )
Beispiel #22
0
def ilæg_observationer(projektnavn: str, sagsbehandler: str, **kwargs) -> None:
    """Registrer nye observationer i databasen"""
    sag = find_sag(projektnavn)
    sagsgang = find_sagsgang(projektnavn)

    fire.cli.print(f"Sags/projekt-navn: {projektnavn}  ({sag.id})")
    fire.cli.print(f"Sagsbehandler:     {sagsbehandler}")

    obstype_trig = fire.cli.firedb.hent_observationstype(
        "trigonometrisk_koteforskel")
    obstype_geom = fire.cli.firedb.hent_observationstype(
        "geometrisk_koteforskel")
    til_registrering = []

    observationer = find_faneblad(projektnavn, "Observationer",
                                  ARKDEF_OBSERVATIONER)
    alle_kilder = ", ".join(sorted(list(set(observationer.Kilde))))
    alle_uuider = observationer.uuid.astype(str)

    # Generer sagsevent
    sagsevent = Sagsevent(sag=sag,
                          id=uuid(),
                          eventtype=EventType.OBSERVATION_INDSAT)
    sagseventtekst = f"Ilægning af observationer fra {alle_kilder}"
    sagseventinfo = SagseventInfo(beskrivelse=sagseventtekst)
    sagsevent.sagseventinfos.append(sagseventinfo)

    # Generer dokumentation til fanebladet "Sagsgang"
    sagsgangslinje = {
        "Dato": pd.Timestamp.now(),
        "Hvem": sagsbehandler,
        "Hændelse": "observationsilægning",
        "Tekst": sagseventtekst,
        "uuid": sagsevent.id,
    }
    sagsgang = sagsgang.append(sagsgangslinje, ignore_index=True)

    for i, obs in enumerate(observationer.itertuples(index=False)):
        # Ignorer allerede registrerede observationer
        if str(obs.uuid) not in ["", "None", "nan"]:
            continue

        # Vi skal bruge fra- og til-punkterne for at kunne oprette et
        # objekt af typen Observation
        try:
            punktnavn = obs.Fra
            punkt_fra = fire.cli.firedb.hent_punkt(punktnavn)
            punktnavn = obs.Til
            punkt_til = fire.cli.firedb.hent_punkt(punktnavn)
        except NoResultFound:
            fire.cli.print(f"Ukendt punkt: '{punktnavn}'",
                           fg="red",
                           bg="white")
            sys.exit(1)

        # For nivellementsobservationer er gruppeidentifikatoren identisk
        # med journalsidenummeret
        side = obs.Journal.split(":")[0]
        if side.isnumeric():
            gruppe = int(side)
        else:
            gruppe = None

        if obs.Type.upper() == "MTL":
            observation = Observation(
                antal=1,
                observationstype=obstype_trig,
                observationstidspunkt=obs.Hvornår,
                opstillingspunkt=punkt_fra,
                sigtepunkt=punkt_til,
                gruppe=gruppe,
                id=uuid(),
                value1=obs.ΔH,
                value2=obs.L,
                value3=obs.Opst,
                value4=obs.σ,
                value5=obs.δ,
            )
            observation.sagsevent = sagsevent

        elif obs.Type.upper() == "MGL":
            observation = Observation(
                antal=1,
                observationstype=obstype_geom,
                observationstidspunkt=obs.Hvornår,
                opstillingspunkt=punkt_fra,
                sigtepunkt=punkt_til,
                gruppe=gruppe,
                id=uuid(),
                value1=obs.ΔH,
                value2=obs.L,
                value3=obs.Opst,
                value4=
                0.0,  # Refraktion, eta_1, er defineret som non-null, så vi sætter den til 0 istf. None
                value5=obs.σ,
                value6=obs.δ,
                value7=
                0,  # 1,2,3 henviser til 1.,2.,3. præcisionsnivellement. 0 til "ingen af dem"
            )
        else:
            fire.cli.print(f"Ukendt observationstype: '{obs.Type}'",
                           fg="red",
                           bg="white")
            sys.exit(1)
        alle_uuider[i] = observation.id
        til_registrering.append(observation)

    # Gør klar til at persistere
    observationer["uuid"] = alle_uuider

    fire.cli.print(sagseventtekst, fg="yellow", bold=True)
    fire.cli.print(str(observationer[["Journal", "Fra", "Til", "uuid"]]))

    # Persister observationerne til databasen
    fire.cli.print(f"Skriver {len(til_registrering)} observationer")
    sagsevent.observationer = til_registrering
    fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)

    try:
        fire.cli.firedb.session.flush()
    except Exception as ex:
        # rul tilbage hvis databasen smider en exception
        fire.cli.firedb.session.rollback()
        fire.cli.print(
            f"Der opstod en fejl - observationer for '{projektnavn}' IKKE indlæst!"
        )
        fire.cli.print(f"Mulig årsag: {ex}")
    else:
        spørgsmål = click.style("Du indsætter nu ", fg="white", bg="red")
        spørgsmål += click.style(f"{len(til_registrering)} observationer ",
                                 fg="white",
                                 bg="red",
                                 bold=True)
        spørgsmål += click.style(f"i ", fg="white", bg="red")
        spørgsmål += click.style(f"{fire.cli.firedb.db}",
                                 fg="white",
                                 bg="red",
                                 bold=True)
        spørgsmål += click.style("-databasen - er du sikker?",
                                 fg="white",
                                 bg="red")

        if bekræft(spørgsmål):
            fire.cli.firedb.session.commit()

            # Skriv resultater til resultatregneark
            resultater = {"Sagsgang": sagsgang, "Observationer": observationer}
            skriv_ark(projektnavn, resultater)
            fire.cli.print(
                f"Observationer registreret. Kopiér nu faneblade fra '{projektnavn}-resultat.xlsx' til '{projektnavn}.xlsx'"
            )
        else:
            fire.cli.firedb.session.rollback()
            fire.cli.print(f"Observationer for '{projektnavn}' IKKE indlæst!")
Beispiel #23
0
    def read(self, sags_id):

        sag = self.fireDb.hent_sag(sags_id)

        namespace = "{http://www.gnu.org/software/gama/gama-local-adjustment}"
        tree = ET.parse(self.input_stream)
        root = tree.getroot()

        beregning = Beregning()

        srid = self.fireDb.hent_srid("EPSG:5799")

        adjusted_element = root.find(namespace +
                                     "coordinates").find(namespace +
                                                         "adjusted")
        cov_mat_values = (
            root.find(namespace +
                      "coordinates").find(namespace +
                                          "cov-mat").findall(namespace +
                                                             "flt"))
        original_index_indicies = (
            root.find(namespace +
                      "coordinates").find(namespace +
                                          "original-index").findall(namespace +
                                                                    "ind"))

        for idx, point in enumerate(adjusted_element.iter(namespace +
                                                          "point")):
            # Read values from the point
            z = point.find(namespace + "z").text
            point_id = point.find(namespace + "id").text

            # Read the correct entry in cov_mat_values
            cov_mat_index = int(original_index_indicies[idx].text) - 1
            cov_mat_element = cov_mat_values[cov_mat_index]
            # Read value as float
            cov_mat_value = float(cov_mat_element.text)
            # .. and tale sqrt to find std_dev
            std_dev = math.sqrt(cov_mat_value)

            koordinat = Koordinat()
            koordinat.srid = srid
            koordinat.z = z
            koordinat.sz = std_dev
            koordinat.punkt = self.fireDb.hent_punkt(point_id)
            beregning.koordinater.append(koordinat)

        observation_id_list = []
        observations_element = root.find(namespace + "observations")
        for idx, diff in enumerate(
                observations_element.iter(namespace + "height-diff")):
            observationId = diff.get("extern")
            observation_id_list.append(observationId)

        observation_list = self.fireDb.hent_observationer(observation_id_list)
        beregning.observationer.extend(observation_list)

        self.fireDb.indset_sagsevent(
            Sagsevent(
                sag=sag,
                eventtype=EventType.KOORDINAT_BEREGNET,
                sagseventinfos=[
                    SagseventInfo(beskrivelse="Beregning indlæst via GNU Gama")
                ],
                beregninger=[beregning],
                koordinater=beregning.koordinater,
            ))
Beispiel #24
0
def test_indset_beregning_invalidates_existing_koordinat(
        firedb: FireDb, sag: Sag, punkt: Punkt, srid: Srid,
        observation: Observation):
    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Testindsættelse af observation")
            ],
            eventtype=EventType.OBSERVATION_INDSAT,
            observationer=[observation],
        ))
    beregning = Beregning()
    beregning.observationer.append(observation)
    koordinat = Koordinat(srid=srid,
                          punkt=punkt,
                          x=0,
                          y=0,
                          z=0,
                          sx=0,
                          sy=0,
                          sz=0)
    beregning.koordinater.append(koordinat)

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.KOORDINAT_BEREGNET,
            sagseventinfos=[SagseventInfo(beskrivelse="Testberegning")],
            beregninger=[beregning],
            koordinater=beregning.koordinater,
        ))

    # new beregning of the same observation with a new koordinat
    beregning2 = Beregning()
    beregning2.observationer.append(observation)
    koordinat2 = Koordinat(
        srid=srid,
        punkt=punkt,
        x=1,
        y=0,
        z=0,
        sx=0,
        sy=0,
        sz=0,
    )
    beregning2.koordinater.append(koordinat2)

    firedb.indset_sagsevent(
        Sagsevent(
            sag=sag,
            eventtype=EventType.KOORDINAT_BEREGNET,
            sagseventinfos=[SagseventInfo(beskrivelse="Testberegning")],
            beregninger=[beregning2],
            koordinater=beregning2.koordinater,
        ))

    assert len(punkt.koordinater) == 2
    assert len([k for k in punkt.koordinater
                if k.registreringtil is None]) == 1
    assert koordinat2.srid is not None
Beispiel #25
0
def ilæg_nye_punkter(projektnavn: str, sagsbehandler: str, **kwargs) -> None:
    """Registrer nyoprettede punkter i databasen"""
    er_projekt_okay(projektnavn)
    sag = find_sag(projektnavn)
    sagsgang = find_sagsgang(projektnavn)

    fire.cli.print(f"Sags/projekt-navn: {projektnavn}  ({sag.id})")
    fire.cli.print(f"Sagsbehandler:     {sagsbehandler}")

    # Opbyg oversigt over nyetablerede punkter
    nyetablerede = find_faneblad(projektnavn, "Nyetablerede punkter",
                                 arkdef.NYETABLEREDE_PUNKTER)
    n = nyetablerede.shape[0]

    if n == 0:
        fire.cli.print("Ingen nyetablerede punkter at registrere")
        return

    landsnummer_pit = fire.cli.firedb.hent_punktinformationtype(
        "IDENT:landsnr")
    beskrivelse_pit = fire.cli.firedb.hent_punktinformationtype(
        "ATTR:beskrivelse")
    bemærkning_pit = fire.cli.firedb.hent_punktinformationtype(
        "ATTR:bemærkning")
    h_over_terræn_pit = fire.cli.firedb.hent_punktinformationtype(
        "AFM:højde_over_terræn")
    attr_gi_pit = fire.cli.firedb.hent_punktinformationtype("ATTR:GI_punkt")
    attr_mv_pit = fire.cli.firedb.hent_punktinformationtype("ATTR:MV_punkt")
    attr_højde_pit = fire.cli.firedb.hent_punktinformationtype(
        "ATTR:højdefikspunkt")
    attr_vandstand_pit = fire.cli.firedb.hent_punktinformationtype(
        "ATTR:vandstandsmåler")
    assert landsnummer_pit is not None, "IDENT:landsnr ikke fundet i database"
    assert beskrivelse_pit is not None, "ATTR:beskrivelse ikke fundet i database"
    assert bemærkning_pit is not None, "ATTR:bemærkning ikke fundet i database"
    assert h_over_terræn_pit is not None, "AFM:højde_over_terræn ikke fundet i database"
    assert attr_gi_pit is not None, "ATTR:GI_punkt ikke fundet i database"
    assert attr_mv_pit is not None, "ATTR:MV_punkt ikke fundet i database"
    assert attr_højde_pit is not None, "ATTR:højdefikspunkt ikke fundet i database"
    assert attr_vandstand_pit is not None, "ATTR:vandstandsmåler ikke fundet i database"

    punkter = {}
    fikspunktstyper = []
    punktinfo = []

    # Opret punkter
    fire.cli.print(f"Behandler punkter")
    # Index frasorterer automatisk blanke linjer og er dermed mere robust.
    # Bemærkes, at felter med usynlige tegn som mellemrum IKKE resulterer
    # i en tom linje og en sådan vil fremtvinge en fejl pga ugyldigt input
    for i in nyetablerede.index:
        # Et tomt tekstfelt kan repræsenteres på en del forskellige måder...
        # Punkter udstyret med uuid er allerede registrerede
        if str(nyetablerede.uuid[i]) not in ["", "None", "nan"]:
            continue

        lokation = normaliser_lokationskoordinat(nyetablerede["Øst"][i],
                                                 nyetablerede["Nord"][i], "DK")

        # Skab nyt punktobjekt
        punkter[i] = Punkt(
            id=uuid(),
            geometriobjekter=[GeometriObjekt(geometri=Point(lokation))],
        )

        try:
            fikspunktstype = FIKSPUNKTSYPER[nyetablerede["Fikspunktstype"]
                                            [i].upper()]
        except KeyError:
            fire.cli.print(
                f"FEJL: '{nyetablerede['Fikspunktstype'][i]}' er ikke en gyldig fikspunktsype! Vælg mellem GI, MV, HØJDE, JESSEN og VANDSTANDSBRÆT",
                bg="red",
                bold=True,
            )
            sys.exit(1)

        fikspunktstyper.append(fikspunktstype)

    # sagsevent for punkter
    er = "er" if len(punkter) > 1 else ""
    sagsevent_punkter = Sagsevent(
        sag=sag,
        eventtype=EventType.PUNKT_OPRETTET,
        sagseventinfos=[
            SagseventInfo(
                beskrivelse=f"Oprettelse af punkt{er} ifm. {projektnavn}", )
        ],
        punkter=list(punkter.values()),
    )
    fire.cli.firedb.indset_sagsevent(sagsevent_punkter, commit=False)
    fire.cli.firedb.session.flush()  # hvis noget ikke virker får vi fejl her!

    # Generer dokumentation til fanebladet "Sagsgang"
    sagsgangslinje = {
        "Dato": sagsevent_punkter.registreringfra,
        "Hvem": sagsbehandler,
        "Hændelse": "punktoprettelse",
        "Tekst": sagsevent_punkter.sagseventinfos[0].beskrivelse,
        "uuid": sagsevent_punkter.id,
    }
    sagsgang = sagsgang.append(sagsgangslinje, ignore_index=True)

    # Opret punktinfo
    fire.cli.print(f"Behandler punktinformationer")
    for i, punkt in punkter.items():
        # Tilføj punktets højde over terræn som punktinformation, hvis anført
        try:
            ΔH = float(nyetablerede["Højde over terræn"][i])
        except (TypeError, ValueError):
            ΔH = 0
        if math.isnan(ΔH):
            ΔH = 0.0
        if not pd.isna(nyetablerede["Højde over terræn"][i]):
            pi_h = PunktInformation(
                infotype=h_over_terræn_pit,
                punkt=punkt,
                tal=ΔH,
            )
            punktinfo.append(pi_h)

        # Tilføj punktets afmærkning som punktinformation, selv hvis ikke anført
        afm_id = 4999  # AFM:4999 = "ukendt"
        afm_ids = {
            "ukendt": 4999,
            "bolt": 2700,
            "lodret bolt": 2701,
            "skruepløk": 2950,
            "ingen": 5998,
        }

        if not pd.isna(nyetablerede["Afmærkning"][i]):
            # Afmærkningsbeskrivelse
            afm = str(nyetablerede["Afmærkning"][i]).lower()
            # Første ord i afmærkningsbeskrivelsen
            afm_første = afm.split()[0].rstrip(":;,.- ").lstrip("afm:")

            if afm_første.isnumeric():
                afm_id = int(afm_første)
            else:
                afm_id = afm_ids.get(afm, 4999)

            afmærkning_pit = fire.cli.firedb.hent_punktinformationtype(
                f"AFM:{afm_id}")
            if afmærkning_pit is None:
                afm_id = 4999
                afmærkning_pit = fire.cli.firedb.hent_punktinformationtype(
                    "AFM:4999")
            beskrivelse = (afmærkning_pit.beskrivelse.replace(
                "-\n", "").replace("\n", " ").rstrip(".").strip())

        if afm_id == 4999:
            fire.cli.print(
                f"ADVARSEL: Nyoprettet punkt index {i} har ingen gyldig afmærkning anført",
                fg="red",
                bg="white",
                bold=True,
            )

        # Grundet den lidt kluntede løsning med AFM:nnnn punktinfo er fx AFM:2700 (bolt)
        # registreret som en tekst-punktinformation (frem for flag, som ville være den
        # ideelle løsning) og tekst attributten skal derfor udfyldes. Vi bruger
        # tekstnøgle til afm_ids.
        afm_txts = {v: k for k, v in afm_ids.items()}
        punktinfo.append(
            PunktInformation(
                infotype=afmærkning_pit,
                punkt=punkt,
                tekst=afm_txts[afm_id].capitalize(),
            ))

        # Tilføj punktbeskrivelsen som punktinformation, hvis anført
        beskrivelse = nyetablerede["Beskrivelse"][i]
        if pd.isna(beskrivelse) or beskrivelse == "":
            navn = nyetablerede["Foreløbigt navn"][i]
            fire.cli.print(
                f"FEJL: Beskrivelse for punkt '{navn}' ikke angivet!",
                fg="white",
                bg="red",
                bold=True,
            )
            fire.cli.firedb.session.rollback()
            raise SystemExit
        punktinfo.append(
            PunktInformation(
                infotype=beskrivelse_pit,
                punkt=punkt,
                tekst=beskrivelse,
            ))

        # Tilknyt regionskode til punktet
        punktinfo.append(opret_region_punktinfo(punkt))

        # Tilknyt ATTR:bemærkning
        punktinfo.append(
            PunktInformation(
                infotype=bemærkning_pit,
                punkt=punkt,
                tekst=f"Nyetb. {datetime.now().year} {sagsbehandler}",
            ))

    # tilknyt diverse punktinfo baseret på fikspunktstypen
    gi_punkter = []
    for punkt, fikspunktstype in zip(punkter.values(), fikspunktstyper):
        if fikspunktstype == FikspunktsType.GI:
            gi_punkter.append(punkt)
            punktinfo.append(
                PunktInformation(infotype=attr_gi_pit, punkt=punkt))

        if fikspunktstype == FikspunktsType.HØJDE:
            punktinfo.append(
                PunktInformation(infotype=attr_højde_pit, punkt=punkt))

        if fikspunktstype == FikspunktsType.MV:
            punktinfo.append(
                PunktInformation(infotype=attr_mv_pit, punkt=punkt))

        if fikspunktstype == FikspunktsType.VANDSTANDSBRÆT:
            punktinfo.append(
                PunktInformation(infotype=attr_vandstand_pit, punkt=punkt))

    # Tilknyt G.I-numre
    gi_identer = fire.cli.firedb.tilknyt_gi_numre(gi_punkter)
    punktinfo.extend(gi_identer)

    # Tilknyt landsnumre til punkter
    landsnumre = dict(
        zip(
            punkter.keys(),
            fire.cli.firedb.tilknyt_landsnumre(punkter.values(),
                                               fikspunktstyper),
        ))
    punktinfo.extend(landsnumre.values())

    # sagsevent for punktinfo
    sagsevent_punktinfo = Sagsevent(
        sag=sag,
        eventtype=EventType.PUNKTINFO_TILFOEJET,
        sagseventinfos=[
            SagseventInfo(
                beskrivelse=f"Oprettelse af punktinfo ifm. {projektnavn}", )
        ],
        punktinformationer=punktinfo,
    )
    fire.cli.firedb.indset_sagsevent(sagsevent_punktinfo, commit=False)
    fire.cli.firedb.session.flush()  # hvis noget ikke virker får vi fejl her!

    # Generer dokumentation til fanebladet "Sagsgang"
    sagsgangslinje = {
        "Dato": sagsevent_punktinfo.registreringfra,
        "Hvem": sagsbehandler,
        "Hændelse": "punktinfoindsættelse",
        "Tekst": sagsevent_punktinfo.sagseventinfos[0].beskrivelse,
        "uuid": sagsevent_punktinfo.id,
    }
    sagsgang = sagsgang.append(sagsgangslinje, ignore_index=True)

    # Opdater regneark
    for k in punkter.keys():
        nyetablerede.at[k, "uuid"] = punkter[k].id
        nyetablerede.at[k, "Landsnummer"] = landsnumre[k].tekst

    # Drop numerisk index
    nyetablerede = nyetablerede.reset_index(drop=True)

    # Forbered  resultater til resultatregneark
    resultater = {"Sagsgang": sagsgang, "Nyetablerede punkter": nyetablerede}

    spørgsmål = click.style("Du indsætter nu ", fg="white", bg="red")
    spørgsmål += click.style(f"{len(punkter)} punkter ",
                             fg="white",
                             bg="red",
                             bold=True)
    spørgsmål += click.style(f"i ", fg="white", bg="red")
    spørgsmål += click.style(f"{fire.cli.firedb.db}",
                             fg="white",
                             bg="red",
                             bold=True)
    spørgsmål += click.style("-databasen - er du sikker?",
                             fg="white",
                             bg="red")
    if bekræft(spørgsmål):
        # Indsæt rækker i database og skriv resultater til regneark
        fire.cli.firedb.session.commit()
        if skriv_ark(projektnavn, resultater):
            fire.cli.print(
                f"Punkter oprettet. Resultater skrevet til '{projektnavn}.xlsx'"
            )
    else:
        fire.cli.firedb.session.rollback()
Beispiel #26
0
def ilæg_revision(
    projektnavn: str,
    sagsbehandler: str,
    **kwargs,
) -> None:
    """Læg reviderede punktdata i databasen"""
    sag = find_sag(projektnavn)
    sagsgang = find_sagsgang(projektnavn)

    fire.cli.print(f"Sags/projekt-navn: {projektnavn}  ({sag.id})")
    fire.cli.print(f"Sagsbehandler:     {sagsbehandler}")
    fire.cli.print("")

    revision = find_faneblad(f"{projektnavn}-revision", "Revision",
                             ARKDEF_REVISION)

    # Tildel navne til endnu ikke oprettede punkter
    oprettelse = revision.query("Attribut == 'OPRET'")
    for i, _ in oprettelse.iterrows():
        revision.loc[i, "Punkt"] = f"NYTPUNKT{i}"

    # Udfyld udeladte identer
    punkter = list(revision["Punkt"])
    udfyldningsværdi = ""
    for i in range(len(punkter)):
        if punkter[i].strip() != "":
            udfyldningsværdi = punkter[i].strip()
            continue
        punkter[i] = udfyldningsværdi
    revision["Punkt"] = punkter

    # Find alle punkter, der skal nyoprettes
    nye_punkter = []
    oprettelse = revision.query("Attribut == 'OPRET'")
    for row in oprettelse.to_dict("records"):
        if row["id"] == -1:
            continue
        punkt = opret_punkt(row["Ny værdi"])
        fire.cli.print(f"Opretter nyt punkt {punkt.ident}: {row['Ny værdi']}")
        nye_punkter.append(punkt)

        # indsæt nyt punkt ID i Punkt kolonnen, for at kunne trække
        # dem ud med hent_punkt() senere
        erstat = lambda x: punkt.id if x == row["Punkt"] else x
        revision["Punkt"] = revision.Punkt.apply(erstat)

    revision = revision.query("Attribut != 'OPRET'")

    # Find alle lokationskoordinater, der skal korrigeres
    nye_lokationer = []
    lokation = revision.query("Attribut == 'LOKATION'")
    lokation = lokation.query("`Ny værdi` != ''")
    for row in lokation.to_dict("records"):
        punkt = fire.cli.firedb.hent_punkt(row["Punkt"])
        # gem her inden ny geometri tilknyttes punktet
        (λ1, φ1) = punkt.geometri.koordinater

        go = læs_lokation(row["Ny værdi"])
        go.punkt = punkt
        nye_lokationer.append(go)
        (λ2, φ2) = go.koordinater

        g = Geod(ellps="GRS80")
        _, _, dist = g.inv(λ1, φ1, λ2, φ2)
        if dist >= 25:
            fire.cli.print(
                f"    ADVARSEL: Ny lokationskoordinat afviger {dist:.0f} m fra den gamle",
                fg="yellow",
                bold=True,
            )

    if len(nye_punkter) > 0 or len(nye_lokationer) > 0:
        sagsevent = Sagsevent(
            id=uuid(),
            sagsid=sag.id,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Oprettelse af nye punkter")
            ],
            eventtype=EventType.PUNKT_OPRETTET,
            punkter=nye_punkter,
            geometriobjekter=nye_lokationer,
        )
        fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)
        sagsgang = opdater_sagsgang(sagsgang, sagsevent, sagsbehandler)
        flush()

    revision = revision.query("Attribut != 'LOKATION'")

    # Find alle koordinater, der skal oprettes

    # Først skal vi bruge alle gyldige koordinatsystemnavne
    srider = fire.cli.firedb.hent_srider()
    sridnavne = [srid.name.upper() for srid in srider]

    # Så itererer vi over hele rammen og ignorerer ikke-koordinaterne
    nye_koordinater = []
    opdaterede_punkter = []
    for r in revision.to_dict("records"):
        sridnavn = r["Attribut"].upper()
        if sridnavn not in sridnavne:
            continue
        try:
            koord = [float(k.replace(",", ".")) for k in r["Ny værdi"].split()]
        except ValueError as ex:
            fire.cli.print(
                f"Ukorrekt koordinatformat:\n{'    '.join(r['Ny værdi'])}\n{ex}"
            )
            fire.cli.print(
                "Skal være på formen: 'x y z t sx sy sz', hvor ubrugte værdier sættes til 'nan'"
            )
            sys.exit(1)

        # Oversæt NaN til None
        koord = [None if isnan(k) else k for k in koord]

        # Tæt-på-kopi af kode fra "niv/ilæg_nye_koter.py". Her bør mediteres og overvejes
        # hvordan denne opgave kan parametriseres på en rimeligt generel måde, så den kan
        # udstilles i et "højniveau-API"
        srid = fire.cli.firedb.hent_srid(sridnavn)

        punkt = fire.cli.firedb.hent_punkt(r["Punkt"])
        opdaterede_punkter.append(r["Punkt"])

        # Det er ikke helt så nemt som i C at oversætte decimal-år til datetime
        år = trunc(koord[3])
        rest = koord[3] - år
        startdato = datetime(år, 1, 1)
        årlængde = datetime(år + 1, 1, 1) - startdato
        tid = startdato + rest * årlængde

        koordinat = Koordinat(
            srid=srid,
            punkt=punkt,
            x=koord[0],
            y=koord[1],
            z=koord[2],
            t=tid,
            sx=koord[4],
            sy=koord[5],
            sz=koord[6],
        )
        nye_koordinater.append(koordinat)

        # I Grønland er vi nødt til at duplikere geografiske koordinater til UTM24,
        # da Oracles indbyggede UTM-rutine er for ringe til at vi kan generere
        # udstillingskoordinater on-the-fly.
        if sridnavn in ("EPSG:4909", "EPSG:4747"):
            srid_utm24 = fire.cli.firedb.hent_srid("EPSG:3184")
            utm24 = Proj("proj=utm zone=24 ellps=GRS80", preserve_units=False)
            x, y = utm24(koord[0], koord[1])
            koordinat = Koordinat(
                srid=srid_utm24,
                punkt=punkt,
                x=x,
                y=y,
                z=None,
                t=tid,
                sx=koord[4],
                sy=koord[5],
                sz=None,
            )
            nye_koordinater.append(koordinat)

    n = len(opdaterede_punkter)
    if n > 0:
        punktnavne = sorted(list(set(opdaterede_punkter)))
        if len(punktnavne) > 10:
            punktnavne[9] = "..."
            punktnavne[10] = punktnavne[-1]
            punktnavne = punktnavne[0:10]
        koordinatoprettelsestekst = (
            f"Opdatering af {n} koordinater til {', '.join(punktnavne)}")

        sagsevent = Sagsevent(
            id=uuid(),
            sagsid=sag.id,
            sagseventinfos=[
                SagseventInfo(beskrivelse=koordinatoprettelsestekst)
            ],
            eventtype=EventType.KOORDINAT_BEREGNET,
            koordinater=nye_koordinater,
        )
        fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)
        sagsgang = opdater_sagsgang(sagsgang, sagsevent, sagsbehandler)
        flush()

    # Så tager vi fat på punktinformationerne
    til_opret = []
    til_ret = []
    til_sluk = []
    punkter_med_oprettelse = set()
    punkter_med_rettelse = set()
    punkter_med_slukning = set()

    # Først, tilknyt regionspunktinfo til nyoprettede punkter
    for p in nye_punkter:
        til_opret.append(opret_region_punktinfo(p))

    # Find identer for alle punkter, der indgår i revisionen
    identer = tuple(sorted(set(revision["Punkt"]) - set(["nan", ""])))
    fire.cli.print("")
    fire.cli.print(f"Behandler {len(identer)} punkter")

    # Så itererer vi over alle punkter
    for ident in identer:
        fire.cli.print(ident, fg="yellow", bold=True)

        # Hent punkt og alle relevante punktinformationer i databasen.
        # Her er det lidt sværere end for koordinaternes vedkommende:
        # Ved opdatering af eksisterende punkter vil vi gerne checke
        # infonøglerne, så vi er nødt til at hente det faktiske punkt,
        # med tilørende infonøgler, fra databasen
        try:
            punkt = fire.cli.firedb.hent_punkt(ident)
            infonøgler = {
                info.objektid: i
                for i, info in enumerate(punkt.punktinformationer)
            }
        except NoResultFound as ex:
            fire.cli.print(
                f"FEJL: Kan ikke finde punkt {ident}!",
                fg="yellow",
                bg="red",
                bold=True,
            )
            fire.cli.print(f"Mulig årsag: {ex}")
            sys.exit(1)

        # Hent alle revisionselementer for punktet fra revisionsarket
        rev = revision.query(f"Punkt == '{ident}'")

        for r in rev.to_dict("records"):
            if r["Attribut"] in sridnavne:
                continue
            if r["id"] == 999999:
                continue
            if r["id"] == -1:
                continue
            pitnavn = r["Attribut"]
            if pitnavn == "":
                continue

            if r["Sluk"] and r["Ny værdi"]:
                fire.cli.print(
                    f"    * FEJL: 'Sluk' og 'Ny værdi' begge udfyldt: {r['Ny værdi']}",
                    fg="red",
                    bold=False,
                )
                continue

            if r["Tekstværdi"] != "" and r["Tekstværdi"] == r["Ny værdi"]:
                fire.cli.print(
                    f"    ADVARSEL: Tekst i 'Ny værdi' identisk med udgangspunkt for {pitnavn}.",
                    fg="yellow",
                    bold=True,
                )
                continue

            if pitnavn is None:
                fire.cli.print(
                    "    * Ignorerer uanført punktinformationstype",
                    fg="red",
                    bold=False,
                )
                continue

            pit = fire.cli.firedb.hent_punktinformationtype(pitnavn)
            if pit is None:
                fire.cli.print(
                    f"    * Ignorerer ukendt punktinformationstype '{pitnavn}'",
                    fg="red",
                    bold=True,
                )
                continue

            # Nyt punktinfo-element?
            if pd.isna(r["id"]):
                # ATTR:muligt_datumstabil+slukket == ikke eksisterende i DB
                # Indsat af fire niv udtræk-revision
                if pitnavn == "ATTR:muligt_datumstabil" and r["Sluk"]:
                    continue

                fire.cli.print(
                    f"    Opretter nyt punktinfo-element: {pitnavn}")
                if pit.anvendelse == PunktInformationTypeAnvendelse.FLAG:
                    if r["Ny værdi"]:
                        fire.cli.print(
                            f"    BEMÆRK: {pitnavn} er et flag. Ny værdi '{r['Ny værdi']}' ignoreres",
                            fg="yellow",
                            bold=True,
                        )
                    pi = PunktInformation(infotype=pit, punkt=punkt)
                elif pit.anvendelse == PunktInformationTypeAnvendelse.TEKST:
                    # Ingen definitiv test her: Tom tekst kan være gyldig.
                    # Men vi sørger for at den ikke er None
                    tekst = r["Ny værdi"]
                    if tekst is None or tekst == "":
                        fire.cli.print(
                            f"    ADVARSEL: Tom tekst anført for {pitnavn}.",
                            fg="yellow",
                            bold=True,
                        )
                        tekst = ""
                    pi = PunktInformation(infotype=pit,
                                          punkt=punkt,
                                          tekst=tekst)
                else:
                    try:
                        # Både punktum og komma er accepterede decimalseparatorer
                        tal = float(r["Ny værdi"].replace(",", "."))
                    except ValueError as ex:
                        fire.cli.print(
                            f"    FEJL: {pitnavn} forventer numerisk værdi [{ex}].",
                            fg="yellow",
                            bold=True,
                        )
                        tal = 0
                    pi = PunktInformation(infotype=pit, punkt=punkt, tal=tal)

                til_opret.append(pi)
                punkter_med_oprettelse.add(ident)
                continue

            # Ingen ændringer? - så afslutter vi og går til næste element.
            if r["Sluk"] == r["Ny værdi"] == "":
                continue

            # Herfra håndterer vi kun punktinformationer med indførte ændringer

            # Nu kan vi bruge objektid som heltal (ovenfor havde vi brug for NaN-egenskaben)
            oid = int(r["id"])
            if r["Sluk"] == "x":
                try:
                    pi = punkt.punktinformationer[infonøgler[oid]]
                except KeyError:
                    fire.cli.print(
                        f"    * Ukendt id - ignorerer element '{oid}'",
                        fg="red",
                        bold=True,
                    )
                    continue
                fire.cli.print(f"    Slukker: {pitnavn}")
                # pi._registreringtil = func.current_timestamp()
                til_sluk.append(pi)
                punkter_med_slukning.add(punkt.ident)
                continue

            fire.cli.print(f"    Retter punktinfo-element: {pitnavn}")
            if pit.anvendelse == PunktInformationTypeAnvendelse.FLAG:
                pi = PunktInformation(infotype=pit, punkt=punkt)
            elif pit.anvendelse == PunktInformationTypeAnvendelse.TEKST:
                # Fjern overflødigt whitespace og duplerede punktummer
                tekst = r["Ny værdi"]
                tekst = re.sub(r"[ \t]+", " ", tekst.strip())
                tekst = re.sub(r"[.]+", ".", tekst)
                pi = PunktInformation(infotype=pit, punkt=punkt, tekst=tekst)
            else:
                try:
                    tal = float(r["Ny værdi"])
                except ValueError as ex:
                    fire.cli.print(
                        f"    FEJL: {pitnavn} forventer numerisk værdi [{ex}].",
                        fg="yellow",
                        bold=True,
                    )
                    tal = 0
                pi = PunktInformation(infotype=pit, punkt=punkt, tal=tal)
            til_ret.append(pi)
            punkter_med_rettelse.add(punkt.ident)
            continue

    fikspunktstyper = [FikspunktsType.GI for _ in nye_punkter]
    landsnumre = fire.cli.firedb.tilknyt_landsnumre(nye_punkter,
                                                    fikspunktstyper)
    til_opret.extend(landsnumre)
    for p in nye_punkter:
        punkter_med_oprettelse.add(p.ident)

    if len(til_opret) > 0 or len(til_ret) > 0:
        sagsevent = Sagsevent(
            id=uuid(),
            sagsid=sag.id,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Opdatering af punktinformationer")
            ],
            eventtype=EventType.PUNKTINFO_TILFOEJET,
            punktinformationer=[*til_opret, *til_ret],
        )

        fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)
        sagsgang = opdater_sagsgang(sagsgang, sagsevent, sagsbehandler)
        flush()

    if len(til_sluk) > 0:
        sagsevent = Sagsevent(
            id=uuid(),
            sagsid=sag.id,
            sagseventinfos=[
                SagseventInfo(beskrivelse="Lukning af punktinformationer")
            ],
            eventtype=EventType.PUNKTINFO_FJERNET,
            punktinformationer_slettede=til_sluk,
        )

        fire.cli.firedb.indset_sagsevent(sagsevent, commit=False)
        sagsgang = opdater_sagsgang(sagsgang, sagsevent, sagsbehandler)
        flush()

    opret_tekst = f"- oprette {len(til_opret)} attributter fordelt på {len(punkter_med_oprettelse)} punkter"
    sluk_tekst = f"- slukke for {len(til_sluk)} attributter fordelt på {len(punkter_med_slukning)} punkter"
    ret_tekst = f"- rette {len(til_ret)} attributter fordelt på {len(punkter_med_rettelse)} punkter"
    lok_tekst = f"- rette {len(nye_lokationer)} lokationskoordinater"

    fire.cli.print("")
    fire.cli.print("-" * 50)
    fire.cli.print("Punkter færdigbehandlet, klar til at")
    fire.cli.print(opret_tekst)
    fire.cli.print(sluk_tekst)
    fire.cli.print(ret_tekst)
    fire.cli.print(lok_tekst)

    spørgsmål = click.style(
        f"Er du sikker på du vil indsætte ovenstående i {fire.cli.firedb.db}-databasen",
        fg="white",
        bg="red",
    )
    if bekræft(spørgsmål):
        fire.cli.firedb.session.commit()
        skriv_ark(projektnavn, {"Sagsgang": sagsgang})
    else:
        fire.cli.firedb.session.rollback()
Beispiel #27
0
sagsbeskrivelse = "Luk alle punkter fra REFGEO hvor MV_STATUS=-1"
sagsinfo = Sagsinfo(aktiv="true",
                    behandler="Kristian Evers",
                    beskrivelse=sagsbeskrivelse)
sagid = "af190b61-190b-413f-ba4d-432ecaca18d2"

try:
    sag = firedb.hent_sag(sagid)
except NoResultFound:
    sag = Sag(id=sagid, sagsinfos=[sagsinfo])
    firedb.indset_sag(sag)

sagsevent = Sagsevent(
    sag=sag,
    sagseventinfos=[
        SagseventInfo(beskrivelse="Lukning af punkter med REFGEO MV_STATUS=-1")
    ],
    id=uuid(),
    eventtype=EventType.PUNKT_NEDLAGT,
)

# Udtræk punkter
statement = text("""
SELECT p.id FROM hvd_ref@refgeo hr
JOIN conv_punkt cp ON hr.refnr=cp.refnr
JOIN punkt p ON cp.id=p.id
WHERE hr.mv_status=-1
""")

refnumre = firedb.session.execute(statement)
punktider = [refnr[0] for refnr in refnumre]