1 : /******************************************************************************
2 : * $Id: ogrvfkdatasource.cpp 18467 2010-01-07 21:02:07Z martinl $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRVFKDatasource class.
6 : * Author: Martin Landa, landa.martin gmail.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2009-2010, Martin Landa <landa.martin gmail.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person
12 : * obtaining a copy of this software and associated documentation
13 : * files (the "Software"), to deal in the Software without
14 : * restriction, including without limitation the rights to use, copy,
15 : * modify, merge, publish, distribute, sublicense, and/or sell copies
16 : * of the Software, and to permit persons to whom the Software is
17 : * furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be
20 : * included in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26 : * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 : * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 : * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : * SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "ogr_vfk.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 :
36 : CPL_CVSID("$Id:");
37 :
38 : /*!
39 : \brief OGRVFKDataSource constructor
40 : */
41 3 : OGRVFKDataSource::OGRVFKDataSource()
42 : {
43 3 : pszName = NULL;
44 :
45 3 : poReader = NULL;
46 :
47 3 : papoLayers = NULL;
48 3 : nLayers = 0;
49 3 : }
50 :
51 : /*!
52 : \brief OGRVFKDataSource destructor
53 : */
54 6 : OGRVFKDataSource::~OGRVFKDataSource()
55 : {
56 3 : CPLFree(pszName);
57 :
58 3 : if (poReader)
59 1 : delete poReader;
60 :
61 64 : for(int i = 0; i < nLayers; i++)
62 61 : delete papoLayers[i];
63 :
64 3 : CPLFree(papoLayers);
65 6 : }
66 :
67 : /*!
68 : \brief Open VFK datasource
69 :
70 : \param pszNewName datasource name
71 : \param bTextOpen True to test if datasource is possible to open
72 :
73 : \return TRUE on success
74 : \return FALSE on failure
75 : */
76 3 : int OGRVFKDataSource::Open(const char *pszNewName, int bTestOpen)
77 : {
78 : FILE * fp;
79 : char szHeader[1000];
80 :
81 : /* open the source file */
82 3 : fp = VSIFOpen(pszNewName, "r");
83 3 : if (fp == NULL) {
84 2 : if (!bTestOpen)
85 : CPLError(CE_Failure, CPLE_OpenFailed,
86 : "Failed to open VFK file `%s'.",
87 0 : pszNewName);
88 :
89 2 : return FALSE;
90 : }
91 :
92 : /* If we aren't sure it is VFK, load a header chunk and check
93 : for signs it is VFK */
94 1 : if (bTestOpen) {
95 1 : size_t nRead = VSIFRead(szHeader, 1, sizeof(szHeader), fp);
96 1 : if (nRead <= 0) {
97 0 : VSIFClose(fp);
98 0 : return FALSE;
99 : }
100 1 : szHeader[MIN(nRead, sizeof(szHeader))-1] = '\0';
101 :
102 : // TODO: improve check
103 1 : if (strncmp(szHeader, "&HVERZE;", 8) != 0) {
104 0 : VSIFClose(fp);
105 0 : return FALSE;
106 : }
107 : }
108 :
109 : /* We assume now that it is VFK. Close and instantiate a
110 : VFKReader on it. */
111 1 : VSIFClose(fp);
112 :
113 1 : pszName = CPLStrdup(pszNewName);
114 :
115 1 : poReader = CreateVFKReader();
116 1 : if (poReader == NULL) {
117 : CPLError(CE_Failure, CPLE_AppDefined,
118 : "File %s appears to be VFK but the VFK reader can't"
119 : "be instantiated.",
120 0 : pszNewName );
121 0 : return FALSE;
122 : }
123 : /* load data (whole file) */
124 1 : poReader->SetSourceFile(pszNewName);
125 1 : poReader->LoadData();
126 :
127 : /* get data blocks, i.e. &B */
128 1 : poReader->LoadDataBlocks();
129 : /* collect geometry properties
130 : load on first request
131 : */
132 : /* poReader->LoadGeometry(); */
133 :
134 : /* get list of layers */
135 1 : papoLayers = (OGRVFKLayer **) CPLCalloc(sizeof(OGRVFKLayer *), poReader->GetDataBlockCount());
136 :
137 62 : for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); iLayer++) {
138 61 : papoLayers[iLayer] = CreateLayer(poReader->GetDataBlock(iLayer));
139 61 : nLayers++;
140 : }
141 :
142 1 : return TRUE;
143 : }
144 :
145 : /*!
146 : \brief Get VFK layer
147 :
148 : \param iLayer layer number
149 :
150 : \return pointer to OGRLayer instance
151 : \return NULL on error
152 : */
153 2 : OGRLayer *OGRVFKDataSource::GetLayer(int iLayer)
154 : {
155 2 : if( iLayer < 0 || iLayer >= nLayers )
156 0 : return NULL;
157 :
158 2 : return papoLayers[iLayer];
159 : }
160 :
161 : /*!
162 : \brief Test datasource capabilies
163 :
164 : \param pszCap capability
165 :
166 : \return True if supported
167 : \return False if not supported
168 : */
169 0 : int OGRVFKDataSource::TestCapability(const char * pszCap)
170 : {
171 0 : return FALSE;
172 : }
173 :
174 : /*!
175 : \brief Create OGR layer from VFKDataBlock
176 :
177 : \param poDataBlock pointer to VFKDataBlock instance
178 :
179 : \return poiter to OGRVFKLayer instance
180 : \return NULL on error
181 : */
182 61 : OGRVFKLayer *OGRVFKDataSource::CreateLayer(const VFKDataBlock *poDataBlock)
183 : {
184 : OGRVFKLayer *poLayer;
185 :
186 61 : poLayer = NULL;
187 :
188 : /* create an empty layer */
189 : poLayer = new OGRVFKLayer(poDataBlock->GetName(), NULL,
190 61 : poDataBlock->GetGeometryType(), this);
191 :
192 : /* define attributes (properties) */
193 636 : for (int iField = 0; iField < poDataBlock->GetPropertyCount(); iField++) {
194 575 : VFKPropertyDefn *poProperty = poDataBlock->GetProperty(iField);
195 575 : OGRFieldDefn oField(poProperty->GetName(), poProperty->GetType());
196 :
197 575 : if(poProperty->GetWidth() > 0)
198 476 : oField.SetWidth(poProperty->GetWidth());
199 575 : if(poProperty->GetPrecision() > 0)
200 30 : oField.SetPrecision(poProperty->GetPrecision());
201 :
202 575 : poLayer->GetLayerDefn()->AddFieldDefn(&oField);
203 : }
204 :
205 61 : return poLayer;
206 : }
207 :
208 : /*!
209 : \brief Get info
210 :
211 : \param key key
212 :
213 : \return value (string)
214 : \return NULL if not found
215 : */
216 0 : const char *OGRVFKDataSource::GetInfo(const char *key)
217 : {
218 0 : return poReader->GetInfo(key);
219 : }
|