/* === 920909 ============================================================ */ /* STATENS KARTVERK - FYSAK-PC */ /* Fil: fylb.c */ /* Ansvarlig: Andreas Røstad */ /* Innhold: Bufferhandteringsrutiner for fysak-pc */ /* ======================================================================= */ #include "stdafx.h" #include #include #include #include #include #include /* Globale strukturer */ extern LC_SYSTEMADM Sys; extern volatile short fyba_initiert; /* Bryter for å vise at LC_Init er utført */ /* Funksjonsdefinisjoner for interne funksjoner */ static void LB_WriteBlank(FILE *fil,short sTegnsett,UT_INT64 ltilpos); static char *LB_GetParameter(LB_LESEBUFFER *plb); static short LB_TestFyll(const char *pszTx); static void LB_WriteRb(void); static short LB_FlyttGrTilSlutt(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste); static short LB_RensOmkrets(LC_POL_OMKR * pPO,long lAktSnr,long lFraSnr); static void LR_TestEndreBuepTilKurve(double dDeltaFi); /* AR-911011 CH LC_GetGrFi Hent gruppe-filnr CD ============================================================================= CD Formål: CD Henter peker til FilAdm for aktuell gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_FILADM * *ppFil u Peker til FilAdm-peker CD short status r UT_TRUE = OK, UT_FALSE = Ingen aktuell gruppe CD CD Bruk: CD status = LC_GetGrFi(&pFil); ============================================================================= */ SK_EntPnt_FYBA short LC_GetGrFi(LC_FILADM **ppFil) { /* Er det noen aktuell gruppe? */ if (Sys.GrId.lNr != INGEN_GRUPPE) { *ppFil = Sys.GrId.pFil; return UT_TRUE; } /* Ingen aktuell gruppe */ return UT_FALSE; } /* AR-911008 CH LC_InitNextFil Initier finn neste fil CD ========================================================================== CD Formål: CD Initierer pFil for bruk i finn neste fil. CD CD Parametre: CD Type Navn I/U Forklaring CD ------------------------------------------------------------------------ CD LC_FILADM **ppFil u Peker til FilAdm-peker CD CD Bruk: CD LC_InitNextFil(&pFil) ========================================================================== */ SK_EntPnt_FYBA void LC_InitNextFil(LC_FILADM **ppFil) { *ppFil = (LC_FILADM *)-1L; } /* AR-911008 CH LC_NextFil Finn neste fil CD ========================================================================== CD Formål: CD Finn neste fil i aktuell base. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM **ppFil iu Peker til FilAdm-peker CD unsigned short usLag i Velg hvilke "lag" det skal søkes i. CD LC_FRAMGR, LC_BAKGR og /eller LC_SEKV CD (Bruk "|" for å kombinere.) CD short sStatus r Status UT_TRUE=OK, UT_FALSE=ingen flere funnet CD CD Bruk: CD LC_FILADM *pFil; CD Denne løkka går gjennom alle framgrunns-filene i basen CD LC_InitNextFil(&pFil) CD while (LC_NextFil(&pFil,LC_FRAMGR)) { CD pszFilNavn = LC_GetFiNa(pFil); CD . CD Behandle filnavnet CD . CD } ========================================================================== */ SK_EntPnt_FYBA short LC_NextFil(LC_FILADM **ppFil,unsigned short usLag) { LC_FILADM *pF; /* Første gang */ if (*ppFil == (void *)-1L) { pF = Sys.pAktBase->pForsteFil; } else { /* LO_TestFilpeker(*ppFil,"LC_NextFil"); */ LO_TestFilpeker(*ppFil,"NextFil"); pF = (*ppFil)->pNesteFil; } /* Er det flere filer i basen? */ while (pF != NULL) { /* Er filen i rett lag? */ if (pF->usLag & usLag) { *ppFil = pF; return UT_TRUE; /* Ikke rett lag, fortsett til neste fil */ } else { pF = pF->pNesteFil; } } return UT_FALSE; } /* AR-911001 CH LC_InitNextBgr Initier finn neste gruppe CD ========================================================================== CD Formål: CD Initierer Bgr for bruk i finn neste gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ------------------------------------------------------------------------ CD LC_BGR * pBgr iu Peker til gruppestruktur CD CD Bruk: CD LC_InitNextBgr(&Bgr) ========================================================================== */ SK_EntPnt_FYBA void LC_InitNextBgr(LC_BGR * pBgr) { pBgr->pFil = Sys.pAktBase->pForsteFil; pBgr->lNr = -1L; } /* AR-911003 CH LC_NextBgr Finn neste gruppe CD ========================================================================== CD Formål: CD Finn neste gruppe i aktuell base. CD Sekvensielle filer blir ikke håndtert. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_BGR * pBgr iu Peker til gruppestruktur der gruppenummer lagres CD unsigned short usLag i Velg hvilke "lag" det skal søkes i. CD LC_FRAMGR og /eller LC_BAKGR CD (Bruk "|" for å kombinere.) CD short sStatus r Status UT_TRUE=OK, UT_FALSE=ingen flere grupper CD CD Bruk: CD LC_BGR Bgr; CD Denne løkka går gjennom alle framgrunns-gruppene i basen CD LC_InitNextBgr(&Bgr); CD while (LC_NextBgr(&Bgr,LC_FRAMGR)) { CD gnavn = LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); CD . CD Behandle gruppen CD . CD } ========================================================================== */ SK_EntPnt_FYBA short LC_NextBgr(LC_BGR * pBgr,unsigned short usLag) { LC_GRTAB_LINJE * grtp; /* Er det noen fil i basen? */ while (pBgr->pFil != NULL) { LO_TestFilpeker(pBgr->pFil,"NextBgr"); /* Er filen i rett lag? */ if (pBgr->pFil->usLag & usLag) { /* Flere grupper i aktuell fil? */ while (pBgr->lNr < pBgr->pFil->lAntGr -1) { pBgr->lNr++; /* * Sjekk gruppetabellen om gruppen er sletta * * (Permanent sletta, eller vanlig NGIS-modus, og * "NGIS-gruppe" merka som sletta.) */ grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr); if (! (grtp->ngi == 0 || (Sys.sNGISmodus == NGIS_NORMAL && grtp->info & GI_NGIS && grtp->info & GI_SLETTA))) { return UT_TRUE; } } } /* Neste fil i basen */ pBgr->pFil = pBgr->pFil->pNesteFil; pBgr->lNr = -1L; } return UT_FALSE; } /* AR-911003 CH LC_InqAntFiler Finn antall filer i basen CD ========================================================================== CD Formål: CD Finn antall filer i aktuell base. CD CD Parametre: CD Type Navn I/U Forklaring CD ------------------------------------------------------------------- CD unsigned short usLag i Velg hvilke "lag" det skal søkes i. CD LC_FRAMGR og /eller LC_BAKGR CD (Bruk "|" for å kombinere.) CD short sAntall r Antall filer i aktuell base. CD CD Bruk: CD Finner antall framgrunnsfiler i basen CD sAntall = LC_InqAntFiler(LC_FRAMGR); ========================================================================== */ SK_EntPnt_FYBA short LC_InqAntFiler(unsigned short usLag) { short sAntall = 0; if (fyba_initiert == 1) { if (Sys.pAktBase != NULL) { if (usLag & LC_FRAMGR) sAntall += Sys.pAktBase->sAntFramgrFil; if (usLag & LC_BAKGR) sAntall += Sys.pAktBase->sAntBakgrFil; } } return sAntall; } /* AR-911001 CH LC_GetGrNr Hent gruppe-nummer CD ========================================================================== CD Formål: CD Henter gruppenummer for aktuell gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_BGR * pBgr iu Peker til gruppestruktur der gruppenummer lagres CD short status r Status UT_TRUE=OK, UT_FALSE=ingen aktuell gruppe CD CD Bruk: CD status = LC_GetGrNr(&Bgr) ========================================================================== */ SK_EntPnt_FYBA short LC_GetGrNr(LC_BGR * pBgr) { pBgr->pFil = Sys.GrId.pFil; pBgr->lNr = Sys.GrId.lNr; /* Er det noen aktuell gruppe? */ if (Sys.GrId.lNr != INGEN_GRUPPE) return UT_TRUE; /* Ingen aktuell gruppe */ return UT_FALSE; } /* AR-911001 CH LC_GetGrPara Hent gruppe-parametre CD ========================================================================== CD Formål: CD Henter diverse opplysninger om aktuell gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD------------------------------------------------------------------------- CD short *ngi u Antall linjer GINFO CD long *nko u Antall koordinater CD short *info u Diverse informasjon. En sum av følgende: CD GI_PINFO = gruppen har PINFO CD GI_NAH = gruppen har høyde informasjon (..NØH) CD GI_NAD = gruppen har dybde informasjon (..NØD) CD GI_KP = gruppen har knutepunkt (...KP n) CD GI_REF = gruppen har referanser (.. :n) CD GI_OY_REF= gruppen har referanser med øy CD GI_NGIS = gruppen er tatt ut fra NGIS for oppdat. CD GI_SLETTA = gruppen er sletta (merka som sletta) CD GI_READ_ONLY = gruppen kan ikke endres. CD CD short gnavn r Gruppenavn. (Se under $LENKE) CD CD Bruk: CD gnavn = LC_GetGrPara(&ngi,&nko,&info); ========================================================================== */ SK_EntPnt_FYBA short LC_GetGrPara(short *ngi,long *nko,unsigned short *info) { /* Feil ==> Ingen aktuell gruppe */ if (Sys.GrId.lNr == INGEN_GRUPPE) { *ngi = 0; *nko = 0; return INGEN_GRUPPE; /* Lovlig gruppe */ } else { *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; return Sys.pGrInfo->gnavn; } } /* AR-900107 CH LC_GetGrParaBgr Hent gruppe-parametre for gruppe CD ============================================================================= CD Formål: CD Henter diverse opplysninger om gitt gruppenummer. CD CD Parametre: CD Type Navn I/U Forklaring CD------------------------------------------------------------------------------ CD LC_BGR * pBgr i Gruppenummer det ønskes opplysninger om. CD short *ngi u Antall linjer GINFO (0=sletta eller ulovlig nummer) CD long *nko u Antall koordinater CD unsigned short *info u Diverse informasjon. En sum av følgende: CD GI_PINFO = gruppen har PINFO CD GI_NAH = gruppen har høyde informasjon (..NØH) CD GI_NAD = gruppen har døbde informasjon (..NØD) CD GI_KP = gruppen har knutepunkt (...KP n) CD GI_REF = gruppen har referanser (.. :n) CD GI_OY_REF= gruppen har referanser med øy CD GI_NGIS = gruppen er tatt ut fra NGIS for oppdat. CD GI_SLETTA = gruppen er sletta (merka som sletta) CD GI_READ_ONLY = gruppen kan ikke endres. CD short gnavn r Gruppenavn. (Se under $LENKE) CD CD Bruk: CD gnavn = LC_GetGrParaBgr(pBgr,&ngi,&nko,&info,&snr); ============================================================================= */ SK_EntPnt_FYBA short LC_GetGrParaBgr(LC_BGR * pBgr,short *ngi,long *nko,unsigned short *info) { LC_GRTAB_LINJE * grtp; /* Aktuell gruppe */ if (pBgr->pFil == Sys.GrId.pFil && pBgr->lNr == Sys.GrId.lNr) { *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; return Sys.pGrInfo->gnavn; /* ==> retur */ } /* Hent fra gruppetabellen */ LO_TestFilpeker(pBgr->pFil,"GetGrParaBgr"); grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr); /* Sjekk om NGIS-gruppe og merka som sletta */ if (Sys.sNGISmodus == NGIS_NORMAL && /* Vanlig modus, og */ grtp->info & GI_NGIS && /* oppdater NGIS, og */ grtp->info & GI_SLETTA) { /* merka som sletta */ *ngi = 0; *nko = 0; } else { *ngi = grtp->ngi; *nko = grtp->nko; } *info = grtp->info; return grtp->gnavn; /* ==> retur */ } /* AR-900107 CH LC_GetObjtypeBgr Hent objekttype CD ============================================================================= CD Formål: CD Henter objekttype for gitt gruppenummer. CD CD Parametre: CD Type Navn I/U Forklaring CD------------------------------------------------------------------------------ CD LC_BGR *pBgr i Gruppenummer det ønskes opplysninger om. CD char *pszObjtype r OBJTYPE CD NULL hvis gruppen ikke finnes CD CD Bruk: CD pszObjtype = LC_GetObjtypeBgr(pBgr); ============================================================================= */ SK_EntPnt_FYBA const char *LC_GetObjtypeBgr(LC_BGR * pBgr) { LC_GRTAB_LINJE * grtp; /* Aktuell gruppe */ if (pBgr->pFil == Sys.GrId.pFil && pBgr->lNr == Sys.GrId.lNr) { return Sys.pGrInfo->szObjtype; /* ==> retur */ } /* Hent fra gruppetabellen */ LO_TestFilpeker(pBgr->pFil,"GetObjtypeBgr"); grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr); /* Sjekk om NGIS-gruppe og merka som sletta */ if (Sys.sNGISmodus == NGIS_NORMAL && /* Vanlig modus, og */ grtp->info & GI_NGIS && /* oppdater NGIS, og */ grtp->info & GI_SLETTA) /* merka som sletta */ { return ""; /* ==> retur */ } return grtp->szObjtype; /* ==> retur */ } /* AR-911001 CH LC_RsGr Les gruppe sekvensielt CD ========================================================================== CD Formål: CD Leser en datagruppe fra ekstern SOSI-fil inn i aktuell gruppe i ringbuffer. CD Rutinen tilsvarer put fra brukerprogram inn i ringbufferet, men rutinen CD tildeler selv nødvendig plass.. CD Gruppen beholder serienummer tildelt i LC_NyGr. CD Brukerindeks og geografisk-indeks blir ikke oppdatert. CD (Dette skjer først når gruppen skrives til basen.) CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD short *rstat iu Lesestatus CD Inn: 1=Les fra starten, 0=Les neste CD Ut: 0=OK, -1=slutten av filen er nådd CD LC_FILADM *pFil i Peker til FilAdm CD short *ngi u Antall linjer GINFO CD long *nko u Antall koordinater CD unsigned short *info u Diverse informasjon. En "sum" av følgende: CD GI_PINFO = gruppen har PINFO CD GI_NAH = gruppen har høyde informasjon (..NØH) CD GI_NAD = gruppen har dybde informasjon (..NØD) CD GI_KP = gruppen har knutepunkt (...KP n) CD GI_REF = gruppen har referanser (.. eller ..REF) CD GI_OY_REF = gruppen har referanser med øy CD GI_NGIS = gruppen er tatt ut fra NGIS for oppdat. CD GI_SLETTA = gruppen er sletta (merka som sletta) CD GI_READ_ONLY = gruppen kan ikke endres. CD long gml_snr u Serienummer gruppen hadde på ekstern fil CD short gnavn r Gruppenavn. (Se under $LENKE) CD CD Bruk: CD gnavn = LC_RsGr(&rstat,pFil,&ngi,&nko,&info,&gml_snr); CD if (info & GI_PINFO) (gruppen har PINFO) CD ; CD if (info & GI_KP) (gruppen har KP) CD ; ========================================================================== */ SK_EntPnt_FYBA short LC_RsGr(short *rstat,LC_FILADM *pFil,short *ngi,long *nko, unsigned short *info,long *gml_snr) { short siste; long snr; UT_INT64 slutt; /* LO_TestFilpeker(pFil,"LC_RsGr"); */ LO_TestFilpeker(pFil,"RsGr"); if (Sys.GrId.lNr == INGEN_GRUPPE) { /* Feil ==> Ingen aktuell gruppe */ LC_Error(31,"(LC_RsGr)",""); /* Feil ==> Ulovlig ekstern fil */ } else if (pFil->usLag != LC_SEKV) { LC_Error(32,"(LC_RsGr)",""); *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } else { /* Lovlig gruppe */ Sys.sPibufStatus = LC_PIBUF_TOM; Sys.sGrEndra = END_KOPI; if (*rstat == 1) { pFil->n64AktPos = 0L; /* Sett ny startposisjon */ } /* Husk snr */ snr = LC_GetSn(); /* Les fra ekstern fil */ siste = LB_RGru(pFil,pFil->n64AktPos,&slutt); /* Snr fra ekstern fil */ *gml_snr = LC_GetSn(); /* Legg tilbake SNR */ LC_PutSn(snr); if (siste) { *rstat = -1; } else { *rstat = 0; pFil->n64AktPos = slutt; *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } } return Sys.pGrInfo->gnavn; } /* AR-911001 CH LC_RsHode Les filhode sekvensiellt CD ========================================================================== CD Formål: CD Leser et filhode fra ekstern SOSI-fil inn i aktuell gruppe i ringbuffer. CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret, men rutinen CD tildeler selv nødvendig plass i RB. CD Denne rutinen er stort sett lik LC_RsGr, men LC_RsHode forandrer CD ikke aktuell filposisjon på den sekvensielle filen. CD Gruppen beholder serienummer hodet hadde på SOSI-filen. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD short *ngi u Antall linjer GINFO CD long *nko u Antall koordinater CD unsigned short *info u Diverse informasjon. En "sum" av følgende: CD GI_PINFO = gruppen har PINFO CD GI_NAH = gruppen har høyde informasjon (..NØH) CD GI_NAD = gruppen har dybde informasjon (..NØD) CD GI_KP = gruppen har knutepunkt (...KP n) CD GI_REF = gruppen har referanser (.. :n) CD GI_OY_REF= gruppen har referanser med øy CD short gnavn r Gruppenavn. (Se under $LENKE) CD CD Bruk: CD gnavn = LC_RsHode(pFil,&ngi,&nko,&info); ============================================================================= */ short LC_RsHode(LC_FILADM *pFil,short *ngi,long *nko,unsigned short *info) { UT_INT64 slutt; /* LO_TestFilpeker(pFil,"LC_RsHode"); */ LO_TestFilpeker(pFil,"RsHode"); if (Sys.GrId.lNr == INGEN_GRUPPE){ /* Feil ==> Ingen aktuell gruppe */ LC_Error(31,"(LC_RsHode)",""); /* Feil ==> Ulovlig ekstern fil */ } else if (pFil->usLag != LC_SEKV) { LC_Error(32,"(LC_RsHode)",""); *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } else { /* Lovlig gruppe */ /* Les fra ekstern fil */ LB_RGru(pFil,0,&slutt); *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; Sys.sGrEndra = END_KOPI; } return Sys.pGrInfo->gnavn; } /* AR-930610 CH LC_WsGr Skriv gruppe sekvensiellt CD ============================================================================= CD Formål: CD Skriver aktuell gruppe til ekstern, sekvensiell SOSI-fil. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD CD Bruk: CD LC_WsGr(pFil); ============================================================================= */ SK_EntPnt_FYBA void LC_WsGr(LC_FILADM *pFil) { UT_INT64 neste = LLONG_MAX; LO_TestFilpeker(pFil,"WsGr"); if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */ /* Feil ==> Ulovlig ekstern fil */ if (pFil->usLag != LC_SEKV) { LC_Error(33,"(LC_WsGr)",""); /* Feil ==> Ikke skriveaksess */ //} else if (pFil->sAccess != UT_UPDATE || pFil->lNgisLag == LC_NGIS_LES) { } else if (pFil->sAccess != UT_UPDATE || strcmp(pFil->szNgisLag,"0") == 0 ) { LC_Error(34,"(LC_WsGr)",""); /* OK ==> Skriv */ } else { /* Sjekk at SOSI-filen har hode */ if ((pFil->TransMaske & LC_TR_ENHET) == 0 && Sys.pGrInfo->gnavn != L_HODE) { LC_Error(141,"(LC_WsGr)",pFil->pszNavn); } if (Sys.pGrInfo->gnavn == L_HODE) { /* Oppdater filtabellen */ LO_BeFt(pFil); } LB_WGru(SKRIV_SISTE,1,Sys.pGrInfo->nko,pFil,pFil->n64AktPos,&neste); pFil->n64AktPos = neste; } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_WsGr)",""); } } /* AR-930610 CH LC_WsGrPart Skriv del av gruppe sekvensiellt CD ========================================================================== CD Formål: CD Skriver en del av aktuell gruppe til ekstern, sekvensiell SOSI-fil. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD long fra_punkt i Punktnummer for første koordinat som skal skrives. CD (Lovlig: 1 <= fra_punkt <= nko) CD long antall i Antall koordinatlinjer som skal skrives. CD (Lovlig: 0 <= antall <= nko) CD CD Bruk: CD LC_WsGrPart(pFil,fra_punkt,antall); ========================================================================== */ SK_EntPnt_FYBA void LC_WsGrPart(LC_FILADM *pFil,long fra_punkt,long antall) { UT_INT64 neste = LLONG_MAX; LO_TestFilpeker(pFil,"WsGrPart"); if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */ /* Feil ==> Ulovlig ekstern fil */ if (pFil->usLag != LC_SEKV) { LC_Error(33,"(LC_WsGr)",""); /* Feil ==> Ikke skriveaksess */ //} else if (pFil->sAccess != UT_UPDATE || pFil->lNgisLag == LC_NGIS_LES) { } else if (pFil->sAccess != UT_UPDATE || strcmp(pFil->szNgisLag,"0") == 0 ) { LC_Error(34,"(LC_WsGr)",""); /* OK ==> Skriv */ } else{ /* Sjekker at punktnummer er lovlig */ fra_punkt = fymin( fymax(1,fra_punkt), fymax(1,Sys.pGrInfo->nko) ); antall = fymin( fymax(antall,0), (Sys.pGrInfo->nko-fra_punkt+1) ); /* Skriver */ LB_WGru(SKRIV_SISTE,fra_punkt,antall,pFil,pFil->n64AktPos,&neste); pFil->n64AktPos = neste; if (Sys.pGrInfo->gnavn == L_HODE){ /* Oppdater filtabellen */ LO_BeFt(pFil); } } } else{ /* Ingen aktuell gruppe */ LC_Error(49,"(LC_WsGr)",""); } } /* AR:2000-10-17 CH LC_EndreHode Endre hodet på eksisterende SOSI-fil CD ============================================================================= CD Formål: CD Skriver aktuell gruppe til starten av sekvensiell SOSI-fil. CD Det er en forutsetning at aktuell gruppe er et filhode. CD Denne rutinen er stort sett lik LC_WsGr, men LC_EndreHode forandrer ikke CD aktuell filposisjon på den sekvensielle filen. CD OBS! CD Det må være nok ledig plass før neste gruppe for tilbakeskrivingen. CD Det er ikke mulig å forandre koordinatsystem, enhet eller origo på fil CD som inneholder data. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD short oppdatert r Skrivestatus (1=OK, 0=Det er ikke plass CD til å skrive hodet) CD CD Bruk: CD ist = LC_EndreHode(pFil); ============================================================================= */ SK_EntPnt_FYBA short LC_EndreHode(LC_FILADM *pFil) { short tegnsett,siste,oppdatert=0; UT_INT64 neste; char* pszNgisLag; unsigned short Maske = LC_TR_ALLT; LC_TRANSPAR Trans; if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */ /* LO_TestFilpeker(pFil,"LC_EndreHode"); */ LO_TestFilpeker(pFil,"EndreHode"); /* Feil ==> Ulovlig ekstern fil */ if (pFil->usLag != LC_SEKV) { LC_Error(33,"(LC_EndreHode)",""); /* Feil ==> Ikke skriveaksess */ } else if (pFil->sAccess != UT_UPDATE || strcmp(pFil->szNgisLag,"0") == 0 ) { LC_Error(34,"(LC_EndreHode)",""); /* OK */ } else { /* Sjekk at aktuell gruppe er filhode */ if (Sys.pGrInfo->gnavn != L_HODE) { /* Feil ==> Ikke filhode */ LC_Error(98,"(LC_EndreHode)",""); } else { /* OK ==> Skriv */ /* Finn ledig plass for å skrive */ siste = LB_Plass(pFil,0,&neste); /* Sjekk mot ledig plass */ if (LB_WGru(KONTROLLER_PLASS,1,Sys.pGrInfo->nko,pFil,0,&neste)) { /* Det er plass nok */ /* Hent hode-opplysninger det ikke er lov til å endre når det er data i filen */ LC_GetTransEx(&Maske,&Trans); LC_GetTegnsett(&tegnsett); pszNgisLag = LH_GetNgisLag(); /* Skriv hvis siste gruppe, eller transpar, tegnsett og NGIS-lag er uendret */ if (siste || (memcmp(&pFil->TransPar,&Trans,sizeof(LC_TRANSPAR)) == 0 && pFil->sTegnsett == tegnsett)) { if ( strcmp(pFil->szNgisLag,pszNgisLag) == 0) { LO_BeFt(pFil); LB_WGru(SKRIV_VANLIG,1,Sys.pGrInfo->nko,pFil,0,&neste); oppdatert = 1; } else { /* Koord.sys, enhet, origo eller tegnsett er endret */ LC_Error(96,"(LC_EndreHode)",""); } } else { /* Koord.sys, enhet, origo eller tegnsett er endret */ LC_Error(96,"(LC_EndreHode)",""); } } else { /* Det er ikke plass til å skrive hodet */ LC_Error(97,"(LC_EndreHode)",""); } } } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_EndreHode)",""); } return oppdatert; } /* AR-920810 CH LC_RxGr Les gruppe fra base CD ========================================================================== CD Formål: CD Velger en gruppe som aktiv gruppe, og leser den fra SOSI-filen hvis den CD ikke er i RB fra før. (Styres også av les_sosi.) CD Hvis gruppen ikke finnes (sletta eller ulovlig gruppenummer) returneres CD ngi=0 og nko=0. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_BGR * pBgr i Peker til fil- og gruppenummer. CD short les_sosi i Lesemetode: Følgende konstanter er definert: CD LES_OPTIMALT (0 = Les mest effektivt base/SOSI) CD LES_SOSI (1 = Les alltid fra SOSI-filen) CD short *ngi u Antall linjer GINFO CD long *nko u Antall koordinater CD unsigned short *info u Diverse informasjon. En sum av følgende: CD GI_PINFO = gruppen har PINFO CD GI_NAH = gruppen har høyde informasjon (..NØH) CD GI_NAD = gruppen har dybde informasjon (..NØD) CD GI_KP = gruppen har knutepunkt (...KP n) CD GI_REF = gruppen har referanser (.. eller ..REF) CD GI_OY_REF = gruppen har referanser med øy CD GI_NGIS = gruppen er tatt ut fra NGIS for oppdat. CD GI_SLETTA = gruppen er sletta (merka som sletta) CD GI_READ_ONLY = gruppen kan ikke endres. CD short gnavn r Gruppenavn - Følgende konstanter er definert: CD INGEN_GRUPPE = Gruppen finnes ikke, ikke lest. CD L_SLUTT = (.SLUTT) CD L_PUNKT = (.PUNKT) CD L_LINJE = (.LINJE) CD L_KURVE = (.KURVE) CD L_BUE = (.BUE) CD L_BUEP = (.BUEP) CD L_SIRKEL = (.SIRKEL) CD L_SIRKELP = (.SIRKELP) CD L_KLOTOIDE = (.KLOTOIDE) CD L_SVERM = (.SVERM) CD L_TEKST = (.TEKST) CD L_TRASE = (.TRASE) CD L_FLATE = (.FLATE) CD L_BEZIER = (.BEZIER) CD L_RASTER = (.RASTER) CD L_DEF = (.DEF) CD L_OBJDEF = (.OBJDEF) CD L_MLINJE = (.MLINJE) CD L_STRUKTUR = (.STRUKTUR) CD L_OBJEKT = (.OBJEKT) CD L_SYMBOL = (.SYMBOL) CD L_HODE = (.HODE) CD CD CD Bruk: CD gnavn = LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); CD if (info & GI_PINFO) (gruppen har PINFO) CD ; CD if (info & GI_KP) (gruppen har KP) CD ; ========================================================================== */ SK_EntPnt_FYBA short LC_RxGr(LC_BGR * pBgr,short les_sosi,short *ngi,long *nko,unsigned short *info) { UT_INT64 slutt; short sNyGruppe = UT_TRUE; LO_TestFilpeker(pBgr->pFil,"RxGr"); // Har aktuell gruppe if (Sys.GrId.lNr != INGEN_GRUPPE) { sNyGruppe = Sys.GrId.pFil != pBgr->pFil || Sys.GrId.lNr != pBgr->lNr; // Hvis aktuell gruppe er endret, skriv den if (Sys.sGrEndra != END_UENDRA) { if (!(!sNyGruppe && les_sosi == LES_SOSI)) { if (LC_WxGr(SKRIV_OPTIMALT) == UT_FALSE) { // "Kan ikke lese ny gruppe. Du har ikke skriveaksess for å lagre aktuell gruppe som er endret. Fil :" LC_Error(163, "(LC_RxGr)", Sys.GrId.pFil->pszNavn); } } } } Sys.sGrEndra = END_UENDRA; Sys.sPibufStatus = LC_PIBUF_TOM; /* Lovlig gruppe */ if (pBgr->lNr >= 0L && pBgr->lNr < pBgr->pFil->lAntGr) { Sys.GrId = *pBgr; /* Hent fra gruppe-tabellen */ Sys.pGrInfo = LI_GetGrt(pBgr->pFil,pBgr->lNr); /* Sjekk om gruppen er sletta */ if (Sys.pGrInfo->ngi == 0 || /* Permanent sletta, eller */ (Sys.sNGISmodus == NGIS_NORMAL && /* Vanlig modus, og */ Sys.pGrInfo->info & GI_NGIS && /* oppdater NGIS, og */ Sys.pGrInfo->info & GI_SLETTA)) { /* merka som sletta */ /* Gruppen er sletta */ ; Sys.GrId.lNr = INGEN_GRUPPE; Sys.pGrInfo = NULL; *ngi = 0; *nko = 0; return -1; /* retur ===> */ } else { /* Gruppen er OK */ /* Tvungen les fra SOSI-filen av samme gruppe */ if (les_sosi == LES_SOSI) { /* Les fra SOSI-filen */ LB_RGru(pBgr->pFil,Sys.pGrInfo->sosi_st,&slutt); if (!sNyGruppe) { Sys.sGrEndra = END_ENDRA; } LC_OppdaterEndret(O_GINFO); /* Hent fra buffer-fil */ } else if (sNyGruppe) { Sys.GrId = *pBgr; LI_ReadRb(pBgr->pFil,Sys.pGrInfo->rb_st,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen, Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko, Sys.pszPinfo, Sys.pGrInfo->ulPiLen); LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi); } *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; return Sys.pGrInfo->gnavn; /* retur ===> */ } } /* Ulovlig gruppe */ Sys.GrId.lNr = INGEN_GRUPPE; Sys.pGrInfo = NULL; *ngi = 0; *nko = 0; return -1; /* retur ===> */ } /* AR-911001 CH LC_WxGr Skriv gruppe til base CD ========================================================================== CD Formål: CD Skriver aktuell gruppe til tilhørende SOSI-fil. CD Brukerindeks og geografisk indeks oppdateres straks, uavhengig av kø. CD Ledig plass fram til neste gruppe blir blanket. CD Filhode blir ALLTID skrevet direkte til SOSI-filen. CD CD Parametre: CD Type Navn I/U Forklaring CD ------------------------------------------------------------------------ CD short k_stat i Skrivemetode: Følgende konstanter er definert: CD SKRIV_OPTIMALT = Skriv mest effektivt kø/SOSI CD SKRIV_SOSI = Skriv direkte til SOSI-filen CD short status r Status: UT_TRUE = OK CD UT_FALSE = Ikke utført, pga. feil. CD CD Bruk: CD LC_WxGr(k_stat) ========================================================================== */ SK_EntPnt_FYBA short LC_WxGr(short k_stat) { short pnr,nivaa; if (Sys.GrId.lNr != INGEN_GRUPPE) /* Aktuell gruppe OK */ { if (Sys.sGrEndra != END_UENDRA) /* Gruppen er endra, må skrive */ { /* Har skriveaksess? */ //if (Sys.GrId.pFil->sAccess == UT_UPDATE && // (Sys.GrId.pFil->szNgisLag[0] == '\0' || strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) ) { //if (Sys.GrId.pFil->sAccess == UT_UPDATE && // (Sys.GrId.pFil->szNgisLag[0] == '\0' || Sys.sNGISmodus == NGIS_SPESIAL) ) { if (Sys.GrId.pFil->sAccess != UT_UPDATE || ((Sys.sNGISmodus == NGIS_NORMAL) && (strcmp(Sys.GrId.pFil->szNgisLag,"0")) == 0) ) { /* Ikke skriveaksess */ LC_Error(34,"(LC_WxGr)",Sys.GrId.pFil->pszNavn); return UT_FALSE; // ===> Retur ved feil } else { /* Sjekk at SOSI-filen har hode */ if ((Sys.GrId.pFil->TransMaske & LC_TR_ENHET) == 0 && Sys.pGrInfo->gnavn != L_HODE) { LC_Error(141,"(LC_WxGr)",Sys.GrId.pFil->pszNavn); } if (Sys.sGrEndra == (short)END_ENDRA) { // Kontroller prikknivå i egenskaper ? // Oppdater ..NGIS-FLAGG LC_OppdaterEndret(O_ENDRET); } Sys.sGrEndra = END_UENDRA; // Filhode som ligger som første gruppe på filen // Oppdater filtabellen if (Sys.pGrInfo->gnavn == L_HODE && Sys.GrId.lNr == 0) { LO_BeFt(Sys.GrId.pFil); // Ajourfører gruppetabellen med kvalitet og enhet } else { nivaa = 2; pnr = 1; LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr, &Sys.pGrInfo->Kvalitet.sMetode, &Sys.pGrInfo->Kvalitet.lNoyaktighet, &Sys.pGrInfo->Kvalitet.sSynbarhet, &Sys.pGrInfo->Kvalitet.sHoydeMetode, &Sys.pGrInfo->Kvalitet.lHoydeNoyaktighet); nivaa = 2; LC_GetCurEnhet(Sys.GrId.pFil, &nivaa, &Sys.pGrInfo->dEnhet, &Sys.pGrInfo->dEnhetHoyde, &Sys.pGrInfo->dEnhetDybde); /* Avrund buffer til riktig enhet */ LC_RoundKoord(); } /* Skriv til buffer-fil */ LB_WriteRb(); /* Skriv direkte, eller filhode */ if (k_stat == SKRIV_SOSI || Sys.pGrInfo->gnavn == L_HODE) { LB_Swap(); /* Legg inn i skrivekøa */ } else { Sys.lAntSkriv++; LI_SetBt (Sys.GrId.pFil, Sys.GrId.lNr, BT_SKRKO); /* Tøm køa hvis den er full */ if (Sys.lAntSkriv > Sys.lMaxSkriv) { LC_Save(); } } /* ----------------------------- Oppdater indekser */ LS_Indx(); /* Serienummer */ LR_Indx(); /* Primær geografisk */ if (Sys.pGrInfo->gnavn == L_FLATE) { LR_IndxFlate(); /* Flate geografisk */ } Sys.pGrInfo->ulPrior[0] = 0UL; /* Prioritetstabell */ Sys.pGrInfo->ulPrior[1] = 0UL; Sys.pGrInfo->ulPrior[2] = 0UL; Sys.pGrInfo->ulPrior[3] = 0UL; //} else { /* Ikke skriveaksess */ // LC_Error(34,"(LC_WxGr)",""); } } } return UT_TRUE; } /* AR-930907 CH LB_WriteRb Skriv aktuell gruppe til buffer-filen CD =========================================================================== CD Formål: CD Skriv aktuell gruppe til buffer-filen. CD CD Parametre: ingen CD CD Bruk: CD LB_WriteRb(); ============================================================================== */ static void LB_WriteRb(void) { LC_GRTAB_LINJE *pForrigeGrInfo, *pNesteGrInfo; long lLen; lLen = LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,Sys.pGrInfo->ulPiLen); /* Er ikke på filen fra før, tildel ny plass */ if (Sys.pGrInfo->rb_st == NY_RB_ST) { Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos; Sys.GrId.pFil->n64NesteLedigRbPos += (UT_INT64)lLen; /* Oppdater kjeden */ pForrigeGrInfo = LI_GetGrt (Sys.GrId.pFil, Sys.GrId.pFil->lSisteGrRb); pForrigeGrInfo->rb_neste_gr = Sys.GrId.lNr; Sys.pGrInfo->rb_forrige_gr = Sys.GrId.pFil->lSisteGrRb; Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE; Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr; /* Er på filen, sjekk om det er nok ledig plass */ } else { /* Siste gruppe i buffer-filen */ if (Sys.pGrInfo->rb_neste_gr == INGEN_GRUPPE) { Sys.GrId.pFil->n64NesteLedigRbPos = Sys.pGrInfo->rb_st + (UT_INT64)lLen; /* Inne i buffer-filen */ } else { pNesteGrInfo = LI_GetGrt(Sys.GrId.pFil,Sys.pGrInfo->rb_neste_gr); /* Det er ikke plass, må flytte gruppen til slutten av filen */ if (Sys.pGrInfo->rb_st + lLen > pNesteGrInfo->rb_st) { /* Tett "hullet" i kjeden */ pNesteGrInfo->rb_forrige_gr = Sys.pGrInfo->rb_forrige_gr; if (Sys.pGrInfo->rb_forrige_gr != INGEN_GRUPPE) { pForrigeGrInfo = LI_GetGrt(Sys.GrId.pFil,Sys.pGrInfo->rb_forrige_gr); pForrigeGrInfo->rb_neste_gr = Sys.pGrInfo->rb_neste_gr; } /* Legg til på slutten */ Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos; Sys.GrId.pFil->n64NesteLedigRbPos += (UT_INT64)lLen; pForrigeGrInfo = LI_GetGrt (Sys.GrId.pFil, Sys.GrId.pFil->lSisteGrRb); pForrigeGrInfo->rb_neste_gr = Sys.GrId.lNr; Sys.pGrInfo->rb_forrige_gr = Sys.GrId.pFil->lSisteGrRb; Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE; Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr; } } } LI_WriteRb(Sys.GrId.pFil,Sys.pGrInfo->rb_st,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen, Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko, Sys.pszPinfo, Sys.pGrInfo->ulPiLen); } /* AR-930608 CH LC_RoundKoord Endre koordinatene i buffer til riktig enhet CD =========================================================================== CD Formål: CD Endrer koordinatene i aktuell gruppe i buffer til valgt enhet. CD (Rutinen blir utført fra LC_WxGr.) CD CD Parametre: ingen CD CD Bruk: CD LC_RoundKoord(); ============================================================================== */ SK_EntPnt_FYBA void LC_RoundKoord(void) { short iniv; long pt; double enhet,enhet_h,enhet_d,tall; /* Lovlig gruppe */ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Kan gruppen endres (ikke READ_ONLY) */ //if ((Sys.pGrInfo->info & GI_READ_ONLY) == 0 ) { if ((Sys.pGrInfo->info & GI_READ_ONLY) == 0 || Sys.sNGISmodus == NGIS_SPESIAL ) { /* Finn aktuell enhet */ iniv = 2; LC_GetCurEnhet(Sys.GrId.pFil,&iniv,&enhet,&enhet_h,&enhet_d); /* Avrund koordinatene */ for (pt=0; ptnko; pt++) { /* Nord */ tall = UT_RoundDD(*(Sys.pdNord+pt) / enhet); *(Sys.pdNord+pt) = tall * enhet; /* Øst */ tall = UT_RoundDD(*(Sys.pdAust+pt) / enhet); *(Sys.pdAust+pt) = tall * enhet; /* Høyde */ if (Sys.pGrInfo->info & GI_NAH) { if ((Sys.pInfo+pt)->dHoyde != HOYDE_MANGLER) { tall = UT_RoundDD((Sys.pInfo+pt)->dHoyde / enhet_h); (Sys.pInfo+pt)->dHoyde = tall * enhet_h; } /* Dybde */ } else if (Sys.pGrInfo->info & GI_NAD) { if ((Sys.pInfo+pt)->dHoyde != HOYDE_MANGLER) { tall = UT_RoundDD((Sys.pInfo+pt)->dHoyde / enhet_d); (Sys.pInfo+pt)->dHoyde = tall * enhet_d; } } } } } } /* AR-911001 CH LC_OppdaterEndret Oppdater ..NGIS-FLAGG CD ========================================================================== CD Formål: CD Oppdaterer ..NGIS-FLAGG i GINFO og ajourfører interne tabeller. CD Hvis endring = O_GINFO oppateres tabellene i forhold til CD eksisterende GINFO. CD CD Parametre: CD Navn Type I/U Forklaring CD -------------------------------------------------------------------------- CD endring short i Kode for endring: CD O_GINFO (0) = Oppdater interne tabeller i fht. GINFO CD O_ENDRET (1) = Merk for endret og oppdat. tab. CD O_SLETTET (2) = Merk for slettet og oppdat. tab. CD CD Bruk: CD LC_OppdaterEndret(O_ENDRET); ============================================================================= */ SK_EntPnt_FYBA void LC_OppdaterEndret(short endring) { short gilin; char *gp; char szFlagg[80]; /* Finn aktuell parameter */ gilin=2; gp = LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi); if (gp == NULL){ Sys.pGrInfo->info &= (unsigned short)(~GI_NGIS); /* Ikke NGIS-oppdatering */ Sys.pGrInfo->info &= (unsigned short)(~GI_READ_ONLY); /* Ikke READ_ONLY */ } else { /* Tolk gammel parameter */ UT_StrCopy(szFlagg,gp,80); /* * Oppdater ..NGIS-FLAGG i GINFO hvis * det er NGIS-standardmodus, og ikke * intern tabelloppdatering. */ if (Sys.sNGISmodus == NGIS_NORMAL && endring != O_GINFO) { /* Kode */ if (endring == O_SLETTET) { szFlagg[0] = 'S'; } else if (endring == O_ENDRET) { if (szFlagg[0] == 'V') { szFlagg[0] = 'E'; } } /* Bygg opp ny ginfo */ LC_UpdateGP(gilin,"..NGIS-FLAGG",szFlagg); } /* ---------- Oppdater interne tabeller --------- */ /* NGIS-oppdatering */ Sys.pGrInfo->info |= GI_NGIS; /* Flagg for sletting */ if (szFlagg[0] == 'S') { Sys.pGrInfo->info |= GI_SLETTA; /* Sletta */ } else { Sys.pGrInfo->info &= (unsigned short)(~GI_SLETTA); /* Ikke sletta */ } /* Flagg for lese/skrive aksess */ if (szFlagg[0] == 'R' || szFlagg[0] == 'H') { Sys.pGrInfo->info |= GI_READ_ONLY; /* Bare leseaksess */ } else { Sys.pGrInfo->info &= (unsigned short)(~GI_READ_ONLY); /* Både lese- og skriveaksess */ } } } /* AR-911001 CH LC_FiLastGr Finn siste gruppe i filen CD ========================================================================== CD Formål: CD Finner gruppenummer for siste gruppe i filen. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD bgr long r Gruppenummer CD CD Bruk: CD bgr = LC_FiLastGr(pFil); ========================================================================== */ SK_EntPnt_FYBA long LC_FiLastGr(LC_FILADM *pFil) { /* LO_TestFilpeker(pFil,"LC_FiLastGr"); */ LO_TestFilpeker(pFil,"FiLastGr"); return pFil->lAntGr - 1; } /* AR-930608 CH LC_CopyGr Kopier gruppe CD ========================================================================== CD Formål: CD Kopierer fra en annen gruppe inn i aktuell gruppe i buffer. CD Rutinen tilsvarer put fra brukerprogram inn i bufret, men rutinen CD tildeler selv nødvendig plass. CD Gruppen beholder serienummer tildelt i LC_NyGr. CD Geografisk-indeks blir ikke oppdatert før gruppen skrives til basen. CD Enhet blir oppdatert slik at opprinnelig enhet blir bevart. Om nødvendig CD legges det inn ..ENHET i GINFO. CD Kvalitet og dato blir oppdatert hvis SOSI-VERSJON < 4.00. CD Hvis det er filhode som kopieres skjer det ingen endring av egenskaper. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_BGR *pBgr i Gruppenummer det skal kopieres fra. CD short ngis i Behandling for ..NGIS-FLAGG: CD OPPDATER_NGIS (0) = ..NGIS-FLAGG oppdateres i henhold CD til hodet i filen det kopieres til. CD BEVAR_NGIS (1) = ..NGIS-FLAGG bevares uforandret i kopien CD short ngi u Antall linjer GINFO CD long nko u Antall koordinater CD unsigned short info u Diverse informasjon. (Se under $LENKE) CD short gnavn r Gruppenavn. (Se under $LENKE) CD CD Bruk: CD gnavn = LC_CopyGr(&Bgr,ngis,&ngi,&nko,&info) ========================================================================== */ SK_EntPnt_FYBA short LC_CopyGr (LC_BGR * pBgr,short ngis,short *ngi,long *nko,unsigned short *info) { short gilin; long snr,rb_forrige_gr,rb_neste_gr; UT_INT64 rb_st,sosi_st; LC_GRTAB_LINJE * grtp; char *cp,szTx[256]; LC_R_LEAF * pRL; /* Peker inn i geografisk søketre */ LO_TestFilpeker(pBgr->pFil,"CopyGr"); grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr); if (Sys.GrId.lNr == INGEN_GRUPPE) { /* Feil ==> Ingen aktuell gruppe */ LC_Error(31,"(LC_CopyGr)",""); /* Gruppen er sletta */ } else if (grtp->ngi == 0 || /* Permanent sletta, eller */ (Sys.sNGISmodus == NGIS_NORMAL && /* Vanlig modus, og */ grtp->info & GI_NGIS && /* oppdater NGIS, og */ grtp->info & GI_SLETTA)){ /* merka som sletta */ LC_Error(35,"(LC_CopyGr)",""); /* Kopierer seg selv */ } else if (pBgr->pFil == Sys.GrId.pFil && pBgr->lNr == Sys.GrId.lNr) { *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } else { /* Lovlig gruppe */ Sys.sGrEndra = END_KOPI; Sys.sPibufStatus = LC_PIBUF_TOM; snr = LC_GetSn(); /* Husk serienummer */ /* Husk viktige data fra akt.gr. */ sosi_st = Sys.pGrInfo->sosi_st; rb_st = Sys.pGrInfo->rb_st; rb_forrige_gr = Sys.pGrInfo->rb_forrige_gr; rb_neste_gr = Sys.pGrInfo->rb_neste_gr; pRL = Sys.pGrInfo->pRL; /* Peker inn i geografisk søketre */ /* Kopier data om gruppen det kopieres fra */ *Sys.pGrInfo = *grtp; /* Legg tilbake data om akt.gr. */ Sys.pGrInfo->sosi_st = sosi_st; Sys.pGrInfo->rb_st = rb_st; Sys.pGrInfo->rb_forrige_gr = rb_forrige_gr; Sys.pGrInfo->rb_neste_gr = rb_neste_gr; Sys.pGrInfo->pRL = pRL; /* Les fra buffer-filen */ LI_ReadRb(pBgr->pFil,grtp->rb_st,Sys.Ginfo.pszTx,grtp->ulGiLen, Sys.pdAust, Sys.pdNord, Sys.pInfo, grtp->nko, Sys.pszPinfo, grtp->ulPiLen); LX_CreGiPeker(&Sys.Ginfo,grtp->ngi); /* Legg tilbake rett SNR */ LX_PutSn(snr); // Hvis det er filhode som kopieres skjer det ingen endring av egenskaper. if (pBgr->lNr != 0) { // ----- Handter NGIS oppdateringsflagg // Søk etter ..NGIS-FLAGG, og fjern den gilin=2; if (LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi) != NULL) { if ( ngis == OPPDATER_NGIS) { // NGIS-flagg if (*Sys.GrId.pFil->szNgisLag != '\0' && strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) { // Skriv navnet med hermetegn hvis det er blanke i navnet if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",Sys.GrId.pFil->szNgisLag); } else { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",Sys.GrId.pFil->szNgisLag); } LC_PutGi(gilin,szTx); Sys.pGrInfo->info |= GI_NGIS; } else { LC_DelGiL(gilin,1); Sys.pGrInfo->info &= (unsigned short)(~GI_NGIS); /* Ikke NGIS-oppdatering */ } } else { // Flagget skal bevares } } else { /* NGIS-flagg */ //if (Sys.GrId.pFil->lNgisLag > 0) { if (*Sys.GrId.pFil->szNgisLag != '\0' && strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) { // Skriv navnet med hermetegn hvis det er blanke i navnet if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",Sys.GrId.pFil->szNgisLag); } else { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",Sys.GrId.pFil->szNgisLag); } LC_PutGi(LC_AppGiL(),szTx); Sys.pGrInfo->info |= GI_NGIS; } } /* ------------ Legg inn div. standardopplysninger */ /* ENHET */ LC_UpdateGiEnhet(Sys.GrId.pFil,grtp->dEnhet, grtp->dEnhetHoyde, grtp->dEnhetDybde); // Bare hvis filen er eldre enn SOSI v 4.0 if (Sys.GrId.pFil->sSosiVer < 400) { // Det skal aldri legges ut kvalitet på .FLATE eller .OBJEKT if (Sys.pGrInfo->gnavn != L_FLATE && Sys.pGrInfo->gnavn != L_OBJEKT) { // ..KVALITET LC_UpdateGiKvalitet(Sys.GrId.pFil,grtp->Kvalitet.sMetode, grtp->Kvalitet.lNoyaktighet, grtp->Kvalitet.sSynbarhet, grtp->Kvalitet.sHoydeMetode, grtp->Kvalitet.lHoydeNoyaktighet); } // NGIS-fil, oppdater DATO if (*Sys.GrId.pFil->szNgisLag != '\0' && strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) { if (*Sys.GrId.pFil->szDato != '\0' && *Sys.GrId.pFil->szDato != '*' && *Sys.GrId.pFil->szDato < '4') { // ..DATO fra fil-hodet gilin=2; if ((cp = LC_GetGP("..DATO",&gilin,Sys.pGrInfo->ngi)) == NULL) { UT_SNPRINTF(szTx,256,"..DATO %s",pBgr->pFil->szDato); LC_PutGi(LC_AppGiL(),szTx); } } } // SOSI-VERSJON //gilin=2; //if ((cp = LC_GetGP("..SOSI-VERSJON",&gilin,Sys.pGrInfo->ngi)) == NULL) { // UT_SNPRINTF(szTx,256,"..SOSI-VERSJON %.2f",((double)(pBgr->pFil->sSosiVer))/100.0); // LC_PutGi(LC_AppGiL(),szTx); //} } } *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } return Sys.pGrInfo->gnavn; } /* AR-930707 CH LC_CopyCoord Kopier koordinater fra annen gruppe CD =========================================================================== CD Formål: CD Kopierer koordinater fra en annen gruppe inn i aktuell gruppe i ringbuffer. CD De kopierte koordinatene kommer som en utvidelse av gruppen. CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret, men rutinen CD tildeler selv nødvendig plass i RB. CD Geografisk-indeks blir ikke oppdatert før gruppen skrives til basen. CD Kvalitet og enhet blir automatisk oppdatert slik at gruppene ikke CD mister informasjon. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_BGR *pBgr i Gruppenummer det skal kopieres fra. CD short retning i Buffer-retning: CD HENT_FORRFRA ( 1) = vanlig, CD HENT_BAKFRA (-1) = buffer skal snues. CD long til_linje i Linjenummer linjen skal skytes inn forran. CD (Lovlig: 1 til nko+1) CD short ngi u Antall GINFO-linjer CD long nko u Antall koordinater CD short info u Diverse informasjon. (Se under $LENKE) CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=ikke utført. CD CD Bruk: CD sStatus = LC_CopyCoord(bgr,retning,til_linje,&ngi,&nko,&info); ============================================================================= */ SK_EntPnt_FYBA short LC_CopyCoord(LC_BGR * pBgr,short retning,long til_linje,short *ngi, long *nko,unsigned short *info) { long l,ko,pnr,fra_pt,til_pt; unsigned short in; unsigned long ulPiLen,ulGiLen; short metode,hoydemetode,synbarhet,met,hmet,syn,nivaa,gi_met,gi_hmet,gi_syn; long noyaktighet,hoydenoyaktighet,noy,hnoy,gi_noy,gi_hnoy; UT_INT64 rb_st; double *pdAust, *pdNord; LB_INFO * pInfo; char *pszPinfo; LC_GRTAB_LINJE * grtp; short sStatus = UT_TRUE; LO_TestFilpeker(pBgr->pFil,"CopyCoord"); grtp = LI_GetGrt(pBgr->pFil,pBgr->lNr); if (Sys.GrId.lNr == INGEN_GRUPPE){ /* Feil ==> Ingen aktuell gruppe */ LC_Error(31,"(LC_CopyCoord)",""); sStatus = UT_FALSE; /* Gruppen er sletta */ } else if (grtp->ngi == 0 || /* Permanent sletta, eller */ (Sys.sNGISmodus == NGIS_NORMAL && /* Vanlig modus, og */ grtp->info & GI_NGIS && /* oppdater NGIS, og */ grtp->info & GI_SLETTA)){ /* merka som sletta */ LC_Error(35,"(LC_CopyCoord)",""); sStatus = UT_FALSE; } else if (pBgr->pFil == Sys.GrId.pFil && pBgr->lNr == Sys.GrId.lNr) { /* Kopierer seg selv */ LC_Error(99,"(LC_CopyCoord)",""); sStatus = UT_FALSE; } else { /* Lovlig gruppe */ /* Husk diverse opplysninger */ ko = grtp->nko; in = grtp->info; metode = grtp->Kvalitet.sMetode; noyaktighet = grtp->Kvalitet.lNoyaktighet; synbarhet = grtp->Kvalitet.sSynbarhet; hoydemetode = grtp->Kvalitet.sHoydeMetode; hoydenoyaktighet = grtp->Kvalitet.lHoydeNoyaktighet; rb_st = grtp->rb_st; ulGiLen = grtp->ulGiLen; ulPiLen = grtp->ulPiLen; /* Tildel plass for koordinatene */ l = Sys.pGrInfo->nko; LC_InsKoL(til_linje,ko); if (Sys.pGrInfo->nko > l) { /* Har det blitt lagt inn flere linjer */ Sys.sGrEndra = (short)END_ENDRA; Sys.sPibufStatus = LC_PIBUF_TOM; /* Alloker midlertidig buffer */ pdAust = (double*)UT_MALLOC(ko * sizeof(double)); pdNord = (double*)UT_MALLOC(ko * sizeof(double)); pInfo = (LB_INFO *)UT_MALLOC(ko * sizeof(LB_INFO)); pszPinfo = (char*)UT_MALLOC(ulPiLen * sizeof(char)); /* Les fra buffer-filen */ LI_ReadCoordRb(pBgr->pFil, rb_st, ulGiLen,pdAust, pdNord, pInfo, ko, pszPinfo, ulPiLen); /* Regn posisjoner */ til_pt = til_linje - 1; if (retning == HENT_FORRFRA) { fra_pt = 0; retning = 1; } else{ fra_pt = ko - 1; retning = -1; } for (l = 0; l < ko; l++) { /* Koordinater og PINFO */ *(Sys.pdAust+til_pt) = *(pdAust+fra_pt); *(Sys.pdNord+til_pt) = *(pdNord+fra_pt); (Sys.pInfo+til_pt)->dHoyde = (pInfo+fra_pt)->dHoyde; (Sys.pInfo+til_pt)->sKp = (pInfo+fra_pt)->sKp; if ((pInfo+fra_pt)->ulPiOfset != LC_INGEN_PINFO) { LC_PutPi(til_pt+1, pszPinfo+((pInfo+fra_pt)->ulPiOfset)); } til_pt++; fra_pt += retning; } Sys.pGrInfo->info |= in; /* Frigi midlertidig buffer */ UT_FREE(pdAust); UT_FREE(pdNord); UT_FREE(pInfo); UT_FREE(pszPinfo); // ----- Oppdater Kvalitet i de kopierte punktene if (Sys.GrId.pFil->sSosiVer < 400) { // Husk kvalitet i GINFO på aktuell gruppe nivaa = 2; pnr = 1; LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,&gi_met,&gi_noy,&gi_syn,&gi_hmet,&gi_hnoy); // Oppdater punktene for (pnr=til_linje; ko>0; pnr++,ko--) { nivaa = 3; LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pnr,&met,&noy,&syn,&hmet,&hnoy); // Funnet punkt uten kvalitet i PINFO if (nivaa < 3) { LC_UpdatePiKvalitet(Sys.GrId.pFil,pnr, metode,noyaktighet,synbarhet,hoydemetode,hoydenoyaktighet); // Funnet punkt med samme kvalitet som aktuell GINFO } else if (met == gi_met && noy == gi_noy && syn == gi_syn && hmet == gi_hmet && hnoy == gi_hnoy) { LC_UpdatePiKvalitet(Sys.GrId.pFil,pnr,met,noy,syn,hmet,hnoy); } } } *ngi = Sys.pGrInfo->ngi; *nko = Sys.pGrInfo->nko; *info = Sys.pGrInfo->info; } else { /* For mange koordinater */ sStatus = UT_FALSE; } } return sStatus; } /* AR-940208 CH LC_SnuGr Snu gruppe CD =========================================================================== CD Formål: CD Snur en gruppe. CD Rutinen tilsvarer put fra brukerprogram inn i ringbufret. CD Både koordinater, høyde, KP og PINFO blir behandlet. CD For .BUE blir fortegnet på radius endret. CD Fortegnet på referanser til gruppen blir oppdatert. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD CD Bruk: CD LC_SnuGr(); ============================================================================= */ SK_EntPnt_FYBA void LC_SnuGr(void) { short ngi,sGiLin,Endret; long fra_pt,til_pt; long nko; unsigned short info; double *pdAust,*pdNord; LB_INFO * pInfo; char *pszPinfo,szRadius[30]; double nva,nvn,oha,ohn; LC_GEO_STATUS GeoStat; LC_BGR Bgr,FlateBgr; LC_POLYGON Polygon; LC_POL_ELEMENT * pPE; LC_OY_ELEMENT * pOE; /* Feil ==> Ingen aktuell gruppe */ if (Sys.GrId.lNr == INGEN_GRUPPE){ LC_Error(31,"(LC_CopyCoord)",""); /* Lovlig gruppe */ } else if (Sys.pGrInfo->nko > 1) { /* Husk diverse opplysninger */ nko = Sys.pGrInfo->nko; /* Tildel plass for koordinatene */ Sys.sGrEndra = (short)END_ENDRA; Sys.sPibufStatus = LC_PIBUF_TOM; /* Lag en midlertidig kopi av original-bufferet */ pdAust = (double*)UT_MALLOC(nko * sizeof(double)); UT_memcpy(pdAust,nko * sizeof(double),Sys.pdAust,nko * sizeof(double)); pdNord = (double*)UT_MALLOC(nko * sizeof(double)); UT_memcpy(pdNord,nko * sizeof(double),Sys.pdNord,nko * sizeof(double)); pInfo = (LB_INFO *)UT_MALLOC(nko * sizeof(LB_INFO)); UT_memcpy(pInfo,nko * sizeof(LB_INFO),Sys.pInfo,nko * sizeof(LB_INFO)); pszPinfo = (char*)UT_MALLOC(Sys.pGrInfo->ulPiLen * sizeof(char)); UT_memcpy(pszPinfo,Sys.pGrInfo->ulPiLen * sizeof(char),Sys.pszPinfo,Sys.pGrInfo->ulPiLen * sizeof(char)); /* Tømmer gruppen for gammelt innhold */ LC_DelKoL(1,nko); LC_InsKoL(1,nko); /* Legger inn koordinater og PINFO */ for (til_pt=0,fra_pt=nko-1; til_ptdHoyde = (pInfo+fra_pt)->dHoyde; (Sys.pInfo+til_pt)->sKp = (pInfo+fra_pt)->sKp; if ((pInfo+fra_pt)->ulPiOfset != LC_INGEN_PINFO) { LC_PutPi(til_pt+1, pszPinfo+((pInfo+fra_pt)->ulPiOfset)); } } /* Frigi midlertidig buffer */ UT_FREE(pdAust); UT_FREE(pdNord); UT_FREE(pInfo); UT_FREE(pszPinfo); /* ====== Hvis gruppen er .BUE ==> skift fortegn på radius ==== */ if (Sys.pGrInfo->gnavn == L_BUE) { sGiLin = 2; pszPinfo = LC_GetGP("..RADIUS",&sGiLin,Sys.pGrInfo->ngi); if (*pszPinfo == '-') { UT_StrCopy(szRadius,pszPinfo+1,30); } else { szRadius[0] = '-'; UT_StrCopy(szRadius+1,pszPinfo,29); } LC_UpdateGP(sGiLin,"..RADIUS",szRadius); } /* ========= Oppdater referanser til gruppen */ /* Husk gruppen */ Bgr = Sys.GrId; LC_POL_InitPolygon(&Polygon); LC_GetGrWin(&Sys.GrId,&nva,&nvn,&oha,&ohn); LC_SBFlate(&GeoStat,LC_FRAMGR,nva,nvn,oha,ohn); if (LC_FFFlate(&GeoStat,&FlateBgr)) { do { if (FlateBgr.pFil == Bgr.pFil) { /* Funnet flate i rett fil, sjekk referansene */ LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info); LC_POL_GetRef(&Polygon); Endret = UT_FALSE; /* Omkretsen */ for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) { if ((memcmp(&pPE->Bgr,&Bgr,sizeof(LC_BGR))) == 0) { pPE->sRetning = (pPE->sRetning == LC_MED_DIG)? LC_MOT_DIG : LC_MED_DIG; Endret = UT_TRUE; } } /* Øyer */ for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) { for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) { if ((memcmp(&pPE->Bgr,&Bgr,sizeof(LC_BGR))) == 0) { pPE->sRetning = (pPE->sRetning == LC_MED_DIG)? LC_MOT_DIG : LC_MED_DIG; Endret = UT_TRUE; } } } /* Lagre de oppdaterte referansene */ if (Endret) { LC_POL_PutRef(&Polygon); LC_WxGr(SKRIV_OPTIMALT); } /* Frigi allokerte kjeder */ LC_POL_FrigiPolygon(&Polygon); } } while (LC_FNFlate(&GeoStat,&FlateBgr)); } LC_AvsluttSok(&GeoStat); /* ========= Les inn igjen opprinnelig gruppe */ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); } } /* AR-911001 CH LC_DelGr Slett gruppe CD ========================================================================== CD Formål: CD Fjerner aktuell gruppe fra basen. CD Grupper som er tatt ut fra NGIS for oppdatering blir ikke sletta fra CD SOSI-filen, men de blir merka som sletta. (LC_SetNgisModus avgjør da om CD disse kan leses.) CD Det er ikke mulig å slette grupper fra sekvensielle filer, eller grupper CD som er brukt i flater. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD short sStatus r Status: UT_TRUE = OK CD UT_FALSE = feil, ikke sletta CD CD Bruk: CD sStatus = LC_DelGr(); ========================================================================== */ SK_EntPnt_FYBA short LC_DelGr(void) { UT_INT64 neste; char *gp; short gilin = 2; short sStatus = UT_TRUE; long lSnr = LC_GetSn(); char *pszNgisFlagg; if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Ikke filhode, eller kladdebase */ //if (Sys.pGrInfo->gnavn != L_HODE && Sys.GrId.pFil->pBase->sType == LC_BASE) { if (Sys.GrId.lNr != 0 && Sys.GrId.pFil->pBase->sType == LC_BASE) { if ( ! (Sys.pGrInfo->info & GI_SLETTA)) { /* Ikke sletta fra før */ if (Sys.GrId.pFil->usLag & LC_FRAMGR) { /* Har skriveaksess */ // Finn og ta vare på NGIS-flagg gp = LC_GetGP("..NGIS-FLAGG",&gilin,Sys.pGrInfo->ngi); if (gp) { pszNgisFlagg = (char*)malloc(strlen(gp)+1); UT_StrCopy(pszNgisFlagg, gp, strlen(gp)+1); } else { pszNgisFlagg = NULL; } // Ny gruppe - ikke lagret til SOSI, eller // ikke NGIS-oppdatering, eller // ny NGIS-gruppe, eller // vanlig NGIS-grupppe if (Sys.pGrInfo->sosi_st == NY_SOSI_ST || pszNgisFlagg == NULL || *pszNgisFlagg == 'N' || *pszNgisFlagg == 'V' || *pszNgisFlagg == 'E' || *pszNgisFlagg == 'S' ) { if (Sys.pGrInfo->gnavn == L_LINJE || Sys.pGrInfo->gnavn == L_KURVE || Sys.pGrInfo->gnavn == L_BUE || Sys.pGrInfo->gnavn == L_BUEP || Sys.pGrInfo->gnavn == L_SIRKEL || Sys.pGrInfo->gnavn == L_SIRKELP || Sys.pGrInfo->gnavn == L_KLOTOIDE || Sys.pGrInfo->gnavn == L_TRASE ) { if (Sys.pGrInfo->nko > 0) { // Sjekk om det finnes referanser til gruppen if (LC_ErReferert()) sStatus = UT_FALSE; } } // Det finnes ikke referanser til gruppen if (sStatus == UT_TRUE) { /* Ikke NGIS-oppdatering, eller ny NGIS-gruppe, fjerner fysisk fra SOSI-filen */ if (Sys.pGrInfo->sosi_st == NY_SOSI_ST || pszNgisFlagg == NULL || *pszNgisFlagg == 'N' ) { if (Sys.pGrInfo->sosi_st != NY_SOSI_ST) { /* Ikke ny gruppe */ LB_Plass(Sys.GrId.pFil,Sys.pGrInfo->sosi_st,&neste); /* Posisjoner og blank ut området */ _fseeki64(Sys.GrId.pFil->pBase->pfSos,Sys.pGrInfo->sosi_st,SEEK_SET); LB_WriteBlank(Sys.GrId.pFil->pBase->pfSos,Sys.GrId.pFil->sTegnsett,neste); fflush(Sys.GrId.pFil->pBase->pfSos); } Sys.pGrInfo->ngi = 0; Sys.pGrInfo->nko = 0; /* Vanlig NGIS-grupppe, merker som slettet */ } else if (*pszNgisFlagg == 'V' || *pszNgisFlagg == 'E' || *pszNgisFlagg == 'S' ) { LC_OppdaterEndret(O_SLETTET); LC_WxGr(SKRIV_SOSI); } /* Fjerner fra snr.tab */ LS_PutSn(Sys.GrId.pFil,INGEN_GRUPPE,lSnr); /* Fjerner fra geogr. søketabell */ LR_R_Delete(Sys.pGrInfo->pRL); Sys.pGrInfo->pRL = NULL; Sys.pGrInfo->info |= GI_SLETTA; /* Gruppen sletta */ LI_PutBt(Sys.GrId.pFil,Sys.GrId.lNr,0L); /* Fjerner all merking */ Sys.GrId.lNr = INGEN_GRUPPE; /* Ingen aktuell gruppe */ Sys.sGrEndra = END_UENDRA; /* Brukt i flate */ /*} else { LC_Error(44,"(LC_DelGr)","");*/ } /* Bare leseaksess */ } else if (*pszNgisFlagg == 'R' || *pszNgisFlagg == 'H' ) { LC_Error(91,"(LC_DelGr)",""); sStatus = UT_FALSE; /* Ukjent NGIS endringsflagg */ } else { LC_Error(91,"(LC_DelGr)",""); sStatus = UT_FALSE; } // Frigir alloker minne if (pszNgisFlagg) free(pszNgisFlagg); } else { /* Ikke skriveaksess */ LC_Error(91,"(LC_DelGr)",""); sStatus = UT_FALSE; } } } else { /* Filhode, eller kladdebase */ sStatus = UT_FALSE; if (Sys.GrId.pFil->pBase->sType != LC_BASE) { /* Slett gruppe ulovlig ved kladdebase */ LC_Error(95,"(LC_DelGr)",""); } else { /* Kan ikke slette filhodet */ LC_Error(48,"(LC_DelGr)",""); } } } return sStatus; } /* AR-920129 CH LC_SplittGr Splitt gruppe CD ========================================================================== CD Formål: CD Splitter aktuell gruppe i to deler. CD Første del av gruppen beholdes som aktuell gruppe. Denne blir ikke CD skrevet til SOSI-filen, men buffer er oppdatert. CD Siste del av gruppen legges som en ny gruppe på samme fil som CD opprinnelig gruppe. Denne blir skrevet til basen. CD Den delen av gruppen som ligger mellom P1 og P2 blir fjernet. CD CD Hvis gruppen er BUEP og en av delene får bare to koordinater CD blir det lagt inn et nytt punkt midt på buen. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD long sP1 i Punktnummer 1. (Må være større enn 1) CD long sP2 i Punktnummer 2. (Må være mindre enn nko) CD LC_BGR * pBgr2 u Nytt gruppenummer for siste del av gruppen. CD short sStatus r Status: UT_TRUE = OK CD UT_FALSE = feil, ikke splittet CD CD Bruk: CD sStatus = LC_SplittGr(sP1,sP2,&Bgr2); ========================================================================== */ SK_EntPnt_FYBA short LC_SplittGr (long sP1,long sP2,LC_BGR * pBgr2) { short ngi,Endret,s; long nko; long l; unsigned short info; LC_FILADM *pFil; LC_BGR Bgr,FlateBgr; long lGmlSnr,lNyttSnr; double nva,nvn,oha,ohn; double a1,n1,a2,n2,as1,ns1,as2,ns2,r,fi,dfi,fi2,dfi2; LC_GEO_STATUS GeoStat; long lAntRef; long lNyAntRef; short sGiLin,sRefPos; long *plRefArray,*plNyRefArray,*plRef,*plNyRef; double fiNy,dfiNy,dA_ny,dN_ny; double ax,nx; bool bStorbue = false; /* Viser om opprinnelig gruppe var OK storbue */ short sStatus = UT_FALSE; /* Har aktuell gruppe med koordinater, og lovlige punktnummer */ if (Sys.GrId.lNr != INGEN_GRUPPE && Sys.pGrInfo->nko > 0 && sP1 > 1 && sP2 < Sys.pGrInfo->nko) { /* Husk at beregning er utført */ sStatus = UT_TRUE; /* Husk gruppen */ pFil = Sys.GrId.pFil; Bgr = Sys.GrId; lGmlSnr = LC_GetSn(); LC_GetGrWin(&Bgr,&nva,&nvn,&oha,&ohn); if (Sys.pGrInfo->gnavn == L_BUE || Sys.pGrInfo->gnavn == L_BUEP || Sys.pGrInfo->gnavn == L_SIRKELP ) { // Tar vare på bueparametrene for opprinnelig "bue" LC_GetBuePar(HENT_FORRFRA,&as1,&ns1,&r,&fi,&dfi,&s); bStorbue = (fabs(dfi) > PI); } // ========= Lag ny gruppe, og kopier hele den opprinnelige gruppen LC_NyGr(pFil,".LINJE",pBgr2,&lNyttSnr); LC_CopyGr(&Bgr,OPPDATER_NGIS,&ngi,&nko,&info); /* Samme brukttabell som opprinnelig gruppe */ for (s=BT_MIN_USER; s<=BT_MAX_USER; s++) { if (LC_GetBt(&Bgr,s) != 0) { LC_SetBt(pBgr2,s); } } // SIRKELP konverteres til BUEP if (Sys.pGrInfo->gnavn == L_SIRKELP ) { LC_PutGi(1,".BUEP"); double a,n; LC_GetTK(1,&a,&n); nko = LC_AppKoL(); LC_PutTK(nko,a,n); LC_PutKp(nko,LC_GetKp(1)); } /* Fjern første del av gruppen */ if (sP2 > sP1){ nko = LC_DelKoL(1, sP2-1); } else if (nko > 1) { nko = LC_DelKoL(1, sP1-1); } /* Sjekk om storbue er blitt liten bue */ if (Sys.pGrInfo->gnavn == L_BUE && bStorbue) { LC_GetBue(HENT_FORRFRA,&a1,&n1,&a2,&n2,&r,&s); GM_KonvBue(a1,n1,a2,n2,r,s,&as2,&ns2,&fi2,&dfi2); /* Buen skal ikke være storbue lenger hvis sentrum er flyttet. * Dette er tilfelle når linjen fra gammelt til nytt senter * skjærer linjen fra nytt start til sluttpunkt. */ if (GM_sLinLin(a1,n1,a2,n2,as1,ns1,as2,ns2,&ax,&nx)) { LC_PutGP("..STORBUE","0",&s); } } // Sjekk at .BUEP har tre koordinater if (Sys.pGrInfo->gnavn == L_BUEP) { if (nko == 2) { // --- Legger inn nytt punkt på buen mellom de to endepunktene. // Åpningsvinkel til starten av den nye buen LC_GetTK(1,&a1,&n1); GM_PktBue(as1,ns1,fi,dfi,a1,n1,&dfiNy); // Midtpunktet fiNy = fi + (dfiNy+((dfi-dfiNy)/2.0)); dA_ny = as1 + fabs(r)*cos(fiNy); dN_ny = ns1 + fabs(r)*sin(fiNy); nko = LC_InsKoL(2,1); LC_PutTK(2,dA_ny,dN_ny); } // Endre til .KURVE hvis buen blir ulovlig LR_TestEndreBuepTilKurve(dfi); } // Lagre LC_WxGr(SKRIV_OPTIMALT); // ========= Oppdater referanser til gruppen LC_SBFlate(&GeoStat,LC_FRAMGR,(double)nva,(double)nvn, (double)oha,(double)ohn); if (LC_FFFlate(&GeoStat,&FlateBgr)) { do { if (FlateBgr.pFil == pFil) { /* Funnet flate i rett fil, sjekk referansene */ LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info); lAntRef = LC_InqAntRef(); plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long)); plNyRefArray = (long *) UT_MALLOC((lAntRef+2) * sizeof(long)); sGiLin = 2; sRefPos = 0; LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos); lNyAntRef = lAntRef; Endret = UT_FALSE; plRef = plRefArray; plNyRef = plNyRefArray; for (l=0; l 0) { *plNyRef++ = *plRef++; *plNyRef++ = lNyttSnr; } else { *plNyRef++ = -lNyttSnr; *plNyRef++ = *plRef++; } Endret = UT_TRUE; lNyAntRef++; } else { *plNyRef++ = *plRef++; } } if (Endret) { LC_PutRef(plNyRefArray,lNyAntRef); LC_WxGr(SKRIV_OPTIMALT); } UT_FREE(plRefArray); UT_FREE(plNyRefArray); } } while (LC_FNFlate(&GeoStat,&FlateBgr)); } LC_AvsluttSok(&GeoStat); // ========= Oppdater opprinnelig gruppe LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); /* Fjern siste del av gruppen */ if (nko > 1) { nko = LC_DelKoL(sP1+1, nko-sP1); } // SIRKELP må konverteres til BUEP if (Sys.pGrInfo->gnavn == L_SIRKELP ) { LC_PutGi(1,".BUEP"); } /* Sjekk om storbue er blitt liten bue */ if (Sys.pGrInfo->gnavn == L_BUE && bStorbue) { LC_GetBue(HENT_FORRFRA,&a1,&n1,&a2,&n2,&r,&s); GM_KonvBue(a1,n1,a2,n2,r,s,&as2,&ns2,&fi2,&dfi2); /* Buen skal ikke være storbue lenger hvis sentrum er flyttet. * Dette er tilfelle når linjen fra gammelt til nytt senter * skjærer linjen fra nytt start til sluttpunkt. */ if (GM_sLinLin(a1,n1,a2,n2,as1,ns1,as2,ns2,&dA_ny,&dN_ny)) { LC_PutGP("..STORBUE","0",&s); } } // Sjekk at .BUEP har tre koordinater if (Sys.pGrInfo->gnavn == L_BUEP) { if (nko == 2) { // --- Legger inn nytt punkt på buen mellom de to endepunktene. // Åpningsvinkel til slutten av den nye buen LC_GetTK(2,&a2,&n2); GM_PktBue(as1,ns1,fi,dfi,a2,n2,&dfiNy); // Midtpunktet fiNy = fi + (dfiNy/2.0); dA_ny = as1 + fabs(r)*cos(fiNy); dN_ny = ns1 + fabs(r)*sin(fiNy); LC_InsKoL(2,1); LC_PutTK(2,dA_ny,dN_ny); } // Endre til .KURVE hvis buen blir ulovlig LR_TestEndreBuepTilKurve(dfi); } } return sStatus; } /* AR-930803 CH LR_TestEndreBuepTilKurve Sammenføy grupper CD ========================================================================== CD Formål: CD Sjekk om BUEP blir ugyldeig etter splitting. CD Konverterer eventuellt til .KURVE CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD double dDeltaFi i Åpningsvinkel for opprinnelig BUEP CD CD Bruk: CD LR_TestEndreBuepTilKurve(dDeltaFi); ============================================================================= */ static void LR_TestEndreBuepTilKurve(double dDeltaFi) { double as,ns,r,fi,dfi; double dAMidt,dNMidt,dAFotP,dNFotP; double a1,n1,a2,n2; short s; // Avrund buffer til riktig enhet LC_RoundKoord(); // Bueparametrene for oppdatert "bue" if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&r,&fi,&dfi,&s) ) { // Buen er snudd krumming (åpningsvinkelen har skiftet fortegn) if (dDeltaFi * dfi < 0.0) { LC_PutGi(1,".KURVE"); } else { // Sjekk at buen ikke har blitt en rett linje etter avrunding til aktuell enhet. LC_GetTK(1,&a1,&n1); LC_GetTK((Sys.pGrInfo->nko+1)/2,&dAMidt,&dNMidt); LC_GetTK(Sys.pGrInfo->nko,&a2,&n2); GM_fotp(a1,n1,a2,n2,dAMidt,dNMidt,&dAFotP,&dNFotP); // Avstand fra fotpunktet til punktet på buen må være minst en enhet if(GM_Avstand(dAMidt,dNMidt,dAFotP,dNFotP) < Sys.pGrInfo->dEnhet) { LC_PutGi(1,".KURVE"); } } } else { LC_PutGi(1,".KURVE"); } } /* AR-930803 CH LC_SammenfoyGr Sammenføy grupper CD ========================================================================== CD Formål: CD Sammenføye to grupper. CD Kopierer koordinater fra gitt gruppe inn i aktuell gruppe. CD De kopierte koordinatene kommer som en utvidelse av gruppen. CD Rutinen tildeler selv nødvendig plass i buffer. CD Kvalitet og enhet blir automatisk oppdatert slik at gruppene ikke CD mister informasjon. CD Gruppen det kopieres fra blir slettet. CD Eventuelle referanser til gruppene blir oppdatert. CD CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_BGR * pFraBgr i Gruppenummer det skal kopieres fra. CD short retning i Buffer-retning: CD HENT_FORRFRA ( 1) = vanlig, CD HENT_BAKFRA (-1) = buffer skal snues. CD short plassering i Forteller hvor pFraBgr skal plasseres i CD aktuell gruppe. CD LC_SG_FORRAN = Heng den andre gruppen inn CD forran første koordinat. CD LC_SG_BAK = Heng den andre gruppen inn CD etter siste koordinat. CD short metode i Forteller hva som skal skje med sammenføingspunktene. CD LC_SG_BEHOLD = Begge punktene beholdes. CD LC_SG_FJERN = Bare det ene av punktene beholdes. CD short ngi u Antall GINFO-linjer CD long nko u Antall koordinater CD unsigned short info u Diverse informasjon. (Se under $LENKE) CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=ikke utført. CD CD Bruk: CD sStatus = LC_SammenfoyGr(bgr,retning,plassering,metode,&ngi,&nko,&info); ============================================================================= */ SK_EntPnt_FYBA short LC_SammenfoyGr(LC_BGR * pFraBgr,short retning,short plassering,short metode, short *ngi,long *nko,unsigned short *info) { short Endret,gnavn; long FraNko,sTilPkt; LC_BGR AktBgr,FlateBgr; long lAktSnr,lFraSnr; double nva,nvn,oha,ohn; LC_GEO_STATUS GeoStat; LC_POLYGON Pol; LC_OY_ELEMENT * pOE; short sStatus = UT_TRUE; if (Sys.GrId.lNr == INGEN_GRUPPE){ /* Feil ==> Ingen aktuell gruppe */ LC_Error(31,"(LC_SammenfoyGr)",""); sStatus = UT_FALSE; } else { /* Husk aktuell gruppe */ AktBgr = Sys.GrId; lAktSnr = LC_GetSn(); sTilPkt = (plassering == LC_SG_FORRAN)? 1 : (Sys.pGrInfo->nko+1); /* ========= Kopier */ if (LC_CopyCoord(pFraBgr,retning,sTilPkt,ngi,nko,info)) { LC_WxGr(SKRIV_OPTIMALT); /* ========= Oppdater referanser */ LC_RxGr(pFraBgr,LES_OPTIMALT,ngi,&FraNko,info); lFraSnr = LC_GetSn(); LC_GetGrWin(&AktBgr,&nva,&nvn,&oha,&ohn); LC_SBFlate(&GeoStat,LC_FRAMGR,(double)nva,(double)nvn, (double)oha,(double)ohn); if (LC_FFFlate(&GeoStat,&FlateBgr)) { do { if (FlateBgr.pFil == AktBgr.pFil) { /* På samme fil ? */ /* Funnet flate i rett fil, sjekk referansene */ gnavn = LC_RxGr(&FlateBgr,LES_OPTIMALT,ngi,nko,info); if ( gnavn == L_FLATE) { /* Hent referansene */ LC_POL_InitPolygon(&Pol); LC_POL_GetRef(&Pol); /* Ytre avgrensning */ Endret = LB_RensOmkrets(&Pol.HovedPO,lAktSnr,lFraSnr); /* Øyer */ for (pOE = Pol.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) { /* Sjkker en og en øy */ Endret |= LB_RensOmkrets(&pOE->PO,lAktSnr,lFraSnr); } /* Lagre oppdatert referanse */ if (Endret == UT_TRUE) { *ngi = LC_POL_PutRef(&Pol); LC_WxGr(SKRIV_OPTIMALT); } /* Frigi allokerte kjeder */ LC_POL_FrigiPolygon(&Pol); } } } while (LC_FNFlate(&GeoStat,&FlateBgr)); } LC_AvsluttSok(&GeoStat); /* ========= Fjern den kopierte gruppen fra basen */ LC_RxGr(pFraBgr,LES_OPTIMALT,ngi,&FraNko,info); lFraSnr = LC_GetSn(); LC_DelGr(); /* ========= Les inn opprinnelig gruppe igjen */ LC_RxGr(&AktBgr,LES_OPTIMALT,ngi,nko,info); /* ========= Fjerner punkt og fjerner KP fra koblingspunktet */ if (metode == LC_SG_FJERN) { if (plassering == LC_SG_BAK) { LC_PutKp(sTilPkt,0); *nko = LC_DelKoL(sTilPkt-1,1); } else { LC_PutKp(FraNko,0); *nko = LC_DelKoL(FraNko+1,1); } } else { if (plassering == LC_SG_BAK) { LC_PutKp(sTilPkt,0); LC_PutKp(sTilPkt-1,0); } else { LC_PutKp(FraNko,0); LC_PutKp(FraNko+1,0); } } } else { /* For mange koordinater */ sStatus = UT_FALSE; } } return sStatus; } /* AR-930803 CH LB_RensOmkrets Fjerner overflødige referanser CD ========================================================================== CD Formål: CD Fjerner overflødige referanser ved sammenføining av to grupper. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD CD CD CD Bruk: CD Endret = LB_RensOmkrets(&Pol.HovedPO,lAktSnr,lFraSnr); ============================================================================= */ static short LB_RensOmkrets(LC_POL_OMKR * pPO,long lAktSnr,long lFraSnr) { LC_POL_ELEMENT * pPE; if (pPO != NULL) { /* Tilslag på første og siste gruppe */ if (pPO->pForstePE->lSnr == lAktSnr && pPO->pSistePE->lSnr == lFraSnr) { /* Overser siste referansen (kopiert gruppe) */ LC_POL_FjernGruppeOmkrets(pPO, pPO->pSistePE); return UT_TRUE; } else if (pPO->pForstePE->lSnr == lFraSnr && pPO->pSistePE->lSnr == lAktSnr) { /* Overser første referansen (kopiert gruppe) */ LC_POL_FjernGruppeOmkrets(pPO, pPO->pForstePE); return UT_TRUE; } /* Resten av referansene */ for(pPE = pPO->pForstePE; pPE->pNestePE != NULL; pPE = pPE->pNestePE) { if (pPE->lSnr == lAktSnr && pPE->pNestePE->lSnr == lFraSnr) { /* Overser siste referansen (kopiert gruppe) */ LC_POL_FjernGruppeOmkrets(pPO, pPE->pNestePE); return UT_TRUE; } else if (pPE->lSnr == lFraSnr && pPE->pNestePE->lSnr == lAktSnr) { /* Overser første referansen (kopiert gruppe) */ LC_POL_FjernGruppeOmkrets(pPO, pPE); return UT_TRUE; } } } return UT_FALSE; } /* AR:2000-07-28 CH LC_NyGr Ny gruppe i basen CD ========================================================================== CD Formål: CD Lager en ny gruppe i basen, og tildeler serienummer. CD Sjekker at gruppenavnet er lovlig i denne versjon av FYBA. CD Ved feil navn vil ".LINJE" bli valgt. CD Legger inn gruppenavn i buffer. CD Gruppen blir "aktuell" gruppe. CD Sjekker ledig plass både for indeks-fil og sosi-fil. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD char *sosi i Gruppenavn (Eks. ".KURVE") CD LC_BGR * pBgr iu Tildelt gruppenummer i basen CD (Bgr.lNr=INGEN_GRUPPE = Feil, ikke oppretta) CD long snr u Tildelt serienummer CD gnavn short r Gruppenavn. (Se under $LENKE) CD INGEN_GRUPPE hvis det ikke er opprettet noen ny gruppe. CD CD Bruk: CD gnavn = LC_NyGr (pFil,sosi,&Bgr,&snr); ============================================================================= */ SK_EntPnt_FYBA short LC_NyGr (LC_FILADM *pFil,char *sosi,LC_BGR * pBgr,long *snr) { short navn_nr,gilin; unsigned long ulLedigPlass; char szTx[256]; char szSosiNavn[LC_MAX_SOSINAVN_LEN]; short sMetode, sSynbarhet, sHoydeMetode,sNivaa; long lNoyaktighet, lHoydeNoyaktighet; /* Test lovlig filpeker */ LO_TestFilpeker(pFil,"NyGr"); /* Preparer SOSI-navnet */ UT_StrCopy(szSosiNavn,sosi,LC_MAX_SOSINAVN_LEN); UT_StrUpper(szSosiNavn); /* Vanlig base */ if (pFil->pBase->sType == LC_BASE) { // Har aktuell gruppe if (Sys.GrId.lNr != INGEN_GRUPPE) { // Er forrige gruppe endra? if (Sys.sGrEndra != END_UENDRA) { LC_WxGr(SKRIV_OPTIMALT); } } /* Setter: 'ingen aktuell gruppe' */ pBgr->lNr = Sys.GrId.lNr = INGEN_GRUPPE; /* Sjekk om lovlig filnummer */ if (pFil->usLag == LC_SEKV) { LC_Error(37,"(LC_NyGr)",""); Sys.pGrInfo->gnavn = INGEN_GRUPPE; /* Ikke skriveaksess */ //} else if (pFil->sAccess != UT_UPDATE || pFil->lNgisLag == LC_NGIS_LES) { //} else if (pFil->sAccess != UT_UPDATE || strcmp(pFil->szNgisLag,"0") == 0 ) { } else if (pFil->sAccess != UT_UPDATE || ((Sys.sNGISmodus == NGIS_NORMAL) && (strcmp(pFil->szNgisLag,"0")) == 0) ) { LC_Error(38,"(LC_NyGr)",""); Sys.pGrInfo->gnavn = INGEN_GRUPPE; } else { if (pFil->lAntGr < LC_MAX_GRU) { /* Sjekk ledig diskplass for SOSI-filer */ UT_InqAvailSize(pFil->pszNavn,&ulLedigPlass); if (ulLedigPlass < ((unsigned long)LC_MAX_KOORD * (unsigned long)120)) { /* Disken er snart full */ LC_Error(93,"(LB_NyGr)",pFil->pszNavn); } /* Sjekk om navnet finnes */ if (LN_FinnNavn(&pFil->SosiNavn,szSosiNavn,&navn_nr) != 1) { navn_nr = L_LINJE; /* Ukjent gruppenavn ==> Velg ".LINJE" */ } pBgr->pFil = Sys.GrId.pFil = pFil; /* Fil */ pBgr->lNr = Sys.GrId.lNr = pFil->lAntGr++; /* Ant. grupper i basen */ Sys.pGrInfo = LI_AppGrt(pBgr->pFil,pBgr->lNr); LB_ClGr(); Sys.pGrInfo->gnavn = navn_nr; /* Gruppenavn */ Sys.pGrInfo->sosi_st = NY_SOSI_ST; /* Setter start SOSI til ny */ Sys.pGrInfo->rb_st = NY_RB_ST; Sys.pGrInfo->dEnhet = pFil->TransPar.dEnhet; /* Enhet */ Sys.pGrInfo->dEnhetHoyde = pFil->TransPar.dEnhet_h; /* Enhet-H */ Sys.pGrInfo->dEnhetDybde = pFil->TransPar.dEnhet_d; /* Enhet-D */ Sys.pGrInfo->ulPrior[0] = 0UL; /* Prioritetstabell */ Sys.pGrInfo->ulPrior[1] = 0UL; Sys.pGrInfo->ulPrior[2] = 0UL; Sys.pGrInfo->ulPrior[3] = 0UL; /* Nuller brukttabellen */ LI_PutBt(pFil,pBgr->lNr,0L); /* Fjerner fra geogr. søketabell */ Sys.pGrInfo->pRL = NULL; /* Nytt serienummer */ *snr = pFil->lMaxSnr + 1L; /* Legg inn gruppenavn */ LC_AppGiL(); LC_PutGi(1,LN_GetNavn(&pFil->SosiNavn,navn_nr)); LC_PutSn(*snr); /* NGIS-flagg */ //if (pFil->lNgisLag > 0) { if (*pFil->szNgisLag != '\0' && strcmp(pFil->szNgisLag,"0") != 0 ) { // Skriv navnet med hermetegn hvis det er blanke i navnet if (strchr(Sys.GrId.pFil->szNgisLag,' ') != NULL) { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N \"%s\"",pFil->szNgisLag); } else { UT_SNPRINTF(szTx,256,"..NGIS-FLAGG N %s",pFil->szNgisLag); } gilin = LC_AppGiL(); LC_PutGi(gilin,szTx); } /* ------------ Legg inn div. standardopplysninger */ if (*Sys.GrId.pFil->szNgisLag != '\0' && strcmp(Sys.GrId.pFil->szNgisLag,"0") != 0 ) { /* ..KVALITET */ sNivaa = 1; LC_GetCurKvalitet(pFil,&sNivaa,1,&sMetode,&lNoyaktighet, &sSynbarhet,&sHoydeMetode,&lHoydeNoyaktighet); UT_SNPRINTF(szTx,256,"..KVALITET %s", LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet, sHoydeMetode,lHoydeNoyaktighet) ); LC_PutGi(LC_AppGiL(),szTx); // ..DATO if (*Sys.GrId.pFil->szDato != '\0' && *Sys.GrId.pFil->szDato != '*' && *Sys.GrId.pFil->szDato < '4') { UT_SNPRINTF(szTx,256,"..DATO %s",pFil->szDato); LC_PutGi(LC_AppGiL(),szTx); } // ..SOSI-VERSJON //UT_SNPRINTF(szTx,256,"..SOSI-VERSJON %.2f",((double)(pFil->sSosiVer))/100.0); //LC_PutGi(LC_AppGiL(),szTx); } /* PINFO-buffer */ Sys.sPibufStatus = LC_PIBUF_TOM; } else{ /* For mange grupper, tab. sprengt */ UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",pFil->lAntGr); LC_Error(39,"(LC_NyGr)",err().tx); Sys.pGrInfo->gnavn = INGEN_GRUPPE; } } } else{ /* Kladdebase */ /* Rens bort gammelt innhold i buffergruppen */ LC_DelKoL(1,Sys.pGrInfo->nko); LC_DelGiL(2,(short)(Sys.pGrInfo->ngi-1)); /* Sjekk om navnet finnes */ if (LN_FinnNavn(&Sys.GrId.pFil->SosiNavn,sosi,&navn_nr) != 1) { LC_PutGi(1,".LINJE"); /* Ukjent gruppenavn ==> Velg ".LINJE" */ } else { LC_PutGi(1,szSosiNavn); } /* Nytt serienummer */ *snr = NYTT_SNR; /* Nullstill info */ Sys.pGrInfo->info = 0; } return (Sys.pGrInfo->gnavn); } /* AR-911001 CH LB_FormaterEnhet Lag GINFO for enhet CD ============================================================================= CD Formål: CD Legger inn enhet med høvelig antall siffer. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD char *streng i Peker til streng hvor ginfo skal legges CD char *sosi i SOSI-navn som skal legges først i strengen CD double enhet i Aktuell enhet CD char *ginfo r Peker til oppbygd streng CD CD Bruk: CD LB_FormaterEnhet(streng,sStrengMaxLen,"..ENHET",enhet); ============================================================================= */ char *LB_FormaterEnhet(char *streng,short sStrengMaxLen,char *SosiNavn,double enhet) { char enhet_buffer[20],*cp; short sAntDes = fymax(1,UT_RoundDS(fabs(fymin(1.0,log10(enhet))))); UT_StrCopy(streng,SosiNavn,sStrengMaxLen); UT_StrCat(streng," ",sStrengMaxLen); UT_DtoA(enhet,sAntDes,'.',20,enhet_buffer); cp = enhet_buffer; while (*cp == ' ') cp++; UT_StrCat(streng,cp,sStrengMaxLen); return(streng); } /* AR-930611 CH LC_InsGiL Skyt inn GINFO-linjer CD ============================================================================= CD Formål: CD Skyter inn linjer GINFO-delen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD short linje i Linjenummer linjen skal skytes inn forran. CD (Lovlig: 1 til ngi+1) CD short antall i Antall linjer som skal skytest inn. CD short ngi r Antall GINFO-linjer i gruppen etter innskuddet. CD CD Bruk: CD ngi = LC_InsGiL(linje, antall); ============================================================================= */ SK_EntPnt_FYBA short LC_InsGiL(short linje, short antall) { short s,len; if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */ if (linje > 0 && linje <= (Sys.pGrInfo->ngi + 1)) { /* På slutten av GINFO */ if (linje == (Sys.pGrInfo->ngi + 1)) { for ( ; antall > 0; antall--) { LC_AppGiL(); } /* Inni GINFO */ } else { Sys.sGrEndra = (short)END_ENDRA; /* Må flytte resten av buffer for å gi plass til de nye linjene */ memmove(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1] + antall, Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1], Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[linje-1]); /* Ny total GINFO-lengde; */ Sys.pGrInfo->ulGiLen += antall; /* Antall GINFO-linjer etter utvidelsen */ Sys.pGrInfo->ngi += antall; /* Oppdater offset for resten av GINFO */ for (s=Sys.pGrInfo->ngi; s>=linje+antall; s--) { Sys.Ginfo.ulOfset[s-1] = Sys.Ginfo.ulOfset[s-1-antall] + antall; } /* Blank ut de nye linjene */ for (s=0; sngi); } /* AR-930610 CH LC_AppGiL Heng på en GINFO-linje CD ============================================================================= CD Formål: CD Henger på en linje i GINFO-delen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD short ngi r Antall GINFO-linjer i gruppen etter utvidelsen. CD (Linjenumret på den tilføyde linjen.) CD CD Bruk: CD ngi = LC_AppGiL(); ============================================================================= */ SK_EntPnt_FYBA short LC_AppGiL() { if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */ Sys.sGrEndra = (short)END_ENDRA; Sys.pGrInfo->ngi++; /* Antall GINFO-linjer etter utvidelsen */ /* Blank ut den nye linjen */ Sys.pGrInfo->ulGiLen++; Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1] = Sys.pGrInfo->ulGiLen - 1; *(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1]) = '\0'; } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_InsGiL)",""); } return(Sys.pGrInfo->ngi); } /* AR-930611 CH LC_InsKoL Skyt inn koordinatlinjer CD ========================================================================== CD Formål: CD Skyter inn linjer koordinatdelen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD long linje i Linjenummer linjen skal skytes inn forran. CD (Lovlig: 1 til nko+1) CD long antall i Antall linjer som skal skytest inn. CD long nko r Antall koordinater i gruppen etter innskuddet. CD CD Bruk: CD nko = LC_InsKoL(linje, antall); ========================================================================== */ SK_EntPnt_FYBA long LC_InsKoL(long linje, long antall) { double *pdAust = Sys.pdAust + linje - 1; double *pdNord = Sys.pdNord + linje - 1; LB_INFO * pInfo = Sys.pInfo + linje - 1; if (Sys.GrId.lNr != INGEN_GRUPPE) { /* AKtuell gruppe OK */ if (Sys.pGrInfo->nko + antall < LC_MAX_KOORD) { if (linje > 0 && linje <= (Sys.pGrInfo->nko + 1)) { Sys.sGrEndra = (short)END_ENDRA; if (linje <= Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM; /* Utfør flyttingen */ memmove(pdAust+antall, pdAust, (Sys.pGrInfo->nko-linje+1) * (sizeof(double))); memmove(pdNord+antall, pdNord, (Sys.pGrInfo->nko-linje+1) * (sizeof(double))); memmove(pInfo+antall, pInfo, (Sys.pGrInfo->nko-linje+1) * (sizeof(LB_INFO))); /* Antall koordinater etter utvidelsen */ Sys.pGrInfo->nko += antall; /* Blank ut det nye området */ while (antall > 0) { *pdAust = 0.0; *pdNord = 0.0; pInfo->dHoyde = HOYDE_MANGLER; pInfo->sKp = 0; pInfo->ulPiOfset = LC_INGEN_PINFO; pdAust++; pdNord++; pInfo++; antall--; } } else { UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",linje); LC_Error(41,"(LC_InsKoL)",err().tx); } } else { /* For mange koordinater */ LC_Error(162,"(LC_InsKoL)",LX_GetGi(1)); } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_InsKoL)",""); } return(Sys.pGrInfo->nko); } /* AR-911001 CH LC_AppKoL Heng på en koordinatlinje CD ========================================================================== CD Formål: CD Henger på en linje i koordinatdelen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD long nko r Antall koordinater i gruppen etter utvidelsen. CD CD Bruk: CD nko = LC_AppKoL(); ========================================================================== */ SK_EntPnt_FYBA long LC_AppKoL() { if (Sys.GrId.lNr != INGEN_GRUPPE) { /* AKtuell gruppe OK */ if (Sys.pGrInfo->nko + 1 < LC_MAX_KOORD) { Sys.sGrEndra = (short)END_ENDRA; Sys.pGrInfo->nko++; /* Antall koordinater etter utvidelsen */ /* Blank ut den nye linjen */ *(Sys.pdAust+Sys.pGrInfo->nko - 1) = 0.0; *(Sys.pdNord+Sys.pGrInfo->nko - 1) = 0.0; (Sys.pInfo+Sys.pGrInfo->nko - 1)->dHoyde = HOYDE_MANGLER; (Sys.pInfo+Sys.pGrInfo->nko - 1)->sKp = 0; (Sys.pInfo+Sys.pGrInfo->nko - 1)->ulPiOfset = LC_INGEN_PINFO; } else { /* For mange koordinater */ LC_Error(162,"(LC_AppKoL)",LX_GetGi(1)); } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_AppKoL)",""); } return(Sys.pGrInfo->nko); } /* AR-930611 CH LC_DelGiL Fjern GINFO-linjer CD ============================================================================= CD Formål: CD Fjerner linjer i GINFO-delen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD short linje i Første linjenummer som skal fjernes. CD (Lovlig: 2 til ngi) CD short antall i Antall linjer som skal fjernes. CD short ngi r Antall GINFO-linjer i gruppen etter setting. CD CD Bruk: CD ngi = LC_DelGiL(linje, antall); ============================================================================= */ SK_EntPnt_FYBA short LC_DelGiL(short linje, short antall) { short start; char *pszTil, *pszFra; if (Sys.GrId.lNr != INGEN_GRUPPE) { /* AKtuell gruppe OK */ if (antall > 0) { Sys.sGrEndra = (short)END_ENDRA; start = fymax(linje,2); /* 2 er første lovlige linje */ antall -= (start-linje); /* Juster antall tilsvarende */ /* Max antall er resten av GINFO */ antall = fymin(start+antall-1,Sys.pGrInfo->ngi) - start + 1; if (start+antall <= Sys.pGrInfo->ngi) { /* Beregn forflytting */ pszTil = Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[start-1]; pszFra = Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[start+antall-1]; /* Utfør flyttingen */ memmove(pszTil, pszFra, Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[start+antall-1] + 1); /* Antall GINFO-linjer etter slettingen */ Sys.pGrInfo->ngi -= antall; /* Ny total GINFO-lengde; */ Sys.pGrInfo->ulGiLen -= (unsigned long)(pszFra - pszTil); /* Oppdater offset for resten av GINFO */ LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi); /* Fjerner fram til slutten av GINFO */ } else { /* Antall GINFO-linjer etter slettingen */ Sys.pGrInfo->ngi -= antall; /* Ny total GINFO-lengde; */ Sys.pGrInfo->ulGiLen = Sys.Ginfo.ulOfset[start-1]; } } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_DelGiL)",""); } return (Sys.pGrInfo->ngi); } /* AR:2008-04-09 CH LC_DelGiNavn Fjerner egenskap fra GINFO CD ========================================================================== CD Formål: CD Fjerner alle forekomster av gitt egenskap (SOSI-navn) fra GINFO. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD char *pszEgenskapNavn i SOSI-navn som skal slettes CD short ngi r Antall GINFO-linjer i gruppen etter setting CD CD Bruk: CD ngi = LC_DelGiNavn("..RADIUS"); ========================================================================== */ SK_EntPnt_FYBA short LC_DelGiNavn(char *pszEgenskapNavn) { short sGiLinje = 2; while (LC_GetGP(pszEgenskapNavn,&sGiLinje,Sys.pGrInfo->ngi) != NULL) { LC_DelGiL(sGiLinje,1); } return Sys.pGrInfo->ngi; } /* AR-930611 CH LC_DelKoL Fjern koordinatlinjer CD ============================================================================= CD Formål: CD Fjerner linjer koordinatdelen i en gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD long linje i Første linje som skal fjernes. CD (Lovlig: 1 til nko) CD long antall i Antall linjer som skal fjernes.(Max resten av gruppen) CD long nko r Antall koordinater i gruppen etter blanking. CD CD Bruk: CD nko = LC_DelKoL(linje, antall); ============================================================================= */ SK_EntPnt_FYBA long LC_DelKoL(long linje, long antall) { long start,s; double *pdAust, *pdNord; LB_INFO * pInfo,*pI; unsigned long ulP1,ulP2,ulDelta; /* UT_FPRINTF(stderr,"DelKoL: %hd - %hd (%hd) \n",linje,antall,Sys.GrInfo.nko); */ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* AKtuell gruppe OK */ Sys.sGrEndra = (short)END_ENDRA; if (linje <= Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM; start = fymax(linje,1); /* 1 er første lovlige linje */ antall -= (start-linje); /* Juster antall tilsvarende */ /* Max antall er resten av punktene */ antall = fymin(start+antall-1,Sys.pGrInfo->nko) - start + 1; /* UT_FPRINTF(stderr," %hd - %hd\n",start,antall); */ if (antall > 0) { pdAust = Sys.pdAust + start - 1; pdNord = Sys.pdNord + start - 1; pInfo = Sys.pInfo + start - 1; /* Pakk PINFO-bufferet */ /* Har gruppen PINFO */ if (Sys.pGrInfo->ulPiLen > 0) { /* Er det PINFO på de punktene som er slettet? */ pI = pInfo; ulP1 = LC_INGEN_PINFO; for (s=0; sulPiOfset != LC_INGEN_PINFO) { ulP1 = pI->ulPiOfset; } } /* Er det funnet PINFO ? */ if (ulP1 != LC_INGEN_PINFO) { /* Sjekk om det er PINFO i resten av gruppen */ pI = pInfo+antall; ulP2 = LC_INGEN_PINFO; for (s=start+antall; s<=Sys.pGrInfo->nko && ulP2==LC_INGEN_PINFO; s++,pI++) { if (pI->ulPiOfset != LC_INGEN_PINFO) { ulP2 = pI->ulPiOfset; } } /* Er det funnet PINFO ? */ if (ulP2 != LC_INGEN_PINFO) { /* Oppdater ofset */ ulDelta = ulP2 - ulP1; pI = pInfo+antall; for (s=start+antall; s <= Sys.pGrInfo->nko; s++,pI++) { if (pI->ulPiOfset != LC_INGEN_PINFO) { pI->ulPiOfset -= ulDelta; } } /* Pakk buffer */ memmove(Sys.pszPinfo+ulP1, Sys.pszPinfo+ulP2, (Sys.pGrInfo->ulPiLen-ulP2) * (sizeof(char))); Sys.pGrInfo->ulPiLen -= ulDelta; /* Det er ikke PINFO i resten av gruppen */ } else { /* Oppdater total PINFO-lengde */ Sys.pGrInfo->ulPiLen = ulP1; } } } /* Utfør flyttingen */ memmove(pdAust, pdAust+antall, (Sys.pGrInfo->nko-start-antall+1) * (sizeof(double))); memmove(pdNord, pdNord+antall, (Sys.pGrInfo->nko-start-antall+1) * (sizeof(double))); memmove(pInfo, pInfo+antall, (Sys.pGrInfo->nko-start-antall+1) * (sizeof(LB_INFO))); /* Antall koordinater etter sletting */ Sys.pGrInfo->nko -= antall; } } else { /* Ingen aktuell gruppe */ LC_Error(49,"(LC_DelKoL)",""); } return(Sys.pGrInfo->nko); } /* AR-930803 CH LB_ClGr Nullstill aktuell gruppe CD ========================================================================== CD Formål: CD Nullstill aktuell gruppe. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD CD Bruk: CD LB_ClGr (); ============================================================================= */ void LB_ClGr (void) { Sys.pGrInfo->ngi = 0; Sys.pGrInfo->nko = 0; Sys.pGrInfo->info = 0; Sys.pGrInfo->ulGiLen = 0; Sys.pGrInfo->ulPiLen = 0; Sys.pGrInfo->szObjtype[0] = '\0'; } /* AR-930610 CH LB_RGru Les gruppe CD ========================================================================== CD Formål: CD Leser en datagruppe fra SOSI-fil inn i aktuell gruppe. CD Eventuelle gamle pekere må være frgitt utenfor denne rutinen. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD UT_INT64 start i Startposisjon på SOSI-filen CD UT_INT64 slutt u Sluttposisjon på SOSI-filen CD short siste_gr r Siste gruppe (0=ikke siste, 1=siste på filen) CD CD Bruk: CD siste_gr = LB_RGru(pFil,start,&slutt); ========================================================================== */ short LB_RGru(LC_FILADM *pFil,UT_INT64 start,UT_INT64 *slutt) { short type,siste,npinf; long snr; char *cp,tx[LC_MAX_SOSI_LINJE_LEN]; LB_LESEBUFFER *pLb = &pFil->pBase->BufAdm; LC_FILADM *pAktFil = Sys.GrId.pFil; LB_INFO *pInfo = NULL; double d; short sLagreNavn; /* Flagg som viser om sosi-navnet skal skrives til buffer */ short sRefFunnet = UT_FALSE; /* Flagg som viser om referanse av ny type (..REF) er funnet i gruppen */ double dEnhet = 0.0; double dEnhet_h = 0.0; double dEnhet_d = 0.0; double dOrigoAust = pFil->TransPar.Origo.dAust; /* Origo til lokale variabler */ double dOrigoNord = pFil->TransPar.Origo.dNord; /* PINFO-buffer er ødelagt */ Sys.sPibufStatus = LC_PIBUF_TOM; /* Angi hvilket tegnsett som skal brukes */ pLb->sTegnsett = pFil->sTegnsett; /* Sett filposisjon */ LO_ReopenSos(pFil); _fseeki64(pFil->pBase->pfSos,start,SEEK_SET); pLb->sStatus = LESEBUFFER_TOM; type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); if (pLb->cur_navn[pLb->cur_niv-1] != L_SLUTT) { /* Ikke lest ".SLUTT" */ /* Sjekk at gruppen har lovlig gruppenavn */ if (type < 0) { UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s %s\"",LN_GetNavn(&(pAktFil->SosiNavn), pLb->cur_navn[pLb->cur_niv-1]),pLb->pp); LC_Error(47,"(LB_RGru)",err().tx); fprintf(stderr,"Error: The library used to stop the program execution here\n"); return 0; } siste = 0; /* Nullstiller gruppen */ LB_ClGr(); /* Legg inn gruppenavnet med serienummer */ Sys.pGrInfo->gnavn = pLb->cur_navn[0]; Sys.pGrInfo->ngi = 1; snr = strtol(pLb->pp,&cp,10); if (Sys.pGrInfo->gnavn != L_HODE) { UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%s %ld:",LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),snr); } else { UT_StrCopy(tx,LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),LC_MAX_SOSI_LINJE_LEN); } UT_StrCopy(Sys.Ginfo.pszTx,tx,LC_MAX_SOSI_LINJE_LEN); *Sys.Ginfo.ulOfset = 0; Sys.pGrInfo->ulGiLen = (unsigned long)strlen(tx) + 1; pLb->set_brukt = SET_BRUKT; /* Leser resten av GINFO */ type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); while (type < LEST_KOORD && pLb->cur_niv > 1) { if (type != LEST_BLANK) { sLagreNavn = UT_TRUE; /* GINFO */ if (type == LEST_GINFO) { /* Referanse */ if (pLb->cur_navn[pLb->cur_niv-1] == L_REF1 || pLb->cur_navn[pLb->cur_niv-1] == L_REF2) { Sys.pGrInfo->info |= GI_REF; if (LN_TestOy(pLb->pp)) Sys.pGrInfo->info |= GI_OY_REF; /* ..REF skal skrives bare på første linje med referanser */ if (pLb->cur_navn[pLb->cur_niv-1] == L_REF2 && sRefFunnet == UT_TRUE) { sLagreNavn = UT_FALSE; } #ifdef UTGAAR /* Gruppen har høyde informasjon */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_HOYDE) { Sys.pGrInfo->info |= GI_NAH; /* Husk at gruppen har høyde */ #endif /* Spesiell "..ENHET" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2) { dEnhet = strtod(pLb->pp,&cp); /* Spesiell "..ENHET-H" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2H) { dEnhet_h = strtod(pLb->pp,&cp); /* Spesiell "..ENHET-D" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET2D) { dEnhet_d = strtod(pLb->pp,&cp); /* Spesiell "...ENHET" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3) { dEnhet = strtod(pLb->pp,&cp); /* Spesiell "...ENHET-H" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3H) { dEnhet_h = strtod(pLb->pp,&cp); /* Spesiell "...ENHET-D" */ } else if (pLb->cur_navn[pLb->cur_niv-1] == L_ENHET3D) { dEnhet_d = strtod(pLb->pp,&cp); } /* Bygg opp GINFO-strengen for denne linjen */ if (sLagreNavn == UT_TRUE) { UT_StrCopy(tx,LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[pLb->cur_niv-1]),LC_MAX_SOSI_LINJE_LEN); } else { *tx = '\0'; } if (sLagreNavn == UT_TRUE && *(pLb->pp) != '\0') { UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN); } if (*(pLb->pp) != '\0') { UT_StrCat(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN); } /* Husk at det er funnet ny type referanse */ if (pLb->cur_navn[pLb->cur_niv-1] == L_REF2) { sRefFunnet = UT_TRUE; /* Viser at referanse av ny type (..REF) er funnet */ } // Husk OBJTYPE if (pLb->cur_navn[pLb->cur_niv-1] == L_OBJTYPE) { UT_StrCopy(Sys.pGrInfo->szObjtype,pLb->pp,LC_MAX_OBJTYPE_LEN); } /* Kommentar */ } else { UT_StrCopy(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN); } /* GINFO og kommentar-linje lagres */ if (Sys.pGrInfo->ngi >= LC_MAX_GINFO) { LC_Error(149,"(LB_RGru)",Sys.Ginfo.pszTx); } else if ((Sys.pGrInfo->ulGiLen + strlen(tx) + 1) >= LC_MAX_GINFO_BUFFER) { LC_Error(150,"(LB_RGru)",Sys.Ginfo.pszTx); } else { Sys.pGrInfo->ngi++; UT_StrCopy(Sys.Ginfo.pszTx + Sys.pGrInfo->ulGiLen, tx,LC_MAX_SOSI_LINJE_LEN); Sys.Ginfo.ulOfset[Sys.pGrInfo->ngi - 1] = Sys.pGrInfo->ulGiLen; Sys.pGrInfo->ulGiLen += (unsigned long)strlen(tx) + 1; } } // Hent neste linje pLb->set_brukt = SET_BRUKT; type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); } // Enhet er ikke gitt i GINFO, bruk filhodets enhet if (dEnhet == 0.0) dEnhet = pFil->TransPar.dEnhet; // Enhet-H er ikke gitt i GINFO brukes enhet-H fra filhodet if (dEnhet_h == 0.0) dEnhet_h = pFil->TransPar.dEnhet_h; // Enhet-D er ikke gitt i GINFO brukes enhet-D fra filhodet if (dEnhet_d == 0.0) dEnhet_d = pFil->TransPar.dEnhet_d; /* Husk aktuell ENHET */ Sys.pGrInfo->dEnhet = dEnhet; Sys.pGrInfo->dEnhetHoyde = dEnhet_h; Sys.pGrInfo->dEnhetDybde = dEnhet_d; /* Koordinatdelen */ while (pLb->cur_niv >= 2) { if (type != LEST_BLANK && type != LEST_KOM) { /* Sjekk at det ikke kommer GINFO innimellom koordinatene */ /* Ikke NØ eller NØH */ if (pLb->cur_niv == 2 && pLb->cur_navn[pLb->cur_niv-1] != L_NAH && pLb->cur_navn[pLb->cur_niv-1] != L_NAD && pLb->cur_navn[pLb->cur_niv-1] != L_NA) { char szMelding[256]; UT_SNPRINTF(szMelding,256,"Egenskap \"%s\" i \"%s\"",pLb->tx,Sys.Ginfo.pszTx); LC_Error(144,"(LB_RGru)",szMelding); } /* Sjekk at det ikke blir for mange koordinater */ if (Sys.pGrInfo->nko >= LC_MAX_KOORD) { UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s %ld:\"",LN_GetNavn(&pAktFil->SosiNavn,pLb->cur_navn[0]),snr); LC_Error(148,"(LB_RGru)",err().tx); } if (*pLb->pp != '\0') { Sys.pGrInfo->nko++; pInfo = Sys.pInfo + Sys.pGrInfo->nko - 1; /* Regn om til basekoordinater og legg inn i buffer */ /* Nord-koordinaten */ d = strtod(pLb->pp,&cp); *(Sys.pdNord + Sys.pGrInfo->nko - 1) = dOrigoNord + (d * dEnhet); /* Øst-koordinaten */ d = strtod(cp,&cp); *(Sys.pdAust + Sys.pGrInfo->nko - 1) = dOrigoAust + (d * dEnhet); /* ..NØH */ if (pLb->cur_navn[pLb->cur_niv-1] == L_NAH) { Sys.pGrInfo->info |= GI_NAH; /* Husk at gruppen har høyde */ /* Regn om høyden */ d = strtod(cp,&cp); pInfo->dHoyde = d * dEnhet_h; } /* ..NØD */ else if (pLb->cur_navn[pLb->cur_niv-1] == L_NAD) { Sys.pGrInfo->info |= GI_NAD; /* Husk at gruppen har dybde */ /* Regn om dybden (Lagres som terrengverdi i mm) */ d = strtod(cp,&cp); pInfo->dHoyde = d * dEnhet_d; } else { pInfo->dHoyde = HOYDE_MANGLER; } } pLb->set_brukt = SET_BRUKT; /* Neste sett */ type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); /* PINFO */ if (Sys.pGrInfo->nko > 0) { pInfo->sKp = 0; pInfo->ulPiOfset = LC_INGEN_PINFO; npinf = 0; *tx = '\0'; while (pLb->cur_niv > 2) { if (type != LEST_BLANK && type != LEST_KOM) { if (pLb->cur_navn[pLb->cur_niv-1] == L_KP) { /* Knutepunkt */ /* Sjekk om det er flere kp i samme punkt */ if (pInfo->sKp != 0) { //UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\"",pLb->pp); UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\" pnr.: %ld ",LX_GetGi(1), Sys.pGrInfo->nko); LC_Error(145,"(LB_RGru)",err().tx); } else { pInfo->sKp = (short)strtol(pLb->pp,&cp,10); Sys.pGrInfo->info |= GI_KP; } } else { /* Annen PINFO */ npinf++; if (npinf > 1) UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN); UT_StrCat(tx, LN_GetNavn(&(pAktFil->SosiNavn),pLb->cur_navn[pLb->cur_niv-1]), LC_MAX_SOSI_LINJE_LEN); if (*(pLb->pp) != '\0'){ UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN); UT_StrCat(tx,pLb->pp,LC_MAX_SOSI_LINJE_LEN); } if (strlen(tx) > LC_MAX_SOSI_LINJE_LEN) { tx[30] = '\0'; LC_Error(143,"(LB_RGru)",tx); tx[0] = '\0'; npinf = 0; } } } pLb->set_brukt = SET_BRUKT; /* Neste sett */ type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); } /* Lagre PINFO */ if (*tx != '\0') { if (Sys.pGrInfo->ulPiLen == 0) { pInfo->ulPiOfset = 0; } else { pInfo->ulPiOfset = Sys.pGrInfo->ulPiLen; } if ((Sys.pGrInfo->ulPiLen + strlen(tx) + 1) >= LC_MAX_PINFO_BUFFER) { LC_Error(161,"(LB_RGru)",Sys.Ginfo.pszTx); } else { UT_StrCopy(Sys.pszPinfo + pInfo->ulPiOfset, tx, LC_MAX_PINFO_BUFFER-pInfo->ulPiOfset); Sys.pGrInfo->ulPiLen += (unsigned long)strlen(tx) + 1; } Sys.pGrInfo->info |= GI_PINFO; } } } else { /* Fyll-linje er lest */ pLb->set_brukt = SET_BRUKT; /* Neste sett */ type = LB_GetSet(pFil->pBase->pfSos,pLb,&(pAktFil->SosiNavn)); } } } else { /* ".SLUTT" */ siste = 1; } if (Sys.pGrInfo->gnavn == L_HODE && !siste ) { /* Oppdater filtabellen */ LO_BeFt(pFil); } *slutt = pLb->startpos; /* Slutt - filposisjon */ return(siste); } /* AR-911001 CH LB_Save Tøm skrivekøa for 1 fil CD ========================================================================== CD Formål: CD Skriver gruppene som ligger i skrivekø ut til SOSI-fil. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD CD Bruk: CD LB_Save(pFil); ========================================================================== */ void LB_Save(LC_FILADM *pFil) { LC_BGR Bgr,AktBgr; long lNr; short ngi; long nko; unsigned short info; Bgr.pFil = pFil; if (Sys.lAntSkriv > 0L) { /* Er det noen i kø ? */ AktBgr = Sys.GrId; for (lNr=0L; lNrlAntGr; lNr++) { if (LI_InqBt(pFil,lNr,BT_SKRKO)) { /* I kø ? */ Bgr.lNr = lNr; LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); LB_Swap(); } } if (AktBgr.lNr != INGEN_GRUPPE) { LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info); } else { Sys.GrId = AktBgr; } } } /* AR-911001 CH LC_Save Tøm skrivekøa CD ========================================================================== CD Formål: CD Skriver gruppene som ligger i skrivekø ut til SOSI-fil. CD CD Parametre: ingen CD CD Bruk: CD LC_Save(); ========================================================================== */ SK_EntPnt_FYBA void LC_Save(void) { LC_BASEADM * pBase; LC_FILADM *pFil; if (Sys.lAntSkriv > 0L) { /* Er det noen i kø ? */ /* Skanner alle baser og alle filer */ for (pBase=Sys.pForsteBase; pBase!=NULL; pBase=pBase->pNesteBase) { for (pFil=pBase->pForsteFil; pFil!=NULL; pFil=pFil->pNesteFil) { LB_Save(pFil); } LO_CloseSos(pBase); } Sys.lAntSkriv = 0L; } } /* AR-930610 CH LB_Swap Dump gruppe fra buffer til SOSI CD ========================================================================== CD Formål: CD Skriver en gruppe fra buffer tilbake til SOSI-fil. Ledig plass fram til CD neste gruppe blir blanket. Hvis det ikke er plass blir gruppen flyttet CD til slutten av filen. Fjerner gruppen fra skrivekøa. CD CD Parametre: ingen CD CD Bruk: CD LB_Swap() ========================================================================== */ void LB_Swap(void) { short siste; long nko; UT_INT64 start,neste; /* Filnummer og posisjon */ start = Sys.pGrInfo->sosi_st; nko = Sys.pGrInfo->nko; if (start == NY_SOSI_ST){ /* Ny gruppe? */ siste = 1; /* På slutten */ start = Sys.GrId.pFil->n64AktPos; } else{ siste = LB_Plass(Sys.GrId.pFil,start,&neste); /* Finn ledig plass */ } /* Ikke siste gruppe */ if ( ! siste ) { /* Skriver */ if ( ! LB_WGru(SKRIV_VANLIG,1,nko,Sys.GrId.pFil,start,&neste)) { /* For lite plass, blank ut "gammelt" området på SOSI-filen */ _fseeki64(Sys.GrId.pFil->pBase->pfSos,start,SEEK_SET); Sys.GrId.pFil->pBase->BufAdm.sStatus = LESEBUFFER_TOM; LB_WriteBlank(Sys.GrId.pFil->pBase->pfSos,Sys.GrId.pFil->sTegnsett,neste); /* Blank ut området */ /* Gruppen skrives på slutten av SOSI-filen */ siste = 1; start = Sys.GrId.pFil->n64AktPos; } } /* Siste gruppe på SOSI-filen */ if ( siste ) { Sys.pGrInfo->sosi_st = start; /* Ny filposisjon */ neste = LLONG_MAX; /* Skriver */ LB_WGru (SKRIV_SISTE,1,nko,Sys.GrId.pFil,start,&neste); Sys.GrId.pFil->n64AktPos = neste; /* Ny slutt-posisjon */ } LI_ClrBt(Sys.GrId.pFil,Sys.GrId.lNr,BT_SKRKO); /* Fjern fra skrivekø */ } /* AR-930610 CH LB_WGru Skriv gruppe til SOSI-fil CD ========================================================================== CD Formål: CD Skriver aktuell gruppe fra buffer til en SOSI-fil. CD Sjekker ikke om buffer er endret i fht. SOSI. (Skriver alltid.) CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD short strategi i Skrivestrategi: Følgende konstanter er definert: CD KONTROLLER_PLASS = Bare kontroller plass, CD (ikke skriv til SOSI). CD SKRIV_VANLIG = Skriv til SOSI, vanlig. CD SKRIV_SISTE = Skriv til SOSI, med .SLUTT CD og sett filstørrelse. CD long fra_punkt i Punktnummer for første koordinat som skal skrives. CD (Lovlig: 1 <= fra_punkt <= nko) CD long antall i Antall koordinatlinjer som skal skrives. CD (Lovlig: 0 <= antall <= nko) CD (Ved skriv av annet enn aktuell gruppe skrives CD alltid hele gruppen.) CD LC_FILADM *pFil i Peker til FilAdm for fil det skal skrives til CD UT_INT64 ffipos i Startposisjon på SOSI-filen CD UT_INT64 *lfipos iu inn: Første pos i neste gruppe (må ikke overskrives) CD ut : Første pos etter gruppen (etter event. utrop.) CD short ist r Status: 1 = Skrevet OK CD 0 = Ikke plass, må flyttes til slutten CD CD Bruk: CD ok = LB_WGru (strategi,fra_punkt,antall,pFil,ffipos,&lfipos); ============================================================================= */ short LB_WGru (short strategi,long fra_punkt,long antall, LC_FILADM *pFil,UT_INT64 ffipos,UT_INT64 *lfipos) { short i,gnavn,ngi,skriv_nah,nah,forrige_nah; long pt,l; unsigned long ulOfset; char tx[LC_MAX_SOSI_LINJE_LEN],*cp,szOrd[60]; char szError[256]; double dN,dA; short sFilMindre; UT_INT64 Size; char szKp[50]; FILE *pfSos = NULL; double dEnhet = 0.0; double dEnhetHoyde = 0.0; double dEnhetDybde = 0.0; double dOrigoNord = pFil->TransPar.Origo.dNord; double dOrigoAust = pFil->TransPar.Origo.dAust; UT_INT64 fpos; UT_INT64 nfipos; /* Neste filposisjon (første etter linjen) */ UT_INT64 afipos = ffipos; /* Aktuell filposisjon */ #ifdef test SH_OutTx(1,1,"WGru:"); SH_OutShort(0,1,1,strategi); SH_OutShort(0,1,3,fra_punkt); SH_OutShort(0,1,4,antall); SH_OutLong(0,1,5,pBgr->lNr); SH_OutTx(0,1,pBgr->pFil->pszNavn); SH_OutTx(0,1,pFil->pszNavn); SH_OutTx(2,1,"ffipos:");SH_OutLong(0,0,10,ffipos); SH_OutTx(0,1,"lfipos:");SH_OutLong(0,0,10,*lfipos); SH_WaitKb(); SH_ErLine(SH_SCR,1); SH_ErLine(SH_SCR,2); #endif /* printf("\nWGru:fra: %s : %ld nko:%ld til %s", strrchr(pBgr->pFil->pszNavn,'\\')+1, pBgr->lNr, antall, strrchr(pFil->pszNavn,'\\')+1); */ /* Hent diverse opplysninger om gruppen */ gnavn = Sys.pGrInfo->gnavn; ngi = Sys.pGrInfo->ngi; /* antall = Sys.pGrInfo->nko; (Ant.koord kommer inn i kallet) */ /* info = Sys.pGrInfo->info; */ if (strategi != KONTROLLER_PLASS) { LO_ReopenSos(pFil); /* Aktiviser SOSI-filen */ pfSos = pFil->pBase->pfSos; _fseeki64 (pfSos, afipos, SEEK_SET); pFil->pBase->BufAdm.sStatus = LESEBUFFER_TOM; } /* Skriv GINFO */ for (i = 1; i <= ngi; i++) { UT_StrCopy(tx,LX_GetGi(i),LC_MAX_SOSI_LINJE_LEN); UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN); /* Spesiell ..ENHET */ if (LN_Enhet(&(Sys.GrId.pFil->SosiNavn),tx)) { cp = tx; while(!UT_IsSpace(*cp)){ cp++; } dEnhet = strtod(cp,&cp); } /* Spesiell ..ENHET-H */ if (LN_EnhetHoyde(&(Sys.GrId.pFil->SosiNavn),tx)) { cp = tx; while(!UT_IsSpace(*cp)){ cp++; } dEnhetHoyde = strtod(cp,&cp); } /* Spesiell ..ENHET-D */ if (LN_EnhetDybde(&(Sys.GrId.pFil->SosiNavn),tx)) { cp = tx; while(!UT_IsSpace(*cp)){ cp++; } dEnhetDybde = strtod(cp,&cp); } /* GINFO, og kommentar-linje lagres */ /* * Sjekk om plassen er oppbrukt. * (Overskriver neste guppe.) */ nfipos = afipos + (long)strlen(tx); while (nfipos > *lfipos) { if (gnavn == L_HODE) { /* Prøver å flytte gruppen til slutten */ if (!LB_FlyttGrTilSlutt(pFil,*lfipos,lfipos)) { LC_Error(146,"(LB_WGru)",pFil->pszNavn); return 1; } } else { return 0; } } /* Skriv til SOSI */ if (strategi != KONTROLLER_PLASS) { LB_WriteLine(pfSos,pFil->sTegnsett,tx); } afipos = nfipos; } /* Enhet er ikke gitt i GINFO, bruk filhodets enhet */ if (dEnhet == 0.0) dEnhet = pFil->TransPar.dEnhet; // Enhet-H er ikke gitt i GINFO, bruk enhet-H fra filhodet if (dEnhetHoyde == 0.0) dEnhetHoyde = pFil->TransPar.dEnhet_h; // Enhet-D er ikke gitt i GINFO, bruk enhet-D fra filhodet if (dEnhetDybde == 0.0) dEnhetDybde = pFil->TransPar.dEnhet_d; /* Hopp fram til første koordinat som skal skrives */ pt = fra_punkt - 1; forrige_nah = -1; skriv_nah = 1; /* Skriv ..NØ(H) før første koordinat linje */ /* =====> Skriv koordinater og PINFO */ for (l=0; ldHoyde != HOYDE_MANGLER); /* Må skrive ..NØ eller ..NØH ved skifte mellom disse */ if (forrige_nah != nah) { skriv_nah = 1; } if (skriv_nah) { /* Skriv ..NØ / ..NØH / ..NØD */ if (nah) { if ((Sys.pGrInfo->info & GI_NAH) != 0) { UT_StrCopy(tx,"..NØH\r\n",LC_MAX_SOSI_LINJE_LEN); } else { UT_StrCopy(tx,"..NØD\r\n",LC_MAX_SOSI_LINJE_LEN); } nfipos = afipos + 7; } else { UT_StrCopy(tx,"..NØ\r\n",LC_MAX_SOSI_LINJE_LEN); nfipos = afipos + 6; } forrige_nah = nah; if (nfipos > *lfipos) { /* Sjekk om plassen er oppbrukt */ return(0); /* Overskriver neste guppe */ } if (strategi != KONTROLLER_PLASS) { LB_WriteLine(pfSos,pFil->sTegnsett,tx); /* Skriv til SOSI */ } afipos = nfipos; skriv_nah = 0; } /* -----> Koordinater */ dN = UT_RoundDD((*(Sys.pdNord+pt) - dOrigoNord) / dEnhet); dA = UT_RoundDD((*(Sys.pdAust+pt) - dOrigoAust) / dEnhet); UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%.0f %.0f",dN,dA); // ----- Høyde eller dybde if (nah) { // NØH if ((Sys.pGrInfo->info & GI_NAH) != 0) { dA = UT_RoundDD((Sys.pInfo+pt)->dHoyde / dEnhetHoyde); } // NØD else { dA = UT_RoundDD((Sys.pInfo+pt)->dHoyde / dEnhetDybde); } UT_SNPRINTF(szOrd,60," %.0f",dA); UT_StrCat(tx,szOrd,LC_MAX_SOSI_LINJE_LEN); } // ----- PINFO ulOfset = (Sys.pInfo+pt)->ulPiOfset; if (ulOfset != LC_INGEN_PINFO) { skriv_nah = 1; UT_StrCat(tx," ",LC_MAX_SOSI_LINJE_LEN); UT_StrCat(tx,Sys.pszPinfo+ulOfset,LC_MAX_SOSI_LINJE_LEN); } // ----- ...KP n if ((Sys.pInfo+pt)->sKp != 0) { skriv_nah = 1; UT_SNPRINTF(szKp,50," ...KP %hd",(Sys.pInfo+pt)->sKp); UT_StrCat(tx,szKp,LC_MAX_SOSI_LINJE_LEN); } // Sjekk at linjen ikke er for lang if (strlen(tx) > (LC_MAX_SOSI_LINJE_LEN - 10)) { tx[LC_MAX_SOSI_LINJE_LEN -10] = '\0'; UT_StrCat(tx, " ?????", LC_MAX_SOSI_LINJE_LEN); LC_Error(134,"(LB_WGru)",LX_GetGi(1)); } // Legg på linjeslutt UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN); /* Sjekk om plassen er oppbrukt */ nfipos = afipos + (long)strlen(tx); if (nfipos > *lfipos) { /* Overskriver neste guppe */ /* printf(" (Overskriv)"); */ return(0); /* ===> RETUR */ } if (strategi != KONTROLLER_PLASS){ LB_WriteLine(pfSos,pFil->sTegnsett,tx); /* Skriver */ } afipos = nfipos; } if (strategi == SKRIV_SISTE) /* På slutten av filen */ { /* Akt.pos + reserveplass */ *lfipos = _ftelli64(pfSos) + (UT_INT64)Sys.sResPlass; /* Legg på 200 ekstra etter filhodet */ if (ffipos == 0) *lfipos += 200; LB_WriteBlank(pfSos,pFil->sTegnsett,*lfipos); /* Skriver .SLUTT */ UT_StrCopy(tx,".SLUTT\r\n",LC_MAX_SOSI_LINJE_LEN); LB_WriteLine(pfSos,pFil->sTegnsett,tx); /* Husk akt. filposisjon */ fpos = _ftelli64(pfSos); if (fpos == -1) { UT_strerror(szError,256,errno); UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"%s - %s",pFil->pszNavn,szError); LC_Error(142,"(LB_WGru)",tx); } // Sjekk om filstørrelsen er redusert sFilMindre = UT_FALSE; if (Sys.sUtvidModus != LC_UTVID_SIKKER) { if (UT_InqPathSize_i64(pFil->pszNavn,&Size) == 0) { if (fpos <= Size) sFilMindre = UT_TRUE; } } // Filstørrelsen er redusert, eller sikker utvidingsmodus if (sFilMindre == UT_TRUE || Sys.sUtvidModus == LC_UTVID_SIKKER) { /* Steng filen for å bevare byte-pekeren */ LO_CloseSos(pFil->pBase); /* Sett filstørrelse */ if (fpos != -1) { if ((i = UT_SetPathSize_i64(pFil->pszNavn,fpos-1)) != 0) { UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"(%s, Posisjon:%lld, Se log-fil for detaljert beskrivelse)",pFil->pszNavn,fpos-1); LC_Error(92,"(LB_WGru)",tx); } } } } else { if (strategi != KONTROLLER_PLASS) { /* Blank fram til neste gruppe, og tøm buffer */ LB_WriteBlank(pfSos,pFil->sTegnsett,*lfipos); } } /* printf(" (OK)"); */ return(1); } /* AR-920309 CH LB_FlyttGrTilSlutt Flytt gruppe til slutten av filen CD ========================================================================== CD Formål: CD Flytt gruppe til slutten av filen CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD UT_INT64 start i Startposisjon på SOSI-filen (første pos. i gr.) CD UT_INT64 *neste u Startposisjon i neste gruppe (første pos. etter gr.) CD short status r Status: UT_FALSE = Feil CD UT_TRUE = OK CD CD Bruk: CD status = LB_FlyttGrTilSlutt(forste,&neste) ========================================================================== */ static short LB_FlyttGrTilSlutt(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste) { UT_INT64 lCurFilpos; long lAntTegn,lNr; char *pszBuffer; LC_GRTAB_LINJE * pGrInfo; /* Husk aktuell filposisjon */ lCurFilpos = _ftelli64(pFil->pBase->pfSos); /* Sjekk gruppetabellen for å finne hvilken gruppe */ /* som starter i start posisjonen. */ for (lNr=1L; lNrlAntGr; lNr++) { pGrInfo = LI_GetGrt(pFil,lNr); if (pGrInfo->ngi != 0) { if (pGrInfo->sosi_st == start) { /* Oppdater startposisjon */ pGrInfo->sosi_st = pFil->n64AktPos; break; } } } /* Finn starten av neste gruppe */ LB_Plass (pFil,start,neste); /* Alloker buffer for flyttingen */ lAntTegn = (long)(*neste - start); pszBuffer = (char*)UT_MALLOC((size_t)lAntTegn * sizeof(char)); /* Les inn gruppen */ _fseeki64(pFil->pBase->pfSos,start,SEEK_SET); fread(pszBuffer,sizeof(char),(size_t)lAntTegn,pFil->pBase->pfSos); /* Skriv gruppen */ _fseeki64(pFil->pBase->pfSos,pFil->n64AktPos,SEEK_SET); fwrite(pszBuffer,sizeof(char),(size_t)lAntTegn,pFil->pBase->pfSos); /* Ny sluttposisjon */ pFil->n64AktPos = _ftelli64(pFil->pBase->pfSos); /* Skriver .SLUTT */ UT_StrCopy(pszBuffer,".SLUTT\r\n",lAntTegn); LB_WriteLine(pFil->pBase->pfSos,pFil->sTegnsett,pszBuffer); UT_FREE(pszBuffer); /* Posisjoner tilbake til opprinnelig posisjon */ _fseeki64(pFil->pBase->pfSos,lCurFilpos,SEEK_SET); return UT_TRUE; } /* AR-920309 CH LB_Plass Finn tilgjengelig plass CD ========================================================================== CD Formål: CD Scanner SOSI-filen og finner hvor mye plass som er tilgjengelig for CD gruppen. (Uten flytting.) CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Peker til FilAdm CD UT_INT64 start i Startposisjon på SOSI-filen (første pos. i gr.) CD UT_INT64 *neste u Startposisjon i neste gruppe (første pos. etter gr.) CD short siste r Siste gruppe: UT_FALSE = Ikke siste gruppe CD UT_TRUE = Siste gruppe CD CD Bruk: CD siste = LB_Plass (pFil,start,&neste) ========================================================================== */ short LB_Plass (LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste) { LB_LESEBUFFER * pLb = &pFil->pBase->BufAdm; LO_ReopenSos(pFil); /* Aktiviser SOSI-filen */ _fseeki64(pFil->pBase->pfSos,start,SEEK_SET); pLb->sStatus = LESEBUFFER_TOM; /* Gruppenavn på egen gruppe */ LB_GetSet(pFil->pBase->pfSos,pLb,&(pFil->SosiNavn)); /* Scann gruppen sett for sett */ do { pLb->set_brukt = SET_BRUKT; LB_GetSet(pFil->pBase->pfSos,pLb,&(pFil->SosiNavn)); } while (pLb->cur_niv != 1); *neste = pLb->startpos; return ((pLb->cur_navn[0] == L_SLUTT)? 1 : 0 ); /* Siste gruppe? */ } /* GL-880119 AR-911001 CH LB_WriteBlank Fyller inn "!!!!!!!" CD ========================================================================== CD Formål: CD Fyller området FRA-OG-MED current-posisjon og fram TIL, CD (men ikke inklusiv) , ltilpos med !!!!!. CD Rutina takler fra 1 til mange posisjoner. CD CD curr-pos ltilpos CD +------------------------------+ CD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD FILE *fil i Filpeker CD short sTegnsett i Tegnsett (Def fra fyut.h) CD long ltilpos i Posisjon det skal blankes fram til CD CD Bruk: CD LB_WriteBlank(fil,sTegnsett,ltilpos); =================================================================== */ static void LB_WriteBlank (FILE *fil,short sTegnsett,UT_INT64 ltilpos) { UT_INT64 fpos; long iant; short i; char buffer[LC_MAX_SOSI_LINJE_LEN] = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n"; fpos = _ftelli64(fil); /* Skriver fulle linjer */ if (ltilpos > fpos){ while (fpos < (ltilpos-40)){ LB_WriteLine(fil,sTegnsett,buffer); fpos = _ftelli64(fil); } /* Skriver resten */ iant = (long)(ltilpos-fpos); if (iant > 2) { /* ant fyll > 2 */ for (i=0 ;( i < (iant - 2)) ; i++) { buffer[i] = '!'; } buffer[iant-2] = '\r'; buffer[iant-1] = '\n'; buffer[iant] = '\0'; LB_WriteLine(fil,sTegnsett,buffer); }else { /* ant fyll = 1 eller 2 */ /* blank sist på forrige linje */ _fseeki64(fil,-2L,SEEK_CUR); if (iant == 1) UT_StrCopy(buffer, " \r\n", LC_MAX_SOSI_LINJE_LEN); else if (iant == 2) UT_StrCopy(buffer, " \r\n", LC_MAX_SOSI_LINJE_LEN); LB_WriteLine(fil,sTegnsett,buffer); } } } /* AR-911001 CH LB_WriteLine Lavnivå skriv tekst linje CD ========================================================================== CD Formål: CD Lavnivå overbygning ove write i C-biblioteket for å skrive en linje. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD FILE *fil i Filpeker CD short sTegnsett i Tegnsett (Spesifisert i UT) CD char *tx i Tekststreng som skal skrives. CD short antall r Antall tegn skrevet, eller -1 ved feil. CD CD Bruk: CD antall = LB_WriteLine(fil,sTegnsett,tx); ========================================================================== */ short LB_WriteLine (FILE *fil,short sTegnsett,char *tx) { UT_KonverterTegnsett(LC_INTERNT_TEGNSETT,sTegnsett,(unsigned char*)tx); return (short)fwrite(tx,strlen(tx),1,fil); } /* AR-920909 CH LB_FyllBuffer Oppdater lesebuffer fra SOSI-filen CD ========================================================================== CD Formål: CD Les neste linje fra SOSI-filen inn i lesebuffer. CD Konverterer til rett internt tegnsett. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD FILE *fil i Filpeker CD LB_LESEBUFFER *plb i Peker til bufferstruktur CD CD Bruk: CD LB_FyllBuffer(fil,&lb); =================================================================== */ void LB_FyllBuffer (FILE *fil,LB_LESEBUFFER *plb) { short ierr; /* Husk filposisjonen */ plb->filpos = _ftelli64(fil); /* Les */ if ((ierr = UT_ReadLine(fil,LC_MAX_SOSI_LINJE_LEN,plb->tx)) != UT_OK) { /* Lesefeil */ if (ierr == UT_EOF) { LC_Error(42,"(LB_FyllBuffer)",""); /* EOF */ } else { LC_Error(43,"(LB_FyllBuffer)",""); /* Annen lesefeil */ } fprintf(stderr,"Error: The library used to stop the program execution here\n"); return; } /* Konverter til rett tegnsett */ UT_KonverterTegnsett(plb->sTegnsett,LC_INTERNT_TEGNSETT,(unsigned char*)plb->tx); if (strlen(plb->tx) >= LC_MAX_SOSI_LINJE_LEN-2) { char szMelding[LC_MAX_SOSI_LINJE_LEN + 10]; UT_SNPRINTF(szMelding, LC_MAX_SOSI_LINJE_LEN + 10, "\"%s\"", plb->tx); LC_Error(164,"(LB_FyllBuffer)",szMelding); fprintf(stderr,"Error: The library used to stop the program execution here\n"); return; } /* Nullstill pekere */ plb->cp = plb->np = plb->pp = plb->ep = plb->tx; plb->set_brukt = SET_BRUKT; plb->sStatus = LESEBUFFER_OK; } /* AR-920909 CH LB_GetSet Hent SOSI-navn og verdi fra buffer CD ============================================================================= CD Formål: CD Hen ett SOSI-navn og tilhørende verdi fra lesebuffer. CD Inn: Hvis buffer har gyldig innhold peker "plb->np" til posisjon CD der tolking skal starte. CD CD Parametre: CD Type Navn I/U Forklaring CD ----------------------------------------------------------------------------- CD FILE *fil i Filpeker CD LB_LESEBUFFER *plb i Peker til bufferstruktur CD LC_NAVNETABELL * pNavn i Peker til navnetabell CD short type r Hva er hentet: >= 0 : Gruppenavn,linjenr CD i navnetab. CD LEST_KOORD (-1): Koordinatlinje CD LEST_BLANK (-2): Fyll-linje CD LEST_GINFO (-3): Annen GINFO CD LEST_KOM (-4): Kommentarlinje CD CD Bruk: CD type = LB_GetSet(fil,&lb,pNavn); ============================================================================= */ short LB_GetSet(FILE *fil,LB_LESEBUFFER *plb,LC_NAVNETABELL * pNavn) { short navn_nr,gml_niv; char cTmp; /* Sjekk at buffer har rett innhold */ if (plb->sStatus != LESEBUFFER_OK) { LB_FyllBuffer(fil,plb); } /* Henter nytt sett */ if (plb->set_brukt == SET_BRUKT) { plb->cp = plb->np; do { /* Hopp over ledende blanke */ while (UT_IsSpace(*plb->cp)) { (plb->cp)++; } /* Linjen er oppbrukt, les inn ny */ if (*plb->cp == '\0') { LB_FyllBuffer(fil,plb); } } while (UT_IsSpace(*plb->cp) || *plb->cp == '\0'); plb->np = plb->cp; if (*plb->cp == '.') { /* --------- SOSI-navn */ plb->startpos = plb->filpos + (plb->cp - plb->tx); /* Husk filposisjon */ /* Scann over navnet (Ikke \0, mellomrom eller filslutt) */ while (*plb->cp && !UT_IsSpace(*plb->cp) && *plb->cp != 26) { (plb->cp)++; } cTmp = *plb->cp; *plb->cp = '\0'; /* Søk i navnetabellen */ gml_niv = plb->cur_niv; plb->cur_niv = LN_PakkNavn(pNavn,plb->np,&navn_nr,&(plb->cur_ant_par)); plb->cur_navn[plb->cur_niv - 1] = navn_nr; *plb->cp = cTmp; /* Sjekk mot sprang i prikknivå */ if ((plb->cur_niv - gml_niv) > 1) { LC_Error(147,"(LB_GetSet)",plb->np); } /* Handter parameter */ if (navn_nr != L_SLUTT) { do { /* Hopp over ledende blanke */ while (UT_IsSpace(*plb->cp)) { (plb->cp)++; } /* Linjen er oppbrukt, les inn ny */ if (*plb->cp == '\0') { LB_FyllBuffer(fil,plb); } } while (UT_IsSpace(*plb->cp) || *plb->cp == '\0'); plb->np = plb->cp; LB_GetParameter(plb); } if (plb->cur_niv == 1) { /* Gruppenavn */ plb->cur_type = navn_nr; } else if (navn_nr == L_NA || navn_nr == L_NAH || navn_nr == L_NAD ) { /* Koordinat */ plb->cur_type = LEST_KOORD; } else { /* Annen GINFO / PINFO */ plb->cur_type = LEST_GINFO; } } else { /* Parameter, kommentar eller fyll */ if (LB_TestFyll(plb->cp)) { /* ------------------ Fyll */ /* Marker at linjen er oppbrukt */ *plb->cp = '\0'; plb->cur_type = LEST_BLANK; plb->np = plb->cp; /* Fyll er alltid nivå 2 eller 3 */ if (plb->cur_niv == 1) { plb->cur_niv = 2; } } else if (*plb->cp == '!') { /* ------------------ Kommentar */ plb->pp = plb->np; /* Resten av linjen er kommentar */ plb->np = strchr(plb->cp,'\0'); plb->cur_type = LEST_KOM; //plb->cur_niv = 2; /* Kommentar er bare lovlig i ginfo */ // Fjernet 24/7-02. if (plb->cur_niv < 2) plb->cur_niv = 2; // Endret 22/8-02. } else { /* ------------------ Parameter */ LB_GetParameter(plb); if (plb->cur_navn[plb->cur_niv - 1] == L_NA || plb->cur_navn[plb->cur_niv - 1] == L_NAH || plb->cur_navn[plb->cur_niv - 1] == L_NAD ) { /* Koordinat */ plb->cur_type = LEST_KOORD; } else { /* Annen GINFO / PINFO */ plb->cur_type = LEST_GINFO; } } } } plb->set_brukt = SET_UBRUKT; return plb->cur_type; } /* AR-920909 CH LB_GetParameter Hent parameter fra buffer CD ========================================================================== CD Formål: CD Hent parameter fra lesebuffer. CD Forutsetter at det ikke er blanke forran parameteren. CD Inn: "plb->np" peker til første posisjon i parameteren. (Der tolking CD skal starte. CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LB_LESEBUFFER *plb i Peker til bufferstruktur CD CD Bruk: CD param = LB_GetParameter(&lb) ========================================================================== */ static char *LB_GetParameter(LB_LESEBUFFER *plb) { short npar = (plb->cur_ant_par == LC_ANT_PAR_UKJENT)? 9999 : plb->cur_ant_par; plb->pp = plb->cp = plb->ep = plb->np; for ( ; npar > 0; npar--) { /* Neste sett er funnet */ if (*plb->cp == '\0' || *plb->cp == '.' || *plb->cp == '!') { break; /* Vanlig ord */ } else if (*plb->cp != '"') { while (*plb->cp && !UT_IsSpace(*plb->cp)) { (plb->cp)++; } plb->ep = plb->cp; /* "Ord" i hermetegn */ } else { (plb->cp)++; /* Start-hermetegn */ while (*plb->cp && *plb->cp != '"') { /* "Ordet" */ (plb->cp)++; } if (*plb->cp == '"') { (plb->cp)++; } plb->ep = plb->cp; } if (npar > 1) { /* Skann fram til neste parameter */ while (UT_IsSpace(*plb->cp)) { (plb->cp)++; } } } /* Avslutt strengen */ if (plb->ep > plb->pp) { /* Vanlig */ plb->cp = plb->ep; (plb->cp)++; plb->np = plb->cp; *plb->ep = '\0'; } else { /* Tom parameter */ plb->np = plb->ep; plb->pp = plb->ep - 1; *plb->pp = '\0'; } return plb->pp; } /* AR-920626 !-------------------------------------------------------------! ! LB_TestFyll - Tester om en streng er fyll-linje. ! ! ! ! Retur: UT_TRUE = linjen er fyll ! ! UT_FALSE = linjen inneholder annen informasjon ! ! ! !-------------------------------------------------------------! */ static short LB_TestFyll(const char *pszTx) { for (; *pszTx; ++pszTx) { if (!UT_IsSpace(*pszTx) && *pszTx != '!') return (UT_FALSE); } return (UT_TRUE); } /* AR/TU:2008-09-11 CH LC_ErstattReferanse Erstatt referanse CD ========================================================================== CD Formål: CD Erstatt referanse i alle grupper i gitt fil. CD CD CD Parametre: CD Type Navn I/U Forklaring CD -------------------------------------------------------------------------- CD LC_FILADM *pFil i Fil som skal behandles CD long lGmlSnr i Gruppe som skal byttes ut CD long lNyttSnr i Ny gruppe CD Verdien 0 fører til gammelt serienummer CD fjernes uten at det legges inn noe nytt. CD bool bSammeRetning i Gruppene er digitalisert i samme retning CD CD Bruk: CD sStatus = LC_ErstattReferanse(pFil, lGmlSnr, lNyttSnr, bSammeRetning); ========================================================================== */ SK_EntPnt_FYBA void LC_ErstattReferanse (LC_FILADM *pFil,long lGmlSnr,long lNyttSnr, bool bSammeRetning) { short ngi; long nko; unsigned short info; LC_BGR BgrGml,Bgr; long lAntRef; short sGiLin,sRefPos; long *plRefArray,*plRef,l; bool bEndret; // Husk gruppen BgrGml = Sys.GrId; lGmlSnr = labs(lGmlSnr); lNyttSnr = labs(lNyttSnr); LC_InitNextBgr(&Bgr); Bgr.pFil = pFil; while (LC_NextBgr(&Bgr,LC_FRAMGR)) { if (Bgr.pFil == pFil) { LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info); if ((info&GI_REF) != 0) { // Gruppen er på rett fil og har referanser, Bytt serienummer LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info); lAntRef = LC_InqAntRef(); plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long)); sGiLin = 2; sRefPos = 0; LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos); bEndret = false; plRef = plRefArray; for (l=0; l 0 && bSammeRetning) { *plRef = lNyttSnr; } else if (*plRef > 0 && !bSammeRetning) { *plRef = -lNyttSnr; } else if (*plRef < 0 && bSammeRetning) { *plRef = -lNyttSnr; } else if (*plRef < 0 && !bSammeRetning) { *plRef = lNyttSnr; } } // Skal fjerne serienummer else { memmove(plRef, plRef+1, (lAntRef-l-1) * sizeof(long)); --l; --plRef; --lAntRef; } bEndret = true; } } if (bEndret) { LC_PutRef(plRefArray,lAntRef); LC_WxGr(SKRIV_OPTIMALT); } UT_FREE(plRefArray); } } } // ========= Leser inn opprinnelig gruppe LC_RxGr(&BgrGml,LES_OPTIMALT,&ngi,&nko,&info); }