Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGRMiraMonDriver class.
5 : * Author: Abel Pau
6 : ******************************************************************************
7 : * Copyright (c) 2024, Xavier Pons
8 : *
9 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice shall be included
17 : * in all copies or substantial portions of the Software.
18 : *
19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 : * DEALINGS IN THE SOFTWARE.
26 : ****************************************************************************/
27 :
28 : #include "ogrmiramon.h"
29 :
30 : /****************************************************************************/
31 : /* OGRMMDriverIdentify() */
32 : /****************************************************************************/
33 :
34 40538 : static int OGRMiraMonDriverIdentify(GDALOpenInfo *poOpenInfo)
35 :
36 : {
37 40538 : if (poOpenInfo->fpL == nullptr || poOpenInfo->nHeaderBytes < 7)
38 39786 : return FALSE;
39 752 : else if (EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "PNT") ||
40 1359 : EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "ARC") ||
41 607 : EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "POL"))
42 : {
43 : // Format
44 239 : if ((poOpenInfo->pabyHeader[0] == 'P' &&
45 179 : poOpenInfo->pabyHeader[1] == 'N' &&
46 85 : poOpenInfo->pabyHeader[2] == 'T') ||
47 154 : (poOpenInfo->pabyHeader[0] == 'A' &&
48 60 : poOpenInfo->pabyHeader[1] == 'R' &&
49 60 : poOpenInfo->pabyHeader[2] == 'C') ||
50 94 : (poOpenInfo->pabyHeader[0] == 'P' &&
51 94 : poOpenInfo->pabyHeader[1] == 'O' &&
52 94 : poOpenInfo->pabyHeader[2] == 'L'))
53 : {
54 : // Version 1.1 or 2.0
55 239 : if ((poOpenInfo->pabyHeader[3] == ' ' &&
56 239 : poOpenInfo->pabyHeader[4] == '1' &&
57 224 : poOpenInfo->pabyHeader[5] == '.' &&
58 224 : poOpenInfo->pabyHeader[6] == '1') ||
59 15 : (poOpenInfo->pabyHeader[3] == ' ' &&
60 15 : poOpenInfo->pabyHeader[4] == '2' &&
61 12 : poOpenInfo->pabyHeader[5] == '.' &&
62 12 : poOpenInfo->pabyHeader[6] == '0'))
63 : {
64 236 : return TRUE;
65 : }
66 : }
67 : }
68 :
69 516 : return FALSE;
70 : }
71 :
72 : /****************************************************************************/
73 : /* OGRMiraMonDriverOpen() */
74 : /****************************************************************************/
75 :
76 118 : static GDALDataset *OGRMiraMonDriverOpen(GDALOpenInfo *poOpenInfo)
77 :
78 : {
79 118 : if (OGRMiraMonDriverIdentify(poOpenInfo) == FALSE)
80 0 : return nullptr;
81 :
82 236 : auto poDS = std::make_unique<OGRMiraMonDataSource>();
83 236 : if (!poDS->Open(poOpenInfo->pszFilename, nullptr, nullptr,
84 118 : poOpenInfo->papszOpenOptions))
85 : {
86 8 : poDS.reset();
87 : }
88 :
89 118 : if (poDS && poOpenInfo->eAccess == GA_Update)
90 : {
91 0 : CPLError(CE_Failure, CPLE_OpenFailed,
92 : "MiraMonVector driver does not support update.");
93 0 : return nullptr;
94 : }
95 :
96 118 : return poDS.release();
97 : }
98 :
99 : /****************************************************************************/
100 : /* OGRMiraMonDriverCreate() */
101 : /****************************************************************************/
102 :
103 : static GDALDataset *
104 66 : OGRMiraMonDriverCreate(const char *pszName, CPL_UNUSED int /*nBands*/,
105 : CPL_UNUSED int /*nXSize*/, CPL_UNUSED int /*nYSize*/,
106 : CPL_UNUSED GDALDataType /*eDT*/, char **papszOptions)
107 : {
108 132 : auto poDS = std::make_unique<OGRMiraMonDataSource>();
109 :
110 66 : if (!poDS->Create(pszName, papszOptions))
111 : {
112 0 : poDS.reset();
113 : }
114 :
115 132 : return poDS.release();
116 : }
117 :
118 : /****************************************************************************/
119 : /* RegisterOGRMM() */
120 : /****************************************************************************/
121 :
122 1523 : void RegisterOGRMiraMon()
123 :
124 : {
125 1523 : if (GDALGetDriverByName("MiraMonVector") != nullptr)
126 301 : return;
127 :
128 1222 : GDALDriver *poDriver = new GDALDriver();
129 1222 : poDriver->SetDescription("MiraMonVector");
130 1222 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
131 1222 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
132 1222 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
133 1222 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
134 1222 : "MiraMon Vectors (.pol, .arc, .pnt)");
135 1222 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "pol arc pnt");
136 1222 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC,
137 1222 : "drivers/vector/miramon.html");
138 1222 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
139 1222 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
140 :
141 1222 : poDriver->SetMetadataItem(
142 : GDAL_DMD_OPENOPTIONLIST,
143 : "<OpenOptionList>"
144 : " <Option name='Height' scope='vector' type='string-select' "
145 : " description='Sets which of the possible heights is chosen: "
146 : "the first, the highest or the lowest one.'>"
147 : " <Value>First</Value>"
148 : " <Value>Lowest</Value>"
149 : " <Value>Highest</Value>"
150 : " </Option>"
151 : " <Option name='MultiRecordIndex' scope='vector' type='string' "
152 : " description='Sets which of the possible records is chosen: "
153 : "0, 1, 2,... or the Last one. Use JSON when a serialized "
154 : "JSON is wanted'>"
155 : " </Option>"
156 : " <Option name='OpenLanguage' scope='vector' type='string-select' "
157 : " description='If the layer to be opened is multilingual "
158 : "(in fact the *.rel* file), this parameter sets the language "
159 : "to be read.'>"
160 : " <Value>ENG</Value>"
161 : " <Value>CAT</Value>"
162 : " <Value>SPA</Value>"
163 : " </Option>"
164 1222 : "</OpenOptionList>");
165 :
166 1222 : poDriver->SetMetadataItem(
167 : GDAL_DS_LAYER_CREATIONOPTIONLIST,
168 : "<LayerCreationOptionList>"
169 : " <Option name='Version' type='string-select' description='Version of "
170 : "the file. "
171 : "V1.1 is a limited 32 bits for FID and for internal offsets. "
172 : "V2.0 is the 64 bits version, with practically no limits for FID nor "
173 : "for internal offsets.' "
174 : "default='last_version'>"
175 : "<Value>V1.1</Value>"
176 : "<Value>V2.0</Value>"
177 : "<Value>last_version</Value>"
178 : "</Option>"
179 : " <Option name='DBFEncoding' type='string-select' "
180 : "description='Encoding of "
181 : "the "
182 : ".dbf files."
183 : "MiraMon can write *.dbf* files in these two charsets.' "
184 : "default='ANSI'>"
185 : "<Value>UTF8</Value>"
186 : "<Value>ANSI</Value>"
187 : "</Option>"
188 : " <Option name='CreationLanguage' scope='vector' type='string-select' "
189 : " description='If the layer to be opened is multilingual "
190 : "(in fact the *.rel* file), this parameter sets the language "
191 : "to be read.'>"
192 : " <Value>ENG</Value>"
193 : " <Value>CAT</Value>"
194 : " <Value>SPA</Value>"
195 : " </Option>"
196 1222 : "</LayerCreationOptionList>");
197 :
198 1222 : poDriver->SetMetadataItem(
199 : GDAL_DMD_CREATIONFIELDDATATYPES,
200 : "Integer Integer64 Real String Date Time "
201 1222 : "Binary IntegerList Integer64List RealList StringList");
202 1222 : poDriver->pfnOpen = OGRMiraMonDriverOpen;
203 1222 : poDriver->pfnIdentify = OGRMiraMonDriverIdentify;
204 1222 : poDriver->pfnCreate = OGRMiraMonDriverCreate;
205 :
206 1222 : GetGDALDriverManager()->RegisterDriver(poDriver);
207 : }
|