Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGRVFKDatasource class.
5 : * Author: Martin Landa, landa.martin gmail.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2009-2010, 2013-2018 Martin Landa <landa.martin gmail.com>
9 : *
10 : * Permission is hereby granted, free of charge, to any person
11 : * obtaining a copy of this software and associated documentation
12 : * files (the "Software"), to deal in the Software without
13 : * restriction, including without limitation the rights to use, copy,
14 : * modify, merge, publish, distribute, sublicense, and/or sell copies
15 : * of the Software, and to permit persons to whom the Software is
16 : * furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be
19 : * included in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
25 : * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
26 : * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 : * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 : * SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "ogr_vfk.h"
32 : #include "cpl_conv.h"
33 : #include "cpl_string.h"
34 :
35 : /*!
36 : \brief OGRVFKDataSource constructor
37 : */
38 17 : OGRVFKDataSource::OGRVFKDataSource()
39 17 : : papoLayers(nullptr), nLayers(0), pszName(nullptr), poReader(nullptr)
40 : {
41 17 : }
42 :
43 : /*!
44 : \brief OGRVFKDataSource destructor
45 : */
46 34 : OGRVFKDataSource::~OGRVFKDataSource()
47 : {
48 17 : CPLFree(pszName);
49 :
50 17 : if (poReader)
51 17 : delete poReader;
52 :
53 993 : for (int i = 0; i < nLayers; i++)
54 976 : delete papoLayers[i];
55 :
56 17 : CPLFree(papoLayers);
57 34 : }
58 :
59 : /*!
60 : \brief Open VFK datasource
61 :
62 : \param poOpenInfo open info
63 :
64 : \return TRUE on success or FALSE on failure
65 : */
66 17 : int OGRVFKDataSource::Open(GDALOpenInfo *poOpenInfo)
67 : {
68 17 : pszName = CPLStrdup(poOpenInfo->pszFilename);
69 :
70 : /* create VFK reader */
71 17 : poReader = CreateVFKReader(poOpenInfo);
72 17 : if (poReader == nullptr || !poReader->IsValid())
73 : {
74 : /*
75 : CPLError(CE_Failure, CPLE_AppDefined,
76 : "File %s appears to be VFK but the VFK reader can't"
77 : "be instantiated",
78 : pszFileName);
79 : */
80 1 : return FALSE;
81 : }
82 :
83 : bool bSuppressGeometry =
84 16 : CPLFetchBool(poOpenInfo->papszOpenOptions, "SUPPRESS_GEOMETRY", false);
85 : /* read data blocks, i.e. &B */
86 16 : poReader->ReadDataBlocks(bSuppressGeometry);
87 :
88 : /* get list of layers */
89 32 : papoLayers = (OGRVFKLayer **)CPLCalloc(sizeof(OGRVFKLayer *),
90 16 : poReader->GetDataBlockCount());
91 :
92 : /* create layers from VFK blocks */
93 992 : for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); iLayer++)
94 : {
95 1952 : papoLayers[iLayer] =
96 976 : CreateLayerFromBlock(poReader->GetDataBlock(iLayer));
97 976 : nLayers++;
98 : }
99 :
100 16 : if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_READ_ALL_BLOCKS", "YES")))
101 : {
102 : /* read data records if requested */
103 16 : poReader->ReadDataRecords();
104 :
105 16 : if (!bSuppressGeometry)
106 : {
107 930 : for (int iLayer = 0; iLayer < poReader->GetDataBlockCount();
108 : iLayer++)
109 : {
110 : /* load geometry */
111 915 : poReader->GetDataBlock(iLayer)->LoadGeometry();
112 : }
113 : }
114 : }
115 :
116 16 : return TRUE;
117 : }
118 :
119 : /*!
120 : \brief Get VFK layer
121 :
122 : \param iLayer layer number
123 :
124 : \return pointer to OGRLayer instance or NULL on error
125 : */
126 147 : OGRLayer *OGRVFKDataSource::GetLayer(int iLayer)
127 : {
128 147 : if (iLayer < 0 || iLayer >= nLayers)
129 0 : return nullptr;
130 :
131 147 : return papoLayers[iLayer];
132 : }
133 :
134 : /*!
135 : \brief Test datasource capabilities
136 :
137 : \param pszCap capability
138 :
139 : \return TRUE if supported or FALSE if not supported
140 : */
141 0 : int OGRVFKDataSource::TestCapability(const char *pszCap)
142 : {
143 0 : if (EQUAL(pszCap, "IsPreProcessed") && poReader)
144 : {
145 0 : if (poReader->IsPreProcessed())
146 0 : return TRUE;
147 : }
148 :
149 0 : return FALSE;
150 : }
151 :
152 : /*!
153 : \brief Create OGR layer from VFKDataBlock
154 :
155 : \param poDataBlock pointer to VFKDataBlock instance
156 :
157 : \return pointer to OGRVFKLayer instance or NULL on error
158 : */
159 : OGRVFKLayer *
160 976 : OGRVFKDataSource::CreateLayerFromBlock(const IVFKDataBlock *poDataBlock)
161 : {
162 : /* create an empty layer */
163 : OGRVFKLayer *poLayer = new OGRVFKLayer(
164 976 : poDataBlock->GetName(), nullptr, poDataBlock->GetGeometryType(), this);
165 :
166 : /* define attributes (properties) */
167 10208 : for (int iField = 0; iField < poDataBlock->GetPropertyCount(); iField++)
168 : {
169 9232 : VFKPropertyDefn *poProperty = poDataBlock->GetProperty(iField);
170 18464 : OGRFieldDefn oField(poProperty->GetName(), poProperty->GetType());
171 :
172 9232 : if (poProperty->GetWidth() > 0)
173 9232 : oField.SetWidth(poProperty->GetWidth());
174 9232 : if (poProperty->GetPrecision() > 0)
175 480 : oField.SetPrecision(poProperty->GetPrecision());
176 :
177 9232 : poLayer->GetLayerDefn()->AddFieldDefn(&oField);
178 : }
179 :
180 976 : if (poDataBlock->GetReader()->HasFileField())
181 : {
182 : /* open option FILE_FIELD=YES specified, append extra
183 : * attribute */
184 122 : OGRFieldDefn oField(FILE_COLUMN, OFTString);
185 61 : oField.SetWidth(255);
186 61 : poLayer->GetLayerDefn()->AddFieldDefn(&oField);
187 : }
188 :
189 976 : return poLayer;
190 : }
|