summaryrefslogtreecommitdiff
path: root/src/FYBA
diff options
context:
space:
mode:
Diffstat (limited to 'src/FYBA')
-rw-r--r--src/FYBA/FYBA.cpp42
-rw-r--r--src/FYBA/FYBA.sln26
-rw-r--r--src/FYBA/FYBA.vcxproj231
-rw-r--r--src/FYBA/FYBA_DLL.cpp25
-rw-r--r--src/FYBA/FYHO.cpp1456
-rw-r--r--src/FYBA/FYLB.cpp4646
-rw-r--r--src/FYBA/FYLD.cpp111
-rw-r--r--src/FYBA/FYLE.cpp494
-rw-r--r--src/FYBA/FYLH.cpp1035
-rw-r--r--src/FYBA/FYLI.cpp2297
-rw-r--r--src/FYBA/FYLO.cpp2529
-rw-r--r--src/FYBA/FYLP.cpp1169
-rw-r--r--src/FYBA/FYLR.cpp2240
-rw-r--r--src/FYBA/FYLS.cpp678
-rw-r--r--src/FYBA/FYLU.cpp2904
-rw-r--r--src/FYBA/FYLX.cpp4948
-rw-r--r--src/FYBA/FYTA.cpp199
-rw-r--r--src/FYBA/Fyba_Callback.cpp232
-rw-r--r--src/FYBA/Fyba_melding.cpp201
-rw-r--r--src/FYBA/Fyba_melding_dll.cpp.bak368
-rw-r--r--src/FYBA/LICENSE24
-rw-r--r--src/FYBA/Makefile.am9
-rw-r--r--src/FYBA/fyba.h1484
-rw-r--r--src/FYBA/fyba_strings.h223
-rw-r--r--src/FYBA/fybax.h344
-rw-r--r--src/FYBA/fyln.cpp870
-rwxr-xr-xsrc/FYBA/make.sh5
-rw-r--r--src/FYBA/stdafx.cpp8
-rw-r--r--src/FYBA/stdafx.h16
29 files changed, 28814 insertions, 0 deletions
diff --git a/src/FYBA/FYBA.cpp b/src/FYBA/FYBA.cpp
new file mode 100644
index 0000000..02da5ee
--- /dev/null
+++ b/src/FYBA/FYBA.cpp
@@ -0,0 +1,42 @@
+/*
+CH FYBA FYsak-Basesystem
+CD ==================================================================
+CD Rutiner for å lese, endre og skrive SOSI-filer.
+CD ==================================================================
+CD
+CH INSTALLERINGS- OG BRUKS-OPPLYSNINGER:
+CD
+CD Bibliotek..: fybale.lib
+CD Kildefiler.: fyba.c, fylo.c, fyln.c, fylr.c, fyls.c, fylx.c, fyli.c
+CD fylh.c, fyho.c, fyle.c, fyba.h, fybax.h
+CD Versjon....: D01
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: Andreas Røstad, Georg Langerak
+CD
+CD Kompilator.: Microsoft C versjon 6.0
+CD Optioner...: /c /AL /J /FPi /G2t /W4
+CD Memory-mod.: Large
+CD Floating-p.: Emulation
+CD Processor..: 80286
+CD
+CD #include...: fyba.h
+CD Linkes med.: utle.lib >= versjon D
+CD +llibce.lib >= versjon 6.0
+CD
+CD ==================================================================
+*/
+
+#include "stdafx.h"
+
+
+/*
+CH LC_InqVer Identifikasjon
+CD =============================================================================
+CD Formål:
+CD Henter versjons-identifikasjon for dette biblioteket.
+ =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_InqVer(void)
+{
+ return FYBA_IDENT;
+}
diff --git a/src/FYBA/FYBA.sln b/src/FYBA/FYBA.sln
new file mode 100644
index 0000000..c7dc815
--- /dev/null
+++ b/src/FYBA/FYBA.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows Desktop
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FYBA", "FYBA.vcxproj", "{26B83785-CE7C-47A5-8B4F-B830185AFFCF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ SosiVis Debug|Win32 = SosiVis Debug|Win32
+ SosiVis Release|Win32 = SosiVis Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.Debug|Win32.Build.0 = Debug|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.Release|Win32.ActiveCfg = Release|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.Release|Win32.Build.0 = Release|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.SosiVis Debug|Win32.ActiveCfg = SosiVis Debug|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.SosiVis Debug|Win32.Build.0 = SosiVis Debug|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.SosiVis Release|Win32.ActiveCfg = SosiVis Release|Win32
+ {26B83785-CE7C-47A5-8B4F-B830185AFFCF}.SosiVis Release|Win32.Build.0 = SosiVis Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/FYBA/FYBA.vcxproj b/src/FYBA/FYBA.vcxproj
new file mode 100644
index 0000000..623e620
--- /dev/null
+++ b/src/FYBA/FYBA.vcxproj
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="SosiVis Debug|Win32">
+ <Configuration>SosiVis Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="SosiVis Release|Win32">
+ <Configuration>SosiVis Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{26B83785-CE7C-47A5-8B4F-B830185AFFCF}</ProjectGuid>
+ <RootNamespace>FYBA</RootNamespace>
+ <SccProjectName>
+ </SccProjectName>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccProvider>
+ </SccProvider>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>NotSet</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\GM;..\UT;..\..\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AdditionalOptions> /J</AdditionalOptions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <GenerateXMLDocumentationFiles>true</GenerateXMLDocumentationFiles>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(SolutionDir)$(Configuration)\$(ProjectName)$(TargetExt)</OutputFile>
+ </Lib>
+ <Xdcmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Xdcmake>
+ <PostBuildEvent>
+ <Command>copy $(TargetPath) ..\..\Lib\$(ProjectName)D$(TargetExt)</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\GM;..\UT;..\..\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <AdditionalOptions> /J</AdditionalOptions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat />
+ </ClCompile>
+ <Lib>
+ <OutputFile>$(SolutionDir)$(Configuration)\$(ProjectName)$(TargetExt)</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>copy $(TargetPath) ..\..\Lib\$(ProjectName)$(TargetExt)</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\GM;..\UT;..\..\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;SOSIVIS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <AdditionalOptions> /J</AdditionalOptions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat />
+ </ClCompile>
+ <Lib>
+ <OutputFile>..\..\Lib\$(ProjectName).lib</OutputFile>
+ </Lib>
+ <PostBuildEvent>
+ <Command>copy $(TargetPath) ..\..\Lib\$(ProjectName)$(TargetExt)</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\GM;..\UT;..\..\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;SOSIVIS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AdditionalOptions> /J</AdditionalOptions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <GenerateXMLDocumentationFiles>true</GenerateXMLDocumentationFiles>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Lib>
+ <OutputFile>..\..\Lib\$(ProjectName)D.lib</OutputFile>
+ </Lib>
+ <Xdcmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Xdcmake>
+ <PostBuildEvent>
+ <Command>copy $(TargetPath) ..\..\Lib\$(ProjectName)D$(TargetExt)</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="FYBA.cpp" />
+ <ClCompile Include="FYHO.cpp" />
+ <ClCompile Include="FYLB.cpp" />
+ <ClCompile Include="FYLD.cpp" />
+ <ClCompile Include="FYLE.cpp" />
+ <ClCompile Include="FYLH.cpp" />
+ <ClCompile Include="FYLI.cpp" />
+ <ClCompile Include="fyln.cpp" />
+ <ClCompile Include="FYLO.cpp" />
+ <ClCompile Include="FYLP.cpp" />
+ <ClCompile Include="FYLR.cpp" />
+ <ClCompile Include="FYLS.cpp" />
+ <ClCompile Include="FYLU.cpp" />
+ <ClCompile Include="FYLX.cpp" />
+ <ClCompile Include="FYTA.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="fyba.h">
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy %(FullPath) ..\..\Include\*.*
+</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\Include\%(Filename)%(Extension);%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy %(FullPath) ..\..\Include\*.*
+</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\Include\%(Filename)%(Extension);%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'">copy %(FullPath) ..\..\Include\*.*
+</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='SosiVis Debug|Win32'">..\..\Include\%(Filename)%(Extension);%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'">copy %(FullPath) ..\..\Include\*.*
+</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='SosiVis Release|Win32'">..\..\Include\%(Filename)%(Extension);%(Outputs)</Outputs>
+ </CustomBuild>
+ <ClInclude Include="FYBAX.H" />
+ <ClInclude Include="stdafx.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="FYBA.END" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="ReadMe.txt" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties DevPartner_IsInstrumented="0" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/src/FYBA/FYBA_DLL.cpp b/src/FYBA/FYBA_DLL.cpp
new file mode 100644
index 0000000..879ab83
--- /dev/null
+++ b/src/FYBA/FYBA_DLL.cpp
@@ -0,0 +1,25 @@
+// FYBA_DLL.cpp : Defines the entry point for the DLL application.
+//
+
+#ifdef WIN32
+
+#include "stdafx.h"
+#include "fyba.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+#endif
diff --git a/src/FYBA/FYHO.cpp b/src/FYBA/FYHO.cpp
new file mode 100644
index 0000000..64606c4
--- /dev/null
+++ b/src/FYBA/FYHO.cpp
@@ -0,0 +1,1456 @@
+/*
+AR-920214
+CH FYHO "Direkte" hoderutiner
+CD =================================================================
+CD
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: Georg Langerak / Andreas Røstad
+CD
+CD Rutiner for å handtere hodet på SOSI-filer direkte på filen.
+CD ==============================================================
+*/
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <time.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+
+/* --- Globale strukturer ---------------------- */
+extern LC_SYSTEMADM Sys;
+
+extern char retur_str[LC_MAX_SOSI_LINJE_LEN]; /* Returstreng */
+
+// ----- Lokale rutiner -----
+static short ho_TestFyllKommentar(const char *pszTx);
+
+/*
+AR:2000-10-07
+CH HO_GetTransEx Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Formål:
+CD Henter ut innholdet under ..TRANSPAR fra fra filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD unsigned short *pusMaske iu [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD [Ut] Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD Følgende konstanter er definert:
+CD LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD LC_TR_KOORDSYS - Koordsys
+CD LC_TR_TRANSSYS - Transsys
+CD LC_TR_GEOSYS - Geosys
+CD LC_TR_GEOKOORD - Geokoord
+CD LC_TR_ORIGO - Origo-nø
+CD LC_TR_ENHET - Enhet
+CD LC_TR_ENHETH - Enhet-h
+CD LC_TR_ENHETD - Enhet-d
+CD LC_TR_VERTDATUM - Vert-datum
+CD LC_TR_VERTINT - Vert-int
+CD LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR * pTrans iu Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = HO_GetTransEx("Test.sos",&usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTransEx(const char *pszFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+ short sStatus;
+ FILE * pFil;
+
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"SOS",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ sStatus = ho_GetTransEx(pFil,pusMaske,pTrans);
+ fclose (pFil);
+
+ /* Åpningsfeil på kladdefilen */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetTransEx)",err().tx);
+ memset(pTrans,0,sizeof(LC_TRANSPAR));
+ *pusMaske = 0;
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR:2000-10-07
+CH ho_GetTransEx Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Henter ut innholdet under ..TRANSPAR fra fra filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD FILE *pFil i Filpeker til sosi-fil.
+CD unsigned short *pusMaske iu [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD [Ut] Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD Følgende konstanter er definert:
+CD LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD LC_TR_KOORDSYS - Koordsys
+CD LC_TR_TRANSSYS - Transsys
+CD LC_TR_GEOSYS - Geosys
+CD LC_TR_GEOKOORD - Geokoord
+CD LC_TR_ORIGO - Origo-nø
+CD LC_TR_ENHET - Enhet
+CD LC_TR_ENHETH - Enhet-h
+CD LC_TR_ENHETD - Enhet-d
+CD LC_TR_VERTDATUM - Vert-datum
+CD LC_TR_VERTINT - Vert-int
+CD LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR * pTrans iu Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = ho_GetTransEx(pFil,&usMaske,&Trans);
+ =============================================================================
+*/
+short ho_GetTransEx(FILE *pFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+ short lin,itxi;
+ char *cp;
+ short ist = UT_TRUE;
+ unsigned short usMaskeInn = *pusMaske;
+
+
+ /* Nullstiller pTrans */
+ memset(pTrans,0,sizeof(LC_TRANSPAR));
+
+ /* Nullstiller masken */
+ *pusMaske = 0;
+
+ /* Sjekk hvilket tegnsett som skal brukes */
+ ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+ /* ----- Div. kontroller ----- */
+ /* Transpar */
+ lin=2;
+ if ( ! ho_GetVal(pFil,"..TRANSPAR",&lin)) {
+ LC_Error(14," (HO_GetTrans) "," ");
+ return UT_FALSE;
+ }
+
+ /* ----- Henter verdier ----- */
+
+ /* Koordsys */
+ if ((usMaskeInn & LC_TR_KOORDSYS) != 0) {
+ lin = 2;
+ cp = ho_GetVal(pFil,"...KOORDSYS",&lin);
+ if (cp == NULL) {
+ lin=2;
+ ho_GetVal(pFil,"..KOORDSYS",&lin);
+ }
+ if (cp != NULL) {
+ *pusMaske |= LC_TR_KOORDSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sKoordsys);
+ UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysDatum);
+ UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysProjek);
+ }
+ }
+
+ /* Transsys */
+ if ((usMaskeInn & LC_TR_TRANSSYS) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...TRANSSYS",&lin)) != NULL) {
+ *pusMaske |= LC_TR_TRANSSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sTranssysTilsys);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA2);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB2);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC2);
+ }
+ }
+
+ /* Geosys */
+ if ((usMaskeInn & LC_TR_GEOSYS) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...GEOSYS",&lin)) != NULL) {
+ *pusMaske |= LC_TR_GEOSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sGeosysDatum);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysProj);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysSone);
+ }
+ }
+
+ /* Geokoord */
+ if ((usMaskeInn & LC_TR_GEOKOORD) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...GEOKOORD",&lin)) != NULL) {
+ *pusMaske |= LC_TR_GEOKOORD;
+ UT_StrShort(cp,0,&itxi,&pTrans->sGeoKoord);
+ }
+ }
+
+ /* Origo */
+ if ((usMaskeInn & LC_TR_ORIGO) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...ORIGO-NØ",&lin)) != NULL) {
+ *pusMaske |= LC_TR_ORIGO;
+ UT_StrDbl(cp,0,&itxi,'.',&pTrans->Origo.dNord);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->Origo.dAust);
+ }
+ }
+
+ /* Enhet */
+ if ((usMaskeInn & LC_TR_ENHET) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...ENHET",&lin)) != NULL) {
+ *pusMaske |= LC_TR_ENHET;
+ pTrans->dEnhet = strtod(cp,&cp);
+ }
+ }
+
+ /* Enhet-h */
+ if ((usMaskeInn & LC_TR_ENHETH) != 0) {
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ENHET-H",&lin)) == NULL) {
+ pTrans->dEnhet_h = pTrans->dEnhet;
+ } else {
+ *pusMaske |= LC_TR_ENHETH;
+ pTrans->dEnhet_h = strtod(cp,&cp);
+ }
+ }
+
+ /* Enhet-d */
+ if ((usMaskeInn & LC_TR_ENHETD) != 0) {
+ /* Enhet-d */
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ENHET-D",&lin)) == NULL) {
+ pTrans->dEnhet_d = pTrans->dEnhet;
+ } else {
+ *pusMaske |= LC_TR_ENHETD;
+ pTrans->dEnhet_d = strtod(cp,&cp);
+ }
+ }
+
+ /* Vert-datum */
+ if ((usMaskeInn & LC_TR_VERTDATUM) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...VERT-DATUM",&lin)) != NULL) {
+ *pusMaske |= LC_TR_VERTDATUM;
+ UT_StrToken(cp,0,&itxi,7,pTrans->szVertdatHref);
+ UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatDref);
+ UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatFref);
+ UT_StrToken(cp,itxi,&itxi,2,pTrans->szVertdatHtyp);
+ }
+ }
+
+ /* Vert-int */
+ if ((usMaskeInn & LC_TR_VERTINT) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...VERT-INT",&lin)) != NULL) {
+ *pusMaske |= LC_TR_VERTINT;
+ UT_StrShort(cp,0,&itxi,&pTrans->sVertintHref);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintDref);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintFref);
+ }
+ }
+
+ /* Vert-delta */
+ if ((usMaskeInn & LC_TR_VERTDELTA) != 0) {
+ lin = 2;
+ if ((cp = ho_GetVal(pFil,"...VERT-DELTA",&lin)) != NULL) {
+ *pusMaske |= LC_TR_VERTDELTA;
+ UT_StrShort(cp,0,&itxi,&pTrans->sVdeltaMin);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVdeltaMax);
+ }
+ }
+
+
+ /* ----- Div. sluttkontroll ----- */
+
+ /* Kontroller at det er funnet Koordsys, Transsys eller Geosys */
+ if ((usMaskeInn & LC_TR_KOORDSYS) != 0 ||
+ (usMaskeInn & LC_TR_TRANSSYS) != 0 ||
+ (usMaskeInn & LC_TR_GEOSYS) != 0 ) {
+ if ((*pusMaske & LC_TR_KOORDSYS) == 0 &&
+ (*pusMaske & LC_TR_TRANSSYS) == 0 &&
+ (*pusMaske & LC_TR_GEOSYS) == 0 ) {
+ /* Ikke noe koordinatsystem funnet */
+ LC_Error(15,"(ho_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+ }
+
+ /* Kontroller at det er funnet Origo */
+ if ((usMaskeInn & LC_TR_ORIGO) != 0 &&
+ (*pusMaske & LC_TR_ORIGO) == 0 ) {
+ /* Origo mangler */
+ LC_Error(16,"(ho_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+
+ /* Kontroller at det er funnet Enhet */
+ if ((usMaskeInn & LC_TR_ENHET) != 0 &&
+ (*pusMaske & LC_TR_ENHET) == 0 ) {
+ /* Enhet mangler */
+ LC_Error(17,"(ho_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+
+ return ist;
+}
+
+
+
+/*
+AR:1999-07-12
+CH HO_GetTrans Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Formål:
+CD Henter transformasjonsparametrene fra filhodet.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD For nye programmer bør HO_GetTransEx benyttes. HO_GetTransEx er
+CD kompatibel med nye versjoner av SOSI.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD short *koosys u Koordinatsystem
+CD double *origo_a u ..ORIGO-AUST
+CD double *origo_n u ..ORIGO-NORD
+CD double *enhet u ...ENHET
+CD double *enhet_h u ...ENHET-H
+CD double *enhet_d u ...ENHET-D
+CD short sStatus r UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = HO_GetTrans(fil,&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTrans(const char *pszFil,short *koosys,double *origo_a,
+ double *origo_n,double *enhet,double *enhet_h,double *enhet_d)
+{
+ short sStatus;
+ FILE * pFil;
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ sStatus = ho_GetTrans(pFil,koosys,origo_a,origo_n,enhet,enhet_h,enhet_d);
+ fclose (pFil);
+
+ /* Åpningsfeil på kladdefilen */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetTrans)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+GL-880427
+AR-900314
+CH ho_GetTrans Finner .TRANSPAR i hodet
+CD =============================================================================
+CD Formål:
+CD Henter transformasjonsparametrene fra filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *pFil i Filpeker til sosi-fil.
+CD short *koosys u Koordinatsystem
+CD double *origo_a u ..ORIGO-AUST
+CD double *origo_n u ..ORIGO-NORD
+CD double *enhet u ...ENHET
+CD double *enhet_h u ...ENHET-H
+CD double *enhet_d u ...ENHET-D
+CD short sStatus r UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD ho_GetTrans(pFil,&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+ =============================================================================
+*/
+short ho_GetTrans(FILE *pFil,short *koosys,double *origo_a,
+ double *origo_n,double *enhet,double *enhet_h,double *enhet_d)
+{
+ short lin;
+ char *cp;
+
+
+ /* Sjekk hvilket tegnsett som skal brukes */
+ ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+ lin=2;
+ if ( ! ho_GetVal(pFil,"..TRANSPAR",&lin)) {
+ LC_Error(14," (HO_GetTrans) "," ");
+ return UT_FALSE;
+ }
+
+
+ *koosys=0;
+ lin=2;
+ cp = ho_GetVal(pFil,"...KOORDSYS",&lin);
+ if (cp == NULL) {
+ lin=2;
+ ho_GetVal(pFil,"..KOORDSYS",&lin);
+ }
+ if (cp == NULL) {
+ LC_Error(15," (HO_GetTrans) "," ");
+ return UT_FALSE;
+
+ } else {
+ *koosys = (short)atoi(cp);
+ }
+
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ORIGO-NØ",&lin)) == NULL) {
+ LC_Error(16," (HO_GetTrans) "," ");
+ return UT_FALSE;
+
+ } else {
+ *origo_n = strtod(cp,&cp);
+ *origo_a = strtod(cp,&cp);
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ENHET",&lin)) == NULL) {
+ LC_Error(17," (HO_GetTrans) "," ");
+ return UT_FALSE;
+ } else {
+ *enhet = strtod(cp,&cp);
+ }
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ENHET-H",&lin)) == NULL) {
+ *enhet_h = *enhet;
+ } else {
+ *enhet_h = strtod(cp,&cp);
+ }
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"...ENHET-D",&lin)) == NULL) {
+ *enhet_d = *enhet;
+ } else {
+ *enhet_d = strtod(cp,&cp);
+ }
+ }
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-890823
+CH HO_GetOmr Finner ..OMRÅDE i hodet
+CD =============================================================================
+CD Formål:
+CD Henter områdeangivelsen fra filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD double *nv_a u
+CD double *nv_n u
+CD double *oh_a u
+CD double *oh_n u
+CD short sStatus r UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = HO_GetOmr(pszFil,&nv_a,&nv_n,&oh_a,&oh_n);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetOmr(const char * pszFil,double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+ short sStatus;
+ FILE * pFil;
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ ho_GetOmr(pFil,nv_a,nv_n,oh_a,oh_n);
+ fclose (pFil);
+ sStatus = UT_TRUE;
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetOmr)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-890823
+CH ho_GetOmr Finner ..OMRÅDE i hodet
+CD =============================================================================
+CD Formål:
+CD Henter områdeangivelsen fra filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *fil i Filpeker til sosi-fil.
+CD double *nv_a u
+CD double *nv_n u
+CD double *oh_a u
+CD double *oh_n u
+CD short sStatus r UT_TRUE, eller UT_FALSE.
+CD
+CD Bruk:
+CD sStatus = ho_GetOmr(fil,&nv_a,&nv_n,&oh_a,&oh_n);
+ =============================================================================
+*/
+short ho_GetOmr(FILE *fil,double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+ short lin,i;
+ char *cp;
+ short sStatus = UT_TRUE;
+
+
+ /* Sjekk hvilket tegnsett som skal brukes */
+ ho_GetTegnsett(fil,&Sys.BufAdm.sTegnsett);
+
+
+ lin=2;
+ if (ho_GetVal(fil,"..OMRÅDE",&lin) == NULL) {
+ LC_Error(7,"(HO_GetOmr)","");
+ *nv_n = -9999999.0;
+ *nv_a = -9999999.0;
+ *oh_n = 9999999.0;
+ *oh_a = 9999999.0;
+ sStatus = UT_FALSE;
+
+
+ } else {
+ /* Min-NØ */
+ i = lin;
+ if ((cp = ho_GetVal(fil,"...MIN-NØ",&i)) == NULL ) {
+ LC_Error(8,"(HO_GetOmr)","");
+ *nv_n = -9999999.0;
+ *nv_a = -9999999.0;
+ sStatus = UT_FALSE;
+
+ } else {
+ *nv_n = strtod(cp,&cp);
+ *nv_a = strtod(cp,&cp);
+ }
+
+ /* Max-NØ */
+ i = lin;
+ if ((cp = ho_GetVal(fil,"...MAX-NØ",&i)) == NULL) {
+ LC_Error(9,"(HO_GetOmr)","");
+ *oh_n = 999999.0;
+ *oh_a = 9999999.0;
+ sStatus = UT_FALSE;
+
+ } else{
+ *oh_n = strtod(cp,&cp);
+ *oh_a = strtod(cp,&cp);
+ }
+ }
+
+ /* Sjekker at området har utstrekning */
+ //if (*oh_a-*nv_a < 0.001 || *oh_n-*nv_n < 0.001) {
+ // LC_Error(104,"(HO_GetOmr)","");
+ // *nv_n = -9999999.0;
+ // *nv_a = -9999999.0;
+ // *oh_n = 9999999.0;
+ // *oh_a = 9999999.0;
+ //}
+
+ return sStatus;
+}
+
+
+
+
+/*
+AR:1999-07-12
+CH HO_GetKvalitet Finner kvalitetsopplysninger
+CD =============================================================================
+CD Formål:
+CD Finne kvalitetsopplysninger i filhode.
+CD (Ikke aktuellt etter SOSI v. 4.00.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD short *psMetode u Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *pLNnoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short *psSynbarhet u Synbarhet i bilde
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD short *psHoydeMetode u Hvordan høyden er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *plHoydeNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short ist r Statusvariabel: UT_TRUE - OK, ..KVALITET er funnet
+CD UT_FALSE - ikke funnet
+CD
+CD Bruk:
+CD ist = HO_GetKvalitet(fil,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_GetKvalitet(const char *pszFil,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+ short sStatus;
+ FILE * pFil;
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ sStatus = ho_GetKvalitet(pFil,psMetode,plNoyaktighet,psSynbarhet,psHoydeMetode,plHoydeNoyaktighet);
+ fclose (pFil);
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetKvalitet)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+
+/*
+OJ-891123
+CH ho_GetKvalitet Finner kvalitetsopplysninger
+CD =============================================================================
+CD Formål:
+CD Finne kvalitetsopplysninger i filhode.
+CD (Ikke aktuellt etter SOSI v. 4.00.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *pFil i Filpeker til sosi-fil.
+CD short *psMetode u Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *pLNnoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short *psSynbarhet u Synbarhet i bilde
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD short *psHoydeMetode u Hvordan høyden er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *plHoydeNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short ist r Statusvariabel: UT_TRUE - OK, ..KVALITET er funnet
+CD UT_FALSE - ikke funnet
+CD
+CD Bruk:
+CD ist = ho_GetKvalitet(fil,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+short ho_GetKvalitet(FILE *pFil,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+ short lin;
+ char *cp;
+ short ist = UT_FALSE;
+
+
+ /* Sjekk hvilket tegnsett som skal brukes */
+ ho_GetTegnsett(pFil,&Sys.BufAdm.sTegnsett);
+
+ lin=2;
+ if ((cp = ho_GetVal(pFil,"..KVALITET",&lin)) != NULL) { /* Kvalitet */
+ ist = UT_TRUE;
+ }
+
+ /* Tolk strengen til tallverdier */
+ LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+ psHoydeMetode,plHoydeNoyaktighet);
+
+
+ /* Handter manglende høyde-kvalitet spesiellt */
+ if (*psHoydeMetode == KVAL_MET_UNDEF) *psHoydeMetode = *psMetode;
+ if (*plHoydeNoyaktighet == KVAL_NOY_UKJENT) *plHoydeNoyaktighet = *plNoyaktighet;
+
+ return ist;
+}
+
+
+
+/*
+AR-920331
+CH HO_GetTegnsett Finner tegnsett
+CD ==========================================================================
+CD Formål:
+CD Finne tegnsett i filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD short *psTegnsett u Tegnsett, konstanter definert:
+CD TS_DOSN8 = DOS norsk 8-bits(standardverdi)
+CD TS_ND7 = Norsk Data 7-bits
+CD TS_DECM8 = DEC multinasjonal 8-bits
+CD TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD TS_DECN7 = DEC norsk 7-bits
+CD short sStatus r Status: UT_TRUE = Funnet
+CD UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD sStatus = HO_GetTegnsett(pszFil,&sTegnsett);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short HO_GetTegnsett(const char *pszFil,short *psTegnsett)
+{
+ short sStatus;
+ FILE * pFil;
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ sStatus = ho_GetTegnsett(pFil,psTegnsett);
+ fclose (pFil);
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetTegnsett)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-920331
+CH ho_GetTegnsett Finner tegnsett
+CD ==========================================================================
+CD Formål:
+CD Finne tegnsett i filhodet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD FILE *fil i Filpeker til sosi-fil.
+CD short *psTegnsett u Tegnsett, konstanter definert:
+CD TS_DOSN8 = DOS norsk 8-bits(standardverdi)
+CD TS_ND7 = Norsk Data 7-bits
+CD TS_DECM8 = DEC multinasjonal 8-bits
+CD TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD TS_DECN7 = DEC norsk 7-bits
+CD short sStatus r Status: UT_TRUE = Funnet
+CD UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD sStatus = ho_GetTegnsett(fil,&sTegnsett);
+CD ==========================================================================
+*/
+short ho_GetTegnsett(FILE *pFil,short *psTegnsett)
+{
+ short lin;
+ char *cp;
+ short ist = UT_FALSE;
+
+ *psTegnsett = TS_DOSN8;
+ lin=2;
+
+ if ((cp = ho_GetVal(pFil,"..TEGNSETT",&lin)) != NULL) { /* Tegnsett */
+ ist = UT_TRUE;
+ UT_StrUpper(cp);
+ if (strcmp(cp,"ISO8859-10") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ISO8859-1") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ANSI") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ND7") == 0) {
+ *psTegnsett = TS_ND7;
+
+ } else if (strcmp(cp,"DECN7") == 0) {
+ *psTegnsett = TS_DECN7;
+
+ } else if (strcmp(cp,"DECM8") == 0) {
+ *psTegnsett = TS_DECM8;
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+AR:1999-07-14
+CH HO_GetVal Finn verdien til et SOSI-navn
+CD =============================================================================
+CD Formål:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD char *sosi_navn i SOSI-navn det skal finnes verdi til
+CD short *sett_nr i/u i: "Sett nummer"(linjenummer) for start søking (min 1)
+CD u: Ved tilslag returneres "Sett nummer" for
+CD tilslaget.
+CD char *para_peker r Peker til parameter-streng avslutta med '\0'.
+CD Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = HO_GetVal(fil,sosi_navn,&sett_nr);
+ =============================================================================
+*/
+SK_EntPnt_FYBA char *HO_GetVal(const char *pszFil,char *sosi_navn,short *sett_nr)
+{
+ short sStatus;
+ FILE * pFil;
+ char *rp = NULL; /* Retur peker */
+
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Hent verdier */
+ rp = ho_GetVal(pFil,sosi_navn,sett_nr);
+ fclose (pFil);
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_GetVal)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return rp;
+}
+
+
+/*
+GL:1988-04-27
+AR:1989-08-23
+CH ho_GetVal Finn verdien til et SOSI-navn
+CD =============================================================================
+CD Formål:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *pFil i Filpeker til sosi-fil.
+CD char *sosi_navn i SOSI-navn det skal finnes verdi til
+CD short *sett_nr i/u i: "Sett nummer"(linjenummer) for start søking (min 1)
+CD u: Ved tilslag returneres "Sett nummer" for
+CD tilslaget.
+CD char *para_peker r Peker til parameter-streng avslutta med '\0'.
+CD Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = ho_GetVal(pFil,sosi_navn,&sett_nr);
+ =============================================================================
+*/
+char *ho_GetVal(FILE *pFil,char *sosi_navn,short *sett_nr)
+{
+ UT_INT64 startpos;
+ short ant_par,navn_nr,type;
+ short funnet = 0;
+ short ferdig = 0;
+ short sett = 0;
+ LB_LESEBUFFER * pLb = &(Sys.BufAdm);
+ char *rp = NULL; /* Retur peker */
+
+
+ // Søk fram til .HODE
+ if (ho_FinnHode(pFil, &startpos) == UT_TRUE) {
+ // Finn riktig info
+ // SOSI-navnet
+ LN_PakkNavn(&(Sys.SosiNavn),sosi_navn,&navn_nr,&ant_par);
+
+ /* Sikkrer at ny lesing startes */
+ pLb->sStatus = LESEBUFFER_TOM;
+ //_fseeki64(pFil,startpos,SEEK_SET);
+ UT_SetPos_i64(pFil,startpos);
+
+ do {
+ sett++;
+ /* Hent "sett" */
+ type = LB_GetSet(pFil,pLb,&(Sys.SosiNavn));
+ if (type >= 0 || type == LEST_GINFO) {
+ if (sett > 1 && pLb->cur_niv == 1) {
+ ferdig = 1;
+
+ } else {
+ if (sett >= *sett_nr) {
+ if (pLb->cur_navn[pLb->cur_niv-1] == navn_nr) {
+ funnet = 1;
+ rp = pLb->pp;
+ *sett_nr = sett;
+ }
+ }
+ }
+ }
+ pLb->set_brukt = SET_BRUKT;
+ } while ( ! ferdig && ! funnet); /* Søk etter navnet */
+ }
+
+ pLb->sStatus = LESEBUFFER_TOM;
+ return rp;
+}
+
+
+/*
+GL-880303
+AR-891124
+CH HO_New Lager nytt hode
+CD =========================================================================
+CD Formål:
+CD Genererer et nytt SOSI-filhode.
+CD Hvis område ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD short koosys i Koordinatsystem
+CD double origo_a i Origo øst
+CD double origo_n i Origo nord
+CD double enhet i Enhet
+CD double enhet_h i Enhet-H
+CD double enhet_d i Enhet-D
+CD double nv_a i Område: Nedre venstre hjørne
+CD double nv_n i
+CD double oh_a i Øvre høyre hjørne
+CD double oh_n i
+CD short sStatus r Status: UT_TRUE = Funnet
+CD UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD sStatus = HO_New(fil,koosys,origo_a,origo_n,enhet,enhet_h-enhet_d,
+CD nv_a,nv_n,oh_a,oh_n);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_New(const char *pszFil,short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d,
+ double nv_a,double nv_n,double oh_a,double oh_n)
+{
+
+ short sStatus = UT_TRUE;
+ FILE * pFil;
+
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_UPDATE,UT_UNKNOWN,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Skriv nytt hode */
+ ho_New(pFil, koosys, origo_a, origo_n, enhet, enhet_h, enhet_d,
+ nv_a, nv_n, oh_a, oh_n);
+
+ fclose (pFil);
+ sStatus = UT_TRUE;
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_New)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+GL-880303
+AR-891124
+CH ho_New Lager nytt hode
+CD =========================================================================
+CD Formål:
+CD Genererer et nytt SOSI-filhode.
+CD Hvis område ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD FILE *fil i Filpeker til sosi-fil.
+CD short koosys i Koordinatsystem
+CD double origo_a i Origo øst
+CD double origo_n i Origo nord
+CD double enhet i Enhet
+CD double enhet_h i Enhet-H
+CD double enhet_d i Enhet-D
+CD double nv_a i Område: Nedre venstre hjørne
+CD double nv_n i
+CD double oh_a i Øvre høyre hjørne
+CD double oh_n i
+CD
+CD Bruk:
+CD ho_New(fil,koosys,origo_a,origo_n,enhet,enhet_h-enhet_d,
+CD nv_a,nv_n,oh_a,oh_n);
+CD =============================================================================
+*/
+void ho_New(FILE *fil,short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d,
+ double nv_a,double nv_n,double oh_a,double oh_n)
+{
+ char tx[LC_MAX_SOSI_LINJE_LEN];
+
+
+ //_fseeki64(fil,0,SEEK_SET);
+ UT_SetPos_i64(fil,0);
+
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,".HODE\r\n");
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..TEGNSETT ISO8859-10\r\n");
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..TRANSPAR\r\n");
+ UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...KOORDSYS %d\r\n",koosys);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...ORIGO-NØ %.0f %.0f\r\n",origo_n,origo_a);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+ //UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET %-.3f\r\n",enhet);
+ LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET",enhet);
+ UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+ if (fabs(enhet-enhet_h)>0.000001) {
+ LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET-H",enhet_h);
+ UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ }
+
+ if (fabs(enhet-enhet_d)>0.000001) {
+ LB_FormaterEnhet(tx,LC_MAX_SOSI_LINJE_LEN,"...ENHET-D",enhet_d);
+ UT_StrCat(tx,"\r\n",LC_MAX_SOSI_LINJE_LEN);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ }
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,"..OMRÅDE\r\n");
+
+ // Hvis nødvendig justeres område
+ if (fabs(oh_n-nv_n) < 0.000001) {
+ nv_n -= 1.0;
+ oh_n += 1.0;
+ }
+ if (fabs(oh_a-nv_a) < 0.000001) {
+ nv_a -= 1.0;
+ oh_a += 1.0;
+ }
+
+ UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...MIN-NØ %.0f %.0f\r\n",nv_n,nv_a);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"...MAX-NØ %.0f %.0f\r\n",oh_n,oh_a);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+ UT_SNPRINTF(tx,LC_MAX_SOSI_LINJE_LEN,"..SOSI-VERSJON %.2f\r\n",((double)FYBA_SOSI_VERSJON)/100.0);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+
+ UT_StrCopy(tx,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n",LC_MAX_SOSI_LINJE_LEN);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,tx);
+ LB_WriteLine(fil,LC_INTERNT_TEGNSETT,".SLUTT\r\n");
+
+ /* chsize(fileno(fil),ftell(fil)-1); */ /* Sett filstørrelse */
+}
+
+
+/*
+AR:1999-07-14
+CH HO_TestSOSI Tester SOSI-filen
+CD =============================================================================
+CD Formål:
+CD Sjekker at filen er en SOSI-fil, og finner posisjonen for .SLUTT.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD UT_INT64 *sluttpos u Posisjon for .SLUTT
+CD short ist r Status: UT_TRUE = OK
+CD UT_FALSE = feil
+CD
+CD Bruk:
+CD ist = HO_TestSOSI(pszFil,&sluttpos);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_TestSOSI(const char *pszFil,UT_INT64 *sluttpos)
+{
+ short sStatus;
+ FILE * pFil;
+
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Sjekk filen */
+ sStatus = ho_TestSOSI(pFil,sluttpos);
+ fclose (pFil);
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_TestSOSI)",err().tx);
+ sStatus = UT_FALSE;
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-891205
+CH ho_TestSOSI Tester SOSI-filen
+CD =============================================================================
+CD Formål:
+CD Sjekker at filen er en SOSI-fil, og finner posisjonen for .SLUTT.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *pFil i Filpeker til sosi-fil.
+CD UT_INT64 *sluttpos u Posisjon for .SLUTT
+CD short ist r Status: UT_TRUE = OK
+CD UT_FALSE = feil
+CD
+CD Bruk:
+CD ist = ho_TestSOSI(pFil,&sluttpos);
+CD =============================================================================
+*/
+short ho_TestSOSI(FILE *pFil,UT_INT64 *sluttpos)
+{
+ short ferdig;
+ char tx[LC_MAX_SOSI_LINJE_LEN];
+ UT_INT64 startpos,filpos;
+ double nv_a,nv_n,oh_a,oh_n;
+ short ist = UT_FALSE;
+
+ *sluttpos = 0;
+
+ // ----- Sjekk at filen starter med .HODE og søk fram til .HODE
+ if (ho_FinnHode(pFil, &startpos) == UT_TRUE) {
+ ist = UT_FALSE;
+
+ // Skann siste del av filen for å finne .SLUTT
+ ferdig = 0;
+ _fseeki64(pFil,-200,SEEK_END);
+ UT_GetPos_i64(pFil,&filpos);
+
+ while (!ferdig && UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx) == UT_OK) {
+ if (*tx == '.' && *(tx+1) == 'S') {
+ if (strncmp(tx,".SLUTT",6) == 0) { /* .SLUTT er funnet */
+ *sluttpos = filpos;
+ ferdig = 1;
+ ist = UT_TRUE;
+ }
+ }
+ //UT_GetPos(pFil,&filpos);
+ filpos = _ftelli64(pFil);
+ }
+
+ if (ist == UT_FALSE) {
+ // .SLUTT ikke er funnet, skann hele filen fra hodet
+ ferdig = 0;
+ filpos = startpos;
+ UT_SetPos_i64(pFil,filpos);
+
+ while (!ferdig && UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx) == UT_OK) {
+ if (*tx == '.' && *(tx+1) == 'S') {
+ if (strncmp(tx,".SLUTT",6) == 0) { /* .SLUTT er funnet */
+ *sluttpos = filpos;
+ ferdig = 1;
+ ist = UT_TRUE;
+ }
+ }
+ UT_GetPos_i64(pFil,&filpos);
+ }
+ }
+ }
+
+
+ /* Sjekk at hodet har transpar og fornuftig område */
+ if (ist == UT_TRUE) {
+ unsigned short usMaske = LC_TR_ALLT;
+ LC_TRANSPAR Trans;
+ ist = ho_GetTransEx(pFil,&usMaske,&Trans);
+
+ if (ist == UT_TRUE) {
+ ist = ho_GetOmr(pFil,&nv_a,&nv_n,&oh_a,&oh_n);
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+HT:1998-05-19
+CH HO_SjekkTegnsett Sjekker tegnsett på SOSI-filen
+CD =============================================================================
+CD Formål:
+CD Sjekker faktisk tegnsett i .HODE.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFil i Fullstendig filnavn
+CD short *psTegnsett u Tegnsett, konstanter definert:
+CD TS_UKJENT = Fikk ikke sjekket tegnsett
+CD TS_DOSN8 = DOS norsk 8-bits(standardverdi)
+CD TS_ND7 = Norsk Data 7-bits
+CD TS_DECM8 = DEC multinasjonal 8-bits
+CD TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD TS_DECN7 = DEC norsk 7-bits
+CD short sStatus r Status: 0 = Ikke funnet
+CD 1 = Ett tegnsett funnet
+CD 2 = Flere tegnsett funnet
+CD Bruk:
+CD sStatus = HO_SjekkTegnsett(fpek,tegnsett);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short HO_SjekkTegnsett(const char *pszFil,short *psTegnsett)
+{
+ short sStatus;
+ FILE * pFil;
+
+
+ /* Åpner filen */
+ pFil = UT_OpenFile(pszFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpnet OK ? */
+ if (sStatus == UT_OK) {
+ /* Sjekk filen */
+ sStatus = ho_SjekkTegnsett(pFil,psTegnsett);
+ fclose (pFil);
+
+ /* Åpningsfeil */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszFil,szError);
+ LC_Error(101,"(HO_SjekkTegnsett)",err().tx);
+ sStatus = 0;
+ }
+
+ return sStatus;
+}
+
+
+/*
+HT-980519
+CH ho_SjekkTegnsett Sjekker tegnsett på SOSI-filen
+CD =============================================================================
+CD Formål:
+CD Sjekker faktisk tegnsett i .HODE.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD FILE *fil i Filpeker til sosi-fil.
+CD short *psTegnsett u Tegnsett, konstanter definert:
+CD TS_UKJENT = Fikk ikke sjekket tegnsett
+CD TS_DOSN8 = DOS norsk 8-bits(standardverdi)
+CD TS_ND7 = Norsk Data 7-bits
+CD TS_DECM8 = DEC multinasjonal 8-bits
+CD TS_ISO8859 = ISO8859-10 Norsk/samisk tegnsett
+CD TS_DECN7 = DEC norsk 7-bits
+CD short sStatus r Status: 0 = Ikke funnet
+CD 1 = Ett tegnsett funnet
+CD 2 = Flere tegnsett funnet
+CD Bruk:
+CD sStatus = ho_SjekkTegnsett(fpek,tegnsett);
+CD =============================================================================
+*/
+short ho_SjekkTegnsett(FILE *fil,short *psTegnsett)
+{
+ char *ch, tx[LC_MAX_SOSI_LINJE_LEN];
+ short tegnsett, lesefeil;
+ short ferdig = 0;
+ short ant = 0;
+
+/* Æ Ø Å æ ø å
+TS_DOSN8 146 157 143 145 155 134
+TS_ND7 91 92 93 123 124 125
+TS_ISO8859 198 216 197 230 248 229 */
+ static unsigned char atab[256] =
+ { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 19 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 39 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 59 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 79 */
+ 0,0,0,0,0,0,0,0,0,0,0,TS_ND7,TS_ND7,TS_ND7,0,0,0,0,0,0, /* 99 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 119 */
+ 0,0,0,TS_ND7,TS_ND7,TS_ND7,0,0,0,0,0,0,0,0,TS_DOSN8,0,0,0,0,0, /* 139 */
+ 0,0,0,TS_DOSN8,0,TS_DOSN8,TS_DOSN8,0,0,0,0,0,0,0,0,TS_DOSN8,0,TS_DOSN8,0,0, /* 159 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 179 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TS_ISO8859,TS_ISO8859,0, /* 199 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TS_ISO8859,0,0,0, /* 219 */
+ 0,0,0,0,0,0,0,0,0,TS_ISO8859,TS_ISO8859,0,0,0,0,0,0,0,0,0, /* 239 */
+ 0,0,0,0,0,0,0,0,TS_ISO8859,0,0,0,0,0,0,0 };
+
+
+ tegnsett = TS_UKJENT;
+
+ /* Sjekker hva som faktisk er tegnsettet i .HODE,
+ starter først på filen og leser */
+ UT_SetPos_i64(fil,0);
+
+ /* Leser første linje i .HODE */
+ lesefeil = UT_ReadLineNoComm(fil,LC_MAX_SOSI_LINJE_LEN,tx);
+ while (!ferdig && ! lesefeil ){
+
+ /* Sjekker tegnsett*/
+ for (ch=tx; *ch; ch++) {
+
+ /* Hvis vi har fått sjekket tegnsettet, og det
+ ikke er funnet tidligere tas det vare på nå */
+ if (atab[(unsigned char)*ch] && !(atab[(unsigned char)*ch] & tegnsett)) {
+ tegnsett |= atab[(unsigned char)*ch];
+ ant++;
+ }
+ }
+
+ /* Leser eventuellt neste linje i .HODE */
+ if (!ferdig) lesefeil = UT_ReadLineNoComm(fil,LC_MAX_SOSI_LINJE_LEN,tx);
+
+ /* Slutt på .HODE? */
+ ferdig = *(tx+1) != '.';
+ }
+
+ *psTegnsett = tegnsett;
+
+ return ant;
+}
+
+
+/*
+AR:2004-05-05
+!---------------------------------------------------------------!
+! ho_TestFyllKommentar - Tester om en streng er fyll/kommentar. !
+! !
+! Retur: UT_TRUE = linjen er fyll/kommentar !
+! UT_FALSE = linjen inneholder annen informasjon !
+! !
+!---------------------------------------------------------------!
+*/
+static short ho_TestFyllKommentar(const char *pszTx)
+{
+ for (; *pszTx; ++pszTx) {
+ if (!UT_IsSpace(*pszTx) && *pszTx != '!') return (UT_FALSE);
+ if (*pszTx == '!') return (UT_TRUE);
+ }
+
+ return (UT_TRUE);
+}
+
+
+/*
+AR:2004-05-05
+!---------------------------------------------------------------------!
+! ho_FinnHode - Finner filposisjonen til .HODE !
+! !
+! Retur: UT_TRUE = Lovlig hode er funnet !
+! UT_FALSE = .HODE er ikke funnet, !
+! eller .HODE er ikke første logiske info i filen. !
+! !
+!---------------------------------------------------------------------!
+*/
+short ho_FinnHode(FILE *pFil, UT_INT64 *lHodepos)
+{
+ char tx[LC_MAX_SOSI_LINJE_LEN], *cp;
+ short ierr;
+
+ *lHodepos = 0L;
+
+ // ----- Sjekk at filen starter med .HODE
+ UT_SetPos_i64(pFil,0);
+
+ do
+ {
+ // Husk filposisjonen
+ *lHodepos = _ftelli64(pFil);
+ // Les
+ if ((ierr = UT_ReadLine(pFil,LC_MAX_SOSI_LINJE_LEN,tx)) != UT_OK) {
+
+ return UT_FALSE; // ===> Retur pga. lesefeil
+ }
+ } while (ho_TestFyllKommentar(tx) == UT_TRUE);
+
+
+ // ----- Har nå funnet en linje som inneholder logisk informasjon
+
+ // Hopp over blanke på starten av linjen
+ cp = &tx[0];
+ while (UT_IsSpace(*cp)) {
+ ++cp;
+ ++(*lHodepos);
+ }
+
+ if (strncmp(cp,".HODE",5) == 0) {
+ return UT_TRUE; // ===> Retur, .HODE er funnet
+ }
+
+ return UT_FALSE; // ===> Retur, .HODE er ikke funnet
+}
diff --git a/src/FYBA/FYLB.cpp b/src/FYBA/FYLB.cpp
new file mode 100644
index 0000000..21c1472
--- /dev/null
+++ b/src/FYBA/FYLB.cpp
@@ -0,0 +1,4646 @@
+/* === 920909 ============================================================ */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylb.c */
+/* Ansvarlig: Andreas Røstad */
+/* Innhold: Bufferhandteringsrutiner for fysak-pc */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <time.h>
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+
+
+/* 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<LC_RxGr>)
+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<LC_RxGr>)
+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<LC_RxGr>)
+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<LC_RxGr>)
+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 = min( max(1,fra_punkt), max(1,Sys.pGrInfo->nko) );
+ antall = min( max(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; pt<Sys.pGrInfo->nko; 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<LC_RxGr>)
+CD short gnavn r Gruppenavn. (Se under $LENKE<LC_RxGr>)
+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<LC_RxGr>)
+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_pt<nko; til_pt++,fra_pt--) {
+ *(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));
+ }
+ }
+
+ /* 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<lAntRef; l++) {
+ if (labs(*plRef) == lGmlSnr) {
+ if (*plRef > 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<LC_RxGr>)
+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<LC_RxGr>)
+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 = max(1,UT_RoundDS(fabs(min(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; s<antall; s++) {
+ /* Beregn ofset og blank ut linjen */
+ if (linje == 1) {
+ Sys.Ginfo.ulOfset[0] = 0;
+ *Sys.Ginfo.pszTx = '\0';
+ } else {
+ /* Førte posisjon etter forrige linje */
+ len = (short)strlen(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-2]);
+ Sys.Ginfo.ulOfset[linje-1] = Sys.Ginfo.ulOfset[linje-2] + len + 1;
+ *(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[linje-1]) = '\0';
+ }
+
+ linje++;
+ }
+ }
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",linje);
+ LC_Error(40,"(LC_InsGiL)",err().tx);
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_InsGiL)","");
+ }
+
+ return(Sys.pGrInfo->ngi);
+}
+
+
+/*
+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 = max(linje,2); /* 2 er første lovlige linje */
+ antall -= (start-linje); /* Juster antall tilsvarende */
+
+ /* Max antall er resten av GINFO */
+ antall = min(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 = max(linje,1); /* 1 er første lovlige linje */
+ antall -= (start-linje); /* Juster antall tilsvarende */
+
+ /* Max antall er resten av punktene */
+ antall = min(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; s<antall && ulP1==LC_INGEN_PINFO; s++,pI++) {
+ if (pI->ulPiOfset != 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);
+ exit (2);
+ }
+
+ 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; lNr<pFil->lAntGr; 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; l<antall; l++,pt++) {
+ nah = ((Sys.pInfo + pt)->dHoyde != 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; lNr<pFil->lAntGr; 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 */
+ }
+ exit(1);
+ }
+
+ /* 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);
+ exit(1);
+ }
+
+ /* 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<lAntRef; ++l,++plRef)
+ {
+ if (labs(*plRef) == lGmlSnr)
+ {
+ // Skal bytte serienummer
+ if (lNyttSnr != 0)
+ {
+ if (*plRef > 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);
+}
diff --git a/src/FYBA/FYLD.cpp b/src/FYBA/FYLD.cpp
new file mode 100644
index 0000000..57eacfd
--- /dev/null
+++ b/src/FYBA/FYLD.cpp
@@ -0,0 +1,111 @@
+/* === 920413 ============================================================= */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fyld.c */
+/* Innhold: Lagring og henting av indekstabeller */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <stdlib.h>
+
+
+
+
+/* Globale strukturer for fyba */
+extern LC_SYSTEMADM Sys;
+
+
+
+/*
+AR:2004-05-04
+CH LC_DelIdx Sletter indeksfilene
+CD ==========================================================================
+CD Formål:
+CD Sletter indeksfilene for gitt SOSI-fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *szSosFil i SOSI-filnavn
+CD
+CD Bruk:
+CD LC_DelIdx(szSosFil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_DelIdx(char *szSosFil)
+{
+ char fil[_MAX_PATH],sdir[_MAX_PATH];
+ char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+ char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+
+
+ // Bygg opp fullstendig filnavn
+ UT_FullPath(fil,szSosFil,_MAX_PATH);
+
+ // Splitt filnavnet
+ UT_splitpath(fil,drive1,dir1,fname1,ext1);
+
+ // Lag subdirectory navn
+ if ( *Sys.szIdxPath != 0) {
+ // Gitt sti for indeksfilene
+ UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+ UT_makepath(sdir,drive2,dir2,fname1,"");
+ } else {
+ // Ikke gitt sti.
+ UT_makepath(sdir,drive1,dir1,fname1,"");
+ }
+
+ /* Lag sti til filer på sub-directory */
+ UT_splitpath(sdir,drive2,dir2,fname2,ext2);
+ UT_StrCat(dir2,fname1,_MAX_DIR);
+ UT_StrCat(dir2,UT_STR_SLASH,_MAX_DIR);
+
+ //
+ // Fjern indeks filene
+ //
+
+ // Administrasjonstabeller
+ UT_makepath(fil,drive2,dir2,"Adm",".Idx");
+ UT_DeleteFile(fil);
+ UT_makepath(fil,drive2,dir2,"admin",".idx"); /* FYBA - C */
+ UT_DeleteFile(fil);
+
+ // Ringbuffer
+ UT_makepath(fil,drive2,dir2,"Rb",".Idx");
+ UT_DeleteFile(fil);
+
+ // Inf
+ UT_makepath(fil,drive2,dir2,"Inf",".Idx"); /* FYBA - D */
+ UT_DeleteFile(fil);
+ UT_makepath(fil,drive2,dir2,"info",".idx"); /* FYBA - C */
+ UT_DeleteFile(fil);
+
+ // Gruppetabell
+ UT_makepath(fil,drive2,dir2,"Grt",".Idx");
+ UT_DeleteFile(fil);
+ UT_makepath(fil,drive2,dir2,"grtab",".idx"); /* FYBA - C */
+ UT_DeleteFile(fil);
+
+ // Serienummer-tabell */
+ UT_makepath(fil,drive2,dir2,"Snr",".Idx");
+ UT_DeleteFile(fil);
+
+ // Brukt-tabell
+ UT_makepath(fil,drive2,dir2,"Bt",".Idx");
+ UT_DeleteFile(fil);
+ UT_makepath(fil,drive2,dir2,"btab",".idx"); /* FYBA - C */
+ UT_DeleteFile(fil);
+
+ // Geografisk søketabell
+ UT_makepath(fil,drive2,dir2,"Geo",".Idx");
+ UT_DeleteFile(fil);
+
+ // Flate geografisk søketabell
+ UT_makepath(fil,drive2,dir2,"flate",".idx"); /* FYBA - C */
+ UT_DeleteFile(fil);
+
+ //
+ // Fjern subdirectory
+ //
+ UT_DeleteDir(sdir);
+}
diff --git a/src/FYBA/FYLE.cpp b/src/FYBA/FYLE.cpp
new file mode 100644
index 0000000..8f0add6
--- /dev/null
+++ b/src/FYBA/FYLE.cpp
@@ -0,0 +1,494 @@
+#include "stdafx.h"
+#include "fyba_strings.h"
+
+/*
+AR-940110
+CH LC_StrError Feilmeldingstekst
+CD ==========================================================================
+CD Formål:
+CD Henter feilmeldingstekst og nivå for et feilmeldingsnummer.
+CD Strengen legges i en egen feilmeldingsstruktur for feil-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "feil-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short feil_nr i Feilmeldingsnummer
+CD char **feilmelding u Peker til feilmeldingstekst avslutta med '\0'.
+CD short *strategi r Feilnivå (0-4)
+CD 0 = Ikke i bruk. (Utkoblet, testmeldinger mm.)
+CD 1 = Lite alvorlig. Vises kort.
+CD 2 = Normal feilmelding. Vises ca. 1 sekund.
+CD 3 = Alvorlig. Krev tastetrykk for å fortsette.
+CD 4 = Svært alvorlig. Programmet bør avbrytes.
+CD
+CD Bruk:
+CD strategi = LC_StrError(ckap,feil_nr,&feilmeldingspeker);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_StrError(short feil_nr,char **feilmelding)
+{
+#define MAX_FEIL_LEN 200
+ static char feil[MAX_FEIL_LEN]; /* Feilmeldings-streng */
+ short strategi = 0;
+
+
+ switch(feil_nr) { /* Finn riktig melding */
+/* --------------------- LO --------------------------- */
+ case 1:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_BASE_UNKNOWN_TYPE,MAX_FEIL_LEN);
+ break;
+ case 2:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_BASE_TOO_MANY_GROUPS,MAX_FEIL_LEN);
+ break;
+ case 3:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_NOT_FOUND,MAX_FEIL_LEN);
+ break;
+ case 4:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_BASE_FYBA_NOT_INITD,MAX_FEIL_LEN);
+ break;
+ case 5:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_BASE_NOT_OPEN,MAX_FEIL_LEN);
+ break;
+ case 6:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_OPEN_FAILED,MAX_FEIL_LEN);
+ break;
+ case 7:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_OMRAADE_MISSING,MAX_FEIL_LEN);
+ break;
+ case 8:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_MIN_NOE_MISSING,MAX_FEIL_LEN);
+ break;
+ case 9:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_MAX_NOE_MISSING,MAX_FEIL_LEN);
+ break;
+ case 10:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_BASE_INDEX_ABORTED,MAX_FEIL_LEN);
+ break;
+ case 13:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_PERM_DENIED,MAX_FEIL_LEN);
+ break;
+ case 101:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_BASE_OPEN_FAILED,MAX_FEIL_LEN);
+ break;
+ case 102:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_NEW_HEADER,MAX_FEIL_LEN);
+ break;
+ case 103:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_NOT_SOSI,MAX_FEIL_LEN);
+ break;
+ case 104:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_FILE_OMRAADE_INVALID,MAX_FEIL_LEN);
+ break;
+
+ case 105:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_SAVE_INVALID_FILEPTR,MAX_FEIL_LEN);
+ break;
+
+ case 106:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_OPEN_BASE_IS_KLADDE,MAX_FEIL_LEN);
+ break;
+
+/* --------------------- HO --------------------------- */
+ case 12:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_READ_ERROR_HODE,MAX_FEIL_LEN);
+ break;
+ case 14:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_TRANSPAR_MISSING,MAX_FEIL_LEN);
+ break;
+ case 15:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_KOORDSYS_MISSING,MAX_FEIL_LEN);
+ break;
+ case 16:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_ORIGO_MISSING,MAX_FEIL_LEN);
+ break;
+ case 17:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_FILE_ENHET_MISSING,MAX_FEIL_LEN);
+ break;
+/* --------------------- LN --------------------------- */
+ case 21:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_NAME_TABLE_FULL,MAX_FEIL_LEN);
+ break;
+
+ case 22:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NAME,MAX_FEIL_LEN);
+ break;
+
+/* --------------------- LB --------------------------- */
+ case 31:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_FILE_NO_CURRENT_GROUP,MAX_FEIL_LEN);
+ break;
+ case 32:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_OPEN_INVALID_EXTERN,MAX_FEIL_LEN);
+ break;
+ case 33:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_SAVE_INVALID_EXTERN,MAX_FEIL_LEN);
+ break;
+ case 34:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_SAVE_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+ break;
+ case 35:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_GROUP_DELETED,MAX_FEIL_LEN);
+ break;
+ case 36:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_FILE_INVALID_GROUP_NR,MAX_FEIL_LEN);
+ break;
+ case 37:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_FILE,MAX_FEIL_LEN);
+ break;
+ case 38:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NEW_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+ break;
+ case 39:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NEW_TOO_MANY_GROUPS,MAX_FEIL_LEN);
+ break;
+ case 40:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_LINE_GI,MAX_FEIL_LEN);
+ break;
+ case 41:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NEW_INVALID_LINE_COO,MAX_FEIL_LEN);
+ break;
+ case 42:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_SLUTT_MISSING,MAX_FEIL_LEN);
+ break;
+ case 43:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_READ_ERROR,MAX_FEIL_LEN);
+ break;
+ case 44:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_GROUP_REFERRED_TO,MAX_FEIL_LEN);
+ break;
+ case 47:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GI_LINE_1,MAX_FEIL_LEN);
+ break;
+ case 48:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_CANT_REMOVE_HEADER,MAX_FEIL_LEN);
+ break;
+ case 49:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_NO_CURRENT_GROUP,MAX_FEIL_LEN);
+ break;
+ case 50:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_DEL_UNKNOWN_FLAG,MAX_FEIL_LEN);
+ break;
+ case 91:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_DEL_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+ break;
+ case 92:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_ERR_FILESIZE_CHANGE,MAX_FEIL_LEN);
+ break;
+ case 93:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_DISK_SOON_FULL,MAX_FEIL_LEN);
+ break;
+ case 94:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NOT_A_HEADER,MAX_FEIL_LEN);
+ break;
+ case 95:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_DEL_NOT_SEQUENTIAL,MAX_FEIL_LEN);
+ break;
+ case 96:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NO_CHANGE_HEADERS,MAX_FEIL_LEN);
+ break;
+ case 97:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_REWRITE_HEADER,MAX_FEIL_LEN);
+ break;
+ case 98:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_SAVE_NOT_A_HEADER,MAX_FEIL_LEN);
+ break;
+ case 99:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_CANT_COPY_COORD,MAX_FEIL_LEN);
+ break;
+ case 100:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_CANT_COPY_COORD_ROOM,MAX_FEIL_LEN);
+ break;
+ case 141:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_ENHET_NOT_SET,MAX_FEIL_LEN);
+ break;
+ case 142:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_READ_FILE_SIZE,MAX_FEIL_LEN);
+ break;
+ case 143:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_PINFO_LONG_OR_NO_NOE,MAX_FEIL_LEN);
+ break;
+ case 144:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_LOGIC_FAIL,MAX_FEIL_LEN);
+ break;
+ case 145:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_MAX_1_KP_OR_NO_NOE,MAX_FEIL_LEN);
+ break;
+ case 146:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NO_ROOM_IN_HEADER,MAX_FEIL_LEN);
+ break;
+ case 147:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GAP,MAX_FEIL_LEN);
+ break;
+ case 148:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MANY_COORDINATES,MAX_FEIL_LEN);
+ break;
+ case 149:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MANY_GINFO,MAX_FEIL_LEN);
+ break;
+ case 150:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MUCH_GINFO,MAX_FEIL_LEN);
+ break;
+ case 161:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MUCH_PINFO,MAX_FEIL_LEN);
+ break;
+ case 162:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_EXTEND_GROUP,MAX_FEIL_LEN);
+ break;
+ case 163:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_READ_NO_WRITE_ACCESS,MAX_FEIL_LEN);
+ case 164:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_READ_LINE_TOO_LONG,MAX_FEIL_LEN);
+ break;
+
+
+/* --------------------- LX --------------------------- */
+ case 51:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_POINT,MAX_FEIL_LEN);
+ break;
+ case 52:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GINFO,MAX_FEIL_LEN);
+ break;
+ case 53:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_NODE,MAX_FEIL_LEN);
+ break;
+ case 54:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NAME,MAX_FEIL_LEN);
+ break;
+ case 55:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_PINFO_TOO_LONG,MAX_FEIL_LEN);
+ break;
+ case 56:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_REF,MAX_FEIL_LEN);
+ break;
+ case 57:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_ENHET ,MAX_FEIL_LEN);
+ break;
+ case 58:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_NGIS_LAG,MAX_FEIL_LEN);
+ break;
+ case 59:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_BUE,MAX_FEIL_LEN);
+ break;
+ case 60:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_CANT_CHANGE_ORIGO_NOE,MAX_FEIL_LEN);
+ break;
+ case 131:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_PROB_TOO_LONG_PINFO,MAX_FEIL_LEN);
+ break;
+ case 132:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NO_HOEYDE_WITH_NAD,MAX_FEIL_LEN);
+ break;
+ case 133:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NO_HOEYDE_WITH_NAH,MAX_FEIL_LEN);
+ break;
+ case 134:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_LINE_TOO_LONG,MAX_FEIL_LEN);
+ break;
+
+
+/* --------------------- LS --------------------------- */
+ case 61:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_SERIAL,MAX_FEIL_LEN);
+ break;
+
+/* --------------------- LI --------------------------- */
+ case 71:
+ strategi = 2;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_LINE_NR,MAX_FEIL_LEN);
+ break;
+ case 72:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_GROUP_NR,MAX_FEIL_LEN);
+ break;
+ case 73:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_BUFFER,MAX_FEIL_LEN);
+ break;
+ case 74:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_BUFFER,MAX_FEIL_LEN);
+ break;
+ case 75:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_MUST_INIT_INDEX,MAX_FEIL_LEN);
+ break;
+ case 79:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_SEARCHT,MAX_FEIL_LEN);
+ break;
+ case 80:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_SEARCHT,MAX_FEIL_LEN);
+ break;
+ case 111:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_GROUPT,MAX_FEIL_LEN);
+ break;
+ case 112:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_GROUPT,MAX_FEIL_LEN);
+ break;
+ case 113:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_SERIALT,MAX_FEIL_LEN);
+ break;
+ case 114:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_SERIALT,MAX_FEIL_LEN);
+ break;
+ case 115:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_INFOT,MAX_FEIL_LEN);
+ break;
+ case 116:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_INFOT,MAX_FEIL_LEN);
+ break;
+ case 117:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_INFOT_FULL,MAX_FEIL_LEN);
+ break;
+ case 118:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_READING_BRUKT,MAX_FEIL_LEN);
+ break;
+ case 119:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_ERR_WRITING_BRUKT,MAX_FEIL_LEN);
+ break;
+ case 120:
+ strategi = 4;
+ UT_StrCopy(feil,FYBA_STRING_NO_BLANKS_FILENAME,MAX_FEIL_LEN);
+ break;
+
+
+/* --------------------- LR --------------------------- */
+
+/* --------------------- LU --------------------------- */
+ case 121:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MANY_CHOICES,MAX_FEIL_LEN);
+ break;
+ case 122:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_MISPLACED_CHOICE,MAX_FEIL_LEN);
+ break;
+ case 123:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_GROUP_CHOICE_MISSING,MAX_FEIL_LEN);
+ break;
+ case 124:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_INVALID_CHOICE,MAX_FEIL_LEN);
+ break;
+ case 125:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_NO_COMPLEX_CHOICE,MAX_FEIL_LEN);
+ break;
+ case 126:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_GAP_IN_LEVEL,MAX_FEIL_LEN);
+ break;
+ case 127:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_TOO_MANY_PRIORITIES,MAX_FEIL_LEN);
+ break;
+ case 128:
+ strategi = 3;
+ UT_StrCopy(feil,FYBA_STRING_DUPLICATE_DEFINITION,MAX_FEIL_LEN);
+ break;
+
+/* --------- Standard melding ved ukjent nr. ------------------- */
+ default:
+ strategi = 3;
+ UT_SNPRINTF(feil,MAX_FEIL_LEN,FYBA_STRING_UNKNOWN_ERROR,feil_nr);
+ break;
+ }
+
+ *feilmelding = feil;
+
+ return strategi;
+}
diff --git a/src/FYBA/FYLH.cpp b/src/FYBA/FYLH.cpp
new file mode 100644
index 0000000..93fafd5
--- /dev/null
+++ b/src/FYBA/FYLH.cpp
@@ -0,0 +1,1035 @@
+/*
+CH FYLH AR-900503 BIBLIOTEK
+CD =================================================================
+CD
+CD Eier.......: STATENS KARTVERK / FYSAK-prosjektet
+CD Ansvarlig..: Georg Langerak / Andreas Røstad
+CD
+CD Rutiner for å handtere hodet på SOSI-filer når dette ligger
+CD som ginfo i RB.
+CD ==============================================================
+*/
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <time.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+/* Globale variabler */
+extern LC_SYSTEMADM Sys;
+
+
+
+/*
+AR:2000-10-07
+CH LC_PutTransEx Legger inn ..TRANSPAR i hodet
+CD ==========================================================================
+CD Formål:
+CD Legger inn innholdet under ..TRANSPAR i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode versjon 3.x.
+CD
+CD Må velge mellom KOORDSYS, TRANSSYS eller GEOSYS.
+CD Kun en av disse kan benyttes i filhodet.
+CD KOORDSYS er den mest vanlige måte å definere referansesystem.
+CD
+CD GEOKOORD skal benyttes for GEOSYS og for TRANSSYS
+CD
+CD Må velge mellom VERT-DATUM eller VERT-INT.
+CD VERT-DATUM er den mest vanlige beskrivelsesmåten.
+CD
+CD Følgende kompaktifisering brukes:
+CD ..TRANSPAR
+CD ...KOORDSYS <SYSKODE> <DATUM> <PROJEK>
+CD ...TRANSSYS <TILSYS> <KONSTA1> <KONSTB1> <KONSTA2> <KONSTB2> <KONSTC1> <KONSTC2>
+CD ...GEOSYS <GEO-DATUM> <GEO-PROJ> <GEO-SONE>
+CD ...GEOKOORD <GEOKOORD>
+CD ...ORIGO-NØ <ORIGO-N> <ORIGO-Ø>
+CD ...ENHET <ENHET>
+CD ...ENHET-H <ENHET-H>
+CD ...ENHET-D <ENHET-D>
+CD ...VERT-DATUM <HØYDE-REF> <DYBDE-REF> <FRISEIL-REF> <HØYDE-TYPE>
+CD ...VERT-INT <H-REF-INT> <D-REF-INT> <F-REF-INT>
+CD ...VERT-DELTA <V-DELTA-MIN> <V-DELTA-MAX>
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short usMaske i Maske som styrer hvilke deler av TRANSPAR som brukt
+CD Følgende konstanter er definert:
+CD LC_TR_KOORDSYS - Koordsys
+CD LC_TR_TRANSSYS - Transsys
+CD LC_TR_GEOSYS - Geosys
+CD LC_TR_GEOKOORD - Geokoord
+CD LC_TR_ORIGO - Origo-nø
+CD LC_TR_ENHET - Enhet
+CD LC_TR_ENHETH - Enhet-h
+CD LC_TR_ENHETD - Enhet-d
+CD LC_TR_VERTDATUM - Vert-datum
+CD LC_TR_VERTINT - Vert-int
+CD LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR * pTrans i Peker til struktur med ..TRANSPAR informasjonen.
+CD short ngi r Antall GINFO-linjer etter oppdateringen.
+CD
+CD Bruk:
+CD LC_TRANSPAR Trans;
+CD unsigned short usMaske = LC_TR_KOORDSYS | LC_TR_ORIGO | LC_TR_ENHET;
+CD Trans.sKoordsys = 32;
+CD Trans.dOrigoAust = 0.0;
+CD Trans.dOrigoNord = 0.0;
+CD Trans.dEnhet = 1.0;
+CD ngi = LC_PutTransEx(usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTransEx(unsigned short usMaske, LC_TRANSPAR * pTrans)
+{
+ short i,lin,ngi;
+ long nko;
+ unsigned short info;
+ char *cp = NULL;
+ char szGiLin[LC_MAX_SOSI_LINJE_LEN];
+
+
+ /* Ingen aktuell gruppe */
+ if (Sys.GrId.lNr == INGEN_GRUPPE) {
+ LC_Error(49,"(LC_PutTrans)","");
+ return Sys.pGrInfo->ngi;
+ }
+
+ /* Aktuell gruppe er ikke .HODE */
+ if (Sys.pGrInfo->gnavn != L_HODE) {
+ LC_Error(94,"(LC_PutTrans)","");
+ return Sys.pGrInfo->ngi;
+ }
+
+
+ /* ----- Fjerner gammel transpar ----- */
+ LC_GetGrPara(&ngi,&nko,&info);
+ lin=2;
+ if (LC_GetGP("..TRANSPAR",&lin,ngi) != NULL) {
+ i = lin;
+ do {
+ i++;
+ if (i <= ngi) cp = LC_GetGi(i);
+ } while ( i <= ngi && cp[2] == '.' );
+ /* i peker nå til første linje etter hele ..TRANSPAR med undernivåer */
+
+ LC_DelGiL(lin,(short)(i-lin));
+ }
+
+ /* ----- Legger inn ny transpar ----- */
+ LC_PutGi(LC_AppGiL(),"..TRANSPAR");
+
+ /* Koordsys */
+ if ((usMaske & LC_TR_KOORDSYS) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...KOORDSYS %hd %s %s",pTrans->sKoordsys,pTrans->szKoordsysDatum,pTrans->szKoordsysProjek);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Transsys */
+ if ((usMaske & LC_TR_TRANSSYS) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...TRANSSYS %hd %f %f %f %f %f %f", pTrans->sTranssysTilsys,
+ pTrans->dTranssysKonstA1, pTrans->dTranssysKonstB1,
+ pTrans->dTranssysKonstA2, pTrans->dTranssysKonstB2,
+ pTrans->dTranssysKonstC1, pTrans->dTranssysKonstC2);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Geosys */
+ if ((usMaske & LC_TR_GEOSYS) != 0) {
+ if (pTrans->sGeosysProj != LC_TR_GEOSYS_INGEN_VERDI)
+ {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOSYS %hd %hd %hd", pTrans->sGeosysDatum,
+ pTrans->sGeosysProj, pTrans->sGeosysSone);
+ }
+ else
+ {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOSYS %hd", pTrans->sGeosysDatum);
+ }
+
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Geokoord */
+ if ((usMaske & LC_TR_GEOKOORD) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...GEOKOORD %hd", pTrans->sGeoKoord);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Origo */
+ if ((usMaske & LC_TR_ORIGO) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...ORIGO-NØ %.0f %.0f", pTrans->Origo.dNord, pTrans->Origo.dAust);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Enhet */
+ if ((usMaske & LC_TR_ENHET) != 0) {
+ LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN, "...ENHET", pTrans->dEnhet));
+ }
+
+ /* Enhet-h */
+ if ((usMaske & LC_TR_ENHETH) != 0) {
+ /*
+ * Hvis enhet og enhet_h er like
+ * skal det ikke legges inn ENHET-H
+ */
+ if (fabs(pTrans->dEnhet-pTrans->dEnhet_h) > 0.0000001) {
+ LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN,"...ENHET-H",pTrans->dEnhet_h));
+ }
+ }
+
+ /* Enhet-d */
+ if ((usMaske & LC_TR_ENHETD) != 0) {
+ /*
+ * Hvis enhet og enhet_d er like
+ * skal det ikke legges inn ENHET-D
+ */
+ if (fabs(pTrans->dEnhet-pTrans->dEnhet_d) > 0.0000001) {
+ LC_PutGi(LC_AppGiL(),LB_FormaterEnhet(szGiLin,LC_MAX_SOSI_LINJE_LEN,"...ENHET-D",pTrans->dEnhet_d));
+ }
+ }
+
+ /* Vert-datum */
+ if ((usMaske & LC_TR_VERTDATUM) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-DATUM %s %s %s %s", pTrans->szVertdatHref,
+ pTrans->szVertdatDref, pTrans->szVertdatFref, pTrans->szVertdatHtyp);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Vert-int */
+ if ((usMaske & LC_TR_VERTINT) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-INT %hd %hd %hd", pTrans->sVertintHref,
+ pTrans->sVertintDref, pTrans->sVertintFref);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ /* Vert-delta */
+ if ((usMaske & LC_TR_VERTDELTA) != 0) {
+ UT_SNPRINTF(szGiLin, LC_MAX_SOSI_LINJE_LEN, "...VERT-DELTA %hd %hd", pTrans->sVdeltaMin, pTrans->sVdeltaMax);
+ LC_PutGi(LC_AppGiL(),szGiLin);
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-910920
+CH LC_PutTrans Legger inn ..TRANSPAR i hodet
+CD ==========================================================================
+CD Formål:
+CD Legger inn transformasjonsparametrene i ginfo i aktuell gruppe.
+CD Forutsetter at aktuell gruppe er et SOSI-filhode versjon 3.x.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD For nye programmer bør LC_PutTransEx benyttes. LC_PutTransEx er
+CD kompatibel med nye versjoner av SOSI.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short koosys i Koordinatsystem
+CD double origo_a i Origo øst
+CD double origo_n i Origo nord
+CD double enhet i Enhet
+CD double enhet_h i Enhet-H
+CD double enhet_d i Enhet-D
+CD short ngi r Antall GINFO-linjer etter oppdateringen.
+CD
+CD Bruk:
+CD ngi = LC_PutTrans(koosys,origo_a,origo_n,enhet,enhet_h,enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTrans(short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d)
+{
+ short i,ngi,linje_enhet;
+ char c[80];
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+ UT_SNPRINTF(c,80,"%d",koosys);
+ ngi = LC_PutGP("...KOORDSYS",c,&i);
+ UT_SNPRINTF(c,80," %.0f %.0f",origo_n,origo_a);
+ ngi = LC_PutGP("...ORIGO-NØ",c,&i);
+ linje_enhet = 2;
+ LC_GetGP("...ENHET",&linje_enhet,ngi);
+ LC_PutGi(linje_enhet,LB_FormaterEnhet(c,80,"...ENHET",enhet));
+
+ /*
+ * Hvis enhet og enhet_h er like
+ * skal det ikke legges inn ENHET-H,
+ * eventuell gammel linje fjernes.
+ */
+
+ if (fabs(enhet-enhet_h) < 0.0000001) {
+ i = 2;
+ if (LC_GetGP("...ENHET-H",&i,ngi) != NULL) {
+ LC_DelGiL(i,1);
+ }
+
+ } else {
+
+ i = 2;
+ if (LC_GetGP("...ENHET-H",&i,ngi) == NULL) {
+ i = linje_enhet + 1;
+ ngi = LC_InsGiL(i,1); /* Ikke funnet, tildel ny linje */
+ }
+ LC_PutGi(i,LB_FormaterEnhet(c,80,"...ENHET-H",enhet_h));
+ }
+
+ /*
+ * Hvis enhet og enhet_d er like
+ * skal det ikke legges inn ENHET-D,
+ * eventuell gammel linje fjernes.
+ */
+ if (fabs(enhet-enhet_d) < 0.000001) {
+ i = 2;
+ if (LC_GetGP("...ENHET-D",&i,ngi) != NULL) {
+ LC_DelGiL(i,1);
+ }
+
+ } else {
+ i = 2;
+ if (LC_GetGP("...ENHET-D",&i,ngi) == NULL) {
+ i = linje_enhet + 1;
+ ngi = LC_InsGiL(i,1); /* Ikke funnet, tildel ny linje */
+ }
+ LC_PutGi(i,LB_FormaterEnhet(c,80,"...ENHET-D",enhet_d));
+
+ }
+
+ } else{ /* Gruppen er ikke filhode */
+ LC_Error(94,"(LC_PutTrans)","");
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutTrans)","");
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR:2000-10-07
+CH LC_GetTransEx Henter ..TRANSPAR fra hodet
+CD ==========================================================================
+CD Formål:
+CD Henter ut innholdet under ..TRANSPAR fra ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Må velge mellom KOORDSYS, TRANSSYS eller GEOSYS. Kun en av disse kan benyttes i filhodet.
+CD KOORDSYS er den mest vanlige måte å definere referansesystem.
+CD
+CD GEOKOORD skal benyttes for GEOSYS og for TRANSSYS
+CD
+CD Må velge mellom VERT-DATUM eller VERT-INT.
+CD VERT-DATUM er den mest vanlige beskrivelsesmåten.
+CD
+
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short *pusMaske iu [Inn] Styrer hvilke deler av TRANSPAR som skal hentes
+CD [Ut] Viser hvilke deler av TRANSPAR som er funnet/hentet.
+CD Følgende konstanter er definert:
+CD LC_TR_ALLT - Alle deler av ..TRANSPAR hentes
+CD LC_TR_KOORDSYS - Koordsys
+CD LC_TR_TRANSSYS - Transsys
+CD LC_TR_GEOSYS - Geosys
+CD LC_TR_GEOKOORD - Geokoord
+CD LC_TR_ORIGO - Origo-nø
+CD LC_TR_ENHET - Enhet
+CD LC_TR_ENHETH - Enhet-h
+CD LC_TR_ENHETD - Enhet-d
+CD LC_TR_VERTDATUM - Vert-datum
+CD LC_TR_VERTINT - Vert-int
+CD LC_TR_VERTDELTA - Vert-delta
+CD
+CD LC_TRANSPAR * pTrans iu Peker til struktur som skal motta ..TRANSPAR informasjonen.
+CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=feil (ikke funnet).
+CD
+CD Bruk:
+CD unsigned short usMaske = LC_TR_ALLT;
+CD LC_TRANSPAR Trans;
+CD ist = LC_GetTransEx(&usMaske,&Trans);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTransEx(unsigned short *pusMaske, LC_TRANSPAR * pTrans)
+{
+ short lin,ngi,itxi;
+ long nko;
+ unsigned short us;
+ char *cp;
+ short ist = UT_TRUE;
+ unsigned short usMaskeInn = *pusMaske;
+
+
+ /* Nullstiller pTrans */
+ memset(pTrans,0,sizeof(LC_TRANSPAR));
+
+ /* Nullstiller masken */
+ *pusMaske = 0;
+
+ LC_GetGrPara(&ngi,&nko,&us);
+
+
+ /* ----- Div. kontroller ----- */
+
+ /* Ingen aktuell gruppe */
+ if (Sys.GrId.lNr == INGEN_GRUPPE) {
+ LC_Error(49,"(LC_GetTransEx)","");
+ return UT_FALSE;
+ }
+ /* Gruppen er ikke filhode */
+ if (Sys.pGrInfo->gnavn != L_HODE) {
+ LC_Error(94,"(LC_GetTransEx)","");
+ return UT_FALSE;
+ }
+ /* Transpar */
+ lin=2;
+ if (LC_GetGP("..TRANSPAR",&lin,ngi) == NULL) {
+ LC_Error(14,"(LC_GetTransEx)","");
+ return UT_FALSE;
+ }
+
+
+ /* ----- Henter verdier ----- */
+
+ /* Koordsys */
+ if ((usMaskeInn & LC_TR_KOORDSYS) != 0) {
+ lin = 2;
+ cp = LC_GetGP("...KOORDSYS",&lin,ngi);
+ if (cp == NULL) {
+ lin=2;
+ cp = LC_GetGP("..KOORDSYS",&lin,ngi);
+ }
+ if (cp != NULL) {
+ *pusMaske |= LC_TR_KOORDSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sKoordsys);
+ UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysDatum);
+ UT_StrToken(cp,itxi,&itxi,36,pTrans->szKoordsysProjek);
+ }
+ }
+
+ /* Transsys */
+ if ((usMaskeInn & LC_TR_TRANSSYS) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...TRANSSYS",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_TRANSSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sTranssysTilsys);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstA2);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstB2);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC1);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->dTranssysKonstC2);
+ }
+ }
+
+ /* Geosys */
+ if ((usMaskeInn & LC_TR_GEOSYS) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...GEOSYS",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_GEOSYS;
+ UT_StrShort(cp,0,&itxi,&pTrans->sGeosysDatum);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysProj);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sGeosysSone);
+ }
+ }
+
+ /* Geokoord */
+ if ((usMaskeInn & LC_TR_GEOKOORD) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...GEOKOORD",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_GEOKOORD;
+ UT_StrShort(cp,0,&itxi,&pTrans->sGeoKoord);
+ }
+ }
+
+ /* Origo */
+ if ((usMaskeInn & LC_TR_ORIGO) != 0) {
+ //pTrans->dOrigoAust = 0.0;
+ //pTrans->dOrigoNord = 0.0;
+ lin = 2;
+ if ((cp = LC_GetGP("...ORIGO-NØ",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_ORIGO;
+ UT_StrDbl(cp,0,&itxi,'.',&pTrans->Origo.dNord);
+ UT_StrDbl(cp,itxi,&itxi,'.',&pTrans->Origo.dAust);
+ }
+ }
+
+ /* Enhet */
+ if ((usMaskeInn & LC_TR_ENHET) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...ENHET",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_ENHET;
+ pTrans->dEnhet = strtod(cp,&cp);
+ }
+ }
+
+ /* Enhet-h */
+ if ((usMaskeInn & LC_TR_ENHETH) != 0) {
+ lin=2;
+ if ((cp = LC_GetGP("...ENHET-H",&lin,ngi)) == NULL) {
+ pTrans->dEnhet_h = pTrans->dEnhet;
+ } else {
+ *pusMaske |= LC_TR_ENHETH;
+ pTrans->dEnhet_h = strtod(cp,&cp);
+ }
+ }
+
+ /* Enhet-d */
+ if ((usMaskeInn & LC_TR_ENHETD) != 0) {
+ lin=2;
+ if ((cp = LC_GetGP("...ENHET-D",&lin,ngi)) == NULL) {
+ pTrans->dEnhet_d = pTrans->dEnhet;
+ } else {
+ *pusMaske |= LC_TR_ENHETD;
+ pTrans->dEnhet_d = strtod(cp,&cp);
+ }
+ }
+
+ /* Vert-datum */
+ if ((usMaskeInn & LC_TR_VERTDATUM) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...VERT-DATUM",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_VERTDATUM;
+ UT_StrToken(cp,0,&itxi,7,pTrans->szVertdatHref);
+ UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatDref);
+ UT_StrToken(cp,itxi,&itxi,6,pTrans->szVertdatFref);
+ UT_StrToken(cp,itxi,&itxi,2,pTrans->szVertdatHtyp);
+ }
+ }
+
+ /* Vert-int */
+ if ((usMaskeInn & LC_TR_VERTINT) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...VERT-INT",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_VERTINT;
+ UT_StrShort(cp,0,&itxi,&pTrans->sVertintHref);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintDref);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVertintFref);
+ }
+ }
+
+ /* Vert-delta */
+ if ((usMaskeInn & LC_TR_VERTDELTA) != 0) {
+ lin = 2;
+ if ((cp = LC_GetGP("...VERT-DELTA",&lin,ngi)) != NULL) {
+ *pusMaske |= LC_TR_VERTDELTA;
+ UT_StrShort(cp,0,&itxi,&pTrans->sVdeltaMin);
+ UT_StrShort(cp,itxi,&itxi,&pTrans->sVdeltaMax);
+ }
+ }
+
+
+ /* ----- Div. sluttkontroll ----- */
+
+ /* Kontroller at det er funnet Koordsys, Transsys eller Geosys */
+ if ((usMaskeInn & LC_TR_KOORDSYS) != 0 ||
+ (usMaskeInn & LC_TR_TRANSSYS) != 0 ||
+ (usMaskeInn & LC_TR_GEOSYS) != 0 ) {
+ if ((*pusMaske & LC_TR_KOORDSYS) == 0 &&
+ (*pusMaske & LC_TR_TRANSSYS) == 0 &&
+ (*pusMaske & LC_TR_GEOSYS) == 0 ) {
+ /* Ikke noe koordinatsystem funnet */
+ LC_Error(15,"(LC_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+ }
+
+ /* Kontroller at det er funnet Origo */
+ if ((usMaskeInn & LC_TR_ORIGO) != 0 &&
+ (*pusMaske & LC_TR_ORIGO) == 0 ) {
+ /* Origo mangler */
+ LC_Error(16,"(LC_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+
+ /* Kontroller at det er funnet Enhet */
+ if ((usMaskeInn & LC_TR_ENHET) != 0 &&
+ (*pusMaske & LC_TR_ENHET) == 0 ) {
+ /* Enhet mangler */
+ LC_Error(17,"(LC_GetTransEx)","");
+ ist = UT_FALSE;
+ }
+
+ return ist;
+}
+
+
+/*
+GL-880427
+AR-910920
+CH LC_GetTrans Finner ..TRANSPAR i hodet
+CD ==========================================================================
+CD Formål:
+CD Henter ut transformasjonsparametrene fra ginfo i aktuell gruppe.
+CD Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD OBS! Denne rutinen opprettholdes bare for bakoverkompatibilitet.
+CD For nye programmer bør LC_GetTransEx benyttes. LC_GetTransEx er
+CD kompatibel med nye versjoner av SOSI.
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short *koosys u Koordinatsystem
+CD double *origo_a u Origo øst
+CD double *origo_n u Origo nord
+CD double *enhet u Enhet
+CD double *enhet_h u ...ENHET-H
+CD double *enhet_d u ...ENHET-D
+CD short ist r status: UT_TRUE=OK, UT_FALSE=feil (navn er ikke funnet)
+CD
+CD Bruk:
+CD ist = LC_GetTrans(&koosys,&origo_a,&origo_n,&enhet,&enhet_h,&enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTrans(short *koosys,double *origo_a,double *origo_n,double *enhet,
+ double *enhet_h,double *enhet_d)
+{
+
+ short lin,ngi;
+ long nko;
+ unsigned short us;
+ char *cp;
+ short ist = UT_TRUE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+ LC_GetGrPara(&ngi,&nko,&us);
+
+ lin=2;
+ if (LC_GetGP("..TRANSPAR",&lin,ngi) == NULL) { /* Transpar */
+ LC_Error(14,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ } else{
+ *koosys=0; /* Koordsys */
+ lin=2;
+ cp = LC_GetGP("...KOORDSYS",&lin,ngi);
+ if (cp == NULL){
+ lin=2;
+ cp = LC_GetGP("..KOORDSYS",&lin,ngi);
+ }
+ if (cp == NULL){
+ LC_Error(15,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ } else{
+ *koosys = atoi(cp);
+ *origo_a = 0.0; /* Origo */
+ *origo_n = 0.0;
+ lin = 2;
+ cp = LC_GetGP("...ORIGO-NØ",&lin,ngi);
+ if (cp == NULL) {
+ LC_Error(16,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ } else{
+ *origo_n=strtod(cp,&cp);
+ *origo_a=strtod(cp,&cp);
+
+ *enhet = 1.0; /* Enhet */
+ lin = 2;
+ cp = LC_GetGP("...ENHET",&lin,ngi);
+ if (cp == NULL){
+ LC_Error(17,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ } else{
+ *enhet = strtod(cp,&cp);
+ }
+ lin=2;
+ cp = LC_GetGP("...ENHET-H",&lin,ngi);
+ if (cp == NULL){
+ *enhet_h = *enhet;
+ } else {
+ *enhet_h = strtod(cp,&cp);
+ }
+ lin=2;
+ cp = LC_GetGP("...ENHET-D",&lin,ngi);
+ if (cp == NULL){
+ *enhet_d = *enhet;
+ } else{
+ *enhet_d = strtod(cp,&cp);
+ }
+ }
+ }
+ }
+
+ } else{ /* Gruppen er ikke filhode */
+ LC_Error(94,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_GetTrans)","");
+ ist = UT_FALSE;
+ }
+
+ return ist;
+}
+
+/*
+AR-920401
+CH LC_GetTegnsett Finner tegnsett
+CD ==========================================================================
+CD Formål:
+CD Finne tegnsett i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short *psTegnsett u Tegnsett, konstanter definert:
+CD TS_DOSN8 = DOS norsk 8-bits(standardverdi)
+CD TS_ND7 = Norsk Data 7-bits
+CD TS_ISO8859 = ISO8859-10 norsk/samisk
+CD TS_DECM8 = DEC multinasjonal 8-bits
+CD TS_DECN7 = DEC norsk 7-bits
+CD short sStatus r Status: UT_TRUE = Funnet
+CD UT_FALSE = Ikke funnet
+CD
+CD Bruk:
+CD sStatus = LC_GetTegnsett(&sTegnsett);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTegnsett(short *psTegnsett)
+{
+ short lin,ngi;
+ long nko;
+ unsigned short us;
+ char *cp;
+ short ist = UT_FALSE;
+
+ *psTegnsett = TS_DOSN8;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+ LC_GetGrPara(&ngi,&nko,&us);
+ lin=2;
+ if ((cp = LC_GetGP("..TEGNSETT",&lin,ngi)) != NULL) { /* Tegnsett */
+ ist = UT_TRUE;
+ UT_StrUpper(cp);
+ if (strcmp(cp,"ISO8859-10") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ISO8859-1") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ANSI") == 0) {
+ *psTegnsett = TS_ISO8859;
+
+ } else if (strcmp(cp,"ND7") == 0) {
+ *psTegnsett = TS_ND7;
+
+ } else if (strcmp(cp,"DECN7") == 0) {
+ *psTegnsett = TS_DECN7;
+
+ } else if (strcmp(cp,"DECM8") == 0) {
+ *psTegnsett = TS_DECM8;
+ }
+ }
+
+ } else { /* Gruppen er ikke filhode */
+ LC_Error(94,"(LC_GetTegnsett)","");
+ ist = UT_FALSE;
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_GetTegnsett)","");
+ ist = UT_FALSE;
+ }
+
+ return ist;
+}
+
+
+/*
+AR-920401
+CH LH_GetNgisLag Finner NGIS-LAG
+CD ==========================================================================
+CD Formål:
+CD Finne NGIS-LAG i ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char* pszNgisLag r NGIS-lag.
+CD Tom streng = ..NGIS-LAG er ikke funnet eller parameter mangler
+CD ..NGIS-LAG 0 = Bare leseaksess
+CD
+CD Bruk:
+CD pszNgisLag = LH_GetNgisLag();
+CD ==========================================================================
+*/
+char* LH_GetNgisLag(void)
+{
+ char *cp;
+ short lin = 2;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+ if ((cp = LC_GetGP("..NGIS-LAG",&lin,Sys.pGrInfo->ngi)) != NULL) {
+ return cp;
+ } else {
+ return "";
+ }
+
+ } else { /* Gruppen er ikke filhode */
+ LC_Error(94,"(LH_GetNgisLag)","");
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LH_GetNgisLag)","");
+ }
+
+ return "";
+}
+
+
+/*
+AR-910920
+CH LC_PutOmr Legger inn ..OMRÅDE i hodet
+CD ==========================================================================
+CD Formål:
+CD Legger inn område i ginfo i aktuell gruppe.
+CD Hvis område ikke har noen utstrekning justeres
+CD dette med 1 meter i hver retning.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode av ny type.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double nv_a i Område
+CD double nv_n i
+CD double oh_a i
+CD double oh_n i
+CD short ist r status: UT_TRUE=OK, UT_FALSE=feil
+CD
+CD Bruk:
+CD ist = LC_PutOmr(nv_a,nv_n,oh_a,oh_n);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutOmr(double nv_a,double nv_n,double oh_a,double oh_n)
+{
+ short i;
+ char c[80];
+ short ist = UT_FALSE;
+ double dNV_N, dNV_A, dOH_A, dOH_N;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+
+ //UT_SNPRINTF(c,80," %ld %ld",UT_RoundDL(floor(nv_n)),UT_RoundDL(floor(nv_a)));
+ dNV_N = UT_RoundDD(floor(nv_n));
+ dNV_A = UT_RoundDD(floor(nv_a));
+
+ dOH_N = UT_RoundDD(ceil(oh_n));
+ dOH_A = UT_RoundDD(ceil(oh_a));
+
+ // Hvis nødvendig justeres område
+ if (fabs(dOH_N-dNV_N) < 0.00000001) {
+ dNV_N -= 1.0;
+ dOH_N += 1.0;
+ }
+ if (fabs(dOH_A-dOH_A) < 0.00000001) {
+ dNV_A -= 1.0;
+ dOH_A += 1.0;
+ }
+
+ UT_SNPRINTF( c,80, " %.0f %.0f", dNV_N, dNV_A );
+ if (LC_PutGP("...MIN-NØ",c,&i)) {
+
+ UT_SNPRINTF( c, 80, " %.0f %.0f", dOH_N, dOH_A );
+ if (LC_PutGP("...MAX-NØ",c,&i)){
+ ist = UT_TRUE;
+ }
+ }
+
+ } else{ /* Gruppen er ikke filhode */
+ LC_Error(94,"(LC_PutOmr)","");
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutOmr)","");
+ }
+
+ return ist;
+}
+
+
+/*
+AR-910920
+CH LC_GetOmr Finner ..OMRÅDE i hodet
+CD ==========================================================================
+CD Formål:
+CD Henter ut område fra ginfo i aktuell gruppe.
+CD OBS! Forutsetter at aktuell gruppe er et SOSI-filhode.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double *nv_a u Område
+CD double *nv_n u
+CD double *oh_a u
+CD double *oh_n u
+CD short ist r status: UT_TRUE=OK, UT_FALSE=feil (navn er ikke funnet)
+CD
+CD Bruk:
+CD ist = LC_GetOmr(&nv_a,&nv_n,&oh_a,&oh_n);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetOmr(double *nv_a,double *nv_n,double *oh_a,double *oh_n)
+{
+ short lin,i,ngi;
+ long nko;
+ unsigned short info;
+ char *cp;
+ short ist = UT_TRUE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_HODE) { /* Aktuell gruppe .HODE */
+ LC_GetGrPara(&ngi,&nko,&info);
+ lin=2;
+ if (LC_GetGP("..OMRÅDE",&lin,ngi) == NULL) {
+ LC_Error(7,"(LC_GetOmr)","");
+ *nv_n = -9999999.0;
+ *nv_a = -9999999.0;
+ *oh_n = 9999999.0;
+ *oh_a = 9999999.0;
+ ist = UT_FALSE;
+ } else {
+ /* Min-NØ */
+ i = lin;
+ cp = LC_GetGP("...MIN-NØ",&i,ngi);
+ if (cp == NULL){
+ LC_Error(8,"(LC_GetOmr)","");
+ ist = UT_FALSE;
+ *nv_n = -9999999.0;
+ *nv_a = -9999999.0;
+ } else{
+ *nv_n = strtod(cp,&cp);
+ *nv_a = strtod(cp,&cp);
+ /* Max-NØ */
+ i = lin;
+ cp = LC_GetGP("...MAX-NØ",&i,ngi);
+ if (cp == NULL){
+ LC_Error(9,"(LC_GetOmr)","");
+ ist = UT_FALSE;
+ *oh_n = 9999999.0;
+ *oh_a = 9999999.0;
+
+ } else{
+ *oh_n = strtod(cp,&cp);
+ *oh_a = strtod(cp,&cp);
+ }
+ }
+ }
+
+ } else{ /* Gruppen er ikke filhode */
+ LC_Error(94,"(LC_GetOmr)","");
+ ist = UT_FALSE;
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_GetOmr)","");
+ ist = UT_FALSE;
+ }
+
+ return ist;
+}
+
+
+/*
+AR-910920
+CH LC_NyttHode Lager nytt hode
+CD ==========================================================================
+CD Formål:
+CD Legger inn et standard SOSI-filhode i ginfo i aktuell gruppe.
+CD
+CD Parametre:
+CD ingen
+CD
+CD Bruk:
+CD LC_NyttHode();
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_NyttHode(void)
+{
+ short ngi;
+ long nko;
+ unsigned short us;
+ char szTx[100];
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Tildel plass */
+ LC_GetGrPara(&ngi,&nko,&us);
+ if (ngi < 10){
+ LC_InsGiL((short)(ngi+1),(short)(10-ngi));
+ } else if (ngi > 10){
+ LC_DelGiL(11,(short)(ngi-10));
+ }
+
+ Sys.pGrInfo->gnavn = L_HODE; /* Aktuell gruppe .HODE */
+
+ /* Generer nytt hode */
+ LC_PutGi(1,".HODE");
+ LC_PutGi(2,"..TEGNSETT ISO8859-10");
+ LC_PutGi(3,"..TRANSPAR");
+ LC_PutGi(4,"...KOORDSYS 0");
+ LC_PutGi(5,"...ORIGO-NØ 0 0");
+ LC_PutGi(6,"...ENHET 0.01");
+ LC_PutGi(7,"..OMRÅDE");
+ LC_PutGi(8,"...MIN-NØ -99999 -99999");
+ LC_PutGi(9,"...MAX-NØ 1999999 1999999");
+
+ //LC_PutGi(10,"..SOSI-VERSJON 3.0");
+ UT_SNPRINTF(szTx,100,"..SOSI-VERSJON %.2f",((double)FYBA_SOSI_VERSJON)/100.0);
+ LC_PutGi(10,szTx);
+
+ LC_PutSn(0L); /* Standard serienummer 0 for hodet*/
+ }
+}
+
+
+/*
+AR-910920
+CH LC_TestHode Tester SOSI-hodet
+CD ==========================================================================
+CD Formål:
+CD Sjekker at ginfo i aktuell gruppe er et lovlig SOSI-filhode.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short ist r status: UT_TRUE=OK, UT_FALSE=feil
+CD
+CD Bruk:
+CD ist = LC_TestHode();
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestHode(void)
+{
+ double d;
+ short ist;
+ unsigned short usMaske = LC_TR_ALLT;
+ LC_TRANSPAR Trans;
+
+
+ ist = LC_GetTransEx(&usMaske,&Trans);
+
+ if (ist == UT_TRUE) {
+ ist = LC_GetOmr(&d,&d,&d,&d);
+ }
+
+ return ist;
+}
+
diff --git a/src/FYBA/FYLI.cpp b/src/FYBA/FYLI.cpp
new file mode 100644
index 0000000..5814574
--- /dev/null
+++ b/src/FYBA/FYLI.cpp
@@ -0,0 +1,2297 @@
+/* === 910828 ============================================================= */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fyli.c */
+/* Innhold: Lagring og henting av indekstabeller */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <limits.h>
+
+#ifdef WIN32
+# include <process.h>
+#endif
+
+/* Div. styrevariabler */
+
+/* Konstanter for ModusXxx */
+#define NY 0
+#define LES 1
+#define SKRIV 2
+
+
+/* Globale strukturer for fyba */
+extern LC_SYSTEMADM Sys;
+
+
+/* Lokale rutiner */
+static FILE *LI_OpenIdxFil(LC_FILADM *pFil, const char *pszNavn, const char *pszType);
+static FILE *LI_OpenAdm(LC_FILADM *pFil);
+static FILE *LI_OpenGrt(LC_FILADM *pFil);
+static FILE *LI_OpenGeo(LC_FILADM *pFil);
+static FILE *LI_OpenSnr(LC_FILADM *pFil);
+static FILE *LI_OpenBt(LC_FILADM *pFil);
+static void LI_OpenRb(LC_FILADM *pFil,UT_INT64 n64FilPos,short sModus);
+static short LI_ReadAdm(LC_FILADM *pFil);
+static void LI_CreateIdx(LC_FILADM *pFil);
+static void LI_FrigiIdx(LC_FILADM *pFil);
+
+
+/*
+AR-910928
+CH LI_TestIdx Sjekk at indeksfilene eksisterer
+CD ==========================================================================
+CD Formål:
+CD Sjekk at indeksfilene eksisterer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char *szSosFil i SOSI-fil
+CD short status r Status
+CD UT_TRUE = OK
+CD UT_FALSE = Fil mangler
+CD
+CD Bruk:
+CD status = LI_TestIdx(szSosFil);
+ ==========================================================================
+*/
+short LI_TestIdx(char *szSosFil)
+{
+ UT_INT64 Size;
+ char fil[_MAX_PATH];
+ char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+
+
+ // Hvis det er valgt spesiell indekskatalog skal indeksen alltid bygges opp på nytt
+ if (*Sys.szIdxPath != '\0') return UT_FALSE;
+
+ /*
+ * Lag sti til indeksfilene
+ */
+ UT_splitpath(szSosFil,drive,dir,fname,ext);
+ /* Lag navn på sub-directory */
+ UT_StrCat(dir,fname,_MAX_DIR);
+ UT_StrCat(dir,UT_STR_SLASH,_MAX_DIR);
+
+ /* Sjekk at indeksfilene finnes */
+ /* -------------- Adm ------------- */
+ UT_makepath(fil,drive,dir,"Adm",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* -------------- Gruppetabell ------------- */
+ UT_makepath(fil,drive,dir,"Grt",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* -------------- RB ------------- */
+ UT_makepath(fil,drive,dir,"Rb",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* -------------- SNR ------------- */
+ UT_makepath(fil,drive,dir,"Snr",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* -------------- BT -------------- */
+ UT_makepath(fil,drive,dir,"Bt",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* -------------- GEO ------------- */
+ UT_makepath(fil,drive,dir,"Geo",".Idx");
+ if (UT_InqPathSize_i64(fil,&Size) != 0) return UT_FALSE;
+
+ /* printf("\nIndeksfilene finnes."); */
+ return UT_TRUE;
+}
+
+
+/*
+AR-910929
+CH LI_OpenInit Åpner og nullstiller indeksfilene
+CD ==========================================================================
+CD Formål:
+CD Åpner indeksfilene og nullstiller tabellene.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short status r Status
+CD UT_TRUE = OK
+CD UT_FALSE = Ikke åpnet OK
+CD
+CD Bruk:
+CD status = LI_OpenInit(pFil);
+ ==========================================================================
+*/
+short LI_OpenInit(LC_FILADM *pFil)
+{
+ char fil[_MAX_PATH];
+ char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+ char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+ FILE *pF;
+
+
+ // ----- Alloker overordnet struktur for indekstabeller
+ LI_CreateIdx(pFil);
+
+ // ----- Splitt filnavnet
+ UT_splitpath(pFil->pszNavn,drive1,dir1,fname1,ext1);
+
+ // Gitt sti for indeksfilene
+ if ( *Sys.szIdxPath != 0) {
+ UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+ UT_makepath(fil,drive2,dir2,fname1,"");
+
+ } else {
+ UT_makepath(fil,drive1,dir1,fname1,"");
+ }
+
+ // ----- Lag subdirectory hvis det ikke finnes fra før
+ // Sjekk at navnet er lovlig (ikke blanke siste i navnet)
+ if (fil[strlen(fil)-1] == ' ')
+ {
+ LC_Error(120,"(LI_OpenInit)",pFil->pszNavn);
+ exit(99);
+ }
+
+ // Opprett katalogen
+ UT_CreateDir(fil);
+
+
+ // ----- Åpner indeksfilene
+
+ /* -------------- Adm ------------- */
+ pF = LI_OpenAdm(pFil);
+
+ /* Marker at basen er åpnet */
+ UT_StrCopy(pFil->szBaseVer, FYBA_IDENT, LC_BASEVER_LEN);
+ UT_StrCopy(pFil->szIdxVer, FYBA_INDEKS_VERSJON, 5);
+ pFil->ulPid = 0;
+ pFil->sIdxOpen = UT_TRUE;
+ pFil->ulPid = UT_GETPID();
+ //pFil->ulPid = GetCurrentProcessId(); // Bruke _getpid() i stede?
+
+ if (fwrite(pFil,sizeof(*pFil),1,pF) != 1) {
+ LC_Error(112,"(LI_OpenInit)","");
+ exit(99);
+ }
+
+ fclose(pF);
+
+ /* -------------- Gruppetabell ------------- */
+ pF = LI_OpenGrt(pFil);
+ fclose(pF);
+
+ /* -------------- RB ------------- */
+ LI_OpenRb(pFil,0L,SKRIV);
+ pFil->pBase->n64FilPosRb = 0L;
+
+ /* -------------- SNR ------------- */
+ pF = LI_OpenSnr(pFil);
+ fclose(pF);
+
+ /* -------------- BT -------------- */
+ pF = LI_OpenBt(pFil);
+ fclose(pF);
+
+ /* -------------- GEO ------------- */
+ /* (Geografisk søk er uaktuellt ved kladdebase) ?????? */
+ pF = LI_OpenGeo(pFil);
+ fclose(pF);
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-910930
+CH LI_OpenRead Åpner og leser indeksfilene
+CD ==========================================================================
+CD Formål:
+CD Åpner indeksfilene og leser inn tabellene.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short status r Status
+CD UT_OK (0): Lest OK
+CD LI_LESEFEIL: Feil ved les fra Adm.idx
+CD LI_OPPTATT: Filen er åpen i et annet program
+CD LI_FEIL_INDEKSVERSJON: Feil indeksversjon
+CD LI_FEIL_STORRELSE: Feil størrelse på SOSI-filen
+CD LI_FEIL_OPPDATTID: Feil oppdateringstid på SOSI-filen
+CD
+CD Bruk:
+CD status = LI_OpenRead(pFil);
+ ==========================================================================
+*/
+short LI_OpenRead(LC_FILADM *pFil)
+{
+ FILE *pF;
+ long linje;
+ long lSnr;
+ long lGrNr;
+ unsigned long bt;
+ LC_GRTAB_LINJE * pGrt;
+ LC_BOKS Boks;
+ short sStatus;
+
+
+ /* -------------- Admin ------------- */
+ // Her sjekkes det også mot feil versjon, lesefeil
+ // og om filen er åpen i annet program.
+ if ((sStatus = LI_ReadAdm(pFil)) != UT_OK)
+ {
+ return sStatus;
+ }
+
+ // Alloker overordnet struktur for indekstabeller
+ LI_CreateIdx(pFil);
+
+ /* -------------- RB ------------- */
+ LI_OpenRb(pFil,0L,SKRIV);
+ pFil->pBase->n64FilPosRb = 0L;
+
+ /* -------------- Gruppetabell ------------- */
+ pF = LI_OpenGrt(pFil);
+ for (linje = 0; linje<pFil->lAntGr; linje++) {
+ pGrt = LI_AppGrt(pFil,linje);
+ if (fread(pGrt,sizeof(*pGrt),1,pF) != 1) { /* Les */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+ LC_Error(111,"(LI_OpenRead): ",err().tx);
+ exit(99);
+ }
+ }
+ fclose(pF);
+
+ /* -------------- SNR ------------- */
+ pF = LI_OpenSnr(pFil);
+ lSnr = 0;
+ while (fread(&lGrNr,sizeof(lGrNr),1,pF) == 1) {
+ if (lGrNr != INGEN_GRUPPE) LI_PutSnr(pFil,lSnr,lGrNr);
+ lSnr++;
+ }
+ if (! feof(pF)) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",lSnr);
+ LC_Error(111,"(LI_OpenRead): ",err().tx);
+ exit(99);
+ }
+ fclose(pF);
+
+
+ /* -------------- BT -------------- */
+ pF = LI_OpenBt(pFil);
+ for (linje = 0; linje<pFil->lAntGr; linje++) {
+ if (fread(&bt,sizeof(bt),1,pF) != 1) { /* Les */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+ LC_Error(111,"(LI_OpenRead): ",err().tx);
+ exit(99);
+ }
+ LI_PutBt(pFil,linje,bt);
+ }
+ fclose(pF);
+
+ /* -------------- GEO ------------- */
+ pF = LI_OpenGeo(pFil);
+ for (linje = 0; linje<pFil->lAntGr; linje++) {
+ if (fread(&Boks,sizeof(Boks),1,pF) != 1) { /* Les */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+ LC_Error(111,"(LI_OpenRead): ",err().tx);
+ exit(99);
+ }
+
+ if (Boks.dMaxAust != (double)LONG_MAX) {
+ /* Lagre omskrevet boks i søketreet */
+ pGrt = LI_GetGrt(pFil,linje);
+ pGrt->pRL = LR_InsertGeo(pFil,linje,&Boks);
+ }
+ }
+ fclose(pF);
+
+ return UT_OK;
+}
+
+
+/*
+AR-930809
+CH LI_CreateIdx Allokerer Idx struktur i minne
+CD ==========================================================================
+CD Formål:
+CD Allokerer Idx struktur i minne
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD LI_CreateIdx(pFil);
+ ==========================================================================
+*/
+static void LI_CreateIdx(LC_FILADM *pFil)
+{
+ pFil->pIdx = (LC_IDX_TABELL *) UT_MALLOC(sizeof(LC_IDX_TABELL));
+ memset(pFil->pIdx,'\0',sizeof(LC_IDX_TABELL));
+}
+
+
+/*
+AR-930809
+CH LI_FrigiIdx Frigi Idx struktur i minne
+CD ==========================================================================
+CD Formål:
+CD Frigi Idx struktur i minne
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD LI_FrigiIdx(pFil);
+ ==========================================================================
+*/
+static void LI_FrigiIdx(LC_FILADM *pFil)
+{
+ int i;
+ LC_GRTAB_LINJE * *ppGt = pFil->pIdx->GtAdm;
+ long **pplSnr;
+ unsigned long **ppulBt;
+
+
+ if (pFil->pIdx != NULL) {
+ ppGt = pFil->pIdx->GtAdm;
+ pplSnr = pFil->pIdx->SnrAdm;
+ ppulBt = pFil->pIdx->BtAdm;
+
+ for (i=0; i<LC_ANT_IDX_BLOKK; i++) {
+ /* Gruppetabellen */
+ if (*ppGt != NULL) {
+ UT_FREE(*ppGt);
+ }
+ ppGt++;
+
+ /* SNR-tabellen */
+ if (*pplSnr != NULL) {
+ UT_FREE(*pplSnr);
+ }
+ pplSnr++;
+
+ /* Brukt-tabellen */
+ if (*ppulBt != NULL) {
+ UT_FREE(*ppulBt);
+ }
+ ppulBt++;
+
+ }
+
+ /* Frigi GEO-tabellen */
+ if (pFil->pGeoRN != NULL) {
+ LR_R_FrigiGren(pFil->pGeoRN);
+ }
+
+ /* Frigir topp-blokken */
+ UT_FREE(pFil->pIdx);
+
+ pFil->pIdx = NULL;
+ }
+}
+
+
+/*
+AR-910830
+CH LI_Close Stenger indeksfilene
+CD ==========================================================================
+CD Formål:
+CD Skriver adm. opplysning og stenger indeksfilene.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short s_stat i Slutt-status (brukes foreløpig ikke)
+CD (RESET_IDX) = Fjern indeksfilene
+CD (SAVE_IDX ) = Lagrer indeksfilene
+CD
+CD Bruk:
+CD LI_Close(pFil,SAVE_IDX);
+ ==========================================================================
+*/
+void LI_Close(LC_FILADM *pFil,short s_stat)
+{
+ long lGrNr,lSnr;
+ unsigned long flag;
+ FILE *pF;
+ LC_R_LEAF * pRL;
+ LC_BOKS Boks;
+
+
+ /* RB */
+ if (pFil->pBase->pCurRb != NULL) {
+ fclose(pFil->pBase->pfRb);
+ pFil->pBase->pCurRb = NULL;
+ }
+
+ if (s_stat == SAVE_IDX && pFil->pIdx != NULL && *Sys.szIdxPath == '\0') {
+
+ /* Gruppetabellen */
+ pF = LI_OpenGrt(pFil); /* Åpne og posisjoner */
+ for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+ if (fwrite(LI_GetGrt(pFil,lGrNr),sizeof (LC_GRTAB_LINJE),1,pF) != 1) {
+ LC_Error(112,"(LI_Close)","");
+ exit(99);
+ }
+ }
+ fclose(pF);
+
+ /* Brukttabellen */
+ pF = LI_OpenBt(pFil); /* Åpne og posisjoner */
+ for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+ flag = LI_GetBt(pFil,lGrNr);
+ if (fwrite(&flag,sizeof flag,1,pF) != 1) {
+ LC_Error(112,"(LI_Close)","");
+ exit(99);
+ }
+ }
+ fclose(pF);
+
+ /*Serienummertabellen */
+ pF = LI_OpenSnr(pFil); /* Åpne og posisjoner */
+ for (lSnr=0; lSnr<=pFil->lMaxSnr; lSnr++) {
+ lGrNr = LI_GetSnr(pFil,lSnr);
+ if (fwrite(&lGrNr,sizeof lGrNr,1,pF) != 1) {
+ LC_Error(112,"(LI_Close)","");
+ exit(99);
+ }
+ }
+ fclose(pF);
+
+ /* Geografisk søketabell */
+ pF = LI_OpenGeo(pFil); /* Åpne og posisjoner */
+ for (lGrNr=0; lGrNr<pFil->lAntGr; lGrNr++) {
+ pRL = LI_GetGeo(pFil,lGrNr);
+
+ if (pRL == NULL) {
+ Boks.dMaxAust = (double)LONG_MAX;
+ if (fwrite(&Boks,sizeof (LC_BOKS),1,pF) != 1) {
+ LC_Error(112,"(LI_Close)","");
+ exit(99);
+ }
+
+ } else {
+ if (fwrite(&(pRL->Boks),sizeof (LC_BOKS),1,pF) != 1) {
+ LC_Error(112,"(LI_Close)","");
+ exit(99);
+ }
+ }
+ }
+ fclose(pF);
+
+ /* Lagre adm. blokken */
+ LI_SaveAdm(pFil);
+
+ } else {
+ /* Fjern indeks filene */
+ LC_DelIdx(pFil->pszNavn);
+ }
+
+ /*
+ * Frigi overordnet struktur for indekstabeller
+ */
+ LI_FrigiIdx(pFil);
+
+}
+
+
+/*
+AR-910929
+CH LI_OpenIdxFil Åpne indeksfil
+CD ==========================================================================
+CD Formål:
+CD Åpner indeksfil på rett katalog
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD const char *pszNavn i Filnavn
+CD const char *pszType i Filtype
+CD
+CD Bruk:
+CD pF = LI_OpenIdxFil(pFil,"Adm",".Idx");
+ ==========================================================================
+*/
+static FILE *LI_OpenIdxFil(LC_FILADM *pFil, const char *pszNavn, const char *pszType)
+{
+ short ierr;
+ char fil[_MAX_PATH];
+ char drive1[_MAX_DRIVE],dir1[_MAX_DIR],fname1[_MAX_FNAME],ext1[_MAX_EXT];
+ char drive2[_MAX_DRIVE],dir2[_MAX_DIR],fname2[_MAX_FNAME],ext2[_MAX_EXT];
+
+ FILE *pF;
+
+ // ----- Bygg opp fullt filnavn til filen
+ // Splitt SOSI-filnavnet
+ UT_splitpath(pFil->pszNavn,drive1,dir1,fname1,ext1);
+
+ // Gitt sti for indeksfilene
+ if ( *Sys.szIdxPath != 0) {
+ UT_splitpath(Sys.szIdxPath,drive2,dir2,fname2,ext2);
+ UT_StrCat(dir2,fname1,_MAX_DIR);
+ UT_StrCat(dir2,UT_STR_SLASH,_MAX_DIR);
+ // Bygg opp filnavn
+ UT_makepath(fil,drive2,dir2,pszNavn,pszType);
+
+ } else {
+ UT_StrCat(dir1,fname1,_MAX_DIR);
+ UT_StrCat(dir1,UT_STR_SLASH,_MAX_DIR);
+ // Bygg opp filnavn
+ UT_makepath(fil,drive1,dir1,pszNavn,pszType);
+ }
+
+ // Åner filen
+ pF = UT_OpenFile(fil,"",UT_UPDATE,UT_UNKNOWN,&ierr);
+ if (ierr != UT_OK){
+ char szError[256];
+ UT_strerror(szError,256,ierr);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+ LC_Error(6,"(LI_OpenIdxFil)",err().tx);
+ exit(2);
+ }
+
+ /* Posisjoner hvis nødvendig */
+ //fseek(pF,0L,SEEK_SET); // OBS! Er denne nødvendig? AR:2004-05-14 Fjernet
+
+ return pF;
+}
+
+
+/*
+AR-910929
+CH LI_OpenAdm Åpne og posisjoner, Adm
+CD ==========================================================================
+CD Formål:
+CD Sjekker at rett Adm-fil er åpen, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenAdm(pFil);
+ ==========================================================================
+*/
+static FILE *LI_OpenAdm(LC_FILADM *pFil)
+{
+ FILE *fi = LI_OpenIdxFil(pFil,"Adm",".Idx");
+ fseek(fi,0L,SEEK_SET);
+
+ return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenGrt Åpne og posisjoner, Grt
+CD ==========================================================================
+CD Formål:
+CD Sjekker at rett Grt-fil er åpen, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenGrt(pFil);
+ ==========================================================================
+*/
+static FILE *LI_OpenGrt(LC_FILADM *pFil)
+{
+ FILE *fi = LI_OpenIdxFil(pFil,"Grt",".Idx");
+ fseek(fi,0L,SEEK_SET);
+
+ return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenGeo Åpne og posisjoner, Geo
+CD ==========================================================================
+CD Formål:
+CD Sjekker at rett Geo-fil er åpen, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenGeo(pFil);
+ ==========================================================================
+*/
+static FILE *LI_OpenGeo(LC_FILADM *pFil)
+{
+ FILE *fi = LI_OpenIdxFil(pFil,"Geo",".Idx");
+ fseek(fi,0L,SEEK_SET);
+
+ return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenSnr Åpne og posisjoner, Snr
+CD ==========================================================================
+CD Formål:
+CD Sjekker at rett Snr-fil er åpen, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenSnr(pFil);
+ ==========================================================================
+*/
+static FILE *LI_OpenSnr(LC_FILADM *pFil)
+{
+ FILE *fi = LI_OpenIdxFil(pFil,"Snr",".Idx");
+ fseek(fi,0L,SEEK_SET);
+
+ return fi;
+}
+
+
+/*
+AR-910929
+CH LI_OpenBt Åpne og posisjoner, Bt
+CD ==========================================================================
+CD Formål:
+CD Åpne Bt-fil, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD pF = LI_OpenBt(pFil);
+ ==========================================================================
+*/
+static FILE *LI_OpenBt(LC_FILADM *pFil)
+{
+ FILE *fi = LI_OpenIdxFil(pFil,"Bt",".Idx");
+ fseek(fi,0L,SEEK_SET);
+
+ return fi;
+}
+
+
+/*
+AR-930810
+CH LI_GetGeo Get geo-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en linje fra geografisk søketabell.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long linje i Linjenummer i geo-tabellen (gruppenummer)
+CD LC_GEOTABELL *geop r Peker til geo-tabell-struktur
+CD
+CD Bruk:
+CD geop = LI_GetGeo(pFil,linje);
+ ==========================================================================
+*/
+LC_R_LEAF * LI_GetGeo(LC_FILADM *pFil,long linje)
+{
+ LC_GRTAB_LINJE * pGT;
+
+ pGT = LI_GetGrt(pFil,linje);
+
+ return pGT->pRL; /* Peker til element søketreet */
+}
+
+
+/*
+AR-930810
+CH LI_GetSnr Get snr-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en linje fra serienummer-tabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lSnr i Serienummer
+CD long lGrNr r Gruppenummer
+CD
+CD Bruk:
+CD lGrNr = LI_GetSnr(pFil,lSnr);
+ ==========================================================================
+*/
+long LI_GetSnr(LC_FILADM *pFil,long lSnr)
+{
+ long **pplGrNr;
+
+ if (pFil->pIdx != NULL) {
+ /* Lovlig serienummer? */
+ if (lSnr <= pFil->lMaxSnr) {
+ /* Finner starten av aktuell blokk */
+ pplGrNr = pFil->pIdx->SnrAdm + (lSnr / LC_IDX_LIN_BLOKK);
+ /* Er denne blokken brukt? */
+ if (*pplGrNr != NULL) {
+ /* Hent aktuell linje i denne blokken */
+ return *(*pplGrNr + (lSnr % LC_IDX_LIN_BLOKK));
+ }
+ }
+ }
+
+ return INGEN_GRUPPE;
+}
+
+
+/*
+AR-930810
+CH LI_PutSnr Put snr-linje
+CD ==========================================================================
+CD Formål:
+CD Legger inn en linje i serienummer-tabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lSnr i Serienummer
+CD long lGrNr i Gruppenummer
+CD
+CD Bruk:
+CD LI_PutSnr(pFil,lSnr,lGrNr);
+ ==========================================================================
+*/
+void LI_PutSnr(LC_FILADM *pFil,long lSnr,long lGrNr)
+{
+ long **pplGrNr,*pL;
+ int antall;
+
+ if (pFil->pBase->sType == LC_BASE) {
+ if (pFil->pIdx != NULL) {
+ if (lSnr < LC_MAX_GRU) {
+ /* Finner starten av aktuell blokk */
+ pplGrNr = pFil->pIdx->SnrAdm + (lSnr / LC_IDX_LIN_BLOKK);
+
+ /* Blokken finnes ikke, lag ny blokk */
+ if (*pplGrNr == NULL)
+ {
+ *pplGrNr = (long *) UT_MALLOC(sizeof(long)*LC_IDX_LIN_BLOKK);
+
+ for (pL=*pplGrNr,antall=0; antall<LC_IDX_LIN_BLOKK; pL++,antall++) {
+ *pL = INGEN_GRUPPE;
+ }
+ }
+
+ /* Legg inn aktuell linje i blokken */
+ *(*pplGrNr + (lSnr % LC_IDX_LIN_BLOKK)) = lGrNr;
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"%ld",lSnr);
+ LC_Error(61,"(LI_PutSnr): ",err().tx);
+ exit(99);
+ }
+
+ } else {
+ LC_Error(75,"(LI_PutSnr): ","");
+ exit(99);
+ }
+ }
+}
+
+
+/*
+AR-930810
+CH LI_GetGrt Get grt-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en linje fra gruppetabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long linje i Linjenummer i grt-tabellen (gruppenummer)
+CD LC_GRTAB_LINJE *grtp r Peker til grt-tabell-linje
+CD
+CD Bruk:
+CD grtp = LI_GetGrt(pFil,linje);
+ ==========================================================================
+*/
+LC_GRTAB_LINJE * LI_GetGrt(LC_FILADM *pFil,long linje)
+{
+ LC_GRTAB_LINJE * *ppGt;
+
+ if (pFil->pIdx != NULL) {
+ /* Finner starten av aktuell blokk */
+ ppGt = pFil->pIdx->GtAdm + (linje / LC_IDX_LIN_BLOKK);
+ /* Er denne blokken brukt? */
+ if (*ppGt != NULL) {
+ /* Hent aktuell linje i denne blokken */
+ return (*ppGt + (linje % LC_IDX_LIN_BLOKK));
+ }
+ }
+
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+ LC_Error(111,"(LI_GetGrt): ",err().tx);
+ exit(99);
+
+ return NULL;
+}
+
+
+/*
+AR-930810
+CH LI_AppGrt Ny grt-linje
+CD ==========================================================================
+CD Formål:
+CD Legger inn en NY linje i gruppetabell.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long linje i Linjenummer i grt-tabellen (gruppenummer)
+CD LC_GEOTABELL *grtp r Peker til grt-tabell-struktur
+CD
+CD Bruk:
+CD pgrt = LI_AppGrt(pFil,linje,geop);
+ ==========================================================================
+*/
+LC_GRTAB_LINJE * LI_AppGrt(LC_FILADM *pFil,long linje)
+{
+ LC_GRTAB_LINJE * *ppGt;
+
+ if (pFil->pIdx != NULL) {
+ /* Finner starten av aktuell blokk */
+ ppGt = pFil->pIdx->GtAdm + (linje / LC_IDX_LIN_BLOKK);
+ if (*ppGt == NULL) {
+ /* Blokken finnes ikke, lag ny blokk */
+ *ppGt = (LC_GRTAB_LINJE *)UT_MALLOC(sizeof(LC_GRTAB_LINJE)*LC_IDX_LIN_BLOKK);
+ memset(*ppGt,'\0',sizeof(LC_GRTAB_LINJE)*LC_IDX_LIN_BLOKK);
+ }
+
+ /* Finn aktuell linje i blokken */
+ return (*ppGt + (linje % LC_IDX_LIN_BLOKK)); /* Funnet ===> */
+
+ } else {
+ LC_Error(75,"(LI_PutGrt): ",err().tx);
+ exit(99);
+ }
+
+ return NULL;
+}
+
+
+/*
+AR-930810
+CH LI_GetBt Get bt-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en linje fra brukt-tabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long linje i Linjenummer i bt-tabellen (gruppenummer)
+CD unsigned long bt_val r Hentet bit-mønster
+CD
+CD Bruk:
+CD bt_val = LI_GetBt(pFil,linje);
+ ==========================================================================
+*/
+unsigned long LI_GetBt(LC_FILADM *pFil,long linje)
+{
+ unsigned long **ppulFlag;
+
+ if (pFil->pIdx != NULL) {
+ /* Finner starten av aktuell blokk */
+ ppulFlag = pFil->pIdx->BtAdm + (linje / LC_IDX_LIN_BLOKK);
+ /* Er denne blokken brukt? */
+ if (*ppulFlag != NULL) {
+ /* Hent aktuell linje i denne blokken */
+ return *(*ppulFlag + (linje % LC_IDX_LIN_BLOKK));
+ }
+ }
+
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %ld",pFil->pszNavn,linje);
+ LC_Error(111,"(LI_GetBt): ",err().tx);
+ exit(99);
+
+ return 0L;
+}
+
+
+/*
+AR-930810
+CH LI_PutBt Put bt-linje
+CD ==========================================================================
+CD Formål:
+CD Legger inn en linje i brukt-tabell.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long linje i Linjenummer i bt-tabellen (gruppenummer)
+CD unsigned long bt_val i Bit mønster som skal lagres
+CD
+CD Bruk:
+CD LI_PutBt(pFil,linje,bt_val);
+ ==========================================================================
+*/
+void LI_PutBt(LC_FILADM *pFil,long linje,unsigned long bt_val)
+{
+ unsigned long **ppulFlag;
+
+ if (pFil->pIdx != NULL) {
+ /* Finner starten av aktuell blokk */
+ ppulFlag = pFil->pIdx->BtAdm + (linje / LC_IDX_LIN_BLOKK);
+
+ /* Blokken finnes ikke, lag ny blokk */
+ if (*ppulFlag == NULL)
+ {
+ *ppulFlag = (unsigned long *) UT_MALLOC(sizeof(unsigned long)*LC_IDX_LIN_BLOKK);
+ memset(*ppulFlag,'\0',sizeof(unsigned long)*LC_IDX_LIN_BLOKK);
+ }
+
+ /* Legg inn aktuell linje i blokken */
+ *(*ppulFlag + (linje % LC_IDX_LIN_BLOKK)) = bt_val;
+
+ } else {
+ LC_Error(75,"(LI_PutBt): ",err().tx);
+ exit(99);
+ }
+}
+
+
+/*
+AR-881123
+CH LC_SetBt Sett merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Legg inn merke i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD short kolonne i Kolonne som skal merkes.
+CD (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_SetBt(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetBt(LC_BGR * pGr,short kolonne)
+{
+ /* LO_TestFilpeker(pGr->pFil,"LC_SetBt"); */
+ LO_TestFilpeker(pGr->pFil,"SetBt");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= BT_MIN_USER && kolonne <= BT_MAX_USER) {
+ /* Merk */
+ LI_SetBt(pGr->pFil,pGr->lNr,kolonne);
+ }
+
+ } else{ /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_SetBt)",errtx);
+ }
+}
+
+
+/*
+AR-881123
+CH LC_ClrBt Slett merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Fjern merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD kolonne short i Kolonne som skal merkes.
+CD (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_ClrBt(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ClrBt(LC_BGR * pGr,short kolonne)
+{
+ /* LO_TestFilpeker(pGr->pFil,"LC_ClrBt"); */
+ LO_TestFilpeker(pGr->pFil,"ClrBt");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= BT_MIN_USER && kolonne <= BT_MAX_USER) {
+ /* Fjern merkingen */
+ LI_ClrBt(pGr->pFil,pGr->lNr,kolonne);
+ }
+
+ } else{ /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_ClrBt)",errtx);
+ }
+}
+
+
+/*
+AR-881123
+CH LC_GetBt Hent merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Hent merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD kolonne short i Kolonne som skal brukes.
+CD (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD merke short r UT_FALSE = ikke marka, UT_TRUE = merka
+CD
+CD Bruk:
+CD merke = LC_GetBt(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBt(LC_BGR * pGr,short kolonne)
+{
+ /* LO_TestFilpeker(pGr->pFil,"LC_GetBt"); */
+ LO_TestFilpeker(pGr->pFil,"GetBt");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= BT_MIN_BT && kolonne <= BT_MAX_BT) {
+ /* Returner verdi */
+ return (LI_InqBt(pGr->pFil,pGr->lNr,kolonne));
+ }
+
+ } else{ /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_GetBt)",errtx);
+ }
+
+ return UT_FALSE; /* Retur ved feil */
+}
+
+
+/*
+AR-881123
+CH LC_EraseBt Slett område i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Blanker en eller flere kolonner i brukttabellen i aktuell base.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD fra_kol short i Første kolonne som skal blankes.
+CD (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD til_kol short i Siste kolonne som skall blankes.
+CD (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD
+CD Bruk:
+CD LC_EraseBt(fra_kol,til_kol);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_EraseBt(short fra_kol,short til_kol)
+{
+ /* Beregner lovlige kolonner */
+ fra_kol = max(fra_kol,BT_MIN_USER);
+ til_kol = min(til_kol,BT_MAX_USER);
+
+ LI_EraseBt(fra_kol,til_kol);
+}
+
+
+/*
+AR-891120
+CH LI_SetBt Sett merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Legg inn merke i brukttabellen.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lGrNr i Gruppenummer
+CD kolonne short i Kolonne som skal merkes.
+CD (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_SetBt(pFil,lGrNr,kolonne);
+ ==========================================================================
+*/
+void LI_SetBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+ LI_PutBt (pFil,lGrNr,LI_GetBt(pFil,lGrNr) | (0x1UL << kolonne));
+}
+
+
+/*
+AR-891120
+CH LI_ClrBt Slett merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Fjern merke i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lGrNr i Gruppenummer
+CD kolonne short i Kolonne som skal merkes.
+CD (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_ClrBt(pFil,lGrNr,kolonne);
+ ==========================================================================
+*/
+void LI_ClrBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+ LI_PutBt(pFil,lGrNr,LI_GetBt(pFil,lGrNr) & (~ (0x1UL << kolonne) ));
+}
+
+
+/*
+AR-910828
+CH LI_InqBt Hent merke i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Hent merke i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lGrNr i Gruppenummer
+CD kolonne short i Kolonne som skal brukes.
+CD (Lovlig BT_MIN_BT - BT_MAX_BT)
+CD merke short r UT_TRUE = marka, UT_FALSE = ikke merka.
+CD
+CD Bruk:
+CD merke = LI_InqBt(pFil,lGrNr,kolonne);
+ ==========================================================================
+*/
+short LI_InqBt(LC_FILADM *pFil,long lGrNr,short kolonne)
+{
+ return ((LI_GetBt(pFil,lGrNr) & (0x1UL << kolonne)) == 0)? UT_FALSE : UT_TRUE;
+}
+
+
+/*
+AR-910827
+CH LI_EraseBt Slett område i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Blanker en eller flere kolonner i brukttabellen i aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short fra_kol i Første kolonne som skal blankes. (Lovlig 0 - BT_MAX_BT)
+CD short til_kol i Siste kolonne som skal blankes. (Lovlig 0 - BT_MAX_BT)
+CD
+CD Bruk:
+CD LI_EraseBt(fra_kol,til_kol);
+ ==========================================================================
+*/
+void LI_EraseBt(short fra_kol,short til_kol)
+{
+ long lNr;
+ unsigned long maske;
+ LC_FILADM *pFil;
+
+ /* Beregner lovlige områder */
+ fra_kol = max(fra_kol,BT_MIN_BT);
+ til_kol = min(til_kol,BT_MAX_BT);
+
+ maske = 0x0000; /* Lager slettemaske */
+ for ( ; fra_kol <= til_kol; fra_kol++){
+ maske |= (0x1UL << fra_kol); /* Merker bit som skal blankes */
+ }
+ maske = ~ maske; /* Inverterer masken */
+
+ /*
+ * Fjerner merkingen
+ */
+ for (pFil=Sys.pAktBase->pForsteFil; pFil != NULL; pFil=pFil->pNesteFil) {
+ for (lNr=0L; lNr<pFil->lAntGr; lNr++) {
+ LI_PutBt(pFil,lNr,(maske & LI_GetBt(pFil,lNr)));
+ }
+ }
+}
+
+
+/*
+AR-910827
+CH LC_CopyBt Kopier kolonne i brukttabellen
+CD ==========================================================================
+CD Formål:
+CD Kopier kolonne i brukttabellen.
+CD Samtidig er det mulig å utføre logiske operasjoner mellom de to kolonnene.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short fra_kol i Kolonne det skal kopieres fra. (Lovlig 0 - BT_MAX_BT)
+CD short til_kol i Kolonne det skal kopieres til. (Lovlig 1 - BT_MAX_USER)
+CD short operasjon i Logisk operasjon mellom kolonnene.
+CD BC_COPY = Overskriv gammelt innhold.
+CD BC_AND = Logisk AND mellom de to kolonnene.
+CD BC_OR = Logisk OR mellom de to kolonnene.
+CD BC_INVERT = Overskriv gammelt innhold med
+CD invertert verdi.
+CD BC_EXCHANGE = Bytter innholdet i de to kolonnene.
+CD
+CD Bruk:
+CD LC_CopyBt(fra_kol,til_kol,operasjon);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CopyBt(short fra_kol,short til_kol,short operasjon)
+{
+ long lNr;
+ unsigned long maske_fra,maske_til;
+ LC_FILADM *pFil = Sys.pAktBase->pForsteFil;
+ unsigned long merke;
+ unsigned long ul;
+
+ /* Beregner lovlige områder */
+ fra_kol = min(max(fra_kol,0),BT_MAX_BT);
+ til_kol = min(max(til_kol,0),BT_MAX_USER);
+
+ /* Returner verdi */
+ maske_fra = 0x00000001UL << fra_kol;
+ maske_til = 0x00000001UL << til_kol;
+
+
+ /* Går gjennom alle grupper */
+ for (; pFil != NULL; pFil=pFil->pNesteFil) {
+ for (lNr=1L; lNr<pFil->lAntGr; lNr++) {
+ merke = LI_GetBt(pFil,lNr);
+ switch (operasjon){
+ case BC_AND: /* AND */
+ if ((merke & maske_fra) && (merke & maske_til)){
+ merke |= maske_til; /* Sett */
+ } else{
+ merke &= ( ~ maske_til); /* Blank */
+ }
+ break;
+
+ case BC_OR: /* OR */
+ if ((merke & maske_fra) || (merke & maske_til)){
+ merke |= maske_til; /* Sett */
+ } else{
+ merke &= ( ~ maske_til); /* Blank */
+ }
+ break;
+
+ case BC_INVERT: /* INVERT (Invertert kopi)*/
+ if (merke & maske_fra) {
+ merke &= ( ~ maske_til); /* Blank */
+ } else{
+ merke |= maske_til; /* Sett */
+ }
+ break;
+
+ case BC_EXCHANGE: /* BYTT */
+ /* Husk innholdet i "til-kolonnen" */
+ ul = merke & maske_til;
+ /* Oppdater "til-kolonnen" */
+ if (merke & maske_fra) {
+ merke |= maske_til; /* Sett */
+ } else{
+ merke &= ( ~ maske_til); /* Blank */
+ }
+ /* Oppdater "fra-kolonnen" */
+ if (ul) {
+ merke |= maske_fra; /* Sett */
+ } else{
+ merke &= ( ~ maske_fra); /* Blank */
+ }
+ break;
+
+ default:
+ case BC_COPY: /* COPY */
+ if (merke & maske_fra) {
+ merke |= maske_til; /* Sett */
+ } else{
+ merke &= ( ~ maske_til); /* Blank */
+ }
+ break;
+ }
+
+ /* Skriv tilbake */
+ LI_PutBt(pFil,lNr,merke);
+ }
+ }
+}
+
+
+/*
+AR-891120
+CH LI_SaveAdm Skriv globale variabler til indeksfil
+CD ==========================================================================
+CD Formål:
+CD Skriver globale variabler til indeksfilen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD
+CD Bruk:
+CD LI_SaveAdm(pFil);
+ ==========================================================================
+*/
+void LI_SaveAdm(LC_FILADM *pFil)
+{
+ UT_INT64 Size;
+ FTID FilTid;
+ FILE *pF;
+
+ /* Åpner Adm-fil, og posisjonerer */
+ pF = LI_OpenAdm(pFil);
+
+ /* Filstørrelse for SOSI-filen */
+ UT_InqPathSize_i64(pFil->pszNavn,&Size);
+ pFil->SosiBytes = Size;
+
+ /* Oppdateringstid for SOSI-filen */
+ UT_InqPathTid(pFil->pszNavn,&FilTid);
+ pFil->SosiTid.usAar = FilTid.usAar;
+ pFil->SosiTid.usMnd = FilTid.usMnd;
+ pFil->SosiTid.usDag = FilTid.usDag;
+ pFil->SosiTid.usTime = FilTid.usTime;
+ pFil->SosiTid.usMin = FilTid.usMin;
+ pFil->SosiTid.usSek = FilTid.usSek;
+
+
+ pFil->sIdxOpen = UT_FALSE;
+ pFil->ulPid = 0;
+ if (fwrite(pFil,sizeof(*pFil),1,pF) != 1) {
+ LC_Error(112,"(LI_SaveAdm)","");
+ exit(99);
+ }
+
+ fclose(pF);
+}
+
+
+/*
+AR-891120
+CH LI_ReadAdm Les globale variabler fra indeksfil
+CD ==========================================================================
+CD Formål:
+CD Åpner Adm-filen, og henter "globale" variabler fra indeksfilen.
+CD
+CD Parametre: ingen
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short status r Status:
+CD UT_OK (0): Lest OK
+CD LI_LESEFEIL: Feil ved lesing av
+CD LI_OPPTATT: Filen er åpen i et annet program
+CD LI_FEIL_INDEKSVERSJON: Feil indeksversjon
+CD LI_FEIL_STORRELSE: Feil størrelse på SOSI-filen
+CD LI_FEIL_OPPDATTID: Feil oppdateringstid på SOSI-filen
+CD
+CD Bruk:
+CD sStatus = LI_ReadAdm(pFil);
+ ==========================================================================
+*/
+static short LI_ReadAdm(LC_FILADM *pFil)
+{
+ unsigned short usLag;
+ FTID SosiTid;
+ UT_INT64 SosiSize;
+ short sAccess;
+ short sTegnsett;
+ char *pszNavn;
+ LC_IDX_TABELL *pIdx;
+ LC_FILADM *pNesteFil;
+ LC_BASEADM *pBase;
+ FILE *pF;
+ LC_R_NODE *pGeoRN;
+ short sStatus = UT_OK;
+
+
+ /* Åpner Adm-fil, og posisjonerer */
+ pF = LI_OpenAdm(pFil);
+
+ /* Tar vare på div. adm som ikke må bli overskrevet av adm fra filen */
+ pszNavn = pFil->pszNavn;
+ sAccess = pFil->sAccess;
+ usLag = pFil->usLag;
+ pBase = pFil->pBase;
+ pIdx = pFil->pIdx;
+ pGeoRN = pFil->pGeoRN;
+ pNesteFil = pFil->pNesteFil;
+ pBase = pFil->pBase;
+ sTegnsett = pFil->sTegnsett;
+
+ /* Hent div. opplysninger om SOSI-filen */
+ UT_InqPathSize_i64(pszNavn,&SosiSize);
+ UT_InqPathTid(pszNavn,&SosiTid);
+
+ /* Leser adm */
+ if (fread(pFil,sizeof(*pFil),1,pF) != 1)
+ {
+ /* printf("\nFeil lengde lest."); */
+ sStatus = LI_LESEFEIL;
+ }
+
+ // lest OK
+ else
+ {
+ /*
+ // Sjekk om filen er åpen i et annet program
+ if (pFil->sIdxOpen == UT_TRUE)
+ {
+ // Sjekk om dette programmet er aktivt nå, eller om det har krasjet
+ // (ulPid er prosessID for programmet som åpnet filen)
+ if (pFil->ulPid != 0)
+ {
+ HANDLE hProgram = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pFil->ulPid );
+ if (hProgram != NULL)
+ {
+ // Programmet finnes / er aktivt nå
+ CloseHandle(hProgram);
+ // printf("\nFilen er åpen i et annet program.");
+ sStatus = LI_OPPTATT;
+ }
+ }
+ }
+ */
+
+ // Ikke åpen i annet program som er aktivt nå
+ if (sStatus == UT_OK)
+ {
+ /* Sjekk versjonsnummer */
+ if (strcmp(FYBA_INDEKS_VERSJON,pFil->szIdxVer) != 0) {
+ /* printf("\nFeil indeksversjon"); */
+ sStatus = LI_FEIL_INDEKSVERSJON;
+
+ /* Sjekk størrelse for SOSI-filen */
+ } else if (pFil->SosiBytes != SosiSize) {
+ /* printf("\nFeil størrelse på SOSI-filen."); */
+ sStatus = LI_FEIL_STORRELSE;
+
+ /* Sjekk oppdateringstid for SOSI-filen */
+ } else if (memcmp(&pFil->SosiTid,&SosiTid,sizeof(FTID)) != 0) {
+ /* printf("\nFeil oppdateringstid"); */
+ sStatus = LI_FEIL_OPPDATTID;
+ }
+ }
+ }
+
+ /* Legg inn igjen diverse adm. */
+ pFil->pszNavn = pszNavn;
+ pFil->sAccess = sAccess;
+ pFil->usLag = usLag;
+ pFil->pBase = pBase;
+ pFil->pIdx = pIdx;
+ pFil->pGeoRN = pGeoRN;
+ pFil->pNesteFil = pNesteFil;
+ pFil->pBase = pBase;
+ pFil->sTegnsett = sTegnsett;
+ UT_StrCopy(pFil->szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+ UT_StrCopy(pFil->szIdxVer,FYBA_INDEKS_VERSJON,5);
+
+
+ // Retur hvis feil
+ if (sStatus != UT_OK)
+ {
+ fclose(pF);
+ return sStatus;
+ }
+
+ // Marker at basen er åpnet
+ pFil->sIdxOpen = UT_TRUE;
+#ifdef LINUX
+ pFil->ulPid = getpid();
+#else
+ pFil->ulPid = _getpid();
+#endif
+
+ // Skriv
+ fseek(pF,0L,SEEK_SET);
+ if (fwrite(pFil,sizeof(*pFil),1,pF) != 1)
+ {
+ LC_Error(112,"(LI_ReadAdm)","");
+ exit(99);
+ }
+
+ // Stenger filen
+ fclose(pF);
+
+ return sStatus;
+}
+
+
+/*
+AR-930824
+CH LI_WriteRb Skriv gruppe til bufferfil
+CD ==========================================================================
+CD Formål:
+CD Skriv gruppe fra buffer i minne til buffer-fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD UT_INT64 n64FilPos i Startposisjon i buffer-filen.
+CD char *pszGi iu Ginfo-buffer
+CD unsigned long ulGiLen i Ant tegn som skal skrives
+CD double *pdAust iu Koord
+CD double *pdNord iu Koord
+CD LB_INFO * pInfo iu Høyde, KP og PINFO-ofsett
+CD long lNko i Ant koord
+CD char *pszPi iu Pinfo-buffer
+CD unsigned long ulPiLen i Ant tegn som skal skrives
+CD
+CD Bruk:
+CD LI_WriteRb(pFil,lFilPos,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+CD Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+ ==========================================================================
+*/
+void LI_WriteRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+ char *pszGi, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen)
+{
+ short sSkrivefeil = UT_FALSE;
+ FILE *pF;
+
+ /* Åpner RB-fil, og posisjonerer */
+ LI_OpenRb(pFil,n64FilPos,SKRIV);
+ pF = pFil->pBase->pfRb;
+
+ /* GINFO */
+ if (ulGiLen > 0) {
+ if (fwrite(pszGi,(sizeof(char))*ulGiLen,1,pF) != 1) {
+ sSkrivefeil = UT_TRUE;
+ }
+ }
+
+ if (lNko > 0) {
+ /* Øst koordinat */
+ if (fwrite(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+ sSkrivefeil = UT_TRUE;
+ }
+
+ /* Nord koordinat */
+ if (fwrite(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+ sSkrivefeil = UT_TRUE;
+ }
+
+ /* Høyde, KP mm. */
+ if (fwrite(pInfo,(sizeof(LB_INFO)) * lNko,1,pF) != 1) {
+ sSkrivefeil = UT_TRUE;
+ }
+
+ /* PINFO */
+ if (ulPiLen > 0) {
+ if (fwrite(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+ sSkrivefeil = UT_TRUE;
+ }
+ }
+ }
+
+ if (sSkrivefeil == UT_TRUE) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+ LC_Error(74,"(LI_WriteRb): ",err().tx);
+ exit(99);
+ }
+
+ pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+/*
+AR-930823
+CH LI_ReadRb Les gruppe fra buffer-fil
+CD ==========================================================================
+CD Formål:
+CD Les gruppe fra buffer-fil til buffer i minne.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm for filen det skal leses fra.
+CD UT_INT64 n64FilPos i Startposisjon i buffer-filen.
+CD char *pszGi iu Ginfo-buffer
+CD unsigned long ulGiLen i Ant tegn som skal leses til buffer
+CD double *pdAust iu Koord
+CD double *pdNord iu Koord
+CD LB_INFO * pInfo iu Høyde, KP og PINFO-ofsett
+CD long lNko i Ant koord
+CD char *pszPi iu Pinfo-buffer
+CD unsigned long ulPiLen i Ant tegn som skal leses til buffer
+CD
+CD Bruk:
+CD LI_ReadRb(pFil,lFilPos,Sys.Ginfo.pszTx,Sys.pGrInfo->ulGiLen,
+CD Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+ ==========================================================================
+*/
+void LI_ReadRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+ char *pszGi, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen)
+{
+ short sLesefeil = UT_FALSE;
+ FILE *pF;
+
+ /* Åpner RB-fil, og posisjonerer */
+ LI_OpenRb(pFil,n64FilPos,LES);
+ pF = pFil->pBase->pfRb;
+
+ /* Leser GINFO */
+ if (ulGiLen > 0) {
+ if (fread(pszGi,(sizeof(char))*ulGiLen,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+ // AR:2004-05-14 - Test
+ /*
+ int antall = fread(pszGi,(sizeof(char))*ulGiLen,1,pF);
+ if (antall != 1) {
+ sLesefeil = UT_TRUE;
+ // Bygger streng for feilvisning
+ char szError[256];
+ strerror_s(szError,256,errno);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"%s",szError);
+ if (feof(pF)) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"Filslutt");
+ }
+ }
+ */
+ }
+
+ if (lNko > 0) {
+ /* Leser øst koordinat */
+ if (fread(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser nord koordinat */
+ if (fread(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser høyde, KP mm. */
+ if (fread(pInfo,(sizeof(LB_INFO)) * lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser PINFO */
+ if (ulPiLen > 0) {
+ if (fread(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+ }
+ }
+
+ if (sLesefeil == UT_TRUE) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+
+ LC_Error(73,"(LI_ReadRb): ",err().tx);
+ exit(99);
+ }
+
+ pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+/*
+AR-930825
+CH LI_ReadCoordRb Les koordinater fra buffer-fil
+CD ==========================================================================
+CD Formål:
+CD Les koordinatene for en gruppe fra buffer-fil til buffer i minne.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm for filen det skal leses fra.
+CD UT_INT64 n64FilPos i Startposisjon for gruppen i buffer-filen.
+CD unsigned long ulGiLen i Ant tegn GINFO
+CD double *pdAust iu Koord
+CD double *pdNord iu Koord
+CD LB_INFO * pInfo iu Høyde, KP og PINFO-ofsett
+CD long lNko i Ant koord
+CD char *pszPi iu Pinfo-buffer
+CD unsigned long ulPiLen i Ant tegn som skal leses til buffer
+CD
+CD Bruk:
+CD LI_ReadCoordRb(pFil,lFilPos,Sys.pGrInfo->ulGiLen,
+CD Sys.pdAust, Sys.pdNord, Sys.pInfo, Sys.pGrInfo->nko,
+CD Sys.pszPinfo, Sys.pGrInfo->ulPiLen);
+ ==========================================================================
+*/
+void LI_ReadCoordRb(LC_FILADM *pFil, UT_INT64 n64FilPos, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen)
+{
+ short sLesefeil = UT_FALSE;
+ FILE *pF;
+
+ /* Åpner RB-fil, og posisjonerer */
+ LI_OpenRb(pFil,n64FilPos+(UT_INT64)ulGiLen,LES);
+ pF = pFil->pBase->pfRb;
+
+ if (lNko > 0) {
+ /* Leser øst koordinat */
+ if (fread(pdAust,(sizeof(double))*lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser nord koordinat */
+ if (fread(pdNord,(sizeof(double))*lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser høyde, KP mm. */
+ if (fread(pInfo,(sizeof(LB_INFO))*lNko,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+
+ /* Leser PINFO */
+ if (ulPiLen > 0) {
+ if (fread(pszPi,(sizeof(char))*ulPiLen,1,pF) != 1) {
+ sLesefeil = UT_TRUE;
+ }
+ }
+ }
+
+ if (sLesefeil == UT_TRUE) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s : %lld",pFil->pszNavn,n64FilPos);
+ LC_Error(73,"(LI_ReadCoordRb): ",err().tx);
+ exit(99);
+ }
+
+ pFil->pBase->n64FilPosRb = _ftelli64(pF);
+}
+
+
+
+/*
+AR-930823
+CH LI_BerBufferLen Beregn bufferlengde
+CD ==========================================================================
+CD Formål:
+CD Beregn nødvendig plass for å skrive gitt gruppe til RB.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned long ulGiLen i Ant tegn som skal leses til buffer
+CD long lNko i Ant koord
+CD unsigned long ulPiLen i Ant tegn som skal leses til buffer
+CD long lLen r Ant byte for å lagre gruppen
+CD
+CD Bruk:
+CD lLen = LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,
+CD Sys.pGrInfo->ulPiLen);
+ ==========================================================================
+*/
+long LI_BerBufferLen(unsigned long ulGiLen,long lNko,unsigned long ulPiLen)
+{
+ /* GINFO */
+ /* Koordinat Ø og N */
+ /* Høyde, KP og PINFO-ofsett */
+ /* PINFO */
+ return ((long)sizeof(char) * (long)ulGiLen) +
+ (2L * (long)sizeof(double) * lNko) +
+ ((long)sizeof(LB_INFO) * lNko) +
+ ((long)sizeof(char) * (long)ulPiLen);
+
+
+#ifdef TEST
+ long lLen;
+
+ /* GINFO */
+ lLen = (sizeof(char)) * ulGiLen;
+
+ /* Koordinat Ø og N */
+ lLen += 2L * (sizeof(double)) * lNko;
+
+ /* Høyde, KP og PINFO-ofsett */
+ lLen += (sizeof(LB_INFO)) * lNko;
+
+ /* PINFO */
+ lLen += (sizeof(char)) * ulPiLen;
+
+ return lLen;
+#endif
+}
+
+
+/*
+AR-910929
+CH LI_OpenRb Åpne og posisjoner, Rb
+CD ==========================================================================
+CD Formål:
+CD Sjekker at rett Rb-fil er åpen, og posisjoner
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD UT_INT64 n64FilPos i Filposisjon i byte fra filstart
+CD short sModus i Modus (LES / SKRIV)
+CD
+CD Bruk:
+CD void LI_OpenRb(pFil,lFilPos);
+ ==========================================================================
+*/
+static void LI_OpenRb(LC_FILADM *pFil,UT_INT64 n64FilPos,short sModus)
+{
+ if (pFil->pBase->pCurRb != pFil) {
+ // ----- Feil fil er åpen, stenger denne og åpner rett fil
+
+ // Stenger forrige fil
+ if (pFil->pBase->pCurRb != NULL) {
+ fclose(pFil->pBase->pfRb);
+ }
+
+ // Byggr opp fullt filnavn til Rb-filen og åpner filen
+ pFil->pBase->pfRb = LI_OpenIdxFil(pFil, "Rb", ".Idx");
+
+ // Husk current filnummer
+ pFil->pBase->pCurRb = pFil;
+ pFil->pBase->sModusRb = NY;
+ }
+
+ // Posisjoner hvis nødvendig
+ if (pFil->pBase->sModusRb == NY || sModus != pFil->pBase->sModusRb || n64FilPos != pFil->pBase->n64FilPosRb) {
+ //_fseeki64(pFil->pBase->pfRb,n64FilPos,SEEK_SET);
+ UT_SetPos_i64(pFil->pBase->pfRb,n64FilPos);
+
+ pFil->pBase->sModusRb = sModus;
+ }
+}
+
+
+
+/*
+AR-930927
+CH LC_SetModusMerk Setter flag for merking av referert gruppe.
+CD ==========================================================================
+CD Formål:
+CD Setter flag for merking av referert gruppe.
+CD Har innvirkning for virkemåten til:
+CD LC_FAGeo, LC_FASn, og LC_FAGiQuery
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD unsigned short modus i 0 = Ikke merk referert gruppe.
+CD 1 = Merk referert gruppe.
+CD
+CD Bruk:
+CD LC_SetModusMerk(1);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetModusMerk(unsigned short usModus)
+{
+ Sys.usMerkRefGr = usModus;
+}
+
+
+/*
+AR-881123
+CH LC_MerkGr Merk en gruppe brukttabellen
+CD ==========================================================================
+CD Formål:
+CH Merk aktuell gruppe i brukttabellen. Hvis flag for merking av referert
+CD gruppe er satt, blir også eventuelle refererte grupper merket.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sKolonne i Kolonne som skal merkes.
+CD (Lovlig BT_MIN_USER - BT_MAX_USER)
+CD short sBryter i Bryter 1=på, 0=av
+CD long lAntall r Antall grupper merket.
+CD
+CD Bruk:
+CD lAntall = LC_MerkGr(sKolonne,sBryter);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_MerkGr(short sKolonne,short sBryter)
+{
+ LC_BGR AktBgr,Bgr;
+ long lAntRef;
+ short sGiLin,sRefPos;
+ long l;
+ short ngi;
+ long nko;
+ unsigned short info;
+ long *plRefArr;
+ long lAntall = 0L;
+
+
+ /* Lovlig gruppe */
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+ /* Lovlig kolonne */
+ if (sKolonne >= BT_MIN_BT && sKolonne <= BT_MAX_BT) {
+ /* Merk denne gruppen */
+ if (sBryter) {
+ LI_SetBt(Sys.GrId.pFil,Sys.GrId.lNr,sKolonne);
+
+ } else {
+ LI_ClrBt(Sys.GrId.pFil,Sys.GrId.lNr,sKolonne);
+ }
+ lAntall++;
+
+ /* Er det referanser på gruppen og rekursiv merking er aktivisert? */
+ if ((Sys.pGrInfo->info & GI_REF) && Sys.usMerkRefGr) {
+ /* Husk aktuell gruppe */
+ AktBgr = Sys.GrId;
+
+ /* Hent og merk refererte grupper */
+ lAntRef = LC_InqAntRef();
+ plRefArr = (long *) UT_MALLOC(lAntRef * sizeof(long));
+ sGiLin = 2;
+ sRefPos = 0;
+ LC_GetRef(plRefArr,lAntRef,&sGiLin,&sRefPos);
+ for (l=0; l<lAntRef; l++) {
+ if (plRefArr[l] != START_OY && plRefArr[l] != SLUTT_OY) {
+ if (LC_FiSn(AktBgr.pFil,labs(plRefArr[l]),&Bgr)) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ lAntall += LC_MerkGr(sKolonne,sBryter);
+ }
+ }
+ }
+ UT_FREE(plRefArr);
+
+ /* Les tilbake aktuell gruppe */
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+ }
+ }
+
+ return lAntall;
+}
+
+
+/*
+AR-931101
+CH LC_ClrPrioritet Slett prioritets-bit
+CD ==========================================================================
+CD Formål:
+CD Slett prioritets-bit.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD kolonne short i Kolonne som skal merkes.
+CD (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD
+CD Bruk:
+CD LC_ClrPrioritet(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ClrPrioritet(LC_BGR * pGr,short kolonne)
+{
+ short s;
+ LC_GRTAB_LINJE * pGrt;
+
+ LO_TestFilpeker(pGr->pFil,"ClrPrioritet");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= 0 && kolonne < LC_MAX_ANT_PRIOR) {
+
+ pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+ /* Fjern merkingen */
+ s = kolonne / 32;
+ pGrt->ulPrior[s] &= (~ (0x1UL << (kolonne % 32)) );
+
+ }
+
+ } else{ /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_ClrPrioritet)",errtx);
+ }
+}
+
+
+/*
+AR-931101
+CH LC_SetPrioritet Sett prioritets-bit
+CD ==========================================================================
+CD Formål:
+CD Sett prioritets-bit.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD kolonne short i Kolonne som skal merkes.
+CD (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD
+CD Bruk:
+CD LC_SetPrioritet(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetPrioritet(LC_BGR * pGr,short kolonne)
+{
+ short s;
+ LC_GRTAB_LINJE * pGrt;
+
+ LO_TestFilpeker(pGr->pFil,"SetPrioritet");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= 0 && kolonne < LC_MAX_ANT_PRIOR) {
+
+ pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+ /* Fjern merkingen */
+ s = kolonne / 32;
+ pGrt->ulPrior[s] |= (0x1UL << (kolonne % 32));
+ }
+
+ } else { /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_SetPrioritet)",errtx);
+ }
+}
+
+
+/*
+AR-931101
+CH LC_InqPrioritet Hent prioritets-bit
+CD ==========================================================================
+CD Formål:
+CD Hent prioritets-bit.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD kolonne short i Kolonne som skal hentes.
+CD (Lovlig 0 til LC_MAX_ANT_PRIOR-1)
+CD short sAvPaa r Av eller På (UT_TRUE = På, UT_FALSE = Av)
+CD
+CD Bruk:
+CD sAvPaa = LC_InqPrioritet(pGr,kolonne);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqPrioritet(LC_BGR * pGr,short kolonne)
+{
+ short s;
+ LC_GRTAB_LINJE * pGrt;
+
+ LO_TestFilpeker(pGr->pFil,"InqPrioritet");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+ /* Lovlig kolonne */
+ if (kolonne >= 0 && kolonne < LC_MAX_ANT_PRIOR) {
+
+ pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+ /* Returner aktuellt bit */
+ s = kolonne / 32;
+ return ((pGrt->ulPrior[s] & (0x1UL << (kolonne % 32))) == 0UL)? UT_FALSE : UT_TRUE;
+ }
+
+ } else { /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_SetPrioritet)",errtx);
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-931101
+CH LC_ErasePrioritet Blank ut prioritets-bit
+CD ==========================================================================
+CD Formål:
+CD Blank ut prioritets-bit.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pGr i Gruppenummer
+CD
+CD Bruk:
+CD LC_ErasePrioritet(pGr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_ErasePrioritet(LC_BGR * pGr)
+{
+ LC_GRTAB_LINJE * pGrt;
+
+ LO_TestFilpeker(pGr->pFil,"ErasePrioritet");
+
+ /* Lovlig gruppe */
+ if (pGr->lNr >= 0L && pGr->lNr < pGr->pFil->lAntGr) {
+
+ pGrt = LI_GetGrt(pGr->pFil,pGr->lNr);
+
+ /* Blank ut alle bit */
+ pGrt->ulPrior[0] = 0x0UL;
+ pGrt->ulPrior[1] = 0x0UL;
+ pGrt->ulPrior[2] = 0x0UL;
+ pGrt->ulPrior[3] = 0x0UL;
+
+ } else { /* Ulovlig gruppe */
+ char errtx[50];
+ UT_SNPRINTF(errtx,50," %ld",pGr->lNr);
+ LC_Error(72,"(LC_SetPrioritet)",errtx);
+ }
+}
+
+
+/*
+AR-931101
+CH LC_EraseAllPrioritet Blank ut ALLE prioritets-bit
+CD ==========================================================================
+CD Formål:
+CD Blank ut alle prioritets-bit på alle gruppene i denne filen.
+CD
+CD Parametre:
+CD Navn Type I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Filpeker
+CD
+CD Bruk:
+CD LC_EraseAllPrioritet(pFil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_EraseAllPrioritet(LC_FILADM *pFil)
+{
+ LC_GRTAB_LINJE * pGrt;
+ long lNr;
+
+ LO_TestFilpeker(pFil,"EraseAllPrioritet");
+
+ for (lNr=0L; lNr<pFil->lAntGr; lNr++) {
+
+ pGrt = LI_GetGrt(pFil,lNr);
+
+ /* Blank ut alle bit */
+ pGrt->ulPrior[0] = 0x0UL;
+ pGrt->ulPrior[1] = 0x0UL;
+ pGrt->ulPrior[2] = 0x0UL;
+ pGrt->ulPrior[3] = 0x0UL;
+
+ } /* endfor */
+}
+
+/*
+AR:2005-06-20
+CH LC_DumpBt Dump brukttabellen til stderr
+CD ==========================================================================
+CD Formål:
+CD Dump brukttabellen til stderr
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_DumpBt();
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_DumpBt(const char *pszMelding)
+{
+ short ngi,s;
+ long nko;
+ unsigned short info;
+ LC_BGR Bgr,AktBgr;
+ char szTx[1024],szOrd[30];
+ LC_FILADM *pAktuellFil = NULL;
+
+
+ LC_GetGrNr(&AktBgr);
+
+ UT_FPRINTF(stderr,"\n=================================================\n");
+ UT_FPRINTF(stderr,"Dump av brukt-tabellen i FYBA: %s\n", pszMelding);
+ UT_FPRINTF(stderr,"=================================================\n");
+
+ UT_StrCopy(szTx,"\n Snr ",1024);
+
+ for (s=BT_MIN_BT; s<=BT_MAX_BT; ++s)
+ {
+ UT_SNPRINTF(szOrd,30,"%3hd",s);
+ UT_StrCat(szTx,szOrd,1024);
+ }
+ UT_FPRINTF(stderr,"%s\n",szTx);
+
+ UT_FPRINTF(stderr,"---------------------------------------------------------------------------------------------------------\n");
+
+ LC_InitNextBgr(&Bgr);
+
+ /* Alle gruppene i framgrunn */
+ while (LC_NextBgr(&Bgr,LC_FRAMGR)) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ // Filnavn
+ if (Bgr.pFil != pAktuellFil)
+ {
+ UT_FPRINTF(stderr,"%s\n",Bgr.pFil->pszNavn);
+ pAktuellFil = Bgr.pFil;
+ }
+ // Snr
+ UT_SNPRINTF(szTx,1024,"%7ld: ", LC_GetSn());
+
+ for (s=BT_MIN_BT; s<=BT_MAX_BT; ++s)
+ {
+ UT_SNPRINTF(szOrd,30,"%3hd",LC_GetBt(&Bgr,s));
+ UT_StrCat(szTx,szOrd,1024);
+ }
+
+ UT_FPRINTF(stderr,"%s\n",szTx);
+ }
+
+ UT_FPRINTF(stderr,"\n=================================================\n");
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+}
diff --git a/src/FYBA/FYLO.cpp b/src/FYBA/FYLO.cpp
new file mode 100644
index 0000000..eafbda7
--- /dev/null
+++ b/src/FYBA/FYLO.cpp
@@ -0,0 +1,2529 @@
+/* === AR-920210 ========================================================= */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylo.c */
+/* Innhold: Åpningsrutiner for FYSAK-PC */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <math.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/* --- Lokale rutiner -------------------------- */
+static LC_BASEADM * LO_AppBaseAdm(void);
+static short LO_DelBaseAdm(LC_BASEADM * pBase);
+static LC_FILADM * LO_AppFilAdm(LC_BASEADM * pBase);
+static void LO_DelFilAdm(LC_FILADM *pFil);
+static short LO_OpenKladd(LC_BASEADM * pBase);
+static short LO_InklSos(LC_FILADM *pFil,short vising);
+
+/* --- Globale strukturer ---------------------- */
+LC_SYSTEMADM Sys;
+
+LC_FEILMELDING& err() { /* Feilmeldingsstruktur - construct on first use to prevent */
+ /* it from being uninitialized */
+ static LC_FEILMELDING* err = new LC_FEILMELDING;
+ return *err;
+}
+char retur_str[LC_MAX_SOSI_LINJE_LEN]; /* Returstreng */
+
+volatile short fyba_initiert = 0; /* Bryter for å vise at LC_Init er utført */
+
+
+void (*LC_ErrorAdr)(short ifeilnr, const char* logtx, const char* vartx) = NULL;
+void (*LC_StartMessageAdr)(const char *cfil) = NULL;
+void (*LC_ShowMessageAdr)(double prosent) = NULL;
+void (*LC_EndMessageAdr)(void) = NULL;
+short (*LC_CancelAdr)(void) = NULL;
+
+
+
+/*
+AR-910920
+CH LC_Init Initierer FYBA
+CD =============================================================================
+CD Formål:
+CD Initierer FYBA.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_Init();
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_Init(void)
+{
+ fyba_initiert = 1; /* FYBA er initiert */
+
+ /* Husker aktuelle versjonsnummer */
+ UT_StrCopy(Sys.szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+ UT_StrCopy(Sys.szIdxVer,FYBA_INDEKS_VERSJON,5);
+
+ /* Ingen aktuell gruppe */
+ Sys.GrId.lNr = INGEN_GRUPPE;
+ Sys.sGrEndra = END_UENDRA;
+
+ Sys.sResPlass = 0;
+ Sys.lMaxSkriv = 0L;
+ Sys.lAntSkriv = 0L;
+ Sys.sNGISmodus = NGIS_NORMAL;
+ Sys.sUtvidModus = LC_UTVID_SIKKER;
+
+ /* Allokerer buffer */
+ Sys.Hode.pszTx = (char*)UT_MALLOC(LC_MAX_GINFO_BUFFER * sizeof(char));
+ Sys.Ginfo.pszTx = (char*)UT_MALLOC(LC_MAX_GINFO_BUFFER * sizeof(char));
+ Sys.pszPinfo = (char*)UT_MALLOC(LC_MAX_PINFO_BUFFER * sizeof(char));
+ Sys.pdAust = (double *)UT_MALLOC(LC_MAX_KOORD * sizeof(double));
+ Sys.pdNord = (double *)UT_MALLOC(LC_MAX_KOORD * sizeof(double));
+ Sys.pInfo = (LB_INFO *)UT_MALLOC(LC_MAX_KOORD * sizeof(LB_INFO));
+
+ /* Initierer lesebuffer for HO-rutinene */
+ Sys.BufAdm.sStatus = LESEBUFFER_TOM;
+
+ /* Initierer navnetabell for HO-rutinene */
+ LN_InitTab(&(Sys.SosiNavn));
+
+ Sys.usMerkRefGr = 0;
+
+ /* Ingen base er åpnet */
+ Sys.pForsteBase = NULL;
+ Sys.pAktBase = NULL;
+}
+
+
+/*
+AR-910920
+CH LC_Close Stenger ned FYBA
+CD =============================================================================
+CD Formål:
+CD Stenger ned FYBA.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_Close();
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_Close(void)
+{
+ LC_BASEADM *pBase, *pNesteBase;
+
+ /* Ingen aktuell gruppe */
+ Sys.GrId.lNr = INGEN_GRUPPE;
+
+ if (fyba_initiert != 0) {
+ fyba_initiert = 0; /* FYBA er ikke initiert */
+
+ /* Frigir buffer */
+ UT_FREE(Sys.Hode.pszTx);
+ UT_FREE(Sys.Ginfo.pszTx);
+ UT_FREE(Sys.pszPinfo);
+ UT_FREE(Sys.pdAust);
+ UT_FREE(Sys.pdNord);
+ UT_FREE(Sys.pInfo);
+
+ /* Initierer navnetabell for HO-rutinene */
+ LN_InitTab(&(Sys.SosiNavn));
+
+ /* Stenger eventuelle åpne baser. */
+ for (pBase=Sys.pForsteBase; pBase!=NULL; pBase=pNesteBase) {
+ pNesteBase = pBase->pNesteBase;
+ LC_CloseBase(pBase,RESET_IDX);
+ }
+
+ /* Ingen base er åpnet */
+ Sys.pForsteBase = NULL;
+ Sys.pAktBase = NULL;
+
+ }
+}
+
+
+
+
+
+/*
+AR-910920
+CH LC_SetDefLpfi Ledig plass mellom grupper
+CD ==========================================================================
+CD Formål:
+CD Legger inn standardverdi for antall tegn ledig plass bak gruppe
+CD på .SOS-fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short ant_tegn i Antall tegn ledig plass.
+CD
+CD Bruk:
+CD LC_SetDefLpfi(ant_tegn);
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetDefLpfi(short ant_tegn)
+{
+ Sys.sResPlass = ant_tegn;
+}
+
+
+/*
+AR-911003
+CH LC_InqDefLpfi Hent ledig plass mellom grupper
+CD ==========================================================================
+CD Formål:
+CD Henter ut standardverdi for antall tegn ledig plass bak gruppe
+CD på .SOS-fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short ant_tegn r Antall tegn ledig plass.
+CD
+CD Bruk:
+CD ant_tegn = LC_InqDefLpfi();
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_InqDefLpfi(void)
+{
+ return Sys.sResPlass;
+}
+
+
+/*
+AR-911021
+CH LC_InqLag Finn hvilet lag aktuell gruppe tilhører
+CD ==========================================================================
+CD Formål:
+CD Finn hvilket lag aktuell gruppe tilhører.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD unsigned short *usLag u "Lag": LC_FRAMGR eller LC_BAKGR
+CD short status r UT_TRUE = OK, UT_FALSE = Ingen aktuell gruppe
+CD
+CD Bruk:
+CD status = LC_InqLag(&usLag);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqLag(unsigned short *usLag)
+{
+ /* Er det noen aktuell gruppe? */
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+ *usLag = Sys.GrId.pFil->usLag;
+ return UT_TRUE;
+ }
+
+ /* Ingen aktuell gruppe */
+ return UT_FALSE;
+}
+
+
+/*
+AR-920221
+CH LC_InqFilLag Finn hvilet lag en fil tilhører
+CD ==========================================================================
+CD Formål:
+CD Finn hvilket lag en fil tilhører.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Filpeker
+CD unsigned short usLag r "Lag": LC_FRAMGR eller LC_BAKGR
+CD
+CD Bruk:
+CD usLag = LC_InqFilLag(pFil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA unsigned short LC_InqFilLag(LC_FILADM *pFil)
+{
+ /* LO_TestFilpeker(pFil,"LC_InqFilLag"); */
+ LO_TestFilpeker(pFil,"InqFilLag");
+ return pFil->usLag;
+}
+
+
+/*
+AR-920221
+CH LC_SetFilLag Velg hvilet lag en fil tilhører
+CD ==========================================================================
+CD Formål:
+CD Velg hvilket lag en fil tilhører.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Filpeker
+CD unsigned short usLag i "Lag": LC_FRAMGR eller LC_BAKGR
+CD
+CD Bruk:
+CD LC_SetFilLag(pFil,LC_FRAMGR);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetFilLag(LC_FILADM *pFil,unsigned short usLag)
+{
+ short ostat;
+
+ LO_TestFilpeker(pFil,"SetFilLag");
+
+ /* Må lagre aktuell gruppe hvis den er på denne filen og er endret */
+ //if (pFil == Sys.GrId.pFil && Sys.sGrEndra != END_UENDRA) {
+ if (pFil == Sys.GrId.pFil && Sys.GrId.lNr != INGEN_GRUPPE && Sys.sGrEndra != END_UENDRA) {
+ LC_WxGr(SKRIV_OPTIMALT);
+ Sys.sGrEndra = END_UENDRA;
+ }
+
+ /* Tømmer skrivekøa for denne filen */
+ LB_Save(pFil);
+
+ /* Steng eventuell åpen fil */
+ LO_CloseSos(pFil->pBase);
+
+ if ( usLag == LC_FRAMGR) {
+ /* Sjekk at filen kan åpnes med den ønskede aksessen */
+ pFil->pBase->pfSos = UT_OpenFile(pFil->pszNavn,"",UT_UPDATE,UT_OLD,&ostat);
+
+ /* Åpningsfeil */
+ if (ostat != UT_OK) {
+ char szError[256];
+ UT_strerror(szError,256,ostat);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pFil->pszNavn,szError);
+ LC_Error(101,"(LC_SetFilLag)",err().tx);
+
+ } else {
+ // Husk current filnummer mm
+ pFil->pBase->pCurSos = pFil;
+ pFil->sAccess = UT_UPDATE;
+ pFil->usLag = LC_FRAMGR;
+
+ // Husk antall filer i framgrunn/bakgrunn
+ pFil->pBase->sAntFramgrFil++;
+ pFil->pBase->sAntBakgrFil--;
+ }
+
+ } else {
+ pFil->sAccess = UT_READ;
+ pFil->usLag = LC_BAKGR;
+
+ // Husk antall filer i framgrunn/bakgrunn
+ pFil->pBase->sAntBakgrFil++;
+ pFil->pBase->sAntFramgrFil--;
+ }
+}
+
+
+/*
+AR-971114
+CH LC_Backup Lag backup av gitt SOSI-fil
+CD ==========================================================================
+CD Formål:
+CD Lag backup av gitt SOSI-fil.
+CD Kopien legges på en underkatlog med navn "Backup" under den katalogen
+CD SOSI-filen ligger på. Kopien navnes "Filnavn.nnn" der nnn er et
+CD fortløpende nummer fra 000 og oppover. Det første ledige numret blir brukt.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Filpeker
+CD char *pszBackupPath i Katalognavn for lagring av backup.
+CD short sStatus r UT_TRUE = OK
+CD UT_FALSE = Feil.
+CD
+CD Bruk:
+CD sStatus = LC_Backup(pFil, szBackupPath);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_Backup(LC_FILADM *pFil, const char *pszBackupPath)
+{
+ char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+ char szBakFil[_MAX_PATH];
+ char szBakKatalog[_MAX_PATH];
+ short sIdx;
+ UT_INT64 Size;
+
+ LO_TestFilpeker(pFil,"Backup");
+
+ /* Må lagre aktuell gruppe hvis den er på denne filen og er endret */
+ //if (pFil == Sys.GrId.pFil && Sys.sGrEndra != END_UENDRA) {
+ if (pFil == Sys.GrId.pFil && Sys.GrId.lNr != INGEN_GRUPPE && Sys.sGrEndra != END_UENDRA) {
+ LC_WxGr(SKRIV_OPTIMALT);
+ Sys.sGrEndra = END_UENDRA;
+ }
+
+ /* Tømmer skrivekøa for denne filen */
+ LB_Save(pFil);
+
+ /* Steng eventuell åpen fil */
+ LO_CloseSos(pFil->pBase);
+
+
+ UT_splitpath(pFil->pszNavn,drive,dir,fname,ext);
+
+ /* Opprett katalogen */
+ if (pszBackupPath != NULL && *pszBackupPath != '\0') {
+ UT_StrCopy(szBakKatalog,pszBackupPath,_MAX_PATH);
+ } else {
+ UT_makepath(szBakKatalog,drive,dir,"Backup","");
+ }
+ UT_CreateDir(szBakKatalog);
+
+ /* Lag standard navn */
+ for (sIdx=0; sIdx<100; sIdx++) {
+
+ UT_SNPRINTF(ext,_MAX_EXT,".b%02hd",sIdx);
+ UT_makepath(szBakFil,"",szBakKatalog,fname,ext);
+
+ /* Kontroller om filen finnes fra før */
+ /* (Gjøres ved å prøve å spørre om filens størrelse) */
+ if (UT_InqPathSize_i64(szBakFil,&Size) != 0) {
+ break; /* Har funnet et ubrukt navn */
+ }
+ }
+
+ /* Kopier */
+ return UT_CopyFile(pFil->pszNavn,szBakFil, UT_FALSE);
+}
+
+
+/*
+AR-910920
+CH LC_MaxSkriv Max skriv før lagring
+CD ==========================================================================
+CD Formål:
+CD Setter max antall skriv uten lagring til SOSI-filen.
+CD (0 = allt skrives direkte til SOSI-filen.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD long antall i Max antall skriv uten lagring til SOSI-filen
+CD
+CD Bruk:
+CD LC_MaxSkriv(antall);
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_MaxSkriv(long antall)
+{
+ Sys.lMaxSkriv = labs(antall);
+}
+
+
+/*
+AR-910920
+CH LC_InqMaxSkriv Max skriv før lagring
+CD ==========================================================================
+CD Formål:
+CD Spørr etter max antall skriv uten lagring til SOSI-filen.
+CD (0 = allt skrives direkte til SOSI-filen.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD long antall i Max antall skriv uten lagring til SOSI-filen
+CD
+CD Bruk:
+CD antall = LC_InqMaxSkriv();
+ =============================================================================
+*/
+SK_EntPnt_FYBA long LC_InqMaxSkriv(void)
+{
+ return Sys.lMaxSkriv;
+}
+
+
+/*
+AR-900924
+CH LC_SetNgisModus Velg NGIS modus
+CD ==========================================================================
+CD Formål:
+CD Velger handteringsmåte for grupper som er merket for oppdatering av NGIS.
+CD Standardverdi fra LC_Init er NGIS_NORMAL.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short modus i Behandlingsmåte:
+CD NGIS_NORMAL (0) = Vanlig handtering
+CD NGIS_SPESIAL (1) = Spesialmodus der det er mulig å lese
+CD grupper som er merka som sletta.
+CD
+CD Bruk:
+CD LC_SetNgisModus(NGIS_NORMAL);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetNgisModus(short modus)
+{
+ if (modus == NGIS_SPESIAL){
+ Sys.sNGISmodus = NGIS_SPESIAL;
+ } else{
+ Sys.sNGISmodus = NGIS_NORMAL;
+ }
+}
+
+
+/*
+AR-2003-03-31
+CH LC_GetNgisModus Hent NGIS modus
+CD ==========================================================================
+CD Formål:
+CD Henter handteringsmåte for grupper som er merket for oppdatering av NGIS.
+CD Standardverdi fra LC_Init er NGIS_NORMAL.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short modus r Behandlingsmåte:
+CD NGIS_NORMAL (0) = Vanlig handtering
+CD NGIS_SPESIAL (1) = Spesialmodus der det er mulig å lese
+CD grupper som er merka som sletta.
+CD
+CD Bruk:
+CD modus = LC_GetNgisModus();
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetNgisModus(void)
+{
+ return Sys.sNGISmodus;
+}
+
+
+/*
+AR-900924
+CH LC_GetNgisLag Hent NGIS-LAG
+CD ==========================================================================
+CD Formål:
+CD Henter NGIS-LAG for gitt fil.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Fil det ønskes opplsninger om.
+CD char* pszNgisLag r NGIS-lag.
+CD Tom streng = ..NGIS-LAG er ikke funnet
+CD "0" = Bare leseaksess (..NGIS-LAG 0)
+CD
+CD
+CD Bruk:
+CD pszNgisLag = LC_GetNgisLag(pFil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char* LC_GetNgisLag(LC_FILADM *pFil)
+{
+ LO_TestFilpeker(pFil,"LC_GetNgisLag");
+
+ UT_StrCopy(retur_str,pFil->szNgisLag,LC_MAX_SOSI_LINJE_LEN);
+
+ return retur_str;
+}
+
+
+/*
+AR-970109
+CH LC_SetUtvidModus Velg utvis modus
+CD ==========================================================================
+CD Formål:
+CD Velger handteringsmåte for utvidelse av SOSI-filer.
+CD Standardverdi fra LC_Init er LC_UTVID_SIKKER.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short modus i Behandlingsmåte:
+CD LC_UTVID_SIKKER (0) = SOSI-filen stenges og filstørrelsen
+CD oppdateres etter hver gruppe som er
+CD skrevet på slutten av filen.
+CD LC_UTVID_RASK (1) = SOSI-filen stenges IKKE etter hver
+CD gruppe som er skrevet på slutten
+CD av filen.
+CD (Må bare brukes i spesielle tilfeller.)
+CD
+CD Bruk:
+CD LC_SetUtvidModus(LC_UTVID_SIKKER);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SetUtvidModus(short modus)
+{
+ if (modus == LC_UTVID_SIKKER) {
+ Sys.sUtvidModus = LC_UTVID_SIKKER;
+ } else{
+ Sys.sUtvidModus = LC_UTVID_RASK;
+ }
+}
+
+
+/*
+AR-970109
+CH LC_GetUtvidModus Hent utvis modus
+CD ==========================================================================
+CD Formål:
+CD Henter valgt handteringsmåte for utvidelse av SOSI-filer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short modus r Behandlingsmåte:
+CD LC_UTVID_SIKKER (0) = SOSI-filen stenges og filstørrelsen
+CD oppdateres etter hver gruppe som er
+CD skrevet på slutten av filen.
+CD LC_UTVID_RASK (1) = SOSI-filen stenges IKKE etter hver
+CD gruppe som er skrevet på slutten
+CD av filen.
+CD (Må bare brukes i spesielle tilfeller.)
+CD
+CD Bruk:
+CD short sModus = LC_GetUtvidModus();
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetUtvidModus(void)
+{
+ return Sys.sUtvidModus;
+}
+
+
+/*
+AR-910922
+CH LO_AppBaseAdm Legg til ny BaseAdm
+CD ==========================================================================
+CD Formål:
+CD Allokerer en ny BasAdm-tabell.
+CD Legger tabellen inn i kjeden av base-adm-tabeller.
+CD Velg basen som aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase r Basepeker.
+CD
+CD Bruk:
+CD pBase = LO_AppBaseAdm();
+ =============================================================================
+*/
+static LC_BASEADM * LO_AppBaseAdm(void)
+{
+ LC_BASEADM * pBase;
+
+ /*
+ * Allokerer og nullstiller minne til blokken
+ */
+ pBase = (LC_BASEADM *) UT_MALLOC(sizeof(LC_BASEADM));
+ memset(pBase,'\0',sizeof(LC_BASEADM));
+
+ /*
+ * Legger blokken inn i kjeden av baser
+ */
+ pBase->pNesteBase = Sys.pForsteBase;
+ Sys.pForsteBase = pBase;
+
+ /* Velg basen som aktuell base */
+ Sys.pAktBase = pBase;
+
+ return pBase;
+}
+
+
+/*
+AR-931110
+CH LC_InqCurBase Aktuell base
+CD ==========================================================================
+CD Formål:
+CD Spørr etter aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase r Basepeker.
+CD
+CD Bruk:
+CD pBase = LC_InqCurBase();
+ =============================================================================
+*/
+SK_EntPnt_FYBA LC_BASEADM * LC_InqCurBase(void)
+{
+ return Sys.pAktBase;
+}
+
+
+/*
+AR-910924
+CH LO_DelBaseAdm Fjern en BaseAdm
+CD ==========================================================================
+CD Formål:
+CD Fjerner tabellen fra kjeden av base-adm-tabeller og frigir minnet.
+CD OBS! All aktivitet mot basen må være avsluttet før dette kallet.
+CD (Alle sosi-filer må være stengt!)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase i Peker til baseadministrasjonsblokk.
+CD short sStatus r UT_TRUE=OK, UT_FALSE=Basen har åpne filer.
+CD
+CD Bruk:
+CD sStatus = LO_DelBaseAdm(pBase);
+ =============================================================================
+*/
+static short LO_DelBaseAdm(LC_BASEADM * pBase)
+{
+ LC_BASEADM * pB;
+
+ /*
+ * Sjekk at basen er tom
+ */
+ if (pBase->pForsteFil != NULL) return UT_FALSE;
+
+ /*
+ * Sjekk at alle filer er stengt
+ */
+ if (pBase->pCurSos != NULL) fclose(pBase->pfSos);
+ if (pBase->pCurRb != NULL) fclose(pBase->pfRb);
+
+ /*
+ * Fjern blokken fra kjeden av Baser
+ */
+
+ /* Første base i systemet */
+ if (Sys.pForsteBase != NULL) {
+ if (Sys.pForsteBase == pBase) {
+ Sys.pForsteBase = pBase->pNesteBase;
+
+ } else {
+ /* Skanner til basen forran den aktuelle */
+ pB = Sys.pForsteBase;
+ while ((pB->pNesteBase != pBase) && (pB->pNesteBase != NULL)) {
+ pB = pB->pNesteBase;
+ }
+
+ /* Heng sammen kjeden */
+ pB->pNesteBase = pBase->pNesteBase;
+ }
+ }
+
+ /*
+ * Frigi minne som var brukt av blokken
+ */
+ UT_FREE(pBase);
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-910922
+CH LC_OpenBase Åpner ny base
+CD ==========================================================================
+CD Formål:
+CD Åpner en base, nullstiller tabellene.
+CD
+CD Hvis basen er kladdebase opprettes en SOSI-fil med en gruppe i basen,
+CD denne brukes som buffer for les / skriv.
+CD Kladdefilen legges på current directory.
+CD Kladdebase brukes bare når alle SOSI-filer åpnes med sekvensiell les/skriv.
+CD
+CD Den nye basen velges som aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sBaseType i Basetype. Konstanter definert:
+CD LC_BASE = Vanlig base.
+CD LC_KLADD = Kladdebase. Brukes bare i spesielle
+CD tilfeller hvis ingen fil åpnes
+CD som LC_BASE_xx.
+CD LC_BASEADM * pBase r Basepeker.
+CD
+CD Bruk:
+CD pBase = LC_OpenBase(sBaseType);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA LC_BASEADM * LC_OpenBase(short sBaseType)
+{
+ LC_BASEADM * pBase;
+
+ /*
+ * Sjekk at FYBA er initiert og at det er gitt lovlig sBaseType
+ */
+ if (fyba_initiert != 1){
+ LC_Error(4,"(LC_OpenBase)","");
+ exit(2);
+ }
+ if (sBaseType != LC_BASE && sBaseType != LC_KLADD) {
+ LC_Error(1,"(LC_OpenBase)","");
+ exit(2);
+ }
+
+ /*
+ * Legg til ny baseadm og sett denne som aktuell base
+ */
+ pBase = LO_AppBaseAdm();
+
+ /*
+ * Initierer
+ */
+ pBase->sType = sBaseType;
+ pBase->lAntGr = 0L;
+ pBase->sAntFramgrFil = 0;
+ pBase->sAntBakgrFil = 0;
+ pBase->pForsteFil = NULL;
+ pBase->pCurSos = NULL;
+ pBase->pfSos = NULL;
+
+ /* Initierer lesebuffer for les mot SOSI-fil */
+ pBase->BufAdm.sStatus = LESEBUFFER_TOM;
+
+ /*
+ * Kladdebase ==> Opprett kladde-SOSI-fil og opprett en gruppe i denne
+ */
+ if (sBaseType == LC_KLADD) {
+ if (! LO_OpenKladd(pBase)) {
+
+ /*
+ * Frigir BaseAdm og returnerer hvis det ikke kan Åpnes kladdebase.
+ */
+ LO_DelBaseAdm(pBase);
+ return NULL;
+ }
+ }
+
+ return pBase;
+}
+
+
+/*
+AR-911003
+CH LC_SelectBase Velg aktuell base
+CD ==========================================================================
+CD Formål:
+CD Velger ny aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase i Peker til BasAdm.
+CD
+CD Bruk:
+CD LC_SelectBase(pBase);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_SelectBase(LC_BASEADM * pBase)
+{
+ Sys.pAktBase = pBase;
+}
+
+
+/*
+AR-910922
+CH LO_OpenKladd Åpne kladdebase
+CD ==========================================================================
+CD Formål:
+CD Initierer en base for bruk som kladdebase for bare sekvensielle filer,
+CD Nullstiller tabellene.
+CD Oppretter en gruppe i basen, denne brukes som buffer for les / skriv.
+CD Kladdefilen legges på samme directory som indeksfilene.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase i Basepeker.
+CD short status r Status. UT_TRUE=OK, UT_FALSE=Feil ved åpning
+CD
+CD Bruk:
+CD status = LO_OpenKladd(pBase);
+ ==========================================================================
+*/
+static short LO_OpenKladd(LC_BASEADM * pBase)
+{
+ short status = UT_TRUE;
+ short o_stat;
+ long snr;
+ FILE *kladdefil;
+ LC_BGR Bgr;
+ char fil[] = "FyKladd.Sos";
+
+ /*
+ * Åpner kladde-sosi-filen
+ */
+ kladdefil = UT_OpenFile(fil,"",UT_UPDATE,UT_UNKNOWN,&o_stat);
+
+ /* Åpnet OK */
+ if (o_stat == UT_OK){
+ ho_New(kladdefil,0,0.0,0.0,0.001,0.001,0.001,-199999.0,-199999.0,1999999.0,1999999.0);
+ fclose(kladdefil);
+ /* Nuller styrevariablene */
+ pBase->sType = LC_BASE; /* Åpner midlertidig som base */
+
+ /* Åpner kladde filen */
+ if (LC_OpenSos(fil,LC_BASE_FRAMGR,LC_NY_IDX,LC_INGEN_STATUS,
+ &(Bgr.pFil),&o_stat)) {
+
+ LC_NyGr(Bgr.pFil,".LINJE",&Bgr,&snr);
+
+ /* Merke for at dette er åpen kladdebase */
+ pBase->sType = LC_KLADD;
+
+ /* Åpningsfeil */
+ } else {
+ UT_DeleteFile(fil);
+ char szError[256];
+ UT_strerror(szError,256,o_stat);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+ LC_Error(101,"(LC_OpenKladd)",err().tx);
+ status = UT_FALSE;
+ }
+
+ /* Åpningsfeil på kladdefilen */
+ } else {
+ char szError[256];
+ UT_strerror(szError,256,o_stat);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",fil,szError);
+ LC_Error(101,"(LO_OpenKladd)",err().tx);
+ status = UT_FALSE;
+ }
+
+ return status;
+}
+
+
+/*
+AR-891204
+CH LC_CloseBase Steng base
+CD ==========================================================================
+CD Formål:
+CD Stenger alle filer i basen, og frigir baseadministrasjonsblokken.
+CD Hvis aktuell base blir stengt blir første base i systemet valgt som ny
+CD aktuell base.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD PLCBASEADM pBase i Peker tilBaseAdm
+CD short s_stat i Slutt-status
+CD RESET_IDX = Fjern indeksfilene
+CD SAVE_IDX = Lagrer indeksfilene.
+CD ABORT = Fjerner indeksfilene (ved avbrutt
+CD indeks oppbygging).
+CD
+CD Bruk:
+CD LC_CloseBase(pBase,s_stat);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseBase(LC_BASEADM * pBase,short s_stat)
+{
+ short sAktBaseSletta = (pBase == Sys.pAktBase);
+
+ if (pBase == NULL) {
+ LC_Error(101,"(LC_CloseBase)","LC_CloseBase fikk NULL-peker");
+ return;
+ }
+
+ /*
+ * Steng SOSI-filene
+ */
+ while (pBase->pForsteFil != NULL) {
+ LC_CloseSos(pBase->pForsteFil,s_stat);
+ }
+
+ /*
+ * Kladdebase ==> Slett kladdefilen
+ */
+ if (pBase->sType == LC_KLADD) {
+ UT_DeleteFile("FyKladd.Sos");
+ }
+
+ /*
+ * Frigi base-administrasjonsblokken
+ */
+ LO_DelBaseAdm(pBase);
+
+ /* Aktuell base er sletta, velg første base som ny aktuell base */
+ if (sAktBaseSletta) {
+ Sys.pAktBase = Sys.pForsteBase;
+ }
+}
+
+
+/*
+AR-910922
+CH LO_AppFilAdm Legg til ny FilAdm
+CD ==========================================================================
+CD Formål:
+CD Allokerer en ny FilAdm-tabell.
+CD Legger tabellen inn i kjeden av fil-adm-tabeller.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase i Base der filen skal ligge.
+CD LC_FILADM *pFil r Peker til filadministrasjonsblokk.
+CD
+CD Bruk:
+CD pFil = LO_AppFilAdm();
+ =============================================================================
+*/
+static LC_FILADM *LO_AppFilAdm(LC_BASEADM * pBase)
+{
+ LC_FILADM *pFil;
+
+ /*
+ * Allokerer minne til blokken
+ */
+ pFil = (LC_FILADM *) UT_MALLOC(sizeof(LC_FILADM));
+ memset(pFil,'\0',sizeof(LC_FILADM));
+
+ /*
+ * Legger blokken inn i kjeden av filer
+ */
+ if (pBase->pForsteFil == NULL) {
+ pBase->pForsteFil = pFil;
+ } else {
+ pBase->pSisteFil->pNesteFil = pFil;
+ }
+
+ pBase->pSisteFil = pFil;
+ pFil->pNesteFil = NULL;
+
+ /*
+ * Husker hvilken base filen tilhører
+ */
+ pFil->pBase = pBase;
+
+ return pFil;
+}
+
+
+/*
+AR-910924
+CH LO_DelFilAdm Fjern en FilAdm
+CD ==========================================================================
+CD Formål:
+CD Fjerner en fil fra kjeden av fil-adm-tabeller og frigir minnet.
+CD OBS! All aktivitet mot filen og indeksfilene må være avsluttet før dette
+CD kallet.
+CD szBaseVer settes til '\0', slik at dette kan brukes for å sjekke om en
+CD filpeker er lovlig.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til filadministrasjonsblokk.
+CD
+CD Bruk:
+CD LO_DelFilAdm(pFil);
+ =============================================================================
+*/
+static void LO_DelFilAdm(LC_FILADM *pFil)
+{
+ LC_FILADM *pF;
+ LC_BASEADM * pBase = pFil->pBase;
+
+
+ /*
+ * Fjern blokken fra kjeden av filer
+ */
+
+ /* Første fil i basen */
+ if (pBase->pForsteFil == pFil) {
+ pBase->pForsteFil = pFil->pNesteFil;
+ if (pBase->pSisteFil == pFil) {
+ pBase->pSisteFil = NULL;
+ }
+
+ } else {
+ /* Skanner til filen forran den aktuelle */
+ pF = pBase->pForsteFil;
+ while (pF->pNesteFil != pFil) {
+ pF = pF->pNesteFil;
+ }
+
+ /* Heng sammen kjeden */
+ pF->pNesteFil = pFil->pNesteFil;
+ if (pBase->pSisteFil == pFil) {
+ pBase->pSisteFil = pF;
+ }
+ }
+
+ /*
+ * Marker at blokken er frigitt.
+ */
+ pFil->szBaseVer[0] = '\0';
+
+
+ //UT_FPRINTF(stderr,"Frigir minne til FilAdm for: %s\n",pFil->pszNavn);
+
+ /*
+ * Frigi minne som var brukt av blokken
+ */
+ if (pFil->pszNavn != NULL)
+ {
+ UT_FREE(pFil->pszNavn);
+ pFil->pszNavn = NULL;
+ }
+
+ // OBS! midlertidig? AR:2004-05-19
+ //memset(pFil,'\0',sizeof(LC_FILADM));
+
+ UT_FREE(pFil);
+}
+
+
+/*
+AR-920508
+CH LC_OpenSos Åpner og sjekker SOSI-fil
+CD ==========================================================================
+CD Formål:
+CD Åpner en ny fil i aktuell base.
+CD Allokerer minne til ny filadministrasjonsblokk og initierer denne.
+CD Åpner SOSI-filen og legger navn mm. inn i fil-adm.
+CD Leser hodet og tolker det inn i filtabellen.
+CD Hode blir ikke generert for nye filer. Dette kan lages med LC_PutGi, eller
+CD LC_NyttHode eller kopieres fra annen fil, og skrives med LC_WsGr
+CD eller LC_WxGr.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------
+CD char *fil i Filnavn inkl. sti og fil-type
+CD (Hvis fil-type mangler forutsettes .SOS)
+CD short sModus i Filmodus
+CD LC_BASE_FRAMGR = Framgrunnsfil
+CD LC_BASE_BAKGR = Bakgrunnsfil (Bare les)
+CD LC_SEKV_LES = Sekvensiell, les
+CD LC_SEKV_SKRIV = Sekvensiell, skriv
+CD LC_SEKV_UTVID = Sekvensiell, utvid gammel fil
+CD short sNyIdx i Indeksgenerering:
+CD LC_NY_IDX = Tvungen nygenerering
+CD LC_GML_IDX = Bruk gammel .idx hvis den er OK
+CD short sVisStatus i Vis indeksoppbygging
+CD LC_VIS_STATUS = Vis status
+CD LC_INGEN_STATUS = Ikke vis status
+CD LC_FILADM **pFil u Peker til FilAdm blokk.
+CD short *o_stat u Detaljert åpningsstatus:
+CD 0: Åpning og hode OK
+CD >0: Åpningsfeil feilmelding
+CD -1: Åpning OK, tom fil / ikke SOSI-fil
+CD -2: Ikke åpnet, kan ikke bruke append på
+CD tom fil / ikke sosi-fil
+CD -3: (LC_CANCEL): Ikke åpnet,
+CD indeksoppbygging avbrutt med [Esc],
+CD eller feil på filen.
+CD -4: (LC_DUBLIKAT): Filen er i basen fra før (pFil)
+CD -5: (LC_OPPTATT): Filen er åpen i annet program
+CD short status r Åpningsstatus: UT_TRUE = OK
+CD UT_FALSE = Feil, (o_stat gir detalj)
+CD
+CD Bruk:
+CD ist=LC_OpenSos(fil,LC_BASE_FRAMGR,LC_NY_IDX,LC_VIS_STATUS,&pFil,&o_stat);
+CD ist=LC_OpenSos(fil,LC_SEKV_LES,LC_NY_IDX,LC_INGEN_STATUS,&pFil,&o_stat);
+ ==========================================================================
+*/
+
+/// <summary><c>LC_OpenSos</c> Åpner og sjekker SOSI-fil <c>FYBA</c> biblioteket.
+/// </summary>
+/// <param name="fil">Filnavn inkl. sti og fil-type (Hvis fil-type mangler forutsettes .SOS)</param>
+SK_EntPnt_FYBA short LC_OpenSos(const char *fil,short sModus,short sNyIdx,short sVisStatus,
+ LC_FILADM **pFil, short *o_stat)
+{
+ short sAccess;
+ UT_INT64 sluttpos;
+ double nv_a,nv_n,oh_a,oh_n;
+ char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+ char szSosFil[_MAX_PATH];
+ LC_FILADM *pFi;
+ UT_INT64 Size;
+ short sStatus;
+
+ /*
+ * Sjekk at FYBA er initiert
+ */
+ if (fyba_initiert != 1) {
+ LC_Error(4,"(LC_OpenSos)","");
+ exit(2);
+ }
+ if (Sys.pForsteBase == NULL) {
+ LC_Error(5,"(LC_OpenSos)","");
+ exit(2);
+ }
+
+ if (Sys.pAktBase->sType == LC_KLADD) {
+ if (sModus == LC_BASE_FRAMGR || sModus == LC_BASE_BAKGR) {
+ LC_Error(106,"(LC_OpenSos)",fil);
+ exit(2);
+ }
+ }
+
+ *o_stat = 0;
+ LO_CloseSos(Sys.pAktBase); /* Steng eventuell åpen fil */
+
+ /*
+ * Bygg opp fullstendig filnavn
+ */
+ UT_FullPath(szSosFil,fil,_MAX_PATH);
+ UT_splitpath(szSosFil,drive,dir,fname,ext);
+ if (*ext == '\0') UT_StrCopy(ext, ".sos",_MAX_EXT);
+ UT_makepath(szSosFil,drive,dir,fname,ext);
+ /* UT_StrUpper(szSosFil); */
+
+ /* UT_FPRINTF(stderr,"Åpner: %s\n",szSosFil); */
+
+ /* Sjekk om filen er i basen fra før */
+ if ((*pFil = LC_GetFiNr(szSosFil)) != NULL) {
+ *o_stat = LC_DUBLIKAT;
+ return UT_FALSE;
+ }
+
+ /*
+ * Tolk aksess for UT_OpenFile
+ */
+ if (sModus == LC_BASE_BAKGR || sModus == LC_SEKV_LES) {
+ sAccess = UT_READ;
+ } else {
+ sAccess = UT_UPDATE;
+ }
+
+ /*
+ * Fil som bare skal leses må finnes fra før.
+ */
+ if (sModus == LC_SEKV_LES || sModus == LC_BASE_BAKGR) {
+ if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+ *o_stat=-2;
+ return UT_FALSE;
+ }
+ }
+
+ /*
+ * Sekvensiell utvid krever at filen finnes og at det er lov å skrive.
+ */
+ if (sModus == LC_SEKV_UTVID) {
+ if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+ *o_stat=-2;
+ return UT_FALSE;
+ }
+ }
+
+ /*
+ * Basefil og gammel indeks, krever at filene finnes.
+ */
+ if ((sModus == LC_BASE_FRAMGR && sNyIdx == LC_GML_IDX) ||
+ (sModus == LC_BASE_BAKGR && sNyIdx == LC_GML_IDX)) {
+ /* Må også sjekke lovlig aksess ? */
+ if (UT_InqPathSize_i64(szSosFil,&Size) != UT_OK) {
+ sNyIdx = LC_NY_IDX;
+ } else {
+ if (! LI_TestIdx(szSosFil)) {
+ sNyIdx = LC_NY_IDX;
+ }
+ }
+ }
+
+ /*
+ * Legg til ny Filadm
+ */
+ pFi = *pFil = LO_AppFilAdm(Sys.pAktBase);
+
+ /*
+ * Initierer
+ */
+ UT_StrCopy(pFi->szBaseVer,FYBA_IDENT,LC_BASEVER_LEN);
+ UT_StrCopy(pFi->szIdxVer,FYBA_INDEKS_VERSJON,5);
+ pFi->sSosiVer = FYBA_SOSI_VERSJON;
+ UT_StrCopy(pFi->szDato,"*",LC_DATO_LEN);
+ pFi->SosiNiv[0] = 0;
+ pFi->SosiNiv[1] = 0;
+ pFi->pszNavn = (char*)UT_MALLOC(strlen(szSosFil)+1);
+ UT_StrCopy(pFi->pszNavn,szSosFil,strlen(szSosFil)+1);
+ pFi->sAccess = sAccess;
+ pFi->lMaxSnr = NYTT_SNR; /* Ikke noe akt. snr */
+ pFi->lAntGr = 0L;
+ pFi->sTegnsett = TS_DOSN8; /* Standard når ikke annet er gitt */
+ pFi->n64NesteLedigRbPos = 0;
+ *pFi->szNgisLag = '\0';
+
+ pFi->pIdx = NULL;
+ pFi->pGeoRN=NULL;
+
+ if (sModus == LC_BASE_FRAMGR) {
+ pFi->usLag = LC_FRAMGR;
+ } else if (sModus == LC_BASE_BAKGR) {
+ pFi->usLag = LC_BAKGR;
+ } else {
+ pFi->usLag = LC_SEKV;
+ }
+
+ /* Åpner .SOS-filen */
+ pFi->pBase->pfSos = UT_OpenFile(pFi->pszNavn,"",sAccess,UT_OLD,o_stat);
+
+ /* Ukjent fil med skriveaksess ==> opprett filen */
+ if (*o_stat == ENOENT && sAccess == UT_UPDATE){
+ pFi->pBase->pfSos = UT_OpenFile(pFi->pszNavn,"",sAccess,UT_UNKNOWN,o_stat);
+ }
+ pFi->pBase->pCurSos = pFi;
+
+
+ if (*o_stat == UT_OK) { /* Gammel file er åpnet OK */
+ /* Sjekk at SOSI-filen er OK */
+ if (ho_TestSOSI(pFi->pBase->pfSos,&sluttpos) == UT_FALSE){
+ *o_stat = -1; /* Tom fil */
+ }
+
+ } else {
+ /* Åpningsfeil på SOSI-filen ==> avbryter */
+ char szError[256];
+ UT_strerror(szError,256,*o_stat);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pFi->pszNavn,szError);
+ LC_Error(101,"(LC_OpenSos)",err().tx);
+ pFi->pBase->pCurSos = NULL;
+ LO_DelFilAdm(pFi);
+ *pFil = NULL;
+ return UT_FALSE;
+ }
+
+
+ /* Eksisterende fil er åpnet OK, hent tegnsett */
+ if (*o_stat == UT_OK) {
+ ho_GetTegnsett(pFi->pBase->pfSos,&(pFi->sTegnsett));
+
+ /* Tom fil, pr. def. DOSN8 når ikke gitt annet tegnsett */
+ } else if (*o_stat == -1) {
+ pFi->sTegnsett = TS_DOSN8;
+ }
+
+ /* Område */
+ if (*o_stat == UT_OK) {
+ /* Eksisterende fil er åpnet OK, hent område */
+ ho_GetOmr(pFi->pBase->pfSos,&nv_a,&nv_n,&oh_a,&oh_n);
+ pFi->Omraade.dMinAust = nv_a;
+ pFi->Omraade.dMinNord = nv_n;
+ pFi->Omraade.dMaxAust = oh_a;
+ pFi->Omraade.dMaxNord = oh_n;
+
+ } else {
+ /* Tom fil, pr. def. ingen utstrekning */
+ pFi->Omraade.dMinAust = pFi->Omraade.dMinNord = (double)LONG_MAX;
+ pFi->Omraade.dMaxAust = pFi->Omraade.dMaxNord = (double)LONG_MIN;
+ }
+
+ /* Filen er åpnet OK */
+ if (*o_stat == UT_OK || *o_stat == -1) {
+
+ /* Sett aktuell filposisjon mm. */
+ if (sModus == LC_SEKV_UTVID) {
+ if (*o_stat == -1) { /* Kan ikke utvide tom fil */
+ *o_stat=-2;
+ return UT_FALSE;
+ }
+
+ /* Aktuell posisjon settes til slutten av filen */
+ pFi->n64AktPos = sluttpos;
+
+ /* ----- Oppdater filtabellen ----- */
+
+ /* ..TRANSPAR */
+ pFi->TransMaske = LC_TR_ALLT;
+ ho_GetTransEx(pFi->pBase->pfSos,&(pFi->TransMaske),&(pFi->TransPar));
+
+ /* Ikke noe akt. snr */
+ pFi->lMaxSnr = NYTT_SNR;
+
+ /* Kvalitet */
+ ho_GetKvalitet(pFi->pBase->pfSos,&(pFi->Kvalitet.sMetode),
+ &(pFi->Kvalitet.lNoyaktighet),
+ &(pFi->Kvalitet.sSynbarhet),
+ &(pFi->Kvalitet.sHoydeMetode),
+ &(pFi->Kvalitet.lHoydeNoyaktighet));
+
+
+ } else { /* Annen aksess */
+ /* Aktuell posisjon settes til starten av filen */
+ pFi->n64AktPos = 0L;
+ /* I dette tilfellet oppdateres filtabellen */
+ /* når hodet leses/skrives fra/til SOSI-filen */
+ /* Denne brukes senere for å sjekke at hode er skrevet til filen */
+ pFi->TransPar.dEnhet = 0.0;
+ }
+ }
+
+ /*
+ * Basefil, handter indeks.
+ */
+ if (sModus == LC_BASE_FRAMGR || sModus == LC_BASE_BAKGR) {
+
+ if (sNyIdx == LC_GML_IDX) {
+ // Lagret indeks, les inn indeksfilene
+ sStatus = LI_OpenRead(pFi);
+
+ if (sStatus == UT_OK) {
+ // Åpnet OK, nullstill prioritetstabellen
+ LC_EraseAllPrioritet(pFi);
+
+ } else if (sStatus == LI_OPPTATT) {
+ // Filen er åpen i et annet program
+ LO_CloseSos(Sys.pAktBase); // Steng eventuell åpen fil
+ LO_DelFilAdm(*pFil); // Frigir filadministrasjonsblokken
+ *pFil = NULL;
+ *o_stat = LC_OPPTATT;
+ return UT_FALSE;
+
+ } else {
+ // Feil indeksversjon, størrelse eller oppdateringstid på SOSI-filen
+ // - Må bygge ny indeks
+ LI_Close(pFi,RESET_IDX);
+ sNyIdx = LC_NY_IDX;
+
+ /*
+ * Må initiere deler av fil-adm på nytt.
+ */
+ pFi->lAntGr = 0L;
+ pFi->n64NesteLedigRbPos = 0;
+ pFi->lMaxSnr = NYTT_SNR; /* Ikke noe akt. snr */
+ pFi->SosiNiv[0] = 0;
+ pFi->SosiNiv[1] = 0;
+ }
+ }
+
+
+ if (sNyIdx == LC_NY_IDX) {
+ LI_OpenInit(pFi); /* Initierer LI-systemet */
+ LN_InitTab(&(pFi->SosiNavn)); /* Initierer navne-systemet */
+
+ if (*o_stat != -1) { /* Filen har innhold */
+ /* Bygg indekser for filen, m. vising av status */
+ pFi->usDataFeil = 0;
+ if (! LO_InklSos(pFi,sVisStatus)) {
+ /* Indeksoppbygging er avbrutt */
+ /* Steng filen */
+ LC_CloseSos(pFi,RESET_IDX);
+ *pFil = NULL;
+ *o_stat = LC_CANCEL;
+ return UT_FALSE;
+ }
+
+ /* Gi melding om ulovlig referanse */
+ if ((pFi->usDataFeil & LC_DATAFEIL_REF) != 0) {
+ LC_Error(56,"(LC_OpenSos)",pFi->pszNavn);
+ }
+
+ /* Gi melding om ulovlig bue */
+ if ((pFi->usDataFeil & LC_DATAFEIL_BUE) != 0) {
+ LC_Error(59,"(LC_OpenSos)",pFi->pszNavn);
+ }
+ }
+ }
+
+ /*
+ * Sekvensiell fil, initier navnesystemet.
+ */
+ } else {
+ LN_InitTab(&(pFi->SosiNavn));
+ }
+
+
+ // Husk antall filer i framgrunn/bakgrunn
+ if (pFi->usLag & LC_FRAMGR) pFi->pBase->sAntFramgrFil++;
+ else if (pFi->usLag & LC_BAKGR) pFi->pBase->sAntBakgrFil++;
+
+
+ // Initierer filtype
+ LC_SetFilType(pFi,LC_FILTYPE_UKJENT);
+ return UT_TRUE;
+}
+
+
+/*
+AR-910925
+CH LO_ReopenSos Reåpne SOSI-fil
+CD ==========================================================================
+CD Formål:
+CD Åpner på nytt en av filene i filtabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LO_ReopenSos(pFil);
+ ==========================================================================
+*/
+void LO_ReopenSos(LC_FILADM *pFil)
+{
+ short ostat;
+
+ if (pFil->pBase->pCurSos != pFil) {
+ if (pFil->pBase->pCurSos != NULL){ /* Stenger forrige fil */
+ fclose(pFil->pBase->pfSos);
+ }
+
+ /* Åner filen */
+ pFil->pBase->pfSos = UT_OpenFile(pFil->pszNavn,"",pFil->sAccess,UT_OLD,&ostat);
+
+ /* Åpningsfeil */
+ if (ostat != UT_OK) {
+ LC_Error(6,"(LO_ReopenSos)",pFil->pszNavn);
+ exit(2);
+ }
+
+ /* Husk current filnummer */
+ pFil->pBase->pCurSos = pFil;
+ }
+}
+
+
+/*
+AR-881027
+CH LC_CloseSos Steng SOSI-fil
+CD ==========================================================================
+CD Formål:
+CD Stenger en SOSI-fil, og fjerner den fra basen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm-blokk
+CD short s_stat i Slutt-status
+CD RESET_IDX = Fjern indeksfilene
+CD SAVE_IDX = Lagrer indeksfilene.
+CD
+CD Bruk:
+CD LC_CloseSos(pFil,SAVE_IDX);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseSos(LC_FILADM *pFil,short s_stat)
+{
+ LC_BGR Bgr,AktBgr;
+ short ngi,linje_nr;
+ long nko;
+ unsigned short info;
+ char szSosiNiv[10];
+ LC_BOKS * pB;
+
+
+ /* LO_TestFilpeker(pFil,"LC_CloseSos"); */
+ LO_TestFilpeker(pFil,"CloseSos");
+
+ /*
+ * Hvis aktuell gruppe er på denne filen
+ */
+ if (Sys.GrId.lNr != INGEN_GRUPPE && Sys.GrId.pFil == pFil) {
+
+ if (pFil->pBase->sType == LC_BASE) {
+ /* Hvis gruppen er endra, skriv den til filen */
+ if (Sys.sGrEndra != END_UENDRA) {
+ if (LC_WxGr(SKRIV_SOSI) == UT_FALSE) {
+ // Indeksfilene ikke er brukbare
+ s_stat = RESET_IDX;
+ }
+ }
+ }
+ /* Vis at det ikke er noen aktuell gruppe lenger */
+ Sys.GrId.lNr = INGEN_GRUPPE;
+ }
+
+ // Husk antall filer i framgrunn/bakgrunn
+ if (pFil->usLag & LC_FRAMGR) pFil->pBase->sAntFramgrFil--;
+ else if (pFil->usLag & LC_BAKGR) pFil->pBase->sAntBakgrFil--;
+
+ /*
+ * Sikrer oppdatering av sosi-filen
+ */
+ if (pFil->pBase->sType == LC_BASE) {
+ LB_Save(pFil);
+ }
+
+ /* Oppdater ..SOSI-NIVÅ i fil-hodet */
+ if (pFil->SosiNiv[1] > pFil->SosiNiv[0]) {
+ AktBgr = Sys.GrId;
+ Bgr.pFil = pFil;
+ Bgr.lNr = 0;
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ UT_SNPRINTF (szSosiNiv, 10, "%d", (int)pFil->SosiNiv[1]);
+ ngi = LC_PutGP("..SOSI-NIVÅ", szSosiNiv, &linje_nr);
+ LC_WxGr(SKRIV_SOSI);
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ } else {
+ Sys.GrId = AktBgr;
+ }
+ }
+
+ /* UT_FPRINTF(stderr,"Stenger: %s\n",pFil->pszNavn); */
+ LO_CloseSos(pFil->pBase);
+
+ /*
+ * Indeks skal alltid fjernes for kladdefilen i kladdebase
+ */
+ if (pFil->pBase->sType == LC_KLADD && (pFil->usLag & LC_FRAMGR)) {
+ s_stat = RESET_IDX;
+ }
+
+ /*
+ * Fjern indeksfilene / lagre indeks og steng filer
+ */
+ if (pFil->usLag != LC_SEKV) {
+ LI_Close(pFil,s_stat);
+ }
+
+ /*
+ * Frigi fil-administrasjonsblokken
+ */
+ LO_DelFilAdm(pFil);
+
+ /* Oppdaterer omskrevet boks for basen */
+ if (Sys.pAktBase != NULL) { /* er basen fortsatt aapent? */
+ pFil = Sys.pAktBase->pForsteFil;
+ pB = &(Sys.pAktBase->Omraade);
+ pB->dMinAust = pB->dMinNord = (double)LONG_MAX;
+ pB->dMaxAust = pB->dMaxNord = (double)LONG_MIN;
+ while (pFil != NULL) {
+ /* Er filen i rett lag? (Hoper over sekvensielle filer) */
+ if (pFil->usLag & (LC_FRAMGR | LC_BAKGR)) {
+ /* Filen inneholder data */
+ if (pFil->pGeoRN != NULL) {
+ pB->dMinAust = min(pB->dMinAust,pFil->Omraade.dMinAust);
+ pB->dMinNord = min(pB->dMinNord,pFil->Omraade.dMinNord);
+ pB->dMaxAust = max(pB->dMaxAust,pFil->Omraade.dMaxAust);
+ pB->dMaxNord = max(pB->dMaxNord,pFil->Omraade.dMaxNord);
+ }
+ }
+ pFil = pFil->pNesteFil;
+ }
+ }
+}
+
+
+/*
+AR:2009-03-20
+CH LC_FcloseSos Steng åpen SOSI-fil i filsystemet
+CD ==========================================================================
+CD Formål:
+CD Denne rutinen brukes til å sikre at en fil er oppdatert og stengt i filsystemet,
+CD slik at SOSI-filen kan leses fra andre program.
+CD
+CD OBS!
+CD Stenger bare filen i filsystemet.
+CD Filen er fortsatt åpen i basen.
+CD FYBA åpner automatisk filen på nytt når det er behov for dette.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LC_FcloseSos(pFil);
+==========================================================================
+*/
+SK_EntPnt_FYBA void LC_FcloseSos(LC_FILADM *pFil)
+{
+ LO_TestFilpeker(pFil,"LC_FcloseSos");
+
+ // Må lagre aktuell gruppe hvis den er på denne filen og er endret
+ if (pFil == Sys.GrId.pFil && Sys.GrId.lNr != INGEN_GRUPPE && Sys.sGrEndra != END_UENDRA) {
+ LC_WxGr(SKRIV_OPTIMALT);
+ Sys.sGrEndra = END_UENDRA;
+ }
+
+ // Tømmer skrivekøa for denne filen
+ LB_Save(pFil);
+
+ // Steng eventuell åpen fil
+ LO_CloseSos(pFil->pBase);
+}
+
+
+/*
+AR-911001
+CH LO_CloseSos Steng current SOSI-fil
+CD ==========================================================================
+CD Formål:
+CD Stenger current SOSI-fil i basen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BASEADM * pBase i Peker til BaseAdm-blokk
+CD
+CD Bruk:
+CD LO_CloseSos(pBase);
+ ==========================================================================
+*/
+void LO_CloseSos(LC_BASEADM * pBase)
+{
+ if (pBase->pCurSos != NULL) {
+ fclose(pBase->pfSos);
+ pBase->pCurSos = NULL;
+ }
+}
+
+
+/*
+AR-890510
+CH LO_BeFt Beregn omregnings-parametre
+CD ==========================================================================
+CD Formål:
+CD Oppdaterer filtabellen med hodeinformasjoner fra aktuell gruppe,
+CD som må være SOSI-filens hode.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm-blokk
+CD
+CD Bruk:
+CD LO_BeFt(pFil);
+ ==========================================================================
+*/
+void LO_BeFt(LC_FILADM *pFil)
+{
+ double nva,nvn,oha,ohn;
+ short lin;
+ char *cp;
+
+
+ /* Transformasjonsparametre */
+ pFil->TransMaske = LC_TR_ALLT;
+ LC_GetTransEx(&(pFil->TransMaske),&(pFil->TransPar));
+
+ /* Område */
+ LC_GetOmr(&nva,&nvn,&oha,&ohn);
+ pFil->Omr.dMinAust = nva;
+ pFil->Omr.dMinNord = nvn;
+ pFil->Omr.dMaxAust = oha;
+ pFil->Omr.dMaxNord = ohn;
+
+ /* Kvalitet */
+ LC_GetKvalitet(&(pFil->Kvalitet.sMetode),
+ &(pFil->Kvalitet.lNoyaktighet),
+ &(pFil->Kvalitet.sSynbarhet),
+ &(pFil->Kvalitet.sHoydeMetode),
+ &(pFil->Kvalitet.lHoydeNoyaktighet));
+
+ /* Tegnsett */
+ LC_GetTegnsett(&(pFil->sTegnsett));
+
+ /* SOSI-VERSJON */
+ lin=2;
+ if ((cp = LC_GetGP("..SOSI-VERSJON",&lin,Sys.pGrInfo->ngi)) != NULL) {
+ pFil->sSosiVer = (short)(strtod(cp,&cp)*100.0);
+ } else {
+ pFil->sSosiVer = FYBA_SOSI_VERSJON;
+ }
+
+ // DATO
+ lin=2;
+ if ((cp = LC_GetGP("..DATO",&lin,Sys.pGrInfo->ngi)) != NULL) {
+ UT_StrCopy(pFil->szDato,cp,LC_DATO_LEN);
+ } else {
+ UT_StrCopy(pFil->szDato,"*",LC_DATO_LEN);
+ }
+
+ /* SOSI-NIVÅ */
+ lin=2;
+ if ((cp = LC_GetGP("..SOSI-NIVÅ",&lin,Sys.pGrInfo->ngi)) != NULL) {
+ pFil->SosiNiv[0] = (char)(strtol(cp,&cp,10));
+ } else {
+ pFil->SosiNiv[0] = 0;
+ }
+
+ /* ..NGIS-LAG */
+ UT_StrCopy(pFil->szNgisLag,LH_GetNgisLag(),LC_NGISLAG_LEN);
+}
+
+
+/*
+AR-911003
+CH LC_GetBaOm Hent baseområde
+CD ==========================================================================
+CD Formål:
+CD Henter baseområdet for aktuell base (Sum av filhodene).
+CD Sekvensielle filer regnes ikke med.
+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 double *nva u Nedre venstre øst
+CD double *nvn u Nedre venstre nord
+CD double *oha u Øvre høyre øst
+CD double *ohn u Øvre høyre nord
+CD short sStatus r UT_TRUE=OK, UT_FALSE=ingen fil
+CD
+CD Bruk:
+CD sStatus = LC_GetBaOm(LC_FRAMGR,&nva,&nvn,&oha,&ohn);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBaOm(unsigned short usLag,double *nva,double *nvn,double *oha,
+ double *ohn)
+{
+ double na,nn,oa,on;
+ LC_FILADM *pFil;
+ short sAntall = 0;
+
+ *nvn = LONG_MAX;
+ *nva = LONG_MAX;
+ *ohn = LONG_MIN;
+ *oha = LONG_MIN;
+
+ LC_InitNextFil(&pFil);
+ while (LC_NextFil(&pFil,usLag)) {
+ sAntall++;
+ if (LC_GetFiOm(pFil,&na,&nn,&oa,&on)) {
+ *nva = min (*nva, na);
+ *nvn = min (*nvn, nn);
+ *oha = max (*oha, oa);
+ *ohn = max (*ohn, on);
+ }
+ }
+
+ return (sAntall > 0);
+}
+
+
+/*
+AR-910928
+CH LC_GetFiOm Hent område fra fil-hode
+CD ==========================================================================
+CD Formål:
+CD Hent område for en SOSI-fil i basen.
+CD Fungerer ikke mot sekvensielle filer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD double nva u Nedre venstre øst
+CD double nvn u Nedre venstre nord
+CD double oha u Øvre høyre øst
+CD double ohn u Øvre høyre nord
+CD short ist r Status (UT_TRUE=OK, UT_FALSE=sekvensiell fil)
+CD
+CD Bruk:
+CD ist = LC_GetFiOm(pFil,&nva,&nvn,&oha,&ohn);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetFiOm(LC_FILADM *pFil,double *nva,double *nvn,double *oha,double *ohn)
+{
+ /* LO_TestFilpeker(pFil,"LC_GetFiOm"); */
+ LO_TestFilpeker(pFil,"LC_GetFiOm");
+
+ if (pFil->usLag != LC_SEKV) {
+ *nva = pFil->Omr.dMinAust;
+ *nvn = pFil->Omr.dMinNord;
+ *oha = pFil->Omr.dMaxAust;
+ *ohn = pFil->Omr.dMaxNord;
+ return UT_TRUE;
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911001
+CH LO_InklSos Inkluder SOSI-fil i base
+CD ==========================================================================
+CD Formål:
+CD Hjelperutine for LC_OpenSos.
+CD Bygger indeks og klargjør filen for basen.
+CD Prosessen kan avbrytes med <ESC>, og rutinen returnerer da UT_FALSE.
+CD Aktuell gruppe blir brukt under prosessen, og etterpå er det ingen
+CD aktuell gruppe tilgjengelig.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short sVisStatus i Vis indeksoppbygging
+CD LC_VIS_STATUS = Vis status
+CD LC_INGEN_STATUS = Ikke vis status
+CD short sStatus r Status: UT_TRUE=OK, UT_FALSE=avbrutt eller feil
+CD
+CD Bruk:
+CD ant_bgr = LO_InklSos(pFil,LC_VIS_STATUS);
+ ==========================================================================
+*/
+static short LO_InklSos(LC_FILADM *pFil,short sVisStatus)
+{
+ unsigned long ulLedigPlass;
+ short siste,ngi,nivaa;
+ long nko;
+ unsigned short info;
+ UT_INT64 pos,fpos;
+ long lGrNr;
+ LC_BGR Bgr;
+ LC_GRTAB_LINJE *pForrigeGrInfo,*pGrInfo;
+ LC_BOKS * pB;
+ short avbrutt = 0;
+ double lengde_faktor = 0.0;
+ short sStatus = UT_TRUE;
+ short pnr = 1;
+
+ // Hvis aktuell gruppe er endret, skriv den
+ if (Sys.GrId.lNr != INGEN_GRUPPE && Sys.sGrEndra != END_UENDRA) {
+ LC_WxGr(SKRIV_OPTIMALT);
+ }
+
+ LO_ReopenSos(pFil); // Sikkrer at filen er åpen - Kan ha blitt stengt i LC_WxGr
+
+ Sys.GrId.pFil = pFil;
+
+ // ----- Søk fram til .HODE
+ if (ho_FinnHode(pFil->pBase->pfSos, &pos) == UT_TRUE) {
+
+ // ----- Bygg indeks
+ /* Sikkrer at ny lesing startes */
+ _fseeki64(pFil->pBase->pfSos,pos,SEEK_SET);
+
+ /* Ledetekst */
+ if (sVisStatus == LC_VIS_STATUS) {
+ LC_StartMessage(pFil->pszNavn);
+ fpos = _ftelli64(pFil->pBase->pfSos);
+ _fseeki64(pFil->pBase->pfSos,-1,SEEK_END);
+ lengde_faktor = 100.0 / (double)_ftelli64(pFil->pBase->pfSos);
+ _fseeki64(pFil->pBase->pfSos,fpos,SEEK_SET);
+ }
+
+ pForrigeGrInfo = NULL;
+
+ do {
+ if (pFil->lAntGr < LC_MAX_GRU) { /* Klargjør for lesing */
+
+ /* Sjekk ledig diskplass for SOSI-filer */
+
+ if (pFil->sAccess == UT_UPDATE) {
+ UT_InqAvailSize(pFil->pszNavn,&ulLedigPlass);
+ if (ulLedigPlass < ((unsigned long)LC_MAX_KOORD * (unsigned long)120)) {
+ /* Disken er snart full */
+ LC_Error(93,"(LO_InklSos)",pFil->pszNavn);
+ }
+ }
+
+ Sys.GrId.lNr = pFil->lAntGr++; /* (Nr er 1 mindre enn antall) */
+
+ Sys.pGrInfo = LI_AppGrt(pFil,Sys.GrId.lNr);
+
+
+ Sys.pGrInfo->sosi_st = pos;
+
+
+
+ /* Les gruppen */
+ siste = LB_RGru(pFil,pos,&pos);
+
+ /* Buffer for GetPP er ødelagt */
+ Sys.sPibufStatus = LC_PIBUF_TOM;
+
+ /* Grafisk vising av mengde lest */
+ if (sVisStatus == LC_VIS_STATUS) {
+ LC_ShowMessage((double)pos * lengde_faktor);
+ }
+
+ /* Gruppe lest OK */
+ if ( ! siste) {
+ LC_OppdaterEndret(O_GINFO);
+ nivaa = 2;
+ 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);
+
+ /* Oppdater buffer-fil */
+ Sys.GrId.pFil->lSisteGrRb = Sys.GrId.lNr;
+ Sys.pGrInfo->rb_st = Sys.GrId.pFil->n64NesteLedigRbPos;
+ Sys.pGrInfo->rb_forrige_gr = Sys.GrId.lNr - 1L;
+ Sys.pGrInfo->rb_neste_gr = INGEN_GRUPPE;
+ Sys.pGrInfo->ulPrior[0] = 0UL;
+ Sys.pGrInfo->ulPrior[1] = 0UL;
+ Sys.pGrInfo->ulPrior[2] = 0UL;
+ Sys.pGrInfo->ulPrior[3] = 0UL;
+
+ if (pForrigeGrInfo != NULL) {
+ pForrigeGrInfo->rb_neste_gr = 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);
+
+ Sys.GrId.pFil->n64NesteLedigRbPos +=
+ (UT_INT64)LI_BerBufferLen(Sys.pGrInfo->ulGiLen,Sys.pGrInfo->nko,Sys.pGrInfo->ulPiLen);
+
+ pForrigeGrInfo = Sys.pGrInfo;
+
+ /* Nuller merking */
+ LI_PutBt(pFil,Sys.GrId.lNr,0L);
+
+ LS_Indx(); /* Serienummer tabeller */
+ LR_Indx(); /* Geografisk indeks */
+
+ /* ".SLUTT" er lest */
+ } else {
+ pFil->n64AktPos = pos;
+ pFil->lAntGr--;
+ }
+
+ } else { /* For mange grupper, tab. sprengt */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld",pFil->lAntGr+1L);
+ LC_Error(2,"(LO_InklSos)",err().tx);
+ exit(99);
+ }
+
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ } while ( !siste && !avbrutt);
+
+
+ /* Bygg indeks for grupper med referanser */
+ if (! avbrutt) { /* Lesing er avbrutt */
+ lengde_faktor = 100.0 / (double)pFil->lAntGr;
+
+ Bgr.pFil = pFil;
+ for (lGrNr=0; lGrNr<pFil->lAntGr && !avbrutt; lGrNr++) {
+ if (sVisStatus == LC_VIS_STATUS) {
+ LC_ShowMessage((double)lGrNr * lengde_faktor);
+ }
+
+ /* Sjekk om gruppen har referanser */
+ pGrInfo = LI_GetGrt(pFil,lGrNr);
+ if ((pGrInfo->info & GI_REF) != 0) {
+ /* Les inn og beregn omskreven boks medregnet refererte grupper */
+ Bgr.lNr = lGrNr;
+ if (LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info) != INGEN_GRUPPE) {
+ LR_IndxFlate();
+ }
+ }
+
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ }
+ }
+
+ Sys.GrId.lNr = INGEN_GRUPPE; /* Ingen aktuell gruppe */
+ Sys.sGrEndra = END_UENDRA;
+
+ /* Oppdaterer omskrevet boks for basen */
+ if ( ! avbrutt) { /* Lesing er avbrutt */
+ pFil = Sys.pAktBase->pForsteFil;
+ pB = &(Sys.pAktBase->Omraade);
+ pB->dMinAust = pB->dMinNord = (double)LONG_MAX;
+ pB->dMaxAust = pB->dMaxNord = (double)LONG_MIN;
+ while (pFil != NULL) {
+ /* Er filen i rett lag? (Hoper over sekvensielle filer) */
+ if (pFil->usLag & (LC_FRAMGR | LC_BAKGR)) {
+ /* Filen inneholder data */
+ if (pFil->pGeoRN != NULL) {
+ pB->dMinAust = min(pB->dMinAust,pFil->Omraade.dMinAust);
+ pB->dMinNord = min(pB->dMinNord,pFil->Omraade.dMinNord);
+ pB->dMaxAust = max(pB->dMaxAust,pFil->Omraade.dMaxAust);
+ pB->dMaxNord = max(pB->dMaxNord,pFil->Omraade.dMaxNord);
+ }
+ }
+ pFil = pFil->pNesteFil;
+ }
+ }
+
+ if (avbrutt) { /* Lesing er avbrutt */
+ LC_Error(10,"(LO_InklSos)","");
+ pFil->lAntGr = 0L;
+ sStatus = UT_FALSE;
+ }
+
+ if (sVisStatus == LC_VIS_STATUS) {
+ LC_EndMessage();
+ }
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-911001
+CH LC_GetFiNr Get fil nummer
+CD ==========================================================================
+CD Formål:
+CD Sjekker alle filer i aktuell base om noen av den har det gitte filnavnet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char fil_navn i Filnavn
+CD LC_FILADM *pFil r Peker til FilAdm for filen. (NULL = ukjent fil)
+CD
+CD Bruk:
+CD pFil = LC_GetFiNr(fil_navn);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA LC_FILADM *LC_GetFiNr(const char *fil_navn)
+{
+ LC_FILADM *pFil;
+ char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+ char szSosFil[_MAX_PATH];
+
+
+ /*
+ * Bygg opp fullstendig filnavn
+ */
+ UT_FullPath(szSosFil,fil_navn,_MAX_PATH);
+ UT_splitpath(szSosFil,drive,dir,fname,ext);
+ if (*ext == '\0') UT_StrCopy(ext,".sos",_MAX_EXT);
+ UT_makepath(szSosFil,drive,dir,fname,ext);
+
+ for (pFil=Sys.pAktBase->pForsteFil; pFil!=NULL; pFil=pFil->pNesteFil) {
+ /* Rett filnavn? ==> */
+ if (UT_FilnavnCmp(pFil->pszNavn,szSosFil) == 0) return pFil;
+ }
+
+ return NULL;
+}
+
+
+/*
+AR-911001
+CH LC_GetFiNa Hent filnavn
+CD ==========================================================================
+CD Formål:
+CD Henter filnavnet for en fil i basen. Fungerer både for basefiler
+CD og for sekvensielle filer.
+CD OBS! Hvis du skal endre på filnavnet må du først kopiere det
+CD til en lokale varialel.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD char *fil_navn r Peker til filnavn
+CD
+CD Bruk:
+CD fil_navn = LC_GetFiNa(pFil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetFiNa(LC_FILADM *pFil)
+{
+ /* LO_TestFilpeker(pFil,"LC_GetFiNa"); */
+ LO_TestFilpeker(pFil,"GetFiNa");
+
+ return pFil->pszNavn;
+}
+
+
+/*
+AR-920729
+CH LO_TestFilpeker Sjekk at en filpeker er gyldig
+CD ==========================================================================
+CD Formål:
+CD Sjekk at en filpeker er gyldig.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm
+CD char *pszRutineNavn i Melding (rutinenavnet for kallende rutine)
+CD
+CD Bruk:
+CD LO_TestFilpeker(pFil,"LC_OpenBase");
+ ==========================================================================
+*/
+void LO_TestFilpeker(LC_FILADM *pFil,char *pszRutineNavn)
+{
+ char szTx[100];
+
+
+ if (pFil == NULL || *(pFil->szBaseVer) != 'F') {
+
+ UT_SNPRINTF(szTx,100," %s, (Filpeker: %p)",pszRutineNavn,pFil);
+ LC_Error(105,"(TestFilpeker)",szTx);
+ }
+}
+
+
+/*
+AR-921008
+CH LC_ErFilBase Sjekker om en fil er i basen
+CD ==========================================================================
+CD Formål:
+CD Sjekker om en fil er i basen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------
+CD char *fil i Filnavn inkl. sti og fil-type
+CD (Hvis fil-type mangler forutsettes .SOS)
+CD short status r Status: UT_TRUE = Filen er med i basen.
+CD UT_FALSE = Filen er IKKE med i basen.
+CD
+CD Bruk:
+CD ist = LC_ErFilBase(fil);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_ErFilBase(const char *fil)
+{
+ char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
+ char szSosFil[_MAX_PATH];
+
+ /*
+ * Bygg opp fullstendig filnavn
+ */
+ UT_FullPath(szSosFil,fil,_MAX_PATH);
+ UT_splitpath(szSosFil,drive,dir,fname,ext);
+ if (*ext == '\0') UT_StrCopy(ext,".sos",_MAX_EXT);
+ UT_makepath(szSosFil,drive,dir,fname,ext);
+
+ /* Sjekk om filen er i basen fra før */
+ if (LC_GetFiNr(szSosFil) != NULL) return UT_TRUE; /* Er i basen */
+
+ return UT_FALSE; /* Er ikke i basen */
+}
+
+
+
+/*
+AR-940923
+CH LC_ErKoordsysLik Sjekker KOORDSYS
+CD =======================================================================
+CD Formål:
+CD Sjekk at alle filene i basen har samme koordinatsystem.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD short status r Status: UT_TRUE = KOORDSYS er lik.
+CD UT_FALSE = KOORDSYS er IKKE lik.
+CD
+CD Bruk:
+CD ist = LC_ErKoordsysLik();
+ =======================================================================
+*/
+SK_EntPnt_FYBA short LC_ErKoordsysLik(void)
+{
+ short sKoSys = 0;
+ short sFilNr = 0;
+ LC_FILADM *pFil;
+
+ /* Sjekk at alle filene i basen har samme koordinatsystem */
+ LC_InitNextFil(&pFil);
+
+ while (LC_NextFil(&pFil,LC_FRAMGR | LC_BAKGR))
+ {
+ sFilNr++;
+ if (sFilNr == 1)
+ {
+ sKoSys = pFil->TransPar.sKoordsys;
+ }
+
+ else if (pFil->TransPar.sKoordsys != sKoSys)
+ {
+ LC_FILADM *pF;
+
+ // Skriv filnavn og koordinatsystem til loggfilen
+
+ UT_FPRINTF(stderr,"Det er funnet filer med ulikt koordinatsystem:\n");
+
+ LC_InitNextFil(&pF);
+ while (LC_NextFil(&pF,LC_FRAMGR | LC_BAKGR))
+ {
+ UT_FPRINTF(stderr," \"%s\" : %hd\n",pF->pszNavn,pF->TransPar.sKoordsys);
+ }
+ return UT_FALSE;
+ }
+ }
+
+ return UT_TRUE;
+}
+
+
+
+/*
+AR-940923
+CH LC_ErVertdatumLik Sjekker VERT-DATUM
+CD =======================================================================
+CD Formål:
+CD Sjekk at alle filene i basen har samme VERT-DATUM.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD short status r Status: UT_TRUE = VERT-DATUM er lik.
+CD UT_FALSE = VERT-DATUM er IKKE lik.
+CD
+CD Bruk:
+CD ist = LC_ErVertdatumLik();
+ =======================================================================
+*/
+SK_EntPnt_FYBA short LC_ErVertdatumLik(void)
+{
+ char szVertdatHref[7];
+ char szVertdatDref[6];
+ char szVertdatFref[6];
+ char szVertdatHtyp[2];
+
+ bool bForsteFil = true;
+ LC_FILADM *pFil;
+
+ /* Sjekk at alle filene i basen har samme VERT-DATUM */
+ LC_InitNextFil(&pFil);
+
+ while (LC_NextFil(&pFil,LC_FRAMGR | LC_BAKGR))
+ {
+ // Sjekker bare filer med VERT-DATUM gitt i filhodet
+ // (Overser standardverdien)
+ if (strlen(pFil->TransPar.szVertdatHref) > 0)
+ {
+ if ( bForsteFil)
+ {
+ UT_StrCopy(szVertdatHref, pFil->TransPar.szVertdatHref, 7);
+ UT_StrCopy(szVertdatDref, pFil->TransPar.szVertdatDref, 6);
+ UT_StrCopy(szVertdatFref, pFil->TransPar.szVertdatFref, 6);
+ UT_StrCopy(szVertdatHtyp, pFil->TransPar.szVertdatHtyp, 2);
+ bForsteFil = false;
+ }
+
+ else if (UT_StrCmpi(pFil->TransPar.szVertdatHref,szVertdatHref) != 0 ||
+ UT_StrCmpi(pFil->TransPar.szVertdatDref,szVertdatDref) != 0 ||
+ UT_StrCmpi(pFil->TransPar.szVertdatFref,szVertdatFref) != 0 ||
+ UT_StrCmpi(pFil->TransPar.szVertdatHtyp,szVertdatHtyp) != 0 )
+ {
+ LC_FILADM *pF;
+
+ // Skriv filnavn og VERT-DATUM til loggfilen
+
+ UT_FPRINTF(stderr,"Det er funnet filer med ulikt VERT-DATUM:\n");
+
+ LC_InitNextFil(&pF);
+ while (LC_NextFil(&pF,LC_FRAMGR | LC_BAKGR))
+ {
+ UT_FPRINTF(stderr," \"%s\" : \"%s %s %s %s\"\n",
+ pF->pszNavn,
+ pF->TransPar.szVertdatHref,
+ pF->TransPar.szVertdatDref,
+ pF->TransPar.szVertdatFref,
+ pF->TransPar.szVertdatHtyp);
+ }
+ return UT_FALSE;
+ }
+ }
+ }
+
+ return UT_TRUE;
+}
+
+
+/*
+AR:2000-11-30
+CH LC_SetEndringsstatus Setter endringsstatus for aktuell gruppe
+CD ==========================================================================
+CD Formål:
+CD Setter endringsstatus for aktuell gruppe.
+CD
+CD NB! Denne rutinen bør normalt ikke brukes av vanlige klient-program!
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sStatus i Kode for endring:
+CD END_UENDRA 0 Ikke endra
+CD END_KOPI 1 Endra ved totalkopi fra annen gruppe
+CD END_ENDRA 2 Endra ved normal Put fra program
+CD
+CD Bruk:
+CD LC_dg_SetEndringsstatus(END_KOPI);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetEndringsstatus(short sStatus)
+{
+ Sys.sGrEndra = sStatus;
+}
+
+/*
+JAØ:2001-03-06
+CH LC_SetFilType Setter filtype for en sosifil
+CD ==========================================================================
+CD Formål:
+CD Setter filtype for en fil.
+CD
+CD Denne rutinen er primært tenkt brukt i GabEdit hvor det er behov for å
+CD definere flere typer arbeidsfil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til filen
+CD short type i Filtypen som skal settes
+CD LC_FILTYPE_UKJENT
+CD LC_FILTYPE_INAKTIV
+CD LC_FILTYPE_GAB_EIENDOM
+CD LC_FILTYPE_GAB_ADRESSE
+CD LC_FILTYPE_GAB_BYGNING
+CD LC_FILTYPE_BYGG
+CD LC_FILTYPE_DEK
+CD LC_FILTYPE_DEK_ENDRING
+CD LC_FILTYPE_GRUNNKRETS
+CD LC_FILTYPE_POSTKRETS
+CD LC_FILTYPE_SKOLEKRETS
+CD LC_FILTYPE_KIRKESOGN
+CD LC_FILTYPE_TETTSTED
+CD LC_FILTYPE_VALGKRETS
+CD
+CD Bruk:
+CD LC_SetFilType(pFil,type);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetFilType(LC_FILADM *pFil, short sType)
+{
+ LO_TestFilpeker(pFil,"SetFilType");
+ pFil->sFilType = sType;
+}
+
+/*
+JAØ:2001-03-06
+CH LC_GetFilType Henter filtype for en sosifil
+CD ==========================================================================
+CD Formål:
+CD Finner filtypen for en fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til filen
+CD short type r Filtypen som skal settes
+CD LC_FILTYPE_UKJENT
+CD LC_FILTYPE_INAKTIV
+CD LC_FILTYPE_GAB_EIENDOM
+CD LC_FILTYPE_GAB_ADRESSE
+CD LC_FILTYPE_GAB_BYGNING
+CD LC_FILTYPE_BYGG
+CD LC_FILTYPE_DEK
+CD LC_FILTYPE_DEK_ENDRING
+CD LC_FILTYPE_GRUNNKRETS
+CD LC_FILTYPE_POSTKRETS
+CD LC_FILTYPE_SKOLEKRETS
+CD LC_FILTYPE_KIRKESOGN
+CD LC_FILTYPE_TETTSTED
+CD LC_FILTYPE_VALGKRETS
+CD
+CD Bruk:
+CD type = LC_GetFilType(pFil);
+=============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetFilType(LC_FILADM *pFil)
+{
+ LO_TestFilpeker(pFil,"GetFilType");
+ return pFil->sFilType;
+}
+
+
+/*
+AR:2004-05-03
+CH LC_GetIdxPath Hent katalog for ny indeksfil
+CD ==========================================================================
+CD Formål:
+CD Hent katalognavn for ny indeks. For detaljer se under LC_SetIdxPath.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD const char *pszIdxPath r Katalog for indeks
+CD
+CD Bruk:
+CD const char *pszIdxPath = LC_GetIdxPath();
+ ==========================================================================
+*/
+SK_EntPnt_FYBA const char *LC_GetIdxPath(void)
+{
+ return Sys.szIdxPath;
+}
+
+
+/*
+AR:2011-05-31
+CH LC_SetIdxPath Velg katalog for ny indeksfil
+CD ==========================================================================
+CD Formål:
+CD Velg katalognavn for ny indeks. Indeksfilene for en SOSI-fil legges som
+CD en underkatalog under den gitte katalogen. Underkatalogen har samme navn
+CD som SOSI-filen. Hvis det er valgt spesiell plassering av indeksfilene blir
+CD disse alltid slettet når SOSI-filen stenges.
+CD OBS! Ingen SOSI-filer kan være åpne når indekskatalog velges.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD const char *pszIdxPath i Katalog for indeks
+CD "" = Tom streng betyr at indeksfilene legges på en
+CD underkatalog under katalogen der SOSI-filen ligger
+CD (default).
+CD "katalognavn" = Indeksfilene legges på en
+CD underkatalog under denne katalogen.
+CD short status r Status: UT_TRUE = OK
+CD UT_FALSE = Feil, feilmelding er gitt.
+CD
+CD Bruk:
+CD status = LC_SetIdxPath("C:\\kart\\test");
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_SetIdxPath(const char *pszIdxPath)
+{
+ if (LC_InqAntFiler(LC_FRAMGR|LC_BAKGR) == 0)
+ {
+ // Handter TEMP spesielt
+ /*
+ CD "TEMP" = Indeksfilene legges på brukerens temp-katalog.
+ // 2011-05-31: Handtering av "TEMP" er fjernet.
+ if (_strcmpi(pszIdxPath,"TEMP") == 0)
+ {
+ char szBuffer[_MAX_PATH];
+ size_t returnValue;
+ // Hent katalognavn fra environment
+ getenv_s( &returnValue, szBuffer, _MAX_PATH, "TEMP");
+ if(returnValue == 0)
+ {
+ getenv_s( &returnValue, szBuffer, _MAX_PATH, "TMP");
+ }
+ if(returnValue == 0)
+ {
+ Sys.szIdxPath[0] = '\0';
+ return UT_FALSE;
+ }
+ else
+ {
+ UT_StrCopy(Sys.szIdxPath,szBuffer,_MAX_PATH);
+ if (Sys.szIdxPath[strlen(Sys.szIdxPath)-1] != UT_SLASH) UT_StrCat(Sys.szIdxPath,UT_STR_SLASH,_MAX_PATH);
+ }
+ }
+ else
+ */
+ if (*pszIdxPath == '\0')
+ {
+ Sys.szIdxPath[0] = '\0';
+ }
+
+ else
+ {
+ UT_StrCopy(Sys.szIdxPath,pszIdxPath,_MAX_PATH);
+ if (Sys.szIdxPath[strlen(Sys.szIdxPath)-1] != UT_SLASH) UT_StrCat(Sys.szIdxPath,UT_STR_SLASH,_MAX_PATH);
+
+ // Opprett katalogen hvis den ikke finnes fra før
+ UT_CreateDir(Sys.szIdxPath);
+ }
+
+ return UT_TRUE;
+ }
+
+ return UT_FALSE;
+}
diff --git a/src/FYBA/FYLP.cpp b/src/FYBA/FYLP.cpp
new file mode 100644
index 0000000..a5ecf76
--- /dev/null
+++ b/src/FYBA/FYLP.cpp
@@ -0,0 +1,1169 @@
+/* === AR-970929 ========================================================= */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylp.c */
+/* Innhold: Polygonhandtering for FYSAK-PC */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+#include <memory.h>
+#include <limits.h>
+
+
+/* Globale variabler for FYBA */
+extern LC_SYSTEMADM Sys; /* Systemadministrasjon */
+
+
+/*
+AR-970929
+CH LC_POL_LeggTilGruppeOmkrets Legg til eit element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR YtrePolygon;
+CD pElement = LC_POL_LeggTilGruppeOmkrets(YtrePolygon,pBgr,sRetning,lSnr);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR * pPO I/U Peikar til polygonadministrasjonsblokka
+CD LC_BGR * pBgr I Gruppenummer
+CD short sRetning I Nøsteretning (LC_MED_DIG eller LC_MOT_DIG)
+CD long lSnr I Serienummer
+CD LC_POL_ELEMENT * pElement R Peker til innlagt element
+CD
+CD Legg til eit element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA LC_POL_ELEMENT * LC_POL_LeggTilGruppeOmkrets(LC_POL_OMKR *pPO,LC_BGR *pBgr,
+ short sRetning, long lSnr)
+{
+ LC_POL_ELEMENT * pPE;
+ pPE = (LC_POL_ELEMENT *) UT_MALLOC(sizeof(LC_POL_ELEMENT));
+ pPE->pForrigePE = pPO->pSistePE;
+ pPE->pNestePE = NULL;
+
+ if(pPO->pForstePE == NULL) {
+ pPO->pForstePE = pPE;
+
+ } else {
+ pPO->pSistePE->pNestePE = pPE;
+
+ }
+
+ pPO->pSistePE = pPE;
+
+ pPE->Bgr = *pBgr;
+ pPE->sRetning = sRetning;
+ pPE->lSnr = lSnr;
+
+ return pPE;
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FjernSisteGruppeOmkrets Fjernar siste element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR YtrePolygon;
+CD LC_POL_FjernSisteGruppeOmkrets(&YtrePolygon);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR * pPO I/U Peikar til polygonadministrasjonsblokka
+CD
+CD Fjernar siste element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernSisteGruppeOmkrets(LC_POL_OMKR *pPO)
+{
+ LC_POL_ELEMENT *pPE = pPO->pSistePE;
+
+ if (pPE != NULL) {
+ pPO->pSistePE = pPE->pForrigePE;
+ if(pPE->pForrigePE == NULL) {
+ pPO->pForstePE = NULL;
+
+ } else {
+ pPE->pForrigePE->pNestePE = NULL;
+ }
+ UT_FREE(pPE);
+ }
+}
+
+
+/*
+AR-971112
+CH LC_POL_FjernGruppeOmkrets Fjernar element
+CD =======================================================================
+CD Bruk:
+CD LC_POL_OMKR YtrePolygon;
+CD LC_POL_FjernGruppeOmkrets(&YtrePolygon,);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I/U Peikar til polygonadministrasjonsblokka
+CD LC_POL_ELEMENT *pPE I Peker til element som skal fjernes
+CD
+CD Fjernar et element i kjeden av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernGruppeOmkrets(LC_POL_OMKR *pPO, LC_POL_ELEMENT *pPE)
+{
+ /* Oppdaterer pekeren til neste element */
+ if (pPE->pForrigePE != NULL) {
+ /* Inne i kjeden */
+ pPE->pForrigePE->pNestePE = pPE->pNestePE;
+ } else {
+ /* Starten av kjeden */
+ pPO->pForstePE = pPE->pNestePE;
+ }
+
+ /* Oppdaterer pekeren til forrige element */
+ if (pPE->pNestePE != NULL) {
+ /* Inne i kjeden */
+ pPE->pNestePE->pForrigePE = pPE->pForrigePE;
+ } else {
+ /* Slutten av kjeden */
+ pPO->pSistePE = pPE->pForrigePE;
+ }
+ UT_FREE(pPE);
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FrigiAlleOyer Frigjer minne som er allokert til kjede av øyelement
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM OyKjede;
+CD LC_POL_FrigiAlleOyer(OyKjede);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOA I/U Peikar til øyadministrasjonsblokka
+CD
+CD Frigjer minne som er allokert til kjede av øy (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiAlleOyer(LC_OY_ADM *pOA)
+{
+ LC_OY_ELEMENT *pOE,*pNesteOE;
+
+ pOE = pOA->pForsteOE;
+
+ /* Frigir omkretsen av hver øy */
+ while(pOE != NULL) {
+ LC_POL_FrigiOmkrets(&(pOE->PO));
+ pNesteOE = pOE->pNesteOE;
+ UT_FREE(pOE);
+ pOE = pNesteOE;
+ }
+ pOA->pForsteOE = NULL;
+ pOA->pSisteOE = NULL;
+}
+
+
+/*
+SJM-931003
+CH LC_POL_FjernOy Fjernar ei oy frå kjede av øyelement
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM OyKjede;
+CD LC_POL_FjernOy(OyKjede,OyElement);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOA I/U Peikar til øyadministrasjonsblokka
+CD LC_OY_ELEMENT *pOE I/U Peikar til kjede av oyar
+CD
+CD Frigjer minne som er allokert til kjede av øy (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FjernOy(LC_OY_ADM *pOA,LC_OY_ELEMENT *pOE)
+{
+ /* UT_FPRINTF(stderr,"LC_POL_FjernOy: Kallar LC_POL_Frigi()\n"); */
+ LC_POL_FrigiOmkrets(&(pOE->PO));
+
+ /* Frigir øykjeda */
+ if (pOE->pForrigeOE != NULL) {
+ pOE->pForrigeOE->pNesteOE = pOE->pNesteOE;
+ } else {
+ pOA->pForsteOE = pOE->pNesteOE;
+ }
+
+ if (pOE->pNesteOE != NULL) {
+ pOE->pNesteOE->pForrigeOE = pOE->pForrigeOE;
+ } else {
+ pOA->pSisteOE = pOE->pForrigeOE;
+ }
+ UT_FREE(pOE);
+}
+
+
+/*
+SJM-930921
+CH LC_POL_LeggTilOy Legg til eit element
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM OyKjede;
+CD LC_POL_LeggTilOy(&OyKjede,pPO);
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOyKjede I/U Peikar til kjede av øyelement
+CD LC_POL_OMKR *pPO I Peikar til polygonadministrasjonsblokka
+CD
+CD Legg til eit element i kjeden av øyar (i polygon) - element.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_LeggTilOy(LC_OY_ADM *pOA,LC_POL_OMKR *pPO)
+{
+ LC_OY_ELEMENT *pOE;
+ pOE = (LC_OY_ELEMENT *) UT_MALLOC(sizeof(LC_OY_ELEMENT));
+ pOE->pForrigeOE = pOA->pSisteOE;
+ pOE->pNesteOE = NULL;
+ pOE->PO = *pPO;
+
+ if(pOA->pForsteOE == NULL) {
+ pOA->pForsteOE = pOE;
+
+ } else {
+ pOA->pSisteOE->pNesteOE = pOE;
+
+ }
+
+ pOA->pSisteOE = pOE;
+ /* *********************************************
+ UT_FPRINTF(stderr,"LC_POL_LeggTilOy: Aktuell OE %p\n",pOE);
+ UT_FPRINTF(stderr,"LC_POL_LeggTilOy: OA->førsteOE %p\n" ,pOA->pForsteOE);
+ UT_FPRINTF(stderr,"LC_POL_LeggTilOy: SisteOE->nesteOE %p\n",pOA->pSisteOE->pNesteOE);
+ UT_FPRINTF(stderr,"LC_POL_LeggTilOy: SisteOE %p\n",pOA->pSisteOE);
+ ********************************************* */
+}
+
+
+/*
+SJM-930921
+CH LC_POL_FrigiOmkrets Frigjer minne som er allokert til kjede av polygonelement
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I/U Peikar til polygonadministrasjonsblokka
+CD
+CD Frigir minne som er allokert til kjede av polygonelement.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiOmkrets(LC_POL_OMKR *pPO)
+{
+ LC_POL_ELEMENT *pPE,*pNestePE;
+
+ pPE = pPO->pForstePE;
+
+ while(pPE != NULL) {
+ /* UT_FPRINTF(stderr,"LC_POL_FrigiOmkrets: pPE = %p\n",pPE); */
+ pNestePE = pPE->pNestePE;
+ UT_FREE(pPE);
+ pPE = pNestePE;
+ }
+ pPO->pForstePE = NULL;
+ pPO->pSistePE = NULL;
+}
+
+
+/*
+AR-931208
+CH LC_POL_FrigiPolygon Frigi minne som er allokert til polygon
+CD =======================================================================
+CD Formål:
+CD Frigir minne som er allokert til polygon. (Både omkrets og hull.)
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon I Peikar til polygonbeskrivelse
+CD
+CD Bruk:
+CD LC_POLYGON Polygon;
+CD LC_POL_FrigiPolygon(&Polygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_FrigiPolygon(LC_POLYGON *pPolygon)
+{
+ /* Frigir øy-kjeden */
+ LC_POL_FrigiAlleOyer(&(pPolygon->OyOA));
+
+ /* Frigir omkretsen */
+ LC_POL_FrigiOmkrets(&(pPolygon->HovedPO));
+}
+
+
+/*
+SJM-930921
+CH LC_POL_InitOmkrets Initierer polygon-omkrets
+CD =======================================================================
+CD Bruk:
+CD POL_OMKR YtrePolygon;
+CD LC_POL_InitOmkrets(YtrePolygon);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I/U Peikar til polygonadministrasjonsblokka
+CD
+CD Initierer administrasjonsblokka for polygonelement
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitOmkrets(LC_POL_OMKR *pPO)
+{
+ pPO->pForstePE = NULL;
+ pPO->pSistePE = NULL;
+}
+
+
+/*
+SJM-930921
+CH LC_POL_InitOy Initierer øy-kjeden
+CD =======================================================================
+CD Bruk:
+CD LC_OY_ADM OyKjede;
+CD LC_POL_InitOy(OyKjede);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_OY_ADM *pOA I/U Peikar til øyadministrasjonsblokka
+CD
+CD Initierer øy-kjeden.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitOy(LC_OY_ADM *pOA)
+{
+ pOA->pForsteOE = NULL;
+ pOA->pSisteOE = NULL;
+}
+
+
+/*
+AR-931208
+CH LC_POL_InitPolygon Initierer polygon-struktur
+CD =======================================================================
+CD Formål:
+CD Initierer polygon-struktur.
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon I Peikar til polygonbeskrivelse
+CD
+CD Bruk:
+CD LC_POLYGON Polygon;
+CD LC_POL_InitPolygon(&Polygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_InitPolygon(LC_POLYGON *pPolygon)
+{
+ LC_POL_InitOmkrets(&(pPolygon->HovedPO));
+ LC_POL_InitOy(&(pPolygon->OyOA));
+}
+
+
+/*
+AR-931208
+CH LC_POL_PutRef Legger inn referanser i GINFO
+CD =======================================================================
+CD Formål:
+CD Legger inn referanser i GINFO, ut fra beskrivelse i struktur.
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon I Polygonbeskrivelse
+CD short ngi r Antall linjer GINFO
+CD
+CD Bruk:
+CD ngi = LC_POL_PutRef(pPolygon);
+CD =======================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PutRef(LC_POLYGON *pPolygon)
+{
+ #define MAX_LEN 66 /* Ginfolinjen skrives ut når den er lengre en 70 tegn */
+ LC_POL_ELEMENT *pPE;
+ LC_OY_ELEMENT *pOE;
+ short gilin;
+ char temp[LC_MAX_SOSI_LINJE_LEN],*ginfo,*cp;
+ char szOrd[50];
+ short ledig_linje = -1;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ /* Pakker gammel GINFO */
+ for (gilin=2; gilin <= Sys.pGrInfo->ngi; gilin++) {
+ ginfo = LX_GetGi(gilin);
+
+ /* Gammel type referanse er funnet */
+ if (strncmp(ginfo,".. ",3) == 0) {
+ if (ledig_linje == -1) { /* Første linje med referanse */
+ ledig_linje = gilin;
+ }
+
+ /* Ny type referanse er funnet */
+ } else if (strncmp(ginfo,"..REF ",6) == 0) {
+ if (ledig_linje == -1) { /* Første linje med referanse */
+ ledig_linje = gilin;
+ }
+ /* Søk over resten av referansene */
+ for (gilin++; gilin <= Sys.pGrInfo->ngi; gilin++) {
+ ginfo = LX_GetGi(gilin);
+ if (strncmp(ginfo,"..",2) == 0) { /* Annen GINFO er funnet */
+ gilin--;
+ break; /* Avbryt, alle referanser er funnet*/
+ }
+ }
+
+ /* Annen GINFO */
+ } else {
+ if (ledig_linje != -1) {
+ /* Funnet linje som skal flyttes opp */
+ LC_PutGi(ledig_linje,ginfo);
+ ledig_linje++;
+ }
+ }
+
+
+ }
+
+ if (ledig_linje == -1) ledig_linje = Sys.pGrInfo->ngi + 1;
+
+
+ /* Legger inn referanser */
+ if (pPolygon->HovedPO.pForstePE != NULL) {
+ /* Husk at det finnes flate i filen */
+ if ( Sys.GrId.pFil->SosiNiv[1] < 4) {
+ Sys.GrId.pFil->SosiNiv[1] = 4;
+ }
+
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ UT_StrCopy(temp,"..REF ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 6;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+
+ /* Legger ut hovedpolygonet */
+ for (pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+ /* Strengen er full, skriver ut */
+ if(strlen(temp) > MAX_LEN) {
+ if (ledig_linje > Sys.pGrInfo->ngi) {
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ledig_linje ++;
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ *temp = '\0';
+ cp = temp;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+ }
+
+ /* Skriv ut referansen */
+ if (cp > temp) {
+ if (! UT_IsSpace(*(cp-1)) && *(cp-1) != '(') {
+ *cp++ = ' ';
+ *cp = '\0';
+ }
+ }
+ UT_SNPRINTF(szOrd, 50, ":%ld", ((pPE->sRetning == LC_MED_DIG)? pPE->lSnr : -pPE->lSnr));
+ UT_StrCat(temp, szOrd, LC_MAX_SOSI_LINJE_LEN);
+ cp = strchr(temp,'\0');
+ }
+
+
+ /* Legger ut øyer */
+ for (pOE = pPolygon->OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+ /* Strengen er full, skriver ut */
+ if(strlen(temp) >= (MAX_LEN-2)) {
+ if (ledig_linje > Sys.pGrInfo->ngi) {
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ledig_linje ++;
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ *temp = '\0';
+ cp = temp;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+ }
+
+ /* Startparantesen */
+ if (cp > temp) {
+ if (! UT_IsSpace(*(cp-1))) {
+ *cp++ = ' ';
+ }
+ }
+ *cp++ = '(';
+ *cp = '\0';
+
+ /* Legger ut elementa i øyane */
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+ /* Strengen er full, skriver ut */
+ if(strlen(temp) >= MAX_LEN) {
+ if (ledig_linje > Sys.pGrInfo->ngi) {
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ledig_linje ++;
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ *temp = '\0';
+ cp = temp;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+ }
+
+ /* Skriv ut referansen */
+ if (cp > temp) {
+ if (! UT_IsSpace(*(cp-1)) && *(cp-1) != '(') {
+ *cp++ = ' ';
+ *cp = '\0';
+ }
+ }
+ UT_SNPRINTF(szOrd, 50, ":%ld", ((pPE->sRetning == LC_MED_DIG)? pPE->lSnr : -pPE->lSnr));
+ UT_StrCat(temp, szOrd, LC_MAX_SOSI_LINJE_LEN);
+ cp = strchr(temp,'\0');
+ }
+
+
+ /* Sluttparantesen */
+ if (cp > temp) {
+ if (*(cp-1) == '.') {
+ *cp++ = ' ';
+ }
+ }
+ *cp++ = ')';
+ *cp = '\0';
+ }
+
+
+ /* Skriver ut resten av strengen */
+ if ((Sys.GrId.pFil->sSosiVer >= 220 && strlen(temp) > 0) ||
+ strlen(temp) > 3) {
+ if (ledig_linje > Sys.pGrInfo->ngi) {
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ledig_linje ++;
+ }
+
+ } else {
+ Sys.pGrInfo->info &= ~((unsigned short)GI_REF);
+ Sys.pGrInfo->info &= ~((unsigned short)GI_OY_REF);
+ }
+
+ /* Sletter 1. ledige og resten */
+ LC_DelGiL(ledig_linje, (short)(Sys.pGrInfo->ngi - ledig_linje + 1));
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-931212
+CH LC_POL_GetRef Hent referanser for flate fra GINFO
+CD ==========================================================================
+CD Formål:
+CD Henter referanser fra GINFO til struktur.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon I Peker til adm. for polygonbeskrivelse
+CD
+CD
+CD Bruk:
+CD short ngi;
+CD long nko;
+CD unsigned short info;
+CD LC_POLYGON Polygon;
+CD LC_POL_ELEMENT * pPE;
+CD LC_OY_ELEMENT * pOE;
+CD
+CD LC_POL_InitPolygon(&Polygon);
+CD
+CD LC_POL_GetRef(&Polygon);
+CD
+CD . Omkretsen .
+CD for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+CD gnavn = LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD .
+CD Behandle ytre avgrensing
+CD .
+CD }
+CD
+CD . Øyer .
+CD for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+CD for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+CD gnavn = LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD .
+CD Behandle indre avgrensing (øy)
+CD .
+CD }
+CD }
+CD
+CD . Frigi allokerte kjeder .
+CD LC_POL_FrigiPolygon(&Polygon);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_GetRef(LC_POLYGON *pPolygon)
+{
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long lSnr;
+ LC_BGR Bgr;
+ short ngi;
+ long nko;
+ unsigned short info;
+ short sRetning;
+ LC_POL_OMKR OyPO;
+ short sGiLinNr = 2;
+ short sOy = UT_FALSE;
+ LC_BGR AktBgr = Sys.GrId;
+ short sRefLin = UT_FALSE; /* Viser om aktuel linje inneholder referanser */
+
+
+ LC_POL_InitOmkrets(&OyPO);
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ Bgr.pFil = Sys.GrId.pFil;
+
+ /* Finn referanser */
+ while (sGiLinNr <= Sys.pGrInfo->ngi) {
+ gp = LX_GetGi(sGiLinNr);
+
+ /* Handter referanselinjer */
+ if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo;
+ while (*gp) { /* Tolk en linje */
+ if (*gp == ':') { /* Tall */
+ gp++;
+ /* Husk retning */
+ if (*gp == '-') {
+ sRetning = LC_MOT_DIG;
+ gp++;
+ } else {
+ sRetning = LC_MED_DIG;
+ }
+ /* Hent serienummer og konverter til gruppenummer */
+ if (isdigit(*gp)) {
+ lSnr = strtol(gp,&gp,10);
+ /* Konverter til gruppenummer */
+ if ((Bgr.lNr = LI_GetSnr(Sys.GrId.pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Legg gruppen inn i kjeden */
+ if (sOy == UT_TRUE) {
+ /* Referanse til flate, pakk ut denne */
+ if (LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info) == L_FLATE) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ LC_POL_GetRefOmkrets(&OyPO);
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ } else {
+ LC_POL_LeggTilGruppeOmkrets(&OyPO,&Bgr,sRetning,lSnr);
+ }
+
+ } else {
+ LC_POL_LeggTilGruppeOmkrets(&(pPolygon->HovedPO),
+ &Bgr,sRetning,lSnr);
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",lSnr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else {
+ //UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ //Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ gp++;
+ }
+
+
+ } else if (*gp == '(') { /* Start øy */
+
+ if (sOy == UT_FALSE) {
+ LC_POL_InitOmkrets(&OyPO);
+ sOy = UT_TRUE;
+
+ } else {
+ /* Øy i øy er ikke lovlig */
+ LC_Error(56,"(LC_POL_GetRef)",Sys.GrId.pFil->pszNavn);
+ UT_FPRINTF(stderr,"Øy i øy i gruppe \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+ gp++;
+
+ } else if (*gp == ')') { /* Slutt øy */
+
+ if (sOy == UT_TRUE) {
+ LC_POL_LeggTilOy(&(pPolygon->OyOA),&OyPO);
+ sOy = UT_FALSE;
+
+ } else {
+ /* Øy i øy er ikke lovlig */
+ LC_Error(56,"(LC_POL_GetRef)",Sys.GrId.pFil->pszNavn);
+ UT_FPRINTF(stderr,"Øy i øy i gruppe \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+ gp++;
+
+ } else { /* Ukjent tegn */
+ gp++;
+ }
+ }
+ }
+
+ sGiLinNr++;
+ }
+ }
+
+ return;
+}
+
+
+/*
+AR-931212
+CH LC_POL_GetRefOmkrets Hent referanser for omkretsen av flate
+CD ==========================================================================
+CD Formål:
+CD Henter referanser fra GINFO til struktur.
+CD Rutinen initierer strukturen pPO, men frigir ikke eventuellt gammelt innhold.
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -------------------------------------------------------------------------
+CD LC_POL_OMKR *pPO; IU Peker til kjede som beskriver omkretsen.
+CD
+CD Bruk:
+CD LC_POL_GetRefOmkrets(&OyPO);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_GetRefOmkrets(LC_POL_OMKR *pPO)
+{
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long lSnr;
+ short sRetning;
+ short sGiLinNr = 2;
+ short sFerdig = UT_FALSE;
+ LC_BGR Bgr = Sys.GrId;
+ short sRefLin = UT_FALSE; /* Viser om aktuel linje inneholder referanser */
+
+
+ LC_POL_InitOmkrets(pPO);
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE && Sys.pGrInfo->ngi > 0) {
+ /* Finn referanser */
+ while (sFerdig == UT_FALSE && sGiLinNr <= Sys.pGrInfo->ngi) {
+ gp = LX_GetGi(sGiLinNr);
+
+ /* Handter referanselinjer */
+ if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo;
+ while (sFerdig == UT_FALSE && *gp) { /* Tolk en linje */
+ if (*gp == ':') { /* Tall */
+ gp++;
+ /* Husk retning */
+ if (*gp == '-') {
+ sRetning = LC_MOT_DIG;
+ gp++;
+ } else {
+ sRetning = LC_MED_DIG;
+ }
+ /* Hent serienummer og konverter til gruppenummer */
+ if (isdigit(*gp)) {
+ lSnr = strtol(gp,&gp,10);
+ /* Konverter til gruppenummer */
+ if ((Bgr.lNr = LI_GetSnr(Sys.GrId.pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Legg gruppen inn i kjeden */
+ LC_POL_LeggTilGruppeOmkrets(pPO,&Bgr,sRetning,lSnr);
+
+ } else {
+ UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",lSnr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ /* Start øy */
+ } else if (*gp == '(') {
+ sFerdig = UT_TRUE;
+ gp++;
+
+ } else { /* Ukjent tegn */
+ gp++;
+ }
+ }
+ }
+
+ sGiLinNr++;
+ }
+ }
+}
+
+
+/*
+SJM-930928
+CH LC_POL_TestBrukt Testar om ei gruppe er brukt i polygonet
+CD =======================================================================
+CD Bruk:
+CD LC_POL_TestBrukt(pPolygon,&Bgr);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POLYGON *pPolygon I Peker til polygonbeskrivelse.
+CD LC_BGR *pBgr I Peikar til gruppe
+CD short status R Status UT_TRUE = gruppe er brukt i polygonet
+CD Status UT_FALSE = gruppe er IKKJE brukt i polygonet
+CD
+CD Testar om ei gruppe er brukt i gitt polygon.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_TestBrukt(LC_POLYGON *pPolygon,LC_BGR *pBgr)
+{
+ LC_POL_ELEMENT *pPE;
+ LC_OY_ELEMENT *pOE;
+
+ /* Sjekk omkretsen */
+ for(pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ if (memcmp(pBgr,&pPE->Bgr, sizeof(LC_BGR)) == 0) {
+ return UT_TRUE;
+ }
+ }
+
+ /* Sjekk øyene */
+ for (pOE = pPolygon->OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ if (memcmp(pBgr,&pPE->Bgr, sizeof(LC_BGR)) == 0) {
+ return UT_TRUE;
+ }
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR:2009-03-04
+CH LC_POL_PTst Polygontest
+CD ==========================================================================
+CD Formål:
+CD Sjekker om gitt punkt ligger innenfor polygon angitt av pPolygon.
+CD Forutsetter at pPolygon danner et lukket polygon.
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short ist r status: UT_FALSE = punktet er utenfor flaten
+CD UT_TRUE = punktet ligger inne på flaten
+CD
+CD Bruk:
+CD .
+==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PTst(LC_POLYGON *pPolygon,double a,double n)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_POL_ELEMENT * pPE;
+ LC_OY_ELEMENT * pOE;
+ short sAntSkjaer;
+ LC_BGR Flate = Sys.GrId; /* Husk gruppenummer for flaten */
+ short inni = UT_FALSE; /* Returverdi: 1 = inne på flaten, 0 = utenfor */
+
+
+ // Har ytre avgrensning?
+ if (pPolygon == NULL || pPolygon->HovedPO.pForstePE == NULL) return inni; // ==> Avbryter, har ikke noen ytre avgrensning
+
+
+ double dEnhet = pPolygon->HovedPO.pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+ // Pluss på et lite tillegg for å unngå treff på node
+ a += dEnhet / 1000.0;
+ n += dEnhet / 1000.0;
+
+ // Inndata
+ if (pPolygon) {
+ // ----- Behandle ytre avgrensing (Omkretsen)
+ sAntSkjaer = 0;
+ for(pPE = pPolygon->HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+ }
+ // Sjekk om punktet er innenfor
+ inni = ((sAntSkjaer % 2) == 1)? 1 : 0;
+
+ // ----- Behandler indre avgrensing (øy)
+ for (pOE = pPolygon->OyOA.pForsteOE; inni && (pOE != NULL); pOE = pOE->pNesteOE) {
+ // Behandler en øy
+ sAntSkjaer = 0;
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+ }
+ // Sjekk om punktet er inni øya
+ inni = ((sAntSkjaer % 2) == 1)? UT_FALSE : UT_TRUE;
+ }
+
+ // Les inn flaten igjen
+ LC_RxGr(&Flate,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return inni;
+}
+
+
+/*
+AR-931213
+CH LC_POL_PTstOmkrets Sjekk om punkt ligger inni polygonomkrets
+CD ==========================================================================
+CD Formål:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av struktur.
+CD Forutsetter at tabellen danner et lukket polygon
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I/U Peker til beskrivelse av omkretsen
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short ist r status: UT_FALSE = punktet er utenfor flaten
+CD UT_TRUE = punktet ligger inne på flaten
+CD
+CD Bruk:
+CD ist = LC_POL_PTstOmkrets(pPO,a,n);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_PTstOmkrets(LC_POL_OMKR *pPO,double a,double n)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_POL_ELEMENT *pPE;
+ short sAntSkjaer = 0;
+ LC_BGR AktBgr = Sys.GrId; /* Husk gruppenummer for aktuell gruppe */
+
+
+ // Har ytre avgrensning?
+ if (pPO == NULL || pPO->pForstePE == NULL) return UT_FALSE; // ==> Avbryter, har ikke noen ytre avgrensning
+
+
+ double dEnhet = pPO->pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+ // Pluss på et lite tillegg for å unngå treff på node
+ a += dEnhet / 1000.0;
+ n += dEnhet / 1000.0;
+
+ /*
+ * Sjekk omkretsen ved å beregne antall skjæringer mellom omkretsen
+ * og en linje fra "test-punktet" til "uendelig øst".
+ */
+
+ for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ /* Beregn skjæringer med denne gruppen */
+ sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+ }
+
+ /* Les inn opprinnelig gruppe igjen */
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ /*
+ * Sjekk om punktet er innenfor omkretsen.
+ * (Inni hvis antall skjæringspunkt er oddetall.)
+ */
+ return ((sAntSkjaer % 2) == 1)? UT_TRUE : UT_FALSE;
+}
+
+
+/*
+JAØ-20061130
+CH LC_POL_OmkretsSkjaering Finner antall skjæringer med polygonomkrets
+CD ==========================================================================
+CD Formål:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av struktur. Egentlig kopi av LC_POL_PTstOmkrets, men returnerer antall
+CD skjæringer istedet for inni/utenfor.
+CD Forutsetter at tabellen danner et lukket polygon
+CD Skifter ikke aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I/U Peker til beskrivelse av omkretsen
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short ist r Antall skjæringer med omkrets fra pkt til "uendelig" øst
+CD
+CD Bruk:
+CD ist = LC_POL_PTstOmkrets(pPO,a,n);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_POL_OmkretsSkjaering(LC_POL_OMKR *pPO,double a,double n)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_POL_ELEMENT *pPE;
+ short sAntSkjaer = 0;
+ LC_BGR AktBgr = Sys.GrId; /* Husk gruppenummer for aktuell gruppe */
+
+
+ // Har ytre avgrensning?
+ if (pPO == NULL || pPO->pForstePE == NULL) return 0; // ==> Avbryter, har ikke noen ytre avgrensning
+
+
+ double dEnhet = pPO->pForstePE->Bgr.pFil->TransPar.dEnhet;
+
+ // Pluss på et lite tillegg for å unngå treff på node
+ a += dEnhet / 1000.0;
+ n += dEnhet / 1000.0;
+
+ /*
+ * Sjekk omkretsen ved å beregne antall skjæringer mellom omkretsen
+ * og en linje fra "test-punktet" til "uendelig øst".
+ */
+
+ for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ /* Beregn skjæringer med denne gruppen */
+ sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+ }
+
+ /* Les inn opprinnelig gruppe igjen */
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ return sAntSkjaer;
+}
+
+
+/*
+AR-950421
+CH LC_POL_Box Henter omskreven boks
+CD =======================================================================
+CD Bruk:
+CD LC_POL_Box(pPA,&nva,&nvn,&oha,&ohn);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_POL_OMKR *pPO I Peikar til polygonadministrasjonsblokka
+CD double *nva U
+CD double *nvn U
+CD double *oha U
+CD double *ohn U
+CD
+CD Henter omskriven boks for polygon.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_POL_Box(LC_POL_OMKR *pPO,double *nva,double *nvn, double *oha,double*ohn)
+{
+ LC_POL_ELEMENT *pPE;
+ double na,nn,oa,on;
+ /* Omskreven boks */
+ double mina = (double)LONG_MAX;
+ double minn = (double)LONG_MAX;
+ double maxa = (double)LONG_MIN;
+ double maxn = (double)LONG_MIN;
+
+ for (pPE = pPO->pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+
+ if (LC_GetGrWin(&pPE->Bgr,&na,&nn,&oa,&on) ) {
+ if (na < mina) mina = na;
+ if (nn < minn) minn = nn;
+ if (oa > maxa) maxa = oa;
+ if (on > maxn) maxn = on;
+ }
+ }
+
+ *nva = mina;
+ *nvn = minn;
+ *oha = maxa;
+ *ohn = maxn;
+}
+
+
+/*
+AR-950421
+CH LC_ErLinjeRefLin Sjekk om linje inneholder referanser
+CD =======================================================================
+CD Bruk:
+CD sRefLin = LC_ErLinjeRefLin(gp,sRefLin);
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD char *pszGinfoLin i Peikar til GINFO-linje
+CD short sRefLin i Flagg som viser om forrige linje inneholdt referanser
+CD short sRefLin r Flagg som viser om aktuell linje inneholdt referanser
+CD
+CD Sjekk om linje er linje med referanser.
+CD =======================================================================
+*/
+short LC_ErLinjeRefLin(char *pszSosiLin, short sRefLin)
+{
+ /* Sjekk om dette er referanselinje */
+ if (strncmp(pszSosiLin,".. ",3) == 0) {
+ return UT_TRUE;
+
+ } else if (strncmp(pszSosiLin,"..REF ",6) == 0) {
+ //if (sRefLin == UT_TRUE) {
+ // UT_FPRINTF(stderr,"Ulovlig SOSI-syntaks \"%s\" i gruppe \"%s : %s\"\n",pszSosiLin,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ // Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ //}
+ return UT_TRUE;
+
+ } else if (sRefLin == UT_TRUE) {
+ /* Annet SOSI-navn */
+ if (*pszSosiLin == '.') {
+ return UT_FALSE;
+
+ } else {
+ return UT_TRUE;
+ }
+
+ } else {
+ return UT_FALSE;
+ }
+}
diff --git a/src/FYBA/FYLR.cpp b/src/FYBA/FYLR.cpp
new file mode 100644
index 0000000..a56879e
--- /dev/null
+++ b/src/FYBA/FYLR.cpp
@@ -0,0 +1,2240 @@
+/* === 911001 ============================================================ */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylr.c */
+/* Ansvarlig: Andreas Røstad */
+/* Innhold: Rutiner for geografisk søking mm. i fysak-pc */
+/* ======================================================================= */
+
+#include "stdafx.h"
+
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+#include <memory.h>
+
+
+/* Globale variabler */
+extern LC_SYSTEMADM Sys;
+
+/* --- Lokale rutiner */
+static LC_R_LEAF * LR_R_Insert(long lGrNr,LC_BOKS * pB,LC_R_NODE * pFar,LC_R_NODE * pRN,LC_R_NODE * *ppNyRN);
+static LC_R_NODE * LR_R_CreateRNode( LC_R_NODE * pFar,short sSonType);
+static LC_R_LEAF * LR_R_CreateRLeaf(long lGrNr, LC_BOKS * pB,LC_R_NODE * pFar);
+static void LR_R_BoksSum(LC_BOKS * pB1,LC_BOKS * pB2);
+static double LR_BoksDeltaArealSum(LC_BOKS * pB1,LC_BOKS * pB2);
+static void LR_LeggTilKB(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,long lNr);
+static short LR_R_BoksTestIntersect(LC_BOKS * pB1,LC_BOKS * pB2);
+static void LR_R_SjekkNode(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN);
+static void LR_R_SjekkNodeFlate(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN);
+static void LR_VelgMetode(LC_GEO_STATUS * pGeoStat);
+
+//#ifdef TEST
+//#include <string.h>
+//static void LR_R_DumpNode(LC_R_NODE * pRN, int iNivo);
+static void LR_R_DumpLov(LC_R_LEAF * pRL, LC_FILADM *pDumpFil, int iNivo, double dA, double dN,long *plAntBarn);
+static void LR_R_DumpNode(LC_R_NODE * pRN, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, double dLengde,long *plAntBarn);
+//#endif
+
+
+
+
+#define MAX_REF 25
+
+
+/*
+AR:2000-07-25
+CH LC_GetGrWin Hent omskrevet rektangel for gruppe
+CD ==========================================================================
+CD Formål:
+CD Henter omskrevet rektangel for gitt gruppe.
+CD For flater er refererte grupper medregnet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr i Gruppenummer
+CD double *nva u Omskrevet rektangel for gruppen. Avrundet utover
+CD double *nvn u en enhet.
+CD double *oha u
+CD double *ohn u
+CD short ist r Status. UT_TRUE=OK, UT_FALSE=ulovlig gruppenummer.
+CD
+CD Bruk:
+CD ist = LC_GetGrWin(&Bgr,&nva,&nvn,&oha,&ohn);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetGrWin(LC_BGR * pBgr,double *nva,double *nvn,double *oha,double *ohn)
+{
+ LC_R_LEAF * pRL;
+
+ /* LO_TestFilpeker(pBgr->pFil,"LC_GetGrWin"); */
+ LO_TestFilpeker(pBgr->pFil,"GetGrWin");
+
+ /* Lovlig gruppe */
+ if (pBgr->lNr >= 0L && pBgr->lNr < pBgr->pFil->lAntGr) {
+ pRL = LI_GetGeo(pBgr->pFil,pBgr->lNr);
+
+ if (pRL != NULL) {
+ *nva = pRL->Boks.dMinAust;
+ *nvn = pRL->Boks.dMinNord;
+ *oha = pRL->Boks.dMaxAust;
+ *ohn = pRL->Boks.dMaxNord;
+
+ } else {
+ *nva = *nvn = (double)LONG_MAX;
+ *oha = *ohn = (double)LONG_MIN;
+ }
+
+ return UT_TRUE; /* ======> */
+ }
+
+ /* Ulovlig gruppe */
+ LC_Error(36,"(LC_GetGrWin)","");
+ return UT_FALSE;
+}
+
+
+/*
+AR-930608
+CH LR_Indx Beregn geografiske ruter for gruppe
+CD ==========================================================================
+CD Formål:
+CD Beregner og lagrer omskrevet boks for koordinatene på aktuell gruppe.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LR_Indx();
+ ==========================================================================
+*/
+void LR_Indx(void)
+{
+ short sfeil;
+ long pt;
+ double min_n,min_a,max_n,max_a;
+ double radius,aust,nord,fi,dfi;
+ LC_BOKS Boks;
+
+ // UT_FPRINTF(stderr,"Indeks for: %s\n",LX_GetGi(1));
+
+ /* Bygg ny indeks */
+ if (Sys.pGrInfo->nko > 0) {
+
+ /* Nullstill omskreven boks */
+ min_a = min_n = (double)LONG_MAX;
+ max_a = max_n = (double)LONG_MIN;
+
+ /* Handterer "bue" */
+ if (Sys.pGrInfo->gnavn == L_BUE || Sys.pGrInfo->gnavn == L_BUEP ||
+ Sys.pGrInfo->gnavn == L_SIRKEL || Sys.pGrInfo->gnavn == L_SIRKELP) {
+
+ if (LC_GetBuePar(HENT_FORRFRA,&aust,&nord,&radius,&fi,&dfi,&sfeil)) {
+ /* Beregner omskrevet rektangel for "buen" */
+ GM_buebox(aust,nord,radius,fi,dfi,&min_a,&min_n,&max_a,&max_n);
+
+ } else {
+ if (Sys.pGrInfo->gnavn == L_BUE) {
+ /* Ulovlig bue-angivelse */
+ //LC_Error(130,"(LR_Indx)",LX_GetGi(1));
+ UT_FPRINTF(stderr,"Ulovlig forhold mellom koordinater og radius i: %s : %s\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ }
+
+ // Spesialhandtering av ulogiske sirkler og buer. Håndteres som KURVE
+ for (pt=0; pt<Sys.pGrInfo->nko; pt++) {
+ min_a = min(min_a,*(Sys.pdAust + pt));
+ min_n = min(min_n,*(Sys.pdNord + pt));
+ max_a = max(max_a,*(Sys.pdAust + pt));
+ max_n = max(max_n,*(Sys.pdNord + pt));
+ }
+ }
+
+ /* Andre grupper enn "bue" */
+ } else {
+ /* Omskreven firkant */
+ for (pt=0; pt<Sys.pGrInfo->nko; pt++) {
+ min_a = min(min_a,*(Sys.pdAust + pt));
+ min_n = min(min_n,*(Sys.pdNord + pt));
+ max_a = max(max_a,*(Sys.pdAust + pt));
+ max_n = max(max_n,*(Sys.pdNord + pt));
+ }
+ }
+
+ /* Beregn omskreven boks */
+ /* Nedre venstre justeres ut en enhet */
+ Boks.dMinAust = min_a - Sys.pGrInfo->dEnhet;
+ Boks.dMinNord = min_n - Sys.pGrInfo->dEnhet;
+ /* Øvre høyre justeres ut en enhet */
+ Boks.dMaxAust = max_a + Sys.pGrInfo->dEnhet;
+ Boks.dMaxNord = max_n + Sys.pGrInfo->dEnhet;
+
+ // Finnes ikke i treet fra før
+ if (Sys.pGrInfo->pRL == NULL ) {
+ /* Lagre omskrevet boks i søketreet */
+ Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+
+ // Sjekk om boksen avviker fra gammel boks
+ } else if (memcmp(&(Sys.pGrInfo->pRL->Boks),&Boks,sizeof(LC_BOKS)) != 0) {
+
+ /* Fjern eventuell gammel forekomst i R-treet */
+ LR_R_Delete(Sys.pGrInfo->pRL);
+
+ /* Lagre omskreven firkant i søketreet */
+ Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+ }
+
+ } else if (Sys.pGrInfo->pRL != NULL) {
+ /* Fjern eventuell gammel forekomst i R-treet */
+ LR_R_Delete(Sys.pGrInfo->pRL);
+ Sys.pGrInfo->pRL = NULL;
+ }
+}
+
+
+// ==========================================================================
+SK_EntPnt_FYBA void LC_DumpGeoRtre(LC_FILADM *pFil)
+{
+ short ostat;
+ LC_FILADM *pDumpFil;
+ long lAntBarn = 0;
+
+ // Åpner ny SOSI-fil for dump
+ HO_New("Indeksdump.sos", 99, 0.0, 0.0, 0.001, 0.001, 0.001,
+ -151000, -151000, 151000, 1000);
+ if (LC_OpenSos("Indeksdump.sos",LC_BASE_FRAMGR,LC_NY_IDX,LC_INGEN_STATUS,&pDumpFil,&ostat))
+ {
+ short sUtvidModus = LC_GetUtvidModus();
+ long lMaxSkriv = LC_InqMaxSkriv();
+ LC_SetUtvidModus(LC_UTVID_RASK);
+ LC_MaxSkriv(100000000L);
+
+ if (pFil->pGeoRN != NULL)
+ {
+ LR_R_DumpNode(pFil->pGeoRN,pDumpFil,0, 0.0, 0.0, 100000.0,&lAntBarn);
+ }
+
+ LC_MaxSkriv(lMaxSkriv);
+ LC_Save();
+ LC_SetUtvidModus(sUtvidModus);
+
+ LC_CloseSos(pDumpFil,SAVE_IDX);
+ }
+}
+
+
+// ==========================================================================
+static void LR_R_DumpNode(LC_R_NODE * pRN, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, double dLengde,long *plAntBarn)
+{
+ LC_BGR Bgr;
+ char szTx[100];
+ int i;
+ long lSnr;
+ double dDeltaN;
+ long lBarn = 0;
+
+ iNivo++;
+ /* Rekursiv sjekk av de underliggende løv eller nodene */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ LC_NyGr(pDumpFil,".LINJE",&Bgr,&lSnr);
+ LC_PutGi(LC_AppGiL(), "..LTEMA 1000");
+ LC_PutTK(LC_AppKoL(), dA, dN);
+ dDeltaN = dLengde;
+
+ if (i == 0) {
+ LC_PutTK(LC_AppKoL(), dA-dLengde, dN-dDeltaN);
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ if (pRN->sSonType == LC_LEAF) {
+ LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA-dLengde, dN-dDeltaN, &lBarn);
+ } else {
+ LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA-dLengde, dN-dDeltaN, dLengde / 3.1, &lBarn);
+ }
+
+ } else if (i == 1) {
+ LC_PutTK(LC_AppKoL(), dA, dN-dDeltaN);
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ if (pRN->sSonType == LC_LEAF) {
+ LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA, dN-dDeltaN, &lBarn);
+ } else {
+ LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA, dN-dDeltaN, dLengde / 3.1, &lBarn);
+ }
+
+ } else {
+ LC_PutTK(LC_AppKoL(), dA+dLengde, dN-dDeltaN);
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ if (pRN->sSonType == LC_LEAF) {
+ LR_R_DumpLov(pRN->Son.pLeaf[i], pDumpFil, iNivo, dA+dLengde, dN-dDeltaN, &lBarn);
+ } else {
+ LR_R_DumpNode(pRN->Son.pNode[i], pDumpFil, iNivo, dA+dLengde, dN-dDeltaN, dLengde / 3.1, &lBarn);
+ }
+ }
+ }
+
+ // Skriv ut noden
+ LC_NyGr(pDumpFil,".PUNKT",&Bgr,&lSnr);
+ LC_PutGi(LC_AppGiL(), "..PTEMA 3000");
+ LC_PutGi(LC_AppGiL(), "..NODE 1");
+
+ UT_SNPRINTF(szTx,100,"..NIVÅ %d", iNivo-1);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..MIN-NØ %f %f", pRN->Boks.dMinNord, pRN->Boks.dMinAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..MAX-NØ %f %lf", pRN->Boks.dMaxNord, pRN->Boks.dMaxAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..DELTA-NØ %f %f",
+ pRN->Boks.dMaxNord - pRN->Boks.dMinNord,
+ pRN->Boks.dMaxAust - pRN->Boks.dMinAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..BARN %ld",lBarn);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ LC_PutTK(LC_AppKoL(), dA, dN);
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ (*plAntBarn) += lBarn;
+
+}
+
+
+// ==========================================================================
+static void LR_R_DumpLov(LC_R_LEAF * pRL, LC_FILADM *pDumpFil, int iNivo, double dA, double dN, long *plAntBarn)
+{
+ LC_BGR Bgr;
+ char szTx[100];
+ long lSnr;
+
+
+ (*plAntBarn)++;
+ // Skriv ut løvet
+ LC_NyGr(pDumpFil,".PUNKT",&Bgr,&lSnr);
+ LC_PutGi(LC_AppGiL(), "..PTEMA 5000");
+ LC_PutGi(LC_AppGiL(), "..LØV 1");
+
+ UT_SNPRINTF(szTx,100,"..NR %ld", pRL->lNr);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..NIVÅ %d", iNivo);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..MIN-NØ %f %f", pRL->Boks.dMinNord, pRL->Boks.dMinAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..MAX-NØ %f %f", pRL->Boks.dMaxNord, pRL->Boks.dMaxAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ UT_SNPRINTF(szTx,100,"..DELTA-NØ %f %f",
+ pRL->Boks.dMaxNord - pRL->Boks.dMinNord,
+ pRL->Boks.dMaxAust - pRL->Boks.dMinAust);
+ LC_PutGi(LC_AppGiL(), szTx);
+
+ LC_PutTK(LC_AppKoL(), dA, dN);
+ LC_WxGr(SKRIV_OPTIMALT);
+}
+
+
+/*
+AR-900214
+CH LR_IndxFlate Beregn geografisk indeks for flate
+CD =============================================================================
+CD Formål:
+CD Utvider omskrevet boks for aktuell gruppe, slik at den tar hensyn til
+CD referanser.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LR_IndxFlate();
+ =============================================================================
+*/
+void LR_IndxFlate(void)
+{
+ long ref_arr[MAX_REF];
+ unsigned char ref_status[MAX_REF];
+ long ant_ref;
+ short s,ngi;
+ long nko;
+ unsigned short info;
+ double min_n,min_a,max_n,max_a;
+ LC_R_LEAF * pRL;
+ LC_FILADM *pFi = Sys.GrId.pFil;
+ LC_GRF_STATUS GrfStat;
+ LC_BOKS Boks;
+ short sRefBrukt = UT_FALSE;
+
+
+ LC_GetGrPara(&ngi,&nko,&info);
+
+ /* Sjekk om gruppen har referanser */
+ if ((info & GI_REF) != 0 || nko >0) {
+
+ /* Nullstill omskreven boks */
+ min_a = min_n = (double)LONG_MAX;
+ max_a = max_n = (double)LONG_MIN;
+
+ /* Koordinater direkte på denne gruppen */
+ if (nko > 0) {
+ pRL = LI_GetGeo(pFi,Sys.GrId.lNr);
+ if (pRL != NULL) {
+ min_a = pRL->Boks.dMinAust;
+ min_n = pRL->Boks.dMinNord;
+ max_a = pRL->Boks.dMaxAust;
+ max_n = pRL->Boks.dMaxNord;
+
+ } else {
+ /* Initier med inverse område fra filhodet */
+ min_a = Sys.GrId.pFil->Omraade.dMaxAust;
+ min_n = Sys.GrId.pFil->Omraade.dMaxNord;
+ max_a = Sys.GrId.pFil->Omraade.dMinAust;
+ max_n = Sys.GrId.pFil->Omraade.dMinNord;
+ }
+
+ } else {
+ /* Initier med inverse område fra filhodet */
+ min_a = Sys.GrId.pFil->Omraade.dMaxAust;
+ min_n = Sys.GrId.pFil->Omraade.dMaxNord;
+ max_a = Sys.GrId.pFil->Omraade.dMinAust;
+ max_n = Sys.GrId.pFil->Omraade.dMinNord;
+ }
+
+ LC_InitGetRefFlate(&GrfStat);
+ /*
+ * Bygger opp omskreven firkant for gruppen ut fra omskreven
+ * firkant for gruppene som inngår.
+ * (Behandle bare ytre avgrensing.)
+ */
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+ do {
+ for (s=0; s<ant_ref; s++) {
+ pRL = LI_GetGeo(pFi,ref_arr[s]);
+ if (pRL != NULL) {
+ min_a = min(min_a, pRL->Boks.dMinAust);
+ min_n = min(min_n, pRL->Boks.dMinNord);
+ max_a = max(max_a, pRL->Boks.dMaxAust);
+ max_n = max(max_n, pRL->Boks.dMaxNord);
+ }
+ }
+
+ if (ant_ref > 0) sRefBrukt = UT_TRUE;
+
+ if (ant_ref < MAX_REF) break;
+
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+ } while (ant_ref > 0);
+
+ /* Lagre omskreven firkant i søketreet */
+ Boks.dMinAust = min_a;
+ Boks.dMinNord = min_n;
+ Boks.dMaxAust = max_a;
+ Boks.dMaxNord = max_n;
+
+ /* Fjern eventuell representasjonspunktet fra R-treet */
+ if (Sys.pGrInfo->pRL != NULL) LR_R_Delete(Sys.pGrInfo->pRL);
+
+ /* Legger inn hele flaten */
+ Sys.pGrInfo->pRL = LR_InsertGeo(Sys.GrId.pFil,Sys.GrId.lNr,&Boks);
+ }
+
+ /* Husk om referanser er brukt */
+ if (sRefBrukt == UT_TRUE) {
+ LI_SetBt(pFi,Sys.GrId.lNr,BT_REFBOX);
+ } else {
+ LI_ClrBt(pFi,Sys.GrId.lNr,BT_REFBOX);
+ }
+}
+
+/*
+AR-911003
+CH LC_SBGeo Sett søkegrense for grov geografisk søk
+CD =============================================================================
+CD Formål:
+CD Definerer geografisk område for geografisk søk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus.
+CD unsigned short usLag i Velg hvilke "lag" det skal søkes i.
+CD LC_FRAMGR og /eller LC_BAKGR
+CD double nv_a i Koordinat nedre venstre hjørne.
+CD double nv_n i
+CD double oh_a i Koordinat øvre høyre hjørne.
+CD double oh_n i
+CD
+CD Bruk:
+CD LC_GEO_STATUS GeoStat;
+CD .
+CD LC_SBGeo(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFGeo(&GeoStat,&Bgr)) {
+CD do{
+CD . Behandle funnet gruppe
+CD .
+CD } while (LC_FNGeo(&GeoStat,&bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBGeo(LC_GEO_STATUS * pGeoStat,unsigned short usLag,
+ double nv_a,double nv_n,double oh_a,double oh_n)
+{
+ /* Normaliserer vinduet */
+ GM_NormVindu(&nv_a,&nv_n,&oh_a,&oh_n);
+
+ /* Avrunder ut til nærmeste meter utover */
+ /* Nedre venstre ut til nærneste heltall under */
+ //pGeoStat->nvn = (long)floor(nv_n);
+ //pGeoStat->nva = (long)floor(nv_a);
+ /* Øvre høyre ut til nærneste heltall over */
+ //pGeoStat->ohn = (long)ceil(oh_n);
+ //pGeoStat->oha = (long)ceil(oh_a);
+
+ pGeoStat->nvn = nv_n;
+ pGeoStat->nva = nv_a;
+ pGeoStat->ohn = oh_n;
+ pGeoStat->oha = oh_a;
+
+ /* Husk lag */
+ pGeoStat->usLag = usLag;
+
+ /* Nullstiller resultatpekerne */
+ pGeoStat->pForsteKB = NULL;
+ pGeoStat->pSisteKB = NULL;
+ pGeoStat->pAktuellKB = NULL;
+
+ /* Velg søkemetode */
+ LR_VelgMetode(pGeoStat);
+}
+
+
+/*
+AR-911003
+CH LC_FFGeo Finn første ved geografisk søk
+CD ==========================================================================
+CD Formål:
+CD Finner første gruppe i det definerte området for kombinert geografisk søk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FFGeo(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ LC_BOKS Boks;
+ LC_FILADM *pFil;
+
+ /* Beregn søkeboksen */
+ Boks.dMinAust = pGeoStat->nva;
+ Boks.dMinNord = pGeoStat->nvn;
+ Boks.dMaxAust = pGeoStat->oha;
+ Boks.dMaxNord = pGeoStat->ohn;
+
+ /* Frigir eventuell gammel resultatkjede */
+ LC_AvsluttSok(pGeoStat);
+
+ /* Sjekker alle filer */
+ LC_InitNextFil(&pFil);
+ while (LC_NextFil(&pFil,pGeoStat->usLag)) {
+ /* Filen inneholder data, må sjekke alle berørte noder */
+ if (pFil->pGeoRN != NULL) {
+ LR_R_SjekkNode(pGeoStat,&Boks,pFil,pFil->pGeoRN);
+ }
+ }
+
+ pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_BGR Bgr;
+ LC_R_LEAF * pRL;
+
+ LC_InitNextBgr(&Bgr);
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LR_R_SjekkNode Sjekker node om overlappende boks
+CD ==========================================================================
+CD Formål:
+CD Sjekker en node og underliggende noder om de har lagret bokser
+CD som overlapper søkerektanglet. De gruppene som blir funnet blir hengt på
+CD kjeden med søkeresultat i pGeoStat.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat i Peker til struktur for søkestatus
+CD LC_BOKS * pB i Søkeboks
+CD LC_FILADM * pFil i Filpeker
+CD LC_R_NODE * pRN i Peker til node som skal sjekkes
+CD
+CD Bruk:
+CD LR_R_SjekkNode(pGeoStat,pB,pFil,pRN->pSon[i]);
+ ==========================================================================
+*/
+static void LR_R_SjekkNode(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN)
+{
+ int i;
+
+
+ /* Sjekk om denne noden berører søkeboksen */
+ if (LR_R_BoksTestIntersect(&(pRN->Boks),pB)) {
+
+ /* Har kommet til ytterste nivå */
+ if (pRN->sSonType == LC_LEAF) {
+
+ /* Sjekk de gruppene som er lagret under denne noden */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ if (LR_R_BoksTestIntersect(&(pRN->Son.pLeaf[i]->Boks),pB)) {
+ LR_LeggTilKB(pGeoStat,pFil,pRN->Son.pLeaf[i]->lNr);
+ }
+ }
+
+ /* Node */
+ } else {
+
+ /* Rekursiv sjekk av de underliggende nodene */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ LR_R_SjekkNode(pGeoStat,pB,pFil,pRN->Son.pNode[i]);
+ }
+ }
+ }
+}
+
+
+/*
+AR-911003
+CH LR_R_BoksTestIntersect Sjekker om to bokser "berører" hverandre
+CD ==========================================================================
+CD Formål:
+CD Sjekker om to bokser "berører" hverandre.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BOKS * pB1 i Rektangel 1
+CD LC_BOKS * pB2 i Rektangel 2
+CD short sStatus r UT_TRUE=Berører, UT_FALSE=Ikke berøring
+CD
+CD Bruk:
+CD LR_R_BoksTestIntersect(...);
+ ==========================================================================
+*/
+static short LR_R_BoksTestIntersect(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+ if (pB1->dMaxNord >= pB2->dMinNord &&
+ pB1->dMaxAust >= pB2->dMinAust &&
+ pB1->dMinNord <= pB2->dMaxNord &&
+ pB1->dMinAust <= pB2->dMaxAust ) {
+
+ /* Tilslag */
+ return UT_TRUE;
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FNGeo Finn neste ved geografisk søk
+CD ==========================================================================
+CD Formål:
+CD Finner neste gruppe i det definerte området for geografisk søk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNGeo(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ /* Søket er utført og ligger som en kjede */
+ if (pGeoStat->pAktuellKB != NULL) {
+ pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_R_LEAF * pRL;
+ LC_BGR Bgr = pGeoStat->Bgr;
+
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FFGeoFil Finn første ved geografisk søk i en fil
+CD ==========================================================================
+CD Formål:
+CD Finner første gruppe i det definerte området for kombinert geografisk søk.
+CD Søker bare i en gitt fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_FILADM * pOnsketFil i Filpeker til den filen det skal søkes i.
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FFGeoFil(LC_GEO_STATUS * pGeoStat,LC_FILADM *pOnsketFil,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ LC_BOKS Boks;
+
+ /* Beregn søkeboksen */
+ Boks.dMinAust = pGeoStat->nva;
+ Boks.dMinNord = pGeoStat->nvn;
+ Boks.dMaxAust = pGeoStat->oha;
+ Boks.dMaxNord = pGeoStat->ohn;
+
+ /* Frigir eventuell gammel resultatkjede */
+ LC_AvsluttSok(pGeoStat);
+
+ /* Sjekker den aktuelle filen */
+ if (pOnsketFil->usLag & pGeoStat->usLag) {
+ /* File inneholder data, må sjekke alle berørte noder */
+ if (pOnsketFil->pGeoRN != NULL) {
+ LR_R_SjekkNode(pGeoStat,&Boks,pOnsketFil,pOnsketFil->pGeoRN);
+ }
+ }
+
+ pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_BGR Bgr;
+ LC_R_LEAF * pRL;
+
+ LC_InitNextBgr(&Bgr);
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+ /* Rett fil? */
+ if (Bgr.pFil == pOnsketFil) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-911003
+CH LC_FNGeoFil Finn neste ved geografisk søk i en fil
+CD ==========================================================================
+CD Formål:
+CD Finner neste gruppe i det definerte området for geografisk søk.
+CD Søker bare i en gitt fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_FILADM * pFil i Filpeker til den filen det skal søkes i.
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBGeo.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNGeoFil(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ if (pGeoStat->pAktuellKB != NULL) {
+ pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_R_LEAF * pRL;
+ LC_BGR Bgr = pGeoStat->Bgr;
+
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+
+ if (Bgr.pFil == pFil) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-911002
+CH LC_FAGeo Finn alle ved geografisk søk
+CD ==========================================================================
+CD Formål:
+CD Finn alle i geografisk søkeområde.
+CD Tilslag merkes i brukttabellen kolonne BT_GEOSOK (15).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD long lAntall r Antall funnet.
+CD
+CD Bruk:
+CD .
+CD LC_SBGeo(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD antall = LC_FAGeo(&Bgr);
+CD .
+ =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGeo(LC_GEO_STATUS * pGeoStat)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR AktBgr,Bgr;
+ long lAntall = 0;
+
+
+ /* Husk aktuell gruppe */
+ AktBgr = Sys.GrId;
+
+ /* Blanker brukttabellen */
+ LI_EraseBt(BT_GEOSOK,BT_GEOSOK);
+
+ /* Utfører søket */
+ if (LC_FFGeo(pGeoStat,&Bgr)) {
+ do {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ lAntall += LC_MerkGr(BT_GEOSOK,1); /* Tilslag */
+ } while (LC_FNGeo(pGeoStat,&Bgr));
+ }
+ LC_AvsluttSok(pGeoStat);
+
+ /* Les tilbake aktuell gruppe */
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return lAntall;
+}
+
+
+/*
+AR-911003
+CH LC_SBFlate Sett søkegrense for geografisk søk på flate
+CD =============================================================================
+CD Formål:
+CD Definerer punkt for geografisk søk på flate.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD unsigned short usLag i Velg hvilke "lag" det skal søkes i.
+CD LC_FRAMGR og /eller LC_BAKGR
+CD double nv_a i Koordinat nedre venstre hjørne
+CD double nv_n i
+CD double oh_a i Koordinat øvre høyre hjørne
+CD double oh_n i
+CD
+CD Bruk:
+CD LC_GEO_STATUS GeoStat;
+CD .
+CD LC_SBFlate(&GeoStat,LC_FRAMGR | LC_BAKGR,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFFlate(&GeoStat,&Bgr)) {
+CD do{
+CD . Behandle funnet gruppe
+CD .
+CD } while (LC_FNFlate(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBFlate(LC_GEO_STATUS * pGeoStat,unsigned short usLag,
+ double nv_a,double nv_n,double oh_a,double oh_n)
+{
+ /* Normaliserer vinduet */
+ GM_NormVindu(&nv_a,&nv_n,&oh_a,&oh_n);
+
+ /* Avrunder ut til nærmeste meter utover */
+ /* Nedre venstre ut til nærneste heltall under */
+ pGeoStat->nvn = (long)floor(nv_n);
+ pGeoStat->nva = (long)floor(nv_a);
+ /* Øvre høyre ut til nærneste heltall over */
+ pGeoStat->ohn = (long)ceil(oh_n);
+ pGeoStat->oha = (long)ceil(oh_a);
+
+ /* Husk lag */
+ pGeoStat->usLag = usLag;
+
+ /* Nullstiller resultatpekerne */
+ pGeoStat->pForsteKB = NULL;
+ pGeoStat->pSisteKB = NULL;
+ pGeoStat->pAktuellKB = NULL;
+
+ /* Velg søkemetode */
+ LR_VelgMetode(pGeoStat);
+}
+
+
+/*
+AR-911003
+CH LC_FFFlate Finn første ved flatesøk
+CD =============================================================================
+CD Formål:
+CD Finner første gruppe i det definerte området for flatesøk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBFlate.
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_FFFlate(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ LC_BOKS Boks;
+ LC_FILADM *pFil;
+
+ /* Beregn søkeboksen */
+ Boks.dMinAust = pGeoStat->nva;
+ Boks.dMinNord = pGeoStat->nvn;
+ Boks.dMaxAust = pGeoStat->oha;
+ Boks.dMaxNord = pGeoStat->ohn;
+
+ /* Frigir eventuell gammel resultatkjede */
+ LC_AvsluttSok(pGeoStat);
+
+ /* Sjekker alle filer */
+ LC_InitNextFil(&pFil);
+ while (LC_NextFil(&pFil,pGeoStat->usLag)) {
+
+ /* File inneholder data, må sjekke alle berørte kvadranter */
+ if (pFil->pGeoRN != NULL) {
+ LR_R_SjekkNodeFlate(pGeoStat,&Boks,pFil,pFil->pGeoRN);
+ }
+ }
+
+ pGeoStat->pAktuellKB = pGeoStat->pForsteKB;
+
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_BGR Bgr;
+ LC_R_LEAF * pRL;
+
+ LC_InitNextBgr(&Bgr);
+
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+ if (LI_InqBt(Bgr.pFil,Bgr.lNr,BT_REFBOX)) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-980205
+CH LR_R_SjekkNodeFlate Sjekker node om overlappende boks (flate)
+CD ==========================================================================
+CD Formål:
+CD Sjekker en node og underliggende noder om de har lagret bokser
+CD som overlapper søkerektanglet. De gruppene som blir funnet blir hengt på
+CD kjeden med søkeresultat i pGeoStat. Finner bare grupper der det er brukt
+CD referanser for oppbygging av geografisk boks.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat i Peker til struktur for søkestatus
+CD LC_BOKS * pB i Søkeboks
+CD LC_FILADM * pFil i Filpeker
+CD LC_R_NODE * pRN i Peker til node som skal sjekkes
+CD
+CD Bruk:
+CD LR_R_SjekkNodeFlate(pGeoStat,pB,pFil,pRN->pSon[i]);
+ ==========================================================================
+*/
+static void LR_R_SjekkNodeFlate(LC_GEO_STATUS * pGeoStat,LC_BOKS * pB,LC_FILADM *pFil,LC_R_NODE * pRN)
+{
+ int i;
+
+
+ /* Sjekk om denne noden berører søkeboksen */
+ if (LR_R_BoksTestIntersect(&(pRN->Boks),pB)) {
+
+ /* Har kommet til ytterste nivå */
+ if (pRN->sSonType == LC_LEAF) {
+
+ /* Sjekk de gruppene som er lagret under denne noden */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ if (LR_R_BoksTestIntersect(&(pRN->Son.pLeaf[i]->Boks),pB)) {
+ /* Huskes bare hvis det er brukt referanser */
+ if (LI_InqBt(pFil,pRN->Son.pLeaf[i]->lNr,BT_REFBOX)) {
+ LR_LeggTilKB(pGeoStat,pFil,pRN->Son.pLeaf[i]->lNr);
+ }
+ }
+ }
+
+ /* Node */
+ } else {
+
+ /* Rekursiv sjekk av de underliggende nodene */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ LR_R_SjekkNodeFlate(pGeoStat,pB,pFil,pRN->Son.pNode[i]);
+ }
+ }
+ }
+}
+
+
+/*
+AR-911002
+CH LC_FNFlate Finn neste ved flatesøk
+CD ==========================================================================
+CD Formål:
+CD Finner neste gruppe i det definerte området for flatesøk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD LC_BGR * pBgr u Funnet gruppe
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD Se under LC_SBFlate.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_FNFlate(LC_GEO_STATUS * pGeoStat,LC_BGR * pBgr)
+{
+ /* Bruker R-tre */
+ if (pGeoStat->usMetode == LC_GEO_RTRE) {
+ if (pGeoStat->pAktuellKB != NULL) {
+ pGeoStat->pAktuellKB = pGeoStat->pAktuellKB->pNesteKB;
+ if (pGeoStat->pAktuellKB != NULL) {
+ /* Tilslag */
+ *pBgr = pGeoStat->pAktuellKB->Bgr;
+ return UT_TRUE;
+ }
+ }
+
+ /* Sekvensiell gjennomgang av alle grupper */
+ } else {
+ LC_R_LEAF * pRL;
+ LC_BGR Bgr = pGeoStat->Bgr;
+
+ while (LC_NextBgr(&Bgr,pGeoStat->usLag)) {
+ if (LI_InqBt(Bgr.pFil,Bgr.lNr,BT_REFBOX)) {
+ pRL = LI_GetGeo(Bgr.pFil,Bgr.lNr);
+ if (pRL != NULL) {
+ /* Sjekk område-tabellen */
+ if (pGeoStat->ohn >= pRL->Boks.dMinNord && pGeoStat->oha >= pRL->Boks.dMinAust &&
+ pGeoStat->nvn <= pRL->Boks.dMaxNord && pGeoStat->nva <= pRL->Boks.dMaxAust) {
+ *pBgr = pGeoStat->Bgr = Bgr; /* Tilslag */
+ return UT_TRUE;
+ }
+ }
+ }
+ }
+
+ /* Ikke tilslag */
+ pGeoStat->Bgr = Bgr;
+ }
+
+ /* Ikke tilslag */
+ return UT_FALSE;
+}
+
+
+/*
+AR-890824
+CH LC_WTst Vindustest
+CD ==========================================================================
+CD Formål:
+CD Sjekk om aktuell gruppe berører gitt vindu.
+CD Tar hensyn til gruppenavnet. Handterer (PUNKT, LINJE, KURVE, BUE,
+CD BUEP, SIRKEL, SIRKELP, SVERM, TRASE ).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double nva i Avgrensing av vinduet
+CD double nvn i
+CD double oha i
+CD double ohn i
+CD short ist r status: 0 = ikke berøring
+CD 1 = skjæring
+CD
+CD Bruk:
+CD .
+CD LC_SBGeo(&GeoStat,nv_a,nv_n,oh_a,oh_n);
+CD if (LC_FFGeo(&GeoStat,&Bgr)){
+CD do{
+CD LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD if (LC_WTst(nv_a,nv_n,oh_a,oh_n)) { (Nøyaktig vindustest)
+CD . Behandle funnet gruppe
+CD .
+CD }
+CD } while (LC_FNGeo(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_WTst(double nva,double nvn,double oha,double ohn)
+{
+ short ngi,gruppenavn,sfeil;
+ long nko,pt;
+ unsigned short info;
+ double radius,aust,nord,fi,dfi;
+ double *pdAust = Sys.pdAust;
+ double *pdNord = Sys.pdNord;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Har aktuell gruppe */
+ gruppenavn = LC_GetGrPara(&ngi,&nko,&info);
+ if (nko > 0){ /* Har koordinater */
+
+ /* .BUE, .BUEP, .SIRKEL eller .SIRKELP */
+ if (gruppenavn == L_BUE || gruppenavn == L_BUEP ||
+ gruppenavn == L_SIRKEL || gruppenavn == L_SIRKELP) {
+
+ if (LC_GetBuePar(HENT_FORRFRA,&aust,&nord,&radius,&fi,&dfi,&sfeil)) {
+ /* Vindustest på buen */
+ if (GM_wtstBue(aust,nord,radius,fi,dfi,nva,nvn,oha,ohn)) {
+ return(1);
+ }
+
+ } else {
+ // Spesialhandtering av ulogiske sirkler og buer
+ // Handteres som punkt/linje
+ // Sjekk første koordinat
+ if (GM_wtst(*pdAust,*pdNord,*pdAust,*pdNord,nva,nvn,oha,ohn)) {
+ return(1);
+ }
+
+ // Sjekk resten av gruppen
+ ++pdAust;
+ ++pdNord;
+ for (pt=1; pt<Sys.pGrInfo->nko; ++pt,++pdAust,++pdNord) {
+ if (GM_wtst(*(pdAust-1),*(pdNord-1),*pdAust,*pdNord,
+ nva,nvn,oha,ohn)) {
+ return(1);
+ }
+ }
+ }
+
+ /* .PUNKT eller .SVERM */
+ } else if (gruppenavn == L_PUNKT || gruppenavn == L_SVERM) {
+ /* Sjekk om noe punkt er innenfor */
+ for (pt=1; pt<=Sys.pGrInfo->nko; ++pt) {
+ LC_GetTK(pt,&aust,&nord);
+ if (aust >= nva && aust <= oha &&
+ nord >= nvn && nord <= ohn ) {
+ return(1);
+ }
+ }
+
+ /* .TRASE */
+ } else if (gruppenavn == L_TRASE) {
+
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_POLYGON Polygon;
+ LC_POL_ELEMENT * pPE;
+ LC_BGR BgrTrase = Sys.GrId; /* Husk gruppenummer for traseen */
+
+
+ /* Initier referansehandtering, og les beskrivelsen */
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ /* Behandle referansene */
+ for (pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (LC_WTst(nva,nvn,oha,ohn)) { /* (Nøyaktig vindustest) */
+ /* Frigi allokerte kjeder */
+ LC_POL_FrigiPolygon(&Polygon);
+
+ /* Les inn traseen igjen */
+ LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+
+ return (1);
+ }
+ }
+
+ /* Frigi allokerte kjeder */
+ LC_POL_FrigiPolygon(&Polygon);
+
+ /* Les inn traseen igjen */
+ LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+
+
+ /* Andre gruppenavn */
+ } else {
+ /* Sjekk første koordinat */
+ if (GM_wtst(*pdAust,*pdNord,*pdAust,*pdNord,nva,nvn,oha,ohn)) {
+ return(1);
+ }
+
+ /* Sjekk resten av gruppen */
+ ++pdAust;
+ ++pdNord;
+ for (pt=1; pt<Sys.pGrInfo->nko; ++pt,++pdAust,++pdNord) {
+ if (GM_wtst(*(pdAust-1),*(pdNord-1),*pdAust,*pdNord,
+ nva,nvn,oha,ohn)) {
+ return(1);
+ }
+ }
+ }
+ }
+ }
+ return (0);
+}
+
+
+/*
+AR-890824
+CH LC_PTst Polygontest
+CD ==========================================================================
+CD Formål:
+CD Sjekker om gitt punkt ligger innenfor polygon angitt av aktuell gruppe.
+CD Forutsetter at tabellen danner et lukket polygon
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short ist r status: 0 = punktet er utenfor flaten
+CD 1 = punktet ligger inne på flaten
+CD
+CD Bruk:
+CD .
+CD LC_SBFlate(&GeoStat,a-d,n-d,a+d,n+d);
+CD if (LC_FFFlate(&GeoStat,&Bgr)) {
+CD do{
+CD LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+CD if (LC_PTst(a,n)){ (Nøyaktig polygontest)
+CD . Behandle funnet gruppe
+CD .
+CD }
+CD } while (LC_FNFlate(&GeoStat,&Bgr));
+CD }
+CD LC_AvsluttSok(&GeoStat);
+CD .
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PTst(double a,double n)
+{
+ LC_POLYGON Polygon;
+ short inni = 0; /* Returverdi: 1 = inne på flaten, 0 = utenfor */
+
+ // Sjekk om gruppen er flate
+ if (Sys.pGrInfo->gnavn == L_FLATE)
+ {
+ // Initier flatehandtering, og les flatebeskrivelsen
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ // Utfør selve polygontesten
+ inni = LC_POL_PTst(&Polygon,a,n);
+
+ // Frigi allokerte kjeder
+ LC_POL_FrigiPolygon(&Polygon);
+ }
+
+ return inni;
+}
+
+
+/*
+AR-911002
+CH LC_PTstOmkrets Sjekk om punkt ligger inni polygon
+CD ==========================================================================
+CD Formål:
+CD Sjekker om gitt punkt ligger innenfor yttergrensen for polygon angitt
+CD av aktuell gruppe.
+CD Forutsetter at tabellen danner et lukket polygon
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short ist r status: 0 = punktet er utenfor flaten
+CD 1 = punktet ligger inne på flaten
+CD
+CD Bruk:
+CD ist = LC_PTstOmkrets(a,n);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PTstOmkrets(double a,double n)
+{
+ long ref_arr[MAX_REF];
+ unsigned char ref_status[MAX_REF];
+ long ant_ref;
+ short ngi,s;
+ long nko;
+ unsigned short info;
+ LC_GRF_STATUS GrfStat;
+ LC_BGR Bgr;
+ short sAntSkjaer = 0;
+ LC_BGR Flate = Sys.GrId; /* Husk gruppenummer for flaten */
+
+ Bgr.pFil = Flate.pFil;
+
+ double dEnhet = Sys.pGrInfo->dEnhet;
+
+ // Pluss på et lite tillegg for å unngå treff på node
+ a += dEnhet / 1000.0;
+ n += dEnhet / 1000.0;
+
+ /* Sjekk om gruppen er flate */
+ if (LC_GetGrPara(&ngi,&nko,&info) == L_FLATE){
+
+ LC_InitGetRefFlate(&GrfStat);
+
+ /* Behandle ytre avgrensing */
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+ do {
+ for (s=0; s<ant_ref; s++) {
+ Bgr.lNr = ref_arr[s];
+ sAntSkjaer += LR_PTstGruppe(&Bgr,a,n);
+ }
+ /* Les inn flaten igjen */
+ LC_RxGr(&Flate,LES_OPTIMALT,&ngi,&nko,&info);
+
+ if (ant_ref < MAX_REF) break;
+
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+ } while (ant_ref > 0);
+ }
+
+ /* Sjekk om punktet er innenfor */
+ return ((sAntSkjaer % 2) == 1)? 1 : 0;
+}
+
+
+/*
+AR-921028
+CH LR_PTstGruppe Sjekk om punkt ligger inni polygon
+CD ==========================================================================
+CD Formål:
+CD Sjekker antall skjæringer mellom gitt gruppe og linje fra gitt punkt
+CD til "uendelig" øst.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr i Peker til datagruppe
+CD double a i Punkt som skal sjekkes
+CD double n i
+CD short sAntSkjaer r Antall skjæringer
+CD
+CD Bruk:
+CD ist = LR_PTstOmkrets(&Bgr,a,n);
+ ==========================================================================
+*/
+short LR_PTstGruppe(LC_BGR * pBgr,double a,double n)
+{
+ double maxa = 99999999999.0; /* "Uendelig" øst */
+ short ngi,gruppenavn,sfeil;
+ long pt,nko;
+ unsigned short info;
+ #define ARR_LEN 50
+ long punkt, antall;
+ double a1,n1,a2,n2,radius,as,ns,fi,dfi;
+ double n_arr[ARR_LEN],a_arr[ARR_LEN];
+ LC_POLYGON Polygon;
+ LC_POL_ELEMENT * pPE;
+ LC_BGR BgrTrase;
+ short sAntSkjaer = 0;
+
+
+ /* Sjekk gruppen */
+ gruppenavn = LC_RxGr(pBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (nko > 0) {
+
+ /* .TRASE */
+ if (gruppenavn == L_TRASE) {
+ BgrTrase = Sys.GrId; /* Husk gruppenummer for traseen */
+
+ /* Initier referansehandtering, og les beskrivelsen */
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ /* Behandle referansene */
+ for (pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ sAntSkjaer += LR_PTstGruppe(&pPE->Bgr,a,n);
+ }
+
+ /* Frigi allokerte kjeder, og les inn traseen igjen */
+ LC_POL_FrigiPolygon(&Polygon);
+ LC_RxGr(&BgrTrase,LES_OPTIMALT,&ngi,&nko,&info);
+
+ /* "bue" */
+ } else if (gruppenavn == L_BUE || gruppenavn == L_BUEP ||
+ gruppenavn == L_SIRKEL || gruppenavn == L_SIRKELP) {
+
+ if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&radius,&fi,&dfi,&sfeil)) {
+ sAntSkjaer += GM_sLinBue(as,ns,radius,fi,dfi,
+ a,n,maxa,n,&a1,&n1,&a2,&n2);
+ }
+
+ /* Annen gruppe */
+ } else {
+ punkt = 1;
+ do { /* Finn skjæringspunkter */
+ LC_GetArrayTK(HENT_FORRFRA,ARR_LEN,punkt,a_arr,n_arr,&antall);/* Henter */
+ if (antall > 0) {
+ for (pt=1; pt<antall; pt++) {
+ sAntSkjaer += GM_shor(a_arr[pt-1],n_arr[pt-1],
+ a_arr[pt],n_arr[pt],a,n,maxa,n,&a1,&n1);
+ }
+ punkt += (antall-1);
+ }
+ } while (punkt < nko);
+ }
+ }
+
+ return sAntSkjaer;
+}
+
+
+/*
+AR-980108
+CH LR_InsertGeo Legg gruppen inn i geografisk indeks
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_FILADM * pFil i Filpeker
+CD long lNr i Gruppenummer i filen
+CD LC_BOKS * pB i Boks som skal legges inn i treet
+CD LC_R_LEAF * pRL r Peker inn i geografisk søketre
+CD
+CD Formål:
+CD Legg gruppen inn i geografisk indeks.
+CD Forutsetter at grupen ikke ligger i søketreet fra før.
+CD =======================================================================
+*/
+LC_R_LEAF * LR_InsertGeo(LC_FILADM *pFil,long lNr,LC_BOKS * pB)
+{
+ LC_R_NODE * pNyRN,*pRotRN;
+ LC_R_LEAF * pRL;
+
+
+ /* Lagre omskrevet boks i søketreet */
+ pRL = LR_R_Insert(lNr,pB,NULL,pFil->pGeoRN,&pNyRN);
+
+ /* Hvis rot-noden er splittet må det lages ny rot-node */
+ if (pNyRN != NULL) {
+ if (pFil->pGeoRN != NULL) {
+ /* Lag ny rot-node */
+ pRotRN = LR_R_CreateRNode(NULL,LC_NODE);
+ pRotRN->Son.pNode[0] = pFil->pGeoRN;
+ pRotRN->Son.pNode[1] = pNyRN;
+ pRotRN->sSonAnt = 2;
+
+ /* Oppdater boks */
+ pRotRN->Boks = pFil->pGeoRN->Boks;
+ LR_R_BoksSum(&(pRotRN->Boks),&(pNyRN->Boks));
+
+ /* Oppdater far i sønnene */
+ pFil->pGeoRN->pFar = pRotRN;
+ pNyRN->pFar = pRotRN;
+
+ pFil->pGeoRN = pRotRN;
+
+ } else {
+ pFil->pGeoRN = pNyRN;
+ }
+ }
+
+ return pRL;
+}
+
+
+/*
+AR-980108
+CH LR_R_Insert Insert i R-tre
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD long lGrNr i Gruppenummer i filen
+CD LC_BOKS *pB i Boks som skal legges inn i treet
+CD LC_R_NODE *pFar i Peker til far i quad-treet
+CD LC_R_NODE *pRN i Peker til node i R-treet
+CD LC_R_NODE **ppNyRN u Peker til peker til nyopprettet node i R-treet
+CD LC_R_LEAF *pRL r Peker til forekomst i R-treet
+CD
+CD Formål:
+CD Leger inn et rektangl i R-treet med rot i node pRN.
+CD Hvis pRN == NULL (Tomt tre) settes *ppNyRN til å peke til et nyt tre.
+CD =======================================================================
+*/
+static LC_R_LEAF * LR_R_Insert(long lGrNr,LC_BOKS *pB,LC_R_NODE *pFar,LC_R_NODE *pRN,LC_R_NODE **ppNyRN)
+{
+ LC_R_NODE *pNyRN,*pKandidatRN[LC_R_MAX_SON+1];
+ LC_R_LEAF *pRL,*pKandidatRL[LC_R_MAX_SON+1];
+ int i,iIdxMin=0,iIdxMax=0;
+ double dDeltaAreal,dMinDeltaAreal;
+ double dMinAust,dMaxAust;
+
+ // Test
+ //static int iNivo;
+ //iNivo++;
+ //UT_FPRINTF(stderr,"LR_R_Insert nivå :%d\n",iNivo);
+
+
+ *ppNyRN = NULL;
+
+
+ /* Treet er tomt, må allokere ny node */
+ if (pRN == NULL) {
+ *ppNyRN = pRN = LR_R_CreateRNode(NULL,LC_LEAF);
+ }
+
+ /* Har kommet til ytterste nivå */
+ if (pRN->sSonType == LC_LEAF) {
+
+ pRL = LR_R_CreateRLeaf(lGrNr,pB,pRN);
+
+ /* Hvis ledig plass */
+ if (pRN->sSonAnt < LC_R_MAX_SON) {
+ /* Legg inn rektanglet */
+ pRN->Son.pLeaf[pRN->sSonAnt] = pRL;
+ (pRN->sSonAnt)++;
+
+ /* Oppdaterer omskrevet boks */
+ LR_R_BoksSum(&(pRN->Boks),pB);
+
+ /* Fullt, må opprett ny node */
+ } else {
+ *ppNyRN = pNyRN = LR_R_CreateRNode(pRN->pFar,LC_LEAF);
+
+ /* Fordel boksene på de to nodene etter lineær kost algoritmen */
+
+ /* Beregn "ekstrem-bokser" */
+ dMinAust = LONG_MAX;
+ dMaxAust = LONG_MIN;
+
+ iIdxMax = 0;
+ for (i=0; i<pRN->sSonAnt; i++) {
+ pKandidatRL[i] = pRN->Son.pLeaf[i];
+ if (pKandidatRL[i]->Boks.dMinAust > dMaxAust) {
+ dMaxAust = pKandidatRL[i]->Boks.dMinAust;
+ iIdxMax = i;
+ }
+ }
+ pKandidatRL[LC_R_MAX_SON] = pRL;
+ if (pB->dMinAust > dMaxAust) {
+ dMaxAust = pB->dMinAust;
+ iIdxMax = LC_R_MAX_SON;
+ }
+
+ for (i=0; i<pRN->sSonAnt; i++) {
+ if (iIdxMax != i) {
+ if (pKandidatRL[i]->Boks.dMaxAust < dMinAust) {
+ dMinAust = pKandidatRL[i]->Boks.dMaxAust;
+ iIdxMin = i;
+ }
+ }
+ }
+ if (iIdxMax != LC_R_MAX_SON && pB->dMaxAust < dMinAust) {
+ dMinAust = pB->dMaxAust;
+ iIdxMin = LC_R_MAX_SON;
+ }
+
+ /* Plasser ut ekstremboksene */
+ pRN->Son.pLeaf[0] = pKandidatRL[iIdxMax];
+ pRN->sSonAnt = 1;
+ pRN->Boks = pKandidatRL[iIdxMax]->Boks;
+ pKandidatRL[iIdxMax]->pFar = pRN;
+ pKandidatRL[iIdxMax] = NULL;
+
+ pNyRN->Son.pLeaf[0] = pKandidatRL[iIdxMin];
+ pNyRN->sSonAnt = 1;
+ pNyRN->Boks = pKandidatRL[iIdxMin]->Boks;
+ pKandidatRL[iIdxMin]->pFar = pNyRN;
+ pKandidatRL[iIdxMin] = NULL;
+
+ /* Resten av boksene plasseres der de fører til minst utvielse av boksen */
+ for (i=0; i<=LC_R_MAX_SON; i++) {
+ if (pKandidatRL[i] != NULL) {
+
+ if (LR_BoksDeltaArealSum(&(pRN->Boks),&(pKandidatRL[i]->Boks)) <
+ LR_BoksDeltaArealSum(&(pNyRN->Boks),&(pKandidatRL[i]->Boks)) ) {
+
+ pRN->Son.pLeaf[pRN->sSonAnt] = pKandidatRL[i];
+ pRN->sSonAnt++;
+ LR_R_BoksSum(&(pRN->Boks),&(pKandidatRL[i]->Boks));
+ pKandidatRL[i]->pFar = pRN;
+
+ } else {
+ pNyRN->Son.pLeaf[pNyRN->sSonAnt] = pKandidatRL[i];
+ pNyRN->sSonAnt++;
+ LR_R_BoksSum(&(pNyRN->Boks),&(pKandidatRL[i]->Boks));
+ pKandidatRL[i]->pFar = pNyRN;
+ }
+ }
+ }
+ }
+
+ /* Node */
+ } else {
+ /* velg den noden som utvides minst ved tillegg av den nye boksen */
+ dMinDeltaAreal = LONG_MAX;
+ iIdxMin = 0;
+ for (i=0; i<pRN->sSonAnt; i++) {
+ /* Beregn hvor mye boksen ville ha blitt utvidet hvis denne ble valget */
+ dDeltaAreal = LR_BoksDeltaArealSum(&(pRN->Son.pNode[i]->Boks),pB);
+ if (dDeltaAreal < dMinDeltaAreal) {
+
+ dMinDeltaAreal = dDeltaAreal;
+ iIdxMin = i;
+ }
+ }
+
+ /* Legger inn rektanglet i den noden med minst utvdelse */
+ pRL = LR_R_Insert(lGrNr,pB,pRN,pRN->Son.pNode[iIdxMin],ppNyRN);
+
+ /* Denne noden har blitt splittet, dette må tas vare på her */
+ if (*ppNyRN != NULL) {
+
+ /* Hvis ledig plass */
+ if (pRN->sSonAnt < LC_R_MAX_SON) {
+ /* Legg inn rektanglet */
+ pRN->Son.pNode[pRN->sSonAnt] = *ppNyRN;
+ (pRN->sSonAnt)++;
+
+ /* Oppdaterer omskrevet boks */
+ LR_R_BoksSum(&(pRN->Boks),pB);
+
+ /* Ingen splitting på nivået over */
+ *ppNyRN = NULL;
+
+ /* Fullt, må opprett ny node */
+ } else {
+ pNyRN = LR_R_CreateRNode(pFar,LC_NODE);
+
+ /* Fordel boksene på de to nodene etter lineær kost algoritmen */
+
+ /* Beregn "ekstrem-bokser" */
+ dMinAust = LONG_MAX;
+ dMaxAust = LONG_MIN;
+
+ for (i=0; i<pRN->sSonAnt; i++) {
+ pKandidatRN[i] = pRN->Son.pNode[i];
+ if (pKandidatRN[i]->Boks.dMinAust > dMaxAust) {
+ dMaxAust = pKandidatRN[i]->Boks.dMinAust;
+ iIdxMax = i;
+ }
+ }
+ pKandidatRN[LC_R_MAX_SON] = *ppNyRN;
+ if (pKandidatRN[i]->Boks.dMinAust > dMaxAust) {
+ dMaxAust = pKandidatRN[i]->Boks.dMinAust;
+ iIdxMax = LC_R_MAX_SON;
+ }
+
+ for (i=0; i<pRN->sSonAnt; i++) {
+ if (iIdxMax != i) {
+ if (pKandidatRN[i]->Boks.dMaxAust < dMinAust) {
+ dMinAust = pKandidatRN[i]->Boks.dMaxAust;
+ iIdxMin = i;
+ }
+ }
+ }
+
+ /* Plasser ut ekstremboksene */
+ pRN->Son.pNode[0] = pKandidatRN[iIdxMax];
+ pRN->sSonAnt = 1;
+ pRN->Boks = pKandidatRN[iIdxMax]->Boks;
+ pKandidatRN[iIdxMax]->pFar = pRN;
+ pKandidatRN[iIdxMax] = NULL;
+
+ pNyRN->Son.pNode[0] = pKandidatRN[iIdxMin];
+ pNyRN->sSonAnt = 1;
+ pNyRN->Boks = pKandidatRN[iIdxMin]->Boks;
+ pKandidatRN[iIdxMin]->pFar = pNyRN;
+ pKandidatRN[iIdxMin] = NULL;
+
+ /* Resten av boksene plasseres der de fører til minst utvielse av boksen */
+ for (i=0; i<=LC_R_MAX_SON; i++) {
+ if (pKandidatRN[i] != NULL) {
+
+ if (LR_BoksDeltaArealSum(&(pRN->Boks),&(pKandidatRN[i]->Boks)) <
+ LR_BoksDeltaArealSum(&(pNyRN->Boks),&(pKandidatRN[i]->Boks)) ) {
+
+ pRN->Son.pNode[pRN->sSonAnt] = pKandidatRN[i];
+ pRN->sSonAnt++;
+ LR_R_BoksSum(&(pRN->Boks),&(pKandidatRN[i]->Boks));
+ pKandidatRN[i]->pFar = pRN;
+
+ } else {
+ pNyRN->Son.pNode[pNyRN->sSonAnt] = pKandidatRN[i];
+ pNyRN->sSonAnt++;
+ LR_R_BoksSum(&(pNyRN->Boks),&(pKandidatRN[i]->Boks));
+ pKandidatRN[i]->pFar = pNyRN;
+ }
+ }
+ }
+
+ /* Husk den nye noden til nivået over */
+ *ppNyRN = pNyRN;
+ }
+
+ } else {
+ /* Oppdater omskrevet boks for noden */
+ LR_R_BoksSum(&(pRN->Boks),pB);
+ }
+ }
+
+
+ // Test
+ //iNivo--;
+
+ return pRL;
+}
+
+
+/*
+AR-980108
+CH LR_R_BoksSum Summerer to bokser
+CD =======================================================================
+CD Formål:
+CD Summerer to bokser ved at boks1 blir utvidet slik at den også dekker
+CD boks2.
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_BOKS * pB1 iu Boks1 som skal utvides
+CD LC_BOKS * pB2 i Boks2 som skal legges til boks1
+CD =======================================================================
+*/
+static void LR_R_BoksSum(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+ pB1->dMinAust = min(pB1->dMinAust,pB2->dMinAust);
+ pB1->dMinNord = min(pB1->dMinNord,pB2->dMinNord);
+ pB1->dMaxAust = max(pB1->dMaxAust,pB2->dMaxAust);
+ pB1->dMaxNord = max(pB1->dMaxNord,pB2->dMaxNord);
+}
+
+
+/*
+AR-980108
+CH LR_BoksDeltaArealSum Bereg arealendring ved sumering
+CD =======================================================================
+CD Formål:
+CD Beregner hvor mye arealet av boks1 blir utvidet hvis den blir
+CD summert med boks2.
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_BOKS * pB1 i Boks1
+CD LC_BOKS * pB2 i Boks2
+CD double dDeltaAreal r Arealendring
+CD =======================================================================
+*/
+static double LR_BoksDeltaArealSum(LC_BOKS * pB1,LC_BOKS * pB2)
+{
+ //long lNy, lGml;
+ //lGml = (pB1->dMaxAust - pB1->dMinAust) * (pB1->dMaxNord - pB1->dMinNord);
+ //return (lNy - lGml);
+
+ double dDeltaAreal = (max(pB1->dMaxAust,pB2->dMaxAust) - min(pB1->dMinAust,pB2->dMinAust)) *
+ (max(pB1->dMaxNord,pB2->dMaxNord) - min(pB1->dMinNord,pB2->dMinNord));
+
+ return dDeltaAreal;
+}
+
+
+/*
+AR-980108
+CH LR_R_Delete Fjern fra "søketreet"
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_LEAF * pRL i Peker til forekomst i R-treet
+CD
+CD Formål:
+CD Fjern et gitt element fra R-treet for geografisk søk.
+CD =======================================================================
+*/
+void LR_R_Delete(LC_R_LEAF * pRL)
+{
+ LC_R_NODE *pFar,*pRN,*pSonRN;
+ int i,iFunnet,iIdx=0,iFerdig;
+
+
+ if (pRL != NULL) {
+ // Husk "far"
+ pFar = pRL->pFar;
+
+ /* Fjerner pekeren fra gruppetabellen */
+ Sys.pGrInfo->pRL = NULL;
+
+ /* Fjern pekeren til løvet */
+ pRN = pFar;
+ iFunnet = UT_FALSE;
+
+ for (i=0; i<pRN->sSonAnt; i++) {
+
+ /* Sjekk om dette er den rette pekeren */
+ if (iFunnet == UT_FALSE) {
+ if (pRN->Son.pLeaf[i] == pRL) {
+ iFunnet = UT_TRUE;
+ iIdx = i;
+ }
+
+ /* Pakk de andre pekerne i denne noden */
+ } else {
+ pRN->Son.pLeaf[iIdx] = pRN->Son.pLeaf[i];
+ }
+ }
+
+ if (iFunnet == UT_TRUE) {
+ (pRN->sSonAnt)--;
+ }
+
+ // Frigir det aktuelle "løvet"
+ UT_FREE((char *)pRL);
+
+ /* Sjekk om det er mere som skal fjernes oppover i treet */
+ iFerdig = UT_FALSE;
+ while ( iFerdig == UT_FALSE) {
+
+ /* Antall sønner er 0, denne noden skal fjernes på nivået over */
+ if (pRN->sSonAnt == 0) {
+
+ // Er ikke på øverste nivå
+ if (pRN->pFar != NULL) {
+
+ /* Husk noden */
+ pSonRN = pRN;
+
+ /* Fjern pekeren til noden */
+ pRN = pSonRN->pFar;
+ iFunnet = UT_FALSE;
+
+ for (i=0; i<pRN->sSonAnt; i++) {
+
+ /* Sjekk om dette er den rette pekeren */
+ if (iFunnet == UT_FALSE) {
+ if (pRN->Son.pNode[i] == pSonRN) {
+ iFunnet = UT_TRUE;
+ iIdx = i;
+ }
+
+ /* Pakk de andre pekerne i denne noden */
+ } else {
+ pRN->Son.pNode[iIdx] = pRN->Son.pNode[i];
+ }
+ }
+
+ if (iFunnet == UT_TRUE) {
+ (pRN->sSonAnt)--;
+ }
+
+ /* Frigir noden */
+ UT_FREE((char *)pSonRN);
+
+
+ /* Har kommet til toppen */
+ } else {
+ iFerdig = UT_TRUE;
+
+ /* Treet er tomt initierer verdier på nytt */
+ pRN->sSonType = LC_LEAF;
+ /* Omskrevet boks initieres til stor invers verdi */
+ pRN->Boks.dMinAust = pRN->Boks.dMinNord = LONG_MAX;
+ pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+ }
+
+
+ /* Har flere sønner, må beregne omskrevet boks på nytt */
+ } else {
+
+ pRN->Boks.dMinAust = pRN->Boks.dMinNord = LONG_MAX;
+ pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+
+ if (pRN->sSonType == LC_LEAF) {
+ for (i=0; i<pRN->sSonAnt; i++) {
+ LR_R_BoksSum(&(pRN->Boks),&(pRN->Son.pLeaf[i]->Boks));
+ }
+
+ } else {
+ for (i=0; i<pRN->sSonAnt; i++) {
+ LR_R_BoksSum(&(pRN->Boks),&(pRN->Son.pNode[i]->Boks));
+ }
+ }
+
+ iFerdig = UT_TRUE;
+ }
+ }
+ }
+}
+
+
+/*
+AR-980204
+CH LR_R_CreateRNode Alloker og initier R-tre-node
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_NODE * pFar i Peker til far i R-treet
+CD short sSonType i Hvilken type sønner har denne noden LC_NODE / LC_LEAF
+CD LC_R_NODE * pRN r Peker til ny node i R-tre
+CD
+CD Formål:
+CD Alloker og initier node i R-tre.
+CD =======================================================================
+*/
+static LC_R_NODE * LR_R_CreateRNode( LC_R_NODE * pFar,short sSonType)
+{
+ LC_R_NODE * pRN;
+
+ pRN = (LC_R_NODE *)UT_MALLOC(sizeof(LC_R_NODE));
+
+ pRN->pFar = pFar;
+ pRN->sSonType = sSonType;
+ pRN->sSonAnt = 0;
+
+
+ //for (i=0; i>LC_R_MAX_SON; i++) {
+ // if (sSonType == LC_NODE) {
+ // pRN->Son.pNode[i] = NULL;
+ // } else {
+ // pRN->Son.pLeaf[i] = NULL;
+ // }
+ //}
+
+ /* Omskrevet boks initieres til stor invers boks */
+ pRN->Boks.dMinAust = pRN->Boks.dMinNord = LONG_MAX;
+ pRN->Boks.dMaxAust = pRN->Boks.dMaxNord = LONG_MIN;
+
+ return pRN;
+}
+
+
+/*
+AR-980204
+CH LR_R_CreateRLeaf Alloker og initier R-tre-løv
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD long lGrNr i Gruppenummer i filen
+CD LC_BOKS * pB i Boks som skal legges inn i treet
+CD LC_R_NODE * pFar i Peker til far i R-treet
+CD LC_R_LEAF * pCL r Peker til ny forekomst
+CD
+CD Formål:
+CD Alloker og initier løv R-tre.
+CD =======================================================================
+*/
+static LC_R_LEAF * LR_R_CreateRLeaf(long lGrNr, LC_BOKS * pB,LC_R_NODE * pFar)
+{
+ LC_R_LEAF * pCL = (LC_R_LEAF *)UT_MALLOC(sizeof(LC_R_LEAF));
+
+ pCL->pFar = pFar;
+ pCL->Boks = *pB;
+ pCL->lNr = lGrNr;
+
+ return pCL;
+}
+
+
+/*
+AR-980113
+CH LR_LeggTilKB Legg til Bgr i søkeresultat-kjede
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat i Peker til struktur for søkestatus
+CD LC_FILADM * pFil i Filpeker
+CD long lNr i Gruppenummer i filen
+CD
+CD Formål:
+CD Legg til Bgr i kjede med søkeresultat.
+CD =======================================================================
+*/
+static void LR_LeggTilKB(LC_GEO_STATUS * pGeoStat,LC_FILADM *pFil,long lNr)
+{
+ LC_KJEDE_BGR * pKB;
+
+ pKB = (LC_KJEDE_BGR *) UT_MALLOC(sizeof(LC_KJEDE_BGR));
+
+ /* Sosi-gruppe */
+ pKB->Bgr.pFil = pFil;
+ pKB->Bgr.lNr = lNr;
+
+ /* Oppdater pekerne i kjeden */
+ pKB->pNesteKB = NULL;
+
+ if (pGeoStat->pForsteKB == NULL) {
+ pGeoStat->pForsteKB = pKB;
+
+ } else {
+ pGeoStat->pSisteKB->pNesteKB = pKB;
+ }
+
+ pGeoStat->pSisteKB = pKB;
+}
+
+
+/*
+AR-980113
+CH LC_AvsluttSok Avslutter geografisk søk
+CD =======================================================================
+CD Bruk:
+CD
+CD parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat i Peker til struktur for søkestatus
+CD
+CD Formål:
+CD Avslutter geografisk søk, og frigir kjede med søkeresultat.
+CD =======================================================================
+*/
+SK_EntPnt_FYBA void LC_AvsluttSok(LC_GEO_STATUS * pGeoStat)
+{
+ LC_KJEDE_BGR *pKB, *pNesteKB;
+
+
+ pNesteKB = pGeoStat->pForsteKB;
+
+ while (pNesteKB != NULL) {
+ pKB = pNesteKB;
+ pNesteKB = pKB->pNesteKB;
+ UT_FREE(pKB);
+ }
+
+ pGeoStat->pForsteKB = NULL;
+ pGeoStat->pSisteKB = NULL;
+ pGeoStat->pAktuellKB = NULL;
+}
+
+
+/*
+AR-980209
+CH LR_VelgMetode Velg søkemetode for geografisk søk
+CD ==========================================================================
+CD Formål:
+CD Velg søkemetode for geografisk søk. Bruker R-tre hvis utstrekningen av
+CD søkeområdet er mindre enn 10% av baseområdet i nord eller øst retning.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GEO_STATUS * pGeoStat iu Peker til struktur for søkestatus
+CD
+ ==========================================================================
+*/
+static void LR_VelgMetode(LC_GEO_STATUS * pGeoStat)
+{
+ LC_BOKS * pB = &Sys.pAktBase->Omraade;
+
+ if ( pGeoStat->oha - pGeoStat->nva < (pB->dMaxAust - pB->dMinAust) / 10 ||
+ pGeoStat->ohn - pGeoStat->nvn < (pB->dMaxNord - pB->dMinNord) / 10 ) {
+ pGeoStat->usMetode = LC_GEO_RTRE;
+
+ } else {
+ pGeoStat->usMetode = LC_GEO_SEKV;
+ }
+}
+
+
+/*
+AR-980108
+CH LR_R_FrigiGren Frigir en gren fra "søketreet"
+CD =======================================================================
+CD Bruk:
+CD
+CD Parametere:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_R_NODE * pRN i Peker til node i R-treet
+CD
+CD Formål:
+CD Frigir en gren fra R-treet for geografisk søk.
+CD =======================================================================
+*/
+void LR_R_FrigiGren(LC_R_NODE * pRN)
+{
+ int i;
+
+ /* Har kommet til ytterste nivå */
+ if (pRN->sSonType == LC_LEAF) {
+ /* Sjekk løvene som er lagret under denne noden */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ UT_FREE((char *)pRN->Son.pLeaf[i]);
+ }
+
+ /* Node */
+ } else {
+ /* Rekursiv sjekk av de underliggende nodene */
+ for (i=0; i<pRN->sSonAnt; i++) {
+ // Vis alle underliggende nivåer
+ LR_R_FrigiGren(pRN->Son.pNode[i]);
+ }
+ }
+
+ UT_FREE((char *)pRN);
+}
diff --git a/src/FYBA/FYLS.cpp b/src/FYBA/FYLS.cpp
new file mode 100644
index 0000000..e4261fc
--- /dev/null
+++ b/src/FYBA/FYLS.cpp
@@ -0,0 +1,678 @@
+/* == AR 891104 ========================================== */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fyls.c */
+/* Innhold: Serienummer system for fysak-pc */
+/* ======================================================= */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+
+
+/* Globale variabler */
+extern LC_SYSTEMADM Sys;
+
+
+/*
+AR-910930
+CH LS_Indx Oppdater indekstabellen
+CD =============================================================================
+CD Formål:
+CD Oppdater søketabellen for serienummer.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LS_Indx();
+================================================================================
+*/
+void LS_Indx(void)
+{
+ long lSnr = LC_GetSn();
+
+ /* Legg inn snr i tabellen og oppdaterer max snr for filen */
+ LS_PutSn(Sys.GrId.pFil,Sys.GrId.lNr,lSnr);
+}
+
+
+/*
+AR-910930
+CH LC_SBSn Sett søkegrense for serienummer
+CD ==========================================================================
+CD Formål:
+CD Setter søkegrenser for serienummersøk.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD LC_FILADM * pFil i Peker til FilAdm
+CD long lMinSnr i Fra og med serienummer
+CD long lMaxSnr i Til og med serienummer
+CD
+CD Bruk:
+CD LC_SNR_ADM SnrAdm;
+CD LC_SBSn(&SnrAdm,pFil,lMinSnr,lMaxSnr);
+=============================================================================
+*/
+SK_EntPnt_FYBA void LC_SBSn(LC_SNR_ADM * pSnrAdm,LC_FILADM *pFil,long lMinSnr,long lMaxSnr)
+{
+ /* LO_TestFilpeker(pFil,"LC_SBSn"); */
+ LO_TestFilpeker(pFil,"SBSn");
+
+ pSnrAdm->pFil = pFil;
+ pSnrAdm->lMinSnr = lMinSnr;
+ pSnrAdm->lMaxSnr = lMaxSnr;
+}
+
+
+/*
+AR-911118
+CH LC_FiSn Finn gruppenummer for et serienummer
+CD ==========================================================================
+CD Formål:
+CD Finn gruppenummer for et gitt serienummer i søkeområdet for serienummer.
+CD Endrer IKKE "current gruppe".
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm
+CD long lSnr i Serienummer som skal finnes
+CD LC_BGR * pBgr u Gruppenummer i basen
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FiSn(pFil,lSnr,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FiSn(LC_FILADM *pFil,long lSnr,LC_BGR * pBgr)
+{
+ /* LO_TestFilpeker(pFil,"LC_FiSn"); */
+ LO_TestFilpeker(pFil,"FiSn");
+
+ pBgr->pFil = pFil;
+ pBgr->lNr = LI_GetSnr(pFil,lSnr);
+
+ /* Ukjent serienummer ==> */
+ if (pBgr->lNr == INGEN_GRUPPE) return UT_FALSE;
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-91118
+CH LC_MoveSn Flytt til gruppenummer for et serienummer
+CD ==========================================================================
+CD Formål:
+CD Finn gruppenummer for et gitt serienummer i søkeområdet for serienummer.
+CD Intern "aktuellt serienummer" blir endret, slik at videre søk med
+CD neste/forrige nå tar utgangspunkt i dette serienummer.
+CD (Bare hvis snr er funnet).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD long lSnr i Serienummer som skal finnes
+CD LC_BGR * pBgr u Gruppenummer i basen
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_MoveSn(pSnrAdm,snr,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_MoveSn(LC_SNR_ADM * pSnrAdm,long lSnr,LC_BGR * pBgr)
+{
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_MoveSn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"MoveSn");
+
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = LI_GetSnr(pSnrAdm->pFil,lSnr);
+
+ /* Ukjent serienummer ==> */
+ if (pBgr->lNr == INGEN_GRUPPE) return UT_FALSE;
+
+ pSnrAdm->lAktSnr = lSnr;
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-910930
+CH LC_FiArraySn Finn gruppenummer for flere serienummer
+CD ==========================================================================
+CD Formål:
+CD Finner gruppenummer for tabell med serienummer.
+CD Endrer IKKE "current gruppe".
+CD Serienummertabellen kan være "rå" slik den kommer fra GetRef. Linjer med
+CD start øy og slutt øy overses.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short antall i Antall linjer brukt i serienummertabellen
+CD long *snr i Tabell med serienummer som skal finnes
+CD long *bgr u Tabell med gruppenummer funnet
+CD (INGEN_GRUPPE = ikke funnet)
+CD
+CD Bruk:
+CD LC_FiArraySn(pFil,antall,snr,bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA void LC_FiArraySn(LC_FILADM *pFil,short antall,long *snr,long *bgr)
+{
+ short s;
+
+ LO_TestFilpeker(pFil,"LC_FiArraySn");
+
+ /* Søk gjennom hele serienummertabellen */
+ for (s=0; s<antall; s++) {
+ if (snr[s] == START_OY || snr[s] == SLUTT_OY) {
+ bgr[s] = INGEN_GRUPPE;
+
+ } else {
+ bgr[s] = LI_GetSnr(pFil,labs(snr[s]));
+ } /* endif */
+ }
+}
+
+
+/*
+AR-911022
+CH LC_FASn Finn alle serienummer
+CD ==========================================================================
+CD Formål:
+CD Finner alle grupper i fil/serienummer søkeområdet og merker i kolonne
+CD BT_SNRSOK i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm i Peker til statusblokk for serienummersøk
+CD long antall r Antall grupper funnet.
+CD
+CD Bruk:
+CD antall_funnet = LC_FASn(&SnrAdm);
+=============================================================================
+*/
+SK_EntPnt_FYBA long LC_FASn(LC_SNR_ADM * pSnrAdm)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR AktBgr,Bgr;
+ long lSnr,lGrNr;
+ long lAntall = 0;
+ long lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FASn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FASn");
+
+ /* Husk aktuell gruppe */
+ AktBgr = Sys.GrId;
+
+ /* Blanker brukttabellen */
+ LI_EraseBt(BT_SNRSOK,BT_SNRSOK);
+
+ /* Sjekker alle serienummer i søkeområdet */
+ Bgr.pFil = pSnrAdm->pFil;
+ for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ Bgr.lNr = lGrNr;
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ lAntall += LC_MerkGr(BT_SNRSOK,1); /* Tilslag */
+ }
+ }
+
+ /* Les tilbake aktuell gruppe */
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return lAntall;
+}
+
+
+/*
+AR-911022
+CH LC_FFSn Finn første serienummer
+CD =============================================================================
+CD Formål:
+CD Finner første gruppe i fil/serienummer søkeområdet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FFSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FFSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+ long lMaxSnr;
+
+ if (pSnrAdm->pFil == NULL) {
+ LC_Error(5,"(LC_FFSn)","Ingen aktuelt fil.");
+ return UT_FALSE;
+ }
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FFSn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FFSn");
+
+ lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra starten av søkeområdet */
+ for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FFSnBt Finn første serienummer med tilleggskrav
+CD ==========================================================================
+CD Formål:
+CD Finner første gruppe som er merka i gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm i Peker til statusblokk for serienummersøk
+CD short kolonne i Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FFSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+=============================================================================
+*/
+SK_EntPnt_FYBA short LC_FFSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+ LC_BGR Bgr;
+ long lMaxSnr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FFSnBt"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FFSnBt");
+
+ lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra starten av søkeområdet */
+ for (lSnr=pSnrAdm->lMinSnr; lSnr<=lMaxSnr; lSnr++) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ Bgr.pFil = pSnrAdm->pFil;
+ Bgr.lNr = lGrNr;
+ if (LC_GetBt(&Bgr,kolonne)) { /* Merka? */
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FNSn Finn neste serienummer
+CD ==========================================================================
+CD Formål:
+CD Finner neste gruppe i fil/serienummer søkeområdet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FNSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FNSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+ long lMaxSnr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FNSn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FNSn");
+
+ lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra aktuellt serienummer */
+ for (lSnr=pSnrAdm->lAktSnr+1L; lSnr<=lMaxSnr; lSnr++) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FNSnBt Finn neste serienummer med tilleggskrav
+CD ==========================================================================
+CD Formål:
+CD Finner neste gruppe også er merka i gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm i Peker til statusblokk for serienummersøk
+CD short kolonne i Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FNSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FNSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+ LC_BGR Bgr;
+ long lMaxSnr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FNSnBt"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FNSnBt");
+
+ lMaxSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra aktuellt serienummer */
+ for (lSnr=pSnrAdm->lAktSnr+1L; lSnr<=lMaxSnr; lSnr++) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ Bgr.pFil = pSnrAdm->pFil;
+ Bgr.lNr = lGrNr;
+ if (LC_GetBt(&Bgr,kolonne)) { /* Merka? */
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-911022
+CH LC_FPSn Finn forige serienummer
+CD =============================================================================
+CD Formål:
+CD Finner forrige gruppe i fil/serienummer søkeområdet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FPSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FPSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FPSn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FPSn");
+
+ /* Sjekker fra aktuellt serienummer */
+ for (lSnr=pSnrAdm->lAktSnr-1L; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FPSnBt Finn forige serienummer med tilleggskrav
+CD ==========================================================================
+CD Formål:
+CD Finner forrige gruppe i fil/serienummer søkeområdet, som også er merka i
+CD gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm i Peker til statusblokk for serienummersøk
+CD short kolonne i Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FPSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FPSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+ long lSnr,lGrNr;
+ LC_BGR Bgr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FPSnBt"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FPSnBt");
+
+ /* Sjekker fra aktuellt serienummer */
+ for (lSnr=pSnrAdm->lAktSnr-1L; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ Bgr.pFil = pSnrAdm->pFil;
+ Bgr.lNr = lGrNr;
+ if (LC_GetBt(&Bgr,kolonne)) { /* Merka? */
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FLSn Finn siste serienummer
+CD =============================================================================
+CD Formål:
+CD Finner siste gruppe i fil/serienummer søkeområdet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm iu Peker til statusblokk for serienummersøk
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FLSn(&SnrAdm,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FLSn(LC_SNR_ADM * pSnrAdm,LC_BGR * pBgr)
+{
+ long lGrNr;
+ long lSnr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FLSn"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FLSn");
+
+ lSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra slutten av tabellen */
+ for (; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LC_FLSnBt Finn siste serienummer med tilleggskrav
+CD ==========================================================================
+CD Formål:
+CD Finner siste gruppe i fil/serienummer søkeområdet som også er merka i
+CD gitt kolonne i brukttabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_SNR_ADM * pSnrAdm i Peker til statusblokk for serienummersøk
+CD short kolonne i Kolonne i brukt-tabellen som skal sjekkes
+CD LC_BGR * pBgr u Gruppenummer
+CD short sstat r Søkestatus (UT_TRUE=Funnet, UT_FALSE=Ingen funnet)
+CD
+CD Bruk:
+CD sstat = LC_FLSnBt(&SnrAdm,BT_GEOSOK,&Bgr);
+================================================================================
+*/
+SK_EntPnt_FYBA short LC_FLSnBt(LC_SNR_ADM * pSnrAdm,short kolonne,LC_BGR * pBgr)
+{
+ long lGrNr;
+ LC_BGR Bgr;
+ long lSnr;
+
+ /* LO_TestFilpeker(pSnrAdm->pFil,"LC_FLSnBt"); */
+ LO_TestFilpeker(pSnrAdm->pFil,"FLSnBt");
+
+ lSnr = min(pSnrAdm->pFil->lMaxSnr, pSnrAdm->lMaxSnr);
+
+ /* Sjekker fra slutten av tabellen */
+ for (; lSnr>=pSnrAdm->lMinSnr; lSnr--) {
+ if ((lGrNr = LI_GetSnr(pSnrAdm->pFil,lSnr)) != INGEN_GRUPPE) {
+ Bgr.pFil = pSnrAdm->pFil;
+ Bgr.lNr = lGrNr;
+ if (LC_GetBt(&Bgr,kolonne)) { /* Merka? */
+ /* Tilslag ==> */
+ pBgr->pFil = pSnrAdm->pFil;
+ pBgr->lNr = lGrNr;
+ pSnrAdm->lAktSnr = lSnr;
+ return UT_TRUE;
+ }
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-910930
+CH LS_PutSn Legg inn serienummer
+CD ==========================================================================
+CD Formål:
+CD Legg inn snr i tabellen og oppdaterer max snr for filen
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lGrNr i Gruppenummer
+CD long lSnr i Serienummer
+CD
+CD Bruk:
+CD LS_PutSn(pFil,lGrNr,lSnr);
+=============================================================================
+*/
+void LS_PutSn(LC_FILADM *pFil,long lGrNr,long lSnr)
+{
+ if (lSnr >= 0L) {
+ /* LO_TestFilpeker(pFil,"LC_PutSn"); */
+ LO_TestFilpeker(pFil,"PutSn");
+
+ /* Max snr på filen */
+ if (lSnr > pFil->lMaxSnr) {
+ pFil->lMaxSnr = lSnr;
+ }
+
+ /* Legg inn verdi */
+ LI_PutSnr(pFil,lSnr,lGrNr);
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %ld ",lSnr);
+ LC_Error(61,"(LS_PutSn)",err().tx);
+ }
+}
+
+
+/*
+AR-891104
+CH LS_VisSn Vis serienummer-tabellen
+CD =============================================================================
+CD Formål:
+CD Henter en linje fra serienummer-tabellen som formatert streng.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD long lin i Linjenummer i SN-tab som skal hentes
+CD char *tx r Peker til streng med formatert SN-linje
+CD
+CD Bruk:
+CD UT_FPRINTF(stderr,"\nSerienummertabell:\n");
+CD for (lin=0L; lin<100L; lin++) {
+CD UT_FPRINTF(stderr,"%s\n",LS_VisSn(BlaFile,lin));
+CD }
+ =============================================================================
+*/
+char *LS_VisSn(LC_FILADM *pFil,long lin)
+{
+ if (lin >= 0L && lin < pFil->lMaxSnr){
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"%8ld: %8ld",lin,LI_GetSnr(pFil,lin));
+ } else{
+ *err().tx = '\0';
+ }
+ return err().tx;
+}
diff --git a/src/FYBA/FYLU.cpp b/src/FYBA/FYLU.cpp
new file mode 100644
index 0000000..d14fa7a
--- /dev/null
+++ b/src/FYBA/FYLU.cpp
@@ -0,0 +1,2904 @@
+/* === AR-920613 ========================================================== */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylu.c */
+/* Innhold: Rutiner for utvalg */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <locale>
+
+using namespace std;
+
+#define U_PARA_LEN 128 /* Max lengde av parameterstreng */
+
+
+/* Felles variabler for hele FYBA */
+extern LC_SYSTEMADM Sys;
+
+/* Funksjonsdefinisjoner for interne funksjoner */
+static void LU_FrigiUtvalg(LC_UTVALG *pU);
+static void LU_DelLastQuery(LC_UTVALG_BLOKK *pUB);
+static short LU_TolkUtvalgslinje(LC_UTVALG_ELEMENT * pUE,const char *pszTx);
+static short LU_PiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,long lPnr);
+static short LU_PiTestLinje(LC_UTVALG_ELEMENT * pUE,long lPnr);
+//static short LU_GiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG *pU);
+static short LU_GiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE);
+static short LU_GiTestLinje(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,
+ short *gilin,char **apara);
+static short LU_ParaTest(LC_UTVALG_ELEMENT * pUE,char *para,char *pszAktPara,short sMaxLen);
+static void LU_JustPara(char *para,short ledd,short start,short slutt,
+ char *akt_para,short max_len);
+static short LU_LesULinje(FILE *pKomFil,short sMaxTxLen,char *pszTx,
+ short *psNiv);
+static void LU_AppUtvalg (LC_UTVALG_BLOKK *pUtBlokk,char *pszNavn);
+static void LU_PakkPrioritet(LC_UT_ADM * pUtAdm);
+static void LU_HuskPrior(short *NyPrior,short *sAntPrior,short sPrior);
+static void LU_SjekkDatatype(char *pszVerdi,char szMetode,short *sType);
+
+
+int LU_compare (const void *arg1, const void *arg2);
+
+
+/*
+AR-911003
+CH LC_OpenQuery Initier query
+CD ==========================================================================
+CD Formål:
+CD Initierer query mot GINFO/PINFO.
+CD Tildeler administrasjonsblokk for utvalg.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm r Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD pUtAdm = LC_OpenQuery();
+ ==========================================================================
+*/
+SK_EntPnt_FYBA LC_UT_ADM *LC_OpenQuery(void)
+{
+ LC_UT_ADM *pUtAdm;
+
+ /* Tildeler administrasjonsblokk */
+ pUtAdm = (LC_UT_ADM *) UT_MALLOC(sizeof(LC_UT_ADM));
+ memset(pUtAdm,'\0',sizeof(LC_UT_ADM));
+
+ /* Nullstiller */
+ memset(&(pUtAdm->Gruppe), 0, sizeof(LC_UTVALG_BLOKK));
+ memset(&(pUtAdm->Punkt), 0, sizeof(LC_UTVALG_BLOKK));
+ memset(&(pUtAdm->Pinfo), 0, sizeof(LC_UTVALG_BLOKK));
+
+ return pUtAdm;
+}
+
+
+/*
+AR-910718
+CH LC_CloseQuery Avslutter query
+CD ==========================================================================
+CD Formål:
+CD Avslutter query mot GINFO/PINFO.
+CD Frigir minne brukt til administrasjon og utvalgstabeller.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm i Peker til administrasjonsblokk for utvalg.
+CD
+CD
+CD Bruk:
+CD LC_CloseQuery(pUtAdm);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseQuery(LC_UT_ADM * pUtAdm)
+{
+ LC_UTVALG *pU,*pNesteU;
+ LC_LAG *pLag,*pNesteLag; //JAØ-19980922
+
+
+ if (pUtAdm != NULL)
+ {
+ /*
+ * Frigir GRUPPE-UTVALG.
+ */
+ pU = pUtAdm->Gruppe.pForsteU;
+ while (pU != NULL) {
+ pNesteU = pU->pNesteU;
+ LU_FrigiUtvalg(pU);
+
+ pU = pNesteU;
+ }
+
+ /*
+ * Frigir PUNKT-UTVALG.
+ */
+ pU = pUtAdm->Punkt.pForsteU;
+ while (pU != NULL) {
+ pNesteU = pU->pNesteU;
+ LU_FrigiUtvalg(pU);
+ pU = pNesteU;
+ }
+
+ /*
+ * Frigir PINFO-UTVALG.
+ */
+ pU = pUtAdm->Pinfo.pForsteU;
+ while (pU != NULL) {
+ pNesteU = pU->pNesteU;
+ LU_FrigiUtvalg(pU);
+ pU = pNesteU;
+ }
+
+ /*
+ * Frigir lag. JAØ-19980922
+ */
+ pLag = pUtAdm->pForsteLag;
+ while (pLag != NULL) {
+ pNesteLag = pLag->pNesteLag;
+ if (pLag->pszLagNavn != NULL) UT_FREE(pLag->pszLagNavn);
+ UT_FREE(pLag);
+ pLag = pNesteLag;
+ }
+
+ /*
+ * Frigir Adm.blokken.
+ */
+ UT_FREE(pUtAdm);
+ }
+}
+
+
+/*
+AR-920521
+CH LU_FrigiUtvalg Frigi et utvalg
+CD ==========================================================================
+CD Formål:
+CD Frigir et utvalg med alle underliggende utvalgselementer.
+CD
+CD Parameters:
+CD Type Navn I/O Forklaring
+CD -------------------------------------------------------------------------
+CD LC_UTVALG * pU i Peker til utvalget.
+CD
+CD Bruk:
+CD LU_FrigiUE(pU);
+CD ==========================================================================
+*/
+static void LU_FrigiUtvalg (LC_UTVALG * pU)
+{
+ /* Frigi utvalgs-elementer */
+ if (pU->pForsteUE != NULL) LU_FrigiUE(pU->pForsteUE);
+
+ /* Frigi navn og regel */
+ if (pU->pszNavn != NULL) UT_FREE(pU->pszNavn);
+ if (pU->pszRegel != NULL) UT_FREE(pU->pszRegel);
+
+ /* Frigi toppblokken for utvalget */
+ UT_FREE(pU);
+}
+
+
+/*
+AR-920521
+CH LU_FrigiUE Frigi utvalgselementer
+CD ==========================================================================
+CD Formål:
+CD Frigir alle elementene (utvalgslinjene) på et nivå i kjeden av
+CD utvalgselementer for et utvalg.
+CD
+CD Parameters:
+CD Type Navn I/O Forklaring
+CD -------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pForsteUE i Start utvalgs-kjede på dette nivå.
+CD
+CD Bruk:
+CD LU_FrigiUE(pForsteUE);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LU_FrigiUE (LC_UTVALG_ELEMENT * pUE)
+{
+ LC_UTVALG_ELEMENT * pNesteUE;
+
+ /* Går gjennom alle elementene på dette nivå */
+ while (pUE != NULL) {
+ /* Frigi elementer på underliggende nivå under dette objektet */
+ if (pUE->pForsteUE != NULL) LU_FrigiUE(pUE->pForsteUE);
+
+ /* Husk hva som er neste element på dette nivå */
+ pNesteUE = pUE->pNesteUE;
+
+ /* Frigi dette elementet */
+ if (pUE->min != NULL) UT_FREE(pUE->min);
+ if (pUE->max != NULL) UT_FREE(pUE->max);
+
+ UT_FREE((char *)pUE);
+
+ pUE = pNesteUE;
+ }
+}
+
+
+/*
+AR-920527
+CH LC_PutQueryLine Legg inn en query-linje
+CD ==========================================================================
+CD Formål:
+CD Legger inn og tolker en linje med query-tekst.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm i Peker til administrasjonsblokk for utvalg.
+CD char *qulin i Linje med query-tekst. (Uten prikker på første nivå).
+CD short sType i Gruppe eller Punkt (U_GRUPPE eller U_PUNKT).
+CD short ist r Status (UT_TRUE=OK, UT_FALSE=linjen er ikke OK)
+CD
+CD Bruk:
+CD ist = LC_PutQueryLine(pUtAdm,qulin,sType);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_PutQueryLine(LC_UT_ADM *pUtAdm,const char *qulin,short sType)
+{
+ const char *cp;
+ LC_UTVALG_BLOKK *pUB;
+ short sNiv = 0;
+ short sStatus = UT_FALSE;
+
+ if (pUtAdm != NULL)
+ {
+ /* Preparer strengen */
+ cp = qulin;
+ while (UT_IsSpace(*cp)) {
+ cp++;
+ }
+ /* Tell opp antall prikker */
+ while (*cp == '.') {
+ sNiv++;
+ cp++;
+ }
+
+ /* Første utvalg i blokken, alloker topp-blokk */
+ if (sType == U_GRUPPE) {
+ pUB = &pUtAdm->Gruppe;
+
+ } else { // U_PUNKT
+ pUB = &pUtAdm->Punkt;
+ }
+
+ if (pUB->pForsteU == NULL) {
+ /* Legg til et nytt utvalg */
+ LU_AppUtvalg(pUB,"Query");
+ }
+
+ /* Alloker minne og tolk linjen */
+ sStatus = LU_AppUE(pUB->pSisteU,sNiv,cp);
+
+ // Ta vare på opplysning om HØYDE er brukt
+ if (sStatus != UT_FALSE) {
+ if (strcmp(pUB->pSisteU->pSisteUE->sosi,"HØYDE") == 0) {
+ pUB->sHoydeBrukt = UT_TRUE;
+ }
+ }
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-920522
+CH LC_PutQueryRegel Legg inn et regelnavn
+CD ==========================================================================
+CD Formål:
+CD Legger inn et regelnavn på siste linje i utvalgstabellen.
+CD (Navnet blir intern konvertert til "store" bokstaver.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UTVALG *pU i Peker til utvalg
+CD char *navn i Regelnavn.
+CD
+CD Bruk:
+CD LC_PutQueryRegel(pU,navn);
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PutQueryRegel(LC_UTVALG * pU,const char *navn)
+{
+ /* Frigi eventuell gammel regel */
+ if (pU->pszRegel != NULL) UT_FREE(pU->pszRegel);
+
+ /* Legg inn ny regel */
+ pU->pszRegel = (char*)UT_MALLOC(strlen(navn)+1);
+ UT_StrCopy(pU->pszRegel, navn, strlen(navn)+1);
+ UT_StrUpper(pU->pszRegel);
+}
+
+/*
+JAØ-19980921
+CH LC_PutLag Legg inn peker til lag
+CD ==========================================================================
+CD Formål:
+CD Legger inn peker til det laget utvalget tilhører.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UT_ADM *UtAdm i Peker til administrasjonsblokk for utvalg.
+CD LC_UTVALG *pU i Peker til utvalg
+CD char *navn i Lag-navn.
+CD
+CD Bruk:
+CD LC_PutLag(pUB,pU,navn);
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PutLag(LC_UT_ADM *pUtAdm,LC_UTVALG *pU,const char *navn)
+{
+ LC_LAG * pLag,*pNyttLag;
+ short sFunnet = 0;
+
+
+ if (pUtAdm != NULL)
+ {
+ /* Det er allerede lagt inn lag på dette utvalget ? */
+ if (pU->pLag != NULL) {
+ /* Annet lag enn forrige gang ? */
+ if (strcmp(navn,pU->pLag->pszLagNavn) != 0) {
+ LC_Error(128,"(LU_HuskPrior)",pU->pszNavn);
+ }
+
+ } else {
+ /* Tester om lag-navnet allerede er registrert. */
+ pLag = pUtAdm->pForsteLag;
+ while ((pLag != NULL) && (!sFunnet)) {
+ sFunnet = (strcmp(navn,pLag->pszLagNavn) == 0);
+ if (!sFunnet) pLag = pLag->pNesteLag;
+ }
+
+ if (pLag == NULL) { /* Nytt lag, må opprettes og settes inn i kjeden. */
+ pNyttLag = (LC_LAG *)UT_MALLOC(sizeof(LC_LAG));
+ memset(pNyttLag,0,sizeof(LC_LAG));
+ pNyttLag->sLagAktiv = 1;
+ pNyttLag->pszLagNavn = (char*)UT_MALLOC(strlen(navn)+1);
+ UT_StrCopy(pNyttLag->pszLagNavn,navn,strlen(navn)+1);
+ pNyttLag->pNesteLag = NULL;
+ pU->pLag = pNyttLag;
+
+ if (pUtAdm->pForsteLag == NULL) {
+ pUtAdm->pForsteLag = pNyttLag;
+ } else {
+ pUtAdm->pSisteLag->pNesteLag = pNyttLag;
+ }
+ pUtAdm->pSisteLag = pNyttLag;
+ pUtAdm->pSisteLag->pNesteLag = NULL;
+ } else {
+ pU->pLag = pLag;
+ }
+ }
+ }
+} /* END LC_PutLag */
+
+
+/*
+AR-890308
+CH LC_LesUtvalg Les utvalg i kom.filen
+CD =============================================================================
+CD Formål:
+CD Leser og tolker gruppe og punktutvalg på kommandofilen og legger i tabell.
+CD Forutsetter at filen er åpnet på forhånd.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD FILE *pKomFil i Peker til "handle" for åpnet kommandofil.
+CD short sStatus r UT_TRUE=OK, UT_FALSE=feil i linjen
+CD
+CD Bruk:
+CD sStatus = LC_LesUtvalg(pUtAdm,pKomFil);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_LesUtvalg(LC_UT_ADM *pUtAdm,const char *pszKomFil)
+{
+ FILE * pKomFil;
+ short sFunnet;
+ char szTx[100],ord[60],szNavn[50];
+ short itxi,lesefeil,sNiv;
+ short sForrigeMaxPrioritet,sPrioritet;
+ LC_UTVALG_BLOKK *pUB=NULL;
+ short sStatus;
+
+
+ if (pUtAdm != NULL)
+ {
+ /* Åpner filen */
+ pKomFil = UT_OpenFile(pszKomFil,"",UT_READ,UT_OLD,&sStatus);
+
+ /* Åpningsfeil */
+ if (sStatus != UT_OK) {
+ char szError[256];
+ UT_strerror(szError,256,sStatus);
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s - %s",pszKomFil,szError);
+ LC_Error(101,"(LC_LesUtvalg)",err().tx);
+ return UT_FALSE;
+ }
+
+ /* Starter først på filen og leser */
+ UT_SetPos(pKomFil,0L);
+
+ lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+ while (! lesefeil) {
+ sFunnet = UT_FALSE;
+ /* Hent kommandonavn */
+ UT_StrToken(szTx,0,&itxi,60,ord);
+ UT_StrUpper(ord);
+ UT_StrToken(szTx,itxi,&itxi,60,szNavn);
+
+ if (sNiv == 1 && strcmp(ord,"GRUPPE-UTVALG") == 0) {
+ pUB = &pUtAdm->Gruppe;
+ sFunnet = UT_TRUE;
+
+ } else if(sNiv == 1 && strcmp(ord,"PUNKT-UTVALG") == 0) {
+ pUB = &pUtAdm->Punkt;
+ sFunnet = UT_TRUE;
+
+ } else if(sNiv == 1 && strcmp(ord,"PINFO-UTVALG") == 0) {
+ pUB = &pUtAdm->Pinfo;
+ sFunnet = UT_TRUE;
+ }
+
+ if (sFunnet) {
+ sForrigeMaxPrioritet = pUtAdm->sMaxPrior;
+
+ /* Legg til et utvalg */
+ LU_AppUtvalg(pUB,szNavn);
+
+ lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+ while (! lesefeil && sNiv > 1) {
+ UT_StrToken(szTx,0,&itxi,60,ord);
+ UT_StrUpper(ord);
+
+ /* PRIORITET */
+ if (sNiv == 2 && strcmp(ord,"PRIORITET") == 0) {
+ UT_StrShort(szTx,itxi,&itxi,&sPrioritet);
+ pUB->pSisteU->sPrioritet = sPrioritet;
+ pUB->pSisteU->sOriginalPrioritet = sPrioritet;
+ if (sPrioritet > pUtAdm->sMaxPrior) pUtAdm->sMaxPrior = sPrioritet;
+
+ /* BRUK-REGEL */
+ } else if (sNiv == 2 && strcmp(ord,"BRUK-REGEL") == 0) {
+ UT_StrToken(szTx,itxi,&itxi,61,ord);
+ LC_PutQueryRegel(pUB->pSisteU,ord);
+
+ /* GRUPPE */ //JAØ-19980921
+ } else if (sNiv == 2 && strcmp(ord,"LAG") == 0) {
+ UT_StrToken(szTx,itxi,&itxi,61,ord);
+ LC_PutLag(pUtAdm,pUB->pSisteU,ord);
+
+ /* Vanlige utvalgslinjer */
+ } else {
+ /* Legg inn linjen */
+ if (LU_AppUE(pUB->pSisteU,(short)(sNiv-2),szTx) == UT_FALSE) {
+
+ // Logisk feil i linjen.
+ LU_DelLastQuery(pUB);
+ pUtAdm->sMaxPrior = sForrigeMaxPrioritet;
+ fclose (pKomFil);
+ return UT_FALSE; // Avbryter tolkingen ==>
+ }
+
+ /* Sjekk om HØYDE er brukt i utvalg */
+ if (strcmp(pUB->pSisteU->pSisteUE->sosi,"HØYDE") == 0) {
+ pUB->sHoydeBrukt = UT_TRUE;
+ }
+
+ /* PUNKT-UTVALG */
+ if (pUB == &pUtAdm->Punkt) {
+ /* "!" er brukt, må sjekke alle punkt */
+ if (pUB->pSisteU->pSisteUE->metode == LC_U_IKKE) {
+ pUB->sTestAllePi = UT_TRUE;
+ }
+ }
+ }
+
+ /* Les neste linje */
+ lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+ }
+
+ /* Fjern utvalg som ikker er avsluttet med regel */
+ if (pUB->pSisteU->pszRegel == NULL) {
+ LU_DelLastQuery(pUB);
+ pUtAdm->sMaxPrior = sForrigeMaxPrioritet;
+ }
+
+ } else { /* Hopp over ukjent linje */
+ lesefeil = LU_LesULinje(pKomFil,100,szTx,&sNiv);
+ }
+ }
+
+ fclose (pKomFil);
+
+ /* Pakk prioritetene */
+ LU_PakkPrioritet(pUtAdm);
+
+ return UT_TRUE;
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-920610
+CH LU_AppUE Legg til en ny utvalgslinje
+CD ==========================================================================
+CD Formål:
+CD Legg til et nytt element i kjeden utvalgslinjer.
+CD
+CD Parameters:
+CD Type Navn I/O Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UTVALG *pU i Aktuellt utvalg
+CD short sNiv i Nivå (antall prikker forran navnet)
+CD char *pszTx i Lest linje
+CD short sStatus r UT_TRUE=OK, UT_FALSE=feil i linjen
+CD
+CD Bruk:
+CD sStatus = LU_AppUE(pUB->pSisteU,sNiv,szTx);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA short LU_AppUE (LC_UTVALG *pU,short sNiv,const char *pszTx)
+{
+ LC_UTVALG_ELEMENT *pUE,*pNyUE,*pForrigeUE=NULL;
+ short sAktNiv = 0;
+
+ /* Finn rett posisjon i kjedene */
+ pUE=pU->pSisteUE;
+ while (sAktNiv < sNiv && pUE != NULL) {
+ pForrigeUE = pUE;
+ pUE = pUE->pSisteUE;
+ sAktNiv++;
+ }
+
+ //if (sAktNiv < sNiv-1) {
+ if (sAktNiv < sNiv || sNiv > sAktNiv) {
+ LC_Error(126,"(LU_AppUE)",pszTx);
+ return UT_FALSE; /* ==> Retur når ulovlig sprang i nivå */
+ }
+
+ /* Alloker minne og initier */
+ pNyUE = (LC_UTVALG_ELEMENT *)UT_MALLOC(sizeof(LC_UTVALG_ELEMENT));
+ memset(pNyUE,0,sizeof(LC_UTVALG_ELEMENT));
+ pNyUE->min = NULL;
+ pNyUE->max = NULL;
+
+ pNyUE->pNesteUE = NULL;
+ pNyUE->pForsteUE = NULL;
+ pNyUE->pSisteUE = NULL;
+
+
+ /* Heng inn i kjedene */
+ if (sNiv == 0) {
+ if (pU->pSisteUE == NULL) {
+ pU->pForsteUE = pNyUE;
+ pU->pSisteUE = pNyUE;
+
+ } else {
+ pU->pSisteUE->pNesteUE = pNyUE;
+ pU->pSisteUE = pNyUE;
+ }
+
+ } else {
+ if (pForrigeUE->pSisteUE == NULL) {
+ pForrigeUE->pForsteUE = pNyUE;
+ pForrigeUE->pSisteUE = pNyUE;
+
+ } else {
+ pForrigeUE->pSisteUE->pNesteUE = pNyUE;
+ pForrigeUE->pSisteUE = pNyUE;
+ }
+ }
+
+ /* Tolk linjen */
+ if ( ! LU_TolkUtvalgslinje(pNyUE,pszTx)) {
+ LC_Error(124,"(LU_AppUE)",pszTx);
+ return UT_FALSE; /* ==> Retur når ulovlig utvalgslinje */
+ }
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-910718
+CH LU_DelLastQery Fjern siste utvalg fra tabellen
+CD ==========================================================================
+CD Formål:
+CD Fjerner siste utvalg fra tabellen. (Fram til forrige regelnavn.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ------------------------------------------------------------------------
+CD LC_UTVALG_BLOKK *pUB i Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LU_DelLastQuery(pUB);
+ =============================================================================
+*/
+static void LU_DelLastQuery(LC_UTVALG_BLOKK *pUB)
+{
+ /* Husk aktuellt utvalg */
+ LC_UTVALG * pU = pUB->pSisteU;
+
+ /*
+ * Ordne pekere
+ */
+
+ /* I toppblokken */
+ pUB->pSisteU = pU->pForrigeU;
+ if (pUB->pSisteU == NULL) pUB->pForsteU = NULL;
+
+ /* I kjeden av utvalg */
+ if (pU->pForrigeU != NULL) {
+ pU->pForrigeU->pNesteU = NULL;
+ }
+
+ /*
+ * Frigi minne
+ */
+ LU_FrigiUtvalg(pU);
+}
+
+
+/*
+ÅE-20040709 Forandret litt for at type skulle ta negative tall.
+AR-920526
+CH LU_TolkUtvalgslinje Tolk utvalgslinje i kom.filen
+CD ==========================================================================
+CD Formål:
+CD Tolker en utvalgslinje fra kommandofilen og legger i tabell.
+CD Forutsetter at linjen er lest.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE i Peker til utvalgselement
+CD char *pszTx i Linje med query-tekst. (Uten prikker i starten)
+CD short ist r Status (UT_TRUE=OK, UT_FALSE=linjen er ikke OK)
+CD
+CD Bruk:
+CD ist = LU_TolkUtvalgslinje(pUE,pszTx);
+ =============================================================================
+*/
+static short LU_TolkUtvalgslinje(LC_UTVALG_ELEMENT * pUE,const char *pszTx)
+{
+ char tx[100],ord[60];
+ const char *cp;
+ short itxi;
+ short i;
+
+ // ----- Preparer strengen
+ cp = pszTx;
+ while (UT_IsSpace(*cp)){
+ ++cp;
+ }
+ UT_StrCopy(tx,cp,100);
+ UT_StrUpper(tx);
+
+
+ // ----- Hent kommandonavn
+ UT_StrToken(tx,0,&itxi,60,ord);
+
+ if (strcmp(ord,"VELG") == 0) {
+ pUE->kommando = LC_U_ELLER;
+
+ } else if (strcmp(ord,"ELLER") == 0) {
+ pUE->kommando = LC_U_ELLER;
+
+ } else if (strcmp(ord,"OG") == 0) {
+ pUE->kommando = LC_U_OG;
+
+ } else {
+ return UT_FALSE; /* ===> Feil i utvalgslinjen */
+ }
+
+ // ----- Tolk resten av strengen
+ pUE->metode = LC_U_ALLE;
+ pUE->type = LC_U_TALL;
+ pUE->ledd = 0;
+ pUE->start = 0;
+ pUE->slutt = 0;
+
+ // ----- SOSI-navn
+ UT_StrToken(tx,itxi,&itxi,60,ord);
+ if (*ord) {
+ UT_StrCopy(pUE->sosi,ord,LC_MAX_SOSINAVN_LEN);
+ } else {
+ return UT_FALSE; /* ===> Feil i utvalgslinjen */
+ }
+
+ /* Metode */
+ UT_StrToken(tx,itxi,&itxi,60,ord);
+ UT_StrUpper(ord);
+
+ if (*ord) {
+ if (!strcmp(ord,"="))
+ pUE->metode = LC_U_LIK;
+ else if (!strcmp(ord,"<>"))
+ pUE->metode = LC_U_FRATIL;
+ else if (!strcmp(ord,"/"))
+ pUE->metode = LC_U_DELELIG;
+ else if (!strcmp(ord,"!/"))
+ pUE->metode = LC_U_UDELELIG;
+ else if (!strcmp(ord,"()"))
+ pUE->metode = LC_U_CONTEIN;
+ else if (!strcmp(ord,"!()"))
+ pUE->metode = LC_U_IKKECONTEIN;
+ else if (!strcmp(ord,"AL"))
+ pUE->metode = LC_U_ALLE;
+ else if (!strcmp(ord,"!="))
+ pUE->metode = LC_U_IKKELIK;
+ else if (!strcmp(ord,"!"))
+ pUE->metode = LC_U_IKKE;
+ else if (!strcmp(ord,"><"))
+ pUE->metode = LC_U_UTENFOR;
+ else if (!strcmp(ord,"<"))
+ pUE->metode = LC_U_MINDRE;
+ else if (!strcmp(ord,">"))
+ pUE->metode = LC_U_STORRE;
+ else if (! strcmp(ord,"IV"))
+ pUE->metode = LC_U_IKKEVALGT;
+ else if (!strcmp(ord,"FL"))
+ pUE->metode = LC_U_FLERE;
+ else if (!strcmp(ord,"!FL"))
+ pUE->metode = LC_U_IKKEFLERE;
+ else {
+ return UT_FALSE; /* ===> Feil i utvalgslinjen */
+ }
+ }
+
+ // ----- Min
+ UT_StrToken(tx,itxi,&itxi,60,ord);
+ if (*ord) {
+ pUE->min = (char*)UT_MALLOC(strlen(ord)+1);
+ UT_StrCopy(pUE->min,ord,strlen(ord)+1);
+
+ // Sjekk type
+ LU_SjekkDatatype(pUE->min,0,&pUE->type);
+
+ } else {
+ pUE->min = (char*)UT_MALLOC(1);
+ UT_StrCopy(pUE->min,"",1);
+ pUE->type = LC_U_ALFA;
+ }
+
+
+ // ----- Max
+ UT_StrToken(tx,itxi,&itxi,60,ord);
+ if (*ord) {
+ pUE->max = (char*)UT_MALLOC(strlen(ord)+1);
+ UT_StrCopy(pUE->max, ord, strlen(ord)+1);
+
+ // Sjekk type
+ if (pUE->type != LC_U_ALFA) {
+ LU_SjekkDatatype(pUE->max,pUE->metode,&pUE->type);
+ }
+
+ } else {
+ pUE->max = (char*)UT_MALLOC(1);
+ UT_StrCopy(pUE->max,"",1);
+ }
+
+ // ----- Type
+ UT_StrToken(tx,itxi,&itxi,60,ord);
+ if(*ord){
+ if(*ord == 'T'){
+ pUE->type = LC_U_TALL | LC_U_DEFINERT;
+ } else if(*ord == 'A'){
+ pUE->type = LC_U_ALFA | LC_U_DEFINERT;
+ } else if(*ord == 'F'){
+ pUE->type = LC_U_FLYT | LC_U_DEFINERT;
+ } else{
+ return UT_FALSE; /* ===> Feil i utvalgslinjen */
+ }
+
+ char *cp2 = ord + 1;
+ for (i=0; i<2; ++i) {
+ if (*cp2 == '#') {
+ ++cp2;
+ pUE->ledd = (char) strtol(cp2,&cp2,10); /* Ledd-nummer */
+ }else if (*cp2 == '[') {
+ ++cp2;
+ pUE->start = (char) strtol(cp2,&cp2,10); /* Startposisjon */
+ ++cp2;
+ pUE->slutt = (char) strtol(cp2,&cp2,10); /* Sluttposisjon */
+ }
+ }
+ }
+
+
+ // Sikkrer at det er lagt inn strenger for min og max
+ //if (pUE->min == NULL) pUE->min = strcpy(UT_MALLOC(2),"");
+ //if (pUE->max == NULL) pUE->max = strcpy(UT_MALLOC(2),"");
+
+ return UT_TRUE;
+}
+
+
+/*
+AR-881115
+CH LU_SjekkDatatype Sjekk datatype
+CD =============================================================================
+CD Formål:
+CD Finner datatype ut fra utvalgsparameter.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszVerdi i Verdi
+CD char szMetode i Utvalgsmetode
+CD short *psType iu Type, Inn=foreløpig type, Ut=beregnet type
+CD
+CD Bruk:
+CD LU_SjekkDatatype(pszVerdi,szMetode,sType);
+ =============================================================================
+*/
+static void LU_SjekkDatatype(char *pszVerdi,char szMetode,short *psType)
+{
+ char *cp;
+ short i=0;
+
+
+ locale loc ( "Norwegian" );
+
+ /* Sjekk typen */
+ for (cp=pszVerdi; *cp!='\0'; ++cp)
+ {
+ // Første tegn:
+ if (i==0)
+ {
+ if (*cp=='.')
+ {
+ *psType = LC_U_FLYT;
+ }
+ else if (*cp!='+' && *cp!='-' && !isdigit( *cp, loc ))
+ {
+ *psType = LC_U_ALFA;
+ break;
+ }
+ }
+ else if ( ! isdigit( *cp, loc ) )
+ {
+ // Resten av tegnene:
+ if (*cp == '.') // funnet '.' tidligere
+ {
+ if ((*psType == LC_U_FLYT)&&(szMetode != LC_U_FRATIL)&&(szMetode != LC_U_UTENFOR)&&(szMetode != LC_U_DELELIG))
+ {
+ *psType = LC_U_ALFA;
+ break;
+ }
+ else
+ {
+ *psType = LC_U_FLYT;
+ }
+
+ }
+ else
+ {
+ *psType = LC_U_ALFA;
+ break;
+ }
+ }
+ ++i;
+ }
+
+ if (*psType == LC_U_TALL)
+ {
+ // Hvis tallet har for mange siffer til long må det håndteres som tekst
+ long lTall = atol(pszVerdi);
+ if (lTall == LONG_MAX || lTall == LONG_MIN)
+ {
+ *psType = LC_U_ALFA;
+ }
+ }
+}
+
+
+/*
+AR-881115
+CH LC_GetUtRegelNavn Henter regelnavn
+CD =============================================================================
+CD Formål:
+CD Henter regelnavn for at programmet utenfor skal kunne sjekke
+CD at det er tilgjengelig videre behandling av alle definerte navn.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD short *ist iu Status (Inn: 1=start, 0=neste)
+CD (Ut: 0=OK, -1=ferdig);
+CD char *regelpeker r Peker til utvalgsnavn.
+CD
+CD Bruk:
+CD regelpeker = LC_GetUtRegelNavn(pUtAdm,&ist);
+ =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetUtRegelNavn(LC_UT_ADM *pUtAdm,short *ist)
+{
+ if (pUtAdm != NULL)
+ {
+ if (*ist == 1) {
+ pUtAdm->pAktUB = &pUtAdm->Gruppe;
+ pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+
+ } else {
+ if (pUtAdm->pAktUB->pAktU != NULL) {
+ pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pAktU->pNesteU;
+ }
+ }
+
+ /* Sjekk om dette er et lovlig utvalg */
+ while (pUtAdm->pAktUB->pAktU == NULL) {
+ /* Ferdig med GRUPPE-UTVALG ,sjekk PUNKT-UTVALG */
+ if (pUtAdm->pAktUB == &(pUtAdm->Gruppe)) {
+ pUtAdm->pAktUB = &pUtAdm->Punkt;
+ pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+
+ /* Ferdig med PUNKT-UTVALG ,sjekk PINFO-UTVALG */
+ } else if (pUtAdm->pAktUB == &pUtAdm->Punkt) {
+ pUtAdm->pAktUB = &pUtAdm->Pinfo;
+ pUtAdm->pAktUB->pAktU = pUtAdm->pAktUB->pForsteU;
+
+ } else {
+ /* RETUR når det ikke er tilslag */
+ *ist = -1;
+ return NULL;
+ }
+ }
+
+ /* RETUR ved tilslag */
+ *ist = 0;
+ return pUtAdm->pAktUB->pAktU->pszRegel;
+ }
+
+ *ist = -1;
+ return NULL;
+}
+
+
+/*
+AR-920526
+CH LC_FinnPinfoUtvalg
+CD ==========================================================================
+CD Formål:
+CD Finner et PINFO-UTVALG i kjeden av slike utvalg.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD char *pszNavn i Utvalgsnavn
+CD LC_UTVALG * pUtvalg r Peker til utvalget. (NULL = ikke funnet)
+CD
+CD Bruk:
+CD pUtvalg = LC_FinnPinfoUtvalg(pszNavn);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA LC_UTVALG * LC_FinnPinfoUtvalg(LC_UT_ADM * pUtAdm,const char *pszNavn)
+{
+ LC_UTVALG * pU;
+
+ if (pUtAdm != NULL)
+ {
+ /* Søk i kjeden av pinfo-utvalg */
+ for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU=pU->pNesteU) {
+ if (strcmp(pszNavn,pU->pszRegel) == 0) {
+ return pU; /* ==> Funnet */
+ }
+ }
+ }
+
+ // Ikke funnet
+ return NULL;
+}
+
+
+/*
+AR-881130
+CH LC_PunktUtvalg PUNKT-utvalg
+CD =============================================================================
+CD Formål:
+CD Sjekker PINFO-delen av aktuell gruppe for tilslag på PUNKT-UTVALG.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD short sPrior i Prioritet.
+CD short *psStat iu Søkestatus, Inn: 1=start søk, 0=fortsett søk
+CD Ut : 0=tilslag, -1=ikke tilslag
+CD long lPnr i Punktnummer som skal sjekkes.
+CD char **ppszRegel u Peker til regelnavn
+CD
+CD Bruk:
+CD LC_PunktUtvalg(pUtAdm,sPrior,&psStat,lPnr,&ppszRegel);
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_PunktUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *psStat,long lPnr,char **ppszRegel)
+{
+ LC_UTVALG * pU;
+
+
+ if (pUtAdm != NULL)
+ {
+ if (*psStat == 1) { /* Initier søk */
+ /* Utvalgsmetode "!" (ikke) er brukt, eller
+ punktet har PINFO mm. */
+ if (pUtAdm->Punkt.sTestAllePi == UT_TRUE ||
+ LC_TestPi(lPnr,pUtAdm->Punkt.sHoydeBrukt)) {
+ pU = pUtAdm->Punkt.pForsteU;
+
+ } else {
+ pU = NULL;
+ }
+
+ } else {
+ if (pUtAdm->Punkt.pAktU != NULL) {
+ pU = pUtAdm->Punkt.pAktU->pNesteU;
+ } else {
+ pU = NULL;
+ }
+ }
+
+ /* Søk */
+ while (pU != NULL) {
+ /* Rett prioritet ? */
+ if (sPrior == LC_OVERSE_PRIORITET || pU->sPrioritet == sPrior) {
+ if (LC_PiTestUtvalg(pUtAdm,pU,lPnr)) { /* Tilslag */
+ pUtAdm->Punkt.pAktU = pU;
+ *ppszRegel = pU->pszRegel;
+ *psStat = 0;
+ return; /* ==> Retur ved tilslag */
+ }
+ }
+
+ /* Fortsett med neste utvalg */
+ pU = pU->pNesteU;
+ }
+
+ pUtAdm->Punkt.pAktU = pU;
+ }
+
+ *psStat = -1; /* Ikke tilslag */
+ return;
+}
+
+
+/*
+AR-920929
+CH LC_PiTestUtvalg Sjekk PUNKT/PINFO utvalg
+CD ==========================================================================
+CD Formål:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller et punkt-utvalg.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Administrasjonsblokk
+CD LC_UTVALG * pU i Peker til utvalg
+CD long lPnr i Punktnummer som skal sjekkes.
+CD short sTilslag r Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD sTilslag = LC_PiTestUtvalg(pUtAdm,pU,lPnr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG * pU,long lPnr)
+{
+ short sTilslag = UT_FALSE;
+
+
+ if (pUtAdm != NULL)
+ {
+ LC_UTVALG_ELEMENT * pUE = pU->pForsteUE;
+
+ /* Søk */
+ while (pUE != NULL) {
+ /* Linjen må testes i disse tilfeller */
+ /* Har tilslag, og metode er ..OG */
+ /* Har ikke tilslag, og metode er ..ELLER */
+ if (( sTilslag && pUE->kommando == LC_U_OG) ||
+ (!sTilslag && pUE->kommando == LC_U_ELLER)) {
+ sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+ }
+
+ pUE = pUE->pNesteUE;
+ }
+ }
+
+ return sTilslag;
+}
+
+
+/*
+AR-920617
+CH LU_PiTestDelutvalg Sjekk en del av et utvalg
+CD ==========================================================================
+CD Formål:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller en del av et
+CD punkt-utvalg. Sjekker et utvalgselement samt underliggende elementer
+CD under dette.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Administrasjonsblokk
+CD LC_UTVALG_ELEMENT * pUE i Peker til utvalgselement
+CD long lPnr i Punktnummer som skal sjekkes.
+CD short sTilslag r Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+ ==========================================================================
+*/
+static short LU_PiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,long lPnr)
+{
+ short sTilslag = UT_FALSE;
+ short sForste = UT_TRUE;
+ /* Søk */
+ while (pUE != NULL) {
+ if (sForste) {
+ /*
+ * Første element i delutvalget skal alltid testes.
+ */
+ sTilslag = LU_PiTestLinje(pUE,lPnr);
+
+ pUE = pUE->pForsteUE;
+
+ sForste = UT_FALSE;
+
+ } else {
+ /*
+ * Elementet må testes i disse tilfeller:
+ * - Har tilslag, og metode er ..OG.
+ * - Har ikke tilslag, og metode er ..ELLER.
+ * Elementet kan være toppen av et nytt delutvalg, kaller derfor
+ * LU_PiTestDelutvalg for å teste dette elementet.
+ */
+ if (( sTilslag && pUE->kommando == LC_U_OG) ||
+ (!sTilslag && pUE->kommando == LC_U_ELLER)) {
+
+ sTilslag = LU_PiTestDelutvalg(pUtAdm,pUE,lPnr);
+ }
+
+ pUE = pUE->pNesteUE;
+ }
+ }
+
+ return sTilslag;
+}
+
+
+/*
+AR-920617
+CH LU_PiTestLinje Sjekk en utvalgslinje
+CD ==========================================================================
+CD Formål:
+CD Sjekk om PINFO i aktuellt punkt tilfredstiller en linje punkt-utvalg.
+CD
+CD Parametre
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE i Peker til administrasjonsblokk for utvalg.
+CD long lPnr i Punktnummer som skal sjekkes.
+CD short tilslag r Status: 1=tilslag, 0=ikke tilslag.
+CD
+CD Bruk:
+CD tilslag = LU_PiTestLinje(pUE,lPnr);
+ ==========================================================================
+*/
+static short LU_PiTestLinje(LC_UTVALG_ELEMENT * pUE,long lPnr)
+{
+ char akt_para[U_PARA_LEN];
+ short tilslag;
+ long lMaxAntall;
+ char *para;
+ short sSett = 1;
+ short metode = pUE->metode;
+
+ /* Metode IKKE "!" */
+ if (metode == LC_U_IKKE){
+ /* AR:2002-04-24 */
+ /* if ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) == NULL ||
+ *para == '\0') { */
+ if (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) == NULL) {
+ return UT_TRUE;
+ }
+
+ } else if (metode == LC_U_FLERE) { /* Metode "FL" */
+ /* Teller opp antall av dette SOSI-navnet */
+ tilslag = 0;
+ while (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+ tilslag++;
+ /* Tilslag hvis navnet finnes mer enn 1 gang */
+ if (tilslag > 1) return UT_TRUE;
+ sSett++;
+ }
+
+ } else if (metode == LC_U_IKKEFLERE) { /* Metode "!FL" */
+ /* Teller opp antall av dette SOSI-navnet */
+ lMaxAntall = max(atol(pUE->min),1l);
+ tilslag = 0;
+
+ while (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+ tilslag++;
+ /* Har flere forekomster, avbryter */
+ if (tilslag > lMaxAntall) return UT_FALSE;
+ sSett++;
+ }
+ /* Tilslag, ikke flere forekomster */
+ return UT_TRUE;
+
+ } else if (metode == LC_U_ALLE) { /* Metode "AL" */
+ if (LC_GetPiVerdi(pUE->sosi,lPnr,&sSett) != NULL) {
+ return UT_TRUE;
+ }
+
+ /* Metode IKKE LIK "!=" */
+ } else if (metode == LC_U_IKKELIK) {
+ tilslag = 0;
+ pUE->metode = LC_U_LIK; /* Sjekker først på likhet */
+ /* Hent parameter */
+ while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ tilslag = 1;
+ break; /* Vet nå at det ikke blir tilslag, hopper ut */
+ }
+ sSett++;
+ }
+ pUE->metode = LC_U_IKKELIK;
+ if (! tilslag) /* Tilslag når "=-testen" ikke ga tilslag */
+ return UT_TRUE;
+
+ /* Metode INNEHOLDER IKKE "!()" */
+ } else if (metode == LC_U_IKKECONTEIN) {
+ tilslag = 0;
+ pUE->metode = LC_U_CONTEIN; /* Sjekker først INNEHOLDER */
+ /* Hent parameter */
+ while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ tilslag = 1;
+ break; /* Vet nå at det ikke blir tilslag, hopper ut */
+ }
+ sSett++;
+ }
+ pUE->metode = LC_U_IKKECONTEIN;
+ if (! tilslag) /* Tilslag når "()-testen" ikke ga tilslag */
+ return UT_TRUE;
+
+ /* Andre utvalgsmetoder */
+ } else {
+ /* Hent parameter */
+ while ((para = LC_GetPiVerdi(pUE->sosi,lPnr,&sSett)) != NULL) {
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ return UT_TRUE;
+ }
+ sSett++;
+ }
+ }
+
+ return UT_FALSE; /* Ikke tilslag */
+}
+
+
+/*
+AR-881130
+CH LC_GruppeUtvalg GINFO-utvalg
+CD ==========================================================================
+CD Formål:
+CD Sjekker GINFO-delen av aktuell gruppe mot alle gruppeutvalg fra fil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD short sPrior i Prioritet.
+CD LC_OVERSE_PRIORITET = Tar ikke hensyn til prioritet.
+CD short *sstat iu Søkestatus, Inn: 1=start søk, 0=fortsett søk
+CD Ut : 0=tilslag, -1=ikke tilslag
+CD char **regelnavn u Peker til regelnavn
+CD char *regelnavn u Peker til utvalgsnavn
+CD
+CD Bruk:
+CD pszUtvalgsNavn = LC_GruppeUtvalg(pUtAdm.sPrior,&sstat,&regel);
+ =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GruppeUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *sstat,char **regelnavn)
+{
+ LC_UTVALG * pU;
+
+ if (pUtAdm != NULL)
+ {
+ if (*sstat == 1) { /* Initier søk */
+ pU = pUtAdm->Gruppe.pForsteU;
+ pUtAdm->sGruppeValgt = UT_FALSE;
+
+ } else {
+ if (pUtAdm->Gruppe.pAktU != NULL) {
+ pU = pUtAdm->Gruppe.pAktU->pNesteU;
+ } else {
+ pU = NULL;
+ }
+ }
+
+ /* Søk */
+ while (pU != NULL) {
+ /* Rett prioritet ? */
+ if (sPrior == LC_OVERSE_PRIORITET || pU->sPrioritet == sPrior) {
+ if (LU_GiTestUtvalg(pUtAdm,pU)) { /* Tilslag */
+ *regelnavn = pU->pszRegel;
+ *sstat = 0;
+ pUtAdm->sGruppeValgt = UT_TRUE;
+ pUtAdm->Gruppe.pAktU = pU;
+
+ return pU->pszNavn; /* ==> Retur ved tilslag */
+ }
+ }
+
+ /* Fortsett med neste utvalg */
+ pU = pU->pNesteU;
+ }
+
+ pUtAdm->Gruppe.pAktU = pU;
+ }
+
+ *sstat = -1; /* Ikke tilslag */
+ return NULL;
+}
+
+
+/*
+AR-881213
+CH LC_GiQuery Query mot aktuell ginfo
+CD =============================================================================
+CD Formål:
+CD Sjekker GINFO-delen av aktuell gruppe mot aktuellt query-oppsett.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD short status r Søkestatus, UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD ist = LC_GiQuery(pUtAdm);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GiQuery(LC_UT_ADM *pUtAdm)
+{
+ if (pUtAdm != NULL)
+ {
+ pUtAdm->sGruppeValgt = UT_FALSE;
+
+ return LU_GiTestUtvalg(pUtAdm,pUtAdm->Gruppe.pForsteU);
+ }
+
+ return UT_FALSE;
+}
+
+/*
+JAØ-20000512
+CH LC_FAGiKombinertFlateQuery Finn alle ved query mot ginfo i flate og omkrets
+CD =============================================================================
+CD Formål:
+CD Sjekker GINFO-delen av alle flater mot aktuell queryopsett. Finner de flatene
+CD som har tilslag på utvalgsblokken pUtAdmFlate og har har referanser til grupper
+CD som har tilslag på utvalgsblokken pUtAdmOmkrets.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (30).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdmFlate i Peker til administrasjonsblokk for utvalg for flata.
+CD LC_UT_ADM *pUtAdmOmkrets i Peker til administrasjonsblokk for utvalg for omkrets.
+CD unsigned short usLag i Velg hvilke "lag" det skal søkes i.
+CD LC_FRAMGR og /eller LC_BAKGR
+CD short sAlle i Flagg for hvorvidt utvalg for omkrets må slå til på
+CD alle gruppene i omkretsen. TRUE/FALSE
+CD short antall r Antall tilslag på utvalget.
+CD
+CD Bruk:
+CD antall = LC_FAGiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+ =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGiKombinertFlateQuery(LC_UT_ADM * pUtAdmFlate,LC_UT_ADM * pUtAdmOmkrets,
+ unsigned short usLag,short sMetode)
+{
+ #define RED_MAX_REF 10
+
+ short ngi,gnavn,tilslag,i,avbryt;
+ long nko;
+ long ant_ref;
+ unsigned short info;
+ LC_BGR Bgr,AktBgr,FlateBgr;
+ short avbrutt = UT_FALSE;
+ long *gs;
+
+ LC_GRF_STATUS GrfStat;
+ long gsnr[RED_MAX_REF];
+ unsigned char ref_status[RED_MAX_REF];
+ long antall = -1L;
+
+
+ if (pUtAdmFlate != NULL && pUtAdmOmkrets != NULL)
+ {
+ antall = 0L;
+
+ LC_GetGrNr(&AktBgr);
+
+ /* Blanker brukttabellen */
+ LI_EraseBt(BT_GISOK,BT_GISOK);
+
+ LC_InitNextBgr(&FlateBgr);
+
+ // Sjekker alle grupper i aktuellt lag
+ while (LC_NextBgr(&FlateBgr,usLag) && !avbrutt) {
+ // Filhodet behandles ikke
+ if (FlateBgr.lNr != 0L) {
+ gnavn = LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (gnavn == L_FLATE) { // Er det en flate ?
+ if (ngi > 0){ // Med koordinat ?
+ if (LC_GiQuery(pUtAdmFlate)){ // Tilslag på flata.
+
+ LC_InitGetRefFlate(&GrfStat);
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE|GRF_INDRE,gsnr,(unsigned char*)ref_status,RED_MAX_REF);
+ Bgr.pFil = FlateBgr.pFil;
+
+ tilslag = 0;
+ avbryt = 0;
+ do {
+ i = 0;
+ gs = gsnr;
+ while ((i < ant_ref) && !avbryt) {
+ if (!((ref_status[i] & GRF_START_OY) || (ref_status[i] & GRF_SLUTT_OY))) {
+ Bgr.lNr = labs(*gs);
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ tilslag = LC_GiQuery(pUtAdmOmkrets);
+ if (sMetode == LC_ALLE) {
+ avbryt = !tilslag;
+ } else if (sMetode == LC_INGEN) {
+ avbryt = tilslag;
+ } else { //(sMetode == LC_NOEN)
+ avbryt = tilslag;
+ }
+ }
+ i++;
+ gs++;
+
+ }
+
+ LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE|GRF_INDRE,gsnr,(unsigned char*)ref_status,RED_MAX_REF);
+ } while (ant_ref>0 && !avbryt);
+
+ if (sMetode == LC_INGEN) tilslag = !tilslag;
+ if (tilslag) {
+ LC_RxGr(&FlateBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ antall += LC_MerkGr(BT_GISOK,1); // Tilslag
+ }
+ }
+ }
+ }
+ }
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ }
+
+ if (avbrutt) antall = -1L;
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+ }
+
+ return antall;
+}
+
+/*
+AR-900109
+CH LC_FAGiQuery Finn alle ved query mot ginfo
+CD =============================================================================
+CD Formål:
+CD Sjekker GINFO-delen av alle grupper mot aktuell queryopsett.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (14).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD unsigned short usLag i Velg hvilke "lag" det skal søkes i.
+CD LC_FRAMGR og /eller LC_BAKGR
+CD short antall r Antall tilslag på utvalget.
+CD
+CD Bruk:
+CD antall = LC_FAGiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+ =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAGiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR Bgr,AktBgr;
+ short avbrutt = UT_FALSE;
+ long antall = -1L;
+
+
+ if (pUtAdm != NULL)
+ {
+ antall = 0L;
+
+ LC_GetGrNr(&AktBgr);
+
+ /* Blanker brukttabellen */
+ LI_EraseBt(BT_GISOK,BT_GISOK);
+
+ LC_InitNextBgr(&Bgr);
+
+ /* Sjekker alle grupper i aktuellt lag */
+ while(LC_NextBgr(&Bgr,usLag) && !avbrutt) {
+ /* Filhodet behandles ikke */
+ if (Bgr.lNr != 0L) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (ngi > 0){ /* Finnes gruppen ? */
+ if (LC_GiQuery(pUtAdm)){
+ antall += LC_MerkGr(BT_GISOK,1); /* Tilslag */
+ }
+ }
+ }
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ }
+
+ if (avbrutt) antall = -1L;
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+ }
+
+ return antall;
+}
+
+/*
+AR-20040705
+ÅE-20040705
+CH LC_FAPiQuery Finn alle grupper ved query mot pinfo
+CD =============================================================================
+CD Formål:
+CD Sjekker PINFO-delen av alle grupper mot aktuell queryopsett.
+CD Tilslag merkes i brukttabellen kolonne BT_GISOK (14).
+CD [Esc] avbryter utvalget, antall tilslag settes da til -1.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD unsigned short usLag i Velg hvilke "lag" det skal søkes i.
+CD LC_FRAMGR og /eller LC_BAKGR
+CD short antall r Antall tilslag på utvalget.
+CD
+CD Bruk:
+CD antall = LC_FAPiQuery(pUtAdm, LC_FRAMGR | LC_BAKGR);
+CD
+ =============================================================================
+*/
+SK_EntPnt_FYBA long LC_FAPiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR Bgr,AktBgr;
+ long lPunkt;
+ short avbrutt = UT_FALSE;
+ short ustat;
+ short sFunnet = UT_FALSE;
+ char *regel;
+ long antall = -1L;
+
+
+ if (pUtAdm != NULL)
+ {
+ antall = 0L;
+
+ LC_GetGrNr(&AktBgr);
+
+ /* Blanker brukttabellen */
+ LI_EraseBt(BT_GISOK,BT_GISOK);
+
+ LC_InitNextBgr(&Bgr);
+
+ /* Sjekker alle grupper i aktuellt lag */
+ while(LC_NextBgr(&Bgr,usLag) && !avbrutt) {
+ /* Filhodet behandles ikke */
+ if (Bgr.lNr != 0L) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (nko > 0){ /* Finnes gruppen ? */
+ sFunnet=UT_FALSE;
+ lPunkt=1;
+ // Kontrollerer punkt i gruppa:
+ while (lPunkt<=nko && sFunnet==UT_FALSE && !avbrutt) {
+ ustat = 1;
+ LC_PunktUtvalg(pUtAdm,LC_OVERSE_PRIORITET,&ustat,lPunkt,&regel);
+ if (ustat == 0 && sFunnet==UT_FALSE && !avbrutt) {
+ sFunnet = UT_TRUE;
+ antall += LC_MerkGr(BT_GISOK,1); /* Tilslag */
+ break; // avbryter søk i denne gruppen ved første aktuelle pinfo
+ }
+ lPunkt++;
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ }
+ }
+ }
+ avbrutt = LC_Cancel(); /* <ESC> avbryter lesing */
+ }
+
+ if (avbrutt) antall = -1L;
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+ }
+
+ return antall;
+}
+
+
+/*
+AR-890904
+CH LU_GiTestUtvalg Sjekk et utvalg
+CD ==========================================================================
+CD Formål:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller et gruppe-utvalg.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Administrasjonsblokk
+CD LC_UTVALG * pU i Peker til utvalg
+CD short sTilslag r Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD bTilslag = LU_GiTestUtvalg(pUtAdm,pU);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LU_GiTestUtvalg(LC_UT_ADM * pUtAdm,LC_UTVALG * pU)
+{
+ short sTilslag = UT_FALSE;
+ LC_UTVALG_ELEMENT * pUE = pU->pForsteUE;
+
+ // Hvis utvalgsregelen er med i et lag og dette ikke
+ // skal tegnes ut, returneres FALSE. JAØ-19980922
+ if (pU->pLag != NULL) {
+ if (pU->pLag->sLagAktiv == 0) return 0;
+ }
+ // Innført at også utvalgsregler kan slås av for tegning. JAØ-20020927
+ if (!pU->sTegnes) return 0;
+ /* Søk */
+ while (pUE != NULL) {
+ /* Linjen må testes i disse tilfeller */
+ /* Har tilslag, og metode er ..OG */
+ /* Har ikke tilslag, og metode er ..ELLER */
+ if (( sTilslag && pUE->kommando == LC_U_OG) ||
+ (!sTilslag && pUE->kommando == LC_U_ELLER)) {
+ sTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+ }
+
+ pUE = pUE->pNesteUE;
+ }
+
+ return sTilslag;
+}
+
+
+
+/*
+AR-890904
+CH LU_GiTestDelutvalg Sjekk en del av et utvalg
+CD ==========================================================================
+CD Formål:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller en del av et
+CD gruppe-utvalg. Sjekker et utvalgselement samt underliggende elementer
+CD under dette.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Administrasjonsblokk
+CD LC_UTVALG_ELEMENT * pUE i Peker til utvalgselement
+CD short sTilslag r Status: UT_TRUE=tilslag, UT_FALSE=ikke tilslag
+CD
+CD Bruk:
+CD bTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+ ==========================================================================
+*/
+static short LU_GiTestDelutvalg(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE)
+{
+ char *apara;
+ short gilin;
+ short sTilslag = UT_FALSE;
+ short sForste = UT_TRUE;
+ /* Søk */
+ while (pUE != NULL) {
+ if (sForste) {
+ /*
+ * Første element i delutvalget skal alltid testes.
+ */
+ sTilslag = LU_GiTestLinje(pUtAdm,pUE,&gilin,&apara);
+
+ pUE = pUE->pForsteUE;
+
+#ifdef TEST
+ if (pUE->pForsteUE != NULL) {
+ pUE = pUE->pForsteUE;
+ } else {
+ pUE = pUE->pNesteUE;
+ }
+#endif
+
+ sForste = UT_FALSE;
+
+ } else {
+ /*
+ * Elementet må testes i disse tilfeller:
+ * - Har tilslag, og metode er ..OG.
+ * - Har ikke tilslag, og metode er ..ELLER.
+ * Elementet kan være toppen av et nytt delutvalg, kaller derfor
+ * LU_GiTestDelutvalg for å teste dette elementet.
+ */
+ if (( sTilslag && pUE->kommando == LC_U_OG) ||
+ (!sTilslag && pUE->kommando == LC_U_ELLER)) {
+ sTilslag = LU_GiTestDelutvalg(pUtAdm,pUE);
+ }
+
+ pUE = pUE->pNesteUE;
+ }
+ }
+
+ return sTilslag;
+}
+
+
+/*
+AR-881215
+CH LU_GiTestLinje Sjekk en utvalgslinje
+CD ==========================================================================
+CD Formål:
+CD Sjekk om GINFO av aktuell gruppe tilfredstiller en linje ginfo-utvalg.
+CD
+CD Parametre
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD LC_UTVALG_ELEMENT * pUE i Peker til administrasjonsblokk for utvalg.
+CD char *gilin u GINFO-linje for funnet tilslag.
+CD char **apara u Peker til aktuell del av parameterstreng.
+CD short tilslag r Status: 1=tilslag, 0=ikke tilslag.
+CD
+CD Bruk:
+CD tilslag = LU_GiTestLinje(pUtAdm,pUE,&gilin,&apara);
+ ==========================================================================
+*/
+static short LU_GiTestLinje(LC_UT_ADM * pUtAdm,LC_UTVALG_ELEMENT * pUE,
+ short *gilin,char **apara)
+{
+ static char akt_para[U_PARA_LEN];
+ short metode,tilslag;
+ long lMaxAntall;
+ char *para;
+
+ metode = pUE->metode;
+ *gilin = 1;
+ *apara = akt_para;
+
+ /* Metode IKKE "!" */
+ if (metode == LC_U_IKKE){
+ /* AR:2002-04-24 */
+ /* if ((para = LC_GetGP(pUE->sosi,gilin,9999)) == NULL ||
+ *para == '\0') { */
+ if (LC_GetGP(pUE->sosi,gilin,9999) == NULL) {
+ return UT_TRUE;
+ }
+
+ /* Metode "FL" */
+ } else if (metode == LC_U_FLERE) {
+ /* Teller opp antall av dette SOSI-navnet */
+ tilslag = 0;
+ while ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+ tilslag++;
+ /* Tilslag hvis navnet finnes mer enn 1 gang */
+ if (tilslag > 1) return UT_TRUE;
+ (*gilin)++;
+ }
+
+ /* Metode "!FL" */
+ } else if (metode == LC_U_IKKEFLERE) {
+ /* Teller opp antall av dette SOSI-navnet */
+ lMaxAntall = max(atol(pUE->min),1l);
+ tilslag = 0;
+ while ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+ tilslag++;
+ /* Har flere forekomster, avbryter */
+ if (tilslag > lMaxAntall) return UT_FALSE;
+ (*gilin)++;
+ }
+ /* Tilslag, ikke flere forekomster */
+ return UT_TRUE;
+
+ /* Metode "AL" */
+ } else if (metode == LC_U_ALLE) {
+ if ((*apara = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) {
+ return UT_TRUE;
+ }
+
+ /* Metode IKKE VALGT "IV" */
+ } else if (metode == LC_U_IKKEVALGT) {
+ if (! pUtAdm->sGruppeValgt)
+ return UT_TRUE;
+
+ /* Metode IKKE LIK "!=" */
+ } else if (metode == LC_U_IKKELIK) {
+ tilslag = 0;
+ pUE->metode = LC_U_LIK; /* Sjekker først på likhet */
+ while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ tilslag = 1;
+ break; /* Vet nå at det ikke blir tilslag, hopper ut */
+ }
+ (*gilin)++;
+ }
+ pUE->metode = LC_U_IKKELIK;
+ if (! tilslag) /* Tilslag når "=-testen" ikke ga tilslag */
+ return UT_TRUE;
+
+ /* Metode INNEHOLDER IKKE "!()" */
+ } else if (metode == LC_U_IKKECONTEIN) {
+ tilslag = 0;
+ pUE->metode = LC_U_CONTEIN; /* Sjekker først INNEHOLDER */
+ while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ tilslag = 1;
+ break; /* Vet nå at det ikke blir tilslag, hopper ut */
+ }
+ (*gilin)++;
+ }
+ pUE->metode = LC_U_IKKECONTEIN;
+ if (! tilslag) /* Tilslag når "=-testen" ikke ga tilslag */
+ return UT_TRUE;
+
+
+ /* Andre utvalgsmetoder */
+ } else {
+ while ((para = LC_GetGP(pUE->sosi,gilin,9999)) != NULL) { /* Hent parameter */
+ if (LU_ParaTest(pUE,para,akt_para,U_PARA_LEN)) { /* Tilslag? */
+ return UT_TRUE;
+ }
+ (*gilin)++;
+ }
+ }
+
+ return 0; /* Ikke tilslag */
+}
+
+
+/*
+AR:2006-08-08
+CH LU_ParaTest Sjekk parameter for tilslag
+CD =============================================================================
+CD Formål:
+CD Sjekk om parameteren tilfredsstiller denne utvalgslinjen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_UTVALG_ELEMENT * pUE i Peker til utvalgslinje
+CD char *para i Peker til parameterstreng
+CD char *akt_para i Aktuell del av parameterstrengen.
+CD short sMaxLen i Maks lengde for akt_para
+CD short tilslag r Status: 1=tilslag, 0=ikke tilslag
+CD
+CD Bruk:
+CD tilslag = LU_ParaTest(pUE,para,&akt_para,sMaxLen);
+ =============================================================================
+*/
+static short LU_ParaTest(LC_UTVALG_ELEMENT * pUE,char *para,char *pszAktPara,short sMaxLen)
+{
+ long heltall;
+ double flyttall,desimal;
+ short metode = pUE->metode;
+
+
+ /* Juster for ledd, og del av streng
+ * når dette er gitt som del av utvalgslinjen
+ * (og ikke som del av SOSI-navnet)
+ */
+ if((pUE->ledd > 0) || (pUE->start > 0) || (pUE->slutt > 0)) { // Ledd eller del av streng er angitt utenfor SOSI-navnet
+ LU_JustPara(para,(short)pUE->ledd,(short)pUE->start,(short)pUE->slutt,
+ pszAktPara,U_PARA_LEN);
+ }
+ else {
+ UT_StrCopy(pszAktPara,para,sMaxLen);
+ }
+
+ // Sjekk først at sammenligningen kan gjøres med aktuell talltype
+ short type = pUE->type;
+ if ((type & LC_U_TALL) == LC_U_TALL)
+ {
+ heltall = atol(pszAktPara); // OBS! Denne brukes i selve sammenligningen lenger nede i koden
+ if (heltall == LONG_MIN || heltall == LONG_MAX)
+ {
+ // Tallet har for mange siffer, må håndtere sammenligningen som tekst
+ type = LC_U_ALFA;
+ }
+ }
+
+ // ----- Utfør testen
+ switch (metode) {
+ case LC_U_LIK: /* Lik "=" */
+ if ((type & LC_U_TALL) == LC_U_TALL){ /* Heltall */
+ if (heltall == atol(pUE->min) )
+ return (1);
+ } else if ((type & LC_U_FLYT) == LC_U_FLYT){ /* Flyttall */
+ if (atof(pszAktPara) == atof(pUE->min) )
+ return (1);
+ } else{ /* Streng */
+ UT_StrUpper(pszAktPara);
+ if (strcmp(pszAktPara,pUE->min) == 0)
+ return (1);
+ }
+ break;
+
+ case LC_U_FRATIL: /* Fra - til "<>" */
+ if ((type & LC_U_TALL) == LC_U_TALL){ /* Heltall */
+ if (heltall >= atol(pUE->min) && heltall <= atol(pUE->max))
+ return (1);
+ } else if ((type & LC_U_FLYT) == LC_U_FLYT){ /* Flyttall */
+ flyttall = atof(pszAktPara);
+ if (flyttall >= atof(pUE->min) && flyttall <= atof(pUE->max))
+ return (1);
+ } else{ /* Streng */
+ UT_StrUpper(pszAktPara);
+ if (strcmp(pszAktPara,pUE->min) >= 0 && strcmp(pszAktPara,pUE->max) <= 0)
+ return (1);
+ }
+ break;
+
+ case LC_U_DELELIG: /* Delelig "/" */
+ // 2001-03-19: Endret slik at algoritmen for desimaltall alltid brukes.
+ //if (type == U_FLYT){ /* Flyttall */
+ desimal = modf(atof(pszAktPara) / atof(pUE->min), &flyttall);
+ if (fabs(fabs(desimal*atof(pUE->min)) - fabs(atof(pUE->max))) < 1.0E-6) {
+ return (1);
+ }
+
+ //} else{ /* Heltall eller streng */
+ // if ((atol(pszAktPara) % atol(pUE->min)) == atol(pUE->max)) {
+ // return (1);
+ // }
+ //}
+ break;
+
+ case LC_U_UDELELIG: /* Ikke delellig "!/" */
+ // 2001-03-19: Endret slik at algoritmen for desimaltall alltid brukes.
+ //if (type == U_FLYT){ /* Flyttall */
+ desimal = modf(atof(pszAktPara) / atof(pUE->min), &flyttall);
+ if (fabs(desimal) >= 1.0E-6)
+ return (1);
+
+ //} else{ /* Heltall eller streng */
+ // if ((atol(pszAktPara) % atol(pUE->min)) != 0L)
+ // return (1);
+ //}
+ break;
+
+ case LC_U_CONTEIN: /* Inneholder "()" */
+ UT_StrUpper(pszAktPara);
+ if (strstr(pszAktPara,pUE->min) != NULL)
+ return (1);
+ break;
+
+ case LC_U_UTENFOR: /* Utenfor "><" */
+ if ((type & LC_U_TALL) == LC_U_TALL){ /* Heltall */
+ if (heltall < atol(pUE->min) || heltall > atol(pUE->max))
+ return (1);
+ } else if ((type & LC_U_FLYT) == LC_U_FLYT){ /* Flyttall */
+ flyttall = atof(pszAktPara);
+ if (flyttall < atof(pUE->min) || flyttall > atof(pUE->max))
+ return (1);
+ } else{ /* Streng */
+ UT_StrUpper(pszAktPara);
+ if (strcmp(pszAktPara,pUE->min) < 0 || strcmp(pszAktPara,pUE->max) > 0)
+ return (1);
+ }
+ break;
+
+ case LC_U_MINDRE: /* Mindre enn "<" */
+ if ((type & LC_U_TALL) == LC_U_TALL){ /* Heltall */
+ if (heltall < atol(pUE->min))
+ return (1);
+ } else if ((type & LC_U_FLYT) == LC_U_FLYT){ /* Flyttall */
+ if (atof(pszAktPara) < atof(pUE->min))
+ return (1);
+ } else{ /* Streng */
+ UT_StrUpper(pszAktPara);
+ if (strcmp(pszAktPara,pUE->min) < 0)
+ return (1);
+ }
+ break;
+
+ case LC_U_STORRE: /* Større enn ">" */
+ if ((type & LC_U_TALL) == LC_U_TALL){ /* Heltall */
+ if (heltall > atol(pUE->min))
+ return (1);
+ } else if ((type & LC_U_FLYT) == LC_U_FLYT){ /* Flyttall */
+ if (atof(pszAktPara) > atof(pUE->min))
+ return (1);
+ } else{ /* Streng */
+ UT_StrUpper(pszAktPara);
+ if (strcmp(pszAktPara,pUE->min) > 0)
+ return (1);
+ }
+ break;
+ }
+
+ return (0); /* Ikke tilslag */
+}
+
+
+/*
+AR-891206
+CH LU_JustPara Juster parameter for ledd og posisjon
+CD =============================================================================
+CD Formål:
+CD Juster parameteren for leddnummer og del av streng.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *para i Parameterstreng som skal behandles
+CD short ledd i Leddnummer
+CD short start i Startposisjon i strengen (0=hele strengen)
+CD short slutt i Sluttposisjon i strengen (0=resten)
+CD char *akt_para iu Ny behandla parameterstreng
+CD short max_len i Max lengde på akt_para
+CD
+CD Bruk:
+CD LU_JustPara(para,ledd,start,slutt,akt_para,max_len);
+ =============================================================================
+*/
+static void LU_JustPara(char *para,short ledd,short start,short slutt,
+ char *akt_para,short max_len)
+{
+ char *cp,*nt;
+ /* Juster for ledd */
+ cp = UT_strtok(para," ",&nt);
+ while(cp != NULL && --ledd > 0){
+ cp = UT_strtok(NULL," ",&nt);
+ }
+
+ /* Juster for delstreng */
+ if (cp != NULL){
+ if (start != 0){
+ if (slutt != 0){
+ slutt = min(slutt,((short)strlen(cp)));
+ *(cp+slutt) = '\0';
+ }
+ start = min(start,((short)strlen(cp)));
+ cp += (start-1);
+ }
+ UT_StrCopy(akt_para,cp,max_len);
+
+ } else{
+ *akt_para = '\0';
+ }
+}
+
+
+/*
+AR-891207
+CH LC_QueryGP Søk i ginfo og finn verdi
+CD =============================================================================
+CD Formål:
+CD Bruker query-tekst for å finne linje der parameter skal hentes.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD char *qulin i Linje med query-tekst.
+CD unsigned short iniv i Nivå: Det er definert konstanter som henges
+CD sammen med "|".
+CD LC_GINFO = søk i GINFO på aktuell gruppe
+CD LC_HODE = søk i filhodet
+CD Hvis begge er brukt søkes det først i GINFO.
+CD unsigned short *univ u Nivå: LC_GINFO = parameter er fra GINFO
+CD LC_HODE = parameter er fra filhodet
+CD short *ulin u GINFO-linjenummer for tilslaget.
+CD char **para u Funnet parameter.
+CD short funnet r Status: UT_TRUE=funnet, UT_FALSE=ikke funnet
+CD
+CD Bruk:
+CD funnet = LC_QueryGP(qulin,LC_GINFO | LC_HODE,&univ,&ulin,&para);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_QueryGP(char *qulin,unsigned short iniv,unsigned short *univ,short *ulin,char **para)
+{
+ LC_BGR Bgr,Hode;
+ short ngi;
+ long nko;
+ unsigned short info;
+ short sFunnet = UT_FALSE;
+ LC_UT_ADM *pUtAdm;
+
+ /* Åpne query */
+ pUtAdm = LC_OpenQuery();
+ /* Tolk linjen */
+ if (LC_PutQueryLine(pUtAdm,qulin,U_GRUPPE)) {
+ LC_PutQueryRegel(pUtAdm->Gruppe.pSisteU,"S");
+
+ /* Sjekk GINFO */
+ /* Initier søk */
+ pUtAdm->Gruppe.pAktU = pUtAdm->Gruppe.pForsteU;
+ pUtAdm->sGruppeValgt = UT_FALSE;
+
+ /* Søk */
+ sFunnet = LU_GiTestLinje(pUtAdm,pUtAdm->Gruppe.pForsteU->pForsteUE,ulin,para);
+ *univ = LC_GINFO;
+
+ /*
+ * Ikke funnet, og konstant er satt for at hodet skal sjekkes.
+ * Sjekk hodet.
+ */
+ if ( (! sFunnet) && (iniv & LC_HODE)) {
+ LC_GetGrNr(&Bgr); /* Husk aktuell gruppe */
+ Hode.pFil = Bgr.pFil;
+ Hode.lNr = 0L;
+ /* Les filhode */
+ LC_RxGr(&Hode,LES_OPTIMALT,&ngi,&nko,&info);
+
+ /* Initier søk */
+ pUtAdm->Gruppe.pAktU = pUtAdm->Gruppe.pForsteU;
+ pUtAdm->sGruppeValgt = UT_FALSE;
+
+ /* Søk */
+ sFunnet = LU_GiTestLinje(pUtAdm,pUtAdm->Gruppe.pForsteU->pForsteUE,ulin,para);
+ *univ = LC_HODE;
+
+ /* Les tilbake opprinnelig gruppe */
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+ }
+
+ LC_CloseQuery(pUtAdm);
+ return sFunnet;
+}
+
+
+/*
+AR-920524
+CH LU_LesULinje Les en utvalgs-linje fra kommandofilen
+CD ==========================================================================
+CD Formål:
+CD Les en utvalgs-linje fra kommandofilen.
+CD
+CD Parameters:
+CD Type Name I/O Forklaring
+CD ----------------------------------------------------------------
+CD FILE *pKomFil i Filpeker for beskrivelsesfil
+CD short sMaxTxLen i Max lengde av pszTx
+CD char *pszTx i Lest linje
+CD short *psNiv u Nivå (antall prikker forran navnet)
+CD short lesefeil r Lesefeil fra UT_ReadLine.
+CD
+CD Bruk:
+CD lesefeil = LU_LesULinje(pFil,sMaxTxLen,pszTx,&sNiv);
+CD =============================================================================
+*/
+static short LU_LesULinje(FILE *pKomFil,short sMaxTxLen,char *pszTx,
+ short *psNiv)
+{
+ char szLinje[100],*cp;
+ short lesefeil;
+
+ if (!(lesefeil = UT_ReadLineNoComm(pKomFil,100,szLinje))) {
+
+ cp = szLinje;
+
+ /* Hopp over ledende blanke */
+ while (UT_IsSpace(*cp)) {
+ cp++;
+ }
+
+ /* Tell opp antall prikker */
+ *psNiv = 0;
+ while (*cp == '.') {
+ (*psNiv)++;
+ cp++;
+ }
+
+ /* Kopier ut linjen */
+ UT_StrCopy(pszTx,cp,sMaxTxLen);
+ }
+
+ return lesefeil;
+}
+
+
+/*
+AR-920524
+CH LU_AppUtvalg Legg til et nytt utvalg
+CD ==========================================================================
+CD Formål:
+CD Legg til et nytt utvalg i en av kjedene av utvalg.
+CD
+CD Parametre:
+CD Type Navn I/O Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UTVALG_BLOKK *pUtBlokk i Toppblokk for aktuell utvalgstype.
+CD char *pszNavn i Utvalgsnavn
+CD
+CD Bruk:
+CD LU_AppUtvalg(pUtAdm->pGruppe,szNavn);
+CD =============================================================================
+*/
+static void LU_AppUtvalg (LC_UTVALG_BLOKK *pUB,char *pszNavn)
+{
+ LC_UTVALG * pU;
+
+ /* Alloker minne og initier */
+ pU = (LC_UTVALG *)UT_MALLOC(sizeof(LC_UTVALG));
+ memset(pU, 0, sizeof(LC_UTVALG));
+
+ pU->sPrioritet = 0;
+ pU->sOriginalPrioritet = 0;
+ pU->sStatus = LC_UFORANDRET;
+ pU->sTegnes = 1;
+ pU->pszNavn = (char*)UT_MALLOC(strlen(pszNavn)+1);
+ UT_StrCopy(pU->pszNavn, pszNavn, strlen(pszNavn)+1);
+ pU->pszRegel = NULL;
+
+ pU->pForsteUE = NULL;
+ pU->pSisteUE = NULL;
+ pU->pForrigeU = NULL;
+ pU->pNesteU = NULL;
+
+ /* Første */
+ if (pUB->pForsteU == NULL) {
+ pUB->pForsteU = pU;
+ pUB->pSisteU = pU;
+
+ } else {
+ pU->pForrigeU = pUB->pSisteU;
+ pUB->pSisteU->pNesteU = pU;
+ pUB->pSisteU = pU;
+ }
+
+ return;
+}
+
+
+/*
+AR-920402
+CH LC_InqMaxPrioritet Hent største prioritet
+CD ==========================================================================
+CD Formål:
+CD Henter største prioritet for gitt utvalgstype.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ----------------------------------------------------------------------
+CD LC_UT_ADM * pUA i Peker til administrasjonsblokk for utvalg.
+CD short sMaxPrioritet r Max prioritet
+CD
+CD Bruk:
+CD sMaxPrioritet = LC_InqMaxPrioritet(pUA);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_InqMaxPrioritet(LC_UT_ADM * pUA)
+{
+ if (pUA != NULL)
+ {
+ return pUA->sMaxPrior;
+ }
+
+ return 0;
+}
+
+
+/*
+AR-920814
+CH LC_TestPrioritetBrukt Tester om en prioritet er brukt
+CD ==========================================================================
+CD Formål:
+CD Tester om en prioritet er brukt.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD short sPrioritet i Prioritet som skal testes.
+CD short sBrukt r Status: UT_TRUE=brukt, UT_FALSE=ikke brukt.
+CD
+CD Bruk:
+CD sBrukt = LC_TestPrioritetBrukt(pUtAdm,sPrioritet);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestPrioritetBrukt(LC_UT_ADM * pUtAdm,short sPrioritet)
+{
+ LC_UTVALG * pU;
+
+
+ if (pUtAdm != NULL)
+ {
+ /*
+ * Test GRUPPE-UTVALG.
+ */
+ for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) return UT_TRUE; /* ==> Funnet */
+ }
+
+ /*
+ * Test PUNKT-UTVALG.
+ */
+ for (pU=pUtAdm->Punkt.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) return UT_TRUE; /* ==> Funnet */
+ }
+
+ /*
+ * Test PINFO-UTVALG.
+ */
+ for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) return UT_TRUE; /* ==> Funnet */
+ }
+ }
+
+ return UT_FALSE; /* ==> Ikke funnet */
+}
+
+
+/*
+AR-940110
+CH LU_PakkPrioritet Pakker prioriteten
+CD ==========================================================================
+CD Formål:
+CD Pakker prioriteten.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LU_PakkPrioritet(pUtAdm);
+ ==========================================================================
+*/
+static void LU_PakkPrioritet(LC_UT_ADM * pUtAdm)
+{
+ LC_UTVALG * pU;
+ short s,sFerdig;
+ short NyPrior[LC_MAX_ANT_PRIOR];
+ short sAntNyPrior = 0;
+
+
+ if (pUtAdm != NULL)
+ {
+ /*
+ * Bygger opp tabell over hvilke prioriteter som er brukt.
+ */
+
+ /* GRUPPE-UTVALG. */
+ for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+ }
+ /* PUNKT-UTVALG. */
+ for (pU=pUtAdm->Punkt.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+ }
+ /* PINFO-UTVALG. */
+ for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ LU_HuskPrior(NyPrior,&sAntNyPrior,pU->sPrioritet);
+ }
+
+ /* Sorter prioritetene */
+ qsort(NyPrior,sAntNyPrior,sizeof(short),LU_compare);
+
+
+ /*
+ * Legg inn nye prioriteter.
+ */
+
+ /* GRUPPE-UTVALG. */
+ for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ sFerdig = UT_FALSE;
+ for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+ if (NyPrior[s] == pU->sPrioritet) {
+ pU->sPrioritet = s;
+ sFerdig = UT_TRUE;
+ }
+ }
+ }
+ /* PUNKT-UTVALG. */
+ for (pU=pUtAdm->Punkt.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ sFerdig = UT_FALSE;
+ for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+ if (NyPrior[s] == pU->sPrioritet) {
+ pU->sPrioritet = s;
+ sFerdig = UT_TRUE;
+ }
+ }
+ }
+ /* PINFO-UTVALG. */
+ for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ sFerdig = UT_FALSE;
+ for (s=0; sFerdig==UT_FALSE && s<sAntNyPrior; s++) {
+ if (NyPrior[s] == pU->sPrioritet) {
+ pU->sPrioritet = s;
+ sFerdig = UT_TRUE;
+ }
+ }
+ }
+
+ /* Oppdaterer max prioritet */
+ pUtAdm->sMaxPrior = sAntNyPrior-1;
+ }
+
+ return;
+}
+
+
+/* ===================================================== */
+int LU_compare (const void *arg1, const void *arg2)
+ {
+ if (*(short*)arg1 == *(short*)arg2) return 0;
+ if (*(short*)arg1 < *(short*)arg2) return -1;
+ return 1;
+ }
+
+
+/*
+AR-940110
+CH LU_HuskPrior Legg inn prioritet i tabellen
+CD ==========================================================================
+CD Formål:
+CD Legg inn prioritet i tabellen
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short *NyPrior iu Tabell over nye prioriteter
+CD short *sAntPrior iu Antall brukt i NyPrior
+CD short sPrior i Prioritet som skal legges inn.
+CD
+CD
+CD Bruk:
+CD LU_HuskPrior(NyPrior,&sAntPrior,pU->sPrioritet);
+ ==========================================================================
+*/
+static void LU_HuskPrior(short *NyPrior,short *sAntPrior,short sPrior)
+{
+ short s;
+ char szTx[10];
+
+ for (s=0; s<*sAntPrior; s++) {
+ if (sPrior == NyPrior[s]) {
+ return; /* ==> Prioriteten er brukt før, returner */
+ }
+ }
+
+ if (*sAntPrior >= LC_MAX_ANT_PRIOR) {
+ UT_SNPRINTF(szTx,10,"%hd",sPrior);
+ LC_Error(127,"(LU_HuskPrior)",szTx);
+
+ } else {
+ /* Ny prioritet, husk denne */
+ NyPrior[*sAntPrior] = sPrior;
+ (*sAntPrior)++;
+ }
+
+ return;
+}
+
+
+/*
+AR: 1999-11-20
+CH LC_LoggPrioritetUtvalg Skriver prioritetsoversikt
+CD ==========================================================================
+CD Formål:
+CD Skriver oversikt over prioriteter og utvalg til log-filen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_UT_ADM * pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LC_LoggPrioritetUtvalg(pUtAdm);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_LoggPrioritetUtvalg(LC_UT_ADM * pUtAdm)
+{
+ if (pUtAdm != NULL)
+ {
+ short sMaxPrioritet = LC_InqMaxPrioritet(pUtAdm);
+ short sPrioritet;
+ LC_UTVALG * pU;
+ short sG = 0;
+ short sP = 0;
+
+ UT_FPRINTF(stderr,"\n\n***** Prioriteter og utvalg *****\n");
+
+ for (sPrioritet=0; sPrioritet<sMaxPrioritet; sPrioritet++) {
+
+ UT_FPRINTF(stderr,"\nPrioritet: %hd\n",sPrioritet);
+
+ /* GRUPPE-UTVALG. */
+ for (pU=pUtAdm->Gruppe.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) {
+ UT_FPRINTF(stderr," Gruppeutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+ sG++;
+ }
+ }
+
+ /* PUNKT-UTVALG. */
+ for (pU=pUtAdm->Punkt.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) {
+ UT_FPRINTF(stderr," Punktutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+ sP++;
+ }
+ }
+
+ /* PINFO-UTVALG. */
+ #ifdef TEST
+ for (pU=pUtAdm->Pinfo.pForsteU; pU != NULL; pU = pU->pNesteU) {
+ if (sPrioritet == pU->sPrioritet) {
+ UT_FPRINTF(stderr," Pinfoutvalg: %s (%hd) \n",pU->pszNavn ,pU->sOriginalPrioritet);
+ }
+ }
+ #endif
+ }
+
+ UT_FPRINTF(stderr,"\nTotalt %hd gruppeutvalg, og %hd punktutvalg.\n",sG,sP);
+ }
+}
+
+
+/*
+AR-940110
+CH LC_UtvalgPrioritet Finn brukt prioritet
+CD ==========================================================================
+CD Formål:
+CD Sjekker GINFO og PINFO for å finne hvilke prioriteter som "berører" aktuell
+CD gruppe. Resultatet markeres i Gruppetabellen ulPrior.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD LC_UT_ADM *pUtAdm i Peker til administrasjonsblokk for utvalg.
+CD
+CD Bruk:
+CD LC_UtvalgPrioritet(pUtAdm);
+ ===========================================================================
+*/
+SK_EntPnt_FYBA void LC_UtvalgPrioritet(LC_UT_ADM *pUtAdm)
+{
+ long lPnr;
+ short sPrior,sKolonne;
+ LC_UTVALG * pU;
+ unsigned long ulPrioritet[4];
+
+
+ if (pUtAdm != NULL)
+ {
+ ulPrioritet[0] = 0x00000000UL;
+ ulPrioritet[1] = 0x00000000UL;
+ ulPrioritet[2] = 0x00000000UL;
+ ulPrioritet[3] = 0x80000000UL; /* Info er bygd opp */
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+
+ /*
+ * GINFO
+ */
+
+ /* Initier søk */
+ pU = pUtAdm->Gruppe.pForsteU;
+ pUtAdm->sGruppeValgt = UT_FALSE;
+
+ /* Søk */
+ while (pU != NULL) {
+
+ sKolonne = pU->sPrioritet / 32;
+ sPrior = pU->sPrioritet % 32;
+
+ /* Hvis vi har tilslag på denne prioriteten trenger vi ikke å sjekke dette utvalget */
+ if ((ulPrioritet[sKolonne] & (0x1UL << sPrior)) == 0UL) {
+
+ if (LU_GiTestUtvalg(pUtAdm,pU)) {
+ /* Tilslag */
+ pUtAdm->sGruppeValgt = UT_TRUE;
+
+ /* Husk at prioriteten er brukt */
+ ulPrioritet[sKolonne] |= (0x1UL << sPrior);
+ }
+ }
+
+ /* Fortsett med neste utvalg */
+ pU = pU->pNesteU;
+ }
+
+
+ /*
+ * PINFO
+ *
+ * Sjekker bare hvis :
+ * - utvalgsmetode "!" (ikke) er brukt,
+ * - gruppen har PINFO
+ * - gruppen har KP
+ * - gruppen har høyde
+ */
+
+ if (pUtAdm->Punkt.sTestAllePi == UT_TRUE ||
+ Sys.pGrInfo->info & GI_PINFO ||
+ Sys.pGrInfo->info & GI_KP ||
+ Sys.pGrInfo->info & GI_NAH) {
+
+ for (lPnr=1; lPnr<=Sys.pGrInfo->nko; ++lPnr) {
+ /* Initier søk */
+ /* Utvalgsmetode "!" (ikke) er brukt, eller
+ punktet har PINFO mm. */
+ if (pUtAdm->Punkt.sTestAllePi == UT_TRUE ||
+ LC_TestPi(lPnr,pUtAdm->Punkt.sHoydeBrukt)) {
+ pU = pUtAdm->Punkt.pForsteU;
+ } else {
+ pU = NULL;
+ }
+
+ /* Søk */
+ while (pU != NULL) {
+
+ sKolonne = pU->sPrioritet / 32;
+ sPrior = pU->sPrioritet % 32;
+
+ /* Hvis vi har tilslag på denne prioriteten trenger vi ikke å sjekke dette utvalget */
+ if ((ulPrioritet[sKolonne] & (0x1UL << sPrior)) == 0UL) {
+
+ if (LC_PiTestUtvalg(pUtAdm,pU,lPnr)) {
+ /* Tilslag */
+ /* Husk at prioriteten er brukt */
+ ulPrioritet[sKolonne] |= (0x1UL << sPrior);
+ }
+ }
+
+ /* Fortsett med neste utvalg */
+ pU = pU->pNesteU;
+ }
+ }
+ }
+
+ Sys.pGrInfo->ulPrior[0] = ulPrioritet[0];
+ Sys.pGrInfo->ulPrior[1] = ulPrioritet[1];
+ Sys.pGrInfo->ulPrior[2] = ulPrioritet[2];
+ Sys.pGrInfo->ulPrior[3] = ulPrioritet[3];
+ }
+ }
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErLik_Avrundet Rund av og sjekk om sammenfallende punkt
+CD ==========================================================================
+CD Formål:
+CD Runder av til valgt enhet, og sjekker om de to punktene er sammenfallende.
+CD (Avviket er mindre enn 1/10 enhet både nord og øst)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD double dA1 i P1
+CD double dN1 i
+CD double dA2 i P2
+CD double dN2 i
+CD double dEnhet i Enhet som skal brukes i sammenligningen
+CD bool bErLike r Status: true = Samme koordinat
+CD false = Ikke samme koordinat
+CD
+CD Bruk:
+CD bSammenfallende = LC_ErLik(dA1,dN1,dA2,dN2,dEnhet);
+ ===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErLik_Avrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet)
+{
+ // 2010-01-25: Endret fra UT_RoundDD til UT_RoundHalfUpDD
+ dA1 = UT_RoundHalfUpDD(dA1 / dEnhet) * dEnhet;
+ dN1 = UT_RoundHalfUpDD(dN1 / dEnhet) * dEnhet;
+ dA2 = UT_RoundHalfUpDD(dA2 / dEnhet) * dEnhet;
+ dN2 = UT_RoundHalfUpDD(dN2 / dEnhet) * dEnhet;
+
+ return ((fabs(dA1-dA2) < dEnhet/10.0) && (fabs(dN1-dN2) < dEnhet/10.0));
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErLik_IkkeAvrundet Sjekk om sammenfallende punkt (uten avrunding)
+CD ==========================================================================
+CD Formål:
+CD Sjekker om de to punktene er sammenfallende innen gitt nøyaktighet.
+CD Det skjer ingen avrunding av koordinatene før sammenligningen.
+CD (Avviket er mindre enn 1/10 enhet både nord og øst)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD double dA1 i P1
+CD double dN1 i
+CD double dA2 i P2
+CD double dN2 i
+CD double dEnhet i Enhet som skal brukes i sammenligningen
+CD bool bErLike r Status: true = Samme koordinat
+CD false = Ikke samme koordinat
+CD
+CD Bruk:
+CD bSammenfallende = LC_ErLik(dA1,dN1,dA2,dN2,dEnhet);
+ ===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErLik_IkkeAvrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet)
+{
+ return ((fabs(dA1-dA2) < dEnhet/10.0) && (fabs(dN1-dN2) < dEnhet/10.0));
+}
+
+
+/*
+AR:2007-08-23
+CH LC_ErReferert Sjekk om gruppe er referert
+CD ==========================================================================
+CD Formål:
+CD Sjekker om aktuell gruppe er referert fra andre grupper.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD bool bReferert r Det finnes referanser til gruppen
+CD
+CD Bruk:
+CD bReferert = LC_ErReferert();
+===========================================================================
+*/
+SK_EntPnt_FYBA bool LC_ErReferert(void)
+{
+ LC_BGR FlateBgr;
+ double a,n;
+ LC_GEO_STATUS GeoStat;
+ short ngi;
+ long nko;
+ unsigned short info;
+ long lAntRef;
+ short sGiLin,sRefPos;
+ long *plRefArray,*plRef;
+ long l;
+
+ bool bReferert = false;
+
+ /* Husk gruppen */
+ LC_FILADM *pFil = Sys.GrId.pFil;
+ LC_BGR Bgr = Sys.GrId;
+ long lGmlSnr = LC_GetSn();
+
+ LC_GetTK(1,&a,&n);
+ LC_SBFlate(&GeoStat,LC_FRAMGR,a-0.1,n-0.1,a+0.1,n+0.1);
+ 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));
+ sGiLin = 2;
+ sRefPos = 0;
+ LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+ plRef = plRefArray;
+ for (l=0; (!bReferert) && l<lAntRef; l++) {
+ if (labs(*plRef) == lGmlSnr) {
+ bReferert = true;
+ }
+ ++plRef;
+ }
+
+ UT_FREE(plRefArray);
+ }
+ } while ((!bReferert) && LC_FNFlate(&GeoStat,&FlateBgr));
+ }
+ LC_AvsluttSok(&GeoStat);
+
+ // Leser inn opprinnelig gruppe igjen
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ return bReferert;
+}
+
+/*
+AR:2009-04-28
+CH LC_ErReferertFraAntall Tell antall referanser til gruppe
+CD ==========================================================================
+CD Formål:
+CD Tell antall referanser til aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ---------------------------------------------------------------------------
+CD long lAntall r Antall grupper som refererer gruppen
+CD
+CD Bruk:
+CD lAntall = LC_ErReferertFraAntall();
+===========================================================================
+*/
+SK_EntPnt_FYBA long LC_ErReferertFraAntall(void)
+{
+ LC_BGR FlateBgr;
+ double a,n;
+ LC_GEO_STATUS GeoStat;
+ short ngi;
+ long nko;
+ unsigned short info;
+ long lAntRef;
+ short sGiLin,sRefPos;
+ long *plRefArray,*plRef;
+ long l;
+
+ long lAntall = 0;
+
+ /* Husk gruppen */
+ LC_FILADM *pFil = Sys.GrId.pFil;
+ LC_BGR Bgr = Sys.GrId;
+ long lGmlSnr = LC_GetSn();
+
+ LC_GetTK(1,&a,&n);
+ LC_SBFlate(&GeoStat,LC_FRAMGR,a-0.1,n-0.1,a+0.1,n+0.1);
+ 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));
+ sGiLin = 2;
+ sRefPos = 0;
+ LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+
+ plRef = plRefArray;
+ for (l=0; l<lAntRef; l++) {
+ if (labs(*plRef) == lGmlSnr) {
+ ++lAntall;
+ }
+ ++plRef;
+ }
+
+ UT_FREE(plRefArray);
+ }
+ } while (LC_FNFlate(&GeoStat,&FlateBgr));
+ }
+ LC_AvsluttSok(&GeoStat);
+
+ // Leser inn opprinnelig gruppe igjen
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ return lAntall;
+}
diff --git a/src/FYBA/FYLX.cpp b/src/FYBA/FYLX.cpp
new file mode 100644
index 0000000..7d2418a
--- /dev/null
+++ b/src/FYBA/FYLX.cpp
@@ -0,0 +1,4948 @@
+/* === AR-911003 ============================================================ */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fylx.c */
+/* Innhold: Put og get rutiner til RB */
+/* ========================================================================== */
+
+#include "stdafx.h"
+
+#include <math.h>
+
+#include <ctype.h>
+#include <limits.h>
+
+
+/* Globale variabler for FYBA */
+extern LC_SYSTEMADM Sys; /* Systemadministrasjon */
+extern char retur_str[LC_MAX_SOSI_LINJE_LEN]; /* Returstreng */
+
+/* Statiske variabler */
+
+/* Lokale rutiner */
+static long LX_GetRefOmkrets(LC_GR_STATUS *pGRS,long *ref_array,
+ unsigned char *ref_status,long max_ref);
+static long LX_GetRefOy(LC_GRF_STATUS * pGS,long *ref_array,
+ unsigned char *ref_status,long max_ref);
+static void LX_CreatePibuf(long lPnr);
+static double LX_ArealGruppe(LC_BGR * pBgr,short retning);
+static void LX_PutGi(short lin_nr, const char *szGinfo);
+
+
+/*
+AR-920921
+CH LC_InitGetRefFlate Initierer status for GetRefFlate
+CD ==========================================================================
+CD Formål:
+CD Initierer status for GetRefFlate.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GRF_STATUS * pRefStat iu Struktur med statusopplysninger.
+CD
+CD Bruk:
+CD LC_InitGetRefFlate(pGrfStat,pBgr);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitGetRefFlate(LC_GRF_STATUS * pGS)
+{
+ pGS->Omkr.sGiLinNr = 2;
+ pGS->Omkr.sRefPos = 0;
+ pGS->Omkr.sRefLin = UT_FALSE;
+
+ pGS->usOmkretsFerdig = UT_FALSE;
+
+ pGS->Bgr.pFil = NULL;
+ pGS->Bgr.lNr = INGEN_GRUPPE;
+}
+
+
+/*
+AR-920930
+CH LC_GetRefFlate Hent referanser for flate fra GINFO
+CD ==========================================================================
+CD Formål:
+CD Henter ut et array med referanser for flate fra GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -------------------------------------------------------------------------
+CD LC_GRF_STATUS * GrfStat iu Struktur med statusopplysninger.
+CD unsigned short usHent i Hva skal hentes:
+CD GRF_YTRE = Ytre avgrensing
+CD GRF_INDRE = Indre avgrensing, øyer
+CD (kan kombineres med | (or).)
+CD long *ref_array u GRUPPENUMMER for refererte grupper.
+CD unsigned char *ref_status u Status for gruppene i ref_array.
+CD LC_MED_DIG = Brukes MED dig retning.
+CD LC_MOT_DIG = Brukes MOT dig retning.
+CD GRF_START_OY = Første gruppe i øy
+CD GRF_SLUTT_OY = Siste gruppe i øy
+CD long max_ref i Max antall linjer i ref_array og ref_status.
+CD long ant_ref r Antall linjer brukt i ref_array.
+CD 0 viser at hele flata er behandla.
+CD
+CD Bruk:
+CD #define MAX_REF 20
+CD long ref_arr[MAX_REF];
+CD char ref_status[MAX_REF];
+CD long ant_ref;
+CD LC_GRF_STATUS GrfStat;
+CD
+CD LC_InitGetRefFlate(&GrfStat);
+CD
+CD ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+CD do {
+CD if (ant_ref > 0) {
+CD .
+CD Behandle ytre avgrensing
+CD .
+CD }
+CD
+CD [if (ant_ref < MAX_REF) break;]
+CD
+CD ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REF);
+CD } while (ant_ref > 0);
+CD
+CD LC_InitGetRefFlate(&GrfStat);
+CD ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REF);
+CD do {
+CD if (ant_ref > 0) {
+CD .
+CD Behandle indre avgrensing (øy)
+CD .
+CD }
+CD
+CD [if (ant_ref < MAX_REF) break;]
+CD
+CD ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REF);
+CD } while (ant_ref > 0);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetRefFlate(LC_GRF_STATUS * GrfStat,unsigned short usHent,long *ref_array,
+ unsigned char *ref_status,long max_ref)
+{
+ long antall;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ if ((usHent & GRF_YTRE) && GrfStat->usOmkretsFerdig == UT_FALSE) {
+ /* Ytre avgrensning */
+ antall = LX_GetRefOmkrets(&GrfStat->Omkr,ref_array,ref_status,max_ref);
+ if (antall > 0) {
+ return antall;
+ }
+
+ /* Ferdig med behandling av omkretsen */
+ GrfStat->usOmkretsFerdig = UT_TRUE;
+ }
+
+ if (usHent & GRF_INDRE) {
+ /* Indre avgrensning (øy) */
+ return LX_GetRefOy(GrfStat,ref_array,ref_status,max_ref);
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+AR-920930
+CH LX_GetRefOmkrets Hent referanser for omkretsen
+CD ==========================================================================
+CD Formål:
+CD Henter ut et array med referanser for omkretsen av flate.
+CD ant_ref == 0 eller ant_ref < max_ref viser at hele omkretsen er behandla.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GR_STATUS *pGRS iu Struktur med statusopplysninger.
+CD long *ref_array u GRUPPENUMMER for refererte grupper.
+CD unsigned char *ref_status u Status for gruppene i ref_array.
+CD LC_MED_DIG = Brukes MED dig retning
+CD LC_MOT_DIG = Brukes MOT dig retning
+CD long max_ref i Max antall linjer i ref_array.
+CD short ant_ref r Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD ant_ref = LX_GetRefOmkrets(&OmkrStat,ref_array,ref_status,max_ref);
+CD ==========================================================================
+*/
+static long LX_GetRefOmkrets(LC_GR_STATUS *pGRS,long *ref_array,
+ unsigned char *ref_status,long max_ref)
+{
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long snr,grnr;
+ long ant_ref = 0;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Finn referanser */
+ while (pGRS->sGiLinNr <= Sys.pGrInfo->ngi) {
+ gp = LX_GetGi(pGRS->sGiLinNr);
+
+ /* Handter referanselinjer */
+ if ((pGRS->sRefLin = LC_ErLinjeRefLin(gp,pGRS->sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo + pGRS->sRefPos;
+ pGRS->sRefPos = 0;
+ while (*gp){ /* Tolk en linje */
+ if (ant_ref < max_ref) {
+ if (*gp == ':') { /* Tall */
+ ++gp;
+ /* Husk retning */
+ if (*gp == '-') {
+ *ref_status++ = LC_MOT_DIG;
+ ++gp;
+ } else {
+ *ref_status++ = LC_MED_DIG;
+ }
+ /* Hent serienummer og konverter til gruppenummer */
+ if (isdigit(*gp)) {
+ snr = strtol(gp,&gp,10);
+ /* Konverter til gruppenummer */
+ if ((grnr = LI_GetSnr(Sys.GrId.pFil,snr)) != INGEN_GRUPPE) {
+ *ref_array++ = grnr;
+ ++ant_ref;
+
+ } else {
+ UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",snr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ ref_status--;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ ref_status--;
+ }
+
+ } else if (*gp == '(') { /* Start øy, ferdig med omkretsen */
+ pGRS->sRefPos = (short)(gp - ginfo);
+ return ant_ref;
+
+ } else { /* Ukjent tegn */
+ ++gp;
+ }
+
+ } else { /* Tabellen er full */
+ pGRS->sRefPos = (short)(gp - ginfo);
+ return ant_ref;
+ }
+ }
+ }
+ pGRS->sGiLinNr++;
+ }
+ }
+ return (ant_ref);
+}
+
+
+/*
+AR-920930
+CH LX_GetRefOy Hent referanser for øyer
+CD ==========================================================================
+CD Formål:
+CD Henter ut et array med referanser for omkretsen av øy.
+CD ant_ref == 0 eller ant_ref < max_ref viser at hele omkretsen er behandla.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -------------------------------------------------------------------------
+CD LC_GRF_STATUS * pGS iu Struktur med statusopplysninger.
+CD long *ref_array u GRUPPENUMMER for refererte grupper.
+CD unsigned char *ref_status u Status for gruppene i ref_array.
+CD LC_MED_DIG = Brukes MED dig retning
+CD LC_MOT_DIG = Brukes MOT dig retning
+CD GRF_START_OY = Første gruppe i øy
+CD GRF_SLUTT_OY = Siste gruppe i øy
+CD long max_ref i Max antall linjer i ref_array.
+CD short ant_ref r Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD ant_ref = LX_GetRefOy(&GS,ref_array,ref_status,max_ref);
+CD ==========================================================================
+*/
+static long LX_GetRefOy(LC_GRF_STATUS * pGS,long *ref_array,
+ unsigned char *ref_status,long max_ref)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long snr,grnr,antall;
+ unsigned char ucRetning;
+ LC_BGR Bgr,GmlBgr;
+ long ant_ref = 0;
+
+
+ Bgr.pFil = Sys.GrId.pFil;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Husk aktuell gruppe */
+ GmlBgr = Sys.GrId;
+
+ /* Les inn resten av påbegynnt refferert flate */
+ if (pGS->Bgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&(pGS->Bgr),LES_OPTIMALT,&ngi,&nko,&info);
+
+ ant_ref = LX_GetRefOmkrets(&(pGS->Oy),ref_array,ref_status,max_ref);
+ ref_array += ant_ref;
+ ref_status += ant_ref;
+
+ /* Les inn igjen aktuell gruppe */
+ LC_RxGr(&GmlBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ if (ant_ref < max_ref) {
+ pGS->Bgr.pFil = NULL;
+ pGS->Bgr.lNr = INGEN_GRUPPE;
+ }
+ }
+
+ /* Finn referanser */
+ while (pGS->Omkr.sGiLinNr <= Sys.pGrInfo->ngi) {
+ gp = LX_GetGi(pGS->Omkr.sGiLinNr);
+
+ /* Handter referanselinjer */
+ if ((pGS->Omkr.sRefLin = LC_ErLinjeRefLin(gp,pGS->Omkr.sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo + pGS->Omkr.sRefPos;
+ pGS->Omkr.sRefPos = 0;
+ while (*gp) { /* Tolk en linje */
+ if (ant_ref < max_ref) {
+ if (*gp == ':') { /* Tall */
+ ++gp;
+ /* Husk retning */
+ if (*gp == '-') {
+ ucRetning = LC_MOT_DIG;
+ ++gp;
+ } else {
+ ucRetning = LC_MED_DIG;
+ }
+ /* Hent serienummer og konverter til gruppenummer */
+ if (isdigit(*gp)) {
+ snr = strtol(gp,&gp,10);
+ /* Konverter til gruppenummer */
+ if ((grnr = LI_GetSnr(Sys.GrId.pFil,snr)) != INGEN_GRUPPE) {
+ Bgr.lNr = grnr;
+ /* Referanse til flate, pakk ut denne */
+ if (LC_GetGrParaBgr(&Bgr,&ngi,&nko,&info)
+ == L_FLATE) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ pGS->Oy.sGiLinNr = 2;
+ pGS->Oy.sRefPos = 0;
+ pGS->Oy.sRefLin = UT_FALSE;
+
+ antall = LX_GetRefOmkrets(&(pGS->Oy),ref_array,
+ ref_status,max_ref-ant_ref);
+ ref_array += antall;
+ ref_status += antall;
+ ant_ref += antall;
+
+ /* Les inn igjen aktuell gruppe */
+ LC_RxGr(&GmlBgr,LES_OPTIMALT,&ngi,&nko,&info);
+
+ if (ant_ref >= max_ref) {
+ pGS->Bgr = Bgr;
+ } else {
+ pGS->Bgr.pFil = NULL;
+ pGS->Bgr.lNr = INGEN_GRUPPE;
+ }
+
+ } else {
+ *ref_status++ = ucRetning;
+ *ref_array++ = grnr;
+ ++ant_ref;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Snr. %ld er referert i \"%s : %s\", finnes ikke!\n",snr,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else if (*gp == '(') { /* Start øy */
+ *ref_array++ = INGEN_GRUPPE;
+ *ref_status++ = GRF_START_OY;
+ ++ant_ref;
+ ++gp;
+
+ } else if (*gp == ')') { /* Slutt øy */
+ *ref_array++ = INGEN_GRUPPE;
+ *ref_status++ = GRF_SLUTT_OY;
+ ++ant_ref;
+ ++gp;
+
+ } else { /* Ukjent tegn */
+ ++gp;
+ }
+
+ } else { /* Tabellen er full */
+ pGS->Omkr.sRefPos = (short)(gp - ginfo);
+ return ant_ref; /* ==> Retur */
+ }
+ }
+ }
+ pGS->Omkr.sGiLinNr++;
+ }
+ }
+
+ return ant_ref;
+}
+
+
+/*
+AR-921012
+CH LC_InqAntRef Spørr om antall referanser
+CD ==========================================================================
+CD Formål:
+CD Spørr om antall referanser i GINFO i aktuell gruppe.
+CD Dette kallet kan brukes til å finne hvor stor array som må allokeres før
+CD kall til LC_GetRef.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long ant_ref r Antall referanser i GINFO.
+CD OBS! Start- og sluttparantes for øy blir regnet
+CD som egne referanser.
+CD
+CD Bruk:
+CD long lAntRef;
+CD short sGiLin,sRefPos;
+CD long *plRefArray;
+CD
+CD lAntRef = LC_InqAntRef();
+CD plRefArray = (long *) UT_MALLOC(lAntRef * sizeof(long));
+CD sGiLin = 2;
+CD sRefPos = 0;
+CD LC_GetRef(plRefArray,lAntRef,&sGiLin,&sRefPos);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_InqAntRef(void)
+{
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long lAntRef = 0;
+ short gilin = 2;
+ short sRefLin = UT_FALSE; /* Viser om aktuel linje inneholder referanser */
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Finn referanser */
+ while (gilin <= Sys.pGrInfo->ngi){
+ gp = LX_GetGi(gilin);
+
+ /* Handter referanselinjer */
+ if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo;
+ while (*gp) { /* Tolk en linje */
+ if (*gp == ':') { /* Tall */
+ ++gp;
+ if (isdigit(*gp) || *gp == '-') {
+ while (*gp && (!UT_IsSpace(*gp)) && *gp != ')') {
+ ++gp;
+ }
+ ++lAntRef;
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i gruppe \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else if (*gp == '(' || *gp == ')') { /* Start og slutt øy */
+ ++lAntRef;
+ ++gp;
+
+ } else { /* Ukjent tegn */
+ ++gp;
+ }
+ }
+ }
+ ++gilin;
+ }
+ }
+ return lAntRef;
+}
+
+
+/*
+AR-900213
+OJ-900213
+CH LC_GetRef Hent referanser fra GINFO
+CD ==========================================================================
+CD Formål:
+CD Henter ut et array med referanser fra GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long *ref_array u Serienr. for refererte grupper.
+CD Start øy, og slutt øy angis ved fiktive gruppenr.
+CD Følgende konstanter er definert:
+CD START_OY = 9999999L = Start øy.
+CD SLUTT_OY = -9999999L = Slutt øy.
+CD long max_ref i Max antall linjer i ref_array.
+CD short *gilin i/u linje for start referanselesing
+CD short *refpos i/u posisjon i linja for neste innlegging i array.
+CD long ant_ref r Antall linjer brukt i ref_array.
+CD
+CD Bruk:
+CD ant_ref = LC_GetRef(ref_array,max_ref,&gilin,&refpos);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetRef(long *ref_array,long max_ref,short *gilin,short *refpos)
+{
+ char *gp,ginfo[LC_MAX_SOSI_LINJE_LEN];
+ long ant_ref = 0;
+ short sRefLin = UT_FALSE; /* Viser om aktuel linje inneholder referanser */
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ /* Finn referanser */
+ while (*gilin <= Sys.pGrInfo->ngi){
+ gp = LX_GetGi(*gilin);
+
+ /* Handter referanselinjer */
+ if ((sRefLin = LC_ErLinjeRefLin(gp,sRefLin)) == UT_TRUE) {
+ UT_StrCopy(ginfo,gp,LC_MAX_SOSI_LINJE_LEN);
+ gp = ginfo + *refpos;
+ *refpos = 0;
+ while (*gp){ /* Tolk en linje */
+ if (ant_ref < max_ref){
+ if (*gp == ':'){ /* Tall */
+ ++gp;
+ if (isdigit(*gp) || *gp == '-') {
+ *ref_array++ = strtol(gp,&gp,10);
+ ++ant_ref;
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig referanse \"%s\" i gruppe \"%s : %s\"\n",ginfo,Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_REF;
+ }
+
+ } else if (*gp == '('){ /* Start øy */
+ *ref_array++ = START_OY;
+ ++ant_ref;
+ ++gp;
+ } else if (*gp == ')'){ /* Slutt øy */
+ *ref_array++ = SLUTT_OY;
+ ++ant_ref;
+ ++gp;
+ } else{ /* Ukjent tegn */
+ ++gp;
+ }
+ } else{ /* Tabellen er full */
+ *refpos = (short)(gp - ginfo);
+ return (ant_ref);
+ }
+ }
+ }
+ (*gilin)++;
+ }
+ }
+ return (ant_ref);
+}
+
+
+/*
+OJ-901016
+AR-930930
+CH LC_PutRef Legger inn referanser i GINFO
+CD ==========================================================================
+CD Formål:
+CD Legger inn et array med referanser til GINFO i aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long ref_array i Gruppenummer for refererte grupper.
+CD Start øy, og slutt øy angis ved fiktive gruppenr.
+CD Følgende konstanter er definert:
+CD START_OY = 9999999L = Start øy.
+CD SLUTT_OY = -9999999L = Slutt øy.
+CD long ant_ref i Antall linjer i ref_array.
+CD short *ngi r Antall linjer GINFO
+CD
+CD Bruk:
+CD ngi = LC_PutRef(ref_array,ant_ref);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutRef(long *ref_array,long ant_ref)
+{
+ #define MAX_LEN 66 /* Ginfolinjen skrives ut når den er lengre en 66 tegn */
+ short gilin;
+ long j;
+ char temp[LC_MAX_SOSI_LINJE_LEN],*ginfo,*cp;
+ short ledig_linje = -1;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ /* Pakker gammel GINFO */
+ for (gilin=2; gilin <= Sys.pGrInfo->ngi; ++gilin) {
+ ginfo = LX_GetGi(gilin);
+
+ /* Gammel type referanse er funnet */
+ if (strncmp(ginfo,".. ",3) == 0) {
+ if (ledig_linje == -1) { /* Første linje med referanse */
+ ledig_linje = gilin;
+ }
+
+ /* Ny type referanse er funnet */
+ } else if (strncmp(ginfo,"..REF ",6) == 0) {
+ if (ledig_linje == -1) { /* Første linje med referanse */
+ ledig_linje = gilin;
+ }
+ /* Søk over resten av referansene */
+ for (++gilin; gilin <= Sys.pGrInfo->ngi; ++gilin) {
+ ginfo = LX_GetGi(gilin);
+ if (strncmp(ginfo,"..",2) == 0) { /* Annen GINFO er funnet */
+ gilin--;
+ break; /* Avbryt, alle referanser er funnet*/
+ }
+ }
+
+ /* Annen GINFO */
+ } else {
+ if (ledig_linje != -1) {
+ /* Funnet linje som skal flyttes opp */
+ LC_PutGi(ledig_linje,ginfo);
+ ++ledig_linje;
+ }
+ }
+ }
+
+ if (ledig_linje == -1) ledig_linje = Sys.pGrInfo->ngi + 1;
+
+ /* Legger inn referanser */
+ if (ant_ref > 0) {
+
+ /* Husk at det finnes flate i filen */
+ if ( Sys.GrId.pFil->SosiNiv[1] < 4) {
+ Sys.GrId.pFil->SosiNiv[1] = 4;
+ }
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ UT_StrCopy(temp,"..REF ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 6;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+
+
+ j=0;
+ while (j < ant_ref) {
+ /* Strengen er full, skriver ut */
+ if (*ref_array != SLUTT_OY && strlen(temp) > MAX_LEN) {
+ if (ledig_linje > Sys.pGrInfo->ngi) {
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ++ledig_linje;
+
+ if (Sys.GrId.pFil->sSosiVer >= 220) {
+ *temp = '\0';
+ cp = temp;
+ } else {
+ UT_StrCopy(temp,".. ",LC_MAX_SOSI_LINJE_LEN);
+ cp = temp + 3;
+ }
+ }
+ /* Bygg opp streng */
+ if (*ref_array == START_OY) {
+ if (! UT_IsSpace(*(cp-1))) {
+ *cp++ = ' ';
+ }
+ *cp++ = '(';
+ *cp = '\0';
+
+ } else if (*ref_array == SLUTT_OY) {
+ if (*(cp-1) == '.') {
+ *cp++ = ' ';
+ }
+ *cp++ = ')';
+ *cp = '\0';
+
+ } else { /* Referanse */
+ if (! UT_IsSpace(*(cp-1)) && *(cp-1) != '(') {
+ *cp++ = ' ';
+ *cp = '\0';
+ }
+ char szOrd[50];
+ UT_SNPRINTF(szOrd,50,":%ld",*ref_array);
+ UT_StrCat(temp,szOrd,LC_MAX_SOSI_LINJE_LEN);
+ cp = strchr(temp,'\0');
+ }
+
+ ++j;
+ ++ref_array;
+ }
+
+ if (ledig_linje > Sys.pGrInfo->ngi) { /* Skriver ut strengen */
+ ledig_linje = LC_AppGiL();
+ }
+ LC_PutGi(ledig_linje,temp);
+ ++ledig_linje;
+
+ } else {
+ Sys.pGrInfo->info &= ~((unsigned short)GI_REF);
+ Sys.pGrInfo->info &= ~((unsigned short)GI_OY_REF);
+ }
+
+ /* Sletter 1. ledige og resten */
+ LC_DelGiL(ledig_linje, (short)(Sys.pGrInfo->ngi - ledig_linje + 1));
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+JEK-920918
+CH LC_SirkelTilBuep Konverterer en "sirkel" til to BUEP
+CD ============================================================================
+CD Formål: fi
+CD Konverterer en SIRKEL/SIRKELP til to BUEP.
+CD Forutsetter at aktuell gruppe er SIRKEL eller SIRKELP.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ----------------------------------------------------------------------------
+CD short buff_retning i Buffer-retning (kun for BUE og BUEP)
+CD HENT_FORRFRA (1) = Vanlig
+CD HENT_BAKFRA (-1) = Buffer skal snues
+CD short *sfeil u Feilstatus, definert dersom ist = 0
+CD 1 = Ulovlig geometritype(ikke bue)
+CD 2 = Feil ved beregning av bueparametre
+CD short ist r Returstatus
+CD UT_TRUE = Alt OK
+CD UT_FALSE = Feil, se returvariabel sfeil
+CD
+CD Bruk:
+CD ist = LC_SirkelTilBuep(buff_retning, &as, &ns, &radius, &fi, &dfi, &sfeil )
+ ============================================================================
+*/
+/*
+SK_EntPnt_FYBA short LC_SirkelTilBuep(short antDelingspunkt,double a1,double n1,double h1,double a2,double n2,double h2,
+ short *ngi, long *nko, LC_BGR *pNyBgr)
+{
+ double as,ns,da,dn,aNy,nNy,r,fi,dfi,dfi2,fiNy;
+ short gnavn,ngi;
+ long nko;
+ unsigned short info;
+ double fi1,a_ny=0.0,n_ny=0.0;
+ long lGmlSnr,lNyttSnr;
+ short sGiLinje;
+ short sfeil;
+
+
+ if (Sys.pGrInfo->gnavn != L_SIRKEL && Sys.pGrInfo->gnavn != L_SIRKELP)
+ return UT_FALSE; // ==> Ikke sirkel
+
+ lGmlSnr = LC_GetSn();
+ LC_GetBuePar(LC_MED_DIG,&as,&ns,&r,&fi,&dfi,&sfeil);
+
+ LC_PutGi(1,".BUEP");
+
+ sGiLinje = 2;
+ if (LC_GetGP("..RADIUS", &sGiLinje, ngi)) ngi = LC_DelGiL(sGiLinje,1);
+
+ // Sikrer at det er tre koordinater i gruppen
+ if (nko > 3) nko = LC_DelKoL(4,nko-3);
+ else if (nko < 3) nko = LC_InsKoL(nko+1,3-nko);
+
+ // Hvis det er bare ett nytt punkt deles sirkelen i to halvsirkler
+ if (antDelingspunkt == 1)
+ {
+ // Beregner et nytt "fiktivt" punkt på motsatt side av sirkelen
+ da = a1 - as;
+ dn = n1 - ns;
+ a2 = as - da;
+ n2 = ns - dn;
+ h2 = HOYDE_MANGLER;
+
+ }
+ else if (antDelingspunkt != 2)
+ {
+ // Ikke gitt noe delingspunkt
+ if (Sys.pGrInfo->gnavn == L_SIRKEL)
+ {
+ a1 = as - r;
+ n1 = n2 = ns;
+ a2 = as + r;
+ h1 = h2 = LC_GetTH(1);
+ }
+ else // L_SIRKELP
+ {
+ LC_GetTK(1,&a1,&n1);
+ h1 = LC_GetTH(1);
+
+
+ }
+
+ a1 = as - r;
+ n1 = n2 = ns;
+ a2 = as + r;
+ h1 = h2 = HOYDE_MANGLER;
+ }
+
+ LC_PutTK(1,a1,n1);
+ LC_PutKp(1,kpdiv.kpnr);
+ if (AntPkt > 1) LC_PutTH(1,h1);
+ GH_DrawMarks(pGA,1,&a1,&n1,FALSE);
+
+ LC_PutTK(3,a2,n2);
+ LC_PutKp(3,kpdiv.kpnr);
+ if (AntPkt > 1) {
+ LC_PutTH(3,h2);
+ GH_DrawMarks(pGA,1,&a2,&n2,FALSE);
+ }
+
+ // Åpningsvinkel for buen fra P1 til P2
+ fi1 = GM_retning(as,ns,a1,n1);
+ GM_PktBue(as,ns,fi1,dfi,a2,n2,&dfi2);
+
+ // Beregner et nytt punkt midt på buen fra P1 til P2
+ fiNy = fi1 + (dfi2 / 2.0);
+ aNy = as + fabs(r)*cos(fiNy);
+ nNy = ns + fabs(r)*sin(fiNy);
+
+ // OBS! Bør legge inn sjekk mot at punktet faller sammen med noen av de andre punktene
+
+ LC_PutTK(2,aNy,nNy);
+ if (AntPkt > 1) {
+ if (h1 != HOYDE_MANGLER && h2 != HOYDE_MANGLER) LC_PutTH(2,(h1+h2)/2.0);
+ }
+
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ // ----- Oppretter og tilpasser den andre delen
+ LC_NyGr(pBgr->pFil,".BUEP",&cur.bgr,&lNyttSnr);
+ gnavn = LC_CopyGr(pBgr,OPPDATER_NGIS,&ngi,&nko,&info);
+
+ LC_PutTK(1,a2,n2);
+ LC_PutKp(1,kpdiv.kpnr);
+ if (AntPkt > 1) LC_PutTH(1,h1);
+
+ LC_PutTK(3,a1,n1);
+ LC_PutKp(3,kpdiv.kpnr);
+ if (AntPkt > 1) LC_PutTH(3,h2);
+
+ // Beregner et nytt punkt på motsatt side av sirkelen av midtpunktet i den andre halvparten av sirkelen
+ da = aNy - as;
+ dn = nNy - ns;
+ aNy = as - da;
+ nNy = ns - dn;
+
+ LC_PutTK(2,aNy,nNy);
+ if (AntPkt > 1) {
+ if (h1 != HOYDE_MANGLER && h2 != HOYDE_MANGLER) LC_PutTH(2,(h1+h2)/2.0);
+ }
+
+ LC_WxGr(SKRIV_OPTIMALT);
+
+ cur.gnavn = LC_RxGr(&cur.bgr,LES_OPTIMALT,&cur.ngi,&cur.nko,&cur.info);
+ TegnGruppe(pGA,T_KOMFIL,VIS_FARGE,1,cur.nko);
+
+ if (Utvalg.bPaa) LC_SetBt(&cur.bgr,UTVALG_1);
+ LC_SetBt(&cur.bgr,TMP_TOT_SK);
+ LC_SetBt(&cur.bgr,TOT_SK);
+ LC_SetBt(&cur.bgr,KLADD1);
+
+ OppdaterReferanser(pBgr->pFil,a1,n1,lGmlSnr,lNyttSnr);
+
+ return UT_TRUE;
+}
+*/
+
+
+
+/*
+JEK-920918
+CH LC_GetBuePar Beregner parametre som definerer sirkelbue
+CD ============================================================================
+CD Formål: fi
+CD Sirkelbue defineres i SOSI ved en av /
+CD geometrielementene .SIRKEL, .SIRKELP, /
+CD .BUE, .BUEP. / \
+CD Denne rutina regner om til en intern as, ns * -radius- ) dfi
+CD bueangivelse med sirkelsentrum, radius \ /
+CD og retning til buens startpunkt samt \
+CD delta for sluttpunktet uansett hvordan \
+CD buen er definert i SOSI.
+CD
+CD NB! Alle retninger i radianer, 0-retning i øst-aksen og positiv
+CD omløpsretning mot urviseren.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD ----------------------------------------------------------------------------
+CD short buff_retning i Buffer-retning (kun for BUE og BUEP)
+CD HENT_FORRFRA (1) = Vanlig
+CD HENT_BAKFRA (-1) = Buffer skal snues
+CD double *as u Øst-koordinat sentrum sirkelbue
+CD double *an u Nord-koordinat sentrum sirkelbue
+CD double *radius u Radius i sirkelbue.
+CD double *fi u Retningsvinkel sentrum -> startpunkt bue
+CD double *dfi u Vinkel mellom fi og sentrum -> sluttpunkt bue
+CD dfi > 0 = Positiv omløpsretning(mot klokka)
+CD dfi < 0 = Negativ omløpsretning(med klokka)
+CD short *sfeil u Feilstatus, definert dersom ist = 0
+CD 1 = Ulovlig geometritype(ikke bue)
+CD 2 = Feil ved beregning av bueparametre
+CD short ist r Returstatus
+CD UT_TRUE = Alt OK
+CD UT_FALSE = Feil, se returvariabel sfeil
+CD
+CD Bruk:
+CD ist = LC_GetBuePar(buff_retning, &as, &ns, &radius, &fi, &dfi, &sfeil )
+ ============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBuePar(short buff_retning, double *as, double *ns, double *radius,
+ double *fi, double *dfi, short *sfeil)
+{
+ short ist;
+ short storbue;
+ double a,n,a2,n2,a3,n3;
+
+
+ *sfeil = 0;
+ ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* ----- Sjekker geometritype og henter parametre for buen */
+
+ if (Sys.pGrInfo->gnavn == L_BUE) { /* .BUE */
+ if (LC_GetBue(buff_retning,&a,&n,&a2,&n2,&(*radius),&storbue)){
+ if (GM_KonvBue(a,n,a2,n2,*radius,storbue,&(*as),&(*ns),&(*fi),&(*dfi))){
+ ist = UT_TRUE;
+ } else {
+ *sfeil=2;
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mer enn 2*radius mellom endepunktene\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ } else if (Sys.pGrInfo->gnavn == L_BUEP) { /* .BUEP */
+ if (LC_GetBuep(buff_retning,&a,&n,&a2,&n2,&a3,&n3)) {
+ if (GM_KonvBuep(a,n,a2,n2,a3,n3,&(*as),&(*ns),&(*radius),&(*fi),&(*dfi))){
+ ist = UT_TRUE;
+ } else {
+ *sfeil = 2;
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - punktene ligger på rett linje\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ } else if (Sys.pGrInfo->gnavn == L_SIRKEL) { /* .SIRKEL */
+ if (LC_GetSirkel(&(*as),&(*ns),&(*radius))) {
+ if(GM_KonvSirkel(&(*fi),&(*dfi))) {
+ ist = UT_TRUE;
+ } else {
+ *sfeil = 2;
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ } else if (Sys.pGrInfo->gnavn == L_SIRKELP) { /* .SIRKELP */
+ if (LC_GetSirkelp(&a,&n,&a2,&n2,&a3,&n3)) {
+ if (GM_KonvSirkelp(a,n,a2,n2,a3,n3,&(*as),&(*ns),&(*radius),&(*fi),&(*dfi))){
+ ist = UT_TRUE;
+ } else {
+ *sfeil = 2;
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\"\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ } else { /* Feil geometritype */
+ *sfeil = 1;
+ }
+
+ if (ist == UT_TRUE) {
+ *radius = fabs(*radius);
+ }
+
+ } else { /* Feil geometritype (ingen aktuell gruppe) */
+ *sfeil = 1;
+ }
+
+ return ist;
+}
+
+
+/*
+AR-890824
+CH LC_GetBue Hent bue
+CD ==========================================================================
+CD Formål:
+CD Henter ut nødvendige opplysninger om en bue.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short retning i Buffer-retning:
+CD HENT_FORRFRA ( 1) = vanlig,
+CD HENT_BAKFRA (-1) = buffer skal snues.
+CD double *a1 u Koordinat i første punkt
+CD double *n1 u
+CD double *a2 u Koordinat i siste punkt
+CD double *n2 u
+CD double *radius u Radius
+CD short *storbue u 0=vanlig bue, 1=storbue
+CD short ist r status: UT_TRUE = OK,
+CD UT_FALSE = feil (Gruppen er ikke OK bue)
+CD
+CD Bruk:
+CD ist = LC_GetBue(retning,&a1,&n1,&a2,&n2,&radius,&storbue);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBue(short retning,double *a1,double *n1,double *a2,double *n2,
+ double *radius,short *storbue)
+{
+ short gilin;
+ char *gp;
+ short ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_BUE && Sys.pGrInfo->nko > 1) {
+ /* Hent koordinater */
+ if (retning == HENT_FORRFRA) {
+ LC_GetTK(1,a1,n1);
+ LC_GetTK(Sys.pGrInfo->nko,a2,n2);
+ } else {
+ LC_GetTK(Sys.pGrInfo->nko,a1,n1);
+ LC_GetTK(1,a2,n2);
+ }
+
+ /* Finn radius og storbue */
+ gilin = 2;
+ if ((gp = LC_GetGP("..RADIUS",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+ *radius = strtod(gp,&gp);
+ if (retning == HENT_BAKFRA) *radius = - *radius;
+ gilin = 2;
+ if ((gp = LC_GetGP("..STORBUE",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+ *storbue = (short)strtol(gp,&gp,10);
+ } else {
+ *storbue = 0;
+ }
+ ist = UT_TRUE; /* Buen er OK */
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler ..RADIUS\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for få koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetBuep Hent buep
+CD ==========================================================================
+CD Formål:
+CD Henter ut nødvendige opplysninger om en buep.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short retning i Buffer-retning:
+CD HENT_FORRFRA ( 1) = vanlig,
+CD HENT_BAKFRA (-1) = buffer skal snues.
+CD double *a1 u Koordinat i første punkt
+CD double *n1 u
+CD double *a2 u Koordinat i midtre punkt
+CD double *n2 u
+CD double *a3 u Koordinat i siste punkt
+CD double *n3 u
+CD short ist r status: UT_TRUE = OK,
+CD UT_FALSE = feil (Gruppen er ikke OK buep)
+CD
+CD Bruk:
+CD ist = LC_GetBuep(retning,&a1,&n1,&a2,&n2,&a3,&n3);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetBuep(short retning,double *a1,double *n1,double *a2,double *n2,
+ double *a3,double *n3)
+{
+ short ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_BUEP && Sys.pGrInfo->nko > 2) {
+ /* Hent koordinater */
+ LC_GetTK((1+Sys.pGrInfo->nko)/2, a2, n2);
+ if (retning == HENT_FORRFRA) {
+ LC_GetTK(1,a1,n1);
+ LC_GetTK(Sys.pGrInfo->nko,a3,n3);
+ } else {
+ LC_GetTK(1,a3,n3);
+ LC_GetTK(Sys.pGrInfo->nko,a1,n1);
+ }
+
+ ist = UT_TRUE; /* Buen er OK */
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for få koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetSirkel Hent silkel
+CD ==========================================================================
+CD Formål:
+CD Henter ut nødvendige opplysninger om en sirkel.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double *as u Koordinat i sentrum
+CD double *ns u
+CD double *radius u Radius
+CD short ist r status: UT_TRUE = OK,
+CD UT_FALSE = Feil (Gruppen er ikke OK sirkel)
+CD
+CD Bruk:
+CD ist = LC_GetSirkel(&as,&ns,&radius);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetSirkel(double *as,double *ns,double *radius)
+{
+ short gilin;
+ char *gp;
+ short ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_SIRKEL && Sys.pGrInfo->nko > 0) {
+ /* Hent koordinater */
+ LC_GetTK(1,as,ns);
+
+ /* Finn radius */
+ gilin = 2;
+ if ((gp = LC_GetGP("..RADIUS",&gilin,Sys.pGrInfo->ngi)) != NULL) {
+ *radius = strtod(gp,&gp);
+ ist = UT_TRUE; /* Sirkelen er OK */
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler ..RADIUS\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - mangler koordinat\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+AR-911029
+CH LC_GetSirkelp Hent silkelp
+CD ==========================================================================
+CD Formål:
+CD Henter ut nødvendige opplysninger om en sirkelp.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double *a1 u Koordinat i P1
+CD double *n1 u
+CD double *a2 u Koordinat i P2
+CD double *n2 u
+CD double *a3 u Koordinat i P3
+CD double *n3 u
+CD short ist r status: UT_TRUE = OK,
+CD UT_FALSE = Feil (Gruppen er ikke OK sirkelp)
+CD
+CD Bruk:
+CD ist = LC_GetSirkelp(&a1,&n1,&a2,&n2,&a3,&n3);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetSirkelp(double *a1,double *n1,double *a2,double *n2,
+ double *a3,double *n3)
+{
+ short ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (Sys.pGrInfo->gnavn == L_SIRKELP && Sys.pGrInfo->nko > 2) {
+ /* Hent koordinater */
+ LC_GetTK(1,a1,n1);
+ LC_GetTK((1+Sys.pGrInfo->nko)/2, a2, n2);
+ LC_GetTK(Sys.pGrInfo->nko,a3,n3);
+
+ ist = UT_TRUE; /* Buen er OK */
+
+ } else {
+ UT_FPRINTF(stderr,"Ulovlig bue: \"%s : %s\" - for få koordinater\n",Sys.GrId.pFil->pszNavn,LX_GetGi(1));
+ Sys.GrId.pFil->usDataFeil |= LC_DATAFEIL_BUE;
+ }
+ }
+
+ return ist;
+}
+
+
+/*
+OJ-891126
+CH LC_GetCurEnhet Hent enhet på angitt nivå
+CD ==========================================================================
+CD Formål:
+CD Henter ut enhet fra filhode eller GINFO
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm
+CD short *nivaa iu angir nivå for henting, returnerer aktuelt nivå
+CD 1 = filhode
+CD 2 = GINFO
+CD double *enhet u Aktuell enhet
+CD double *enhet_h u Aktuell enhet-H
+CD double *enhet_d u Aktuell enhet-D
+CD
+CD Bruk:
+CD LC_GetCurEnhet(pFil,&nivaa,&enhet,&enhet_h,&enhet_d);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetCurEnhet(LC_FILADM * pFil,short *nivaa, double *enhet,
+ double *enhet_h, double *enhet_d)
+{
+ LO_TestFilpeker(pFil,"GetCurEnhet");
+
+ *enhet = pFil->TransPar.dEnhet;
+ *enhet_h = pFil->TransPar.dEnhet_h;
+ *enhet_d = pFil->TransPar.dEnhet_d;
+
+ /* Enhet fra GINFO */
+ if (*nivaa == 2)
+ {
+ short lin = 2;
+ char *para;
+ double enhet_temp;
+
+ para = LC_GetGP("..ENHET",&lin,Sys.pGrInfo->ngi);
+ if (para == NULL) {
+ *nivaa = 1;
+ } else {
+ UT_AtoD(para,'.',&enhet_temp);
+ if (enhet_temp > LC_ACCY) *enhet = enhet_temp;
+ }
+
+ lin=2;
+ para = LC_GetGP("...ENHET-H",&lin,Sys.pGrInfo->ngi);
+ if (para != NULL) {
+ UT_AtoD(para,'.',&enhet_temp);
+ if (enhet_temp > LC_ACCY) *enhet_h = enhet_temp;
+ }
+
+ lin=2;
+ para = LC_GetGP("...ENHET-D",&lin,Sys.pGrInfo->ngi);
+ if (para != NULL) {
+ UT_AtoD(para,'.',&enhet_temp);
+ if (enhet_temp > LC_ACCY) *enhet_d = enhet_temp;
+ }
+ }
+}
+
+
+/*
+AR-890515
+CH LC_UpdateGiEnhet Oppdater ..ENHET i GINFO
+CD ==========================================================================
+CD Formål:
+CD Setter koordinat-enhet for gruppen.
+CD Oppdaterer ..ENHET / ..ENHET-H / ..ENHET-D i GINFO.
+CD Rutinen handterer selv tildeling eller sletting av GINFO-linje.
+CD Hvis verdien er lik filhodets verdi blir det ikke lagt inn verdi i GINFO.
+CD Enhet = 0.0 = bruk filhodets enhet, og fører til at det ikke legges inn
+CD i GINFO. Eventuell eksisterende linje jgernes.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm
+CD double enhet i Grunnriss-enhet
+CD double enhet_h i Høyde-enhet
+CD double enhet_d i Dybde-enhet
+CD ngi short r Antall GINFO-linjer etter oppdatering
+CD
+CD Bruk:
+CD ngi = LC_UpdateGiEnhet(pFil,enhet,enhet_h,enhet_d);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGiEnhet(LC_FILADM *pFil,double enhet,double enhet_h,double enhet_d)
+{
+ short linje;
+ char tx[80];
+
+ LO_TestFilpeker(pFil,"UpdateGiEnhet");
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ // ----- ..ENHET
+ linje = 2;
+
+ // Ikke spesiell ..ENHET
+ if (fabs(enhet - pFil->TransPar.dEnhet) < LC_ACCY || fabs(enhet) < LC_ACCY)
+ {
+ if (LC_GetGP("..ENHET",&linje,Sys.pGrInfo->ngi) != NULL)
+ {
+ LC_DelGiL(linje,1); /* Funnet, fjern linjen */
+ }
+ }
+
+ // Spesiell ..ENHET
+ else
+ {
+ if (LC_GetGP("..ENHET",&linje,Sys.pGrInfo->ngi) == NULL)
+ {
+ linje = LC_AppGiL(); /* Ikke funnet, tildel ny linje */
+ }
+ LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET",enhet));
+ }
+
+ // ----- ..ENHET-H
+ linje = 2;
+
+ // Ikke spesiell ..ENHET-H
+ if (fabs(enhet_h - pFil->TransPar.dEnhet_h) < LC_ACCY || fabs(enhet_h) < LC_ACCY)
+ {
+ if (LC_GetGP("..ENHET-H",&linje,Sys.pGrInfo->ngi) != NULL)
+ {
+ LC_DelGiL(linje,1); /* Funnet, fjern linjen */
+ }
+ }
+
+ // Spesiell ..ENHET-H
+ else
+ {
+ if (LC_GetGP("..ENHET-H",&linje,Sys.pGrInfo->ngi) == NULL)
+ {
+ linje = LC_AppGiL(); /* Ikke funnet, tildel ny linje */
+ }
+ LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET-H",enhet_h));
+ }
+
+ // ----- ..ENHET-D
+ linje = 2;
+
+ // Ikke spesiell ..ENHET-D
+ if (fabs(enhet_d - pFil->TransPar.dEnhet_d) < LC_ACCY || fabs(enhet_d) < LC_ACCY)
+ {
+ if (LC_GetGP("..ENHET-D",&linje,Sys.pGrInfo->ngi) != NULL)
+ {
+ LC_DelGiL(linje,1); /* Funnet, fjern linjen */
+ }
+ }
+
+ // Spesiell ..ENHET-D
+ else
+ {
+ if (LC_GetGP("..ENHET-D",&linje,Sys.pGrInfo->ngi) == NULL)
+ {
+ linje = LC_AppGiL(); /* Ikke funnet, tildel ny linje */
+ }
+ LC_PutGi(linje,LB_FormaterEnhet(tx,80,"..ENHET-D",enhet_d));
+ }
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+OJ-891123
+CH LC_GetKvalitet Finner kvalitetsopplysninger
+CD ==========================================================================
+CD Formål:
+CD Finne kvalitetsopplysninger i filhode eller vanlig gruppe.
+CD (Tolker aktuell gruppe.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short *psMetode u Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long *pLNnoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over
+CD short *psSynbarhet u Synbarhet i bilde
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD KVAL_SYN_STD standard metode fra nivå over.
+CD short *psHoydeMetode u Hvordan høyden er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long *plHoydeNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over
+CD short ist r Status: UT_TRUE = OK, ..KVALITET er funnet
+CD UT_FALSE = ikke funnet
+CD
+CD Bruk:
+CD ist = LC_GetKvalitet(&sMetode,&lNoyaktighet,&sSynbarhet,
+CD &sHoydeMetode,&lHoydeNoyaktighet);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetKvalitet(short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+ short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+ short lin;
+ char *cp;
+ short ist = UT_FALSE;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ lin=2;
+ /* Søk i GINFO */
+ if ((cp = LC_GetGP("..KVALITET",&lin,Sys.pGrInfo->ngi)) != NULL) {
+ ist = UT_TRUE;
+ }
+
+ LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+ psHoydeMetode,plHoydeNoyaktighet);
+ }
+
+ return ist;
+}
+
+
+/*
+OJ-900103
+CH LC_GetCurKvalitet Finner kvalitetsopplysninger på angitt nivå
+CD ==========================================================================
+CD Formål:
+CD Finne kvalitetsopplysninger på angitt nivå, hode ginfo eller pinfo.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm
+CD short *nivaa iu Hvor skal det letes.
+CD 0 = ikke funnet
+CD 1 = hode
+CD 2 = ginfo
+CD 3 = pinfo
+CD Returnerer aktuelt nivå.
+CD long pnr i punktnr. ved spørring på pinfo
+CD short *psMetode u Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *pLNnoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short *psSynbarhet u Synbarhet i bilde
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD short *psHoydeMetode u Hvordan høyden er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD long *plHoydeNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD short ist r Statusvariabel:
+CD UT_TRUE = OK, KVALITET er funnet
+CD UT_FALSE = KVALITET er ikke funnet
+CD
+CD Bruk:
+CD ist = LC_GetCurKvalitet(pFil,&nivaa,pnr,&sMetode,&lNoyaktighet,
+CD &sSynbarhet,&sHoydeMetode,&lHoydeNoyaktighet);
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetCurKvalitet(LC_FILADM *pFil,short *nivaa,long pnr,
+ short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+ short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+ short lin;
+ char *cp;
+ short sMetode, sHoydeMetode, sSynbarhet;
+ long lNoyaktighet, lHoydeNoyaktighet;
+ LC_GETPP_STATUS pp_stat;
+ short sFunnetNivaa = 0;
+
+ short sStatus = UT_FALSE;
+
+ LO_TestFilpeker(pFil,"GetCurKvalitet");
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ *psMetode = KVAL_MET_STD;
+ *plNoyaktighet = KVAL_NOY_STD;
+ *psSynbarhet = KVAL_SYN_STD;
+ *psHoydeMetode = KVAL_MET_STD;
+ *plHoydeNoyaktighet = KVAL_NOY_STD;
+
+
+ /* Søk i PINFO */
+ if (*nivaa == 3) {
+ LC_InitPP("...KVALITET",pnr,pnr,&pp_stat);
+ if ((cp = LC_GetPP(&pnr,&pp_stat)) != NULL) {
+ LN_TolkKvalitet(cp,psMetode,plNoyaktighet,psSynbarhet,
+ psHoydeMetode,plHoydeNoyaktighet);
+ sStatus = UT_TRUE;
+ sFunnetNivaa = 3;
+ }
+ }
+
+ /* Søk i GINFO */
+ if (*nivaa >= 2) {
+ lin=2;
+ if ((cp = LC_GetGP("..KVALITET",&lin,Sys.pGrInfo->ngi)) != NULL){ /* Kvalitet */
+ LN_TolkKvalitet(cp,&sMetode,&lNoyaktighet,&sSynbarhet,
+ &sHoydeMetode,&lHoydeNoyaktighet);
+
+ /* Oppdater med kvalitet fra GINFO */
+ if (*psMetode == KVAL_MET_STD) *psMetode = sMetode;
+ if (*plNoyaktighet == KVAL_NOY_STD) *plNoyaktighet = lNoyaktighet;
+ if (*psSynbarhet == KVAL_SYN_STD) *psSynbarhet = sSynbarhet;
+ if (*psHoydeMetode == KVAL_MET_STD) *psHoydeMetode = sHoydeMetode;
+ if (*plHoydeNoyaktighet == KVAL_NOY_STD) *plHoydeNoyaktighet = lHoydeNoyaktighet;
+
+ sStatus = UT_TRUE;
+ if (sFunnetNivaa == 0) sFunnetNivaa = 2;
+ }
+ }
+
+ /* Hent fra hodet */
+ /* Oppdater med kvalitet fra HODE */
+ if (*psMetode == KVAL_MET_STD) *psMetode = pFil->Kvalitet.sMetode;
+ if (*plNoyaktighet == KVAL_NOY_STD) *plNoyaktighet = pFil->Kvalitet.lNoyaktighet;
+ if (*psSynbarhet == KVAL_SYN_STD) *psSynbarhet = pFil->Kvalitet.sSynbarhet;
+ if (*psHoydeMetode == KVAL_MET_STD) *psHoydeMetode = pFil->Kvalitet.sHoydeMetode;
+ if (*plHoydeNoyaktighet == KVAL_NOY_STD) *plHoydeNoyaktighet = pFil->Kvalitet.lHoydeNoyaktighet;
+
+ /* Handter eventuell standardverdi */
+ if (*psMetode == KVAL_MET_STD) *psMetode = KVAL_MET_UNDEF;
+ if (*plNoyaktighet == KVAL_NOY_STD) *plNoyaktighet = KVAL_NOY_UKJENT;
+ if (*psSynbarhet == KVAL_SYN_STD) *psSynbarhet = KVAL_SYN_GOD;
+ if (*psHoydeMetode == KVAL_MET_STD) *psHoydeMetode = KVAL_MET_UNDEF;
+ if (*plHoydeNoyaktighet == KVAL_NOY_STD) *plHoydeNoyaktighet = KVAL_NOY_UKJENT;
+
+ if (*psMetode != KVAL_MET_UNDEF ||
+ *plNoyaktighet != KVAL_NOY_UKJENT ||
+ *psSynbarhet != KVAL_SYN_GOD ||
+ *psHoydeMetode != KVAL_MET_UNDEF ||
+ *plHoydeNoyaktighet != KVAL_NOY_UKJENT ) {
+
+ sStatus = UT_TRUE;
+ if (sFunnetNivaa == 0) sFunnetNivaa = 1;
+ }
+ }
+
+ *nivaa = sFunnetNivaa;
+
+ return sStatus;
+}
+
+
+/*
+CH OJ-891205
+CH LC_UpdateGiKvalitet Oppdaterer ..KVALITET i Ginfo
+CD ==========================================================================
+CD Formål:
+CD Oppdaterer GINFO med ..KVALITET
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD Parametre:
+CD LC_FILADM *pFil i Peker til FilAdm for sosifil kvalitet skal
+CD testes mot.
+CD short sMetode i Metode i ..KVALITET
+CD long lNoyaktighet i Nøyaktighet i ..KVALITET
+CD short sSynbarhet i Synbarhet i ..KVALITET
+CD short sHoydeMetode i HøydeMetode i ..KVALITET
+CD long lHoydeNoyaktighet i HøydeNøyaktighet i ..KVALITET
+CD short ngi r Antall linjer i ginfo.
+CD
+CD Bruk:
+CD ngi = LC_UpdateGiKvalitet(pFil,sMetode,lNoyaktighet,sSynbarhet,
+CD sHoydeMetode,lHoydeNoyaktighet);
+CD
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGiKvalitet(LC_FILADM *pFil,short sMetode,long lNoyaktighet,
+ short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet)
+{
+ // Endret slik at ..KVALITET blir skrevet ut til gruppen bare hvis den er
+ // forskjellig fra kvalitet i filhodet.
+ // Fjerner aldri eksisterende kvalitet fra GINFO.
+
+ short ho_metode,ho_hmetode,ho_synbarhet;
+ long ho_noyaktighet,ho_hnoyaktighet;
+ short linje_nr,nivaa;
+ short pnr = 1;
+ short ngi = Sys.pGrInfo->ngi;
+
+
+ LO_TestFilpeker(pFil,"UpdateGiKvalitet");
+
+ // Hent kvalitet fra hode
+ nivaa = 1;
+ LC_GetCurKvalitet(pFil,&nivaa,pnr,&ho_metode,&ho_noyaktighet,
+ &ho_synbarhet,&ho_hmetode,&ho_hnoyaktighet);
+
+ // Hvis ulik kvalitet i gruppen og filhodet
+ if ((sMetode != ho_metode) ||
+ (lNoyaktighet != ho_noyaktighet) ||
+ (sSynbarhet != ho_synbarhet) ||
+ (sHoydeMetode != ho_hmetode) ||
+ (lHoydeNoyaktighet != ho_hnoyaktighet))
+ {
+ // Formatterer strengen og oppdater GINFO
+ ngi = LC_PutGP("..KVALITET",
+ LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,
+ sHoydeMetode,lHoydeNoyaktighet),&linje_nr);
+ }
+
+ //else
+ //{
+ // // Samme kvalitet som i filhodet, fjern eventuell GI-linje
+ // linje_nr = 2;
+ // if (LC_GetGP("..KVALITET",&linje_nr,ngi) != NULL) {
+ // ngi = LC_DelGiL(linje_nr,1);
+ // }
+ //}
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+OJ-891208
+AR-920312
+CH LC_UpdatePiKvalitet Oppdaterer ...KVALITET i Pinfo
+CD ==========================================================================
+CD Formål:
+CD Oppdaterer PINFO med ...KVALITET
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM * pFil i Peker til FilAdm for sosifil kvalitet
+CD skal testes mot.
+CD long pnr i Punktnummer som skal oppdateres.
+CD short sMetode i Metode i ..KVALITET
+CD long lNoyaktighet i Nøyaktighet i ..KVALITET
+CD short sSynbarhet i Synbarhet i ..KVALITET
+CD short sHoydeMetode i HøydeMetode i ..KVALITET
+CD long lHoydeNoyaktighet i HøydeNøyaktighet i ..KVALITET
+CD short sStatus r UT_TRUE = OK,
+CD UT_FALSE = ikke utført (for lite plass tilgjengelig)
+CD
+CD Bruk:
+CD sStatus = LC_UpdatePiKvalitet(pFil,pnr,sMetode,lNoyaktighet,sSynbarhet,
+CD sHoydeMetode,lHoydeNoyaktighet)
+CD ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdatePiKvalitet(LC_FILADM *pFil,long pnr,short sMetode,long lNoyaktighet,
+ short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet)
+{
+ char temp[LC_MAX_SOSI_LINJE_LEN],*pp,*neste,*cp;
+ short nivaa;
+ short gi_metode,gi_hmetode,gi_synbarhet;
+ long gi_noyaktighet,gi_hnoyaktighet;
+
+ LO_TestFilpeker(pFil,"UpdatePiKvalitet");
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ /* Fjern eksisterende KVALITET fra PINFO */
+ pp = LC_GetPi(pnr);
+ if ((neste = strstr(pp,"...KVALITET")) != NULL) { /* Finn SOSI-navnet */
+ cp = neste - 1; /* Avslutt første del av pinfo */
+ while (UT_IsSpace(*cp) && cp >= pp) {
+ cp--;
+ }
+ *(cp+1) = '\0';
+ UT_StrCopy(temp,pp,LC_MAX_SOSI_LINJE_LEN);
+
+ /* Hopp over KVALITETen */
+ if ((cp = strstr(neste+3,"...")) != NULL) { /* Neste SOSI-navn */
+ /* Heng på resten av den gamle PINFOen */
+ if (*temp) UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp,cp,LC_MAX_SOSI_LINJE_LEN);
+ }
+
+ /* KVALITET er ikke funnet, ta vare på hele strengen */
+ } else {
+ UT_StrCopy(temp,pp,LC_MAX_SOSI_LINJE_LEN);
+ }
+
+ /* Hent kvalitet fra ginfo/hode */
+ nivaa = 2;
+ LC_GetCurKvalitet(pFil,&nivaa,pnr,&gi_metode,&gi_noyaktighet,
+ &gi_synbarhet,&gi_hmetode,&gi_hnoyaktighet);
+
+ /* Hvis Kvaliteten avviker fra ginfo/hode, heng den på PINFO */ /* Legg inn endringen */
+ if (sMetode != gi_metode ||
+ lNoyaktighet != gi_noyaktighet ||
+ sSynbarhet != gi_synbarhet ||
+ sHoydeMetode != gi_hmetode ||
+ lHoydeNoyaktighet != gi_hnoyaktighet ) {
+
+ if (*temp) UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp,"...KVALITET ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp,LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+ LC_MAX_SOSI_LINJE_LEN);
+ }
+
+ if(strlen(temp) > LC_MAX_SOSI_LINJE_LEN) {
+ LC_Error(131,"(LC_UpdatePiKvalitet)",temp);
+ }
+
+ /* Lagre strengen */
+ return LC_PutPi(pnr,temp);
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-930609
+CH LC_GetGP Get GINFO-parameter
+CD ==========================================================================
+CD Formål:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Leddnummer, delstreng,skilletegn og formateringskode kan inngå som
+CD forlengelse av SOSI-navnet.
+CD
+CD Leddnummer for flerleddet parameter angis ved #n.
+CD Eks: ..GID#2 er bruksnummer.
+CD
+CD Delstreng angis ved: [start:slutt].
+CD NB! 1 er første tegn.
+CD Sluttposisjon 0 betyr at resten av strengen skal brukes.
+CD Eks: ..STRENG[2:0] Posisjon 2 og resten av strengen.
+CD
+CD Skilletegn for flerleddet GINFO. Dette angis ved ^x hvor x er det tegnet
+CD som skal skrives ut mellom leddene.
+CD
+CD Formateringskode. Dette brukes for å angi plassering av komma og antall
+CD desimaler i desimaltall.
+CD Eks: ..AREAL%-3.2 Betyr at ..AREAL fra GINFO skal formateres slik:
+CD Komma flyttes 3 posisjoner til venstre (divisjon med tusen) og resultatet
+CD presenteres avrundet til 2 desimaler.
+CD
+CD Eks: ..DYBDE£-1.2 Betyr at ..DYBDE fra GINFO skal formateres slik:
+CD Komma flyttes 1 posisjon til venstre (divisjon med ti) og resultatet
+CD presenteres med 2 desimaler uten avrunding. Spesielt for dybdeverdier.
+CD
+CD Disse tilleggene kan kombineres, slik at ..GID#2[1:2] betyr at det er
+CD tegn nummer 1 og 2 i det andre leddet (bruksnumret) som skal brukes.
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char sosi_navn i SOSI-navn det skal finnes verdi til.
+CD Leddnummer, posisjon, skilletegn
+CD og formateringskode kan inngå
+CD som forlengelse av navnet.
+CD OBS! Store og små bokstaver er signifikante.
+CD
+CD short *forste_linje iu GINFO-linjenummer for start søking
+CD (1 er første linje i GINFO.)
+CD Ved tilslag returneres linjenummer for tilslaget.
+CD short siste_linje i Siste GINFO-linje det skal søkes i.
+CD char *para_peker r Peker til parameter-streng avslutta med '\0'.
+CD Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD para_peker = LC_GetGP(sosi_navn,&forste_linje,siste_linje);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetGP(const char *sosi_navn,short *forste_linje,short siste_linje)
+{
+ short gi_lin,sAntallBlank,sSosiLen,sFortegn,s;
+ char *ginfo,*cp,*nt,*cs,szSosiNavn[LC_MAX_SOSINAVN_LEN];
+ double d;
+ char cSkilleTegn = '\0';
+ short sLedd = 0;
+ short sStart = 0;
+ short sSlutt = 0;
+ short funnet = 0;
+ short sFormater = UT_FALSE;
+ short sFlyttKomma = 0; /* Flytting av komma ( <0 flytt til venstre) */
+ short sAntDes = 2; /* Antall desimaler */
+
+ char *rp = NULL; /* Retur peker */
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Sjekk at det er lovlige linjenummer */
+ if (*forste_linje < 1) *forste_linje = 1;
+ if (siste_linje > Sys.pGrInfo->ngi) siste_linje = Sys.pGrInfo->ngi;
+
+ /* Plukk ut info om ledd, delstreng og formatering */
+ UT_StrCopy(szSosiNavn,sosi_navn,LC_MAX_SOSINAVN_LEN);
+ UT_StrUpper(szSosiNavn);
+
+ if ((cs = strpbrk(szSosiNavn,"#[^%£")) != NULL) {
+ cp = cs;
+ while (*cp != '\0') {
+ if (*cp == '#') {
+ ++cp;
+ sLedd = (short) strtol(cp,&cp,10); /* Ledd-nummer */
+ } else if (*cp == '^') {
+ ++cp;
+ cSkilleTegn = *cp; /* Skilletegn */
+ ++cp;
+ } else if (*cp == '[') {
+ ++cp;
+ sStart = (short) strtol(cp,&cp,10); /* Startposisjon */
+ ++cp;
+ sSlutt = (short) strtol(cp,&cp,10); /* Sluttposisjon */
+ } else if ((*cp == '%') || (*cp == '£')) {
+ if(*cp == '£')
+ sFormater = 2;
+ else
+ sFormater = UT_TRUE;
+ ++cp;
+ if (*cp == '-') {
+ sFortegn = -1;
+ ++cp;
+ } else {
+ sFortegn = 1;
+ }
+ if (isdigit(*cp)) sFlyttKomma = (short) strtol(cp,&cp,10); /* Flytting av komma */
+ sFlyttKomma *= sFortegn;
+ if (*cp == '.') ++cp;
+ if (isdigit(*cp)) sAntDes = (short) strtol(cp,&cp,10); /* Ant. des */
+ } else {
+ ++cp;
+ }
+ }
+ /* Fjern tilleggsinfo fra SOSI-navnet */
+ *cs = '\0';
+ }
+
+ /* Søk etter SOSI-navnet */
+ sSosiLen = (short)strlen(szSosiNavn);
+ gi_lin = *forste_linje;
+ while (gi_lin <= siste_linje) {
+ /* Les ny linje */
+ ginfo = LX_GetGi(gi_lin);
+
+ /* Er dette rett navn? */
+ if ((strncmp(ginfo,szSosiNavn,sSosiLen) == 0) &&
+ ( (UT_IsSpace(*(ginfo+sSosiLen)) || *(ginfo+sSosiLen) == '\0'))) {
+
+ /* Hopp over blanke mellom navn og verdi */
+ cp = ginfo + sSosiLen;
+ while (UT_IsSpace(*cp)) {
+ ++cp;
+ }
+ // Kopier parameter
+ UT_StrCopy(retur_str,cp,LC_MAX_SOSI_LINJE_LEN);
+ rp = retur_str;
+
+ // Har ikke ledd , funnet OK
+ if (sLedd == 0) {
+
+
+ //Fjerner hermetegn " eller ' foran
+ while (*rp == '"' || *rp == '\'')
+ ++rp;
+
+ //Finner enden av strengen
+ cp = strchr(rp+1,'\0');
+
+ //Går framover fra enden og fjerner anførselstegn
+ while (cp-- && (*cp == '"' || *cp == '\'') && cp != NULL)
+ *cp = '\0';
+
+ funnet = 1;
+ // Husk linjenummeret
+ *forste_linje = gi_lin;
+ break; // Funnet, ==> hopp ut av løkken
+
+ // Handter leddnummer
+ } else {
+ s = sLedd;
+ cs = rp+strlen(rp); // Markerer slutten av parameterstrengen
+ while(s > 0) {
+ if(s-- == sLedd) { // Første ledd leses
+ cp = UT_strtok(rp," ",&nt);
+ }
+ else { // Neste ledd leses
+ cp = UT_strtok(NULL," ",&nt);
+ }
+ if (cp != NULL) {
+ // Test på hermetegn
+ if (*cp == '"') {
+ if((cp+strlen(cp)) != cs) { // Dersom ikke slutten av parameterstrengen
+ *(cp+strlen(cp)) = ' '; // Setter tilbake space for NULL
+ }
+ rp = cp+1; // Unngår start-hermetegnet
+ cp = UT_strtok(rp,"\"",&nt); // Leser til slutt-hermetegnet eller \0
+ }
+ else if (*cp == '\'') {
+ if((cp+strlen(cp)) != cs) { // Dersom ikke slutten av parameterstrengen
+ *(cp+strlen(cp)) = ' '; // Setter tilbake space for NULL
+ }
+ rp = cp+1; // Unngår start-hermetegnet
+ cp = UT_strtok(rp,"'",&nt); // Leser til slutt-hermetegnet eller \0
+ }
+ }
+ else { // cp == NULL
+ break;
+ }
+ }
+
+ /* Leddet er funnet */
+ if (cp != NULL) {
+ /* Aktuelt ledd huskes */
+ rp = cp;
+ funnet = 1;
+ /* Husk linjenummeret */
+ *forste_linje = gi_lin;
+ break; /* Funnet, ==> hopp ut av løkken */
+
+ } else {
+ /* AR-950901 */
+ /* rp = NULL; */ /* Det aktuelle leddet finnes ikke */
+ /* Aktuellt ledd huskes */
+ rp = strchr(rp,'\0');
+ funnet = 1;
+ /* Husk linjenummeret */
+ *forste_linje = gi_lin;
+ break; /* Funnet, ==> hopp ut av l›kken */
+ }
+ }
+ }
+
+ ++gi_lin;
+ }
+
+ /* Spesialnavn */
+ if ( ! funnet && (*szSosiNavn != '.' && ((*forste_linje <= siste_linje) || (siste_linje == 1)))) {
+ /* Handter AREAL spesielt*/
+ if (strcmp(szSosiNavn,"AREAL") == 0) {
+ d = LC_BerAreal();
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter LENGDE spesielt */
+ } else if (strcmp(szSosiNavn,"LENGDE") == 0) {
+ if ( ! LC_BerLengde3D(&d)){
+ d = LC_BerLengde();
+ }
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter LENGDE_HORISONTAL spesielt */
+ } else if (strcmp(szSosiNavn,"LENGDE_HORISONTAL") == 0) {
+ d = LC_BerLengde();
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter LENGDE_AVGRENS spesielt */
+ } else if (strcmp(szSosiNavn,"LENGDE_AVGRENS") == 0) {
+ d = LC_BerAvgrensLengde();
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter LENGDE_YTRE_AVGRENS spesielt */
+ } else if (strcmp(szSosiNavn,"LENGDE_YTRE_AVGRENS") == 0) {
+ d = LC_BerYtreAvgrensLengde();
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter LENGDE_INDRE_AVGRENS spesielt */
+ } else if (strcmp(szSosiNavn,"LENGDE_INDRE_AVGRENS") == 0) {
+ d = LC_BerIndreAvgrensLengde();
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+ sFormater = UT_FALSE; /* Formatering er utført */
+
+ /* Handter SNR spesielt */
+ } else if (strcmp(szSosiNavn,"SNR") == 0) {
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld",LC_GetSn());
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+
+ /* Handter NPT spesielt */
+ } else if (strcmp(szSosiNavn,"NPT") == 0) {
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", Sys.pGrInfo->nko);
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+
+ // Handter REF_FRA spesielt (referert fra antall grupper)
+ } else if (strcmp(szSosiNavn,"REF_FRA") == 0) {
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", LC_ErReferertFraAntall());
+ rp = retur_str;
+
+ // Handter NPT_REF spesielt antall punkt referert
+ } else if (strcmp(szSosiNavn,"NPT_REF") == 0) {
+
+ if(Sys.pGrInfo->info & GI_REF)
+ {
+ // Gruppen har referanser
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_POLYGON Polygon;
+ LC_POL_ELEMENT * pPE;
+ LC_OY_ELEMENT * pOE;
+ long lSumNko = 0;
+
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ // Ytre avgrensning
+ for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_GetGrParaBgr(&pPE->Bgr,&ngi,&nko,&info);
+ lSumNko += nko;
+ }
+
+ // Indre avgrensning
+ for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_GetGrParaBgr(&pPE->Bgr,&ngi,&nko,&info);
+ lSumNko += nko;
+ }
+ }
+
+ // Frigi allokerte kjeder
+ LC_POL_FrigiPolygon(&Polygon);
+
+ //Lag returstrengen
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%ld", lSumNko);
+ }
+
+ else
+ {
+ // Har ikke referanser
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd", 0);
+ }
+
+ *forste_linje = siste_linje + 1;
+ rp = retur_str;
+
+
+ /* Handter KVALITET spesielt */
+ } else if (strcmp(szSosiNavn,"KVALITET") == 0) {
+ short sMetode, sSynbarhet, sHoydeMetode;
+ long lNoyaktighet, lHoydeNoyaktighet;
+ short nivaa = 2;
+ /* Funnet kvalitet? */
+ if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,1,
+ &sMetode,&lNoyaktighet,&sSynbarhet,
+ &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+ /* Formater kvaliteten */
+ UT_StrCopy(retur_str,
+ LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+ LC_MAX_SOSI_LINJE_LEN);
+ rp = retur_str;
+ }
+ *forste_linje = siste_linje + 1;
+ }
+ }
+
+ /* Har funnet navnet */
+ //if (rp != NULL) {
+ if ((rp != NULL) && (*rp != '\0')) { //22.11.2007 AR/ÅE Stopper tom variabel som har adresse
+ /* Handter delstreng */
+ if (sStart != 0) {
+ if (sSlutt != 0 && sSlutt < (short)strlen(rp)) {
+ *(rp+sSlutt) = '\0';
+ }
+ sStart = min(sStart,((short)strlen(rp)));
+ rp += (sStart-1);
+ }
+
+ /* Handter skilletegn */
+ if (cSkilleTegn != '\0') {
+ /* Skann hele strengen */
+ sAntallBlank = 0;
+ cp = cs = rp;
+ while (*cp) {
+ if (*cp == ' ') { /* Funnet blank */
+ if (sAntallBlank == 0) { /* Første i dette mellomrommet */
+ *(cs++) = cSkilleTegn;
+ }
+ ++cp;
+ ++sAntallBlank;
+
+ } else { /* Kopier og pakk strengen */
+ *(cs++) = *(cp++);
+ sAntallBlank = 0;
+ }
+ }
+ *cs = '\0';
+ }
+
+ /* Handter formateringskode */
+ if (sFormater == 2) { // Desimaltallet skal ikke avrundes
+ // Fjerner unødvendige desimaler fra tall for å unngå avrunding
+ cp = rp;
+ short sTeller=-99;
+ while (*cp) {
+ if (*cp == '.') // Funnet skilletegn
+ sTeller = -1;
+ if(sTeller>-99)
+ if(sTeller++==sAntDes) {
+ *cp = '\0';
+ break;
+ }
+ ++cp;
+ }
+ }
+ if (sFormater) {
+ UT_AtoD (rp,'.',&d);
+ d *= pow((double)10.0,(int)sFlyttKomma);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%.*f",sAntDes,d);
+ rp = retur_str;
+ }
+
+ }
+ }
+
+ return rp;
+}
+
+
+/*
+AR-920615
+CH LC_GetPiVerdi Get PINFO-verdi
+CD ==========================================================================
+CD Formål:
+CD Henter parametrene til et SOSI-navn.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk UT_StrCopy).
+CD
+CD Leddnummer, delstreng og formateringskode kan inngå som
+CD forlengelse av SOSI-navnet.
+CD
+CD Leddnummer for flerleddet parameter angis ved #n.
+CD Eks: ...KVALITET#2 er nøyaktighet.
+CD
+CD Delstreng angis ved: [start:slutt].
+CD NB! 1 er første tegn.
+CD Sluttposisjon 0 betyr at resten av strengen skal brukes.
+CD Eks: ..STRENG[2:0] Posisjon 2 og resten av strengen.
+CD
+CD Formateringskode kan angi skilletegn for flerleddet PINFO. Dette
+CD angis ved ^x hvor x er det tegnet som skal skrives ut mellom leddene.
+CD
+CD Disse tilleggene kan kombineres, slik at ...KVALITET#2[1:2] betyr at
+CD det er tegn nummer 1 og 2 i det andre leddet (nøyaktigheten) som skal
+CD brukes.
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char pszSosiNavn i SOSI-navn det skal finnes verdi til.
+CD Leddnummer posisjon og formateringskode kan
+CD inngå som forlengelse av navnet.
+CD OBS! Store og små bokstaver er signifikante.
+CD HØYDE er spesialverdi som henter formatert
+CD høyde fra punktet eller GINFO.
+CD KVALITET er spesialverdi som henter formatert
+CD kvalitet fra punktet, GINFO eller hode.
+CD long lPnr i Punktnummer
+CD short *sSettNr iu PINFO-nummer (1 er første sett i PINFO.)
+CD Ved tilslag returneres settnummer for tilslaget.
+CD char *pszVerdi r Peker til verdien avslutta med '\0'.
+CD Hvis SOSI-navnet ikke er funnet returneres NULL.
+CD
+CD Bruk:
+CD pszVerdi = LC_GetPiVerdi(pszSosiNavn,lPnr,&sSettNr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPiVerdi(const char *pszSosiNavn,long lPnr,short *sSettNr)
+{
+ short lin,i,sAntallBlank;
+ char *cp,*cs,*nt,szSosiNavn[LC_MAX_SOSINAVN_LEN];
+ short sAntDes,niv;
+ char format[20];
+ double enhet,enhet_h,enhet_d,h;
+ char cSkilleTegn = '\0';
+ short sLedd = 0;
+ short sStart = 0;
+ short sSlutt = 0;
+ short funnet = UT_FALSE;
+ char *rp = NULL; /* Retur peker */
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (lPnr > 0 && lPnr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ /* Er søkebuffer oppbygd ? */
+ if (Sys.sPibufStatus != LC_PIBUF_OK || Sys.lPibufPnr != lPnr) {
+ LX_CreatePibuf(lPnr);
+ }
+
+ if (Sys.sPibufStatus != LC_PIBUF_OK) {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," \"%s\" pnr: %ld",LX_GetGi(1),lPnr);
+ LC_Error(55,"(LC_GetPiVerdi)",err().tx);
+ return NULL;
+
+ } else {
+
+ /* Sjekk at det er lovlige linjenummer */
+ if (*sSettNr < 1) {
+ *sSettNr = 1;
+ }
+ lin = *sSettNr - 1;
+
+ /* Plukk ut info om ledd, delstreng og formatering */
+ UT_StrCopy(szSosiNavn,pszSosiNavn,LC_MAX_SOSINAVN_LEN);
+ if ((cs = strpbrk(szSosiNavn,"#[^")) != NULL) {
+ cp = cs;
+ for (i=0;i<3;++i) {
+ if (*cp == '#') {
+ ++cp;
+ sLedd = (short) strtol(cp,&cp,10); /* Ledd-nummer */
+ } else if (*cp == '^') {
+ ++cp;
+ cSkilleTegn = *cp; /* Skilletegn */
+ ++cp;
+ } else if (*cp == '[') {
+ ++cp;
+ sStart = (short) strtol(cp,&cp,10); /* Startposisjon */
+ ++cp;
+ sSlutt = (short) strtol(cp,&cp,10); /* Sluttposisjon */
+ }
+ }
+ /* Fjern tilleggsinfo fra SOSI-navnet */
+ *cs = '\0';
+ }
+
+
+ /* -------- Vanlig PINFO */
+ /* Søk etter SOSI-navnet */
+ while (lin < Sys.sPibufAntPi) {
+ if (strcmp(Sys.pcPibufNavn[lin],szSosiNavn) == 0) {
+ funnet = UT_TRUE;
+ /* Kopier parameter */
+ UT_StrCopy(retur_str,Sys.pcPibufVerdi[lin],LC_MAX_SOSI_LINJE_LEN);
+ break; /* Funnet, ==> hopp ut av løkken */
+ }
+ ++lin;
+ }
+
+ /* -------- Knutepunkt */
+ if (!funnet) {
+ if (lin < (Sys.sPibufAntPi+1) &&
+ strcmp(szSosiNavn,"...KP") == 0) {
+ if ((i = LC_GetKp(lPnr)) != 0) { /* Funnet KP */
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd",i);
+ funnet = UT_TRUE;
+ }
+ lin = Sys.sPibufAntPi + 1;
+
+ /* -------- Høyde */
+ } else if (lin < (Sys.sPibufAntPi+2) &&
+ strcmp(szSosiNavn,"HØYDE") == 0) {
+ if ((h = LC_GetHoyde(lPnr)) != HOYDE_MANGLER) { /* Funnet høyde */
+
+ /* Hent enhet og formater høyden */
+ niv = 2;
+ LC_GetCurEnhet(Sys.GrId.pFil,&niv,&enhet,&enhet_h,&enhet_d);
+ sAntDes = UT_RoundDS(fabs(min(0.0,log10(enhet_h))));
+ UT_SNPRINTF(format,20,"%%.%dlf",sAntDes);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,format,h);
+ funnet = UT_TRUE;
+ }
+ lin = Sys.sPibufAntPi + 2;
+
+ /* -------- Kvalitet */
+ } else if (lin < (Sys.sPibufAntPi+3) &&
+ strcmp(szSosiNavn,"KVALITET") == 0) {
+ short sMetode, sSynbarhet, sHoydeMetode;
+ long lNoyaktighet, lHoydeNoyaktighet;
+ short nivaa = 3;
+ /* Funnet kvalitet? */
+ if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,lPnr,
+ &sMetode,&lNoyaktighet,&sSynbarhet,
+ &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+ /* Formater kvaliteten */
+ UT_StrCopy(retur_str,
+ LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+ LC_MAX_SOSI_LINJE_LEN);
+ funnet = UT_TRUE;
+ }
+ lin = Sys.sPibufAntPi + 3;
+ }
+ }
+
+ /* Klargjør for retur */
+ *sSettNr = lin+1;
+ if (funnet) {
+ rp = retur_str;
+
+ /* Handter leddnummer */
+ if (sLedd != 0) {
+ cp = UT_strtok(rp," ",&nt);
+ while(cp != NULL && --sLedd > 0){
+ cp = UT_strtok(NULL," ",&nt);
+ }
+ if (cp == NULL) {
+ *rp = '\0';
+ } else {
+ rp = cp;
+ }
+ }
+
+ /* Handter delstreng */
+ if (sStart != 0) {
+ if (sSlutt != 0 && sSlutt < (short)strlen(rp)) {
+ *(rp+sSlutt) = '\0';
+ }
+ sStart = min(sStart,((short)strlen(rp)));
+ rp += (sStart-1);
+ }
+
+ /* Handter skilletegn */
+ if (cSkilleTegn != '\0') {
+ /* Skann hele strengen */
+ sAntallBlank = 0;
+ cp = cs = rp;
+ while (*cp) {
+ if (*cp == ' ') { /* Funnet blank */
+ if (sAntallBlank == 0) { /* Første i dette mellomrommet */
+ *(cs++) = cSkilleTegn;
+ }
+ ++cp;
+ ++sAntallBlank;
+
+ } else { /* Kopier og pakk strengen */
+ *(cs++) = *(cp++);
+ sAntallBlank = 0;
+ }
+ }
+ *cs = '\0';
+ }
+ }
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),lPnr);
+ LC_Error(51,"(LC_GetPiVerdi)",err().tx);
+ }
+ }
+
+ return rp;
+}
+
+
+/*
+AR-920614
+CH LX_CreatePibuf Generer PINFO-buffer
+CD ==========================================================================
+CD Formål:
+CD Henter PINFO for gitt punkt og legger den inn i et buffer.
+CD Det bygges opp en tabell med pekere til starten av hvert SOSI-navn og
+CD hver verdi.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long lPnr i Punktnummer.
+CD
+CD Bruk:
+CD LX_CreatePibuf(lPnr);
+ ==========================================================================
+*/
+static void LX_CreatePibuf(long lPnr)
+{
+ short sAntPi;
+ char *pp,*cp;
+ char *bp = Sys.cPibuf ;
+
+ *Sys.cPibuf = '\0';
+
+ sAntPi = 0;
+ pp = LC_GetPi(lPnr);
+
+ /* For lang pinfo */
+ if (strlen(pp) > LC_MAX_PIBUF_TEGN) {
+ Sys.sPibufStatus = LC_PIBUF_FULL;
+ return;
+ }
+
+ /* Finn første/neste SOSI-navn */
+ while ((cp = strstr(pp,"...")) != NULL) { /* SOSI-navn */
+ ++sAntPi;
+
+ /* Sjekk om det er nok plass i tabell for peker til PINFO-linje */
+ if (sAntPi > LC_MAX_PIBUF_LIN){
+ Sys.sPibufStatus = LC_PIBUF_FULL;
+ return;
+ }
+
+ pp = cp;
+ Sys.pcPibufNavn[sAntPi-1] = bp;
+ while (!UT_IsSpace(*pp) && *pp != '\0') {
+ *bp++ = *pp++;
+ }
+ *bp++ = '\0';
+
+ /* Hopp over blanke mellom navn og verdi */
+ while (UT_IsSpace(*pp)) {
+ ++pp;
+ }
+
+ /* Ta vare på verdien */
+
+ if (*pp == '"') { /* Hermetegn */
+ if ((cp = strchr(pp+1,'"')) != NULL) { /* Slutt-hermetegn */
+ ++pp;
+ *cp++ = '\0';
+ cp = strstr(cp," ..."); /* Neste SOSI-navn */
+
+ } else {
+ UT_ClrTrailsp(pp); /* Fjern blanke på slutten */
+ }
+
+ } else if ((cp = strstr(pp," ...")) != NULL) { /* SOSI-navn */
+ *cp++ = '\0';
+ UT_ClrTrailsp(pp); /* Fjern blanke på slutten */
+
+ } else if ((cp = strchr(pp,'!')) != NULL) { /* Kommentar */
+ *cp = '\0';
+ UT_ClrTrailsp(pp); /* Fjern blanke på slutten */
+ cp = NULL;
+
+ } else {
+ /* Linjeslutt cp = NULL*/
+ UT_ClrTrailsp(pp); /* Fjern blanke på slutten */
+ }
+
+ /* Kopier strengen */
+ Sys.pcPibufVerdi[sAntPi-1] = bp;
+ while (*pp) {
+ *bp++ = *pp++;
+ }
+ *bp++ = '\0';
+
+ /* Neste sett */
+ if (cp != NULL) {
+ pp = cp;
+ }
+ }
+
+ Sys.lPibufPnr = lPnr;
+ Sys.sPibufAntPi = sAntPi; /* Antall elementer brukt i Pibuf */
+ Sys.sPibufStatus = LC_PIBUF_OK;
+}
+
+
+/*
+AR-891001
+CH LC_PutGP Put GINFO-parameter
+CD ==========================================================================
+CD Formål:
+CD Legger inn et SOSI-navn med verdi.
+CD Denne rutinen kan brukes til å legge inn ginfo med nytt SOSI-navn.
+CD Rutinen kan endre antall ginfo-linjer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char sosi_navn i Sosi-navn det skal legges inn verdi til
+CD char verdi i Streng som skal legges inn.
+CD short *linje_nr u Linjenummer for endringen.
+CD short ngi r Ant. ginfo-linjer etter endringen.
+CD
+CD Bruk:
+CD ngi = LC_PutGP(sosi_navn,verdi,&linje_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutGP(const char *sosi_navn,const char *verdi,short *linje_nr)
+{
+ char temp[LC_MAX_SOSI_LINJE_LEN];
+
+
+
+#ifdef TEST
+
+************************************************************
+ short sLedd = 0;
+ short funnet = 0;
+
+ char *rp = NULL; /* Retur peker */
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ /* Plukk ut info om ledd */
+ UT_StrCopy(szSosiNavn,sosi_navn,LC_MAX_SOSINAVN_LEN);
+ UT_StrUpper(szSosiNavn);
+
+ if ((cs = strchr(szSosiNavn,'#')) != NULL) {
+ cp = cs;
+ ++cp;
+ sLedd = (short) strtol(cp,&cp,10); /* Ledd-nummer */
+ /* Fjern tilleggsinfo fra SOSI-navnet */
+ *cs = '\0';
+ }
+
+ /* Søk etter SOSI-navnet */
+ sSosiLen = strlen(szSosiNavn);
+ gi_lin = *forste_linje;
+ while (gi_lin <= siste_linje) {
+ /* Les ny linje */
+ ginfo = LX_GetGi(gi_lin);
+
+ /* Er dette rett navn? */
+ if ((strncmp(ginfo,szSosiNavn,sSosiLen) == 0) &&
+ ( (UT_IsSpace(*(ginfo+sSosiLen)) || *(ginfo+sSosiLen) == '\0'))) {
+
+ /* Hopp over blanke mellom navn og verdi */
+ cp = ginfo + sSosiLen;
+ while (UT_IsSpace(*cp)) {
+ ++cp;
+ }
+ /* Kopier parameter */
+ rp = strcpy(retur_str,cp);
+
+ /* Fjern hermetegn (") */
+ if (*rp == '"') {
+ if ((cp = strchr(rp+1,'"')) != NULL) { /* Slutt-hermetegn */
+ ++rp;
+ *cp = '\0';
+ }
+ }
+
+ /* Fjern hermetegn (') */
+ if (*rp == '\'') {
+ if ((cp = strchr(rp+1,'\'')) != NULL) { /* Slutt-hermetegn */
+ ++rp;
+ *cp = '\0';
+ }
+ }
+
+ /* Har ikke ledd , funnet OK */
+ if (sLedd == 0) {
+ funnet = 1;
+ /* Husk linjenummeret */
+ *forste_linje = gi_lin;
+ break; /* Funnet, ==> hopp ut av løkken */
+
+ /* Handter leddnummer */
+ } else {
+ cp = strtok(rp," ");
+ s = sLedd;
+ while(cp != NULL && --s > 0){
+ cp = strtok(NULL," ");
+ }
+
+ /* Leddet er funnet */
+ if (cp != NULL) {
+ /* Aktuellt ledd huskes */
+ rp = cp;
+ funnet = 1;
+ /* Husk linjenummeret */
+ *forste_linje = gi_lin;
+ break; /* Funnet, ==> hopp ut av løkken */
+
+ } else {
+ /* AR-950901 */
+ /* rp = NULL; */ /* Det aktuelle leddet finnes ikke */
+ /* Aktuellt ledd huskes */
+ rp = strchr(rp,'\0');
+ funnet = 1;
+ /* Husk linjenummeret */
+ *forste_linje = gi_lin;
+ break; /* Funnet, ==> hopp ut av l›kken */
+ }
+ }
+ }
+
+ ++gi_lin;
+ }
+
+ /* Har funnet navnet */
+ if (rp != NULL) {
+
+ /* Handter delstreng */
+ if (sStart != 0) {
+ if (sSlutt != 0 && sSlutt < (short)strlen(rp)) {
+ *(rp+sSlutt) = '\0';
+ }
+ sStart = min(sStart,((short)strlen(rp)));
+ rp += (sStart-1);
+ }
+
+*****************************************************************
+#endif
+
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ *linje_nr = 2;
+ if (LC_GetGP(sosi_navn,linje_nr,Sys.pGrInfo->ngi) != NULL){ /* Finn linjen */
+ /* Legg inn endringen */
+ LC_UpdateGP(*linje_nr,sosi_navn,verdi);
+
+ } else{ /* Ikke funnet, ny linje */
+ *linje_nr = LC_AppGiL();
+ UT_StrCopy(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCopy(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCopy(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+ LC_PutGi(*linje_nr,temp);
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutGP)","");
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR:2010-02-09
+CH LC_AppGP Legg til GINFO-parameter
+CD ==========================================================================
+CD Formål:
+CD Legger til et SOSI-navn med verdi i GINFO.
+CD Lik LC_PutGP, men legger alltid til ny linje i ginfo.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char sosi_navn i Sosi-navn det skal legges inn verdi til
+CD char verdi i Streng som skal legges inn.
+CD short *linje_nr u Linjenummer for endringen.
+CD short ngi r Ant. ginfo-linjer etter endringen.
+CD
+CD Bruk:
+CD ngi = LC_AppGP(sosi_navn,verdi,&linje_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_AppGP(const char *sosi_navn,const char *verdi,short *linje_nr)
+{
+ char temp[LC_MAX_SOSI_LINJE_LEN];
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ *linje_nr = LC_AppGiL();
+ UT_StrCopy(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCopy(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCopy(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+ LC_PutGi(*linje_nr,temp);
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_AppGP)","");
+ }
+
+ return Sys.pGrInfo->ngi;
+}
+
+
+/*
+AR-891001
+CH LC_UpdateGP Endre GINFO-parameter
+CD ==========================================================================
+CD Formål:
+CD Legger inn parametren til et SOSI-navn.
+CD Rutinen handterer at det er flere SOSI-navn på samme linje.
+CD OBS! Denne rutinen kan ikke brukes til å legge inn nytt SOSI-navn.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short linje_nr i Linjenummer som skal endres.
+CD char sosi_navn i Sosi-navn det skal legges inn verdi til
+CD char verdi i Streng som skall legges inn
+CD short ist r 1=ok, 0=navnet er ikke funnet
+CD
+CD Bruk:
+CD ist = LC_UpdateGP(linje_nr,sosi_navn,verdi);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_UpdateGP(short linje_nr,const char *sosi_navn,const char *verdi)
+{
+ char temp[LC_MAX_SOSI_LINJE_LEN],*gp,*neste,*cp;
+ short ist=0;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ gp = LC_GetGi(linje_nr);
+ if ((neste = strstr(gp,sosi_navn)) != NULL){ /* Finn SOSI-navnet */
+
+ cp = neste - 1; /* Avslutt første del av ginfo */
+ while (cp >= gp && UT_IsSpace(*cp)){
+ cp--;
+ }
+ *(cp+1) = '\0';
+
+ neste += strlen(sosi_navn); /* Hopp over SOSI-navnet */
+
+ while (UT_IsSpace(*neste)) /* Ledende blanke */
+ ++neste;
+
+ if (*neste == '"' && (cp = strchr(neste+1,'"')) != NULL){ /* Hermetegn */
+ neste = cp + 1;
+ while (UT_IsSpace(*neste)){ /* Blanke */
+ ++neste;
+ }
+
+ } else if ((cp = strstr(neste-1," ..")) != NULL) { /* SOSI-navn */
+ neste = cp + 1;
+
+ } else if ((cp = strchr(neste,'!')) != NULL) { /* Kommentar */
+ neste = cp;
+
+ } else{ /* Slutten av strengen */
+ neste = strchr(neste,'\0');
+ }
+
+ /* Legg inn endringen */
+ *temp = '\0';
+ if (*gp){ /* Første del */
+ UT_StrCat(temp,gp,LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ }
+ UT_StrCat(temp,sosi_navn,LC_MAX_SOSI_LINJE_LEN); /* Aktuellt navn */
+ UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp,verdi,LC_MAX_SOSI_LINJE_LEN);
+ if (*neste){ /* Siste del */
+ UT_StrCat(temp," ",LC_MAX_SOSI_LINJE_LEN);
+ UT_StrCat(temp,neste,LC_MAX_SOSI_LINJE_LEN);
+ }
+
+ LC_PutGi(linje_nr,temp);
+ ist = 1;
+ }
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_UpdateGP)","");
+ }
+
+ return ist;
+}
+
+
+/*
+AR-881113
+CH LC_InitPP Initier PINFO-søk
+CD ==========================================================================
+CD Formål:
+CD Initierer søk etter PINFO.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD char sosi_navn i Sosi-navn det skal finnes verdi til
+CD long forste_punkt i Første punkt. (1 er første pkt i gr)
+CD long siste_punkt i Siste punkt det skal søkes i
+CD LC_GETPP_STATUS pp_stat iu Struktur med statusvariabler. Denne er
+CD bare for intern bruk i InitPP / GetPP.
+CD
+CD Bruk:
+CD Se under LC_GetPP.
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_InitPP(char *sosi_navn,long forste_punkt,long siste_punkt,
+ LC_GETPP_STATUS *pp_stat)
+{
+ short itxu;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+
+ UT_StrToken(sosi_navn,0,&itxu,LC_MAX_SOSINAVN_LEN,pp_stat->pinfo_navn); /* SOSI-navnet */
+ UT_StrUpper(pp_stat->pinfo_navn);
+ pp_stat->slutt_punkt = min(siste_punkt,Sys.pGrInfo->nko) + 1;
+
+ /* -------- Knutepunkt */
+ if (strcmp(pp_stat->pinfo_navn,"...KP") == 0){
+ pp_stat->type = LC_GETPP_KP;
+ pp_stat->curr_punkt = max(forste_punkt,1) -1; /* Sjekk punktnummer */
+
+ /* -------- Høyde */
+ } else if (strcmp(pp_stat->pinfo_navn,"HØYDE") == 0) {
+ pp_stat->type = LC_GETPP_HOYDE;
+ pp_stat->curr_punkt = max(forste_punkt,1) -1; /* Sjekk punktnummer */
+
+ /* -------- Kvalitet */
+ } else if (strcmp(pp_stat->pinfo_navn,"KVALITET") == 0) {
+ pp_stat->type = LC_GETPP_KVALITET;
+ pp_stat->curr_punkt = max(forste_punkt,1) -1; /* Sjekk punktnummer */
+
+ /* -------- Annen PINFO */
+ } else {
+ pp_stat->type = LC_GETPP_VANLIG;
+ pp_stat->neste_tegn = 0;
+ pp_stat->curr_punkt = max(forste_punkt,1); /* Sjekk punktnummer */
+ }
+ }
+}
+
+
+/*
+AR-890511
+CH LC_GetPP Utfør PINFO-søk
+CD ==========================================================================
+CD Formål:
+CD Henter parametrene til et SOSI-navn definert i LC_InitPP.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long *punkt u Ved tilslag returneres punktnummer for
+CD tilslaget.
+CD LC_GETPP_STATUS pp_stat iu Struktur med statusvariabler. Denne er
+CD bare for intern bruk i InitPP / GetPP.
+CD char *para_peker r Peker til para.-streng avslutta med '\0'.
+CD Hvis ingenting er funnet returneres NULL.
+CD
+CD Bruk:
+CD .
+CD LC_GETPP_STATUS pp_stat;
+CD .
+CD LC_InitPP(sosi_navn,forste_punkt,siste_punkt,pp_stat);
+CD para_peker = LC_GetPP(&punkt,pp_stat);
+CD .
+ =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPP(long *punkt,LC_GETPP_STATUS *pp_stat)
+{
+ short nt,kp_type,sAntDes,niv;
+ char format[20];
+ char *pinfo,*cp,*parameter;
+ char funnet_sosi[LC_MAX_SOSINAVN_LEN];
+ double enhet,enhet_h,enhet_d,h;
+
+
+ /* -------- Knutepunkt */
+ if (pp_stat->type == LC_GETPP_KP) {
+ pp_stat->curr_punkt++;
+ if (LC_FinnKp(&(pp_stat->curr_punkt), pp_stat->slutt_punkt-1, &kp_type)) { /* Søk */
+ *punkt = pp_stat->curr_punkt;
+ /* Lag parameter */
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,"%hd",kp_type);
+ return retur_str; /* OBS! RETURNERER HER! */
+
+ } else { /* Ikke funnet */
+ return NULL; /* OBS! RETURNERER HER! */
+ }
+
+ /* -------- Høyde */
+ } else if (pp_stat->type == LC_GETPP_HOYDE) {
+ pp_stat->curr_punkt++;
+
+ while (pp_stat->curr_punkt < pp_stat->slutt_punkt) { /* Søk etter navnet */
+ h = LC_GetHoyde(pp_stat->curr_punkt);
+ if (h != HOYDE_MANGLER) { /* Funnet høyde */
+ *punkt = pp_stat->curr_punkt;
+
+ /* Hent enhet og formater høyden */
+ niv = 2;
+ LC_GetCurEnhet(Sys.GrId.pFil,&niv,&enhet,&enhet_h,&enhet_d);
+
+ sAntDes = UT_RoundDS(fabs(min(0.0,log10(enhet_h))));
+ UT_SNPRINTF(format,20,"%%.%dlf",sAntDes);
+ UT_SNPRINTF(retur_str,LC_MAX_SOSI_LINJE_LEN,format,h);
+
+ return retur_str; /* OBS! RETURNERER HER! */
+
+ } else { /* Neste punkt */
+ pp_stat->curr_punkt++;
+ }
+ }
+
+ return NULL; /* Ikke funnet */
+
+ /* -------- Kvalitet */
+ } else if (pp_stat->type == LC_GETPP_KVALITET) {
+ short sMetode, sSynbarhet, sHoydeMetode;
+ long lNoyaktighet, lHoydeNoyaktighet;
+ short nivaa = 3;
+
+ pp_stat->curr_punkt++;
+
+ while (pp_stat->curr_punkt < pp_stat->slutt_punkt) { /* Søk etter navnet */
+
+ /* Funnet kvalitet? */
+ if (LC_GetCurKvalitet(Sys.GrId.pFil,&nivaa,pp_stat->curr_punkt,
+ &sMetode,&lNoyaktighet,&sSynbarhet,
+ &sHoydeMetode,&lHoydeNoyaktighet) == UT_TRUE) {
+ *punkt = pp_stat->curr_punkt;
+
+ /* Formater kvaliteten */
+ UT_StrCopy(retur_str,
+ LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,sHoydeMetode,lHoydeNoyaktighet),
+ LC_MAX_SOSI_LINJE_LEN);
+ return retur_str; /* OBS! RETURNERER HER! */
+
+ } else { /* Neste punkt */
+ pp_stat->curr_punkt++;
+ }
+ }
+
+ return NULL; /* Ikke funnet */
+
+ /* -------- Annen PINFO */
+ } else {
+ nt = pp_stat->neste_tegn;
+ while (pp_stat->curr_punkt < pp_stat->slutt_punkt){ /* Søk etter navnet */
+ pinfo = LC_GetPi(pp_stat->curr_punkt);
+ if (*pinfo){ /* Punktet har PINFO */
+ *punkt = pp_stat->curr_punkt;
+ while (*punkt == pp_stat->curr_punkt){
+ UT_StrToken(pinfo,nt,&nt,LC_MAX_SOSINAVN_LEN,funnet_sosi); /* SOSI-navn */
+ parameter = pinfo + nt;
+
+ if (strcmp(pp_stat->pinfo_navn,funnet_sosi) == 0){ /* Tilslag */
+ /* Finn parameter */
+ while (*parameter == ' ') /* Ledende blanke */
+ ++parameter;
+
+ if (*parameter == '"'){ /* Hermetegn */
+ if ((cp = strchr(parameter+1,'"')) != NULL){ /* Slutt-hermetegn */
+ ++parameter;
+ *cp = '\0';
+ }
+ } else if ((cp = strstr(parameter," ..")) != NULL){ /* SOSI-navn */
+ *cp = '\0';
+ nt = (short)(cp - pinfo + 1);
+
+ } else if ((cp = strchr(parameter,'!')) != NULL){ /* Kommentar */
+ *cp = '\0';
+ pp_stat->curr_punkt++;
+ nt = 0;
+ } else{ /* Linjeslutt */
+ pp_stat->curr_punkt++;
+ nt = 0;
+ }
+
+ pp_stat->neste_tegn = nt; /* Klargjør for retur */
+ return parameter; /* OBS! RETURNERER HER! */
+
+ } else{ /* Ikke tilslag, neste PINFO */
+ if ((cp = strstr(parameter," ..")) != NULL){ /* SOSI-navn */
+ nt = (short)(cp - pinfo + 1);
+ } else{ /* Linjeslutt */
+ pp_stat->curr_punkt++;
+ nt = 0;
+ }
+ }
+ }
+
+ } else {
+ pp_stat->curr_punkt++;
+ }
+ }
+ }
+
+ return NULL; /* Ikke funnet */
+}
+
+
+/*
+AR-930609
+CH LC_FinnKp Finn knutepunkt
+CD ==========================================================================
+CD Formål:
+CD Skanner gruppe, og finner punkt som er knutepunkt.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long *forste_punkt iu Punktnummer for start søking.
+CD (1 er første punkt i gruppen.)
+CD Ved tilslag returneres punktnummer for tilslaget.
+CD long siste_punkt i Siste punkt det skal søkes i.
+CD short *kp u Knutepunkt.
+CD short status r Søkestatus (1=funnet, 0=ikke funnet)
+CD
+CD Bruk:
+CD status = LC_FinnKp(&forste_punkt,siste_punkt,kp);
+ ==========================================================================
+*/
+short LC_FinnKp(long *forste_punkt,long siste_punkt,short *kp)
+{
+ long punkt;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ if(Sys.pGrInfo->info & GI_KP){ /* Gruppen har knutepunkt */
+ punkt = max(*forste_punkt,1); /* Sjekk punktnummer */
+ siste_punkt = min(siste_punkt,Sys.pGrInfo->nko);
+
+ /* Skann gruppen */
+ for (punkt--; punkt<siste_punkt; ++punkt) {
+ if ((Sys.pInfo+punkt)->sKp != 0) { /* KP ? */
+ *kp = (Sys.pInfo+punkt)->sKp;
+ *forste_punkt = punkt+1;
+ return(1);
+ }
+ }
+ }
+ }
+ return(0);
+}
+
+
+/*
+AR-890520
+CH LC_PutSn Put Serienummer
+CD ==========================================================================
+CD Formål:
+CD Legger inn nytt serienummer på aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long snr i Serienummer
+CD
+CD Bruk:
+CD LC_PutSn(snr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutSn(long snr)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+ /* Legger inn SNR og marker for endring */
+ LX_PutSn(snr);
+ Sys.sGrEndra = END_ENDRA;
+
+ } else{ /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutSn)","");
+ }
+}
+
+
+/*
+AR-930609
+CH LX_PutSn Lavnivå Put Serienummer
+CD ==========================================================================
+CD Formål:
+CD Legger inn nytt serienummer på aktuell gruppe, uten å sette flagg for at
+CD aktuell gruppe er oppdatert. Sjekker ikke om det er noen aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long snr i Serienummer
+CD
+CD Bruk:
+CD LX_PutSn(snr);
+ ==========================================================================
+*/
+void LX_PutSn(long snr)
+{
+ char szGinfo[LC_MAX_SOSI_LINJE_LEN],*cp;
+
+ /* Legger ikke inn serienr i hodet */
+ if (Sys.GrId.lNr > 0L) {
+ /* Kobler gml SOSI-navn med nytt SNR */
+ UT_StrCopy(szGinfo,Sys.Ginfo.pszTx,LC_MAX_SOSI_LINJE_LEN);
+
+ cp = szGinfo;
+ while (! UT_IsSpace(*cp) && *cp) {
+ ++cp;
+ }
+ *cp = '\0';
+
+ /* Heng på serienummer */
+ if (snr != 0L) {
+ char szOrd[50];
+ UT_SNPRINTF(szOrd, 50, " %ld:", snr);
+ UT_StrCat(szGinfo,szOrd,LC_MAX_SOSI_LINJE_LEN);
+ }
+
+ /* Linjen lagres */
+ LX_PutGi(1,szGinfo);
+ }
+}
+
+
+/*
+AR-930609
+CH LC_GetSn Get serienummer
+CD ==========================================================================
+CD Formål:
+CD Henter serienummer for aktuell gruppe.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------
+CD long snr r Serienr. (INGEN_GRUPPE = ingen aktuell gruppe)
+CD
+CD Bruk:
+CD snr = LC_GetSn();
+ ==========================================================================
+*/
+SK_EntPnt_FYBA long LC_GetSn(void)
+{
+ char *cp;
+
+ /* Aktuell gruppe OK */
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+ cp = strchr(LX_GetGi(1),' ');
+ if (cp != NULL) {
+ return atol(cp); /* ==> */
+ } else {
+ return 0L; /* ==> */
+ }
+ }
+
+ /* Ingen aktuell gruppe */
+ return INGEN_GRUPPE; /* ==> */
+}
+
+
+/*
+AR-930609
+CH LC_PutGi Put GINFO-linje
+CD ==========================================================================
+CD Formål:
+CD Legger inn GINFO-linje rent generellt.
+CD Dette omfatter også nytt gruppenavn (GINFO-linje 1)
+CD Ønsker du å endre serienummer må LC_PutSn benyttes.
+CD Referansenummer legges inn med LC_PutRef.
+CD Blanke på starten og slutten blir skrella vekk, og SOSI-navnet blir
+CD konvertert til "store" bokstaver, .ellers lagres det slik det er.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short lin_nr i Linjenummer i GINFO (1 er første linje)
+CD char *ginfo i GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD LC_PutGi(lin_nr,ginfo);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutGi(short lin_nr, const char *pszGinfo)
+{
+ // Aktuell gruppe OK
+ if (Sys.GrId.lNr != INGEN_GRUPPE)
+ {
+ // Lovlig linje ?
+ if (lin_nr > 0 && lin_nr <= Sys.pGrInfo->ngi)
+ {
+ // Gruppestart håndteres spesielt
+ if (lin_nr == 1)
+ {
+ char ginfo[LC_MAX_SOSI_LINJE_LEN];
+ char *ct;
+
+ /* Husk gammelt SNR */
+ long lGmlSnr = LC_GetSn();
+
+ // Fjern ledende blanke og kopier til lokal variabel
+ while (UT_IsSpace(*pszGinfo)) {
+ ++pszGinfo;
+ }
+ UT_StrCopy(ginfo,pszGinfo,LC_MAX_SOSI_LINJE_LEN);
+
+ /* Finn SOSI-navnet */
+ ct = ginfo;
+ while (*ct && ! UT_IsSpace(*ct)) {
+ ++ct;
+ }
+ *ct = '\0';
+
+ /* Heng på serienummer */
+ if (lGmlSnr != 0L) {
+ char szOrd[50];
+ UT_SNPRINTF(szOrd, 50, " %ld:", lGmlSnr);
+ UT_StrCat(ginfo,szOrd,LC_MAX_SOSI_LINJE_LEN);
+ }
+ LX_PutGi(lin_nr,ginfo);
+ }
+
+ else
+ {
+ LX_PutGi(lin_nr,pszGinfo);
+ }
+
+ /* Linjen lagres */
+
+ } else { /* Ulovlig linjenummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",lin_nr);
+ LC_Error(52,"(LC_PutGi)",err().tx);
+ }
+ }
+}
+
+
+
+/*
+AR-930609
+CH LX_PutGi Lavnivå put GINFO-linje
+CD ==========================================================================
+CD Formål:
+CD Lavnivå innlegging GINFO-linje rent generellt.
+CD Blanke på starten og slutten blir skrella vekk, og SOSI-navnet blir
+CD konvertert til "store" bokstaver, ellers lagres det slik det er.
+CD Sjekker også at det aktuelle SOSI-navnet er lovlig å oppdatere.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short lin_nr i Linjenummer i GINFO (1 er første linje)
+CD char *ginfo i GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD LX_PutGi(lin_nr,ginfo);
+ ==========================================================================
+*/
+static void LX_PutGi(short lin_nr, const char *szGinfo)
+{
+ short navn_nr,gr_start,dummy,sGmlLen,sNyLen;
+ char *cs,tmp,*ct;
+ double enhet,dNord,dAust;
+ char* pszNgisLag;
+ char ginfo[LC_MAX_SOSI_LINJE_LEN];
+ short sLagre = UT_TRUE;
+
+
+ Sys.sGrEndra = END_ENDRA;
+
+ /* Fjern blanke i starten og på slutten */
+ UT_StrCopy(ginfo,szGinfo,LC_MAX_SOSI_LINJE_LEN);
+ UT_ClrTrailsp(ginfo);
+
+ cs = ginfo;
+ while (UT_IsSpace(*cs))
+ {
+ ++cs;
+ }
+
+ // Sjekk at linjen ikke er for lang
+ if (strlen(cs) > (LC_MAX_SOSI_LINJE_LEN - 10))
+ {
+ *(cs + LC_MAX_SOSI_LINJE_LEN -10) = '\0';
+ UT_StrCat(ginfo, " ?????", LC_MAX_SOSI_LINJE_LEN);
+ LC_Error(134,"(LX_PutGi)",LX_GetGi(1));
+ }
+
+ /* Finn SOSI-navnet */
+ ct = cs;
+ while (*ct && ! UT_IsSpace(*ct))
+ {
+ ++ct;
+ }
+
+ /* Konv. SOSI-navnet til stor-bokstaver og finn navnenummer */
+ tmp = *ct;
+ *ct = '\0';
+ UT_StrUpper(cs);
+ gr_start = LN_FinnNavn(&(Sys.GrId.pFil->SosiNavn),cs,&navn_nr);
+ *ct = tmp;
+
+ /* Gruppestart */
+ if (lin_nr == 1) {
+ if (gr_start == 1) {
+ Sys.pGrInfo->gnavn = navn_nr; /* Husk gruppenavnet */
+
+ } else {
+ /* Melding om ukjent gruppestart */
+ LC_Error(54,"(LC_PutGi)",ginfo);
+ sLagre = UT_FALSE;
+ }
+
+ /* Annen GINFO */
+ } else {
+ if (gr_start > 0) {
+ /* ...ENHET i filhode på fil med data */
+ if (Sys.GrId.lNr == 0L && Sys.GrId.pFil->lAntGr > 1 && navn_nr == L_ENHET3) {
+
+ /* Sjekk at enhet ikke er endret */
+ UT_StrDbl(ct,1,&dummy,'.',&enhet);
+ if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet) > LC_ACCY) {
+ LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+ LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+ Sys.GrId.pFil->TransPar.dEnhet);
+ LC_Error(57,"(LX_PutGi)",err().tx);
+ sLagre = UT_FALSE;
+ }
+ }
+
+ /* ...ENHET-H i filhode på fil med data */
+ if (Sys.GrId.lNr == 0L && Sys.GrId.pFil->lAntGr > 1 && navn_nr == L_ENHET3H) {
+ /* Sjekk at enhet ikke er endret */
+ UT_StrDbl(ct,1,&dummy,'.',&enhet);
+ if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet_h) > LC_ACCY) {
+ LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+ LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+ Sys.GrId.pFil->TransPar.dEnhet_h);
+ LC_Error(57,"(LX_PutGi)",err().tx);
+ sLagre = UT_FALSE;
+ }
+ }
+
+ /* ...ENHET-D i filhode på fil med data */
+ if (Sys.GrId.lNr == 0L && Sys.GrId.pFil->lAntGr > 1 && navn_nr == L_ENHET3D) {
+ /* Sjekk at enhet ikke er endret */
+ UT_StrDbl(ct,1,&dummy,'.',&enhet);
+ if (fabs(enhet - Sys.GrId.pFil->TransPar.dEnhet_d) > LC_ACCY) {
+ LB_FormaterEnhet(err().tx,LC_ERR_LEN,
+ LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+ Sys.GrId.pFil->TransPar.dEnhet_d);
+ LC_Error(57,"(LX_PutGi)",err().tx);
+ sLagre = UT_FALSE;
+ }
+ }
+
+ /* ..NGIS-LAG i filhode på fil med data */
+ if (Sys.GrId.lNr == 0L && Sys.GrId.pFil->lAntGr > 1 && navn_nr == L_NGISLAG) {
+
+ /* Sjekk at ..NGIS-LAG ikke er endret */
+ pszNgisLag = ct;
+
+ // Filen har ikke NGIS-LAG eller NGIS-LAG er endret
+ //if (lNgisLag != Sys.GrId.pFil->lNgisLag) {
+ if (*(Sys.GrId.pFil->szNgisLag) == '\0' ||
+ strcmp(pszNgisLag,Sys.GrId.pFil->szNgisLag) != 0) {
+
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s %s",
+ LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+ Sys.GrId.pFil->szNgisLag);
+ LC_Error(58,"(LX_PutGi)",err().tx);
+ sLagre = UT_FALSE;
+ }
+ }
+
+ /* ..ORIGO-NØ i filhode på fil med data */
+ if (Sys.GrId.lNr == 0L && Sys.GrId.pFil->lAntGr > 1 && navn_nr == L_ORIGONO) {
+
+ /* Sjekk at ..ORIGO-NØ ikke er endret */
+ UT_StrDbl(ct,1,&dummy,'.',&dNord);
+ UT_StrDbl(ct,dummy,&dummy,'.',&dAust);
+
+ if (fabs(dNord - Sys.GrId.pFil->TransPar.Origo.dNord) > 0.1 ||
+ fabs(dAust - Sys.GrId.pFil->TransPar.Origo.dAust) > 0.1 ) {
+
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %s %.0f %.0f",
+ LN_GetNavn(&(Sys.GrId.pFil->SosiNavn),navn_nr),
+ Sys.GrId.pFil->TransPar.Origo.dNord, Sys.GrId.pFil->TransPar.Origo.dAust);
+ LC_Error(60,"(LX_PutGi)",err().tx);
+ sLagre = UT_FALSE;
+ }
+ }
+
+ // ..OBJTYPE
+ if (navn_nr == L_OBJTYPE) {
+ UT_StrCopy(Sys.pGrInfo->szObjtype,ct,LC_MAX_OBJTYPE_LEN);
+ }
+
+ /* Referanser */
+ if (navn_nr == L_REF1 || navn_nr == L_REF2) {
+ Sys.pGrInfo->info |= GI_REF;
+ if (LN_TestOy(ginfo)) Sys.pGrInfo->info |= GI_OY_REF;
+
+#ifdef UTGAAR
+ /* Gruppen har høyde informasjon */
+ } else if (navn_nr == L_HOYDE) {
+ Sys.pGrInfo->info |= GI_NAH; /* Husk at gruppen har høyde */
+#endif
+ }
+ }
+ }
+
+
+ if (sLagre == UT_TRUE) {
+ /* Linjen lagres */
+ sGmlLen = (short)strlen(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1]);
+ sNyLen = (short)strlen(cs);
+
+ /* Samme lengde, trenger ikke å flytte noe i buffer */
+ if (sNyLen == sGmlLen) {
+ //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], cs);
+ UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+ /* Siste linje i GINFO, trenger ikke å flytte noe i buffer */
+ } else if (lin_nr == Sys.pGrInfo->ngi) {
+ //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1],cs);
+ UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+ /* Oppdater antall tegn brukt i GINFO-buffer */
+ Sys.pGrInfo->ulGiLen = Sys.pGrInfo->ulGiLen - sGmlLen + sNyLen;
+
+ /* Må flytte resten av buffer for å tilpasse plassen */
+ } else {
+ memmove(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr] - sGmlLen + sNyLen,
+ Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr],
+ Sys.pGrInfo->ulGiLen - Sys.Ginfo.ulOfset[lin_nr]);
+ //strcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1],cs);
+ UT_memcpy(Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1], sNyLen+1, cs, sNyLen+1);
+
+ /* Oppdater antall tegn brukt i GINFO-buffer */
+ Sys.pGrInfo->ulGiLen += (sNyLen - sGmlLen);
+ /* Oppdater pekere til GINFO linjene */
+ LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+ }
+ }
+}
+
+/*
+AR-930609
+CH LX_CreGiPeker Bygg opp pekertabell til GINFO
+CD ==========================================================================
+CD Formål:
+CH Bygg opp pekertabell til GINFO buffer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_GINFO *pGinfo i Peker til GINFO struktur
+CD short ngi i Ant. GINFO linjer
+CD
+CD Bruk:
+CD LX_CreGiPeker(&Sys.Ginfo,Sys.pGrInfo->ngi);
+ ==========================================================================
+*/
+void LX_CreGiPeker(LC_GINFO_BUFFER * pGinfo,short ngi)
+{
+ short i;
+ unsigned long *pulOfset = pGinfo->ulOfset;
+ char *cp = pGinfo->pszTx;
+
+ /* Første GINFO starter alltid i posisjon 0 */
+ *pulOfset++ = 0;
+
+ /* Skanner strengen og finner startposisjonen for resten av GINFO */
+ for (i=1; i<ngi; ++i) {
+ cp = strchr(cp,'\0') + 1;
+ *pulOfset++ = (unsigned long) (cp - pGinfo->pszTx);
+ }
+}
+
+
+/*
+AR-930609
+CH LX_GetGi Intern get GINFO-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en GINFO-linje som en streng rent generellt.
+CD Dette omfatter også serienummer og referansenummer.
+CD Returnerer peker til den aktuelle strengen i GINFO-buffer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short lin_nr i Linjenummer i GINFO (1 er første linje)
+CD char *ginfo r Peker til GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD ginfo = LX_GetGi(lin_nr);
+ ==========================================================================
+*/
+char *LX_GetGi(short lin_nr)
+{
+ return Sys.Ginfo.pszTx + Sys.Ginfo.ulOfset[lin_nr - 1];
+}
+
+
+/*
+AR-930609
+CH LC_GetGi Get GINFO-linje
+CD ==========================================================================
+CD Formål:
+CD Henter en GINFO-linje som en streng rent generellt.
+CD Dette omfatter også serienummer og referansenummer.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short lin_nr i Linjenummer i GINFO (1 er første linje)
+CD char *ginfo r Peker til GINFO-streng avslutta med '\0'
+CD
+CD Bruk:
+CD ginfo = LC_GetGi(lin_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetGi(short lin_nr)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ if (lin_nr > 0 && lin_nr <= Sys.pGrInfo->ngi) { /* Lovlig linje ? */
+
+ UT_StrCopy(retur_str,LX_GetGi(lin_nr),LC_MAX_SOSI_LINJE_LEN);
+
+ } else { /* Ulovlig linjenummer */
+ *retur_str = '\0';
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_GetGi)","");
+ *retur_str = '\0';
+ }
+
+ return retur_str;
+}
+
+
+/*
+AR-910219
+CH LC_PutTK Put koordinat
+CD ==========================================================================
+CD Formål:
+CD Legger inn et punkts koordinater (n,ø) i meter i terreng
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double aust i Øst-koordinat i meter i terreng
+CD double nord i Nord-koordinat i meter i terreng
+CD
+CD Bruk:
+CD LC_PutTK(punkt_nr,aust,nord);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTK(long punkt_nr,double aust,double nord)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+
+ *(Sys.pdAust + punkt_nr - 1) = aust; /* Øst */
+ *(Sys.pdNord + punkt_nr - 1) = nord; /* Nord */
+
+ Sys.sGrEndra = END_ENDRA;
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_PutTK)",err().tx);
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutTK)","");
+ }
+}
+
+
+/*
+AR-930609
+CH LC_GetTK Get koordinat
+CD ==========================================================================
+CD Formål:
+CD Henter et punkts koordinater (ø,n) i meter i terreng
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double *aust u Øst-koordinat i meter i terreng
+CD double *nord u Nord-koordinat i meter i terreng
+CD
+CD Bruk:
+CD LC_GetTK(punkt_nr,&aust,&nord);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetTK(long punkt_nr,double *aust,double *nord)
+{
+ /* Aktuell gruppe OK? */
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+ /* Lovlig punkt ? */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) {
+ *aust = *(Sys.pdAust + punkt_nr - 1); /* Øst */
+ *nord = *(Sys.pdNord + punkt_nr - 1); /* Nord */
+
+ /* Ulovlig punktnummer */
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetTK)",err().tx);
+ }
+ }
+}
+
+
+/*
+AR-930617
+CH LC_GetArrayTK Hent tabell med koordinater
+CD ==========================================================================
+CD Formål:
+CD Henter tabell med koordinater (ø,n) i meter i terreng
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short retning i Buffer-retning:
+CD HENT_FORRFRA ( 1) = vanlig,
+CD HENT_BAKFRA (-1) = buffer skal snues.
+CD long max_antall i Max antall punkt som kan hentes
+CD long fra_punkt i Fra punktnummer (1 eller nko er første punkt)
+CD double *aust u Peker til tab. for øst-koordinater
+CD double *nord u Peker til tab. for nord-koordinater
+CD long *antall u Antall punkt hentet
+CD
+CD Bruk:
+CD LC_GetArrayTK(retning,max_antall,fra_punkt,aust,nord,&lest);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetArrayTK(short retning,long max_antall,long fra_punkt,
+ double *aust,double *nord,long *antall)
+{
+ long ant = 0;
+ long pt;
+ double *pdA,*pdN;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ /* Hent bakfra */
+ if (retning == HENT_BAKFRA) {
+ if (fra_punkt > Sys.pGrInfo->nko) fra_punkt = Sys.pGrInfo->nko;
+ pt = fra_punkt - 1;
+ pdA = Sys.pdAust + pt;
+ pdN = Sys.pdNord + pt;
+ while (ant < max_antall && pt >= 0) {
+ ++ant;
+ *aust++ = *pdA--; /* Øst */
+ *nord++ = *pdN--; /* Nord */
+ --pt;
+ }
+
+ /* Hent forrfra */
+ } else {
+ if (fra_punkt < 1) fra_punkt = 1;
+ pt = fra_punkt - 1;
+ pdA = Sys.pdAust + pt;
+ pdN = Sys.pdNord + pt;
+ while (ant < max_antall && pt < Sys.pGrInfo->nko) {
+ ++ant;
+ *aust++ = *pdA++; /* Øst */
+ *nord++ = *pdN++; /* Nord */
+ ++pt;
+ }
+ }
+ }
+
+ *antall = ant;
+}
+
+
+/*
+AR-940630
+CH LC_GetArrayTH Hent tabell med høyder
+CD ==========================================================================
+CD Formål:
+CD Henter tabell med høyder
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short retning i Buffer-retning:
+CD HENT_FORRFRA ( 1) = vanlig,
+CD HENT_BAKFRA (-1) = buffer skal snues.
+CD long max_antall i Max antall punkt som kan hentes
+CD long fra_punkt i Fra punktnummer (1 eller nko er første punkt)
+CD double *aust u Peker til tab. for høyder
+CD long *antall u Antall punkt hentet
+CD
+CD Bruk:
+CD LC_GetArrayTH(retning,max_antall,fra_punkt,hoyde,&lest);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_GetArrayTH(short retning,long max_antall,long fra_punkt,
+ double *hoyde,long *antall)
+{
+ short gilin;
+ char *gp;
+ long pt;
+ double dGiHoyde;
+ long ant = 0;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ /* Hent høyde fra GINFO */
+ gilin = 2;
+ gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_HOYDE),
+ &gilin,Sys.pGrInfo->ngi);
+ if (gp != NULL) {
+ dGiHoyde = strtod(gp,&gp);
+
+ } else {
+ dGiHoyde = HOYDE_MANGLER;
+ }
+
+ /* Hent aktuelle høyder i punktene */
+
+ /* Hent bakfra */
+ if (retning == HENT_BAKFRA) {
+ if (fra_punkt > Sys.pGrInfo->nko) fra_punkt = Sys.pGrInfo->nko;
+ pt = fra_punkt - 1;
+ while (ant < max_antall && pt >= 0) {
+ ++ant;
+
+ if ((Sys.pGrInfo->info & GI_NAH) != 0 &&
+ (Sys.pInfo + pt)->dHoyde != HOYDE_MANGLER) {
+ *hoyde++ = (Sys.pInfo + pt)->dHoyde;
+
+ } else {
+ *hoyde++ = dGiHoyde;
+ }
+
+ pt--;
+ }
+
+ /* Hent forrfra */
+ } else {
+ if (fra_punkt < 1) fra_punkt = 1;
+ pt = fra_punkt - 1;
+ while (ant < max_antall && pt < Sys.pGrInfo->nko) {
+ ++ant;
+
+ if ((Sys.pGrInfo->info & GI_NAH) != 0 &&
+ (Sys.pInfo + pt)->dHoyde != HOYDE_MANGLER) {
+ *hoyde++ = (Sys.pInfo + pt)->dHoyde;
+
+ } else {
+ *hoyde++ = dGiHoyde;
+ }
+
+ ++pt;
+ }
+ }
+ }
+
+ *antall = ant;
+}
+
+
+/*
+AR-940630
+CH LC_PutTH Put høyde
+CD ==========================================================================
+CD Formål:
+CD Legger inn et punkts høyde i meter i terreng
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double hoyde i Høyde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har høydeverdi.
+CD
+CD Bruk:
+CD LC_PutTH(punkt_nr,hoyde);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTH(long punkt_nr, double hoyde)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+
+ if ((Sys.pGrInfo->info & GI_NAD) == 0) {
+
+ if (hoyde != HOYDE_MANGLER) Sys.pGrInfo->info |= GI_NAH; // Husker at gruppen har høyde
+
+ (Sys.pInfo + punkt_nr - 1)->dHoyde = hoyde;
+
+ Sys.sGrEndra = END_ENDRA;
+ if (punkt_nr == Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM;
+
+ /* Gruppen har ..NAD fra før og det prøves å legge inne en høyde */
+ } else if (hoyde != HOYDE_MANGLER) {
+ LC_Error(132,"(LC_PutTH)",LC_GetGi(1));
+ }
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_PutTH)",err().tx);
+ }
+ }
+}
+
+
+/*
+AR-9930609
+CH LC_GetTH Get høyde
+CD ==========================================================================
+CD Formål:
+CD Henter et punkts høyde i meter i terreng. (Henter BARE FRA PUNKTET.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double *hoyde r Høyde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har høydeverdi.
+CD
+CD Bruk:
+CD hoyde = LC_GetTH(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetTH(long punkt_nr)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ /* Gruppen har ..NAH */
+ if ((Sys.pGrInfo->info & GI_NAH) != 0) {
+ return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetTH)",err().tx);
+ }
+ }
+
+ return HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_GetHoyde Get høyde
+CD ==========================================================================
+CD Formål:
+CD Henter et punkts høyde i meter i terreng. (Henter fra punktet eller fra
+CD GINFO.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double *hoyde r Høyde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har høydeverdi.
+CD
+CD Bruk:
+CD hoyde = LC_GetHoyde(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetHoyde(long punkt_nr)
+{
+ short gilin;
+ char *gp;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ /* Gruppen har ..NAH */
+ if ((Sys.pGrInfo->info & GI_NAH) != 0) {
+ /* Punktet har høyde */
+ if ((Sys.pInfo + punkt_nr - 1)->dHoyde != HOYDE_MANGLER) {
+ return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+ }
+ }
+
+ /* Punktet har ikke høyde, sjekk GINFO */
+ gilin = 2;
+ gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_HOYDE),
+ &gilin,Sys.pGrInfo->ngi);
+ if (gp != NULL) {
+ return strtod(gp,&gp);
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetHoyde)",err().tx);
+ }
+ }
+
+ return HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_PutTD Put dybde
+CD ==========================================================================
+CD Formål:
+CD Legger inn et punkts dybde i meter i terreng
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double hoyde i Dybde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har dybdeverdi.
+CD
+CD Bruk:
+CD LC_PutTD(punkt_nr,dybde);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutTD(long punkt_nr, double dybde)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko){ /* Lovlig punkt ? */
+
+ if ((Sys.pGrInfo->info & GI_NAH) == 0) {
+
+ if (dybde != HOYDE_MANGLER) Sys.pGrInfo->info |= GI_NAD;
+
+ (Sys.pInfo + punkt_nr - 1)->dHoyde = dybde;
+
+ Sys.sGrEndra = END_ENDRA;
+ if (punkt_nr == Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM;
+
+ /* Gruppen har ..NAH fra før og det prøves å legge inn en dybde */
+ } else if (dybde != HOYDE_MANGLER) {
+ LC_Error(133,"(LC_PutTD)",LC_GetGi(1));
+ }
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_PutTD)",err().tx);
+ }
+ }
+}
+
+
+/*
+AR-940630
+CH LC_GetTD Get dybde
+CD ==========================================================================
+CD Formål:
+CD Henter et punkts dybde i meter i terreng. (Henter BARE FRA PUNKTET.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double *dybde r Dybde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har dybdeverdi.
+CD
+CD Bruk:
+CD dybde = LC_GetTD(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetTD(long punkt_nr)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ /* Gruppen har ..NAD */
+ if ((Sys.pGrInfo->info & GI_NAD) != 0) {
+ return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetTD)",err().tx);
+ }
+ }
+
+ return HOYDE_MANGLER;
+}
+
+
+/*
+AR-940630
+CH LC_GetDybde Get dybde
+CD ==========================================================================
+CD Formål:
+CD Henter et punkts dybde i meter i terreng. (Henter fra punktet eller fra
+CD GINFO.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD double *hoyde r Dybde i meter i terreng. Konstanten
+CD HOYDE_MANGLER (-999.999) angir at punktet ikke
+CD har høydeverdi.
+CD
+CD Bruk:
+CD dybde = LC_GetHoyde(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA double LC_GetDybde(long punkt_nr)
+{
+ short gilin;
+ char *gp;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ /* Gruppen har ..NAD */
+ if ((Sys.pGrInfo->info & GI_NAD) != 0) {
+ /* Punktet har dybde */
+ if ((Sys.pInfo + punkt_nr - 1)->dHoyde != HOYDE_MANGLER) {
+ return (Sys.pInfo + punkt_nr - 1)->dHoyde;
+ }
+ }
+
+ /* Punktet har ikke dybde, sjekk GINFO */
+ gilin = 2;
+ gp = LC_GetGP(LN_GetNavn(&Sys.GrId.pFil->SosiNavn,L_DYBDE),
+ &gilin,Sys.pGrInfo->ngi);
+ if (gp != NULL) {
+ return strtod(gp,&gp);
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetHoyde)",err().tx);
+ }
+ }
+
+ return HOYDE_MANGLER;
+}
+
+
+/*
+AR-930609
+CH LC_GetPi Get PINFO
+CD ==========================================================================
+CD Formål:
+CD Henter punktinformasjon i angitte punkt som en streng.
+CD Strengen ligger i et felles "returbuffer" for alle get-rutiner i fyba.
+CD Dette blir ødelagt ved neste kall til en "get-rutine". For å ta vare på
+CD strengen må den kopieres over til egen streng. (Bruk strcpy).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD char *pinfo r Peker til punktinformasjon eksklusiv knutepunkt
+CD
+CD Bruk:
+CD pinfo = LC_GetPi(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA char *LC_GetPi(long punkt_nr)
+{
+ unsigned long ulOfset;
+
+ *retur_str = '\0';
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+
+ ulOfset = (Sys.pInfo+punkt_nr-1)->ulPiOfset;
+
+ if (ulOfset != LC_INGEN_PINFO) {
+ UT_StrCopy(retur_str,Sys.pszPinfo+ulOfset,LC_MAX_SOSI_LINJE_LEN);
+
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetPi)",err().tx);
+ }
+ }
+
+ return retur_str;
+}
+
+
+/*
+AR-930609
+CH LC_PutPi Put PINFO
+CD ==========================================================================
+CD Formål:
+CD Legger inn hele punktinformasjonen på angitte punkt
+CD Ny verdi skriver over eksisterende verdi.
+CD Verdi "" fjerner eksisterende PINFO.
+CD Knutepunkt legges inn med LC_PutKp.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD char *pinfo i PINFO-streng som skal legges inn
+CD (Knutepunkt regnes ikke som pinfo)
+CD short sStatus r UT_TRUE = OK,
+CD UT_FALSE = ikke utført (for lite plass tilgjengelig)
+CD
+CD Bruk:
+CD sStatus = LC_PutPi(punkt_nr,pinfo);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_PutPi(long punkt_nr, const char *pinfo)
+{
+ short sNyLen, sGmlLen;
+ long pt;
+ unsigned long ulOfset;
+ char *pszBuffer = NULL;
+ short sStatus = UT_FALSE;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+
+ /* Fjern blanke i starten */
+ while (UT_IsSpace(*pinfo)) {
+ ++pinfo;
+ }
+ sNyLen = (short)strlen(pinfo);
+
+ if (sNyLen > 0) {
+ /* Ta kopi av strengen */
+ pszBuffer = (char*)UT_MALLOC(sNyLen+1);
+ UT_StrCopy(pszBuffer,pinfo,sNyLen+1);
+ pinfo = pszBuffer;
+
+ /* Fjern blanke på slutten */
+ UT_ClrTrailsp(pszBuffer);
+ sNyLen = (short)strlen(pszBuffer);
+ }
+
+ /* Gammel lengde av PINFO */
+ ulOfset = (Sys.pInfo+punkt_nr-1)->ulPiOfset;
+ if (ulOfset == LC_INGEN_PINFO) {
+ sGmlLen = 0;
+ } else {
+ sGmlLen = (short)strlen(Sys.pszPinfo+ulOfset);
+ }
+
+ /* --------------------- Blank ut PINFO */
+ if (sNyLen == 0) {
+ /* Punktet har PINFO fra før */
+ if (sGmlLen > 0) {
+ /* Merk at punktet ikke har PINFO */
+ (Sys.pInfo+punkt_nr-1)->ulPiOfset = LC_INGEN_PINFO;
+
+ /* Pakk innholdet i bufferet */
+ memmove(Sys.pszPinfo + ulOfset,
+ Sys.pszPinfo + ulOfset + sGmlLen + 1,
+ Sys.pGrInfo->ulPiLen - ulOfset - sGmlLen - 1);
+
+ /* Oppdater ofset for resten av gruppen */
+ /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+ for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+ if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+ (Sys.pInfo+pt)->ulPiOfset -= (sGmlLen + 1);
+ }
+ }
+ /* } */
+
+ /* Ny totallengde av PINFO i denne gruppen */
+ Sys.pGrInfo->ulPiLen -= sGmlLen;
+ }
+
+
+ /* --------------------- Legg inn PINFO */
+ } else {
+
+ /* Sjekk om det blir plass til den nye PINFO'en */
+ if (((long)Sys.pGrInfo->ulPiLen - (long)sGmlLen + (long)sNyLen) < LC_MAX_PINFO_BUFFER) {
+ sStatus = UT_TRUE;
+
+ /* Punktet har ikke PINFO fra før */
+ if (sGmlLen == 0) {
+ /* Søk mot starten av gruppen for å finne slutten av forrige PINFO */
+ ulOfset = 0;
+ for (pt=punkt_nr-2; pt>=0; pt--) {
+ if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+ /* ulOfset = (strlen(Sys.pszPinfo+(Sys.pInfo+pt)->ulPiOfset) + 1); */
+ ulOfset = (Sys.pInfo+pt)->ulPiOfset +
+ strlen(Sys.pszPinfo+(Sys.pInfo+pt)->ulPiOfset) + 1;
+ break; /* ---> avbryter for-løkka */
+ } /* endif */
+ } /* endfor */
+
+ /* Husk ofset */
+ (Sys.pInfo+punkt_nr-1)->ulPiOfset = ulOfset;
+
+ /* Flytt innholdet i bufferet */
+ memmove(Sys.pszPinfo + ulOfset + sNyLen + 1,
+ Sys.pszPinfo + ulOfset,
+ Sys.pGrInfo->ulPiLen - ulOfset);
+
+ /* Oppdater ofset for resten av gruppen */
+ /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+ for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+ if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+ (Sys.pInfo+pt)->ulPiOfset += (sNyLen + 1);
+ }
+ }
+ /* } */
+
+ /* Kopier inn strengen */
+ //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+ UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+ /* Ny totallengde */
+ Sys.pGrInfo->ulPiLen += (sNyLen + 1);
+
+ /* Samme lengde, trenger ikke å flytte noe i buffer */
+ } else if (sNyLen == sGmlLen) {
+ //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+ UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+ /* Punktet har PINFO, men med annen lengde */
+ } else {
+ /* Flytt innholdet i bufferet */
+ memmove(Sys.pszPinfo + ulOfset + sNyLen + 1,
+ Sys.pszPinfo + ulOfset + sGmlLen + 1,
+ Sys.pGrInfo->ulPiLen - ulOfset - sGmlLen - 1);
+
+ /* Kopier inn strengen */
+ //strcpy(Sys.pszPinfo+ulOfset, pinfo);
+ UT_memcpy(Sys.pszPinfo+ulOfset, sNyLen+1, pinfo, sNyLen+1);
+
+ /* Oppdater ofset for resten av gruppen */
+ /* if (Sys.pGrInfo->ulPiLen > ulOfset + sGmlLen + 1) { */
+ for (pt=punkt_nr; pt < Sys.pGrInfo->nko; ++pt) {
+ if ((Sys.pInfo+pt)->ulPiOfset != LC_INGEN_PINFO) {
+ (Sys.pInfo+pt)->ulPiOfset += (sNyLen - sGmlLen);
+ }
+ }
+ /* } */
+
+ /* Ny totallengde */
+ Sys.pGrInfo->ulPiLen += (sNyLen - sGmlLen);
+ }
+ }
+
+ /* Husk at gruppen har PINFO */
+ Sys.pGrInfo->info |= GI_PINFO;
+ }
+
+ /* Husk at gruppen er endret */
+ Sys.sGrEndra = END_ENDRA;
+ if (punkt_nr == Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM;
+
+ /* Frigir midlertidig buffer */
+ if (pszBuffer != NULL) UT_FREE(pszBuffer);
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_PutPi)",err().tx);
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutPi)","");
+ }
+
+ return sStatus;
+}
+
+
+/*
+AR-930609
+CH LC_TestPi Sjekk om punkt har PINFO
+CD ==========================================================================
+CD Formål:
+CD Sjekker om et punkt har PINFO i en eller annen form.
+CD (PINFO, KP, høyde.)
+CD Høyde handteres ikke foreløpig.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD short sTestHoyde i Bryter for å si om høyde skal regnes med i sjekken.
+CD short sStatus r UT_TRUE=har "pinfo", UT_FALSE=har ikke "pinfo"
+CD
+CD Bruk:
+CD sStatus = LC_TestPi(punkt_nr,UT_TRUE);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_TestPi(long punkt_nr,short sTestHoyde)
+{
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+
+ /* ==> Høyde skal behandles */
+ if (sTestHoyde) {
+ /* if (Sys.pGrInfo->info & GI_NAH) return UT_TRUE; */
+ return UT_TRUE;
+ }
+
+ /* ==> Har PINFO */
+ if ((Sys.pInfo+punkt_nr-1)->ulPiOfset != LC_INGEN_PINFO) {
+ return UT_TRUE;
+
+ /* ==> Har KP */
+ } else if ((Sys.pInfo+punkt_nr-1)->sKp != 0) {
+ return UT_TRUE;
+ }
+
+ } else { /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetPi)",err().tx);
+ }
+ }
+
+ return UT_FALSE;
+}
+
+
+/*
+AR-930609
+CH LC_GetKp Get knutepunkt
+CD ==========================================================================
+CD Formål:
+CD Henter knutepunktverdi i punktet.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD short kp_type r Knutepunkttype (1-4095)
+CD (0 = punktet har ikke knutepunkt)
+CD
+CD Bruk:
+CD kp = LC_GetKp(punkt_nr);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA short LC_GetKp(long punkt_nr)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE){ /* Aktuell gruppe OK */
+
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko){ /* Lovlig punkt ? */
+ return (Sys.pInfo+punkt_nr-1)->sKp;
+
+ } else{ /* Ulovlig punktnummer */
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_GetKp)",err().tx);
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+AR-930609
+CH LC_PutKp Put knutepunkt
+CD ==========================================================================
+CD Formål:
+CD Legger inn knutepunktverdi i punktet. Ny verdi skrives over eksisterende
+CD verdi. (Multiple KP er ikke mulig.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD long punkt_nr i Punktnummer (1 er første punkt)
+CD short kp i Knutepunkt (lovlig verdi 0 - SHRT_MAX)
+CD kp == 0 fjerner knutepunkt.
+CD
+CD Bruk:
+CD LC_PutKp(punkt_nr,kp);
+ ==========================================================================
+*/
+SK_EntPnt_FYBA void LC_PutKp(long punkt_nr, short kp)
+{
+ if (Sys.GrId.lNr != INGEN_GRUPPE) { /* Aktuell gruppe OK */
+ if (punkt_nr > 0 && punkt_nr <= Sys.pGrInfo->nko) { /* Lovlig punkt ? */
+ if (kp >= 0 && kp < SHRT_MAX) {
+ if (kp != 0) Sys.pGrInfo->info |= GI_KP; /* Merk at gruppen har KP */
+
+ (Sys.pInfo+punkt_nr-1)->sKp = kp;
+
+ Sys.sGrEndra = END_ENDRA;
+ if (punkt_nr == Sys.lPibufPnr) Sys.sPibufStatus = LC_PIBUF_TOM;
+
+ /* Husk at det finnes KP i filen */
+ if (kp > 0) {
+ if ( Sys.GrId.pFil->SosiNiv[1] < 3) {
+ Sys.GrId.pFil->SosiNiv[1] = 3;
+ }
+ }
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN," %d",kp);
+ LC_Error(53,"(LC_PutKp)",err().tx);
+ }
+
+ } else {
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"(%s) %ld",LC_GetGi(1),punkt_nr);
+ LC_Error(51,"(LC_PutKp)",err().tx);
+ }
+
+ } else { /* Ingen aktuell gruppe */
+ LC_Error(49,"(LC_PutKp)","");
+ }
+}
+
+
+/*
+AR-911106
+CH LC_BerAreal Beregn areal av aktuell FLATE
+CD ==========================================================================
+CD Formål:
+CD Beregner arealet av aktuell gruppe hvis denne er flate.
+CD Referansene brukes for arealberegningen.
+CD Tar hensyn til fradrag for øyer.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double areal u Beregnet areal
+CD
+CD Bruk:
+CD areal = LC_BerAreal();
+ =============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerAreal(void)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ #define MAX_REFERANSE 20
+ long ref_arr[MAX_REFERANSE];
+ unsigned char ref_status[MAX_REFERANSE];
+ long ant_ref;
+ short s,retning;
+ LC_GRF_STATUS GrfStat;
+ LC_BGR BgrFlate,Bgr;
+
+ double dTotalAreal = 0.0;
+ double dDelAreal = 0.0;
+
+ /* Husk gruppenummer for flaten */
+ LC_GetGrNr(&BgrFlate);
+ Bgr.pFil = BgrFlate.pFil;
+
+
+ /* Behandle ytre avgrensing */
+ LC_InitGetRefFlate(&GrfStat);
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REFERANSE);
+ do {
+ for (s=0; s<ant_ref; ++s) {
+ Bgr.lNr = ref_arr[s];
+ retning = (ref_status[s] & LC_MED_DIG)?
+ HENT_FORRFRA : HENT_BAKFRA;
+ dTotalAreal += LX_ArealGruppe(&Bgr,retning);
+ }
+ /* Les inn flaten igjen */
+ LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+
+ if (ant_ref < MAX_REFERANSE) break;
+
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_YTRE,ref_arr,ref_status,MAX_REFERANSE);
+ } while (ant_ref > 0);
+
+ /* Beregn endelig areal innenfor yttergrensen */
+ dTotalAreal = fabs(dTotalAreal / 2.0);
+
+
+ /* Behandler indre avgrensing (øy) */
+ LC_InitGetRefFlate(&GrfStat);
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REFERANSE);
+ do {
+ for (s=0; s<ant_ref; ++s) {
+ if (ref_status[s] & GRF_START_OY) {
+ dDelAreal = 0.0;
+
+ } else if (ref_status[s] & GRF_SLUTT_OY) {
+ /* Beregn endelig areal innenfor yttergrensen */
+ dTotalAreal -= fabs(dDelAreal / 2.0);
+
+ } else {
+ Bgr.lNr = ref_arr[s];
+ retning = (ref_status[s] & LC_MED_DIG)?
+ HENT_FORRFRA : HENT_BAKFRA;
+ dDelAreal += LX_ArealGruppe(&Bgr,retning);
+ }
+ }
+ /* Les inn flaten igjen */
+ LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+
+ if (ant_ref < MAX_REFERANSE) break;
+
+ ant_ref = LC_GetRefFlate(&GrfStat,GRF_INDRE,ref_arr,ref_status,MAX_REFERANSE);
+ } while (ant_ref > 0);
+
+ return dTotalAreal;
+}
+
+
+/*
+AR-900731
+CH LX_BerArealGruppe Beregn areal "arealandel" av aktuell gruppe
+CD ==========================================================================
+CD Formål:
+CD Beregner areal av polygon angitt av yttergrensen av aktuell gruppe.
+CD Forutsetter .FLATE og det er referansene som brukes i arealberegningen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_BGR * pBgr i Gruppepeker
+CD short retning i HENT_FORRFRA eller HENT_BAKFRA
+CD double areal u Beregnet areal
+CD
+CD Bruk:
+CD areal = LX_ArealGruppe(&Bgr,retning);
+ =============================================================================
+*/
+static double LX_ArealGruppe(LC_BGR * pBgr,short retning)
+{
+ #define ARR_LEN 50
+ short ngi, gruppenavn;
+ long nko, pt, antall, punkt;
+ unsigned short info;
+ short storbue;
+ double a1,n1,a2,n2,a3,n3,radius,as,ns,fi,dfi;
+ double n_arr[ARR_LEN],a_arr[ARR_LEN];
+ double a_forrige=0.0, n_forrige=0.0, a, n;
+ short forste;
+ double areal_seg = 0.0;
+ double areal_poly = 0.0;
+
+ gruppenavn = LC_RxGr(pBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ if (nko > 0) {
+ if (gruppenavn == L_BUE) { /* .BUE */
+ if (LC_GetBue(retning,&a1,&n1,&a2,&n2,&radius,&storbue)){
+ areal_poly += (a1 - a2) * (n1 + n2);
+ /* Sektoren */
+ if (GM_KonvBue(a1,n1,a2,n2,radius,storbue,
+ &as,&ns,&fi,&dfi)){
+ areal_seg += (radius*radius*(dfi-sin(dfi)));
+ }
+ }
+
+ } else if (gruppenavn == L_BUEP){ /* .BUEP */
+ if (LC_GetBuep(retning,&a1,&n1,&a2,&n2,&a3,&n3)) {
+ areal_poly += (a1 - a3) * (n1 + n3);
+ /* Sektoren */
+ if (GM_KonvBuep(a1,n1,a2,n2,a3,n3,
+ &as,&ns,&radius,&fi,&dfi)) {
+ areal_seg += (radius*radius*(dfi-sin(dfi)));
+ }
+ }
+
+ } else if (gruppenavn == L_SIRKEL) { /* .SIRKEL */
+ if (LC_GetSirkel(&as,&ns,&radius)) {
+ /* Dobbelt areal av sirkelen */
+ areal_seg = 2.0 * PI * radius * radius;
+ }
+
+ } else if (gruppenavn == L_SIRKELP) { /* .SIRKELP */
+ if (LC_GetSirkelp(&a1,&n1,&a2,&n2,&a3,&n3)) {
+ if (GM_KonvSirkelp(a1,n1,a2,n2,a3,n3,
+ &as,&ns,&radius,&fi,&dfi)) {
+ /* Dobbelt areal av sirkelen */
+ areal_seg = 2.0 * PI * radius * radius;
+ }
+ }
+
+ } else { /* Annen gruppe */
+ punkt = (retning == HENT_FORRFRA)? 1 : nko;
+ forste = UT_TRUE;
+
+ do { /* Beregn areal */
+ LC_GetArrayTK(retning,ARR_LEN,punkt,a_arr,n_arr,&antall);/* Henter */
+ if (antall > 0) {
+ if (forste) {
+ a_forrige = a_arr[0];
+ n_forrige = n_arr[0];
+ forste = UT_FALSE;
+ }
+ for (pt=1; pt<antall; ++pt) {
+ a = a_arr[pt];
+ n = n_arr[pt];
+ areal_poly += (a_forrige - a) * (n_forrige + n);
+ a_forrige = a;
+ n_forrige = n;
+ }
+
+ if (retning == HENT_FORRFRA) {
+ punkt += (antall-1);
+ if (punkt >= nko) antall = 0;
+ } else{
+ punkt -= (antall-1);
+ if (punkt <= 1) antall = 0;
+ }
+ }
+ } while (antall == ARR_LEN);
+ }
+ }
+
+ return (areal_poly + areal_seg);
+}
+
+
+/*
+AR-911106
+CH LC_BerLengde Beregn horisontal lengde av aktuell gruppe
+CD ==========================================================================
+CD Formål:
+CD Beregn horisontal lengde av aktuell gruppe.
+CD Tar ikke hensyn til høyde/dybde.
+CD Referansene brukes IKKE i beregningen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double lengde u Beregnet lengde
+CD
+CD Bruk:
+CD areal = LC_BerLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerLengde(void)
+{
+ short sfeil;
+ long l;
+ double a1,n1,a2,n2,rx,as,ns,fi,dfi;
+ double lengde = 0.0;
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE) {
+ if (Sys.pGrInfo->gnavn == L_LINJE || Sys.pGrInfo->gnavn == L_KURVE) {
+ for (l=2; l<=Sys.pGrInfo->nko; ++l) {
+ LC_GetTK(l-1,&a1,&n1);
+ LC_GetTK(l,&a2,&n2);
+ lengde += sqrt((n2-n1)*(n2-n1)+(a2-a1)*(a2-a1));
+ }
+
+ // Handterer "bue"
+ } else if (Sys.pGrInfo->gnavn == L_BUE || Sys.pGrInfo->gnavn == L_BUEP ||
+ Sys.pGrInfo->gnavn == L_SIRKEL || Sys.pGrInfo->gnavn == L_SIRKELP) {
+
+ if (LC_GetBuePar(HENT_FORRFRA,&as,&ns,&rx,&fi,&dfi,&sfeil)) {
+ lengde = fabs (rx * dfi);
+ }
+ }
+ }
+
+ return lengde;
+}
+
+
+/*
+AR-911106
+CH LC_BerLengde3D Beregn skrå lengde av aktuell gruppe
+CD ==========================================================================
+CD Formål:
+CD Beregn skrå lengde av aktuell gruppe.
+CD Krever at det finnes høyde/dybde i alle punkt.
+CD Referansene brukes IKKE i beregningen.
+CD Beregner bare for LINJE og KURVE.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double lengde u Beregnet lengde
+CD bool beregnet r Status som viser om lengde er beregnet
+CD
+CD Bruk:
+CD beregnet = LC_BerLengde3D(&skraa_lengde);
+=============================================================================
+*/
+SK_EntPnt_FYBA bool LC_BerLengde3D(double *skraa_lengde)
+{
+ long s;
+ double a1,n1,a2,n2,h1,h2,da,dn,dh;
+
+ bool beregnet = false;
+
+ *skraa_lengde = 0.0;
+
+
+ if (Sys.GrId.lNr != INGEN_GRUPPE)
+ {
+
+ // Beregn skrå lengde
+ if (Sys.pGrInfo->gnavn == L_LINJE || Sys.pGrInfo->gnavn == L_KURVE)
+ {
+ // Husk om gruppen har høyde/dybde
+ beregnet = ((Sys.pGrInfo->info & GI_NAH) || (Sys.pGrInfo->info & GI_NAD))? true : false;
+
+ for (s=2; beregnet && s<=Sys.pGrInfo->nko; s++)
+ {
+ LC_GetTK(s-1,&a1,&n1);
+ if (Sys.pGrInfo->info & GI_NAD)
+ {
+ h1 = LC_GetDybde(s-1);
+ }
+ else
+ {
+ h1 = LC_GetHoyde(s-1);
+ }
+
+ LC_GetTK(s,&a2,&n2);
+ if (Sys.pGrInfo->info & GI_NAD)
+ {
+ h2 = LC_GetDybde(s);
+ }
+ else
+ {
+ h2 = LC_GetHoyde(s);
+ }
+
+
+ if (h1 != HOYDE_MANGLER && h2 != HOYDE_MANGLER)
+ {
+ da = a2 - a1;
+ dn = n2 - n1;
+ dh = h2 - h1;
+ (*skraa_lengde) += sqrt(dn*dn + da*da + dh*dh);
+ }
+ else
+ {
+ beregnet = false;
+ }
+ }
+ }
+ }
+
+ return beregnet;
+}
+
+
+/*
+AR:2009-04-28
+CH LC_BerAvgrensLengde Beregn lengden av avgrensning av FLATE
+CD ==========================================================================
+CD Formål:
+CD Beregn lengden av avgrensningen av aktuell gruppe hvis denne er flate.
+CD Både indre og ytre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double lengde u Beregnet areal
+CD
+CD Bruk:
+CD lengde = LC_BerAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerAvgrensLengde(void)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR BgrFlate;
+ double dSumLengde = 0.0;
+
+ if (Sys.pGrInfo->info & GI_REF)
+ {
+ // Husk gruppenummer for flaten
+ LC_GetGrNr(&BgrFlate);
+
+ LC_POLYGON Polygon;
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ LC_POL_ELEMENT * pPE;
+ // Ytre avgrensning
+ for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ dSumLengde += LC_BerLengde();
+ }
+
+ // Indre avgrensning
+ LC_OY_ELEMENT * pOE;
+ for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ dSumLengde += LC_BerLengde();
+ }
+ }
+
+ // Frigi allokerte kjeder
+ LC_POL_FrigiPolygon(&Polygon);
+
+ // Les inn flaten igjen
+ LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return dSumLengde;
+}
+
+
+/*
+AR:2009-04-28
+CH LC_BerIndreAvgrensLengde Beregn lengden av indre avgrensning av FLATE
+CD ==========================================================================
+CD Formål:
+CD Beregn lengden av indre avgrensningen av aktuell gruppe hvis denne er flate.
+CD Bare indre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double lengde u Beregnet lengde
+CD
+CD Bruk:
+CD lengde = LC_BerIndreAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerIndreAvgrensLengde(void)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR BgrFlate;
+ double dSumLengde = 0.0;
+
+ if (Sys.pGrInfo->info & GI_REF)
+ {
+ // Husk gruppenummer for flaten
+ LC_GetGrNr(&BgrFlate);
+
+ LC_POLYGON Polygon;
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ // Indre avgrensning
+ LC_OY_ELEMENT * pOE;
+ LC_POL_ELEMENT * pPE;
+ for (pOE = Polygon.OyOA.pForsteOE; pOE != NULL; pOE = pOE->pNesteOE) {
+ for (pPE = pOE->PO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ dSumLengde += LC_BerLengde();
+ }
+ }
+
+ // Frigi allokerte kjeder
+ LC_POL_FrigiPolygon(&Polygon);
+
+ // Les inn flaten igjen
+ LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return dSumLengde;
+}
+
+
+
+/*
+AR:2009-04-28
+CH LC_BerYtreAvgrensLengde Beregn lengden av ytre avgrensning av FLATE
+CD ==========================================================================
+CD Formål:
+CD Beregn lengden av ytre avgrensningen av aktuell gruppe hvis denne er flate.
+CD Bare ytre avgrensning beregnes.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD double lengde u Beregnet lengde
+CD
+CD Bruk:
+CD lengde = LC_BerYtreAvgrensLengde();
+=============================================================================
+*/
+SK_EntPnt_FYBA double LC_BerYtreAvgrensLengde(void)
+{
+ short ngi;
+ long nko;
+ unsigned short info;
+ LC_BGR BgrFlate;
+ double dSumLengde = 0.0;
+
+ if (Sys.pGrInfo->info & GI_REF)
+ {
+ // Husk gruppenummer for flaten
+ LC_GetGrNr(&BgrFlate);
+
+ LC_POLYGON Polygon;
+ LC_POL_InitPolygon(&Polygon);
+ LC_POL_GetRef(&Polygon);
+
+ LC_POL_ELEMENT * pPE;
+ // Ytre avgrensning
+ for(pPE = Polygon.HovedPO.pForstePE; pPE != NULL; pPE = pPE->pNestePE) {
+ LC_RxGr(&pPE->Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ dSumLengde += LC_BerLengde();
+ }
+
+ // Frigi allokerte kjeder
+ LC_POL_FrigiPolygon(&Polygon);
+
+ // Les inn flaten igjen
+ LC_RxGr(&BgrFlate,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+
+ return dSumLengde;
+}
+
+
+/*
+AR-911106
+CH LC_DumpTab Dump interne tabeller til stderr
+CD ==========================================================================
+CD Formål:
+CD Dump interne tabeller til stderr
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_DumpTab();
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_DumpTab(void)
+{
+ short ngi,s;
+ long nko;
+ unsigned short info;
+ LC_BGR Bgr,AktBgr;
+
+ LC_GetGrNr(&AktBgr);
+
+ UT_FPRINTF(stderr,"\n=================================================\n");
+ UT_FPRINTF(stderr,"Dump av interne tabeller i FYBA\n");
+ UT_FPRINTF(stderr,"=================================================\n");
+
+ UT_FPRINTF(stderr,"\nLC_INGEN_PINFO = %lu\n", LC_INGEN_PINFO);
+
+ UT_FPRINTF(stderr,"\n Snr sosi_st rb_st rb_fgr rb_ngr gna ngi nko info GiLen PiLen\n");
+ LC_InitNextBgr(&Bgr);
+
+ /* Alle gruppene i framgrunn */
+ while (LC_NextBgr(&Bgr,LC_FRAMGR)) {
+ LC_RxGr(&Bgr,LES_OPTIMALT,&ngi,&nko,&info);
+ UT_FPRINTF(stderr,"%7ld: %9lld %9lld %7ld %7ld %3hd %3hd %5ld %4hx %8lu %8lu\n",
+ Sys.GrId.lNr,
+ Sys.pGrInfo->sosi_st,
+ Sys.pGrInfo->rb_st,
+ Sys.pGrInfo->rb_forrige_gr,
+ Sys.pGrInfo->rb_neste_gr,
+ Sys.pGrInfo->gnavn,
+ Sys.pGrInfo->ngi,
+ Sys.pGrInfo->nko,
+ Sys.pGrInfo->info,
+ Sys.pGrInfo->ulGiLen,
+ Sys.pGrInfo->ulPiLen);
+ /* List ut PINFO-pekerene */
+ if (ngi > 0) {
+ for (s=1; s<=Sys.pGrInfo->nko; ++s) {
+ if ((Sys.pInfo+s-1)->ulPiOfset != LC_INGEN_PINFO) {
+ UT_FPRINTF(stderr,"PI ofset %4hd: %8lu\n", s, (Sys.pInfo+s-1)->ulPiOfset);
+ }
+ }
+ }
+ }
+
+ if (AktBgr.lNr != INGEN_GRUPPE) {
+ LC_RxGr(&AktBgr,LES_OPTIMALT,&ngi,&nko,&info);
+ }
+}
diff --git a/src/FYBA/FYTA.cpp b/src/FYBA/FYTA.cpp
new file mode 100644
index 0000000..85d5301
--- /dev/null
+++ b/src/FYBA/FYTA.cpp
@@ -0,0 +1,199 @@
+/* === 900607 ============================================================= */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fyta.c */
+/* Innhold: Lagring og henting av "fil"-tabeller */
+/* ======================================================================== */
+
+#include "stdafx.h"
+
+#include <fcntl.h>
+
+
+/* Div. styrevariabler */
+#define NY 0
+#define LES 1
+#define SKRIV 2
+
+/* Tabellsystem */
+static short fytab_open = 0;
+static struct {
+ FILE *fpek;
+ size_t recl;
+ short modus;
+ long cur_lin;
+} fytab;
+
+
+/*
+AR-900105
+CH LC_InitTabel Åpner tabellsystemet
+CD =============================================================================
+CD Formål:
+CD Initierer tabellsystemet og åpner filen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD long n_rec i Antall reckords som skal nullstilles. Disse kan
+CD etterpå brukes til tilfeldig aksess. Utvidelse
+CD av filen kan senere bare skje i fortløpende
+CD rekkefølge.
+CD short rec_len i Reckordlengde. (Bruk sizeof for å finne lengden.)
+CD void *buffer i Peker til buffer som skal brukes for nullstilling.
+CD short ist r Status. (0=OK, -1=feil)
+CD
+CD Bruk:
+CD .
+CD struct{
+CD long snr;
+CD short ngi;
+CD short nko;
+CD } buffer;
+CD .
+CD .
+CD ist = LC_InitTabel(10000L,sizeof buffer,(void *)(&buffer));
+CD .
+CD ist = LC_PutTabel(linje,(void *)&buffer);
+CD .
+CD ist = LC_GetTabel(linje,(void *)&buffer);
+CD .
+CD LC_CloseTabel();
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_InitTabel(long n_rec,short rec_len,void *buffer)
+{
+ short ierr;
+
+ if (fytab_open){ /* Systemet er allerede i bruk */
+ return -1;
+ }
+ /* Åpner tabellfilen */
+ fytab.fpek = UT_OpenFile("fytabell.tmp","",UT_UPDATE,UT_UNKNOWN,&ierr);
+ if (ierr != UT_OK){ /* Åpningsfeil */
+ return -1;
+ }
+
+ fytab.recl = rec_len;
+
+ /* Nullstill tabellen */
+ if (fseek(fytab.fpek,0L,SEEK_SET) != 0){
+ return -1;
+ }
+ for (; n_rec>0; n_rec--){
+ if (fwrite(buffer,fytab.recl,1,fytab.fpek) != 1){
+ return -1;
+ }
+ }
+
+ fytab.modus = NY;
+ fytab_open = 1; /* Merke for at systemet aktivisert */
+
+ return 0;
+}
+
+
+/*
+AR-900106
+CH LC_GetTabel Get tabell-linje
+CD =============================================================================
+CD Formål:
+CD Henter en linje fra tabellfilen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD long linje i Linjenummer som skal hentes. (0 er første linje)
+CD void *buffer i Peker til struktur som skal ta mot lest reckord.
+CD short ist r Status (0=OK, -1=feil)
+CD
+CD Bruk:
+CD ist = LC_GetTabel(linje,(void *)&buffer);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_GetTabel(long linje,void *buffer)
+{
+ if ( ! fytab_open){ /* Systemet er ikke aktivisert */
+ return -1;
+ }
+
+ if (fytab.modus != LES || fytab.cur_lin != linje){ /* Posisjoner */
+ if (fseek(fytab.fpek,(long)(linje * fytab.recl),SEEK_SET) != 0){
+ return -1;
+ }
+ }
+
+ if (fread(buffer,fytab.recl,1,fytab.fpek) != 1){ /* Les */
+ return -1;
+ }
+
+ fytab.modus = LES;
+ fytab.cur_lin = linje + 1L;
+
+ return 0;
+}
+
+
+/*
+AR-900106
+CH LC_PutTabel Put tabell-linje
+CD =============================================================================
+CD Formål:
+CD Legg inn en linje fra tabellfilen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD long linje i Linjenummer som skal legges inn. (0 er første linje)
+CD (Største lovlige er 1 større enn det største hittil.)
+CD void *buffer i Peker til struktur som skal legges inn.
+CD short ist r Status (0=OK, -1=feil)
+CD
+CD Bruk:
+CD ist = LC_PutTabel(linje,(void *)&buffer);
+ =============================================================================
+*/
+SK_EntPnt_FYBA short LC_PutTabel(long linje,void *buffer)
+{
+ if ( ! fytab_open){ /* Systemet er ikke aktivisert */
+ return -1;
+ }
+
+ if (fytab.modus != SKRIV || linje != fytab.cur_lin){ /* Posisjoner */
+ if (fseek(fytab.fpek,(long)(linje * fytab.recl),SEEK_SET) != 0){
+ return -1;
+ }
+ }
+
+ if (fwrite(buffer,fytab.recl,1,fytab.fpek) != 1){ /* Skriv */
+ return -1;
+ }
+
+ fytab.modus = SKRIV;
+ fytab.cur_lin = linje + 1L;
+
+ return 0;
+}
+
+
+/*
+AR-900106
+CH LC_CloseTabel Stenge tabellsystemet
+CD =============================================================================
+CD Formål:
+CD Avslutter tabellsystemet og stenger og sletter filen.
+CD Tabellen kan nå åpnes på nytt for annen bruk.
+CD
+CD Parametre: ingen
+CD
+CD Bruk:
+CD LC_CloseTabel();
+ =============================================================================
+*/
+SK_EntPnt_FYBA void LC_CloseTabel(void)
+{
+ if (fytab_open){
+ fclose(fytab.fpek); /* Stenger tabellfilen */
+ UT_DeleteFile("fytabell.tmp"); /* Sletter tabellfilen */
+ fytab_open = 0; /* Merke for at systemet er stengt */
+ }
+}
diff --git a/src/FYBA/Fyba_Callback.cpp b/src/FYBA/Fyba_Callback.cpp
new file mode 100644
index 0000000..ca7c03d
--- /dev/null
+++ b/src/FYBA/Fyba_Callback.cpp
@@ -0,0 +1,232 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// Fil: Fyba_Callback.cpp
+// Eier: Statens kartverk, FYSAK-prosjektet
+//
+//////////////////////////////////////////////////////////////////////////
+//
+// Denne filen inneholder eksempel på callback-rutiner som kalles
+// av FYBA for feilmeldings-handtering og visning av framdrift under
+// indeksoppbygging.
+//
+// For å få et godt brukergrensesnitt bør disse rutinene endres til
+// det meldings og feilhandteringssystemet som brukes av hovedprogrammet.
+//
+// En tilsvarende enkel feilmeldingshandtering ligger i FYBA_DLL.DLL.
+// Denne (DLL'ens) meldingshandtering blir brukt hvis meldingsingsrutinene
+// ikke blir registrert av hovedprogrammet.
+//
+// Meldingsrutinene registreres med følgende rutiner:
+// - LC_SetErrorHandler
+// - LC_SetStartMessageHandler
+// - LC_SetShowMessageHandler
+// - LC_SetEndMessageHandler
+// - LC_SetCancelHandler
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#include "stdafx.h"
+
+#include <fyba.h>
+
+#ifdef WIN32
+# include <windows.h>
+#endif
+
+#ifdef LINUX
+
+#include <termios.h>
+#include <stdio.h>
+#include <sys/select.h>
+#include <sys/ioctl.h>
+
+ int _kbhit() {
+ static const int STDIN = 0;
+ static bool bInit = false;
+
+ if (! bInit) {
+ termios term;
+ tcgetattr(STDIN, &term);
+ term.c_lflag &= ~ICANON;
+ tcsetattr(STDIN, TCSANOW, &term);
+ setbuf(stdin, NULL);
+ bInit = true;
+ }
+
+ int bytesWaiting;
+ ioctl(STDIN, FIONREAD, &bytesWaiting);
+ return bytesWaiting;
+ }
+#else
+# include <conio.h>
+#endif
+
+/*
+AR-930907
+CH LC_ErrorHandler Feilmelding
+CD ==========================================================================
+CD Formål:
+CD Feilmelding.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short feil_nr i Feilmeldingsnummer
+CD char *logtx u Peker til feilmeldingstekst avslutta med '\0'.
+CD char *vartx u Peker til feilmeldingstekst avslutta med '\0'.
+CD
+CD Bruk:
+CD LC_SetErrorHandler(LC_ErrorHandler);
+ ==========================================================================
+*/
+void LC_ErrorHandler (short feil_nr, const char logtx[], const char vartx[])
+{
+ short strategi;
+ char *feilmelding;
+
+ /* Hent feilmeldingstekst og strategi */
+ strategi = LC_StrError(feil_nr,&feilmelding);
+
+ /* Meldingen skrives */
+ if (strategi > 0) {
+ printf("\n%s %s\n",feilmelding,vartx);
+ switch(strategi) { /* Velg strategi */
+ case 1:
+ case 2:
+ break;
+ case 3:
+ printf("\aTrykk [Enter] for å fortsette:");
+ if (getchar() == 0) getchar();
+ break;
+ case 4:
+ printf("\aTrykk [Enter] for å avbryte programmet:");
+ if (getchar() == 0) getchar();
+ exit(2);
+ break;
+ }
+ }
+}
+
+
+/*
+AR-900609
+CH LC_StartMessageHandler Starte meldingsvisning
+CD =============================================================================
+CD Formål:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen initiering av visning av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kallt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *cfil i Ekstra meldingstekst (filnavn)
+CD
+CD Bruk:
+CD LC_SetStartMessageHandler(LC_StartMessageHandler);
+ =============================================================================
+*/
+void LC_StartMessageHandler(const char *fnam)
+{
+#ifndef LINUX
+ printf("\nLeser: %s ",fnam);
+ printf("\n0%%");
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_ShowMessageHandler Vise melding
+CD =============================================================================
+CD Formål:
+CD Vising av melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen av visnig av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kalt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD double prosent i Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_SetShowMessageHandler(LC_ShowMessageHandler);
+ =============================================================================
+*/
+void LC_ShowMessageHandler(double prosent)
+{
+#ifndef LINUX
+ printf("\r%d%%",(short)prosent);
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_EndMessageHandler Avslutt melding
+CD =============================================================================
+CD Formål:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Her skal brukerprogrammet legge inn sin egen avslutning av visning av framdrift
+CD under indeksoppbygging.
+CD
+CD Denne rutinen blir kalt fra FYBA under indeksoppbygging, og den skal
+CD ikke kalles fra brukerprogramvaren.
+CD
+CD Parametre:
+Dette CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_SetEndMessageHandler(LC_EndMessageHandler);
+ =============================================================================
+*/
+void LC_EndMessageHandler(void)
+{
+#ifndef LINUX
+ printf("\r100%% ferdig.");
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-910402
+CH LC_CancelHandler Sjekk om Esc er trykket
+CD ==========================================================================
+CD Formål:
+CD Sjekk om det er trykt på Esc (Avbryte indeksoppbygging).
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sAvbrutt r UT_TRUE = Cancel
+CD UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD LC_SetCancelHandler(LC_CancelHandler);
+ ==========================================================================
+*/
+short LC_CancelHandler(void)
+{
+ int tast = 0;
+
+ if (_kbhit()) {
+ tast = getchar();
+ }
+ return ((tast == 27)? UT_TRUE : UT_FALSE );
+}
diff --git a/src/FYBA/Fyba_melding.cpp b/src/FYBA/Fyba_melding.cpp
new file mode 100644
index 0000000..bc9d733
--- /dev/null
+++ b/src/FYBA/Fyba_melding.cpp
@@ -0,0 +1,201 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// Fil: Fyba_melding.cpp
+// Eier: Statens kartverk, FYSAK-prosjektet
+//
+//////////////////////////////////////////////////////////////////////////
+//
+// Denne filen inneholder eksempel på callback-rutiner som kalles
+// av FYBA for feilmeldings-handtering og visning av framdrift under
+// indeksoppbygging.
+//
+// For å få et godt brukergrensesnitt bør disse rutinene endres til
+// det meldings og feilhandteringssystemet som brukes av hovedprogrammet.
+//
+// Rutinene må kompileres og linkes sammen med hovedprogrammet når
+// FYBA brukes som LIB.
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+//
+// Innholdet i rutinene må byttes ut med meldingshandtering som er tilpasset
+// det aktuelle hovedprogrammet.
+//////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+// Fyba_melding.cpp
+//
+// Denne filen inneholder eksempel på rutiner som må linkes inn i
+// hovedprogrammet når FYBA brukes som LIB.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <fyba.h>
+
+//static short sProsent;
+
+
+/*
+AR-890911
+CH LC_Error Feilmeldingsrutine
+CD =============================================================================
+CD Formål:
+CD Standard feilmeldingsrutine.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short feil_nr i Feil-nummer
+CD char *logtx i Tekst som bare skrives til logfil.
+CD Eks:"(utført i LC_RxGr)"
+CD char *vartx i Denne tekststreng henges etter feilmeldingsteksten.
+CD
+CD Bruk:
+CD LC_Error(35,"(Kallt i LC_Error)","");
+ =============================================================================
+*/
+void LC_Error(short feil_nr,const char *logtx,const char *vartx)
+{
+ char szErrMsg[260];
+ short strategi;
+ char *pszFeilmelding;
+
+
+ // Egen enkel implementasjon av feilhandtering
+ /* Hent feilmeldingstekst og strategi */
+ strategi = LC_StrError(feil_nr,&pszFeilmelding);
+ switch(strategi) {
+ case 2: UT_SNPRINTF(szErrMsg,260,"%s","Observer følgende! \n\n"); break;
+ case 3: UT_SNPRINTF(szErrMsg,260,"%s","Det er oppstått en feil! \n\n"); break;
+ case 4: UT_SNPRINTF(szErrMsg,260,"%s","Alvorlig feil avslutt programmet! \n\n"); break;
+ default: szErrMsg[0]='\0';
+ }
+
+ #ifdef WIN32
+ if (strategi > 2) {
+ Beep(100,500);
+ }
+
+ if (UT_StrCat (szErrMsg,pszFeilmelding, sizeof(szErrMsg))) {
+ if (UT_StrCat (szErrMsg,&vartx[0], sizeof(szErrMsg))) {
+ MessageBox(NULL, szErrMsg, "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+
+ } else {
+ MessageBox(NULL, "Klarer ikke å vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+ }
+
+ } else {
+ MessageBox(NULL, "Klarer ikke å vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+ }
+ #else
+ printf("\nError: %s ",pszFeilmelding);
+ fflush(stdout);
+ #endif
+}
+
+
+/*
+AR-900609
+CH LC_StartMess Vise melding
+CD =============================================================================
+CD Formål:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFilnavn i Ekstra meldingstekst (filnavn)
+CD
+CD Bruk:
+CD LC_StartMess(pszFilnavn);
+ =============================================================================
+*/
+void LC_StartMessage(char const *pszFilnavn)
+{
+#ifndef LINUX
+ printf("\nLeser: %s ",pszFilnavn);
+ printf("\n0%%");
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_ShowMess Vise melding
+CD =============================================================================
+CD Formål:
+CD Vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD double prosent i Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_ShowMess(prosent);
+ =============================================================================
+*/
+void LC_ShowMessage(double prosent)
+{
+#ifndef LINUX
+ printf("\r%d%%",(short)prosent);
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-900609
+CH LC_EndMess Avslutt melding
+CD =============================================================================
+CD Formål:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_EndMess();
+ =============================================================================
+*/
+void LC_EndMessage(void)
+{
+#ifndef LINUX
+ printf("\r100%% ferdig.");
+ fflush(stdout);
+#endif
+}
+
+
+/*
+AR-910402
+CH LC_Cancel Sjekk om Esc er trykket
+CD ==========================================================================
+CD Formål:
+CD Sjekk om det er trykkt på Esc (Avbryte indeksoppbygging).
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sAvbrutt r UT_TRUE = Cancel
+CD UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD sAvbrutt = LC_Cancel();
+ ==========================================================================
+*/
+short LC_Cancel(void)
+{
+ /* Ikke mulig å avbryte */
+ return UT_FALSE;
+}
+
diff --git a/src/FYBA/Fyba_melding_dll.cpp.bak b/src/FYBA/Fyba_melding_dll.cpp.bak
new file mode 100644
index 0000000..0da5310
--- /dev/null
+++ b/src/FYBA/Fyba_melding_dll.cpp.bak
@@ -0,0 +1,368 @@
+//////////////////////////////////////////////////////////////////////////
+// Fil: fyba_melding_dll.cpp
+//////////////////////////////////////////////////////////////////////////
+#include "stdafx.h"
+
+#include "fyba.h"
+
+extern void (*LC_ErrorAdr) (short ifeilnr, const char *logtx, const char *vartx);
+extern void (*LC_StartMessageAdr)(const char *cfil);
+extern void (*LC_ShowMessageAdr)(double prosent);
+extern void (*LC_EndMessageAdr)(void);
+extern short (*LC_CancelAdr)(void);
+
+static short sProsent;
+
+// Rutiner for å definere callback-rutiner for informasjon til brukeren.
+
+/*
+AR:2006-03-21
+CH LC_SetErrorHandler Registrer feilmeldingsrutine
+CD =============================================================================
+CD Formål:
+CD Registrer feilmeldingsrutine.
+CD Feilmeldingsrutinen blir kallt hvis det oppstår feil.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD void (*f) (short ,char *,char *) i Peker til feilmeldingsrutine
+CD
+CD Bruk:
+CD LC_SetErrorHandler(ErrorHandler);
+CD
+CD
+CD Feilmeldingsrutinen skal ha følgende definisjon:
+CD
+CD void ErrorHandler(short feil_nr,const char *logtx,const char *vartx);
+CD
+CD Med følgende parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short feil_nr i Feil-nummer
+CD char *logtx i Tekst som bare skrives til logfil.
+CD Eks:"(utført i LC_RxGr)"
+CD char *vartx i Denne tekststreng henges etter feilmeldingsteksten.
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetErrorHandler(void (*f) (short,const char*,const char*))
+{
+ LC_ErrorAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetStartMessageHandler Registrer initieringsrutine
+CD =============================================================================
+CD Formål:
+CD Registrer initieringsrutine.
+CD Initieringsrutinen blir kalt for å starte visning av framdrift.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD void (*f)(char*) i Peker til initieringsrutine
+CD
+CD Bruk:
+CD LC_SetStartMessageHandler(StartMessageHandler);
+CD
+CD Initieringsrutinen skal ha følgende definisjon:
+CD
+CD void StartMessageHandler(char *pszFilnavn);
+CD
+CD Med følgende parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFilnavn i Ekstra meldingstekst (filnavn)
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetStartMessageHandler(void (*f)(const char*))
+{
+ LC_StartMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetShowMessageHandler Registrer visningsrutine
+CD =============================================================================
+CD Formål:
+CD Registrer visningsrutine.
+CD Visningsrutine blir kalt for å vise framdrift ved indeks-oppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD void (*f)(double) i Peker til visningsrutine
+CD
+CD Bruk:
+CD LC_SetShowMessageHandler(ShowMessageHandler);
+CD
+CD Visningsrutinen skal ha følgende definisjon:
+CD
+CD void ShowMessageHandler(double prosent);
+CD
+CD Med følgende parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD double prosent i Prosent ferdig (0.0 - 100.0)
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetShowMessageHandler(void (*f)(double))
+{
+ LC_ShowMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetEndMessageHandler Registrer avslutningsrutine
+CD =============================================================================
+CD Formål:
+CD Registrer avslutningsrutine.
+CD Avslutningsrutinen blir kalt for å avslutte visning av framdrift ved indeksoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD void (*f)(void) i Peker til avslutningsrutine
+CD
+CD Bruk:
+CD LC_SetEndMessageHandler(EndMessageHandler);
+CD
+CD Avslutningsrutinen skal ha følgende definisjon:
+CD
+CD void EndMessageHandler(void);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetEndMessageHandler(void (*f)(void))
+{
+ LC_EndMessageAdr = f;
+}
+
+
+/*
+AR:2006-03-21
+CH LC_SetCancelHandler Registrer avbruddsstyring
+CD =============================================================================
+CD Formål:
+CD Registrer avbruddsstyring.
+CD Rutine for avbruddsstyring blir kalt for å sjekke om bruker ønsker
+CD å avbryte beregningen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short (*f)(void) i Peker til rutine for avbruddsstyring.
+CD
+CD Bruk:
+CD LC_SetCancelHandler(CancelHandler);
+CD
+CD Rutine for avbruddsstyring skal ha følgende definisjon:
+CD
+CD short CancelHandler(void);
+CD
+CD Med følgende parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short sAvbrutt r UT_TRUE = Cancel
+CD UT_FALSE = ikke avbrudd
+CD =============================================================================
+*/
+SK_EntPnt_FYBA void LC_SetCancelHandler(short (*f)(void))
+{
+ LC_CancelAdr = f;
+}
+
+
+/*
+AR-890911
+CH LC_Error Feilmeldingsrutine
+CD =============================================================================
+CD Formål:
+CD Standard feilmeldingsrutine.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD short feil_nr i Feil-nummer
+CD char *logtx i Tekst som bare skrives til logfil.
+CD Eks:"(utført i LC_RxGr)"
+CD char *vartx i Denne tekststreng henges etter feilmeldingsteksten.
+CD
+CD Bruk:
+CD LC_Error(35,"(Kallt i LC_Xxxx)","");
+CD =============================================================================
+*/
+void LC_Error(short feil_nr,const char *logtx,const char *vartx)
+{
+ char szErrMsg[260];
+ short strategi;
+ char *pszFeilmelding;
+
+
+ // Kaller hovedprogrammets implementasjon av feilhandteringen
+ if (LC_ErrorAdr != NULL) {
+ (*LC_ErrorAdr) (feil_nr,logtx,vartx);
+
+
+ // Egen enkel implementasjon av feilhandtering
+ } else {
+ /* Hent feilmeldingstekst og strategi */
+ strategi = LC_StrError(feil_nr,&pszFeilmelding);
+ switch(strategi) {
+ case 2: UT_SNPRINTF(szErrMsg,260,"%s","Observer følgende! \n\n");break;
+ case 3: UT_SNPRINTF(szErrMsg,260,"%s","Det er oppstått en feil! \n\n");break;
+ case 4: UT_SNPRINTF(szErrMsg,260,"%s","Alvorlig feil avslutt programmet! \n\n");break;
+ default: szErrMsg[0]='\0';
+ }
+
+#ifdef WIN32
+ if (strategi > 2) {
+ Beep(100,500);
+ }
+
+ if (UT_StrCat (szErrMsg,pszFeilmelding, sizeof(szErrMsg))) {
+ if (UT_StrCat (szErrMsg,&vartx[0], sizeof(szErrMsg))) {
+ MessageBox(NULL, szErrMsg, "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+
+ } else {
+ MessageBox(NULL, "Klarer ikke å vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+ }
+
+ } else {
+ MessageBox(NULL, "Klarer ikke å vise teksten", "Melding fra FYBA ", MB_ICONHAND | MB_OK);
+ }
+#endif
+ }
+}
+
+
+/*
+AR-900609
+CH LC_StartMessage Vise melding
+CD =============================================================================
+CD Formål:
+CD Starter vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD char *pszFilnavn i Ekstra meldingstekst (filnavn)
+CD
+CD Bruk:
+CD LC_StartMessage(pszFilnavn);
+CD =============================================================================
+*/
+void LC_StartMessage(const char *pszFilnavn)
+{
+ // Kaller hovedprogrammets implementasjon
+ if (LC_StartMessageAdr != NULL) {
+ (*LC_StartMessageAdr) (pszFilnavn);
+
+ // Egen enkel implementasjon
+ } else {
+#ifndef LINUX
+ printf("\nLeser: %s ",pszFilnavn);
+ printf("\n0%%");
+ fflush(stdout);
+#endif
+ }
+}
+
+
+/*
+AR-900609
+CH LC_ShowMessage Vise melding
+CD =============================================================================
+CD Formål:
+CD Vising av melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD double prosent i Prosent ferdig (0.0 - 100.0)
+CD
+CD Bruk:
+CD LC_ShowMessage(prosent);
+CD =============================================================================
+*/
+void LC_ShowMessage(double prosent)
+{
+ // Kaller hovedprogrammets implementasjon
+ if (LC_ShowMessageAdr != NULL) {
+ (*LC_ShowMessageAdr) (prosent);
+
+ // Egen enkel implementasjon
+ } else {
+#ifndef LINUX
+ printf("\r%d%%",(short)prosent);
+ fflush(stdout);
+#endif
+ }
+}
+
+
+/*
+AR-900609
+CH LC_EndMessage Avslutt melding
+CD =============================================================================
+CD Formål:
+CD Avslutt melding om baseoppbygging.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD
+CD Bruk:
+CD LC_EndMessage();
+CD =============================================================================
+*/
+void LC_EndMessage(void)
+{
+ // Kaller hovedprogrammets implementasjon
+ if (LC_EndMessageAdr != NULL) {
+ (*LC_EndMessageAdr) ();
+
+ // Egen enkel implementasjon
+ } else {
+#ifndef LINUX
+ printf("\r100%% ferdig.");
+ fflush(stdout);
+#endif
+ }
+}
+
+
+/*
+AR-910402
+CH LC_Cancel Sjekk om Esc er trykket
+CD ==========================================================================
+CD Formål:
+CD Sjekk om det er trykkt på Esc (Avbryte indeksoppbygging).
+CD
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD short sAvbrutt r UT_TRUE = Cancel
+CD UT_FALSE = ikke avbrudd
+CD
+CD Bruk:
+CD sAvbrutt = LC_Cancel();
+CD ==========================================================================
+*/
+short LC_Cancel(void)
+{
+ // Kaller hovedprogrammets implementasjon
+ if (LC_CancelAdr != NULL) {
+ return (*LC_CancelAdr) ();
+
+ // Egen enkel implementasjon
+ } else {
+ /* Ikke mulig å avbryte */
+ return UT_FALSE;
+ }
+}
+
diff --git a/src/FYBA/LICENSE b/src/FYBA/LICENSE
new file mode 100644
index 0000000..642f5d5
--- /dev/null
+++ b/src/FYBA/LICENSE
@@ -0,0 +1,24 @@
+/******************************************************************************
+* STATENS KARTVERK - FYSAK
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
diff --git a/src/FYBA/Makefile.am b/src/FYBA/Makefile.am
new file mode 100644
index 0000000..0243339
--- /dev/null
+++ b/src/FYBA/Makefile.am
@@ -0,0 +1,9 @@
+AM_CPPFLAGS = --pedantic -Wno-long-long -Wall -O2 -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -Wno-write-strings -I../GM -I../UT
+ACLOCAL_AMFLAGS = -I m5
+
+lib_LTLIBRARIES = libfyba.la
+libfyba_la_SOURCES = fyba.h Fyba_Callback.cpp FYBA_DLL.cpp FYHO.cpp FYLD.cpp FYLH.cpp fyln.cpp FYLP.cpp FYLS.cpp FYLX.cpp stdafx.cpp FYBA.cpp Fyba_melding.cpp FYLB.cpp FYLE.cpp FYLI.cpp FYLO.cpp FYLR.cpp FYLU.cpp FYTA.cpp fyba.h fyba_strings.h fybax.h stdafx.h
+libfyba_la_LDFLAGS = -version-info 0:0:0
+
+library_includedir=$(includedir)/fyba
+library_include_HEADERS = fyba.h
diff --git a/src/FYBA/fyba.h b/src/FYBA/fyba.h
new file mode 100644
index 0000000..c75f19e
--- /dev/null
+++ b/src/FYBA/fyba.h
@@ -0,0 +1,1484 @@
+/******************************************************************************
+*
+* STATENS KARTVERK - FYSAK
+*
+* Filename: fyba.h
+*
+* Content: Prototyper for rutiner for les/skriv av SOSI-fil.
+*
+* Copyright (c) 1990-2011 Statens kartverk
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+* DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#pragma once
+
+//
+// Når FYBA brukes som DLL, defineres FYBA_DLL_IMPORTS
+// Når FYBA brukes som lib er det ikke nødvendig med noen spesiell definisjon.
+// (Når FYBA skal kompileres/lages som DLL defineres FYBA_DLL_EXPORTS)
+//
+
+
+#ifdef WIN32
+#ifdef FYBA_DLL_IMPORTS /* FYBA brukes som DLL */
+# pragma comment (lib, "FYBA_DLL.lib")
+//# ifdef _DEBUG
+//# pragma comment (lib, "FYBA_DLLD.lib")
+//# else
+//# pragma comment (lib, "FYBA_DLL.lib")
+//# endif
+#else
+# ifndef FYBA_DLL_EXPORTS /* FYBA brukes som LIB */
+# ifdef _DEBUG
+# pragma comment (lib, "FYBAD.lib")
+# else
+# pragma comment (lib, "FYBA.lib")
+# endif
+# endif
+#endif
+
+
+# ifndef DllExport
+# define DllExport __declspec(dllexport)
+# define DllImport __declspec(dllimport)
+# endif /* !DllExport */
+#else
+# define DllExport
+# define DLLImport
+# define __cdecl
+#endif
+
+
+#ifndef SK_EntPnt_FYBA
+
+# ifdef FYBA_DLL_EXPORTS /* FYBA kompileres til DLL ==> FYBA_DLL.DLL */
+# define SK_EntPnt_FYBA DllExport
+
+# else
+# ifdef FYBA_DLL_IMPORTS /* FYBA brukes som DLL */
+# define SK_EntPnt_FYBA DllImport
+
+# else /* FYBA kompileres eller brukes som LIB */
+# define SK_EntPnt_FYBA
+# endif
+# endif
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <fygm.h>
+#include <fyut.h>
+
+
+/* ======================================================= */
+/* Definerer konstanter */
+/* ======================================================= */
+ /* Max-verdier for basen */
+#define LC_MAX_GRU 10000000 /* Max grupper i en base */
+#define LC_MAX_GINFO 6000 /* Max linjer GINFO i en gruppe */
+#define LC_MAX_GINFO_BUFFER 250000 /* GINFO-buffer */
+#define LC_MAX_KOORD 90000 /* Max antall koordinater i en gruppe */
+#define LC_MAX_PINFO_BUFFER 250000 /* PINFO-buffer */
+#define LC_MAX_ANT_PRIOR 128 /* Max antall prioriteter */
+#define LC_DATO_LEN 9 /* Max lengde dato (inkl. '\0') */
+#define LC_BASEVER_LEN 50 /* Max lengde av szBaseVer (inkl. '\0') */
+#define LC_MAX_SOSINAVN_LEN 50 /* Max lengde for SOSI-navn (inkl. '\0') */
+#define LC_MAX_NAVN 500 /* Max linjer i navnetabellen (pr. fil) */
+#define LC_NGISLAG_LEN 50 /* Max lengde av NGIS-LAG fra filhodet */
+#define LC_MAX_SOSI_LINJE_LEN 1024 /* Max linjelengde for lesing fra SOSI-filen */
+#define LC_MAX_OBJTYPE_LEN 33 // Max lengde av objettypenavn (inkl. '\0')
+
+#define LC_INTERNT_TEGNSETT TS_ISO8859
+
+
+ /* Konstanter for basetype */
+#define LC_KLADD 3 /* Kladdebase */
+#define LC_BASE 1 /* Vanlig base */
+
+ /* Konstanter for åpning av eksisterende base */
+#define UKJENT_BASE -1
+#define FEIL_VERSJON -2
+#define IKKE_STENGT -3
+#define IDX_MANGLER -4
+#define IDX_FEIL_DATO -5
+#define SOS_MANGLER -6
+#define SOS_FEIL_DATO -7
+#define SOS_FEIL_AKSESS -8
+
+ /* Konstanter for LC_CloseBase */
+#define RESET_IDX 0 /* Fjern indeksfilene */
+#define SAVE_IDX 1 /* Lagrer indeksfilene */
+
+ /* Konstanter for LC_OpenSos */
+#define LC_BASE_FRAMGR 1 /* Framgrunnsfil i basen */
+#define LC_BASE_BAKGR 2 /* Bakgrunnsfil i basen (Bare les) */
+#define LC_SEKV_LES 3 /* Sekvensiell, les */
+#define LC_SEKV_SKRIV 4 /* Sekvensiell, skriv */
+#define LC_SEKV_UTVID 5 /* Sekvensiell, utvid gammel fil */
+
+#define LC_NY_IDX 1 /* Tvungen nygenerering */
+#define LC_GML_IDX 0 /* Bruk gammel .idx hvis den er OK */
+
+#define LC_VIS_STATUS 1 /* Vis status under indeksoppbygging */
+#define LC_INGEN_STATUS 0 /* Ikke vis status */
+
+ /* Lag i basen */
+#define LC_SEKV 0x0001 /* Sekvensiell fil */
+#define LC_BAKGR 0x0002 /* Bakgrunnsfil i base */
+#define LC_FRAMGR 0x0004 /* Framgrunnsfil i base */
+
+ /* Status fra LC_OpenSos */
+#define LC_CANCEL -3 // Avbrutt med [Esc], eller lesefeil
+#define LC_DUBLIKAT -4 // Filen er i basen fra før
+#define LC_OPPTATT -5 // Filen er åpen i annet program
+
+ /* Konstanter for LC_SetNgisModus */
+#define NGIS_NORMAL 0 /* Vanlig modus */
+#define NGIS_SPESIAL 1 /* Spesialmodus der det er mulig å finne og
+ lese grupper som er merka som sletta */
+
+ /* Konstanter for LC_SetUtvidModus */
+#define LC_UTVID_SIKKER 0 /* SOSI-filen stenges og filstørrelsen oppdateres */
+ /* etter hver gruppe som er skrevet på slutten av filen */
+#define LC_UTVID_RASK 1 /* SOSI-filen stenges IKKE etter hver oppdatering*/
+
+ /* Konstanter til QueryGP mfl. */
+#define LC_HODE 1
+#define LC_GINFO 2
+#define LC_PINFO 4
+
+/* Konstanter til bruk ved kombinert flatesøk. JAØ-20000516 */
+#define LC_INGEN 0
+#define LC_NOEN 1
+#define LC_ALLE 2
+
+ /* Gruppenummer når det ikke er noen aktuell gruppe */
+#define INGEN_GRUPPE -1L /* bgr når det ikke er noen akt. gruppe */
+
+ /* Lesemetode for LC_RxGr */
+#define LES_OPTIMALT 0 /* Les mest effektivt base/SOSI */
+#define LES_SOSI 1 /* Les alltid fra SOSI-filen */
+
+ /* Skrivemetode for LC_WxGr */
+#define SKRIV_OPTIMALT 0 /* Skriv mest effektivt kø/SOSI */
+#define SKRIV_SOSI 1 /* Skriv direkte til SOSI-filen */
+
+ /* Handteringmetode for NGIS-nøkkel for LC_CopyGr */
+#define OPPDATER_NGIS 0 /* NGIS-nøkkel oppdateres i henhold til hodet i filen det kopieres til */
+#define BEVAR_NGIS 1 /* NGIS-nøkkel bevares uforandret i kopien */
+
+ /* Manglende kvalitetsopplysninger */
+#define KVAL_MET_UNDEF -1 /* Udefinert metode */
+#define KVAL_MET_STD -2 /* Standard metode fra nivå over */
+
+#define KVAL_NOY_UNDEF -1L // Udefinert nøyaktighet. - OBS! Denne skal utgå
+#define KVAL_NOY_STD -2L /* Standard nøyaktighet fra nivå over */
+#define KVAL_NOY_UKJENT 999999L // Ukjent nøyaktighet
+
+
+#define KVAL_SYN_GOD 0 /* Godt synlig */
+#define KVAL_SYN_UNDEF -1 /* Udefinert synbarhet */
+#define KVAL_SYN_STD -2 /* Standard synbarhet fra nivå over */
+
+ /* For LC_GetTH og LC_PutTH */
+ /* Konstant for å si at punktet ikke har høyde */
+ /* OBS! Denne må stemme med definisjonen i filen port.h */
+#ifndef HOYDE_MANGLER
+# define HOYDE_MANGLER -9999.999 /* Høyde mangler i punktet */
+#endif
+
+#define KOORD_MANGLER -9999.999 /* Koordinat mangler i punktet */
+
+ /* Gruppeinformasjon */
+#define GI_PINFO ((unsigned short)0x0001) /* Har PINFO */
+#define GI_NAH ((unsigned short)0x0002) /* Gruppen har høyde informasjon (..NØH) */
+#define GI_KP ((unsigned short)0x0004) /* Har knutepunkt (...KP n) */
+#define GI_REF ((unsigned short)0x0008) /* Har referanser (.. :n) */
+#define GI_OY_REF ((unsigned short)0x0010) /* Har referanser med øy */
+#define GI_SLETTA ((unsigned short)0x0020) /* Er sletta (merka som sletta) */
+#define GI_NGIS ((unsigned short)0x0040) /* Er tatt ut fra NGIS */
+#define GI_NAD ((unsigned short)0x0080) /* Har dybde informasjon (..NØD) */
+#define GI_READ_ONLY ((unsigned short)0x0100) /* Bare leseaksess (kan ikke endres) */
+
+ /* Avgrensing av brukttabellen */
+#define BT_MIN_BT 0 /* Første kolonne i brukttabellen */
+#define BT_MAX_BT 31 /* Siste kolonne i brukttabellen */
+#define BT_MIN_USER 1 /* Første tilgjengelig for brukerprogram */
+#define BT_MAX_USER 26 /* Siste tilgjengelig for brukerprogram */
+ /* Spesielle posisjoner i brukttabellen */
+#define BT_SKRKO 0 /* I skrivekø */
+#define BT_REFBOX 27 /* Referanser er brukt i omskrevet boks */
+#define BT_X 28 /* Reserve systemposisjon */
+#define BT_SNRSOK 29 /* Funnet ved SNR-søk */
+#define BT_GISOK 30 /* Funnet ved GINFO-søk */
+#define BT_GEOSOK 31 /* Funnet ved geografisk søk */
+
+ /* Logiske operasjoner mellom kolonner i brukttabellen */
+#define BC_AND 0
+#define BC_OR 1
+#define BC_COPY 2
+#define BC_INVERT 3
+#define BC_EXCHANGE 4
+
+
+ /* Konstanter for get og put referansenummer */
+#define START_OY 9999999L /* Start øy */
+#define SLUTT_OY -9999999L /* Slutt øy */
+
+ /* Konstanter for GetArrayTK() */
+#define HENT_FORRFRA 1 /* Vanlig */
+#define HENT_BAKFRA -1 /* Snu buferet */
+
+/* UTVALG */
+
+// Utvalgskommandoer
+#define LC_U_OG 1 // ..OG
+#define LC_U_ELLER 2 // ..VELG og ..ELLER
+
+
+ // Utvalgsmetoder
+#define LC_U_IKKE 0 // ! Ikke (Tilslag når SOSI-navnet
+ // ikke finnes. Bare GINFO.)
+#define LC_U_ALLE 1 // AL Alle
+#define LC_U_FRATIL 2 // <> Fra-til
+#define LC_U_UTENFOR 3 // >< Utenfor
+#define LC_U_MINDRE 4 // < Mindre-enn
+#define LC_U_STORRE 5 // > Større-enn
+#define LC_U_DELELIG 6 // / Delelig-med, eventuellt med
+ // sjekk på om restverdi er 2. verdi
+#define LC_U_UDELELIG 7 // !/ Ikke-delelig-med
+#define LC_U_CONTEIN 8 // () Inneholder
+#define LC_U_IKKECONTEIN 9 // !() Inneholder ikke (Tilslag når
+ // denne navn og verdi kombinasjonen
+ // ikke finnes)
+#define LC_U_LIK 10 // = Lik
+#define LC_U_IKKEVALGT 11 // IV Ikke valgt (Tilslag når gruppen
+ // ikke er tegnet ennå. Kombineres
+ // med SOSI-navnet "..*")
+#define LC_U_IKKELIK 12 // != Ikke lik (Tilslag når denne
+ // navn og verdi kombinasjonen ikke
+ // finnes)
+#define LC_U_FLERE 13 // FL Flere (Tilslag når SOSI-navnet
+ // forekommer flere ganger.)
+#define LC_U_IKKEFLERE 14 // !FL Ikke flere enn (Tilslag når
+ // SOSI-navnet IKKE forekommer
+ // flere ganger enn gitt antall.)
+
+
+
+ // Parametertyper
+#define LC_U_TALL 1 // Heltall
+#define LC_U_FLYT 2 // Flyttall
+#define LC_U_ALFA 4 // Tekststreng
+#define LC_U_DEFINERT 8 // Type definert i utvalgsregel
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Kvalitet !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KVALITET { /* Standard Kvalitet */
+ short sMetode;
+ long lNoyaktighet;
+ short sSynbarhet;
+ short sHoydeMetode;
+ long lHoydeNoyaktighet;
+} LC_KVALITET;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Buffer for lesing av SOSI-fil !
+ *!--------------------------------------------------------------!
+ */
+
+typedef struct dLB_LESEBUFFER {
+ char tx[LC_MAX_SOSI_LINJE_LEN]; /* Lesebuffer */
+ UT_INT64 filpos; /* Filposisjon for starten av bufret */
+ UT_INT64 startpos; /* Startposisjon i filen for aktuellt SOSI-navn */
+ char *cp; /* Peker til aktuell posisjon i bufret */
+ char *pp; /* Peker til start parameter */
+ char *ep; /* Peker til posisjon etter aktuellt ord */
+ char *np; /* Peker til posisjon etter parameter (neste cp) */
+ short cur_navn[6]; /* Aktuellt SOSI-navn på dette nivå */
+ short cur_niv; /* Aktuellt nivå (der cp peker) (Ant. prikker) */
+ short cur_ant_par; /* Antall parametre på aktuellt nivå */
+ short cur_type; /* Viser hva aktuellt set inneholder */
+ short set_brukt; /* Status som viser om aktuellt "sett" er brukt */
+ short sTegnsett; /* SOSI-filens tegnsett */
+ short sStatus; /* Status, viser om buffer har brukbart innhold */
+} LB_LESEBUFFER;
+
+
+/*
+ *!----------------------------------------------------------!
+ *! BUFFER for koordinater og GINFO i minne !
+ *!----------------------------------------------------------!
+*/
+
+/*
+CH SOSI-buffer Binær kopi av SOSI-filen
+CD For å øke hastigheten holder FYBA en binær kopi av SOSI-filen.
+CD Denne kopien ligger delevis i minne og delevis på disk.
+CD
+CD Denne kopien består av gruppeinformasjon, koordinater og punktinformasjon.
+CD
+CD Gruppeinformasjonen for en gruppe handteres som en lang streng med pekere
+CD til startposisjon for hver GINFO-linje.
+CD
+CD !-----------:-----------:----------:----------------------------------!
+CD ! GINFO 1 ! GINFO 2 ! GINFO 3 ! ..... !
+CD !-----------:-----------:----------:----------------------------------!
+CD ! ! !
+CD !---------! ! !
+CD ! ! !
+CD !--------! ! ! !
+CD ! GINFO ! ! ! !
+CD !--------! ! ! !
+CD ! ofset !-! ! !
+CD ! !----- !
+CD ! !-----------------
+CD
+CD Koordinatene lagres i egne array. Punktinformasjonen lagres som
+CD en lang streng for hele gruppen med peker for hvert punkt til startposisjon
+CD for PINFO for hvert punkt på samme måte som GINFO.
+CD
+CD !--------! !--------! !--------:-------:--------!
+CD ! Øst ! ! Nord ! ! Høyde ! KP ! PINFO !
+CD !--------! !--------! !--------!-------!--------!
+CD ! double ! ! double ! ! double ! short ! ushort !
+CD ! m ! ! m ! ! m ! ! ofset !
+*/
+typedef struct d_LB_INFO {
+ double dHoyde; // Høyde
+ short sKp; // Knutepunkt (0=ikke knutepunkt)
+ unsigned long ulPiOfset; // PINFO ofset i eget buffer
+} LB_INFO;
+
+
+# define LC_INGEN_PINFO ULONG_MAX /* Offset ved tom PINFO */
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Navnetabell !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dSOSINAVN { /* Navnetabellen */
+ char szNavn[LC_MAX_SOSINAVN_LEN]; /* Sosi-navn */
+ unsigned char ucAntPar; /* Antall parametre til dette navnet */
+ char cNivo; /* "Prikk-nivå" (1 = Gruppenavn) */
+ bool bBrukt; // Viser om navnet er vært brukt
+} SOSINAVN;
+
+typedef struct dLC_NAVNETABELL {
+ short sAntNavn; /* Antall navn totalt i navnetabellen */
+ SOSINAVN sosi[LC_MAX_NAVN]; /* Navnetabellen */
+} LC_NAVNETABELL;
+
+
+# define LC_ANT_PAR_UKJENT 255 /* Antall parametre til dette navnet er
+ ukjent, ta med fram til neste " ." */
+
+ /* Definerte navn */
+#define L_SLUTT 0
+#define L_PUNKT 1
+#define L_LINJE 2
+#define L_KURVE 3
+#define L_BUE 4
+#define L_BUEP 5
+#define L_SIRKEL 6
+#define L_SIRKELP 7
+#define L_KLOTOIDE 8
+#define L_SVERM 9
+#define L_TEKST 10
+#define L_TRASE 11
+#define L_FLATE 12
+#define L_BEZIER 13
+#define L_RASTER 14
+#define L_DEF 15
+#define L_OBJDEF 16
+#define L_MLINJE 17
+#define L_STRUKTUR 18
+#define L_OBJEKT 19
+#define L_SYMBOL 20
+#define L_HODE 21 /* L_HODE må alltid ligge sist av gruppenavnene */
+
+#define L_NA 22 /* Andre definerte navn */
+#define L_NAH 23
+#define L_REF1 24
+#define L_REF2 25
+#define L_RADIUS 26
+#define L_ENHET2 27
+#define L_ENHET2H 28
+#define L_ENHET2D 29
+#define L_ENHET3 30
+#define L_ENHET3H 31
+#define L_ENHET3D 32
+#define L_ORIGONO 33
+#define L_HOYDE 34
+#define L_DYBDE 35
+#define L_NAD 36
+#define L_NGISFLAGG 37
+#define L_NGISLAG 38
+#define L_OBJTYPE 39
+#define L_KP 40 /* L_KP må alltid ligge sist av de forhåndsdefierte navnene */
+
+
+
+/* ======= INDEKS-TABELLER =================== */
+
+/*
+CH Serienummer-tabell
+CD !-------------*
+CD ! Gruppenummer!
+CD !-------------! Linjenummer i tabellen er serienummer.
+CD ! lGrNr !
+CD ! (long) !
+CD *-------------*
+*/
+
+
+
+/*
+CH Geografisk-søketabell Geografisk søketabell
+CD
+CD Geografisk søk er basert på omskrevet boks.
+CD Boksene organiseres i et R-tre.
+CD
+CD !-----------------------------------*
+CD ! Omskreven boks !
+CD ! !
+CD ! min-N ! min-Ø ! max-N ! max-Ø !
+CD ! ! ! ! !
+CD !--------!--------!--------!--------!
+CD !dMinNord!dMinAust!dMaxNord!dMaxAust!
+CD ! d ! d ! d ! d !
+CD ! ! ! ! !
+CD *-----------------------------------*
+*/
+
+/*
+ *!--------------------------------------------------------------!
+ *! Boks for geografisk søk !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BOKS{
+ double dMinAust;
+ double dMinNord;
+ double dMaxAust;
+ double dMaxNord;
+} LC_BOKS;
+
+#define LC_R_MAX_SON 3 /* Max antall sønner for hver node i R-treet */
+
+typedef struct dLC_R_NODE{
+ struct dLC_R_NODE *pFar; /* Far i treet (node) */
+ LC_BOKS Boks; /* Sum av omskreven boks for sønnene */
+ short sSonType; /* Hvilken type sønner har denne noden LC_NODE / LC_LEAF */
+ short sSonAnt; /* Antall sønner */
+ union {
+ struct dLC_R_NODE *pNode[LC_R_MAX_SON]; /* Sønner i treet (node) */
+ struct dLC_R_LEAF *pLeaf[LC_R_MAX_SON]; /* Sønner i treet (løv) */
+ } Son;
+} LC_R_NODE;
+
+#define LC_NODE 0
+#define LC_LEAF 1
+
+
+typedef struct dLC_R_LEAF{
+ LC_R_NODE *pFar; /* Far i treet (node) */
+ LC_BOKS Boks; /* Omskreven boks for gruppen */
+ long lNr; /* Gruppenummer i filen */
+} LC_R_LEAF;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Gruppetabel !
+ *!--------------------------------------------------------------!
+ */
+/*
+CH Gruppetabell Gruppetabell
+CD Dette er hovedtabellen med informasjon om hver enkelt gruppe på SOSI-filen.
+CD
+CD !------------------------------:-----------------------------------------------*
+CD !Start !Start !Ant. !Ant. ! Gruppeinnhold !
+CD ! på ! i !tegn !tegn !-----------------------------------------------!
+CD !SOSI- ! RB !GINFO- !PINFO- !Gruppe!ant. !ant. !Kvali- !Enhet ! Div. info !
+CD !fil ! !buffer !buffer !navn !GINFO! NØ ! tet ! ! (bit def.) !
+CD !-------!------!-------!-------!------!-----!-----!--------!------!------------!
+CD !sosi_st!rb_st !ulGiLen!ulPiLen!gnavn !ngi !nko !Kvalitet!dEnhet! info !
+CD ! n64 ! n64 ! ul ! ul ! s ! s ! l ! struct ! d ! us !
+CD ! ! ! ! ! ! ! ! ! !0=i !
+CD ! ! ! ! ! ! ! ! ! !1=H !
+CD ! ! ! ! ! ! ! ! ! !2=KP !
+CD ! ! ! ! ! ! ! ! ! !3=REF !
+CD ! ! ! ! ! ! ! ! ! !4=REF med ØY!
+CD ! ! ! ! ! ! ! ! ! !5=sletta !
+CD ! ! ! ! ! ! ! ! ! !6=NGIS oppd !
+CD *------------------------------------------------------------------------------*
+*/
+typedef struct dLC_GRTAB_LINJE{
+ unsigned long ulPrior[4]; /* Bitfelt for prioriteter. */
+ /* Siste bit viser om feltet er bygd opp. */
+ UT_INT64 sosi_st; /* Startposisjon i SOSI-filen */
+ UT_INT64 rb_st; /* Peker til start av gruppen i buffer-fil */
+ long rb_forrige_gr; /* Forrige gruppe i buffer-filen */
+ long rb_neste_gr; /* Neste gruppe i buffer-filen */
+ short gnavn; /* Gruppenavn. Eks. .HODE, .PUNKT, mm */
+ short ngi; /* Antall GINFO-linjer */
+ long nko; /* Antall koordinater */
+ unsigned short info; /* Info, se under gruppetabellen */
+ LC_KVALITET Kvalitet; /* Aktuell kvalitet fra GINFO */
+ char szObjtype[LC_MAX_OBJTYPE_LEN]; /* ..OBJTYPE fra GINFO */
+ double dEnhet; /* Aktuell enhet for gruppen i bufferet */
+ double dEnhetHoyde; /* Aktuell enhet-H for gruppen i bufferet */
+ double dEnhetDybde; /* Aktuell enhet-D for gruppen i bufferet */
+ unsigned long ulGiLen; /* Antall tegn i GINFO-buffer (inkl. \0) */
+ unsigned long ulPiLen; /* Antall tegn i PINFO-buffer (inkl. \0) */
+ LC_R_LEAF *pRL; /* Peker inn i geografisk søketre */
+
+} LC_GRTAB_LINJE;
+
+
+/*
+CH Brukttabell Merking av grupper
+CD Denne tabellen brukes delevis internt av FYBA, og delevis av brukerprogrammet.
+CD
+CD Følgende bit er definert:
+CD -------------------------------------------------------------------------
+CD 31 Gruppen er funnet ved geografisk søk -----! Brukere kan lese/bruke
+CD 30 Gruppen er funnet ved GINFO-utvalg ! disse, men det er ikke
+CD 29 Gruppen er funnet ved serienummer-søk ! lov til å endre dem.
+CD 28 Gruppen er i ringbufferet !
+CD 27 Referanser er brukt i omskrevet blokk ------!
+CD 26 -----!
+CD . ! Brukere har
+CD . ! full tilgang
+CD 2 ! til disse.
+CD 1 -----!
+CD 0 Gruppen ligger i kø for skriving til SOSI-filen
+*/
+
+
+ /*
+ *!--------------------------------------------------------------!
+ *! Overordnet blokk med pekere til de ulike indekstabellene !
+ *!--------------------------------------------------------------!
+ */
+#define LC_IDX_LIN_BLOKK 5000
+#define LC_ANT_IDX_BLOKK (LC_MAX_GRU / LC_IDX_LIN_BLOKK)
+typedef struct dLC_IDX_TABELL{
+ /* Array med pekere til starten av blokk med Gruppetabell-linjer */
+ LC_GRTAB_LINJE * GtAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+ /* Array med pekere til starten av blokk med Gruppenummer for gitt SNR */
+ long *SnrAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+ /* Array med pekere til starten av blokk med Brukttabell-linjer */
+ unsigned long *BtAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK];
+
+ /* Array med pekere til starten av blokk med Geo-tabell-linjer */
+ /* LC_GEOSOK_BOKS *GeoAdm[LC_MAX_GRU / LC_IDX_LIN_BLOKK]; */
+} LC_IDX_TABELL;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Koordinat 2D !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KOORD_2D { /* (ø,n) Koordinatpar */
+ double dAust; /* øst-koordinat */
+ double dNord; /* nord-koordinat */
+} LC_KOORD_2D;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Koordinat 3D !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_KOORD_3D { /* (ø,n,h) Koordinatpar */
+ double dAust; /* øst-koordinat */
+ double dNord; /* nord-koordinat */
+ double dHoyde; /* Høyde */
+} LC_KOORD_3D;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Rektangel !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_REKT {
+ double dMinAust;
+ double dMinNord;
+ double dMaxAust;
+ double dMaxNord;
+} LC_REKT;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Kontanter og struktur for handtering av TRANSPAR i filhodet !
+ *!--------------------------------------------------------------!
+ */
+// Maske som styrer hvilke elementer i LC_TRANSPAR som benyttes
+#define LC_TR_KOORDSYS ((unsigned short)0x0001) /* Koordsys */
+#define LC_TR_TRANSSYS ((unsigned short)0x0002) /* Transsys */
+#define LC_TR_GEOSYS ((unsigned short)0x0004) /* Geosys */
+#define LC_TR_GEOKOORD ((unsigned short)0x0008) /* Geokoord */
+#define LC_TR_ORIGO ((unsigned short)0x0010) /* Origo-nø */
+#define LC_TR_ENHET ((unsigned short)0x0020) /* Enhet */
+#define LC_TR_ENHETH ((unsigned short)0x0040) /* Enhet-h */
+#define LC_TR_ENHETD ((unsigned short)0x0080) /* Enhet-d */
+#define LC_TR_VERTDATUM ((unsigned short)0x0100) /* Vert-datum */
+#define LC_TR_VERTINT ((unsigned short)0x0200) /* Vert-int */
+#define LC_TR_VERTDELTA ((unsigned short)0x0400) /* Vert-delta */
+
+#define LC_TR_ALLT ((unsigned short)0xFFFF) /* Alle deler av ..TRANSPAR */
+
+
+// Definerer struktur for ..TRANSPAR
+typedef struct dLC_TRANSPAR {
+ /* ...KOORDSYS */
+ short sKoordsys;
+ char szKoordsysDatum[36];
+ char szKoordsysProjek[36];
+ /* ...TRANSSYS */
+ short sTranssysTilsys;
+ double dTranssysKonstA1;
+ double dTranssysKonstB1;
+ double dTranssysKonstA2;
+ double dTranssysKonstB2;
+ double dTranssysKonstC1;
+ double dTranssysKonstC2;
+ /* ...GEOSYS */
+ short sGeosysDatum;
+ short sGeosysProj;
+ short sGeosysSone;
+ /*...GEOKOORD */
+ short sGeoKoord;
+ /* ...ORIGO-NØ */
+ LC_KOORD_2D Origo;
+ //double dOrigoAust;
+ //double dOrigoNord;
+ /* ...ENHET */
+ double dEnhet;
+ /* ...ENHET-H */
+ double dEnhet_h;
+ /* ...ENHET-D */
+ double dEnhet_d;
+ /* ...VERT-DATUM */
+ char szVertdatHref[7];
+ char szVertdatDref[6];
+ char szVertdatFref[6];
+ char szVertdatHtyp[2];
+ /* ...VERT-INT */
+ short sVertintHref;
+ short sVertintDref;
+ short sVertintFref;
+ /* ...VERT-DELTA */
+ short sVdeltaMin;
+ short sVdeltaMax;
+} LC_TRANSPAR;
+
+
+#define LC_TR_GEOSYS_INGEN_VERDI -9999 // Brukes for å angi at projeksjon og sone under geosys ikke er gitt
+
+// Konstanter for definering av filtype (primært for bruk i GabEdit) JAØ-20010306
+#define LC_FILTYPE_UKJENT 0
+#define LC_FILTYPE_INAKTIV 1
+#define LC_FILTYPE_GAB_EIENDOM 2
+#define LC_FILTYPE_GAB_ADRESSE 3
+#define LC_FILTYPE_GAB_BYGNING 4
+#define LC_FILTYPE_BYGG 5
+#define LC_FILTYPE_DEK 6
+#define LC_FILTYPE_DEK_ENDRING 7
+#define LC_FILTYPE_GRUNNKRETS 8
+#define LC_FILTYPE_POSTKRETS 9
+#define LC_FILTYPE_SKOLEKRETS 10
+#define LC_FILTYPE_KIRKESOGN 11
+#define LC_FILTYPE_TETTSTED 12
+#define LC_FILTYPE_VALGKRETS 13
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Filadministrasjon !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_FILADM{
+ char szBaseVer[LC_BASEVER_LEN]; // Versjon og dato for aktuell versjon av FYBA
+ char szIdxVer[5]; // Indeksfil-versjon
+ short sIdxOpen; // UT_FALSE/UT_TRUE - Flagg som viser at indeks er åpnet
+ unsigned long ulPid; // Prosess ID for programmet som har åpnet filen
+ short sFilType; // Primært tenkt brukt i GabEdit, definerer hvilken type arbeidsfil dette er.
+ unsigned short usLag; // Lag: (LC_SEKV,LC_FRAMGR,LC_BAKGR)
+ char szNgisLag[LC_NGISLAG_LEN]; // Ngislag i filhodet
+ short sAccess; // Aksess: (READ / UPDATE)
+ /* short sDisk; */ // Disk for SOSI-filen (1=A, 2=B, osv.)
+ char *pszNavn; // Filnavn (SOSI-filens navn, inkl. sti
+ UT_INT64 SosiBytes; // Antall byte i SOSI-filen
+ FTID SosiTid; // Oppdateringstidspunkt for SOSI-filen
+ LC_TRANSPAR TransPar; // Transformasjonsparametre fra filhodet
+ unsigned short TransMaske; // Maske som viser hvilke deler av TransPar som inneholder data
+ LC_REKT Omr; // ..OMRÅDE fra filhodet
+ short sTegnsett; // Tegnsett fra filhodet eller standardverdi
+ char szDato[LC_DATO_LEN]; // ..DATO fra fil-hodet
+ short sSosiVer; // ..SOSI-VERSJON fra fil-hodet * 100
+ char SosiNiv[2]; // ..SOSI-NIVÅ fra fil-hodet
+ // SosiNiv[0] = nivå fra filåpningen
+ // SosiNiv[1] = nivå fra senere handtering
+ // Filhodet oppdateres når filen stenges
+ // short usUlovligRef; // Bryter som viser om det er ulovlige
+ // // referanser i filen (Indeksoppbygging)
+ unsigned short usDataFeil; // Flagg som viser om det er datafeil
+ // i filen (Indeksoppbygging)
+ LC_KVALITET Kvalitet; // Kvalitet fra filhodet
+
+ UT_INT64 n64AktPos; // Aktuell posisjon for sekv. skriv / les
+ UT_INT64 n64NesteLedigRbPos; // Neste ledige posisjon i buffer-filen
+ long lSisteGrRb; // Siste gruppe i buffer-filen
+
+ long lMaxSnr; // Største serienummer brukt i filen
+ long lAntGr; // Antall grupper i filen
+
+ struct dLC_NAVNETABELL SosiNavn; // Navnetabell
+
+ LC_IDX_TABELL *pIdx; // Starten av indekstabellen
+ LC_R_NODE *pGeoRN; // Peker til starten av trestruktur for geografisk søk
+ LC_BOKS Omraade; // Område angitt i filhodet ved åpning
+
+ struct dLC_FILADM *pNesteFil; // Peker til neste fil-adm.
+ struct dLC_BASEADM *pBase; // Peker til base-adm. for denne filen
+} LC_FILADM;
+
+
+/* Konstanter for flagg som viser om det er datafeil i filen (Indeksoppbygging) */
+#define LC_DATAFEIL_REF 1 /* Ulovlig referanse (referanse til gruppe som ikke finnes)*/
+#define LC_DATAFEIL_BUE 2 /* Ulovlige buer i filen */
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Baseadministrasjon !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BASEADM{
+ short sType; // Basetype: LC_BASE / LC_START_KLADD / LC_KLADD
+
+ long lAntGr; // Antall grupper i basen
+ LC_BOKS Omraade; // Summert område fra filhodene
+ short sAntFramgrFil; // Antall filer i framgrunn
+ short sAntBakgrFil; // Antall filer i bakgrunn
+
+ LB_LESEBUFFER BufAdm; // Vanlig lesebuffer mot SOSI-fil
+
+ LC_FILADM *pCurSos; // Fil-adm for åpen SOSI-fil
+ FILE *pfSos; // Filhandel for åpen SOSI-fil
+
+ LC_FILADM *pCurRb; // Fil-adm for åpen Rb-fil
+ FILE *pfRb; // Filhandel for åpen Rb-fil
+ short sModusRb; // LES eller SKRIV til buffer-filen
+ UT_INT64 n64FilPosRb; // Aktuell posisjon i buffer-filen
+
+ LC_FILADM *pForsteFil; // Peker til første fil-adm.
+ LC_FILADM *pSisteFil; // Peker til siste fil-adm.
+
+ struct dLC_BASEADM *pNesteBase; // Peker til neste base-adm
+} LC_BASEADM;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Gruppenummer !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_BGR {
+ LC_FILADM *pFil; /* Peker til FilAdm for SOSI-fil */
+ long lNr; /* Gruppenummer innen filen */
+} LC_BGR;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Hent flate-referanser, status !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_GR_STAT {
+ short sGiLinNr; /* Aktuell GINFO-linjenummer referanselesing */
+ short sRefPos; /* Aktuell posisjon i GINFO-linja */
+ short sRefLin; /* Viser om aktuel linje inneholder referanser */
+} LC_GR_STATUS;
+
+typedef struct dLC_GRF_STAT {
+ LC_GR_STATUS Omkr;
+ unsigned short usOmkretsFerdig;
+ LC_GR_STATUS Oy;
+ LC_BGR Bgr; /* Aktuell øy-gruppe */
+} LC_GRF_STATUS;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Geografisk søk, status mm. !
+ *!--------------------------------------------------------------!
+ */
+
+/* Kjede med resultatet av søket */
+typedef struct dLC_KJEDE_BGR {
+ LC_BGR Bgr;
+ struct dLC_KJEDE_BGR *pNesteKB;
+} LC_KJEDE_BGR;
+
+/* Søkemetode i basen */
+#define LC_GEO_SEKV 0x0000 /* Søker sekvensiellt gjennom gruppene */
+#define LC_GEO_RTRE 0x0001 /* Bruker R-tre-srukturene i søket */
+
+/* Status */
+typedef struct dLC_GEO_STAT {
+ unsigned short usMetode; /* Søkemetode (LC_GEO_SEKV eller LC_GEO_RTRE) */
+ double nvn,nva,ohn,oha; /* Rektangel for søkeområde. */
+ unsigned short usLag; /* Lag det skal søkes i. (LC_FRAMGR | LC_BAKGR) */
+ LC_BGR Bgr; /* Aktuell gruppe */
+ /* Kjede med resultatet av søket */
+ LC_KJEDE_BGR *pForsteKB;
+ LC_KJEDE_BGR *pSisteKB;
+ LC_KJEDE_BGR *pAktuellKB;
+} LC_GEO_STATUS;
+
+
+/*
+CH Utvalgstabell
+CD .===============================================================================.
+CD !Ginfo/!Utvalgs-!Prio-!SOSI-!Utvalgs-!Para-!Ledd-!Start !Slutt !Min !Max !Regel-!
+CD !Pinfo !kommando!ritet!navn !metode !type !nr !i str !i str ! ! !navn !
+CD !------!--------!-----!-----!--------!-----!-----!------!------!----!----!------!
+CD !gi_pi !kommando!sPri-!sosi !metode !type !ledd !start !slutt !min !max !regel !
+CD ! ! !orit-! ! ! ! ! ! ! ! ! !
+CD ! c ! c !et !c[] ! c ! c ! c ! c ! c !c[] !c[] ! c[] !
+CD ! ! ! ! ! ! ! ! ! ! ! ! !
+CD ! ! ! s ! ! ! ! ! ! ! ! ! !
+CD !Def. se under ! ! !Def. se !se ! ! ! !Def. se nedenfor!
+CD ! ! ! ! !nedenfor!nedf.! ! ! ! ! ! !
+CD *-------------------------------------------------------------------------------*
+*/
+
+ /* Gruppe, punkt eller pinfo-uvalg */
+#define U_GRUPPE 1 /* GRUPPE-UTVALG */
+#define U_PUNKT 2 /* PUNKT-UTVALG */
+#define U_PINFO 3 /* PINFO-UTVALG */
+
+/* Struktur for statusopplysninger for LC_InitPP / LC_GetPP */
+typedef struct {
+ short type; /* LC_GETPP_KP, LC_GETPP_HOYDE, LC_GETPP_KVALITET, LC_GETPP_VANLIG */
+ char pinfo_navn[LC_MAX_SOSINAVN_LEN]; /* Sosi-navn det skal finnes verdi til */
+ long curr_punkt; /* Aktuellt punkt */
+ long slutt_punkt; /* Første punkt etter søkeområdet */
+ short neste_tegn; /* Neste tegn (Ved flere PINFO i punktet) */
+} LC_GETPP_STATUS;
+/* Bruk: LC_GETPP_STATUS pp_stat; */
+
+#define LC_GETPP_VANLIG 0
+#define LC_GETPP_KP 1
+#define LC_GETPP_HOYDE 2
+#define LC_GETPP_KVALITET 3
+
+ /* Konstant for sAktuellPrioritet */
+#define LC_OVERSE_PRIORITET -1
+
+/* Utvalgslinje */
+typedef struct sLC_UTVALG_ELEMENT {
+ char kommando;
+ char sosi[LC_MAX_SOSINAVN_LEN];
+ char metode;
+ //char type;
+ short type;
+ char ledd; /* Ledd-nr for flerleddet parameter */
+ char start; /* Startposisjon i tegnstreng (0=hele) */
+ char slutt; /* Sluttposisjon i tegnstreng (0=resten) */
+ char *min;
+ char *max;
+ struct sLC_UTVALG_ELEMENT *pNesteUE; /* Neste på dette nivå */
+ struct sLC_UTVALG_ELEMENT *pForsteUE; /* Første på nivået under */
+ struct sLC_UTVALG_ELEMENT *pSisteUE; /* Siste på nivået under */
+} LC_UTVALG_ELEMENT;
+
+typedef struct sLC_LAG {
+ char *pszLagNavn; /* Lagnavn */
+ short sLagAktiv; /* Lag aktiv for tegning */
+ struct sLC_LAG *pNesteLag; /* Neste lag */
+} LC_LAG;
+
+#define LC_UFORANDRET 0
+#define LC_ENDRET 1
+#define LC_NY 2
+#define LC_SLETTET 3
+
+typedef struct sLC_UTVALG {
+ char *pszNavn;
+ short sPrioritet;
+ short sOriginalPrioritet;
+ short sStatus;
+ short sTegnes; // Flagg for å styre om utvalgsregelen skal brukes ved tegning
+ LC_UTVALG_ELEMENT *pForsteUE; /* Første utvalgslinje på øverste nivå */
+ LC_UTVALG_ELEMENT *pSisteUE; /* Siste utvalgslinje på øverste nivå */
+
+ struct sLC_UTVALG *pForrigeU; /* Forrige utvalg */
+ struct sLC_UTVALG *pNesteU; /* Neste utvalg */
+ struct sLC_LAG *pLag; /* Lag */
+ char *pszRegel; /* Regel */
+} LC_UTVALG;
+
+/* Toppblokk for GRUPPE-, PUNKT- og PINFO-utvalg */
+typedef struct dLC_UTVALG_BLOKK {
+ short sHoydeBrukt;
+ short sTestAllePi; /* "!" er brukt, må sjekke alle punkt */
+ LC_UTVALG *pForsteU;
+ LC_UTVALG *pSisteU;
+ LC_UTVALG *pAktU;
+} LC_UTVALG_BLOKK;
+
+/* Administrasjonsblokk for utvalg */
+typedef struct dLC_UT_ADM {
+ short sMaxPrior; /* Største prioritet */
+ LC_UTVALG_BLOKK Gruppe;
+ LC_UTVALG_BLOKK Punkt;
+ LC_UTVALG_BLOKK Pinfo;
+ LC_UTVALG_BLOKK *pAktUB;
+ short sGruppeValgt;
+ LC_LAG *pForsteLag;
+ LC_LAG *pSisteLag;
+} LC_UT_ADM;
+
+/* Administrasjonsblokk for serienummersøk */
+typedef struct dLC_SNR_ADM {
+ LC_FILADM *pFil;
+ long lMinSnr;
+ long lMaxSnr;
+ long lAktSnr;
+} LC_SNR_ADM;
+
+/*
+CH Polygonbeskrivelse Strukturer for polygonbeskrivelse.
+CD
+CD Dette er et sett med strukturer som er kjedet sammen til en komplett
+CD beskrielse av en flate. Eksempel på bruk er gitt under $LENKE<LC_POL_GetRef>.
+CD
+CD
+CD !-----------------!
+CD ! LC_POLYGON !
+CD ! ! !-------------------------!
+CD ! !- Omkrets --! ! ! !-----------------! !---------------!
+CD ! !LC_POL_OMKR ! ! ! !-!LC_POL_ELEMENT ! !-!LC_POL_ELEMENT !
+CD ! ! ! ! ! ! ! - Bgr ! ! ! - Bgr !
+CD ! !- Siste !--!-------! ! ! - Snr ! ! ! - Snr !
+CD ! !- Første !--!---------! ! - Retning ! ! ! - Retning !
+CD ! !------------! ! ! - Forrige (NULL)! ! ! - Forrige !
+CD ! !- Hull ------! ! ! - Neste !-! ! - Neste (NULL)!
+CD ! !LC_OY_ADM ! ! !-----------------! !---------------!
+CD ! ! ! !
+CD ! !- Første øy !-!-!
+CD !-!-!- Siste øy ! ! !
+CD ! ! !-------------! ! !
+CD ! !-----------------! !
+CD ! !-----------------!
+CD ! ! !------------------------!
+CD ! ! !------------! ! !-----------------! !---------------!
+CD ! !--------------! !-!LC_POL_OMKR ! ! !-!LC_POL_ELEMENT !!!LC_POL_ELEMENT !
+CD ! !LC_OY_ELEMENT ! ! ! ! ! ! ! - Bgr !!! - Bgr !
+CD ! !- Omkrets !--! !- Siste !-! ! ! - Snr !!! - Snr !
+CD ! !- Neste !-! !- Første !---! ! - Retning !!! - Retning !
+CD ! !--------------! ! !------------! ! - Forrige (NULL)!!! - Forrige !
+CD ! ! ! - Neste !!! - Neste (NULL)!
+CD ! ! !-----------------! !---------------!
+CD ! !
+CD ! !---------------! !--------------------------!
+CD ! ! !------------! ! !-----------------! !---------------!
+CD ! !--------------! !-!LC_POL_OMKR ! ! !-!LC_POL_ELEMENT ! !-!LC_POL_ELEMENT !
+CD !--!LC_OY_ELEMENT ! ! ! ! ! ! ! - Bgr ! ! ! - Bgr !
+CD !- Omkrets !--! !- Siste !-! ! ! - Snr ! ! ! - Snr !
+CD !- Neste (NULL)! !- Første !---! ! - Retning ! ! ! - Retning !
+CD !--------------! !------------! ! - Forrige (NULL)! ! ! - Forrige !
+CD ! - Neste !-! ! - Neste (NULL)!
+CD !-----------------! !---------------!
+*/
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Polygon element (ett for hver gruppe i polygonbeskrivelsen) !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_POL_ELEMENT {
+ LC_BGR Bgr; /* Gruppenummer */
+ short sRetning; /* LC_MED_DIG eller LC_MOT_DIG */
+ long lSnr; /* Serienummer */
+ LC_KOORD_2D Pkt; /* (ø,n) Representasjonspunkt (Brukes ikke av FYBA. Til disp.) */
+ struct dLC_POL_ELEMENT *pNestePE; /* Peker til neste element i polygonet */
+ struct dLC_POL_ELEMENT *pForrigePE; /* Peker til forrige element i polygonet */
+} LC_POL_ELEMENT;
+
+/*
+ *!----------------------------------------------------------------------!
+ *! Adm. blokk for polygon (en for hver lukket "del", omkrets eller øy) !
+ *!----------------------------------------------------------------------!
+ */
+typedef struct dLC_POL_OMKR {
+ LC_POL_ELEMENT *pForstePE;
+ LC_POL_ELEMENT *pSistePE;
+} LC_POL_OMKR;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Øy (i polygon) element (en for hver øy) !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_OY_ELEMENT{
+ LC_POL_OMKR PO; /* Administrasjonsblokk til kjede som beskriv øyavgrensinga */
+ struct dLC_OY_ELEMENT *pNesteOE; /* Peker til neste øyelement i polygonet */
+ struct dLC_OY_ELEMENT *pForrigeOE; /* Peker til forrige øyelement i polygonet */
+} LC_OY_ELEMENT;
+
+/*
+ *!------------------------------------------------------------------------!
+ *! Adm. blokk for øy (i polygon) element (en for alle øyene i en flate) !
+ *!------------------------------------------------------------------------!
+ */
+typedef struct dLC_OY_ADM{
+ LC_OY_ELEMENT *pForsteOE; /* Første øy (hull) */
+ LC_OY_ELEMENT *pSisteOE; /* Siste øy (hull) */
+} LC_OY_ADM;
+
+/*
+ *!--------------------------------------------------------------!
+ *! Adm blokk for Polygon (En for hver flate, inkl øyer) !
+ *!--------------------------------------------------------------!
+ */
+
+typedef struct dLC_POLYGON {
+ LC_POL_OMKR HovedPO; /* Adm blokk for kjede som beskriver ytre avgrensing */
+ LC_OY_ADM OyOA; /* Kjede som beskriver hull i flata */
+} LC_POLYGON;
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyho.c */
+/* ======================================================= */
+SK_EntPnt_FYBA short HO_New(const char *pszFil,short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d,
+ double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short HO_TestSOSI(const char *pszFil,UT_INT64 *sluttpos);
+SK_EntPnt_FYBA char *HO_GetVal(const char *pszFil,char *sosi_navn,short *sett_nr);
+SK_EntPnt_FYBA short HO_GetKvalitet(const char *pszFil,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short HO_GetTrans(const char *pszFil,short *koosys,double *origo_a,
+ double *origo_n,double *enhet,double *enhet_h,double *enhet_d);
+SK_EntPnt_FYBA short HO_GetTransEx(const char *pszFil,unsigned short *pusMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short HO_GetOmr(const char *pszFil,double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+SK_EntPnt_FYBA short HO_GetTegnsett(const char *pszFil,short *psTegnsett);
+SK_EntPnt_FYBA short HO_SjekkTegnsett(const char *pszFil,short *psTegnsett);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylh.c */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_GetTrans(short *koosys,double *origo_a,double *origo_n,double *enhet,
+ double *enhet_h,double *enhet_d);
+SK_EntPnt_FYBA short LC_GetTransEx(unsigned short *pusMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short LC_PutTrans(short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d);
+SK_EntPnt_FYBA short LC_PutTransEx(unsigned short usMaske, LC_TRANSPAR *pTrans);
+SK_EntPnt_FYBA short LC_GetTegnsett(short *psTegnsett);
+SK_EntPnt_FYBA short LC_GetOmr(double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+SK_EntPnt_FYBA short LC_PutOmr(double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA void LC_NyttHode(void);
+SK_EntPnt_FYBA short LC_TestHode(void);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylo.c */
+/* ======================================================= */
+SK_EntPnt_FYBA void LC_Init(void);
+SK_EntPnt_FYBA void LC_Close(void);
+SK_EntPnt_FYBA LC_BASEADM* LC_OpenBase(short sBaseType);
+SK_EntPnt_FYBA void LC_CloseBase(LC_BASEADM *pBase,short s_stat);
+SK_EntPnt_FYBA short LC_OpenSos(const char *fil,short sModus,short sNyIdx,short sVisStatus,
+ LC_FILADM **ppFil, short *o_stat);
+SK_EntPnt_FYBA void LC_CloseSos(LC_FILADM *pFil,short s_stat);
+SK_EntPnt_FYBA void LC_FcloseSos(LC_FILADM *pFil);
+SK_EntPnt_FYBA void LC_SetDefLpfi(short ant_tegn);
+SK_EntPnt_FYBA short LC_InqDefLpfi(void);
+SK_EntPnt_FYBA short LC_InqLag(unsigned short *usLag);
+SK_EntPnt_FYBA unsigned short LC_InqFilLag(LC_FILADM *pFil);
+SK_EntPnt_FYBA void LC_SetFilLag(LC_FILADM *pFil,unsigned short usLag);
+SK_EntPnt_FYBA short LC_Backup(LC_FILADM *pFil,const char *pszBackupPath);
+SK_EntPnt_FYBA void LC_MaxSkriv(long);
+SK_EntPnt_FYBA long LC_InqMaxSkriv(void);
+SK_EntPnt_FYBA void LC_SetNgisModus(short modus);
+SK_EntPnt_FYBA short LC_GetNgisModus(void);
+SK_EntPnt_FYBA void LC_SetUtvidModus(short modus);
+SK_EntPnt_FYBA short LC_GetUtvidModus(void);
+SK_EntPnt_FYBA LC_BASEADM* LC_InqCurBase(void);
+SK_EntPnt_FYBA void LC_SelectBase(LC_BASEADM *pBase);
+SK_EntPnt_FYBA short LC_GetBaOm(unsigned short usLag,double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_FYBA short LC_GetFiOm(LC_FILADM *pFil,double *nva,double *nvn,double *oha,double *ohn);
+SK_EntPnt_FYBA LC_FILADM * LC_GetFiNr(const char *fil_navn);
+SK_EntPnt_FYBA char *LC_GetFiNa(LC_FILADM *pFil);
+SK_EntPnt_FYBA short LC_ErFilBase(const char *fil);
+SK_EntPnt_FYBA short LC_ErKoordsysLik(void);
+SK_EntPnt_FYBA short LC_ErVertdatumLik(void);
+SK_EntPnt_FYBA char* LC_GetNgisLag(LC_FILADM *pFil);
+SK_EntPnt_FYBA void LC_SetEndringsstatus(short sStatus);
+SK_EntPnt_FYBA void LC_SetFilType(LC_FILADM *pFil, short sType);
+SK_EntPnt_FYBA short LC_GetFilType(LC_FILADM *pFil);
+SK_EntPnt_FYBA short LC_SetIdxPath(const char *pszIdxPath);
+SK_EntPnt_FYBA const char* LC_GetIdxPath(void);
+/* Konstanter for intgt.sEndra (aktuell gruppe er endra) */
+#define END_UENDRA 0 /* Ikke endra */
+#define END_KOPI 1 /* Endra ved totalkopi fra annen gruppe */
+#define END_ENDRA 2 /* Endra ved normal Put fra program */
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylx.c */
+/* ======================================================= */
+#define GRF_YTRE 0x01 /* Ytre avgrensing */
+#define GRF_INDRE 0x02 /* Indre avgrensing, øyer */
+#define LC_MED_DIG 0x01 /* Brukes MED dig retning */
+#define LC_MOT_DIG 0x02 /* Brukes MOT dig retning */
+#define GRF_START_OY 0x04 /* Første gruppe i øy */
+#define GRF_SLUTT_OY 0x08 /* Siste gruppe i øy */
+
+SK_EntPnt_FYBA long LC_InqAntRef(void);
+SK_EntPnt_FYBA void LC_InitGetRefFlate(LC_GRF_STATUS *pGrfStat);
+SK_EntPnt_FYBA long LC_GetRefFlate(LC_GRF_STATUS *RefStat,unsigned short sHent,long *ref_array,
+ unsigned char *ref_status,long max_ref);
+SK_EntPnt_FYBA short LC_PutRef(long *ref_array,long ant_ref);
+SK_EntPnt_FYBA long LC_GetRef(long *ref_array,long max_ref,short *gilin,short *refpos);
+
+SK_EntPnt_FYBA short LC_GetBuePar(short buff_retning, double *as, double *ns, double *radius,
+ double *fi, double *dfi, short *sfeil);
+SK_EntPnt_FYBA short LC_GetBue(short retning,double *a1,double *n1,double *a2,double *n2,
+ double *radius,short *storbue);
+SK_EntPnt_FYBA short LC_GetBuep(short retning,double *a1,double *n1,double *a2,double *n2,
+ double *a3,double *n3);
+SK_EntPnt_FYBA short LC_GetSirkel(double *as,double *ns,double *radius);
+SK_EntPnt_FYBA short LC_GetSirkelp(double *a1,double *n1,double *a2,double *n2,
+ double *a3,double *n3);
+
+SK_EntPnt_FYBA void LC_GetCurEnhet(LC_FILADM * pFil,short *nivaa, double *enhet,
+ double *enhet_h, double *enhet_d);
+SK_EntPnt_FYBA short LC_UpdateGiEnhet(LC_FILADM *pFil,double enhet,double enhet_h,double enhet_d);
+
+SK_EntPnt_FYBA short LC_GetKvalitet(short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+ short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short LC_GetCurKvalitet(LC_FILADM *pFil,short *nivaa,long pnr,
+ short *psMetode,long *plNoyaktighet,short *psSynbarhet,
+ short *psHoydeMetode,long *plHoydeNoyaktighet);
+SK_EntPnt_FYBA short LC_UpdateGiKvalitet(LC_FILADM *pFil,short sMetode,long lNoyaktighet,
+ short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet);
+SK_EntPnt_FYBA short LC_UpdatePiKvalitet(LC_FILADM *pFil,long pnr,short sMetode,long lNoyaktighet,
+ short sSynbarhet,short sHoydeMetode,long lHoydeNoyaktighet);
+
+SK_EntPnt_FYBA char * LC_GetGP(const char *,short *,short);
+SK_EntPnt_FYBA short LC_PutGP(const char *sosi_navn,const char *verdi,short *linje_nr);
+SK_EntPnt_FYBA short LC_AppGP(const char *sosi_navn,const char *verdi,short *linje_nr);
+SK_EntPnt_FYBA short LC_UpdateGP(short linje_nr,const char *sosi_navn,const char *verdi);
+SK_EntPnt_FYBA void LC_InitPP(char *sosi_navn,long forste_punkt,long siste_punkt,
+ LC_GETPP_STATUS *pp_status);
+SK_EntPnt_FYBA char * LC_GetPP(long *punkt,LC_GETPP_STATUS *pp_stat);
+SK_EntPnt_FYBA char * LC_GetPiVerdi(const char *pszSosiNavn,long sPnr,short *sSettNr);
+SK_EntPnt_FYBA short LC_TestPi(long punkt_nr,short sTestHoyde);
+SK_EntPnt_FYBA short LC_FinnKp(long *forste_punkt,long siste_punkt,short *kp);
+SK_EntPnt_FYBA long LC_GetSn(void);
+SK_EntPnt_FYBA void LC_PutSn(long snr);
+SK_EntPnt_FYBA char * LC_GetGi(short gilin);
+SK_EntPnt_FYBA void LC_PutGi(short gilin,const char *ginfo);
+SK_EntPnt_FYBA void LC_GetTK(long pkt,double *aust,double *nord);
+SK_EntPnt_FYBA void LC_GetArrayTK(short retning,long max_antall,long fra_punkt,
+ double *aust,double *nord,long *antall);
+SK_EntPnt_FYBA void LC_GetArrayTH(short retning,long max_antall,long fra_punkt,
+ double *hoyde,long *antall);
+SK_EntPnt_FYBA void LC_PutTK(long punkt_nr,double aust,double nord);
+SK_EntPnt_FYBA double LC_GetTH(long pkt);
+SK_EntPnt_FYBA void LC_PutTH(long pkt,double hoyde);
+SK_EntPnt_FYBA double LC_GetHoyde(long punkt_nr);
+SK_EntPnt_FYBA void LC_PutTD(long punkt_nr, double dybde);
+SK_EntPnt_FYBA double LC_GetTD(long punkt_nr);
+SK_EntPnt_FYBA double LC_GetDybde(long punkt_nr);
+SK_EntPnt_FYBA char * LC_GetPi(long pkt);
+SK_EntPnt_FYBA short LC_PutPi(long pkt,const char *pi);
+SK_EntPnt_FYBA short LC_GetKp(long pkt);
+SK_EntPnt_FYBA void LC_PutKp(long pkt,short kp);
+SK_EntPnt_FYBA double LC_BerAreal(void);
+SK_EntPnt_FYBA double LC_BerLengde(void);
+SK_EntPnt_FYBA bool LC_BerLengde3D(double *skraa_lengde);
+SK_EntPnt_FYBA double LC_BerAvgrensLengde(void);
+SK_EntPnt_FYBA double LC_BerIndreAvgrensLengde(void);
+SK_EntPnt_FYBA double LC_BerYtreAvgrensLengde(void);
+SK_EntPnt_FYBA void LC_DumpTab(void);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylb.c */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_GetGrFi(LC_FILADM **ppFil);
+SK_EntPnt_FYBA void LC_InitNextFil(LC_FILADM **ppFil);
+SK_EntPnt_FYBA short LC_NextFil(LC_FILADM **ppFil,unsigned short usLag);
+SK_EntPnt_FYBA void LC_InitNextBgr(LC_BGR * pBgr);
+SK_EntPnt_FYBA short LC_NextBgr(LC_BGR * pBgr,unsigned short usLag);
+SK_EntPnt_FYBA short LC_InqAntFiler(unsigned short usLag);
+SK_EntPnt_FYBA short LC_GetGrNr(LC_BGR * pBgr);
+SK_EntPnt_FYBA const char *LC_GetObjtypeBgr(LC_BGR * pBgr);
+SK_EntPnt_FYBA short LC_GetGrPara(short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short LC_GetGrParaBgr(LC_BGR * pBgr,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short LC_RsGr(short *rstat,LC_FILADM *pFil,short *ngi,long *nko,
+ unsigned short *info,long *gml_snr);
+SK_EntPnt_FYBA short LC_RsHode(LC_FILADM *pFil,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA void LC_WsGr(LC_FILADM *pFil);
+SK_EntPnt_FYBA void LC_WsGrPart(LC_FILADM *pFil,long fra_punkt,long antall);
+SK_EntPnt_FYBA short LC_EndreHode(LC_FILADM *pFil);
+SK_EntPnt_FYBA short LC_RxGr(LC_BGR * pBgr,short les_sosi,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short LC_WxGr(short k_stat);
+SK_EntPnt_FYBA void LC_RoundKoord(void);
+SK_EntPnt_FYBA long LC_FiLastGr(LC_FILADM *pFil);
+SK_EntPnt_FYBA short LC_NyGr (LC_FILADM *pFil,char *sosi,LC_BGR * pBgr,long *snr);
+SK_EntPnt_FYBA short LC_CopyGr (LC_BGR * pBgr,short ngis,short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA short LC_CopyCoord(LC_BGR * pBgr,short retning,long til_linje,short *ngi,
+ long *nko,unsigned short *info);
+SK_EntPnt_FYBA short LC_DelGr(void);
+SK_EntPnt_FYBA void LC_SnuGr(void);
+SK_EntPnt_FYBA short LC_SplittGr (long p1,long p2,LC_BGR * pBgr2);
+SK_EntPnt_FYBA short LC_SammenfoyGr(LC_BGR * pFraBgr,short retning,short plassering,short metode,
+ short *ngi,long *nko,unsigned short *info);
+SK_EntPnt_FYBA void LC_ErstattReferanse (LC_FILADM *pFil,long lGmlSnr,long lNyttSnr, bool bSammeRetning);
+
+
+ /* Konstanter for SammenfoyGr() */
+#define LC_SG_FORRAN 1 /* Heng den andre gruppen inn forran første koordinat */
+#define LC_SG_BAK 2 /* Heng den andre gruppen inn etter siste koordinat */
+#define LC_SG_BEHOLD 3 /* Begge sammenføyings-punktene beholdes */
+#define LC_SG_FJERN 4 /* Bare det ene av sammenføyings-punktene beholdes */
+
+
+SK_EntPnt_FYBA short LC_InsGiL (short linje, short antall);
+SK_EntPnt_FYBA short LC_AppGiL (void);
+SK_EntPnt_FYBA short LC_DelGiL (short linje, short antall);
+SK_EntPnt_FYBA short LC_DelGiNavn(char *pszEgenskapNavn);
+SK_EntPnt_FYBA long LC_InsKoL (long linje, long antall);
+SK_EntPnt_FYBA long LC_AppKoL (void);
+SK_EntPnt_FYBA long LC_DelKoL (long linje, long antall);
+SK_EntPnt_FYBA void LC_Save (void);
+SK_EntPnt_FYBA void LC_OppdaterEndret(short endring);
+ #define O_GINFO 0 /* Oppdater tabeller i forhold til GINFO */
+ #define O_ENDRET 1 /* Merk for endret og oppdat. tab. */
+ #define O_SLETTET 2 /* Merk for slettet og oppdat. tab. */
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyli.c */
+/* ======================================================= */
+/* Brukttabellen */
+SK_EntPnt_FYBA void LC_SetBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void LC_ClrBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA short LC_GetBt(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void LC_EraseBt(short fra_kol,short til_kol);
+SK_EntPnt_FYBA void LC_CopyBt(short fra_kol,short til_kol,short operasjon);
+SK_EntPnt_FYBA void LC_SetModusMerk(unsigned short usModus);
+SK_EntPnt_FYBA long LC_MerkGr(short sKolonne,short sBryter);
+SK_EntPnt_FYBA void LC_ClrPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void LC_SetPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA short LC_InqPrioritet(LC_BGR * pGr,short kolonne);
+SK_EntPnt_FYBA void LC_ErasePrioritet(LC_BGR * pGr);
+SK_EntPnt_FYBA void LC_EraseAllPrioritet(LC_FILADM *pFil);
+SK_EntPnt_FYBA void LC_DumpBt(const char *pszMelding);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyld.c */
+/* ======================================================= */
+SK_EntPnt_FYBA void LC_DelIdx(char *szSosFil);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyta.c */
+/* ======================================================= */
+/* Tabellsystemet */
+SK_EntPnt_FYBA short LC_InitTabel(long n_rec,short rec_len,void *buffer);
+SK_EntPnt_FYBA short LC_PutTabel(long linje,void *buffer);
+SK_EntPnt_FYBA short LC_GetTabel(long linje,void *buffer);
+SK_EntPnt_FYBA void LC_CloseTabel(void);
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyln.c */
+/* ======================================================= */
+SK_EntPnt_FYBA char *LC_FormatterKvalitet(short sMetode,long lNoyaktighet,short sSynbarhet,
+ short sHoydeMetode,long lHoydeNoyaktighet);
+SK_EntPnt_FYBA short LC_FinnNivo(const char *pszNavn);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyls.c */
+/* ======================================================= */
+SK_EntPnt_FYBA void LC_SBSn(LC_SNR_ADM *pSnrAdm,LC_FILADM *pFil,long lMinSnr,long lMaxSnr);
+SK_EntPnt_FYBA short LC_MoveSn(LC_SNR_ADM *pSnrAdm,long lSnr,LC_BGR * pBgr);
+SK_EntPnt_FYBA short LC_FiSn(LC_FILADM *pFil,long lSnr,LC_BGR * pBgr);
+SK_EntPnt_FYBA void LC_FiArraySn(LC_FILADM *pFil,short antall,long *snr,long *bgr);
+SK_EntPnt_FYBA long LC_FASn(LC_SNR_ADM *pSnrAdm);
+SK_EntPnt_FYBA short LC_FFSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FNSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FPSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FLSn(LC_SNR_ADM *pSnrAdm,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FFSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FNSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FPSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FLSnBt(LC_SNR_ADM *pSnrAdm,short kolonne,LC_BGR *pBgr);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylr.c */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_GetGrWin(LC_BGR *pBgr,double *nva,double *nvn,double *oha,double *ohn);
+/* Flate-søk */
+SK_EntPnt_FYBA void LC_SBFlate(LC_GEO_STATUS *pGeoStat,unsigned short usLag,
+ double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short LC_FFFlate(LC_GEO_STATUS *pGeoStat,LC_BGR * pBgr);
+SK_EntPnt_FYBA short LC_FNFlate(LC_GEO_STATUS *pGeoStat,LC_BGR * pBgr);
+/* Geografisk søk primær gruppe */
+SK_EntPnt_FYBA void LC_SBGeo(LC_GEO_STATUS *pGeoStat,unsigned short usLag,
+ double nv_a,double nv_n,double oh_a,double oh_n);
+SK_EntPnt_FYBA short LC_FFGeo(LC_GEO_STATUS *pGeoStat,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FNGeo(LC_GEO_STATUS *pGeoStat,LC_BGR *pBgr);
+SK_EntPnt_FYBA long LC_FAGeo(LC_GEO_STATUS *pGeoStat);
+SK_EntPnt_FYBA short LC_FFGeoFil(LC_GEO_STATUS *pGeoStat,LC_FILADM *pFil,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_FNGeoFil(LC_GEO_STATUS *pGeoStat,LC_FILADM *pFil,LC_BGR *pBgr);
+SK_EntPnt_FYBA void LC_AvsluttSok(LC_GEO_STATUS *pGeoStat);
+
+/* Vindustest mm */
+SK_EntPnt_FYBA short LC_WTst(double nva,double nvn,double oha,double ohn);
+SK_EntPnt_FYBA short LC_PTst(double a,double n);
+SK_EntPnt_FYBA short LC_PTstOmkrets(double a,double n);
+
+/* Debugformål */
+SK_EntPnt_FYBA void LC_DumpGeoRtre(LC_FILADM *pFil);
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylu.c */
+/* ======================================================= */
+SK_EntPnt_FYBA LC_UT_ADM * LC_OpenQuery(void);
+SK_EntPnt_FYBA void LC_CloseQuery(LC_UT_ADM *pUtAdm);
+//SK_EntPnt_FYBA short LC_PutQueryLine(LC_UT_ADM *pUtAdm,char *qulin);
+SK_EntPnt_FYBA short LC_PutQueryLine(LC_UT_ADM *pUtAdm,const char *qulin,short sType);
+SK_EntPnt_FYBA void LC_PutQueryRegel(LC_UTVALG *pU,const char *navn);
+SK_EntPnt_FYBA short LC_LesUtvalg(LC_UT_ADM *pUtAdm,const char *pszKomFil);
+SK_EntPnt_FYBA char *LC_GetUtRegelNavn(LC_UT_ADM *pUtAdm,short *ist);
+SK_EntPnt_FYBA char *LC_GruppeUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *sstat,char **regelnavn);
+SK_EntPnt_FYBA short LU_GiTestUtvalg(LC_UT_ADM *pUtAdm,LC_UTVALG * pU);
+SK_EntPnt_FYBA void LC_PunktUtvalg(LC_UT_ADM *pUtAdm,short sPrior,short *psStat,long lPnr,char **ppszRegel);
+SK_EntPnt_FYBA LC_UTVALG *LC_FinnPinfoUtvalg(LC_UT_ADM *pUtAdm,const char *pszNavn);
+SK_EntPnt_FYBA short LC_PiTestUtvalg(LC_UT_ADM *pUtAdm,LC_UTVALG * pU,long lPnr);
+SK_EntPnt_FYBA short LC_GiQuery(LC_UT_ADM *pUtAdm);
+SK_EntPnt_FYBA long LC_FAGiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag);
+SK_EntPnt_FYBA long LC_FAPiQuery(LC_UT_ADM *pUtAdm,unsigned short usLag);
+SK_EntPnt_FYBA long LC_FAGiKombinertFlateQuery(LC_UT_ADM *pUtAdmFlate,LC_UT_ADM *pUtAdmOmkrets,
+ unsigned short usLag,short sMetode);
+SK_EntPnt_FYBA short LC_QueryGP(char *qulin,unsigned short iniv,unsigned short *univ,short *ulin,char **para);
+SK_EntPnt_FYBA short LC_InqMaxPrioritet(LC_UT_ADM *pUA);
+SK_EntPnt_FYBA short LC_TestPrioritetBrukt(LC_UT_ADM *pUtAdm,short sPrioritet);
+SK_EntPnt_FYBA void LC_UtvalgPrioritet(LC_UT_ADM *pUtAdm);
+SK_EntPnt_FYBA void LC_LoggPrioritetUtvalg(LC_UT_ADM *pUtAdm);
+SK_EntPnt_FYBA void LU_FrigiUE(LC_UTVALG_ELEMENT *pUE);
+SK_EntPnt_FYBA short LU_AppUE (LC_UTVALG *pU,short sNiv,const char *pszTx);
+SK_EntPnt_FYBA void LC_PutLag(LC_UT_ADM *pUtAdm,LC_UTVALG *pU,const char *navn);
+SK_EntPnt_FYBA bool LC_ErLik_Avrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet);
+SK_EntPnt_FYBA bool LC_ErLik_IkkeAvrundet(double dA1,double dN1,double dA2, double dN2, double dEnhet);
+SK_EntPnt_FYBA bool LC_ErReferert(void);
+SK_EntPnt_FYBA long LC_ErReferertFraAntall(void);
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylp.c */
+/* ======================================================= */
+SK_EntPnt_FYBA void LC_POL_InitPolygon(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void LC_POL_FrigiPolygon(LC_POLYGON *pPolygon);
+
+SK_EntPnt_FYBA void LC_POL_InitOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA LC_POL_ELEMENT * LC_POL_LeggTilGruppeOmkrets(LC_POL_OMKR *pPO,LC_BGR *pBgr,short sRetning,long lSnr);
+SK_EntPnt_FYBA void LC_POL_FjernSisteGruppeOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA void LC_POL_FjernGruppeOmkrets(LC_POL_OMKR *pPO, LC_POL_ELEMENT *pPE);
+SK_EntPnt_FYBA void LC_POL_FrigiOmkrets(LC_POL_OMKR *pPO);
+
+SK_EntPnt_FYBA void LC_POL_InitOy(LC_OY_ADM *pOA);
+SK_EntPnt_FYBA void LC_POL_FrigiAlleOyer(LC_OY_ADM *pOA);
+SK_EntPnt_FYBA void LC_POL_FjernOy(LC_OY_ADM *pOA,LC_OY_ELEMENT *pOE);
+SK_EntPnt_FYBA void LC_POL_LeggTilOy(LC_OY_ADM *pOA,LC_POL_OMKR *pPO);
+
+SK_EntPnt_FYBA short LC_POL_TestBrukt(LC_POLYGON *pPolygon,LC_BGR *pBgr);
+SK_EntPnt_FYBA short LC_POL_PutRef(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void LC_POL_GetRef(LC_POLYGON *pPolygon);
+SK_EntPnt_FYBA void LC_POL_GetRefOmkrets(LC_POL_OMKR *pPO);
+SK_EntPnt_FYBA short LC_POL_PTst(LC_POLYGON *pPolygon,double a,double n);
+SK_EntPnt_FYBA short LC_POL_PTstOmkrets(LC_POL_OMKR *pPO,double a,double n);
+SK_EntPnt_FYBA short LC_POL_OmkretsSkjaering(LC_POL_OMKR *pPO,double a,double n);
+SK_EntPnt_FYBA void LC_POL_Box(LC_POL_OMKR *pPO,double *nva,double *nvn, double *oha,double*ohn);
+SK_EntPnt_FYBA short LC_ErLinjeRefLin(char *pszSosiLin, short sRefLin);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyln.c */
+/* ======================================================= */
+SK_EntPnt_FYBA const char *LC_GetElementNavn(LC_FILADM *pFil,short sNavnNr,bool *bBrukt);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyba.c */
+/* ======================================================= */
+SK_EntPnt_FYBA char *LC_InqVer(void);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyle.c */
+/* ======================================================= */
+SK_EntPnt_FYBA short LC_StrError(short feil_nr,char **feilmelding);
+
+SK_EntPnt_FYBA void LC_SetErrorHandler(void (*f) (short,const char*,const char*));
+SK_EntPnt_FYBA void LC_SetStartMessageHandler(void (*f)(const char*));
+SK_EntPnt_FYBA void LC_SetShowMessageHandler(void (*f)(double));
+SK_EntPnt_FYBA void LC_SetEndMessageHandler(void (*f)(void));
+SK_EntPnt_FYBA void LC_SetCancelHandler(short (*f)(void));
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Når FYBA brukes som LIB må følgende funksjoner finnes definert
+//
+//////////////////////////////////////////////////////////////////////////
+void LC_Error (short ifeilnr, const char logtx[], const char vartx[]);
+void LC_StartMessage(const char *cfil);
+void LC_ShowMessage(double prosent);
+void LC_EndMessage(void);
+short LC_Cancel(void);
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Når FYBA brukes som DLL må følgende funksjoner finnes definert.
+// Eksempel finnes i filen Fyba_Callback.cpp
+// Funksjonene aktiveres med LC_SetXxxxxHandler rutinene.
+// Hvis disse ikke blir aktivert brukes enkle rutiner som ligger i DLL-en.
+//
+//////////////////////////////////////////////////////////////////////////
+void LC_ErrorHandler (short ifeilnr, const char* logtx, const char* vartx);
+void LC_StartMessageHandler(const char *cfil);
+void LC_ShowMessageHandler(double prosent);
+void LC_EndMessageHandler(void);
+short LC_CancelHandler(void);
+
+
diff --git a/src/FYBA/fyba_strings.h b/src/FYBA/fyba_strings.h
new file mode 100644
index 0000000..e0c5253
--- /dev/null
+++ b/src/FYBA/fyba_strings.h
@@ -0,0 +1,223 @@
+# ifdef FYBA_STRINGS_EN
+/* =========== ENGLISH FYBA_STRINGS ================== */
+
+#define FYBA_STRING_BASE_UNKNOWN_TYPE "Unknown base type, cannot open base."
+#define FYBA_STRING_BASE_TOO_MANY_GROUPS "Too many groups in base."
+#define FYBA_STRING_FILE_NOT_FOUND "No .sos file found by the name:"
+#define FYBA_STRING_BASE_FYBA_NOT_INITD "Cannot open base - FYBA has not been initialized."
+#define FYBA_STRING_BASE_NOT_OPEN "Cannot open SOSI-file. Base has not been opened."
+#define FYBA_STRING_FILE_PERM_DENIED "Permission denied opening SOSI-file or creating index folder."
+#define FYBA_STRING_FILE_OPEN_FAILED "Error opening file:"
+#define FYBA_STRING_FILE_OMRAADE_MISSING "..OMRÅDE missing in file header:"
+#define FYBA_STRING_FILE_MIN_NOE_MISSING "...MIN-NØ missing in file header:"
+#define FYBA_STRING_FILE_MAX_NOE_MISSING "...MAX-NØ missing in file header:"
+#define FYBA_STRING_BASE_INDEX_ABORTED "Index construction aborted."
+#define FYBA_STRING_BASE_OPEN_FAILED "Error opening:"
+#define FYBA_STRING_FILE_NEW_HEADER "New header in:"
+#define FYBA_STRING_FILE_NOT_SOSI "Not a SOSI file:"
+#define FYBA_STRING_FILE_OMRAADE_INVALID "Invalid OMRÅDE in file header! (No dimensions.)"
+#define FYBA_STRING_SAVE_INVALID_FILEPTR "Invalid file pointer while saving."
+#define FYBA_STRING_OPEN_BASE_IS_KLADDE "Cannot open SOSI file. Base was opened as KLADDE. This can only be combined with sequential reading/writing."
+#define FYBA_STRING_FILE_READ_ERROR_HODE "Reading error in header line."
+#define FYBA_STRING_FILE_TRANSPAR_MISSING "..TRANSPAR missing in file header."
+#define FYBA_STRING_FILE_KOORDSYS_MISSING "...KOORDSYS missing in file header."
+#define FYBA_STRING_FILE_ORIGO_MISSING "...ORIGO-NØ missing in file header. (Check the encoding!)"
+#define FYBA_STRING_FILE_ENHET_MISSING "...ENHET missing in file header."
+#define FYBA_STRING_NAME_TABLE_FULL "Name table is full."
+#define FYBA_STRING_INVALID_GROUP_NAME "Invalid group name:"
+#define FYBA_STRING_FILE_NO_CURRENT_GROUP "No current group - nothing read."
+#define FYBA_STRING_OPEN_INVALID_EXTERN "Invalid external file - nothing read."
+#define FYBA_STRING_SAVE_INVALID_EXTERN "Invalid external file - nothing written."
+#define FYBA_STRING_SAVE_NO_WRITE_ACCESS "No write access, nothing written to the file:"
+#define FYBA_STRING_GROUP_DELETED "Group is deleted."
+#define FYBA_STRING_FILE_INVALID_GROUP_NR "Invalid group number, nothing read."
+#define FYBA_STRING_NEW_INVALID_FILE "Invalid file, cannot create new group."
+#define FYBA_STRING_NEW_NO_WRITE_ACCESS "No write access, cannot create new group."
+#define FYBA_STRING_NEW_TOO_MANY_GROUPS "Too many groups in base, cannot create new group."
+#define FYBA_STRING_NEW_INVALID_LINE_GI "Invalid line number for new GINFO"
+#define FYBA_STRING_NEW_INVALID_LINE_COO "Invalid line number for new coordinates."
+#define FYBA_STRING_SLUTT_MISSING ".SLUTT missing in SOSI file."
+#define FYBA_STRING_READ_ERROR "Error reading SOSI file."
+#define FYBA_STRING_GROUP_REFERRED_TO "Group is referenced by another group, cannot be deleted."
+#define FYBA_STRING_INVALID_GI_LINE_1 "Invalid GINFO line nr. 1."
+#define FYBA_STRING_CANT_REMOVE_HEADER "You cannot remove the file header."
+#define FYBA_STRING_NO_CURRENT_GROUP "No current group, nothing changed."
+#define FYBA_STRING_DEL_UNKNOWN_FLAG "Group has an unknown NGIS change flag, cannot be removed."
+#define FYBA_STRING_DEL_NO_WRITE_ACCESS "No write access, group cannot be removed."
+#define FYBA_STRING_ERR_FILESIZE_CHANGE "Error changing file size."
+#define FYBA_STRING_DISK_SOON_FULL "Your disk is soon full. Make some room at : "
+#define FYBA_STRING_NOT_A_HEADER "Current group is not a file header - nothing changed."
+#define FYBA_STRING_DEL_NOT_SEQUENTIAL "You cannot delete groups in sequential mode."
+#define FYBA_STRING_NO_CHANGE_HEADERS "Cannot change KOORDSYS, ENHET, ORIGO or NGIS-LAG in a file with data."
+#define FYBA_STRING_CANT_REWRITE_HEADER "No room to write back header."
+#define FYBA_STRING_SAVE_NOT_A_HEADER "Group is not a header, cannot save it as such."
+#define FYBA_STRING_CANT_COPY_COORD "Cannot copy coordinates from current group to another."
+#define FYBA_STRING_CANT_COPY_COORD_ROOM "Cannot copy coordinates: Not enough room in ring buffer."
+#define FYBA_STRING_ENHET_NOT_SET "ENHET is set to 0.0 in the file header, or header is missing:"
+#define FYBA_STRING_CANT_READ_FILE_SIZE "Error while retrieving file size:"
+#define FYBA_STRING_PINFO_LONG_OR_NO_NOE "PINFO too long -OR- ..NØ missing after PINFO:"
+#define FYBA_STRING_LOGIC_FAIL "Logic error in SOSI-file\nLine order error, property among coordinates:\n"
+#define FYBA_STRING_MAX_1_KP_OR_NO_NOE "Max. 1 KP per point -OR- ..NØ missing after KP:"
+#define FYBA_STRING_NO_ROOM_IN_HEADER "No room in header or corrupt:"
+#define FYBA_STRING_INVALID_GAP "Invalid gap in point-indentation:"
+#define FYBA_STRING_TOO_MANY_COORDINATES "Too many coordinates in group:"
+#define FYBA_STRING_TOO_MANY_GINFO "GINFO-line lost. Too many GINFO lines in:"
+#define FYBA_STRING_TOO_MUCH_GINFO "GINFO-line lost. Too much GINFO in:"
+#define FYBA_STRING_TOO_MUCH_PINFO "PINFO lost. Too much PINFO in:"
+#define FYBA_STRING_CANT_EXTEND_GROUP "Cannot extend group (too many coordinates):"
+#define FYBA_STRING_READ_NO_WRITE_ACCESS "Cannot read new group. No write access to save current, changed group. File:"
+#define FYBA_STRING_READ_LINE_TOO_LONG "Cannot read SOSI file. Line too long: "
+#define FYBA_STRING_INVALID_POINT "Invalid point number:"
+#define FYBA_STRING_INVALID_GINFO "Invalid GINFO line number:"
+#define FYBA_STRING_INVALID_NODE "Invalid Node type:"
+#define FYBA_STRING_INVALID_GROUP_NAME "Invalid group name:"
+#define FYBA_STRING_PINFO_TOO_LONG "PINFO too long, cannot fetch value. (Contact support/developers)"
+#define FYBA_STRING_INVALID_REF "Invalid REF in file:"
+#define FYBA_STRING_CANT_CHANGE_ENHET "Cannot change ENHET in a file with data:"
+#define FYBA_STRING_CANT_CHANGE_NGIS_LAG "Cannot change ..NGIS-LAG in a file with data:"
+#define FYBA_STRING_INVALID_BUE "Invalid curve (BUE) in file:"
+#define FYBA_STRING_CANT_CHANGE_ORIGO_NOE "Cannot change ..ORIGO-NØ in a file with data:"
+#define FYBA_STRING_PROB_TOO_LONG_PINFO "PINFO (probably) too long."
+#define FYBA_STRING_NO_HOEYDE_WITH_NAD "Group has ..NAD, cannot store height per point:"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAH "Group has ..NAH, cannot store depth per point: "
+#define FYBA_STRING_LINE_TOO_LONG "SOSI-line too long (max. 1024 characters), line stripped. Group: "
+#define FYBA_STRING_INVALID_SERIAL "Invalid serial number:"
+#define FYBA_STRING_INVALID_LINE_NR "Invalid line number in table to unpack info:" /* check */
+#define FYBA_STRING_INVALID_GROUP_NR "Invalid group number, identifier corrupt:"
+#define FYBA_STRING_ERR_READING_BUFFER "Error reading from ring buffer."
+#define FYBA_STRING_ERR_WRITING_BUFFER "Error writing to ring buffer."
+#define FYBA_STRING_MUST_INIT_INDEX "Must initialize index table before saving."
+#define FYBA_STRING_ERR_READING_SEARCHT "Error reading geographic search table."
+#define FYBA_STRING_ERR_WRITING_SEARCHT "Error writing geographic search table."
+#define FYBA_STRING_ERR_READING_GROUPT "Error reading group table."
+#define FYBA_STRING_ERR_WRITING_GROUPT "Error writing group table."
+#define FYBA_STRING_ERR_READING_SERIALT "Error reading serial number table."
+#define FYBA_STRING_ERR_WRITING_SERIALT "Error writing serial number table."
+#define FYBA_STRING_ERR_READING_INFOT "Error reading info table."
+#define FYBA_STRING_ERR_WRITING_INFOT "Error writing info table."
+#define FYBA_STRING_ERR_INFOT_FULL "Info storage table is full."
+#define FYBA_STRING_ERR_READING_BRUKT "Error reading 'brukt'-table." /* check */
+#define FYBA_STRING_ERR_WRITING_BRUKT "Error writing 'brukt'-table."
+#define FYBA_STRING_NO_BLANKS_FILENAME "Cannot create catalog for index files with spaces in file name.\n"
+#define FYBA_STRING_TOO_MANY_CHOICES "Too many selections, no room for:"
+#define FYBA_STRING_MISPLACED_CHOICE "Misplaced selection line:"
+#define FYBA_STRING_GROUP_CHOICE_MISSING "Included group selection not found:"
+#define FYBA_STRING_INVALID_CHOICE "Invalid selection line:"
+#define FYBA_STRING_NO_COMPLEX_CHOICE "Complex selections (with OG or ELLER) do not work on PINFO."
+#define FYBA_STRING_GAP_IN_LEVEL "Invalid gap in indentation:"
+#define FYBA_STRING_TOO_MANY_PRIORITIES "Too many priorities, ignoring:"
+#define FYBA_STRING_DUPLICATE_DEFINITION "Level is defined twice in:" /* check */
+#define FYBA_STRING_UNKNOWN_ERROR "Unknown error message. Nr.: %d"
+
+# else
+/* =========== NORWEGIAN FYBA_STRINGS (DEFAULT) ======= */
+
+#define FYBA_STRING_BASE_UNKNOWN_TYPE "Ukjent BaseType er gitt, kan derfor ikke åpne base!"
+#define FYBA_STRING_BASE_TOO_MANY_GROUPS "For mange grupper i basen:"
+#define FYBA_STRING_FILE_NOT_FOUND "Finner ingen .SOS fil med navnet:"
+#define FYBA_STRING_BASE_FYBA_NOT_INITD "Kan ikke åpne base, FYBA er ikke initiert!"
+#define FYBA_STRING_BASE_NOT_OPEN "Kan ikke åpne SOSI-fil, fordi det ikke er åpnet noen base!"
+#define FYBA_STRING_FILE_OPEN_FAILED "Åpningsfeil på filen:"
+#define FYBA_STRING_FILE_PERM_DENIED "Tillatelse nektet under åpning av SOSI-fil eller lagring av indeksen."
+#define FYBA_STRING_FILE_OMRAADE_MISSING "..OMRÅDE mangler i filhodet på filen:"
+#define FYBA_STRING_FILE_MIN_NOE_MISSING "...MIN-NØ mangler i filhodet på filen:"
+#define FYBA_STRING_FILE_MAX_NOE_MISSING "...MAX-NØ mangler i filhodet på filen:"
+#define FYBA_STRING_BASE_INDEX_ABORTED "Indeksoppbygging er avbrutt!"
+#define FYBA_STRING_BASE_OPEN_FAILED "Åpningsfeil på:"
+#define FYBA_STRING_FILE_NEW_HEADER "Nytt hode på:"
+#define FYBA_STRING_FILE_NOT_SOSI "Ikke SOSI-fil:"
+#define FYBA_STRING_FILE_OMRAADE_INVALID "Ulovlig OMRÅDE-angivelse i filhodet! (Ingen utstrekning.)"
+#define FYBA_STRING_SAVE_INVALID_FILEPTR "Ulovlig filpeker ved kall til lagringssystemet, rutine"
+#define FYBA_STRING_OPEN_BASE_IS_KLADDE "Kan ikke åpne SOSI-fil. Basen er åpnet som kladdebase. Dette kan bare kombineres med sekvensiell les/skriv av SOSI-fil."
+#define FYBA_STRING_FILE_READ_ERROR_HODE "Lesefeil ved lesing av hodelinje."
+#define FYBA_STRING_FILE_TRANSPAR_MISSING "..TRANSPAR mangler i filhodet."
+#define FYBA_STRING_FILE_KOORDSYS_MISSING "...KOORDSYS mangler i filhodet."
+#define FYBA_STRING_FILE_ORIGO_MISSING "...ORIGO-NØ mangler i filhodet. (Feil tegnsett?)"
+#define FYBA_STRING_FILE_ENHET_MISSING "...ENHET mangler i filhodet."
+#define FYBA_STRING_NAME_TABLE_FULL "Navnetabellen er full."
+#define FYBA_STRING_INVALID_GROUP_NAME "Ulovlig gruppenavn:"
+#define FYBA_STRING_FILE_NO_CURRENT_GROUP "Ingen aktuell gruppe, ingenting er lest!"
+#define FYBA_STRING_OPEN_INVALID_EXTERN "Ulovlig ekstern fil, ingenting er lest!"
+#define FYBA_STRING_SAVE_INVALID_EXTERN "Ulovlig ekstern fil, ingenting er skrevet!"
+#define FYBA_STRING_SAVE_NO_WRITE_ACCESS "Du har ikke skriveaksess, ingenting er skrevet til filen:"
+#define FYBA_STRING_GROUP_DELETED "Gruppen er sletta."
+#define FYBA_STRING_FILE_INVALID_GROUP_NR "Ulovlig gruppenummer, ingenting er lest!"
+#define FYBA_STRING_NEW_INVALID_FILE "Ulovlig fil, kan ikke lage ny gruppe!"
+#define FYBA_STRING_NEW_NO_WRITE_ACCESS "Du har ikke skriveaksess, kan ikke lage ny gruppe!"
+#define FYBA_STRING_NEW_TOO_MANY_GROUPS "For mange grupper i basen, kan ikke lage ny gruppe:"
+#define FYBA_STRING_NEW_INVALID_LINE_GI "Ulovlig linjenummer for ny GINFO:"
+#define FYBA_STRING_NEW_INVALID_LINE_COO "Ulovlig linjenummer for ny koordinat:"
+#define FYBA_STRING_SLUTT_MISSING ".SLUTT mangler på SOSI-filen"
+#define FYBA_STRING_READ_ERROR "Lesefeil på SOSI-filen"
+#define FYBA_STRING_GROUP_REFERRED_TO "Gruppen er referert fra annen gruppe, kan ikke slette gruppen!"
+#define FYBA_STRING_INVALID_GI_LINE_1 "Ulovlig GINFO-linje nr 1:"
+#define FYBA_STRING_CANT_REMOVE_HEADER "Det er ikke mulig å slette filhodet!"
+#define FYBA_STRING_NO_CURRENT_GROUP "Det er ingen aktuell gruppe, ingenting er utfÞrt!"
+#define FYBA_STRING_DEL_UNKNOWN_FLAG "Gruppen har ukjent NGIS endringsflagg, kan ikke slette gruppen!"
+#define FYBA_STRING_DEL_NO_WRITE_ACCESS "Du har ikke skriveaksess, kan ikke slette gruppen!"
+#define FYBA_STRING_ERR_FILESIZE_CHANGE "Feil ved endring av filstÞrrelse!"
+#define FYBA_STRING_DISK_SOON_FULL "Disken er snart full. Rydd plass til : "
+#define FYBA_STRING_NOT_A_HEADER "Aktuell gruppe er ikke SOSI-filhode, ingenting er utfÞrt"
+#define FYBA_STRING_DEL_NOT_SEQUENTIAL "Det er ikke mulig å slette gruppe på sekvensiell fil!"
+#define FYBA_STRING_NO_CHANGE_HEADERS "Kan ikke endre KOORDSYS, ENHET, ORIGO eller NGIS-LAG på fil med data!"
+#define FYBA_STRING_CANT_REWRITE_HEADER "Det er ikke plass til å skrive tilbake filhodet!"
+#define FYBA_STRING_SAVE_NOT_A_HEADER "Gruppen er ikke filhode, kan ikke lagre den som filhode!"
+#define FYBA_STRING_CANT_COPY_COORD "Kan ikke kopiere koord. fra akt. gruppe til akt.gruppe!"
+#define FYBA_STRING_CANT_COPY_COORD_ROOM "Kan ikke kopiere koordinater: (ikke nok plass i ringbuffer)!"
+#define FYBA_STRING_ENHET_NOT_SET "ENHET er 0.0 i filhodet, eller filhode mangler på filen:"
+#define FYBA_STRING_CANT_READ_FILE_SIZE "Feil ved hent av filstÞrrelse på filen:"
+#define FYBA_STRING_PINFO_LONG_OR_NO_NOE "For lang PINFO / ..NØ mangler etter PINFO! :"
+#define FYBA_STRING_LOGIC_FAIL "Logisk feil i SOSI-fil.\nNivåfeil, egenskap mellom koordinatene:\n"
+#define FYBA_STRING_MAX_1_KP_OR_NO_NOE "Max. 1 KP pr. punkt / ..NØ mangler etter KP! :"
+#define FYBA_STRING_NO_ROOM_IN_HEADER "Ikke plass til hodet, Þdelagt på filen :"
+#define FYBA_STRING_INVALID_GAP "Ulovlig sprang i prikk-nivå!:"
+#define FYBA_STRING_TOO_MANY_COORDINATES "For mange koordinater i gruppe:"
+#define FYBA_STRING_TOO_MANY_GINFO "GINFO-linje mistes! For mange GINFO linjer i:"
+#define FYBA_STRING_TOO_MUCH_GINFO "GINFO-linje mistes! For mye GINFO i:"
+#define FYBA_STRING_TOO_MUCH_PINFO "PINFO mistes! For mye PINFO i:"
+#define FYBA_STRING_CANT_EXTEND_GROUP "Kan ikke utvide gruppe (for mange koordinater):"
+#define FYBA_STRING_READ_NO_WRITE_ACCESS "Kan ikke lese ny gruppe. Du har ikke skriveaksess for å lagre aktuell gruppe som er endret. Fil :"
+#define FYBA_STRING_READ_LINE_TOO_LONG "Kan ikke lese SOSI-fil. For lang SOSI-linje: "
+#define FYBA_STRING_INVALID_POINT "Ulovlig punktnummer:"
+#define FYBA_STRING_INVALID_GINFO "Ulovlig GINFO-linje nummer:"
+#define FYBA_STRING_INVALID_NODE "Ulovlig Knutepunkt-type:"
+#define FYBA_STRING_INVALID_GROUP_NAME "Ulovlig gruppenavn:"
+#define FYBA_STRING_PINFO_TOO_LONG "For lang PINFO, klarer ikke å hente verdi. (Kontakt FYSAK-support)"
+#define FYBA_STRING_INVALID_REF "OBS! Ulovlig ref. i filen:"
+#define FYBA_STRING_CANT_CHANGE_ENHET "Kan ikke endre ENHET på fil med data, bruker:"
+#define FYBA_STRING_CANT_CHANGE_NGIS_LAG "Kan ikke endre ..NGIS-LAG på fil med data, bruker:"
+#define FYBA_STRING_INVALID_BUE "OBS! Ulovlig bue i filen:"
+#define FYBA_STRING_CANT_CHANGE_ORIGO_NOE "Kan ikke endre ..ORIGO-NØ på fil med data, bruker:"
+#define FYBA_STRING_PROB_TOO_LONG_PINFO "Sannsynligvis for lang PINFO !"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAD "Gruppen har ..NAD, kan ikke legge inn hÞyde på punktnivå i:"
+#define FYBA_STRING_NO_HOEYDE_WITH_NAH "Gruppen har ..NAH, kan ikke legge inn dybde på punktnivå i: "
+#define FYBA_STRING_LINE_TOO_LONG "For lang SOSI-linje (max 1024 tegn), linjen forkortes. Gruppe: "
+#define FYBA_STRING_INVALID_SERIAL "Ulovlig serienummer:"
+#define FYBA_STRING_INVALID_LINE_NR "Ulovlig linjenummer i tabell for upakka info:"
+#define FYBA_STRING_INVALID_GROUP_NR "Ulovlig gruppenummer, merking fungerer ikke :"
+#define FYBA_STRING_ERR_READING_BUFFER "Feil ved les fra ringbuffer!"
+#define FYBA_STRING_ERR_WRITING_BUFFER "Feil ved skriv til ringbuffer!"
+#define FYBA_STRING_MUST_INIT_INDEX "Indekstabellene må initieres fÞr lagring"
+#define FYBA_STRING_ERR_READING_SEARCHT "Feil ved les fra geografisk sÞketabell!"
+#define FYBA_STRING_ERR_WRITING_SEARCHT "Feil ved skriv til geografisk sÞketabell!"
+#define FYBA_STRING_ERR_READING_GROUPT "Feil ved les fra gruppetabell!"
+#define FYBA_STRING_ERR_WRITING_GROUPT "Feil ved skriv til gruppetabell!"
+#define FYBA_STRING_ERR_READING_SERIALT "Feil ved les fra serienummer-tabell!"
+#define FYBA_STRING_ERR_WRITING_SERIALT "Feil ved skriv til serienummer-tabell!"
+#define FYBA_STRING_ERR_READING_INFOT "Feil ved les fra info-tabell!"
+#define FYBA_STRING_ERR_WRITING_INFOT "Feil ved skriv til info-tabell!"
+#define FYBA_STRING_ERR_INFOT_FULL "Tabell for upakka info er full!"
+#define FYBA_STRING_ERR_READING_BRUKT "Feil ved les fra brukt-tabell!"
+#define FYBA_STRING_ERR_WRITING_BRUKT "Feil ved skriv til brukt-tabell!"
+#define FYBA_STRING_NO_BLANKS_FILENAME "Kan ikke opprette katalog for indeksfiler når det er blanke sist i filnavnet!\n"
+#define FYBA_STRING_TOO_MANY_CHOICES "For mange utvalg, ikke plass til:"
+#define FYBA_STRING_MISPLACED_CHOICE "Feilplasert utvalgslinje:"
+#define FYBA_STRING_GROUP_CHOICE_MISSING "Inkludert gruppeuvtalg finnes ikke:"
+#define FYBA_STRING_INVALID_CHOICE "Ulovlig utvalgslinje:"
+#define FYBA_STRING_NO_COMPLEX_CHOICE "Komplekse utvalg (..OG og ..ELLER) fungerer ikke for PINFO!"
+#define FYBA_STRING_GAP_IN_LEVEL "Ulovlig sprang i nivå!:"
+#define FYBA_STRING_TOO_MANY_PRIORITIES "For mange prioriteter, mister prioritet :"
+#define FYBA_STRING_DUPLICATE_DEFINITION "Lag er dobbeltdefinert i utvalg :"
+#define FYBA_STRING_UNKNOWN_ERROR "Ukjent feilmelding. Nr.: %d"
+
+# endif
diff --git a/src/FYBA/fybax.h b/src/FYBA/fybax.h
new file mode 100644
index 0000000..92eef6f
--- /dev/null
+++ b/src/FYBA/fybax.h
@@ -0,0 +1,344 @@
+/* == AR-991012 =========================================================== */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fybax.h */
+/* Innhold: Interne prototyper for fysak-pc */
+/* Def. av typer og bufferstørrelser */
+/* Definisjon av filtabellen, ringbuffer mm. */
+/* ======================================================================== */
+
+#pragma once
+
+#include "fyba.h"
+
+
+/* ======================================================= */
+/* Definerer konstanter */
+/* ======================================================= */
+#ifndef _FYBAX_DEFINED
+
+# define FYBA_IDENT "FYBA - G2.0 2011-03-10"
+# define FYBA_INDEKS_VERSJON "G009"
+# define FYBA_SOSI_VERSJON 400
+
+ /* Definerer PI */
+//# ifndef PI
+////# define PI (3.14159265358979324)
+//# define PI (3.14159265358979323846)
+//# endif
+
+/* --- Konstant for testing av likhet på desimaltall -- */
+#define LC_ACCY 1.0E-9
+
+
+ /* Basetype */
+ /* #define LC_START_KLADD 2 */ /* Åpning av kladdebase */
+ /* (LC_BASE og LC_KLADD er definert i FYBA.H) */
+
+ /* Filtabell */
+ /* #define NO_OPEN_SOS -1 */ /* Ingen åpen SOSI-fil */
+
+ /* Kommando til LB_Wgru */
+# define KONTROLLER_PLASS 1 /* Bare kontroller plass, (ikke skriv SOSI) */
+# define SKRIV_VANLIG 2 /* Skriv til SOSI, vanlig */
+# define SKRIV_SISTE 3 /* Skriv til SOSI, med .SLUTT og bytepointer */
+
+ /* Diverse */
+# define NYTT_SNR -1L /* Startverdi for akt.snr i filtabellen */
+
+# define NY_SOSI_ST -1L /* Start.sosi når gruppe ikke er skrevet */
+# define NY_RB_ST -1L /* Start.rb når gruppe ikke er skrevet */
+# define NY_UI_ST -1L /* Start.UI når gruppe ikke er skrevet */
+
+/*
+ * Diverse for intern mellomlagring av hele PINFO
+ */
+ /* Statusverdier */
+# define LC_PIBUF_TOM 0
+# define LC_PIBUF_OK 1
+# define LC_PIBUF_FULL 2
+ /* Ant. tegn i buffer */
+# define LC_MAX_PIBUF_TEGN LC_MAX_SOSI_LINJE_LEN
+ /* Ant linjer i tabell med pekere til startposisjoner i strengen */
+# define LC_MAX_PIBUF_LIN 50
+
+# define LI_LESEFEIL -1 // Filen er åpen i annet program
+# define LI_OPPTATT -2 // Filen er åpen i annet program
+# define LI_FEIL_INDEKSVERSJON -3 // Feil indeksversjon
+# define LI_FEIL_STORRELSE -4 // Feil størrelse på SOSI-filen
+# define LI_FEIL_OPPDATTID -5 // Feil oppdateringstid på SOSI-filen
+
+
+# define _FYBAX_DEFINED
+#endif
+
+
+/* ================================================ */
+/* Definerer data-strukturer */
+/* ================================================ */
+
+/* Lesebuffer */
+/* Konstanter for set_brukt */
+#define SET_UBRUKT 0
+#define SET_BRUKT 1
+
+/* Konstanter for sStatus */
+#define LESEBUFFER_TOM 0 /* (Tom eller ikke ajour) */
+#define LESEBUFFER_OK 1
+
+ /* Verdier for cur_type */
+ /* >= 0 : Gruppenavn,linjenummer i navnetab. */
+#define LEST_KOORD -1 /* Koordinatlinje */
+#define LEST_BLANK -2 /* "blank linje" (!!!, mm) */
+#define LEST_GINFO -3 /* GINFO */
+#define LEST_KOM -4 /* Kommentar-linje */
+
+
+/* Felles streng for feilmeldinger */
+#define LC_ERR_LEN 300
+typedef struct dLC_FEILMELDING {
+ short nr;
+ short strategi;
+ char tx[LC_ERR_LEN];
+} LC_FEILMELDING;
+
+
+/* UTVALG */
+/*
+ // Utvalgskommandoer
+#define U_OG 1 // ..OG
+#define U_ELLER 2 // ..VELG og ..ELLER
+
+
+ // Utvalgsmetoder
+#define U_IKKE 0 // ! Ikke (Tilslag når SOSI-navnet
+ // ikke finnes. Bare GINFO.)
+#define U_ALLE 1 // AL Alle
+#define U_FRATIL 2 // <> Fra-til
+#define U_UTENFOR 3 // >< Utenfor
+#define U_MINDRE 4 // < Mindre-enn
+#define U_STORRE 5 // > Større-enn
+#define U_DELELIG 6 // / Delelig-med, eventuellt med
+ // sjekk på om restverdi er 2. verdi
+#define U_UDELELIG 7 // !/ Ikke-delelig-med
+#define U_CONTEIN 8 // () Inneholder
+#define U_IKKECONTEIN 9 // !() Inneholder ikke (Tilslag når
+ // denne navn og verdi kombinasjonen
+ // ikke finnes)
+#define U_LIK 10 // = Lik
+#define U_IKKEVALGT 11 // IV Ikke valgt (Tilslag når gruppen
+ // ikke er tegnet ennå. Kombineres
+ // med SOSI-navnet "..*")
+#define U_IKKELIK 12 // != Ikke lik (Tilslag når denne
+ // navn og verdi kombinasjonen ikke
+ // finnes)
+#define U_FLERE 13 // FL Flere (Tilslag når SOSI-navnet
+ // forekommer flere ganger.)
+#define U_IKKEFLERE 14 // !FL Ikke flere enn (Tilslag når
+ // SOSI-navnet IKKE forekommer
+ // flere ganger enn gitt antall.)
+
+
+
+ // Parametertyper
+#define U_TALL 1 // Heltall
+#define U_FLYT 2 // Flyttall
+#define U_ALFA 9 // Tekststreng
+*/
+
+ /* GINFO i minne */
+typedef struct dLC_GINFO_BUFFER {
+ char *pszTx; /* GINFO buffer */
+ unsigned long ulOfset[LC_MAX_GINFO]; /* Peker til starten av hver GINFO-linje */
+} LC_GINFO_BUFFER;
+
+
+/*
+ *!--------------------------------------------------------------!
+ *! Systemadministrasjon !
+ *!--------------------------------------------------------------!
+ */
+typedef struct dLC_SYSTEMADM {
+ char szBaseVer[LC_BASEVER_LEN]; // Versjon og dato for aktuell versjon av FYBA
+ char szIdxVer[5]; // Indeksfil-versjon
+
+ short sResPlass; // Ant. tegn reserve plass bak ny gruppe
+ long lMaxSkriv; // Max antall skriv uten lagring til SOSI-filen
+ long lAntSkriv; // Antall skriv siden siste lagring til SOSI
+ short sNGISmodus; // Behandlingsmåte for grupper med NGIS-oppdateringsflagg
+ short sUtvidModus; // Handteringsmåte for utvidelse av SOSI-filer.
+ char szIdxPath[_MAX_PATH]; //Katalognavn for ny indeks.
+ LB_LESEBUFFER BufAdm; // Lesebuffer mot SOSI-fil-hode
+
+ LC_NAVNETABELL SosiNavn; // Navnetabell (brukes av HO-rutinene)
+
+ /* Div opplysninger om aktuell gruppe */
+ short sGrEndra; // Er aktuell gruppe endra?
+ LC_BGR GrId; // Gruppens identifikasjon
+ LC_GRTAB_LINJE *pGrInfo; // Peker til gruppetabell-linje
+
+ /* Aktuell gruppe i minne */
+ /* GINFO i minne */
+ LC_GINFO_BUFFER Hode; // Hodebuffer
+ unsigned short usHoLen; // Ant tegn i hodebuffer
+ LC_GINFO_BUFFER Ginfo; // GINFO-buffer
+ double *pdAust; // Øst koordinat
+ double *pdNord; // Nord koordinat
+ LB_INFO * pInfo; // Høyde,KP og PINFO-peker
+ char *pszPinfo; // PINFO buffer
+
+ /* Søkebuffer for PINFO */
+ long lPibufPnr; // Punktnummer for data i buffer
+ short sPibufAntPi; // Antall elementer brukt i PIbuf
+ char cPibuf[LC_MAX_PIBUF_TEGN]; // Kopi av PINFO, (for raskere søking)
+ short sPibufStatus; // Status for bruken av cPibuf
+ /* Peker til startposisjoner i cPibuf for hver PINFO */
+ char *pcPibufNavn[LC_MAX_PIBUF_LIN]; // Peker til SOSI-navn
+ char *pcPibufVerdi[LC_MAX_PIBUF_LIN]; // Peker til verdi
+
+ unsigned short usMerkRefGr; // Flagg for å vise om refererte grupper skal merkes ved utvalg
+
+ LC_BASEADM * pForsteBase; // Peker til første base-adm.
+ LC_BASEADM * pAktBase; // Peker til aktuell base-adm.
+} LC_SYSTEMADM;
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyho.c */
+/* ======================================================= */
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylb.c */
+/* ======================================================= */
+void LB_Save(LC_FILADM *pFil);
+void LB_NyRp(void);
+short LB_RGru(LC_FILADM *pFil,UT_INT64 start,UT_INT64 *slutt);
+void LB_Swap(void);
+char *LB_FormaterEnhet(char *streng,short sStrengMaxLen,char *SosiNavn,double enhet);
+void LB_ClGr (void);
+short LB_WGru (short strategi,long fra_punkt,long antall,
+ LC_FILADM *pFil,UT_INT64 ffipos,UT_INT64 *lfipos);
+short LB_Plass(LC_FILADM *pFil, UT_INT64 start, UT_INT64 *neste);
+short LB_WriteLine (FILE *fil,short sTegnsett,char *tx);
+short LB_GetSet(FILE *fil,LB_LESEBUFFER *plb,LC_NAVNETABELL * pNavn);
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyli.c */
+/* ======================================================= */
+short LI_TestIdx(char *szSosFil);
+short LI_OpenInit(LC_FILADM *pFil);
+short LI_OpenRead(LC_FILADM *pFil);
+void LI_Close(LC_FILADM *pFil,short s_stat);
+void LI_SaveAdm(LC_FILADM *pFil);
+
+LC_R_LEAF * LI_GetGeo(LC_FILADM *pFil,long linje);
+/* void LI_PutGeo(LC_FILADM *pFil,long linje,LC_GEOSOK_BOKS *geop); */
+
+long LI_GetSnr(LC_FILADM *pFil,long lSnr);
+void LI_PutSnr(LC_FILADM *pFil,long lSnr,long lGrNr);
+
+LC_GRTAB_LINJE * LI_GetGrt(LC_FILADM *pFil,long linje);
+LC_GRTAB_LINJE * LI_AppGrt(LC_FILADM *pFil,long linje);
+
+unsigned long LI_GetBt(LC_FILADM *pFil,long linje);
+void LI_PutBt(LC_FILADM *pFil,long linje,unsigned long bt_val);
+
+void LI_SetBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+void LI_ClrBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+short LI_InqBt(LC_FILADM *pFil,long lGrNr,short kolonne);
+void LI_EraseBt(short fra_kol,short til_kol);
+
+void LI_WriteRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+ char *pszGi, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen);
+void LI_ReadRb(LC_FILADM *pFil, UT_INT64 n64FilPos,
+ char *pszGi, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen);
+void LI_ReadCoordRb(LC_FILADM *pFil, UT_INT64 n64FilPos, unsigned long ulGiLen,
+ double *pdAust, double *pdNord,
+ LB_INFO * pInfo, long lNko,
+ char *pszPi, unsigned long ulPiLen);
+long LI_BerBufferLen(unsigned long ulGiLen,long lNko,unsigned long ulPiLen);
+
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyln.c */
+/* ======================================================= */
+void LN_InitTab(LC_NAVNETABELL *pLn);
+short LN_Enhet(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_EnhetHoyde(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_EnhetDybde(LC_NAVNETABELL *pLn,char *ginfo_linje);
+short LN_TestOy(char *ginfo_linje);
+short LN_PakkNavn(LC_NAVNETABELL *pLn,char *navn,short *navn_nr,
+ short *ant_par);
+short LN_FinnNavn(LC_NAVNETABELL *pLn,char *navn,short *navn_nr);
+char *LN_GetNavn(LC_NAVNETABELL *pLn,short navn);
+char *LN_VisNavn(LC_NAVNETABELL *pLn,short navn);
+void LN_TolkKvalitet(char *pszParameter,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyls.c */
+/* ======================================================= */
+void LS_Indx(void);
+void LS_PutSn(LC_FILADM *pFil,long lGrNr,long lSnr);
+char * LS_VisSn(LC_FILADM *pFil,long lin);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylr.c */
+/* ======================================================= */
+/* Indeksoppbygging */
+void LR_Indx(void);
+void LR_IndxFlate(void);
+short LR_PTstGruppe(LC_BGR * pBgr,double a,double n);
+void LR_R_Delete(LC_R_LEAF * pCL);
+LC_R_LEAF * LR_InsertGeo(LC_FILADM *pFil,long lNr,LC_BOKS * pB);
+void LR_R_FrigiGren(LC_R_NODE *pRN);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylo.c */
+/* ======================================================= */
+LC_FEILMELDING& err();
+void LO_CloseSos(LC_BASEADM *pBase);
+void LO_ReopenSos(LC_FILADM *pFil);
+void LO_BeFt(LC_FILADM *pFil);
+void LO_TestFilpeker(LC_FILADM *pFil,char *pszRutineNavn);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylx.c */
+/* ======================================================= */
+void LX_PutSn(long snr);
+void LX_CreGiPeker(LC_GINFO_BUFFER *pGinfo,short ngi);
+char *LX_GetGi(short lin_nr);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylp.c */
+/* ======================================================= */
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fylh.c */
+/* ======================================================= */
+char* LH_GetNgisLag(void);
+
+/* ======================================================= */
+/* Funksjonsdefinisjoner for fyho.c */
+/* ======================================================= */
+void ho_New(FILE *fil,short koosys,double origo_a,double origo_n,
+ double enhet,double enhet_h,double enhet_d,
+ double nv_a,double nv_n,double oh_a,double oh_n);
+short ho_TestSOSI(FILE *fil,UT_INT64 *sluttpos);
+char *ho_GetVal(FILE *fil,char *sosi_navn,short *sett_nr);
+short ho_GetKvalitet(FILE *fil,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet);
+short ho_GetTrans(FILE *fil,short *koosys,double *origo_a,
+ double *origo_n,double *enhet,double *enhet_h,double *enhet_d);
+short ho_GetTransEx(FILE *pFil,unsigned short *pusMaske, LC_TRANSPAR * pTrans);
+short ho_GetOmr(FILE *fil,double *nv_a,double *nv_n,double *oh_a,double *oh_n);
+short ho_GetTegnsett(FILE *pfFil,short *psTegnsett);
+short ho_SjekkTegnsett(FILE *fil,short *psTegnsett);
+short ho_FinnHode(FILE *pFil, UT_INT64 *lHodepos);
+
diff --git a/src/FYBA/fyln.cpp b/src/FYBA/fyln.cpp
new file mode 100644
index 0000000..8d8c362
--- /dev/null
+++ b/src/FYBA/fyln.cpp
@@ -0,0 +1,870 @@
+/* == AR 910819 ========================================== */
+/* STATENS KARTVERK - FYSAK-PC */
+/* Fil: fyln.c */
+/* Innhold: Navnesystem for fysak-pc */
+/* ======================================================= */
+
+#include "stdafx.h"
+
+#include <fcntl.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/*
+AR-890616
+CH LN_InitTab Klargjør navnetabell
+CD ==========================================================================
+CD Formål:
+CD Initierer navnetabellen med kjente navn.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD
+CD Bruk:
+CD LN_InitTab(pLn);
+ ==========================================================================
+*/
+void LN_InitTab(LC_NAVNETABELL * pLn)
+{
+ UT_StrCopy(pLn->sosi[L_SLUTT].szNavn, ".SLUTT", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_SLUTT].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_SLUTT].cNivo = 1;
+ pLn->sosi[L_SLUTT].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_PUNKT].szNavn, ".PUNKT", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_PUNKT].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_PUNKT].cNivo = 1;
+ pLn->sosi[L_PUNKT].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_LINJE].szNavn, ".LINJE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_LINJE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_LINJE].cNivo = 1;
+ pLn->sosi[L_LINJE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_KURVE].szNavn, ".KURVE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_KURVE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_KURVE].cNivo = 1;
+ pLn->sosi[L_KURVE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_BUE].szNavn, ".BUE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_BUE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_BUE].cNivo = 1;
+ pLn->sosi[L_BUE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_BUEP].szNavn, ".BUEP", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_BUEP].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_BUEP].cNivo = 1;
+ pLn->sosi[L_BUEP].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_SIRKEL].szNavn, ".SIRKEL", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_SIRKEL].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_SIRKEL].cNivo = 1;
+ pLn->sosi[L_SIRKEL].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_SIRKELP].szNavn, ".SIRKELP", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_SIRKELP].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_SIRKELP].cNivo = 1;
+ pLn->sosi[L_SIRKELP].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_KLOTOIDE].szNavn, ".KLOTOIDE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_KLOTOIDE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_KLOTOIDE].cNivo = 1;
+ pLn->sosi[L_KLOTOIDE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_BEZIER].szNavn, ".BEZIER", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_BEZIER].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_BEZIER].cNivo = 1;
+ pLn->sosi[L_BEZIER].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_RASTER].szNavn, ".RASTER", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_RASTER].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_RASTER].cNivo = 1;
+ pLn->sosi[L_RASTER].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_TEKST].szNavn, ".TEKST", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_TEKST].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_TEKST].cNivo = 1;
+ pLn->sosi[L_TEKST].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_TRASE].szNavn, ".TRASE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_TRASE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_TRASE].cNivo = 1;
+ pLn->sosi[L_TRASE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_FLATE].szNavn, ".FLATE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_FLATE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_FLATE].cNivo = 1;
+ pLn->sosi[L_FLATE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_SVERM].szNavn, ".SVERM", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_SVERM].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_SVERM].cNivo = 1;
+ pLn->sosi[L_SVERM].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_DEF].szNavn, ".DEF", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_DEF].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_DEF].cNivo = 1;
+ pLn->sosi[L_DEF].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_OBJDEF].szNavn, ".OBJDEF", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_OBJDEF].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_OBJDEF].cNivo = 1;
+ pLn->sosi[L_OBJDEF].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_MLINJE].szNavn, ".MLINJE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_MLINJE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_MLINJE].cNivo = 1;
+ pLn->sosi[L_MLINJE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_STRUKTUR].szNavn, ".STRUKTUR", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_STRUKTUR].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_STRUKTUR].cNivo = 1;
+ pLn->sosi[L_STRUKTUR].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_OBJEKT].szNavn, ".OBJEKT", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_OBJEKT].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_OBJEKT].cNivo = 1;
+ pLn->sosi[L_OBJEKT].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_SYMBOL].szNavn, ".SYMBOL", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_SYMBOL].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_SYMBOL].cNivo = 1;
+ pLn->sosi[L_SYMBOL].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_HODE].szNavn, ".HODE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_HODE].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_HODE].cNivo = 1;
+ pLn->sosi[L_HODE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_NA].szNavn, "..NØ", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_NA].ucAntPar = 2;
+ pLn->sosi[L_NA].cNivo = 2;
+ pLn->sosi[L_NA].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_NAH].szNavn, "..NØH", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_NAH].ucAntPar = 3;
+ pLn->sosi[L_NAH].cNivo = 2;
+ pLn->sosi[L_NAH].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_NAD].szNavn, "..NØD", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_NAD].ucAntPar = 3;
+ pLn->sosi[L_NAD].cNivo = 2;
+ pLn->sosi[L_NAD].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_REF1].szNavn, "..", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_REF1].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_REF1].cNivo = 2;
+ pLn->sosi[L_REF1].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_REF2].szNavn, "..REF", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_REF2].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_REF2].cNivo = 2;
+ pLn->sosi[L_REF2].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_RADIUS].szNavn, "..RADIUS", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_RADIUS].ucAntPar = 1;
+ pLn->sosi[L_RADIUS].cNivo = 2;
+ pLn->sosi[L_RADIUS].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET2].szNavn, "..ENHET", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET2].ucAntPar = 1;
+ pLn->sosi[L_ENHET2].cNivo = 2;
+ pLn->sosi[L_ENHET2].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET2H].szNavn, "..ENHET-H", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET2H].ucAntPar = 1;
+ pLn->sosi[L_ENHET2H].cNivo = 2;
+ pLn->sosi[L_ENHET2H].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET2D].szNavn, "..ENHET-D", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET2D].ucAntPar = 1;
+ pLn->sosi[L_ENHET2D].cNivo = 2;
+ pLn->sosi[L_ENHET2D].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET3].szNavn, "...ENHET", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET3].ucAntPar = 1;
+ pLn->sosi[L_ENHET3].cNivo = 3;
+ pLn->sosi[L_ENHET3].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET3H].szNavn, "...ENHET-H", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET3H].ucAntPar = 1;
+ pLn->sosi[L_ENHET3H].cNivo = 3;
+ pLn->sosi[L_ENHET3H].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ENHET3D].szNavn, "...ENHET-D", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ENHET3D].ucAntPar = 1;
+ pLn->sosi[L_ENHET3D].cNivo = 3;
+ pLn->sosi[L_ENHET3D].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_ORIGONO].szNavn, "...ORIGO-NØ", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_ORIGONO].ucAntPar = 2;
+ pLn->sosi[L_ORIGONO].cNivo = 3;
+ pLn->sosi[L_ORIGONO].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_HOYDE].szNavn, "..HØYDE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_HOYDE].ucAntPar = 1;
+ pLn->sosi[L_HOYDE].cNivo = 2;
+ pLn->sosi[L_HOYDE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_DYBDE].szNavn, "..DYBDE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_DYBDE].ucAntPar = 1;
+ pLn->sosi[L_DYBDE].cNivo = 2;
+ pLn->sosi[L_DYBDE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_NGISFLAGG].szNavn, "..NGIS-FLAGG", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_NGISFLAGG].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_NGISFLAGG].cNivo = 2;
+ pLn->sosi[L_NGISFLAGG].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_NGISLAG].szNavn, "..NGIS-LAG", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_NGISLAG].ucAntPar = LC_ANT_PAR_UKJENT;
+ pLn->sosi[L_NGISLAG].cNivo = 2;
+ pLn->sosi[L_NGISLAG].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_OBJTYPE].szNavn, "..OBJTYPE", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_OBJTYPE].ucAntPar = 1;
+ pLn->sosi[L_OBJTYPE].cNivo = 2;
+ pLn->sosi[L_OBJTYPE].bBrukt = false;
+
+ UT_StrCopy(pLn->sosi[L_KP].szNavn, "...KP", LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[L_KP].ucAntPar = 1;
+ pLn->sosi[L_KP].cNivo = 3;
+ pLn->sosi[L_KP].bBrukt = false;
+
+ pLn->sAntNavn = L_KP + 1; /* Antall navn i navnetabellen */
+}
+
+
+/*
+AR-910919
+CH LN_Enhet Sjekk om det er ..ENHET
+CD ==========================================================================
+CD Formål:
+CD Sjekk om denne ginfo-linjen er ..ENHET.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD char *ginfo_linje i Første pos i linjen
+CD short ok r 1=linjen er ..ENHET, 0=ikke ..ENHET
+CD
+CD Bruk:
+CD ok = LN_Enhet(pLn,ginfo_linje);
+ ===========================================================================
+*/
+short LN_Enhet(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+ char ord[LC_MAX_SOSINAVN_LEN];
+
+ //JAØ-20000313
+ //Leter etter "..ENHET " istedet for "..ENHET" for ikke å få tilslag på ..ENHET-H eller ..ENHET-D
+ UT_StrCopy(ord,pLn->sosi[L_ENHET2].szNavn,LC_MAX_SOSINAVN_LEN);
+ UT_StrCat(ord, " ", LC_MAX_SOSINAVN_LEN);
+
+ return(strstr(ginfo_linje,ord) != NULL);
+ //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2].szNavn) != NULL);
+}
+
+
+/*
+AR-940704
+CH LN_EnhetHoyde Sjekk om det er ..ENHET-H
+CD ==========================================================================
+CD Formål:
+CD Sjekk om denne ginfo-linjen er ..ENHET-H.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD char *ginfo_linje i Første pos i linjen
+CD short ok r 1=linjen er ..ENHET-H, 0=ikke ..ENHET-H
+CD
+CD Bruk:
+CD ok = LN_EnhetHoyde(pLn,ginfo_linje);
+ ===========================================================================
+*/
+short LN_EnhetHoyde(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+ char ord[LC_MAX_SOSINAVN_LEN];
+
+ // Leter etter "..ENHET-H " istedet for "..ENHET-H" for ikke å få tilslag på andre navn
+ UT_StrCopy(ord,pLn->sosi[L_ENHET2H].szNavn,LC_MAX_SOSINAVN_LEN);
+ UT_StrCat(ord, " ", LC_MAX_SOSINAVN_LEN);
+
+ //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2H].szNavn) != NULL);
+ return(strstr(ginfo_linje,ord) != NULL);
+}
+
+
+/*
+AR-940704
+CH LN_EnhetDybde Sjekk om det er ..ENHET-D
+CD ==========================================================================
+CD Formål:
+CD Sjekk om denne ginfo-linjen er ..ENHET-D.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD char *ginfo_linje i Første pos i linjen
+CD short ok r 1=linjen er ..ENHET-D, 0=ikke ..ENHET-D
+CD
+CD Bruk:
+CD ok = LN_EnhetDybde(pLn,ginfo_linje);
+ ===========================================================================
+*/
+short LN_EnhetDybde(LC_NAVNETABELL * pLn,char *ginfo_linje)
+{
+ char ord[LC_MAX_SOSINAVN_LEN];
+
+ // Leter etter "..ENHET-D " istedet for "..ENHET-D" for ikke å få tilslag på andre navn
+ UT_StrCopy(ord,pLn->sosi[L_ENHET2D].szNavn,LC_MAX_SOSINAVN_LEN);
+ UT_StrCat(ord, " ",LC_MAX_SOSINAVN_LEN);
+
+ //return(strstr(ginfo_linje,pLn->sosi[L_ENHET2D].szNavn) != NULL);
+ return(strstr(ginfo_linje,ord) != NULL);
+}
+
+
+/*
+AR-910315
+CH LN_TestOy Sjekk om referansen inneholder øy
+CD ==========================================================================
+CD Formål:
+CD Sjekk om denne ginfo-linjen inneholder referanse med ØY.
+CD Forutsetter at aktuell linje inneholder referanser.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------
+CD char *ginfo_linje i Første pos i linjen
+CD short ok r 1=linjen har øy-flate, 0=ikke øy
+CD
+CD Bruk:
+CD ok = LN_TestOy(char *ginfo_linje);
+ ===========================================================================
+*/
+short LN_TestOy(char *ginfo_linje)
+{
+ if (strchr(ginfo_linje,'(') != NULL) return 1;
+
+ return 0;
+}
+
+
+/*
+AR-910918
+CH LN_FinnNavn Søk etter et SOSI-navn i navnetabelen
+CD =============================================================================
+CD Formål:
+CD Søker etter navnet i navnetabellen.
+CD (Ukjent navn blir ikke lagt inn i navnetabellen.)
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD char *streng i Peker til SOSI-navn. Avslutta av '\0'.
+CD short *navn_nr u Navnets linjenummer i navnetabellen
+CD short nivo r Antall prikker (0=ukjent navn, 1=gruppenavn, osv.)
+CD
+CD Bruk:
+CD nivo = LN_FinnNavn(pLn,streng,&neste,&navn_nr);
+ =============================================================================
+*/
+short LN_FinnNavn(LC_NAVNETABELL * pLn,char *navn,short *navn_nr)
+{
+ short nr = 0;
+
+ /* Utfør søket */
+ for (; nr < pLn->sAntNavn; nr++)
+ {
+ if (strncmp(navn,pLn->sosi[nr].szNavn,LC_MAX_SOSINAVN_LEN-1) == 0)
+ {
+ // Legger inn merke om at navnet er brukt
+ pLn->sosi[nr].bBrukt = true;
+
+ // Navnet er funnet, ==> returner
+ *navn_nr = nr;
+ return (pLn->sosi[nr].cNivo); /* Nivå */
+ }
+ }
+
+ return 0; /* Ukjent navn */
+}
+
+
+/*
+AR-910710
+CH LN_PakkNavn Søk etter navn, legg inn ukjent navn
+CD ==========================================================================
+CD Formål:
+CD Finner et SOSI-navn i navnetabellen. (Max LC_MAX_SOSINAVN_LEN tegn.)
+CD Hvis navnet er ukjent, blir det lagt inn i tabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD char *navn i SOSI-navn.
+CD short *ant_par u Antall parametre til dette navnet.
+CD LC_ANT_PAR_UKJENT (-1) = Ant. param. er ukjent.
+CD short *navn_nr u Navnenummer.
+CD short nivo r Antall prikker i navnet (1=gruppenavn, osv.)
+CD
+CD Bruk:
+CD type = LN_PakkNavn(pLn,navn,&navn_nr,&ant_par);
+ =============================================================================
+*/
+short LN_PakkNavn (LC_NAVNETABELL * pLn,char *navn,short *navn_nr,short *ant_par)
+{
+ char nivo,*cp;
+ short nr;
+ /* Utfør søket */
+ for (nr=0; nr < pLn->sAntNavn; nr++)
+ {
+ if (strncmp(navn,pLn->sosi[nr].szNavn,LC_MAX_SOSINAVN_LEN-1) == 0)
+ {
+ // Legger inn merke om at navnet er brukt
+ pLn->sosi[nr].bBrukt = true;
+
+ // Navnet er funnet, ==> returner
+ *ant_par = pLn->sosi[nr].ucAntPar;
+ *navn_nr = nr;
+ return (pLn->sosi[nr].cNivo); /* Nivå */
+ }
+ }
+
+ /* Er det plass i tabellen for et nytt navn? */
+ if (pLn->sAntNavn >= LC_MAX_NAVN) {
+ UT_FPRINTF(stderr,"Utskrift av navnetabellen:\n");
+ for (nr=0; nr < pLn->sAntNavn; nr++) {
+ UT_FPRINTF(stderr,"%s\n",LN_VisNavn(pLn,nr));
+ }
+ LC_Error(21,"(LN_PakkNavn)","");
+ exit (2);
+ }
+
+ /* ----- Nytt navn */
+ UT_StrCopy(pLn->sosi[pLn->sAntNavn].szNavn,navn,LC_MAX_SOSINAVN_LEN);
+ pLn->sosi[pLn->sAntNavn].ucAntPar = (unsigned char) LC_ANT_PAR_UKJENT;
+ *ant_par = LC_ANT_PAR_UKJENT;
+
+ /* Finn antall prikker */
+ nivo = 0;
+ cp = navn;
+ while (*cp == '.') {
+ nivo++;
+ cp++;
+ }
+ pLn->sosi[pLn->sAntNavn].cNivo = nivo;
+
+ // Legger inn merke om at navnet er brukt
+ pLn->sosi[pLn->sAntNavn].bBrukt = true;
+
+ *navn_nr = pLn->sAntNavn;
+
+ pLn->sAntNavn++;
+
+ /* Melding om ulovlig gruppestart */
+ if (nivo <= 1) {
+ LC_Error(22,"(LN_PakkNavn)",navn);
+ }
+
+ return (nivo); /* Antall prikker */
+}
+
+
+/*
+AR-910819
+CH LN_GetNavn Hent en linje fra navnetabellen
+CD ==========================================================================
+CD Formål:
+CD Henter et navn fra navnetabellen.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD long navn i Linjenummer i navnetabellen
+CD char *tx r Peker til SOSI-navn, NULL=ukjent linje
+CD
+CD Bruk:
+CD cp = LN_GetNavn(pLn,navn_nr);
+ =============================================================================
+*/
+char *LN_GetNavn(LC_NAVNETABELL * pLn,short navn)
+{
+ SOSINAVN *ip;
+
+ if (navn >= 0 && navn < pLn->sAntNavn){
+ ip = pLn->sosi + navn;
+ return ip->szNavn;
+ }
+
+ return NULL;
+}
+
+
+/*
+AR:2009-05-05
+CH LC_GetElementNavn Hent elementnavn
+CD ==========================================================================
+CD Formål:
+CD Hent et elementnavn fra den interne navnetabellen i FYBA.
+CD Denne tabellen inneholder både gruppenavn (.LINJE, .KURVE, ...) og
+CD egenskapsnavn (..OBJTYPE, ..LTEMA, ...)
+CD
+CD Tabellen har tre logiske deler:
+CD - (Linje 0 - L_HODE): Forhåndsdefinerte gruppenavn.
+CD - (Linje L_HODE+1 - L_KP): Forhåndsdefinerte egenskapsnavn.
+CD - (Linje L_KP+1 - n): Andre elementnavn brukt i SOSI-filen etter
+CD indeksoppbygging.
+CD
+CD Selv om egenskapen blir fjernet fra SOSI-filen blir navnet fortsatt
+CD liggende i navnetabellen
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD --------------------------------------------------------------------------
+CD LC_FILADM *pFil i Peker til FilAdm
+CD short sNavnNr i Linjenummer i navnetabellen (0 - n)
+CD bool *bBrukt Viser om navnet har/er brukt i filen
+CD Hvis det har vært en gruppe som har brukt navnet blir
+CD denne stående "true" selv om gruppen er slettet.
+CD const char *pszNavn r Peker til elementnavn,
+CD NULL = ukjent fil eller ulovlig linjenummer
+CD
+CD
+CD Bruk:
+CD // Går gjennom alle navnene ut over de forhåndsdefinerte navnene.
+CD short sNavnNr = L_KP+1;
+CD while ((pszNavn = LC_GetElementNavn(pFil,sNavnNr)) != NULL)
+CD {
+CD // Gjør noe med navnet
+CD ...
+CD ++sNavnNr;
+CD }
+=============================================================================
+*/
+SK_EntPnt_FYBA const char *LC_GetElementNavn(LC_FILADM *pFil,short sNavnNr,bool *bBrukt)
+{
+ LO_TestFilpeker(pFil,"GetNavn");
+
+ LC_NAVNETABELL *pLn = &(pFil->SosiNavn); //Peker til filens navnetabell
+
+ if (sNavnNr >= 0 && sNavnNr < pLn->sAntNavn)
+ {
+ SOSINAVN *ip = pLn->sosi + sNavnNr;
+
+ *bBrukt = ip->bBrukt;
+
+ return ip->szNavn;
+ }
+
+ return NULL;
+}
+
+
+/*
+AR-910819
+CH LN_VisNavn Hent en linje fra navnetabellen
+CD =============================================================================
+CD Formål:
+CD Henter en linje fra navnetabellen som formatert streng.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -----------------------------------------------------------------------------
+CD LC_NAVNETABELL * pLn i Peker til navnetabell
+CD long navn i Linjenummer i navnetabellen som skall vises
+CD char *tx r Peker til streng med formatert linje
+CD
+CD Bruk:
+CD for (navn=0,linje=10; navn<10; navn++,linje++){
+CD SH_OutTx(linje,1,LN_VisNavn(pLn,navn));
+CD }
+ =============================================================================
+*/
+char *LN_VisNavn(LC_NAVNETABELL * pLn,short navn)
+{
+ SOSINAVN *ip;
+
+ if (navn < pLn->sAntNavn){
+ ip = pLn->sosi + navn;
+ UT_SNPRINTF(err().tx,LC_ERR_LEN,"%2d %16s", navn,ip->szNavn);
+ } else{
+ *err().tx = '\0';
+ }
+
+ return err().tx;
+}
+
+
+/*
+AR-940413
+CH LN_TolkKvalitet Tolk KVALITET
+CD ==========================================================================
+CD Formål:
+CD Tolk parameterstrengen for KVALITET.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -------------------------------------------------------------------------
+CD char *pszParameter i Peker til '\0'-avslutta streng, eller
+CD NULL hvis KVALITET mangler.
+CD short *psMetode u Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long *plNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over.
+CD short *psSynbarhet u Synbarhet i bilde
+CD KVAL_SYN_GOD godt synlig.
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD KVAL_SYN_STD standard metode fra nivå over.
+CD short *psHoydeMetode u Hvordan høyden er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long *plHoydeNoyaktighet u Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over.
+CD
+CD Bruk:
+CD ist = LN_TolkKvalitet(pszParameter,&sMetode,&lNoyaktighet,&sSynbarhet,
+CD &sHoydeMetode,&lHoydeNoyaktighet);
+CD =============================================================================
+*/
+void LN_TolkKvalitet(char *pszParameter,short *psMetode,long *plNoyaktighet,
+ short *psSynbarhet,short *psHoydeMetode,long *plHoydeNoyaktighet)
+{
+ char ord[32];
+ short i;
+ char szMetode[6] = {"*"};
+ char szNoyaktighet[11] = {"*"};
+ char szSynbarhet[6] = {"0"};
+ char szHoydeMetode[6] = {" "};
+ char szHoydeNoyaktighet[11] = {" "};
+
+ /* Er det noen parameterstreng? */
+ if (pszParameter) {
+ /* Hent strengene */
+ if (UT_StrToken(pszParameter,0,&i,32,ord)) {
+ UT_StrCopy(szMetode,ord,6);
+
+ if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+ UT_StrCopy(szNoyaktighet,ord,10);
+
+ if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+ UT_StrCopy(szSynbarhet,ord,6);
+
+ if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+ UT_StrCopy(szHoydeMetode,ord,6);
+
+ if (UT_StrToken(pszParameter,i,&i,32,ord)) {
+ UT_StrCopy(szHoydeNoyaktighet,ord,10);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Tolk strengene til tallverdier */
+ if (*szMetode == '*') {
+ *psMetode = KVAL_MET_UNDEF;
+ } else if (*szMetode == '@') {
+ *psMetode = KVAL_MET_STD;
+ } else {
+ UT_StrShort(szMetode,0,&i,psMetode);
+ }
+
+ if (*szNoyaktighet == '*') {
+ *plNoyaktighet = KVAL_NOY_UKJENT;
+ } else if (*szNoyaktighet == '@') {
+ *plNoyaktighet = KVAL_NOY_STD;
+ } else {
+ UT_StrLong(szNoyaktighet,0,&i,plNoyaktighet);
+ }
+
+ if (*szSynbarhet == '*') {
+ *psSynbarhet = KVAL_SYN_UNDEF;
+ } else if (*szSynbarhet == '@') {
+ *psSynbarhet = KVAL_SYN_STD;
+ } else {
+ UT_StrShort(szSynbarhet,0,&i,psSynbarhet);
+ }
+
+ if (*szHoydeMetode == '*') {
+ *psHoydeMetode = KVAL_MET_UNDEF;
+ } else if (*szHoydeMetode == '@') {
+ *psHoydeMetode = KVAL_MET_STD;
+ } else if (*szHoydeMetode == ' ') {
+ *psHoydeMetode = *psMetode;
+ } else {
+ UT_StrShort(szHoydeMetode,0,&i,psHoydeMetode);
+ }
+
+ if (*szHoydeNoyaktighet == '*') {
+ *plHoydeNoyaktighet = KVAL_NOY_UKJENT;
+ } else if (*szHoydeNoyaktighet == '@') {
+ *plHoydeNoyaktighet = KVAL_NOY_STD;
+ } else if (*szHoydeNoyaktighet == ' ') {
+ *plHoydeNoyaktighet = *plNoyaktighet;
+ } else {
+ UT_StrLong(szHoydeNoyaktighet,0,&i,plHoydeNoyaktighet);
+ }
+
+ return;
+}
+
+
+/*
+AR-940413
+CH LC_FormatterKvalitet Formatter KVALITET
+CD ==========================================================================
+CD Formål:
+CD Formater parameterstrengen for KVALITET.
+CD Resultatet legges i en intern streng, og må kopieres over til andre
+CD variabler før endring.
+CD
+CD Parametre:
+CD Type Navn I/U Forklaring
+CD -------------------------------------------------------------------------
+CD short sMetode i Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long lNoyaktighet i Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over
+CD short sSynbarhet i Synbarhet i bilde
+CD KVAL_SYN_GOD godt synlig.
+CD KVAL_SYN_UNDEF synbarhet er udefinert.
+CD KVAL_SYN_STD standard metode fra nivå over.
+CD short sHoydeMetode i Hvordan data er registrert.
+CD KVAL_MET_UNDEF metode er udefinert.
+CD KVAL_MET_STD standard metode fra nivå over.
+CD long lHoydeNoyaktighet i Registreringsnøyaktighet
+CD KVAL_NOY_UKJENT nøyaktighet er ukjent.
+CD KVAL_NOY_STD standard nøyaktighet fra nivå over
+CD char *pszParameter r Peker til '\0'-avslutta streng.
+CD
+CD Bruk:
+CD pszParameter = LC_FormatterKvalitet(sMetode,lNoyaktighet,sSynbarhet,
+CD sHoydeMetode,lHoydeNoyaktighet);
+CD =============================================================================
+*/
+SK_EntPnt_FYBA char *LC_FormatterKvalitet(short sMetode,long lNoyaktighet,short sSynbarhet,
+ short sHoydeMetode,long lHoydeNoyaktighet)
+{
+ static char szParameter[60];
+ char szMetode[8] = {"*"};
+ char szNoyaktighet[13] = {" *"};
+ char szSynbarhet[8] = {" *"};
+ char szHoydeMetode[8] = {" *"};
+ char szHoydeNoyaktighet[13] = {" *"};
+
+
+ /* Metode */
+ if (sMetode == KVAL_MET_STD) {
+ *szMetode = '@';
+ } else if (sMetode != KVAL_MET_UNDEF) {
+ UT_SNPRINTF(szMetode,8,"%hd",sMetode);
+ }
+
+ /* Nøyaktighet */
+ if (lNoyaktighet == KVAL_NOY_STD) {
+ szNoyaktighet[1] = '@';
+ } else if (lNoyaktighet != KVAL_NOY_UKJENT && lNoyaktighet != KVAL_NOY_UNDEF) {
+ UT_SNPRINTF(szNoyaktighet,13," %ld",lNoyaktighet);
+ }
+
+ /* Synbarhet */
+ if (sSynbarhet == KVAL_SYN_STD) {
+ szSynbarhet[1] = '@';
+ } else if (sSynbarhet != KVAL_SYN_UNDEF) {
+ UT_SNPRINTF(szSynbarhet,8," %hd",sSynbarhet);
+ }
+
+ /* Høyde-metode */
+ if (sHoydeMetode == KVAL_MET_STD) {
+ szHoydeMetode[1] = '@';
+ } else if (sHoydeMetode != KVAL_MET_UNDEF) {
+ UT_SNPRINTF(szHoydeMetode,8," %hd",sHoydeMetode);
+ }
+
+ /* Høyde-nøyaktighet */
+ if (lHoydeNoyaktighet == KVAL_NOY_STD) {
+ szHoydeNoyaktighet[1] = '@';
+ } else if (lHoydeNoyaktighet != KVAL_NOY_UKJENT && lHoydeNoyaktighet != KVAL_NOY_UNDEF) {
+ UT_SNPRINTF(szHoydeNoyaktighet,13," %ld",lHoydeNoyaktighet);
+ }
+
+
+ /* Bygg opp parameterstrengen */
+
+ UT_StrCopy(szParameter,szMetode,60);
+
+ if (szNoyaktighet[1] != '*' ||
+ sSynbarhet != KVAL_SYN_GOD ||
+ sHoydeMetode != sMetode ||
+ lHoydeNoyaktighet != lNoyaktighet) {
+
+ UT_StrCat(szParameter,szNoyaktighet,60);
+
+ if (sSynbarhet != KVAL_SYN_GOD ||
+ sHoydeMetode != sMetode ||
+ lHoydeNoyaktighet != lNoyaktighet) {
+
+ UT_StrCat(szParameter,szSynbarhet,60);
+
+ if (sHoydeMetode != sMetode ||
+ lHoydeNoyaktighet != lNoyaktighet) {
+
+ UT_StrCat(szParameter,szHoydeMetode,60);
+
+ if (lHoydeNoyaktighet != lNoyaktighet) {
+ UT_StrCat(szParameter,szHoydeNoyaktighet,60);
+ }
+ }
+ }
+ }
+
+ return szParameter;
+}
+
+
+/*
+AR: 2000-01-19
+CH LC_FinnNivo Beregn nivå
+CD ==============================================================
+CD Formål:
+CD Teller antall prikker i starten på egenskapsnavn.
+CD
+CD PARAMETERLISTE:
+CD Type Navn I/U Merknad
+CD -------------------------------------------------------------
+CD char *pszGinfo i Streng med egenskapsnavn i starten
+CD short sNivo r Antall prikker
+CD
+CD Bruk:
+CD sNivo = LC_FinnNivo(pszGinfo);
+ ================================================================
+*/
+SK_EntPnt_FYBA short LC_FinnNivo(const char * pszNavn)
+{
+ short sNivo = 0;
+
+ while (*pszNavn != '\0' && *pszNavn == '.') {
+ ++pszNavn;
+ ++sNivo;
+ }
+
+ return sNivo;
+}
diff --git a/src/FYBA/make.sh b/src/FYBA/make.sh
new file mode 100755
index 0000000..eebd5cc
--- /dev/null
+++ b/src/FYBA/make.sh
@@ -0,0 +1,5 @@
+gcc -Wall -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -DI18N_EN -Wno-write-strings -c -I. -I../include *.cpp &&
+ar rcs libfyba.a *.o &&
+gcc -g -D_FILE_OFFSET_BITS=64 -DUNIX -DLINUX -fPIC -DI18N_EN -Wno-write-strings -shared -I. -I../include *.cpp -o ../../lib/libfyba.so
+cp fyba.h ../../include/fyba.h
+
diff --git a/src/FYBA/stdafx.cpp b/src/FYBA/stdafx.cpp
new file mode 100644
index 0000000..cc5aa89
--- /dev/null
+++ b/src/FYBA/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// FYBA.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/src/FYBA/stdafx.h b/src/FYBA/stdafx.h
new file mode 100644
index 0000000..ddc5b6f
--- /dev/null
+++ b/src/FYBA/stdafx.h
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <../UT/fyut.h>
+#include <../GM/fygm.h>
+
+#include "fyba.h"
+#include "fybax.h"