~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to ogr/ogrsf_frmts/sosi/ogrsosidatasource.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: ogrsosidatasource.cpp 21065 2010-11-05 18:47:30Z rouault $
 
3
 *
 
4
 * Project:  SOSI Data Source
 
5
 * Purpose:  Provide SOSI Data to OGR.
 
6
 * Author:   Thomas Hirsch, <thomas.hirsch statkart no>
 
7
 *
 
8
 ******************************************************************************
 
9
 * Copyright (c) 2010, Thomas Hirsch
 
10
 *
 
11
 * Permission is hereby granted, free of charge, to any person obtaining a
 
12
 * copy of this software and associated documentation files (the "Software"),
 
13
 * to deal in the Software without restriction, including without limitation
 
14
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
15
 * and/or sell copies of the Software, and to permit persons to whom the
 
16
 * Software is furnished to do so, subject to the following conditions:
 
17
 *
 
18
 * The above copyright notice and this permission notice shall be included
 
19
 * in all copies or substantial portions of the Software.
 
20
 *
 
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
24
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
26
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
27
 * DEALINGS IN THE SOFTWARE.
 
28
 ****************************************************************************/
 
29
 
 
30
#include "ogr_sosi.h"
 
31
#include <map>
 
32
 
 
33
/* This is the most common encoding for SOSI files. Let's at least try if
 
34
 * it is supported, or generate a meaningful error message.               */
 
35
#ifndef CPL_ENC_ISO8859_10
 
36
#  define CPL_ENC_ISO8859_10 "ISO8859-10"
 
37
#endif
 
38
 
 
39
/************************************************************************/
 
40
/*                              utility methods                         */
 
41
/************************************************************************/
 
42
 
 
43
int epsg2sosi (int nEPSG) {
 
44
    int nSOSI = 23;
 
45
    switch (nEPSG) {
 
46
        case 27391: /* NGO 1984 Axis I-VIII */
 
47
        case 27392:
 
48
        case 27393:
 
49
        case 27394:
 
50
        case 27395:
 
51
        case 27396:
 
52
        case 27397:
 
53
        case 27398: {
 
54
            nSOSI = nEPSG - 27390;
 
55
            break;
 
56
        }
 
57
        case 3043: /* UTM ZONE 31-36 */
 
58
        case 3044:
 
59
        case 3045:
 
60
        case 3046:
 
61
        case 3047:
 
62
        case 3048: {
 
63
            nSOSI = nEPSG - 3022;
 
64
            break;
 
65
        }
 
66
        case 23031: /* UTM ZONE 31-36 / ED50 */
 
67
        case 23032:
 
68
        case 23033:
 
69
        case 23034:
 
70
        case 23035:
 
71
        case 23036: {
 
72
            nSOSI = nEPSG - 23000;
 
73
            break;
 
74
        }
 
75
        case 4326: { /* WSG84 */
 
76
            nSOSI = 84;
 
77
            break;
 
78
        }
 
79
        default: {
 
80
            CPLError( CE_Warning, CPLE_AppDefined, 
 
81
                      "(Yet) unsupported coodinate system writing to SOSI file: %i. Defaulting to EPSG:4326/SOSI 84.", nEPSG);
 
82
            }
 
83
    }
 
84
    return nSOSI;
 
85
}
 
86
 
 
87
int sosi2epsg (int nSOSI) {
 
88
    int nEPSG = 4326;
 
89
    switch (nSOSI) {
 
90
        case 1: /* NGO 1984 Axis I-VIII */
 
91
        case 2:
 
92
        case 3:
 
93
        case 4:
 
94
        case 5:
 
95
        case 6:
 
96
        case 7:
 
97
        case 8: {
 
98
            nEPSG = 27390+nSOSI;
 
99
            break;
 
100
        }
 
101
        case 21: /* UTM ZONE 31-36 */
 
102
        case 22:
 
103
        case 23:
 
104
        case 24:
 
105
        case 25:
 
106
        case 26: {
 
107
            nEPSG = 3022+nSOSI;
 
108
            break;
 
109
        }
 
110
        case 31: /* UTM ZONE 31-36 / ED50 */
 
111
        case 32:
 
112
        case 33:
 
113
        case 34:
 
114
        case 35:
 
115
        case 36: {
 
116
            nEPSG = 23000+nSOSI;
 
117
            break;
 
118
        }
 
119
        case 84: { /* WSG84 */
 
120
            nEPSG = 4326;
 
121
            break;
 
122
        }
 
123
        default: {
 
124
            CPLError( CE_Warning, CPLE_AppDefined, 
 
125
                      "(Yet) unsupported coodinate system in SOSI-file: %i. Defaulting to EPSG:4326.", nSOSI);
 
126
        }
 
127
    }
 
128
    return nEPSG;
 
129
}
 
130
 
 
131
/************************************************************************/
 
132
/*                              OGRSOSIDataSource()                     */
 
133
/************************************************************************/
 
134
 
 
135
OGRSOSIDataSource::OGRSOSIDataSource() {
 
136
    nLayers = 0;
 
137
    
 
138
    poFileadm = NULL;
 
139
    poBaseadm = NULL;
 
140
    papoBuiltGeometries = NULL;
 
141
    papoLayers = NULL;
 
142
    pszName = NULL;
 
143
    poSRS = NULL;
 
144
    
 
145
    poPolyHeaders = NULL;
 
146
    poTextHeaders = NULL;
 
147
    poPointHeaders = NULL;
 
148
    poCurveHeaders = NULL;
 
149
    
 
150
    pszEncoding = CPL_ENC_UTF8;
 
151
}
 
152
 
 
153
/************************************************************************/
 
154
/*                              ~OGRSOSIDataSource()                    */
 
155
/************************************************************************/
 
156
 
 
157
OGRSOSIDataSource::~OGRSOSIDataSource() {
 
158
    if (papoBuiltGeometries != NULL) {
 
159
        for (unsigned int i=0; i<nNumFeatures; i++) {
 
160
            if (papoBuiltGeometries[i] != NULL) {
 
161
                delete papoBuiltGeometries[i];
 
162
                papoBuiltGeometries[i] = NULL;
 
163
            }
 
164
        }
 
165
        CPLFree(papoBuiltGeometries);
 
166
        papoBuiltGeometries = NULL;
 
167
    }
 
168
 
 
169
    if (poPolyHeaders  != NULL) delete poPolyHeaders;
 
170
    if (poTextHeaders  != NULL) delete poTextHeaders; 
 
171
    if (poPointHeaders != NULL) delete poPointHeaders;
 
172
    if (poCurveHeaders != NULL) delete poCurveHeaders; 
 
173
 
 
174
    if (nMode == MODE_WRITING) {
 
175
        if (poFileadm != NULL) LC_CloseSos  (poFileadm, RESET_IDX );
 
176
        if (poBaseadm != NULL) LC_CloseBase (poBaseadm, RESET_IDX );
 
177
    } else {
 
178
        if (poFileadm != NULL) LC_CloseSos  (poFileadm, SAVE_IDX );
 
179
        if (poBaseadm != NULL) LC_CloseBase (poBaseadm, SAVE_IDX );
 
180
    }
 
181
    poFileadm = NULL;
 
182
    poBaseadm = NULL;
 
183
 
 
184
    if (papoLayers != NULL) {
 
185
        for ( int i = 0; i < nLayers; i++ ) {
 
186
            delete papoLayers[i];
 
187
        }
 
188
        CPLFree(papoLayers);
 
189
    }
 
190
    
 
191
    if (poSRS != NULL) poSRS->Release();
 
192
    if (pszName != NULL) CPLFree(pszName);
 
193
}
 
194
 
 
195
OGRFeatureDefn *defineLayer(char *szName, OGRwkbGeometryType szType, S2I *poHeaders) {
 
196
    OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn( szName );
 
197
    poFeatureDefn->SetGeomType( szType );
 
198
    
 
199
    for (unsigned int n=0; n<poHeaders->size(); n++) { /* adding headers in the correct order again */
 
200
        for (S2I::iterator i=poHeaders->begin(); i!=poHeaders->end(); i++) {
 
201
            if (n==i->second) {
 
202
                OGRFieldDefn oFieldTemplate( i->first.c_str(), OFTString );
 
203
                poFeatureDefn->AddFieldDefn( &oFieldTemplate );
 
204
            }
 
205
        }
 
206
    }
 
207
    return poFeatureDefn;
 
208
}
 
209
 
 
210
/************************************************************************/
 
211
/*                              Open()                                  */
 
212
/************************************************************************/
 
213
 
 
214
int  OGRSOSIDataSource::Open( const char *pszFilename, int bUpdate ) {
 
215
    papoBuiltGeometries = NULL;
 
216
    poFileadm = NULL;
 
217
    poBaseadm = NULL;
 
218
    char *pszPos;
 
219
 
 
220
    if ( bUpdate ) {
 
221
        CPLError( CE_Failure, CPLE_OpenFailed,
 
222
                  "Update access not supported by the SOSI driver." );
 
223
        return FALSE;
 
224
    }
 
225
 
 
226
    pszName = CPLStrdup( pszFilename );
 
227
    /* We ignore any layer parameters for now. */
 
228
    pszPos = strchr(pszName, ',');
 
229
    if (pszPos != NULL) {
 
230
        pszPos[0] = '\0';
 
231
    }
 
232
 
 
233
    /* Confirm that we are dealing with a SOSI file. Used also by data
 
234
     * format auto-detection in some ogr utilities. */
 
235
    UT_INT64 nEnd = 0;
 
236
    int bIsSosi = HO_TestSOSI ( pszName, &nEnd );
 
237
    if ( bIsSosi == UT_FALSE ) {
 
238
        return FALSE; /* No error message: This is used by file format auto-detection */
 
239
    }
 
240
 
 
241
    short nStatus = 0, nDetStatus = 0; /* immediate status, detailed status */
 
242
 
 
243
    /* open index base and sosi file */
 
244
    poBaseadm = LC_OpenBase(LC_BASE);
 
245
    nStatus   = LC_OpenSos(pszName, LC_BASE_FRAMGR, LC_GML_IDX, LC_INGEN_STATUS,
 
246
                           &poFileadm, &nDetStatus);
 
247
    if ( nStatus == UT_FALSE ) {
 
248
        char *pszErrorMessage;
 
249
        LC_StrError(nDetStatus, &pszErrorMessage);
 
250
        CPLError( CE_Failure, CPLE_OpenFailed,
 
251
                  "File %s could not be opened by SOSI Driver: %s", pszName, pszErrorMessage );
 
252
        return FALSE;
 
253
    }
 
254
 
 
255
    /* --------------------------------------------------------------------*
 
256
     *      Prefetch all the information needed to determine layers        *
 
257
     *      and prebuild LineString features for later assembly.           *
 
258
     * --------------------------------------------------------------------*/
 
259
 
 
260
    /* allocate room for one pointer per feature */
 
261
    nNumFeatures = poFileadm->lAntGr;
 
262
    void* mem = VSIMalloc2(nNumFeatures, sizeof(void*));
 
263
    if (mem == NULL) {
 
264
        CPLError( CE_Failure, CPLE_OpenFailed,
 
265
                  "Memory allocation for SOSI features failed." );
 
266
        return FALSE;
 
267
    } else {
 
268
        papoBuiltGeometries = (OGRGeometry**)mem;
 
269
    }
 
270
    for (unsigned int i=0; i<nNumFeatures; i++) papoBuiltGeometries[i] = NULL;
 
271
 
 
272
    /* Various iterators and return values used to iterate through SOSI features */
 
273
    short          nName, nNumLines;
 
274
    long           nNumCoo;
 
275
    unsigned short nInfo;
 
276
    LC_SNR_ADM     oSnradm;
 
277
    LC_BGR                 oNextSerial;
 
278
    LC_BGR                *poNextSerial;
 
279
    poNextSerial =&oNextSerial;
 
280
 
 
281
    bool bPointLayer = FALSE; /* Initialize four layers for the different geometry types */
 
282
    bool bCurveLayer = FALSE;
 
283
    bool bPolyLayer  = FALSE;
 
284
    bool bTextLayer  = FALSE;
 
285
    poPolyHeaders  = new S2I();
 
286
    poPointHeaders = new S2I();
 
287
    poCurveHeaders = new S2I();
 
288
    poTextHeaders  = new S2I();
 
289
 
 
290
    LC_SBSn(&oSnradm, poFileadm, 0, nNumFeatures); /* Set FYBA search limits  */
 
291
    LC_InitNextBgr(poNextSerial);
 
292
 
 
293
    /* Prebuilding simple features and extracting layer information. */
 
294
    while (LC_NextBgr(poNextSerial,LC_FRAMGR)) {
 
295
        /* Fetch next group information */
 
296
        nName = LC_RxGr(poNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo);
 
297
 
 
298
        S2S oHeaders;
 
299
        S2S::iterator iHeaders;
 
300
        int iH;
 
301
        /* Extract all strings from group header. */
 
302
        for (short i=1; i<=nNumLines; i++) {
 
303
            char *pszLine = LC_GetGi(i);      /* Get one header line */
 
304
            if ((pszLine[0] == ':')||(pszLine[0] == '(')) continue;  /* If we have a continued REF line, skip it. */
 
305
            if (pszLine[0] == '!') continue;  /* If we have a comment line, skip it. */
 
306
            
 
307
            char *pszUTFLine = CPLRecode(pszLine, pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here, if it is known. */
 
308
                        
 
309
            while (pszUTFLine[0] == '.') pszUTFLine++; /* Skipping the dots at the beginning of a SOSI line */
 
310
            char *pszPos = strstr(pszUTFLine, " "); /* Split header and value */
 
311
            if (pszPos != NULL) {
 
312
                CPLString osKey = CPLString(std::string(pszUTFLine,pszPos)); /* FIXME: clean instantiation of CPLString? */
 
313
                CPLString osValue = CPLString(pszPos+1);
 
314
                
 
315
                oHeaders[osKey]=osValue;          /* Add to header map */
 
316
                switch (nName) {             /* Add to header list for the corresponding layer, if it is not */
 
317
                case L_FLATE: {            /* in there already */
 
318
                    if (poPolyHeaders->find(osKey) == poPolyHeaders->end()) {
 
319
                        iH = poPolyHeaders->size();
 
320
                        (*poPolyHeaders)[osKey] = iH;
 
321
                    }
 
322
                    break;
 
323
                }
 
324
                case L_KURVE: {
 
325
                    if (poCurveHeaders->find(osKey) == poCurveHeaders->end()) {
 
326
                        iH = poCurveHeaders->size();
 
327
                        (*poCurveHeaders)[osKey] = iH;
 
328
                    }
 
329
                    break;
 
330
                }
 
331
                case L_PUNKT: {
 
332
                    if (poPointHeaders->find(osKey) == poPointHeaders->end()) {
 
333
                        iH = poPointHeaders->size();
 
334
                        (*poPointHeaders)[osKey] = iH;
 
335
                    }
 
336
                    break;
 
337
                }
 
338
                case L_TEKST: {
 
339
                    if (poTextHeaders->find(osKey) == poTextHeaders->end()) {
 
340
                        iH = poTextHeaders->size();
 
341
                        (*poTextHeaders)[osKey] = iH;
 
342
                    }
 
343
                    break;
 
344
                }
 
345
                }
 
346
            }
 
347
            //CPLFree(pszUTFLine);
 
348
        }
 
349
 
 
350
        /* Feature-specific tasks */
 
351
        switch (nName) {
 
352
        case L_PUNKT: {
 
353
            /* Pre-build a point feature. Activate point layer. */
 
354
            bPointLayer = TRUE;
 
355
            buildOGRPoint(oNextSerial.lNr);
 
356
            break;
 
357
        }
 
358
        case L_FLATE: {
 
359
            /* Activate polygon layer. */
 
360
            bPolyLayer = TRUE;
 
361
            /* cannot build geometries that reference others yet */
 
362
            break;
 
363
        }
 
364
        case L_KURVE: {
 
365
            /* Pre-build a line feature. Activate line/curve layer. */
 
366
            bCurveLayer = TRUE;
 
367
            buildOGRLineString(nNumCoo, oNextSerial.lNr);
 
368
            break;
 
369
        }
 
370
        case L_TEKST: {
 
371
            /* Pre-build a text line contour feature. Activate text layer. */
 
372
            /* Todo: observe only points 2ff if more than one point is given for follow mode */
 
373
            bTextLayer = TRUE;
 
374
            buildOGRMultiPoint(nNumCoo, oNextSerial.lNr);
 
375
            break;
 
376
        }
 
377
        case L_HODE: {
 
378
            /* Get SRS from SOSI header. */
 
379
            unsigned short nMask = LC_TR_ALLT;
 
380
            LC_TRANSPAR oTrans;
 
381
            if (LC_GetTransEx(&nMask,&oTrans) == UT_FALSE) {
 
382
                CPLError( CE_Failure, CPLE_OpenFailed, 
 
383
                          "TRANSPAR section not found - No reference system information available.");
 
384
                return NULL;
 
385
            }
 
386
            poSRS = new OGRSpatialReference();
 
387
            poSRS->Reference();
 
388
 
 
389
            /* Get coordinate system from SOSI header. */
 
390
            int nEPSG = sosi2epsg(oTrans.sKoordsys);
 
391
            if (poSRS->importFromEPSG(nEPSG) != OGRERR_NONE) {
 
392
                                CPLError( CE_Failure, CPLE_OpenFailed, 
 
393
                          "OGR could not load coordinate system definition EPSG:%i.", nEPSG);
 
394
                return NULL;
 
395
            }
 
396
 
 
397
            /* Get character encoding from SOSI header. */
 
398
            iHeaders = oHeaders.find("TEGNSETT");
 
399
            if (iHeaders != oHeaders.end()) {
 
400
                CPLString osLine = iHeaders->second;
 
401
                if (osLine.compare("ISO8859-1")==0) {
 
402
                    pszEncoding = CPL_ENC_ISO8859_1;
 
403
                } else if (osLine.compare("ISO8859-10")==0) {
 
404
                    pszEncoding = CPL_ENC_ISO8859_10;
 
405
                } else if (osLine.compare("UTF-8")==0) {
 
406
                    pszEncoding = CPL_ENC_UTF8;
 
407
                }
 
408
            }
 
409
 
 
410
            break;
 
411
        }
 
412
        default: {
 
413
            break;
 
414
        }
 
415
        }
 
416
    }
 
417
 
 
418
    /* -------------------------------------------------------------------- *
 
419
     *      Create a corresponding layers. One per geometry type            *
 
420
     * -------------------------------------------------------------------- */
 
421
    int nLayers = 0;
 
422
    if (bPolyLayer)  nLayers++;
 
423
    if (bCurveLayer) nLayers++;
 
424
    if (bPointLayer) nLayers++;
 
425
    if (bTextLayer) nLayers++;
 
426
    this->nLayers = nLayers;
 
427
    /* allocate some memory for up to three layers */
 
428
    papoLayers = (OGRSOSILayer **) VSIMalloc2(sizeof(void*), nLayers);
 
429
 
 
430
    /* Define each layer, using a proper feature definition, geometry type,
 
431
     * and adding every SOSI header encountered in the file as field. */
 
432
    S2I::iterator i;
 
433
    if (bPolyLayer) {
 
434
                OGRFeatureDefn *poFeatureDefn = defineLayer("polygons", wkbPolygon, poPolyHeaders);
 
435
        poFeatureDefn->Reference();
 
436
        papoLayers[--nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPolyHeaders );
 
437
    } else {
 
438
        delete poPolyHeaders;
 
439
        poPolyHeaders = NULL;
 
440
    }
 
441
    if (bCurveLayer) {
 
442
        OGRFeatureDefn *poFeatureDefn = defineLayer("lines", wkbLineString, poCurveHeaders);
 
443
        poFeatureDefn->Reference();
 
444
        papoLayers[--nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poCurveHeaders );
 
445
    } else {
 
446
        delete poCurveHeaders;
 
447
        poCurveHeaders = NULL;
 
448
    }
 
449
    if (bPointLayer) {
 
450
        OGRFeatureDefn *poFeatureDefn = defineLayer("points", wkbPoint, poPointHeaders);
 
451
        poFeatureDefn->Reference();
 
452
        papoLayers[--nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPointHeaders );
 
453
    } else {
 
454
        delete poPointHeaders;
 
455
        poPointHeaders = NULL;
 
456
    }
 
457
    if (bTextLayer) {
 
458
        OGRFeatureDefn *poFeatureDefn = defineLayer("text", wkbMultiPoint, poTextHeaders);
 
459
        poFeatureDefn->Reference();
 
460
        papoLayers[--nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poTextHeaders );
 
461
    } else {
 
462
        delete poTextHeaders;
 
463
        poTextHeaders = NULL;
 
464
    }
 
465
    return TRUE;
 
466
}
 
467
 
 
468
 
 
469
/************************************************************************/
 
470
/*                              Create()                                */
 
471
/************************************************************************/
 
472
 
 
473
int  OGRSOSIDataSource::Create( const char *pszFilename ) {
 
474
        short nStatus;
 
475
        short nDetStatus;
 
476
        
 
477
    poBaseadm = LC_OpenBase(LC_KLADD);
 
478
    nStatus   = LC_OpenSos(pszFilename, LC_SEKV_SKRIV, LC_NY_IDX, LC_INGEN_STATUS,
 
479
                           &poFileadm, &nDetStatus);
 
480
    if (nStatus == UT_FALSE) {
 
481
        CPLError( CE_Failure, CPLE_OpenFailed,
 
482
                  "Could not open SOSI file for writing (Status %i).", nDetStatus );
 
483
        return FALSE;
 
484
        }
 
485
 
 
486
    LC_NyttHode(); /* Create new file header, will be written to file when all 
 
487
                      header information elements are set. */
 
488
                      
 
489
    return TRUE;
 
490
}
 
491
 
 
492
/************************************************************************/
 
493
/*                              CreateLayer()                           */
 
494
/************************************************************************/
 
495
 
 
496
OGRLayer *OGRSOSIDataSource::CreateLayer( const char *pszName, OGRSpatialReference  *poSpatialRef, OGRwkbGeometryType eGType, char **papszOptions ) {
 
497
    /* SOSI does not really support layers - so let's first see that the global settings are consistent */
 
498
    if (poSRS == NULL) {
 
499
        if (poSpatialRef!=NULL) {
 
500
            poSRS = poSpatialRef;
 
501
            poSRS->Reference();
 
502
        
 
503
            const char *pszKoosys = poSRS->GetAuthorityCode("PROJCS");
 
504
            if (pszKoosys == NULL) {
 
505
                OGRErr err = poSRS->AutoIdentifyEPSG();
 
506
                if (err == OGRERR_UNSUPPORTED_SRS) {
 
507
                    CPLError( CE_Failure, CPLE_OpenFailed,
 
508
                        "Could not identify EPSG code for spatial reference system");
 
509
                    return NULL;
 
510
                }
 
511
                pszKoosys = poSRS->GetAuthorityCode("PROJCS");
 
512
            }
 
513
            
 
514
            if (pszKoosys != NULL) {
 
515
                int nKoosys = epsg2sosi(atoi(pszKoosys));
 
516
                CPLDebug( "[CreateLayer]","Projection set to SOSI %i", nKoosys);
 
517
                LC_PutTrans(nKoosys,0,0,0.01,0.01,0.01);
 
518
            } else {
 
519
                pszKoosys = poSRS->GetAuthorityCode("GEOGCS");
 
520
                if (pszKoosys != NULL) {
 
521
                    int nKoosys = epsg2sosi(atoi(pszKoosys));
 
522
                   LC_PutTrans(nKoosys,0,0,0.01,0.01,0.01);
 
523
                } else {
 
524
                    CPLError( CE_Failure, CPLE_OpenFailed,
 
525
                        "Could not retrieve EPSG code for spatial reference system");
 
526
                    return NULL;
 
527
                }
 
528
            }
 
529
        } 
 
530
        LC_WsGr(poFileadm); /* Writing the header here! */
 
531
    
 
532
    } else {
 
533
        if (!poSRS->IsSame(poSpatialRef)) {
 
534
          CPLError( CE_Failure, CPLE_AppDefined,
 
535
                    "SOSI driver does not support different spatial reference systems in one file.");
 
536
        }
 
537
    }
 
538
    
 
539
    OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn( pszName );
 
540
    poFeatureDefn->Reference();
 
541
    poFeatureDefn->SetGeomType( eGType );
 
542
    OGRSOSILayer *poLayer = new OGRSOSILayer( this, poFeatureDefn, poFileadm, NULL /*poHeaderDefn*/);
 
543
    /* todo: where do we delete poLayer and poFeatureDefn? */
 
544
    return poLayer;
 
545
}
 
546
 
 
547
/************************************************************************/
 
548
/*                              GetLayer()                              */
 
549
/************************************************************************/
 
550
 
 
551
OGRLayer *OGRSOSIDataSource::GetLayer( int iLayer ) {
 
552
    if ( iLayer < 0 || iLayer >= nLayers )
 
553
        return NULL;
 
554
    else
 
555
        return papoLayers[iLayer];
 
556
}
 
557
 
 
558
void OGRSOSIDataSource::buildOGRMultiPoint(int nNumCoo, long iSerial) {
 
559
    if (papoBuiltGeometries[iSerial] != NULL) {
 
560
        return;
 
561
    }
 
562
 
 
563
    OGRMultiPoint *poMP = new OGRMultiPoint();
 
564
 
 
565
    long i;
 
566
    double dfEast = 0, dfNorth = 0;
 
567
    for (i=(nNumCoo>1)?2:1; i<=nNumCoo; i++) {
 
568
        LC_GetTK(i, &dfEast, &dfNorth);
 
569
        OGRPoint poP = OGRPoint(dfEast, dfNorth);
 
570
        poMP->addGeometry(&poP); /*poP will be cloned before returning*/
 
571
    }
 
572
    papoBuiltGeometries[iSerial] = poMP;
 
573
}
 
574
 
 
575
void OGRSOSIDataSource::buildOGRLineString(int nNumCoo, long iSerial) {
 
576
    if (papoBuiltGeometries[iSerial] != NULL) {
 
577
        return;
 
578
    }
 
579
 
 
580
    OGRLineString *poLS = new OGRLineString();
 
581
    poLS->setNumPoints(nNumCoo);
 
582
 
 
583
    long i;
 
584
    double dfEast = 0, dfNorth = 0;
 
585
    for (i=1; i<=nNumCoo; i++) {
 
586
        LC_GetTK(i, &dfEast, &dfNorth);
 
587
        poLS->setPoint(i-1, dfEast, dfNorth);
 
588
    }
 
589
    papoBuiltGeometries[iSerial] = poLS;
 
590
}
 
591
void OGRSOSIDataSource::buildOGRPoint(long iSerial) {
 
592
    double dfEast = 0, dfNorth = 0;
 
593
    LC_GetTK(1, &dfEast, &dfNorth);
 
594
    papoBuiltGeometries[iSerial] = new OGRPoint(dfEast, dfNorth);
 
595
}
 
596
 
 
597
/************************************************************************/
 
598
/*                              TestCapability()                        */
 
599
/************************************************************************/
 
600
 
 
601
int OGRSOSIDataSource::TestCapability( const char * pszCap ) {
 
602
    if (strcmp("CreateLayer",pszCap) == 0) {
 
603
        return TRUE; 
 
604
    } else {
 
605
        CPLDebug( "[TestCapability]","Capability %s not supported by SOSI data source", pszCap);
 
606
    }
 
607
        return FALSE;
 
608
}