1 : /******************************************************************************
2 : * $Id: ogrspatialreference.cpp 24323 2012-04-27 05:45:18Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: The OGRSpatialReference class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
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_spatialref.h"
31 : #include "ogr_p.h"
32 : #include "cpl_csv.h"
33 : #include "cpl_http.h"
34 : #include "cpl_atomic_ops.h"
35 :
36 : CPL_CVSID("$Id: ogrspatialreference.cpp 24323 2012-04-27 05:45:18Z warmerdam $");
37 :
38 : // The current opinion is that WKT longitudes like central meridian
39 : // should be relative to greenwich, not the prime meridian in use.
40 : // Define the following if they should be relative to the prime meridian
41 : // of then geogcs.
42 : #undef WKT_LONGITUDE_RELATIVE_TO_PM
43 :
44 : /************************************************************************/
45 : /* OGRPrintDouble() */
46 : /************************************************************************/
47 :
48 253251 : void OGRPrintDouble( char * pszStrBuf, double dfValue )
49 :
50 : {
51 253251 : sprintf( pszStrBuf, "%.16g", dfValue );
52 :
53 253251 : int nLen = strlen(pszStrBuf);
54 :
55 : // The following hack is intended to truncate some "precision" in cases
56 : // that appear to be roundoff error.
57 253251 : if( nLen > 15
58 : && (strcmp(pszStrBuf+nLen-6,"999999") == 0
59 : || strcmp(pszStrBuf+nLen-6,"000001") == 0) )
60 : {
61 1652 : sprintf( pszStrBuf, "%.15g", dfValue );
62 : }
63 :
64 : // force to user periods regardless of locale.
65 253251 : if( strchr( pszStrBuf, ',' ) != NULL )
66 : {
67 0 : char *pszDelim = strchr( pszStrBuf, ',' );
68 0 : *pszDelim = '.';
69 : }
70 253251 : }
71 :
72 : /************************************************************************/
73 : /* OGRSpatialReference() */
74 : /************************************************************************/
75 :
76 : /**
77 : * \brief Constructor.
78 : *
79 : * This constructor takes an optional string argument which if passed
80 : * should be a WKT representation of an SRS. Passing this is equivalent
81 : * to not passing it, and then calling importFromWkt() with the WKT string.
82 : *
83 : * Note that newly created objects are given a reference count of one.
84 : *
85 : * The C function OSRNewSpatialReference() does the same thing as this
86 : * constructor.
87 : *
88 : * @param pszWKT well known text definition to which the object should
89 : * be initialized, or NULL (the default).
90 : */
91 :
92 135857 : OGRSpatialReference::OGRSpatialReference( const char * pszWKT )
93 :
94 : {
95 135857 : bNormInfoSet = FALSE;
96 135857 : nRefCount = 1;
97 135857 : poRoot = NULL;
98 :
99 135857 : if( pszWKT != NULL )
100 3814 : importFromWkt( (char **) &pszWKT );
101 135857 : }
102 :
103 : /************************************************************************/
104 : /* OSRNewSpatialReference() */
105 : /************************************************************************/
106 :
107 : /**
108 : * \brief Constructor.
109 : *
110 : * This function is the same as OGRSpatialReference::OGRSpatialReference()
111 : */
112 31422 : OGRSpatialReferenceH CPL_STDCALL OSRNewSpatialReference( const char *pszWKT )
113 :
114 : {
115 : OGRSpatialReference * poSRS;
116 :
117 31422 : poSRS = new OGRSpatialReference();
118 :
119 62742 : if( pszWKT != NULL && strlen(pszWKT) > 0 )
120 : {
121 522 : if( poSRS->importFromWkt( (char **) (&pszWKT) ) != OGRERR_NONE )
122 : {
123 0 : delete poSRS;
124 0 : poSRS = NULL;
125 : }
126 : }
127 :
128 31422 : return (OGRSpatialReferenceH) poSRS;
129 : }
130 :
131 : /************************************************************************/
132 : /* OGRSpatialReference() */
133 : /* */
134 : /* Simple copy constructor. See also Clone(). */
135 : /************************************************************************/
136 :
137 176 : OGRSpatialReference::OGRSpatialReference(const OGRSpatialReference &oOther)
138 :
139 : {
140 176 : bNormInfoSet = FALSE;
141 176 : nRefCount = 1;
142 176 : poRoot = NULL;
143 :
144 176 : if( oOther.poRoot != NULL )
145 176 : poRoot = oOther.poRoot->Clone();
146 176 : }
147 :
148 : /************************************************************************/
149 : /* ~OGRSpatialReference() */
150 : /************************************************************************/
151 :
152 : /**
153 : * \brief OGRSpatialReference destructor.
154 : *
155 : * The C function OSRDestroySpatialReference() does the same thing as this
156 : * method. Preferred C++ method : OGRSpatialReference::DestroySpatialReference()
157 : *
158 : * @deprecated
159 : */
160 :
161 136033 : OGRSpatialReference::~OGRSpatialReference()
162 :
163 : {
164 136033 : if( poRoot != NULL )
165 127953 : delete poRoot;
166 136033 : }
167 :
168 : /************************************************************************/
169 : /* DestroySpatialReference() */
170 : /************************************************************************/
171 :
172 : /**
173 : * \brief OGRSpatialReference destructor.
174 : *
175 : * This static method will destroy a OGRSpatialReference. It is
176 : * equivalent to calling delete on the object, but it ensures that the
177 : * deallocation is properly executed within the OGR libraries heap on
178 : * platforms where this can matter (win32).
179 : *
180 : * This function is the same as OSRDestroySpatialReference()
181 : *
182 : * @param poSRS the object to delete
183 : *
184 : * @since GDAL 1.7.0
185 : */
186 :
187 296 : void OGRSpatialReference::DestroySpatialReference(OGRSpatialReference* poSRS)
188 : {
189 296 : delete poSRS;
190 296 : }
191 :
192 : /************************************************************************/
193 : /* OSRDestroySpatialReference() */
194 : /************************************************************************/
195 :
196 : /**
197 : * \brief OGRSpatialReference destructor.
198 : *
199 : * This function is the same as OGRSpatialReference::~OGRSpatialReference()
200 : * and OGRSpatialReference::DestroySpatialReference()
201 : *
202 : * @param hSRS the object to delete
203 : */
204 88560 : void CPL_STDCALL OSRDestroySpatialReference( OGRSpatialReferenceH hSRS )
205 :
206 : {
207 88560 : delete ((OGRSpatialReference *) hSRS);
208 88560 : }
209 :
210 : /************************************************************************/
211 : /* Clear() */
212 : /************************************************************************/
213 :
214 : /**
215 : * \brief Wipe current definition.
216 : *
217 : * Returns OGRSpatialReference to a state with no definition, as it
218 : * exists when first created. It does not affect reference counts.
219 : */
220 :
221 27911 : void OGRSpatialReference::Clear()
222 :
223 : {
224 27911 : if( poRoot )
225 1748 : delete poRoot;
226 :
227 27911 : poRoot = NULL;
228 :
229 27911 : bNormInfoSet = FALSE;
230 27911 : dfFromGreenwich = 1.0;
231 27911 : dfToMeter = 1.0;
232 27911 : dfToDegrees = 1.0;
233 27911 : }
234 :
235 : /************************************************************************/
236 : /* operator=() */
237 : /************************************************************************/
238 :
239 : OGRSpatialReference &
240 8 : OGRSpatialReference::operator=(const OGRSpatialReference &oSource)
241 :
242 : {
243 8 : Clear();
244 :
245 8 : if( oSource.poRoot != NULL )
246 8 : poRoot = oSource.poRoot->Clone();
247 :
248 8 : return *this;
249 : }
250 :
251 : /************************************************************************/
252 : /* Reference() */
253 : /************************************************************************/
254 :
255 : /**
256 : * \brief Increments the reference count by one.
257 : *
258 : * The reference count is used keep track of the number of OGRGeometry objects
259 : * referencing this SRS.
260 : *
261 : * The method does the same thing as the C function OSRReference().
262 : *
263 : * @return the updated reference count.
264 : */
265 :
266 1262784 : int OGRSpatialReference::Reference()
267 :
268 : {
269 1262784 : return CPLAtomicInc(&nRefCount);
270 : }
271 :
272 : /************************************************************************/
273 : /* OSRReference() */
274 : /************************************************************************/
275 :
276 : /**
277 : * \brief Increments the reference count by one.
278 : *
279 : * This function is the same as OGRSpatialReference::Reference()
280 : */
281 322 : int OSRReference( OGRSpatialReferenceH hSRS )
282 :
283 : {
284 322 : VALIDATE_POINTER1( hSRS, "OSRReference", 0 );
285 :
286 322 : return ((OGRSpatialReference *) hSRS)->Reference();
287 : }
288 :
289 : /************************************************************************/
290 : /* Dereference() */
291 : /************************************************************************/
292 :
293 : /**
294 : * \brief Decrements the reference count by one.
295 : *
296 : * The method does the same thing as the C function OSRDereference().
297 : *
298 : * @return the updated reference count.
299 : */
300 :
301 1358398 : int OGRSpatialReference::Dereference()
302 :
303 : {
304 1358398 : if( nRefCount <= 0 )
305 : CPLDebug( "OSR",
306 : "Dereference() called on an object with refcount %d,"
307 : "likely already destroyed!",
308 0 : nRefCount );
309 1358398 : return CPLAtomicDec(&nRefCount);
310 : }
311 :
312 : /************************************************************************/
313 : /* OSRDereference() */
314 : /************************************************************************/
315 :
316 : /**
317 : * \brief Decrements the reference count by one.
318 : *
319 : * This function is the same as OGRSpatialReference::Dereference()
320 : */
321 88464 : int OSRDereference( OGRSpatialReferenceH hSRS )
322 :
323 : {
324 88464 : VALIDATE_POINTER1( hSRS, "OSRDereference", 0 );
325 :
326 88464 : return ((OGRSpatialReference *) hSRS)->Dereference();
327 : }
328 :
329 : /************************************************************************/
330 : /* GetReferenceCount() */
331 : /************************************************************************/
332 :
333 : /**
334 : * \fn int OGRSpatialReference::GetReferenceCount() const;
335 : *
336 : * \brief Fetch current reference count.
337 : *
338 : * @return the current reference count.
339 : */
340 :
341 : /************************************************************************/
342 : /* Release() */
343 : /************************************************************************/
344 :
345 : /**
346 : * \brief Decrements the reference count by one, and destroy if zero.
347 : *
348 : * The method does the same thing as the C function OSRRelease().
349 : */
350 :
351 1267874 : void OGRSpatialReference::Release()
352 :
353 : {
354 1267874 : CPLAssert( NULL != this );
355 :
356 1267874 : if( Dereference() <= 0 )
357 5848 : delete this;
358 1267874 : }
359 :
360 : /************************************************************************/
361 : /* OSRRelease() */
362 : /************************************************************************/
363 :
364 : /**
365 : * \brief Decrements the reference count by one, and destroy if zero.
366 : *
367 : * This function is the same as OGRSpatialReference::Release()
368 : */
369 14 : void OSRRelease( OGRSpatialReferenceH hSRS )
370 :
371 : {
372 14 : VALIDATE_POINTER0( hSRS, "OSRRelease" );
373 :
374 14 : ((OGRSpatialReference *) hSRS)->Release();
375 : }
376 :
377 : /************************************************************************/
378 : /* SetRoot() */
379 : /************************************************************************/
380 :
381 : /**
382 : * \brief Set the root SRS node.
383 : *
384 : * If the object has an existing tree of OGR_SRSNodes, they are destroyed
385 : * as part of assigning the new root. Ownership of the passed OGR_SRSNode is
386 : * is assumed by the OGRSpatialReference.
387 : *
388 : * @param poNewRoot object to assign as root.
389 : */
390 :
391 52958 : void OGRSpatialReference::SetRoot( OGR_SRSNode * poNewRoot )
392 :
393 : {
394 52958 : if( poRoot != NULL )
395 2 : delete poRoot;
396 :
397 52958 : poRoot = poNewRoot;
398 52958 : }
399 :
400 : /************************************************************************/
401 : /* GetAttrNode() */
402 : /************************************************************************/
403 :
404 : /**
405 : * \brief Find named node in tree.
406 : *
407 : * This method does a pre-order traversal of the node tree searching for
408 : * a node with this exact value (case insensitive), and returns it. Leaf
409 : * nodes are not considered, under the assumption that they are just
410 : * attribute value nodes.
411 : *
412 : * If a node appears more than once in the tree (such as UNIT for instance),
413 : * the first encountered will be returned. Use GetNode() on a subtree to be
414 : * more specific.
415 : *
416 : * @param pszNodePath the name of the node to search for. May contain multiple
417 : * components such as "GEOGCS|UNIT".
418 : *
419 : * @return a pointer to the node found, or NULL if none.
420 : */
421 :
422 2745630 : OGR_SRSNode *OGRSpatialReference::GetAttrNode( const char * pszNodePath )
423 :
424 : {
425 : char **papszPathTokens;
426 : OGR_SRSNode *poNode;
427 :
428 2745630 : papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
429 :
430 2745630 : if( CSLCount( papszPathTokens ) < 1 )
431 : {
432 0 : CSLDestroy(papszPathTokens);
433 0 : return NULL;
434 : }
435 :
436 2745630 : poNode = GetRoot();
437 5756848 : for( int i = 0; poNode != NULL && papszPathTokens[i] != NULL; i++ )
438 : {
439 3011218 : poNode = poNode->GetNode( papszPathTokens[i] );
440 : }
441 :
442 2745630 : CSLDestroy( papszPathTokens );
443 :
444 2745630 : return poNode;
445 : }
446 :
447 : const OGR_SRSNode *
448 1617266 : OGRSpatialReference::GetAttrNode( const char * pszNodePath ) const
449 :
450 : {
451 : OGR_SRSNode *poNode;
452 :
453 1617266 : poNode = ((OGRSpatialReference *) this)->GetAttrNode(pszNodePath);
454 :
455 1617266 : return poNode;
456 : }
457 :
458 : /************************************************************************/
459 : /* GetAttrValue() */
460 : /************************************************************************/
461 :
462 : /**
463 : * \brief Fetch indicated attribute of named node.
464 : *
465 : * This method uses GetAttrNode() to find the named node, and then extracts
466 : * the value of the indicated child. Thus a call to GetAttrValue("UNIT",1)
467 : * would return the second child of the UNIT node, which is normally the
468 : * length of the linear unit in meters.
469 : *
470 : * This method does the same thing as the C function OSRGetAttrValue().
471 : *
472 : * @param pszNodeName the tree node to look for (case insensitive).
473 : * @param iAttr the child of the node to fetch (zero based).
474 : *
475 : * @return the requested value, or NULL if it fails for any reason.
476 : */
477 :
478 805552 : const char *OGRSpatialReference::GetAttrValue( const char * pszNodeName,
479 : int iAttr ) const
480 :
481 : {
482 : const OGR_SRSNode *poNode;
483 :
484 805552 : poNode = GetAttrNode( pszNodeName );
485 805552 : if( poNode == NULL )
486 42002 : return NULL;
487 :
488 763550 : if( iAttr < 0 || iAttr >= poNode->GetChildCount() )
489 0 : return NULL;
490 :
491 763550 : return poNode->GetChild(iAttr)->GetValue();
492 : }
493 :
494 : /************************************************************************/
495 : /* OSRGetAttrValue() */
496 : /************************************************************************/
497 :
498 : /**
499 : * \brief Fetch indicated attribute of named node.
500 : *
501 : * This function is the same as OGRSpatialReference::GetAttrValue()
502 : */
503 40554 : const char * CPL_STDCALL OSRGetAttrValue( OGRSpatialReferenceH hSRS,
504 : const char * pszKey, int iChild )
505 :
506 : {
507 40554 : VALIDATE_POINTER1( hSRS, "OSRGetAttrValue", NULL );
508 :
509 40554 : return ((OGRSpatialReference *) hSRS)->GetAttrValue( pszKey, iChild );
510 : }
511 :
512 : /************************************************************************/
513 : /* Clone() */
514 : /************************************************************************/
515 :
516 : /**
517 : * \brief Make a duplicate of this OGRSpatialReference.
518 : *
519 : * This method is the same as the C function OSRClone().
520 : *
521 : * @return a new SRS, which becomes the responsibility of the caller.
522 : */
523 :
524 59784 : OGRSpatialReference *OGRSpatialReference::Clone() const
525 :
526 : {
527 : OGRSpatialReference *poNewRef;
528 :
529 59784 : poNewRef = new OGRSpatialReference();
530 :
531 59784 : if( poRoot != NULL )
532 59784 : poNewRef->poRoot = poRoot->Clone();
533 :
534 59784 : return poNewRef;
535 : }
536 :
537 : /************************************************************************/
538 : /* OSRClone() */
539 : /************************************************************************/
540 :
541 : /**
542 : * \brief Make a duplicate of this OGRSpatialReference.
543 : *
544 : * This function is the same as OGRSpatialReference::Clone()
545 : */
546 56988 : OGRSpatialReferenceH CPL_STDCALL OSRClone( OGRSpatialReferenceH hSRS )
547 :
548 : {
549 56988 : VALIDATE_POINTER1( hSRS, "OSRClone", NULL );
550 :
551 56988 : return (OGRSpatialReferenceH) ((OGRSpatialReference *) hSRS)->Clone();
552 : }
553 :
554 : /************************************************************************/
555 : /* dumpReadable() */
556 : /* */
557 : /* Dump pretty wkt to stdout, mostly for debugging. */
558 : /************************************************************************/
559 :
560 0 : void OGRSpatialReference::dumpReadable()
561 :
562 : {
563 0 : char *pszPrettyWkt = NULL;
564 :
565 0 : exportToPrettyWkt( &pszPrettyWkt, FALSE );
566 0 : printf( "%s\n", pszPrettyWkt );
567 0 : CPLFree( pszPrettyWkt );
568 0 : }
569 :
570 : /************************************************************************/
571 : /* exportToPrettyWkt() */
572 : /************************************************************************/
573 :
574 : /**
575 : * Convert this SRS into a a nicely formatted WKT string for display to a person.
576 : *
577 : * Note that the returned WKT string should be freed with OGRFree() or
578 : * CPLFree() when no longer needed. It is the responsibility of the caller.
579 : *
580 : * This method is the same as the C function OSRExportToPrettyWkt().
581 : *
582 : * @param ppszResult the resulting string is returned in this pointer.
583 : * @param bSimplify TRUE if the AXIS, AUTHORITY and EXTENSION nodes should be stripped off
584 : *
585 : * @return currently OGRERR_NONE is always returned, but the future it
586 : * is possible error conditions will develop.
587 : */
588 :
589 154 : OGRErr OGRSpatialReference::exportToPrettyWkt( char ** ppszResult,
590 : int bSimplify ) const
591 :
592 : {
593 154 : if( poRoot == NULL )
594 : {
595 0 : *ppszResult = CPLStrdup("");
596 0 : return OGRERR_NONE;
597 : }
598 :
599 154 : if( bSimplify )
600 : {
601 2 : OGRSpatialReference *poSimpleClone = Clone();
602 : OGRErr eErr;
603 :
604 2 : poSimpleClone->GetRoot()->StripNodes( "AXIS" );
605 2 : poSimpleClone->GetRoot()->StripNodes( "AUTHORITY" );
606 2 : poSimpleClone->GetRoot()->StripNodes( "EXTENSION" );
607 2 : eErr = poSimpleClone->GetRoot()->exportToPrettyWkt( ppszResult, 1 );
608 2 : delete poSimpleClone;
609 2 : return eErr;
610 : }
611 : else
612 152 : return poRoot->exportToPrettyWkt( ppszResult, 1 );
613 : }
614 :
615 : /************************************************************************/
616 : /* OSRExportToPrettyWkt() */
617 : /************************************************************************/
618 :
619 :
620 : /**
621 : * \brief Convert this SRS into a a nicely formatted WKT string for display to a person.
622 : *
623 : * This function is the same as OGRSpatialReference::exportToPrettyWkt().
624 : */
625 :
626 126 : OGRErr CPL_STDCALL OSRExportToPrettyWkt( OGRSpatialReferenceH hSRS, char ** ppszReturn,
627 : int bSimplify)
628 :
629 : {
630 126 : VALIDATE_POINTER1( hSRS, "OSRExportToPrettyWkt", CE_Failure );
631 :
632 126 : *ppszReturn = NULL;
633 :
634 : return ((OGRSpatialReference *) hSRS)->exportToPrettyWkt( ppszReturn,
635 126 : bSimplify );
636 : }
637 :
638 : /************************************************************************/
639 : /* exportToWkt() */
640 : /************************************************************************/
641 :
642 : /**
643 : * \brief Convert this SRS into WKT format.
644 : *
645 : * Note that the returned WKT string should be freed with OGRFree() or
646 : * CPLFree() when no longer needed. It is the responsibility of the caller.
647 : *
648 : * This method is the same as the C function OSRExportToWkt().
649 : *
650 : * @param ppszResult the resulting string is returned in this pointer.
651 : *
652 : * @return currently OGRERR_NONE is always returned, but the future it
653 : * is possible error conditions will develop.
654 : */
655 :
656 135275 : OGRErr OGRSpatialReference::exportToWkt( char ** ppszResult ) const
657 :
658 : {
659 135275 : if( poRoot == NULL )
660 : {
661 80 : *ppszResult = CPLStrdup("");
662 80 : return OGRERR_NONE;
663 : }
664 : else
665 : {
666 135195 : return poRoot->exportToWkt(ppszResult);
667 : }
668 : }
669 :
670 : /************************************************************************/
671 : /* OSRExportToWkt() */
672 : /************************************************************************/
673 :
674 : /**
675 : * \brief Convert this SRS into WKT format.
676 : *
677 : * This function is the same as OGRSpatialReference::exportToWkt().
678 : */
679 :
680 121034 : OGRErr CPL_STDCALL OSRExportToWkt( OGRSpatialReferenceH hSRS,
681 : char ** ppszReturn )
682 :
683 : {
684 121034 : VALIDATE_POINTER1( hSRS, "OSRExportToWkt", CE_Failure );
685 :
686 121034 : *ppszReturn = NULL;
687 :
688 121034 : return ((OGRSpatialReference *) hSRS)->exportToWkt( ppszReturn );
689 : }
690 :
691 : /************************************************************************/
692 : /* importFromWkt() */
693 : /************************************************************************/
694 :
695 : /**
696 : * \brief Import from WKT string.
697 : *
698 : * This method will wipe the existing SRS definition, and
699 : * reassign it based on the contents of the passed WKT string. Only as
700 : * much of the input string as needed to construct this SRS is consumed from
701 : * the input string, and the input string pointer
702 : * is then updated to point to the remaining (unused) input.
703 : *
704 : * This method is the same as the C function OSRImportFromWkt().
705 : *
706 : * @param ppszInput Pointer to pointer to input. The pointer is updated to
707 : * point to remaining unused input text.
708 : *
709 : * @return OGRERR_NONE if import succeeds, or OGRERR_CORRUPT_DATA if it
710 : * fails for any reason.
711 : */
712 :
713 25461 : OGRErr OGRSpatialReference::importFromWkt( char ** ppszInput )
714 :
715 : {
716 25461 : if ( !ppszInput || !*ppszInput )
717 2 : return OGRERR_FAILURE;
718 :
719 25459 : Clear();
720 :
721 25459 : poRoot = new OGR_SRSNode();
722 :
723 25459 : OGRErr eErr = poRoot->importFromWkt( ppszInput );
724 25459 : if (eErr != OGRERR_NONE)
725 44 : return eErr;
726 :
727 : /* -------------------------------------------------------------------- */
728 : /* The following seems to try and detect and unconsumed */
729 : /* VERTCS[] coordinate system definition (ESRI style) and to */
730 : /* import and attach it to the existing root. Likely we will */
731 : /* need to extend this somewhat to bring it into an acceptable */
732 : /* OGRSpatialReference organization at some point. */
733 : /* -------------------------------------------------------------------- */
734 25415 : if (strlen(*ppszInput) > 0 && strstr(*ppszInput, "VERTCS"))
735 : {
736 0 : if(((*ppszInput)[0]) == ',')
737 0 : (*ppszInput)++;
738 0 : OGR_SRSNode *poNewChild = new OGR_SRSNode();
739 0 : poRoot->AddChild( poNewChild );
740 0 : return poNewChild->importFromWkt( ppszInput );
741 : }
742 :
743 25415 : return eErr;
744 : }
745 :
746 : /************************************************************************/
747 : /* OSRImportFromWkt() */
748 : /************************************************************************/
749 :
750 : /**
751 : * \brief Import from WKT string.
752 : *
753 : * This function is the same as OGRSpatialReference::importFromWkt().
754 : */
755 :
756 12094 : OGRErr OSRImportFromWkt( OGRSpatialReferenceH hSRS, char **ppszInput )
757 :
758 : {
759 12094 : VALIDATE_POINTER1( hSRS, "OSRImportFromWkt", CE_Failure );
760 :
761 12094 : return ((OGRSpatialReference *) hSRS)->importFromWkt( ppszInput );
762 : }
763 :
764 : /************************************************************************/
765 : /* SetNode() */
766 : /************************************************************************/
767 :
768 : /**
769 : * \brief Set attribute value in spatial reference.
770 : *
771 : * Missing intermediate nodes in the path will be created if not already
772 : * in existance. If the attribute has no children one will be created and
773 : * assigned the value otherwise the zeroth child will be assigned the value.
774 : *
775 : * This method does the same as the C function OSRSetAttrValue().
776 : *
777 : * @param pszNodePath full path to attribute to be set. For instance
778 : * "PROJCS|GEOGCS|UNIT".
779 : *
780 : * @param pszNewNodeValue value to be assigned to node, such as "meter".
781 : * This may be NULL if you just want to force creation of the intermediate
782 : * path.
783 : *
784 : * @return OGRERR_NONE on success.
785 : */
786 :
787 58672 : OGRErr OGRSpatialReference::SetNode( const char * pszNodePath,
788 : const char * pszNewNodeValue )
789 :
790 : {
791 : char **papszPathTokens;
792 : int i;
793 : OGR_SRSNode *poNode;
794 :
795 58672 : papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
796 :
797 58672 : if( CSLCount( papszPathTokens ) < 1 )
798 0 : return OGRERR_FAILURE;
799 :
800 58672 : if( GetRoot() == NULL || !EQUAL(papszPathTokens[0],GetRoot()->GetValue()) )
801 : {
802 25618 : SetRoot( new OGR_SRSNode( papszPathTokens[0] ) );
803 : }
804 :
805 58672 : poNode = GetRoot();
806 91270 : for( i = 1; papszPathTokens[i] != NULL; i++ )
807 : {
808 : int j;
809 :
810 121120 : for( j = 0; j < poNode->GetChildCount(); j++ )
811 : {
812 95860 : if( EQUAL(poNode->GetChild( j )->GetValue(),papszPathTokens[i]) )
813 : {
814 7338 : poNode = poNode->GetChild(j);
815 7338 : j = -1;
816 7338 : break;
817 : }
818 : }
819 :
820 32598 : if( j != -1 )
821 : {
822 25260 : OGR_SRSNode *poNewNode = new OGR_SRSNode( papszPathTokens[i] );
823 25260 : poNode->AddChild( poNewNode );
824 25260 : poNode = poNewNode;
825 : }
826 : }
827 :
828 58672 : CSLDestroy( papszPathTokens );
829 :
830 58672 : if( pszNewNodeValue != NULL )
831 : {
832 58672 : if( poNode->GetChildCount() > 0 )
833 7794 : poNode->GetChild(0)->SetValue( pszNewNodeValue );
834 : else
835 50878 : poNode->AddChild( new OGR_SRSNode( pszNewNodeValue ) );
836 : }
837 :
838 58672 : return OGRERR_NONE;
839 : }
840 :
841 : /************************************************************************/
842 : /* OSRSetAttrValue() */
843 : /************************************************************************/
844 :
845 : /**
846 : * \brief Set attribute value in spatial reference.
847 : *
848 : * This function is the same as OGRSpatialReference::SetNode()
849 : */
850 1242 : OGRErr CPL_STDCALL OSRSetAttrValue( OGRSpatialReferenceH hSRS,
851 : const char * pszPath, const char * pszValue )
852 :
853 : {
854 1242 : VALIDATE_POINTER1( hSRS, "OSRSetAttrValue", CE_Failure );
855 :
856 1242 : return ((OGRSpatialReference *) hSRS)->SetNode( pszPath, pszValue );
857 : }
858 :
859 : /************************************************************************/
860 : /* SetNode() */
861 : /************************************************************************/
862 :
863 0 : OGRErr OGRSpatialReference::SetNode( const char *pszNodePath,
864 : double dfValue )
865 :
866 : {
867 : char szValue[64];
868 :
869 0 : if( ABS(dfValue - (int) dfValue) == 0.0 )
870 0 : sprintf( szValue, "%d", (int) dfValue );
871 : else
872 0 : OGRPrintDouble( szValue, dfValue );
873 :
874 0 : return SetNode( pszNodePath, szValue );
875 : }
876 :
877 : /************************************************************************/
878 : /* SetAngularUnits() */
879 : /************************************************************************/
880 :
881 : /**
882 : * \brief Set the angular units for the geographic coordinate system.
883 : *
884 : * This method creates a UNIT subnode with the specified values as a
885 : * child of the GEOGCS node.
886 : *
887 : * This method does the same as the C function OSRSetAngularUnits().
888 : *
889 : * @param pszUnitsName the units name to be used. Some preferred units
890 : * names can be found in ogr_srs_api.h such as SRS_UA_DEGREE.
891 : *
892 : * @param dfInRadians the value to multiple by an angle in the indicated
893 : * units to transform to radians. Some standard conversion factors can
894 : * be found in ogr_srs_api.h.
895 : *
896 : * @return OGRERR_NONE on success.
897 : */
898 :
899 46 : OGRErr OGRSpatialReference::SetAngularUnits( const char * pszUnitsName,
900 : double dfInRadians )
901 :
902 : {
903 : OGR_SRSNode *poCS;
904 : OGR_SRSNode *poUnits;
905 : char szValue[128];
906 :
907 46 : bNormInfoSet = FALSE;
908 :
909 46 : poCS = GetAttrNode( "GEOGCS" );
910 :
911 46 : if( poCS == NULL )
912 0 : return OGRERR_FAILURE;
913 :
914 46 : OGRPrintDouble( szValue, dfInRadians );
915 :
916 46 : if( poCS->FindChild( "UNIT" ) >= 0 )
917 : {
918 46 : poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
919 46 : if (poUnits->GetChildCount() < 2)
920 0 : return OGRERR_FAILURE;
921 46 : poUnits->GetChild(0)->SetValue( pszUnitsName );
922 46 : poUnits->GetChild(1)->SetValue( szValue );
923 : }
924 : else
925 : {
926 0 : poUnits = new OGR_SRSNode( "UNIT" );
927 0 : poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
928 0 : poUnits->AddChild( new OGR_SRSNode( szValue ) );
929 :
930 0 : poCS->AddChild( poUnits );
931 : }
932 :
933 46 : return OGRERR_NONE;
934 : }
935 :
936 : /************************************************************************/
937 : /* OSRSetAngularUnits() */
938 : /************************************************************************/
939 :
940 : /**
941 : * \brief Set the angular units for the geographic coordinate system.
942 : *
943 : * This function is the same as OGRSpatialReference::SetAngularUnits()
944 : */
945 0 : OGRErr OSRSetAngularUnits( OGRSpatialReferenceH hSRS,
946 : const char * pszUnits, double dfInRadians )
947 :
948 : {
949 0 : VALIDATE_POINTER1( hSRS, "OSRSetAngularUnits", CE_Failure );
950 :
951 : return ((OGRSpatialReference *) hSRS)->SetAngularUnits( pszUnits,
952 0 : dfInRadians );
953 : }
954 :
955 : /************************************************************************/
956 : /* GetAngularUnits() */
957 : /************************************************************************/
958 :
959 : /**
960 : * \brief Fetch angular geographic coordinate system units.
961 : *
962 : * If no units are available, a value of "degree" and SRS_UA_DEGREE_CONV
963 : * will be assumed. This method only checks directly under the GEOGCS node
964 : * for units.
965 : *
966 : * This method does the same thing as the C function OSRGetAngularUnits().
967 : *
968 : * @param ppszName a pointer to be updated with the pointer to the
969 : * units name. The returned value remains internal to the OGRSpatialReference
970 : * and shouldn't be freed, or modified. It may be invalidated on the next
971 : * OGRSpatialReference call.
972 : *
973 : * @return the value to multiply by angular distances to transform them to
974 : * radians.
975 : */
976 :
977 103998 : double OGRSpatialReference::GetAngularUnits( char ** ppszName ) const
978 :
979 : {
980 103998 : const OGR_SRSNode *poCS = GetAttrNode( "GEOGCS" );
981 :
982 103998 : if( ppszName != NULL )
983 1810 : *ppszName = (char* ) "degree";
984 :
985 103998 : if( poCS == NULL )
986 636 : return CPLAtof(SRS_UA_DEGREE_CONV);
987 :
988 413444 : for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
989 : {
990 413440 : const OGR_SRSNode *poChild = poCS->GetChild(iChild);
991 :
992 413440 : if( EQUAL(poChild->GetValue(),"UNIT")
993 : && poChild->GetChildCount() >= 2 )
994 : {
995 103358 : if( ppszName != NULL )
996 1806 : *ppszName = (char *) poChild->GetChild(0)->GetValue();
997 :
998 103358 : return CPLAtof( poChild->GetChild(1)->GetValue() );
999 : }
1000 : }
1001 :
1002 4 : return 1.0;
1003 : }
1004 :
1005 : /************************************************************************/
1006 : /* OSRGetAngularUnits() */
1007 : /************************************************************************/
1008 :
1009 : /**
1010 : * \brief Fetch angular geographic coordinate system units.
1011 : *
1012 : * This function is the same as OGRSpatialReference::GetAngularUnits()
1013 : */
1014 0 : double OSRGetAngularUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
1015 :
1016 : {
1017 0 : VALIDATE_POINTER1( hSRS, "OSRGetAngularUnits", 0 );
1018 :
1019 0 : return ((OGRSpatialReference *) hSRS)->GetAngularUnits( ppszName );
1020 : }
1021 :
1022 : /************************************************************************/
1023 : /* SetLinearUnitsAndUpdateParameters() */
1024 : /************************************************************************/
1025 :
1026 : /**
1027 : * \brief Set the linear units for the projection.
1028 : *
1029 : * This method creates a UNIT subnode with the specified values as a
1030 : * child of the PROJCS or LOCAL_CS node. It works the same as the
1031 : * SetLinearUnits() method, but it also updates all existing linear
1032 : * projection parameter values from the old units to the new units.
1033 : *
1034 : * @param pszName the units name to be used. Some preferred units
1035 : * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
1036 : * and SRS_UL_US_FOOT.
1037 : *
1038 : * @param dfInMeters the value to multiple by a length in the indicated
1039 : * units to transform to meters. Some standard conversion factors can
1040 : * be found in ogr_srs_api.h.
1041 : *
1042 : * @return OGRERR_NONE on success.
1043 : */
1044 :
1045 40 : OGRErr OGRSpatialReference::SetLinearUnitsAndUpdateParameters(
1046 : const char *pszName, double dfInMeters )
1047 :
1048 : {
1049 40 : double dfOldInMeters = GetLinearUnits();
1050 40 : OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
1051 :
1052 40 : if( dfInMeters == 0.0 )
1053 0 : return OGRERR_FAILURE;
1054 :
1055 40 : if( dfInMeters == dfOldInMeters || poPROJCS == NULL )
1056 32 : return SetLinearUnits( pszName, dfInMeters );
1057 :
1058 104 : for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
1059 : {
1060 96 : const OGR_SRSNode *poChild = poPROJCS->GetChild(iChild);
1061 :
1062 96 : if( EQUAL(poChild->GetValue(),"PARAMETER")
1063 : && poChild->GetChildCount() > 1 )
1064 : {
1065 46 : char *pszParmName = CPLStrdup(poChild->GetChild(0)->GetValue());
1066 :
1067 46 : if( IsLinearParameter( pszParmName ) )
1068 : {
1069 16 : double dfOldValue = GetProjParm( pszParmName );
1070 :
1071 : SetProjParm( pszParmName,
1072 16 : dfOldValue * dfOldInMeters / dfInMeters );
1073 : }
1074 :
1075 46 : CPLFree( pszParmName );
1076 : }
1077 : }
1078 :
1079 8 : return SetLinearUnits( pszName, dfInMeters );
1080 : }
1081 :
1082 : /************************************************************************/
1083 : /* OSRSetLinearUnitsAndUpdateParameters() */
1084 : /************************************************************************/
1085 :
1086 : /**
1087 : * \brief Set the linear units for the projection.
1088 : *
1089 : * This function is the same as OGRSpatialReference::SetLinearUnitsAndUpdateParameters()
1090 : */
1091 2 : OGRErr OSRSetLinearUnitsAndUpdateParameters( OGRSpatialReferenceH hSRS,
1092 : const char * pszUnits,
1093 : double dfInMeters )
1094 :
1095 : {
1096 2 : VALIDATE_POINTER1( hSRS, "OSRSetLinearUnitsAndUpdateParameters",
1097 : CE_Failure );
1098 :
1099 : return ((OGRSpatialReference *) hSRS)->
1100 2 : SetLinearUnitsAndUpdateParameters( pszUnits, dfInMeters );
1101 : }
1102 :
1103 : /************************************************************************/
1104 : /* SetLinearUnits() */
1105 : /************************************************************************/
1106 :
1107 : /**
1108 : * \brief Set the linear units for the projection.
1109 : *
1110 : * This method creates a UNIT subnode with the specified values as a
1111 : * child of the PROJCS, GEOCCS or LOCAL_CS node.
1112 : *
1113 : * This method does the same as the C function OSRSetLinearUnits().
1114 : *
1115 : * @param pszUnitsName the units name to be used. Some preferred units
1116 : * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
1117 : * and SRS_UL_US_FOOT.
1118 : *
1119 : * @param dfInMeters the value to multiple by a length in the indicated
1120 : * units to transform to meters. Some standard conversion factors can
1121 : * be found in ogr_srs_api.h.
1122 : *
1123 : * @return OGRERR_NONE on success.
1124 : */
1125 :
1126 25614 : OGRErr OGRSpatialReference::SetLinearUnits( const char * pszUnitsName,
1127 : double dfInMeters )
1128 :
1129 : {
1130 25614 : return SetTargetLinearUnits( NULL, pszUnitsName, dfInMeters );
1131 : }
1132 :
1133 : /************************************************************************/
1134 : /* OSRSetLinearUnits() */
1135 : /************************************************************************/
1136 :
1137 : /**
1138 : * \brief Set the linear units for the projection.
1139 : *
1140 : * This function is the same as OGRSpatialReference::SetLinearUnits()
1141 : */
1142 4 : OGRErr OSRSetLinearUnits( OGRSpatialReferenceH hSRS,
1143 : const char * pszUnits, double dfInMeters )
1144 :
1145 : {
1146 4 : VALIDATE_POINTER1( hSRS, "OSRSetLinearUnits", CE_Failure );
1147 :
1148 : return ((OGRSpatialReference *) hSRS)->SetLinearUnits( pszUnits,
1149 4 : dfInMeters );
1150 : }
1151 :
1152 : /************************************************************************/
1153 : /* SetTargetLinearUnits() */
1154 : /************************************************************************/
1155 :
1156 : /**
1157 : * \brief Set the linear units for the projection.
1158 : *
1159 : * This method creates a UNIT subnode with the specified values as a
1160 : * child of the target node.
1161 : *
1162 : * This method does the same as the C function OSRSetTargetLinearUnits().
1163 : *
1164 : * @param pszTargetKey the keyword to set the linear units for. ie. "PROJCS" or "VERT_CS"
1165 : *
1166 : * @param pszUnitsName the units name to be used. Some preferred units
1167 : * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
1168 : * and SRS_UL_US_FOOT.
1169 : *
1170 : * @param dfInMeters the value to multiple by a length in the indicated
1171 : * units to transform to meters. Some standard conversion factors can
1172 : * be found in ogr_srs_api.h.
1173 : *
1174 : * @return OGRERR_NONE on success.
1175 : *
1176 : * @since OGR 1.9.0
1177 : */
1178 :
1179 25632 : OGRErr OGRSpatialReference::SetTargetLinearUnits( const char *pszTargetKey,
1180 : const char * pszUnitsName,
1181 : double dfInMeters )
1182 :
1183 : {
1184 : OGR_SRSNode *poCS;
1185 : OGR_SRSNode *poUnits;
1186 : char szValue[128];
1187 :
1188 25632 : bNormInfoSet = FALSE;
1189 :
1190 25632 : if( pszTargetKey == NULL )
1191 : {
1192 25614 : poCS = GetAttrNode( "PROJCS" );
1193 :
1194 25614 : if( poCS == NULL )
1195 102 : poCS = GetAttrNode( "LOCAL_CS" );
1196 25614 : if( poCS == NULL )
1197 10 : poCS = GetAttrNode( "GEOCCS" );
1198 25614 : if( poCS == NULL && IsVertical() )
1199 0 : poCS = GetAttrNode( "VERT_CS" );
1200 : }
1201 : else
1202 18 : poCS = GetAttrNode( pszTargetKey );
1203 :
1204 25632 : if( poCS == NULL )
1205 0 : return OGRERR_FAILURE;
1206 :
1207 25632 : if( dfInMeters == (int) dfInMeters )
1208 22264 : sprintf( szValue, "%d", (int) dfInMeters );
1209 : else
1210 3368 : OGRPrintDouble( szValue, dfInMeters );
1211 :
1212 25632 : if( poCS->FindChild( "UNIT" ) >= 0 )
1213 : {
1214 210 : poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
1215 210 : if (poUnits->GetChildCount() < 2)
1216 0 : return OGRERR_FAILURE;
1217 210 : poUnits->GetChild(0)->SetValue( pszUnitsName );
1218 210 : poUnits->GetChild(1)->SetValue( szValue );
1219 210 : if( poUnits->FindChild( "AUTHORITY" ) != -1 )
1220 12 : poUnits->DestroyChild( poUnits->FindChild( "AUTHORITY" ) );
1221 : }
1222 : else
1223 : {
1224 25422 : poUnits = new OGR_SRSNode( "UNIT" );
1225 50844 : poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
1226 50844 : poUnits->AddChild( new OGR_SRSNode( szValue ) );
1227 :
1228 25422 : poCS->AddChild( poUnits );
1229 : }
1230 :
1231 25632 : return OGRERR_NONE;
1232 : }
1233 :
1234 : /************************************************************************/
1235 : /* OSRSetLinearUnits() */
1236 : /************************************************************************/
1237 :
1238 : /**
1239 : * \brief Set the linear units for the target node.
1240 : *
1241 : * This function is the same as OGRSpatialReference::SetTargetLinearUnits()
1242 : *
1243 : * @since OGR 1.9.0
1244 : */
1245 2 : OGRErr OSRSetTargetLinearUnits( OGRSpatialReferenceH hSRS,
1246 : const char *pszTargetKey,
1247 : const char * pszUnits, double dfInMeters )
1248 :
1249 : {
1250 2 : VALIDATE_POINTER1( hSRS, "OSRSetTargetLinearUnits", CE_Failure );
1251 :
1252 : return ((OGRSpatialReference *) hSRS)->
1253 2 : SetTargetLinearUnits( pszTargetKey, pszUnits, dfInMeters );
1254 : }
1255 :
1256 : /************************************************************************/
1257 : /* GetLinearUnits() */
1258 : /************************************************************************/
1259 :
1260 : /**
1261 : * \brief Fetch linear projection units.
1262 : *
1263 : * If no units are available, a value of "Meters" and 1.0 will be assumed.
1264 : * This method only checks directly under the PROJCS, GEOCCS or LOCAL_CS node
1265 : * for units.
1266 : *
1267 : * This method does the same thing as the C function OSRGetLinearUnits()/
1268 : *
1269 : * @param ppszName a pointer to be updated with the pointer to the
1270 : * units name. The returned value remains internal to the OGRSpatialReference
1271 : * and shouldn't be freed, or modified. It may be invalidated on the next
1272 : * OGRSpatialReference call.
1273 : *
1274 : * @return the value to multiply by linear distances to transform them to
1275 : * meters.
1276 : */
1277 :
1278 169300 : double OGRSpatialReference::GetLinearUnits( char ** ppszName ) const
1279 :
1280 : {
1281 169300 : return GetTargetLinearUnits( NULL, ppszName );
1282 : }
1283 :
1284 : /************************************************************************/
1285 : /* OSRGetLinearUnits() */
1286 : /************************************************************************/
1287 :
1288 : /**
1289 : * \brief Fetch linear projection units.
1290 : *
1291 : * This function is the same as OGRSpatialReference::GetLinearUnits()
1292 : */
1293 0 : double OSRGetLinearUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
1294 :
1295 : {
1296 0 : VALIDATE_POINTER1( hSRS, "OSRGetLinearUnits", 0 );
1297 :
1298 0 : return ((OGRSpatialReference *) hSRS)->GetLinearUnits( ppszName );
1299 : }
1300 :
1301 : /************************************************************************/
1302 : /* GetTargetLinearUnits() */
1303 : /************************************************************************/
1304 :
1305 : /**
1306 : * \brief Fetch linear units for target.
1307 : *
1308 : * If no units are available, a value of "Meters" and 1.0 will be assumed.
1309 : *
1310 : * This method does the same thing as the C function OSRGetTargetLinearUnits()/
1311 : *
1312 : * @param pszTargetKey the key to look on. ie. "PROJCS" or "VERT_CS".
1313 : * @param ppszName a pointer to be updated with the pointer to the
1314 : * units name. The returned value remains internal to the OGRSpatialReference
1315 : * and shouldn't be freed, or modified. It may be invalidated on the next
1316 : * OGRSpatialReference call.
1317 : *
1318 : * @return the value to multiply by linear distances to transform them to
1319 : * meters.
1320 : *
1321 : * @since OGR 1.9.0
1322 : */
1323 :
1324 169402 : double OGRSpatialReference::GetTargetLinearUnits( const char *pszTargetKey,
1325 : char ** ppszName ) const
1326 :
1327 : {
1328 : const OGR_SRSNode *poCS;
1329 :
1330 169402 : if( pszTargetKey == NULL )
1331 : {
1332 169300 : poCS = GetAttrNode( "PROJCS" );
1333 :
1334 169300 : if( poCS == NULL )
1335 2712 : poCS = GetAttrNode( "LOCAL_CS" );
1336 169300 : if( poCS == NULL )
1337 2706 : poCS = GetAttrNode( "GEOCCS" );
1338 169300 : if( poCS == NULL && IsVertical() )
1339 0 : poCS = GetAttrNode( "VERT_CS" );
1340 : }
1341 : else
1342 102 : poCS = GetAttrNode( pszTargetKey );
1343 :
1344 169402 : if( ppszName != NULL )
1345 5418 : *ppszName = (char*) "unknown";
1346 :
1347 169402 : if( poCS == NULL )
1348 2798 : return 1.0;
1349 :
1350 1366652 : for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
1351 : {
1352 1362782 : const OGR_SRSNode *poChild = poCS->GetChild(iChild);
1353 :
1354 1362782 : if( EQUAL(poChild->GetValue(),"UNIT")
1355 : && poChild->GetChildCount() >= 2 )
1356 : {
1357 162734 : if( ppszName != NULL )
1358 1516 : *ppszName = (char *) poChild->GetChild(0)->GetValue();
1359 :
1360 162734 : return CPLAtof( poChild->GetChild(1)->GetValue() );
1361 : }
1362 : }
1363 :
1364 3870 : return 1.0;
1365 : }
1366 :
1367 : /************************************************************************/
1368 : /* OSRGetTargetLinearUnits() */
1369 : /************************************************************************/
1370 :
1371 : /**
1372 : * \brief Fetch linear projection units.
1373 : *
1374 : * This function is the same as OGRSpatialReference::GetTargetLinearUnits()
1375 : *
1376 : * @since OGR 1.9.0
1377 : */
1378 0 : double OSRGetTargetLinearUnits( OGRSpatialReferenceH hSRS,
1379 : const char *pszTargetKey,
1380 : char ** ppszName )
1381 :
1382 : {
1383 0 : VALIDATE_POINTER1( hSRS, "OSRGetTargetLinearUnits", 0 );
1384 :
1385 : return ((OGRSpatialReference *) hSRS)->GetTargetLinearUnits( pszTargetKey,
1386 0 : ppszName );
1387 : }
1388 :
1389 : /************************************************************************/
1390 : /* GetPrimeMeridian() */
1391 : /************************************************************************/
1392 :
1393 : /**
1394 : * \brief Fetch prime meridian info.
1395 : *
1396 : * Returns the offset of the prime meridian from greenwich in degrees,
1397 : * and the prime meridian name (if requested). If no PRIMEM value exists
1398 : * in the coordinate system definition a value of "Greenwich" and an
1399 : * offset of 0.0 is assumed.
1400 : *
1401 : * If the prime meridian name is returned, the pointer is to an internal
1402 : * copy of the name. It should not be freed, altered or depended on after
1403 : * the next OGR call.
1404 : *
1405 : * This method is the same as the C function OSRGetPrimeMeridian().
1406 : *
1407 : * @param ppszName return location for prime meridian name. If NULL, name
1408 : * is not returned.
1409 : *
1410 : * @return the offset to the GEOGCS prime meridian from greenwich in decimal
1411 : * degrees.
1412 : */
1413 :
1414 67474 : double OGRSpatialReference::GetPrimeMeridian( char **ppszName ) const
1415 :
1416 : {
1417 67474 : const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
1418 :
1419 67474 : if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2
1420 : && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
1421 : {
1422 1178 : if( ppszName != NULL )
1423 0 : *ppszName = (char *) poPRIMEM->GetChild(0)->GetValue();
1424 1178 : return CPLAtof(poPRIMEM->GetChild(1)->GetValue());
1425 : }
1426 :
1427 66296 : if( ppszName != NULL )
1428 10 : *ppszName = (char*) SRS_PM_GREENWICH;
1429 :
1430 66296 : return 0.0;
1431 : }
1432 :
1433 : /************************************************************************/
1434 : /* OSRGetPrimeMeridian() */
1435 : /************************************************************************/
1436 :
1437 : /**
1438 : * \brief Fetch prime meridian info.
1439 : *
1440 : * This function is the same as OGRSpatialReference::GetPrimeMeridian()
1441 : */
1442 2 : double OSRGetPrimeMeridian( OGRSpatialReferenceH hSRS, char **ppszName )
1443 :
1444 : {
1445 2 : VALIDATE_POINTER1( hSRS, "OSRGetPrimeMeridian", 0 );
1446 :
1447 2 : return ((OGRSpatialReference *) hSRS)->GetPrimeMeridian( ppszName );
1448 : }
1449 :
1450 : /************************************************************************/
1451 : /* SetGeogCS() */
1452 : /************************************************************************/
1453 :
1454 : /**
1455 : * \brief Set geographic coordinate system.
1456 : *
1457 : * This method is used to set the datum, ellipsoid, prime meridian and
1458 : * angular units for a geographic coordinate system. It can be used on it's
1459 : * own to establish a geographic spatial reference, or applied to a
1460 : * projected coordinate system to establish the underlying geographic
1461 : * coordinate system.
1462 : *
1463 : * This method does the same as the C function OSRSetGeogCS().
1464 : *
1465 : * @param pszGeogName user visible name for the geographic coordinate system
1466 : * (not to serve as a key).
1467 : *
1468 : * @param pszDatumName key name for this datum. The OpenGIS specification
1469 : * lists some known values, and otherwise EPSG datum names with a standard
1470 : * transformation are considered legal keys.
1471 : *
1472 : * @param pszSpheroidName user visible spheroid name (not to serve as a key)
1473 : *
1474 : * @param dfSemiMajor the semi major axis of the spheroid.
1475 : *
1476 : * @param dfInvFlattening the inverse flattening for the spheroid.
1477 : * This can be computed from the semi minor axis as
1478 : * 1/f = 1.0 / (1.0 - semiminor/semimajor).
1479 : *
1480 : * @param pszPMName the name of the prime merdidian (not to serve as a key)
1481 : * If this is NULL a default value of "Greenwich" will be used.
1482 : *
1483 : * @param dfPMOffset the longitude of greenwich relative to this prime
1484 : * meridian.
1485 : *
1486 : * @param pszAngularUnits the angular units name (see ogr_srs_api.h for some
1487 : * standard names). If NULL a value of "degrees" will be assumed.
1488 : *
1489 : * @param dfConvertToRadians value to multiply angular units by to transform
1490 : * them to radians. A value of SRS_UL_DEGREE_CONV will be used if
1491 : * pszAngularUnits is NULL.
1492 : *
1493 : * @return OGRERR_NONE on success.
1494 : */
1495 :
1496 : OGRErr
1497 38860 : OGRSpatialReference::SetGeogCS( const char * pszGeogName,
1498 : const char * pszDatumName,
1499 : const char * pszSpheroidName,
1500 : double dfSemiMajor, double dfInvFlattening,
1501 : const char * pszPMName, double dfPMOffset,
1502 : const char * pszAngularUnits,
1503 : double dfConvertToRadians )
1504 :
1505 : {
1506 38860 : bNormInfoSet = FALSE;
1507 :
1508 : /* -------------------------------------------------------------------- */
1509 : /* For a geocentric coordinate system we want to set the datum */
1510 : /* and ellipsoid based on the GEOGCS. Create the GEOGCS in a */
1511 : /* temporary srs and use the copy method which has special */
1512 : /* handling for GEOCCS. */
1513 : /* -------------------------------------------------------------------- */
1514 38860 : if( IsGeocentric() )
1515 : {
1516 4 : OGRSpatialReference oGCS;
1517 :
1518 : oGCS.SetGeogCS( pszGeogName, pszDatumName, pszSpheroidName,
1519 : dfSemiMajor, dfInvFlattening,
1520 : pszPMName, dfPMOffset,
1521 4 : pszAngularUnits, dfConvertToRadians );
1522 4 : return CopyGeogCSFrom( &oGCS );
1523 : }
1524 :
1525 : /* -------------------------------------------------------------------- */
1526 : /* Do we already have a GEOGCS? If so, blow it away so it can */
1527 : /* be properly replaced. */
1528 : /* -------------------------------------------------------------------- */
1529 38856 : if( GetAttrNode( "GEOGCS" ) != NULL )
1530 : {
1531 : OGR_SRSNode *poCS;
1532 :
1533 0 : if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
1534 0 : Clear();
1535 0 : else if( (poCS = GetAttrNode( "PROJCS" )) != NULL
1536 : && poCS->FindChild( "GEOGCS" ) != -1 )
1537 0 : poCS->DestroyChild( poCS->FindChild( "GEOGCS" ) );
1538 : else
1539 0 : return OGRERR_FAILURE;
1540 : }
1541 :
1542 : /* -------------------------------------------------------------------- */
1543 : /* Set defaults for various parameters. */
1544 : /* -------------------------------------------------------------------- */
1545 38856 : if( pszGeogName == NULL )
1546 0 : pszGeogName = "unnamed";
1547 :
1548 38856 : if( pszPMName == NULL )
1549 396 : pszPMName = SRS_PM_GREENWICH;
1550 :
1551 38856 : if( pszDatumName == NULL )
1552 236 : pszDatumName = "unknown";
1553 :
1554 38856 : if( pszSpheroidName == NULL )
1555 0 : pszSpheroidName = "unnamed";
1556 :
1557 38856 : if( pszAngularUnits == NULL )
1558 : {
1559 626 : pszAngularUnits = SRS_UA_DEGREE;
1560 626 : dfConvertToRadians = CPLAtof(SRS_UA_DEGREE_CONV);
1561 : }
1562 :
1563 : /* -------------------------------------------------------------------- */
1564 : /* Build the GEOGCS object. */
1565 : /* -------------------------------------------------------------------- */
1566 : char szValue[128];
1567 : OGR_SRSNode *poGeogCS, *poSpheroid, *poDatum, *poPM, *poUnits;
1568 :
1569 38856 : poGeogCS = new OGR_SRSNode( "GEOGCS" );
1570 77712 : poGeogCS->AddChild( new OGR_SRSNode( pszGeogName ) );
1571 :
1572 : /* -------------------------------------------------------------------- */
1573 : /* Setup the spheroid. */
1574 : /* -------------------------------------------------------------------- */
1575 77712 : poSpheroid = new OGR_SRSNode( "SPHEROID" );
1576 77712 : poSpheroid->AddChild( new OGR_SRSNode( pszSpheroidName ) );
1577 :
1578 38856 : OGRPrintDouble( szValue, dfSemiMajor );
1579 77712 : poSpheroid->AddChild( new OGR_SRSNode(szValue) );
1580 :
1581 38856 : OGRPrintDouble( szValue, dfInvFlattening );
1582 77712 : poSpheroid->AddChild( new OGR_SRSNode(szValue) );
1583 :
1584 : /* -------------------------------------------------------------------- */
1585 : /* Setup the Datum. */
1586 : /* -------------------------------------------------------------------- */
1587 77712 : poDatum = new OGR_SRSNode( "DATUM" );
1588 77712 : poDatum->AddChild( new OGR_SRSNode(pszDatumName) );
1589 38856 : poDatum->AddChild( poSpheroid );
1590 :
1591 : /* -------------------------------------------------------------------- */
1592 : /* Setup the prime meridian. */
1593 : /* -------------------------------------------------------------------- */
1594 38856 : if( dfPMOffset == 0.0 )
1595 37910 : strcpy( szValue, "0" );
1596 : else
1597 946 : OGRPrintDouble( szValue, dfPMOffset );
1598 :
1599 38856 : poPM = new OGR_SRSNode( "PRIMEM" );
1600 77712 : poPM->AddChild( new OGR_SRSNode( pszPMName ) );
1601 77712 : poPM->AddChild( new OGR_SRSNode( szValue ) );
1602 :
1603 : /* -------------------------------------------------------------------- */
1604 : /* Setup the rotational units. */
1605 : /* -------------------------------------------------------------------- */
1606 38856 : OGRPrintDouble( szValue, dfConvertToRadians );
1607 :
1608 77712 : poUnits = new OGR_SRSNode( "UNIT" );
1609 77712 : poUnits->AddChild( new OGR_SRSNode(pszAngularUnits) );
1610 77712 : poUnits->AddChild( new OGR_SRSNode(szValue) );
1611 :
1612 : /* -------------------------------------------------------------------- */
1613 : /* Complete the GeogCS */
1614 : /* -------------------------------------------------------------------- */
1615 38856 : poGeogCS->AddChild( poDatum );
1616 38856 : poGeogCS->AddChild( poPM );
1617 38856 : poGeogCS->AddChild( poUnits );
1618 :
1619 : /* -------------------------------------------------------------------- */
1620 : /* Attach below the PROJCS if there is one, or make this the root. */
1621 : /* -------------------------------------------------------------------- */
1622 63784 : if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
1623 24928 : poRoot->InsertChild( poGeogCS, 1 );
1624 : else
1625 13928 : SetRoot( poGeogCS );
1626 :
1627 38856 : return OGRERR_NONE;
1628 : }
1629 :
1630 : /************************************************************************/
1631 : /* OSRSetGeogCS() */
1632 : /************************************************************************/
1633 :
1634 : /**
1635 : * \brief Set geographic coordinate system.
1636 : *
1637 : * This function is the same as OGRSpatialReference::SetGeogCS()
1638 : */
1639 10 : OGRErr OSRSetGeogCS( OGRSpatialReferenceH hSRS,
1640 : const char * pszGeogName,
1641 : const char * pszDatumName,
1642 : const char * pszSpheroidName,
1643 : double dfSemiMajor, double dfInvFlattening,
1644 : const char * pszPMName, double dfPMOffset,
1645 : const char * pszAngularUnits,
1646 : double dfConvertToRadians )
1647 :
1648 : {
1649 10 : VALIDATE_POINTER1( hSRS, "OSRSetGeogCS", CE_Failure );
1650 :
1651 : return ((OGRSpatialReference *) hSRS)->SetGeogCS(
1652 : pszGeogName, pszDatumName,
1653 : pszSpheroidName, dfSemiMajor, dfInvFlattening,
1654 10 : pszPMName, dfPMOffset, pszAngularUnits, dfConvertToRadians );
1655 :
1656 : }
1657 :
1658 : /************************************************************************/
1659 : /* SetWellKnownGeogCS() */
1660 : /************************************************************************/
1661 :
1662 : /**
1663 : * \brief Set a GeogCS based on well known name.
1664 : *
1665 : * This may be called on an empty OGRSpatialReference to make a geographic
1666 : * coordinate system, or on something with an existing PROJCS node to
1667 : * set the underlying geographic coordinate system of a projected coordinate
1668 : * system.
1669 : *
1670 : * The following well known text values are currently supported:
1671 : * <ul>
1672 : * <li> "WGS84": same as "EPSG:4326" but has no dependence on EPSG data files.
1673 : * <li> "WGS72": same as "EPSG:4322" but has no dependence on EPSG data files.
1674 : * <li> "NAD27": same as "EPSG:4267" but has no dependence on EPSG data files.
1675 : * <li> "NAD83": same as "EPSG:4269" but has no dependence on EPSG data files.
1676 : * <li> "EPSG:n": same as doing an ImportFromEPSG(n).
1677 : * </ul>
1678 : *
1679 : * @param pszName name of well known geographic coordinate system.
1680 : * @return OGRERR_NONE on success, or OGRERR_FAILURE if the name isn't
1681 : * recognised, the target object is already initialized, or an EPSG value
1682 : * can't be successfully looked up.
1683 : */
1684 :
1685 3022 : OGRErr OGRSpatialReference::SetWellKnownGeogCS( const char * pszName )
1686 :
1687 : {
1688 3022 : OGRSpatialReference oSRS2;
1689 : OGRErr eErr;
1690 :
1691 : /* -------------------------------------------------------------------- */
1692 : /* Check for EPSG authority numbers. */
1693 : /* -------------------------------------------------------------------- */
1694 3022 : if( EQUALN(pszName, "EPSG:",5) )
1695 : {
1696 18 : eErr = oSRS2.importFromEPSG( atoi(pszName+5) );
1697 18 : if( eErr != OGRERR_NONE )
1698 0 : return eErr;
1699 :
1700 18 : if( !oSRS2.IsGeographic() )
1701 0 : return OGRERR_FAILURE;
1702 :
1703 18 : return CopyGeogCSFrom( &oSRS2 );
1704 : }
1705 :
1706 : /* -------------------------------------------------------------------- */
1707 : /* Check for EPSGA authority numbers. */
1708 : /* -------------------------------------------------------------------- */
1709 3004 : if( EQUALN(pszName, "EPSGA:",6) )
1710 : {
1711 0 : eErr = oSRS2.importFromEPSGA( atoi(pszName+6) );
1712 0 : if( eErr != OGRERR_NONE )
1713 0 : return eErr;
1714 :
1715 0 : if( !oSRS2.IsGeographic() )
1716 0 : return OGRERR_FAILURE;
1717 :
1718 0 : return CopyGeogCSFrom( &oSRS2 );
1719 : }
1720 :
1721 : /* -------------------------------------------------------------------- */
1722 : /* Check for simple names. */
1723 : /* -------------------------------------------------------------------- */
1724 3004 : char *pszWKT = NULL;
1725 :
1726 5778 : if( EQUAL(pszName, "WGS84") || EQUAL(pszName,"CRS84") || EQUAL(pszName,"CRS:84") )
1727 2774 : pszWKT = (char* ) SRS_WKT_WGS84;
1728 :
1729 230 : else if( EQUAL(pszName, "WGS72") )
1730 54 : pszWKT = (char* ) "GEOGCS[\"WGS 72\",DATUM[\"WGS_1972\",SPHEROID[\"WGS 72\",6378135,298.26,AUTHORITY[\"EPSG\",\"7043\"]],TOWGS84[0,0,4.5,0,0,0.554,0.2263],AUTHORITY[\"EPSG\",\"6322\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4322\"]]";
1731 :
1732 328 : else if( EQUAL(pszName, "NAD27") || EQUAL(pszName, "CRS27") || EQUAL(pszName,"CRS:27") )
1733 152 : pszWKT = (char* ) "GEOGCS[\"NAD27\",DATUM[\"North_American_Datum_1927\",SPHEROID[\"Clarke 1866\",6378206.4,294.978698213898,AUTHORITY[\"EPSG\",\"7008\"]],AUTHORITY[\"EPSG\",\"6267\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4267\"]]";
1734 :
1735 46 : else if( EQUAL(pszName, "NAD83") || EQUAL(pszName,"CRS83") || EQUAL(pszName,"CRS:83") )
1736 22 : pszWKT = (char* ) "GEOGCS[\"NAD83\",DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6269\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4269\"]]";
1737 :
1738 : else
1739 2 : return OGRERR_FAILURE;
1740 :
1741 : /* -------------------------------------------------------------------- */
1742 : /* Import the WKT */
1743 : /* -------------------------------------------------------------------- */
1744 3002 : eErr = oSRS2.importFromWkt( &pszWKT );
1745 3002 : if( eErr != OGRERR_NONE )
1746 0 : return eErr;
1747 :
1748 : /* -------------------------------------------------------------------- */
1749 : /* Copy over. */
1750 : /* -------------------------------------------------------------------- */
1751 3002 : return CopyGeogCSFrom( &oSRS2 );
1752 : }
1753 :
1754 : /************************************************************************/
1755 : /* OSRSetWellKnownGeogCS() */
1756 : /************************************************************************/
1757 :
1758 : /**
1759 : * \brief Set a GeogCS based on well known name.
1760 : *
1761 : * This function is the same as OGRSpatialReference::SetWellKnownGeogCS()
1762 : */
1763 74 : OGRErr OSRSetWellKnownGeogCS( OGRSpatialReferenceH hSRS, const char *pszName )
1764 :
1765 : {
1766 74 : VALIDATE_POINTER1( hSRS, "OSRSetWellKnownGeogCS", CE_Failure );
1767 :
1768 74 : return ((OGRSpatialReference *) hSRS)->SetWellKnownGeogCS( pszName );
1769 : }
1770 :
1771 : /************************************************************************/
1772 : /* CopyGeogCSFrom() */
1773 : /************************************************************************/
1774 :
1775 : /**
1776 : * \brief Copy GEOGCS from another OGRSpatialReference.
1777 : *
1778 : * The GEOGCS information is copied into this OGRSpatialReference from another.
1779 : * If this object has a PROJCS root already, the GEOGCS is installed within
1780 : * it, otherwise it is installed as the root.
1781 : *
1782 : * @param poSrcSRS the spatial reference to copy the GEOGCS information from.
1783 : *
1784 : * @return OGRERR_NONE on success or an error code.
1785 : */
1786 :
1787 :
1788 4696 : OGRErr OGRSpatialReference::CopyGeogCSFrom(
1789 : const OGRSpatialReference * poSrcSRS )
1790 :
1791 : {
1792 4696 : const OGR_SRSNode *poGeogCS = NULL;
1793 :
1794 4696 : bNormInfoSet = FALSE;
1795 :
1796 : /* -------------------------------------------------------------------- */
1797 : /* Handle geocentric coordinate systems specially. We just */
1798 : /* want to copy the DATUM and PRIMEM nodes. */
1799 : /* -------------------------------------------------------------------- */
1800 4696 : if( IsGeocentric() )
1801 : {
1802 6 : if( GetRoot()->FindChild( "DATUM" ) != -1 )
1803 0 : GetRoot()->DestroyChild( GetRoot()->FindChild( "DATUM" ) );
1804 6 : if( GetRoot()->FindChild( "PRIMEM" ) != -1 )
1805 0 : GetRoot()->DestroyChild( GetRoot()->FindChild( "PRIMEM" ) );
1806 :
1807 6 : const OGR_SRSNode *poDatum = poSrcSRS->GetAttrNode( "DATUM" );
1808 6 : const OGR_SRSNode *poPrimeM = poSrcSRS->GetAttrNode( "PRIMEM" );
1809 :
1810 6 : if( poDatum == NULL || poPrimeM == NULL )
1811 0 : return OGRERR_FAILURE;
1812 :
1813 6 : poRoot->InsertChild( poDatum->Clone(), 1 );
1814 6 : poRoot->InsertChild( poPrimeM->Clone(), 2 );
1815 :
1816 6 : return OGRERR_NONE;
1817 :
1818 : }
1819 :
1820 : /* -------------------------------------------------------------------- */
1821 : /* Do we already have a GEOGCS? If so, blow it away so it can */
1822 : /* be properly replaced. */
1823 : /* -------------------------------------------------------------------- */
1824 4690 : if( GetAttrNode( "GEOGCS" ) != NULL )
1825 : {
1826 : OGR_SRSNode *poPROJCS;
1827 :
1828 1652 : if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
1829 1642 : Clear();
1830 10 : else if( (poPROJCS = GetAttrNode( "PROJCS" )) != NULL
1831 : && poPROJCS->FindChild( "GEOGCS" ) != -1 )
1832 10 : poPROJCS->DestroyChild( poPROJCS->FindChild( "GEOGCS" ) );
1833 : else
1834 0 : return OGRERR_FAILURE;
1835 : }
1836 :
1837 : /* -------------------------------------------------------------------- */
1838 : /* Find the GEOGCS node on the source. */
1839 : /* -------------------------------------------------------------------- */
1840 4690 : poGeogCS = poSrcSRS->GetAttrNode( "GEOGCS" );
1841 4690 : if( poGeogCS == NULL )
1842 0 : return OGRERR_FAILURE;
1843 :
1844 : /* -------------------------------------------------------------------- */
1845 : /* Attach below the PROJCS if there is one, or make this the root. */
1846 : /* -------------------------------------------------------------------- */
1847 4690 : if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
1848 348 : poRoot->InsertChild( poGeogCS->Clone(), 1 );
1849 : else
1850 4342 : SetRoot( poGeogCS->Clone() );
1851 :
1852 4690 : return OGRERR_NONE;
1853 : }
1854 :
1855 : /************************************************************************/
1856 : /* OSRCopyGeogCSFrom() */
1857 : /************************************************************************/
1858 :
1859 : /**
1860 : * \brief Copy GEOGCS from another OGRSpatialReference.
1861 : *
1862 : * This function is the same as OGRSpatialReference::CopyGeogCSFrom()
1863 : */
1864 0 : OGRErr OSRCopyGeogCSFrom( OGRSpatialReferenceH hSRS,
1865 : OGRSpatialReferenceH hSrcSRS )
1866 :
1867 : {
1868 0 : VALIDATE_POINTER1( hSRS, "OSRCopyGeogCSFrom", CE_Failure );
1869 0 : VALIDATE_POINTER1( hSrcSRS, "OSRCopyGeogCSFrom", CE_Failure );
1870 :
1871 : return ((OGRSpatialReference *) hSRS)->CopyGeogCSFrom(
1872 0 : (const OGRSpatialReference *) hSrcSRS );
1873 : }
1874 :
1875 : /************************************************************************/
1876 : /* SetFromUserInput() */
1877 : /************************************************************************/
1878 :
1879 : /**
1880 : * \brief Set spatial reference from various text formats.
1881 : *
1882 : * This method will examine the provided input, and try to deduce the
1883 : * format, and then use it to initialize the spatial reference system. It
1884 : * may take the following forms:
1885 : *
1886 : * <ol>
1887 : * <li> Well Known Text definition - passed on to importFromWkt().
1888 : * <li> "EPSG:n" - number passed on to importFromEPSG().
1889 : * <li> "EPSGA:n" - number passed on to importFromEPSGA().
1890 : * <li> "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
1891 : * <li> "urn:ogc:def:crs:EPSG::n" - ogc urns
1892 : * <li> PROJ.4 definitions - passed on to importFromProj4().
1893 : * <li> filename - file read for WKT, XML or PROJ.4 definition.
1894 : * <li> well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
1895 : * WGS84 or WGS72.
1896 : * <li> WKT (directly or in a file) in ESRI format should be prefixed with
1897 : * ESRI:: to trigger an automatic morphFromESRI().
1898 : * <li> "IGNF:xxx" - "+init=IGNF:xxx" passed on to importFromProj4().
1899 : * </ol>
1900 : *
1901 : * It is expected that this method will be extended in the future to support
1902 : * XML and perhaps a simplified "minilanguage" for indicating common UTM and
1903 : * State Plane definitions.
1904 : *
1905 : * This method is intended to be flexible, but by it's nature it is
1906 : * imprecise as it must guess information about the format intended. When
1907 : * possible applications should call the specific method appropriate if the
1908 : * input is known to be in a particular format.
1909 : *
1910 : * This method does the same thing as the OSRSetFromUserInput() function.
1911 : *
1912 : * @param pszDefinition text definition to try to deduce SRS from.
1913 : *
1914 : * @return OGRERR_NONE on success, or an error code if the name isn't
1915 : * recognised, the definition is corrupt, or an EPSG value can't be
1916 : * successfully looked up.
1917 : */
1918 :
1919 2531 : OGRErr OGRSpatialReference::SetFromUserInput( const char * pszDefinition )
1920 :
1921 : {
1922 2531 : int bESRI = FALSE;
1923 : OGRErr err;
1924 :
1925 2531 : if( EQUALN(pszDefinition,"ESRI::",6) )
1926 : {
1927 2 : bESRI = TRUE;
1928 2 : pszDefinition += 6;
1929 : }
1930 :
1931 : /* -------------------------------------------------------------------- */
1932 : /* Is it a recognised syntax? */
1933 : /* -------------------------------------------------------------------- */
1934 2531 : if( EQUALN(pszDefinition,"PROJCS",6)
1935 : || EQUALN(pszDefinition,"GEOGCS",6)
1936 : || EQUALN(pszDefinition,"COMPD_CS",8)
1937 : || EQUALN(pszDefinition,"GEOCCS",6)
1938 : || EQUALN(pszDefinition,"VERT_CS",7)
1939 : || EQUALN(pszDefinition,"LOCAL_CS",8) )
1940 : {
1941 1465 : err = importFromWkt( (char **) &pszDefinition );
1942 1465 : if( err == OGRERR_NONE && bESRI )
1943 2 : err = morphFromESRI();
1944 :
1945 1465 : return err;
1946 : }
1947 :
1948 1066 : if( EQUALN(pszDefinition,"EPSG:",5)
1949 : || EQUALN(pszDefinition,"EPSGA:",6) )
1950 : {
1951 : OGRErr eStatus;
1952 :
1953 356 : if( EQUALN(pszDefinition,"EPSG:",5) )
1954 354 : eStatus = importFromEPSG( atoi(pszDefinition+5) );
1955 :
1956 : else /* if( EQUALN(pszDefinition,"EPSGA:",6) ) */
1957 2 : eStatus = importFromEPSGA( atoi(pszDefinition+6) );
1958 :
1959 : // Do we want to turn this into a compound definition
1960 : // with a vertical datum?
1961 356 : if( eStatus == OGRERR_NONE && strchr( pszDefinition, '+' ) != NULL )
1962 : {
1963 2 : OGRSpatialReference oVertSRS;
1964 :
1965 : eStatus = oVertSRS.importFromEPSG(
1966 2 : atoi(strchr(pszDefinition,'+')+1) );
1967 2 : if( eStatus == OGRERR_NONE )
1968 : {
1969 2 : OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
1970 :
1971 2 : Clear();
1972 :
1973 2 : CPLString osName = poHorizSRS->GetChild(0)->GetValue();
1974 2 : osName += " + ";
1975 2 : osName += oVertSRS.GetRoot()->GetValue();
1976 :
1977 2 : SetNode( "COMPD_CS", osName );
1978 2 : GetRoot()->AddChild( poHorizSRS );
1979 2 : GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
1980 : }
1981 :
1982 2 : return eStatus;
1983 : }
1984 : else
1985 354 : return eStatus;
1986 : }
1987 :
1988 710 : if( EQUALN(pszDefinition,"urn:ogc:def:crs:",16)
1989 : || EQUALN(pszDefinition,"urn:ogc:def:crs,crs:",20)
1990 : || EQUALN(pszDefinition,"urn:x-ogc:def:crs:",18)
1991 : || EQUALN(pszDefinition,"urn:opengis:crs:",16)
1992 : || EQUALN(pszDefinition,"urn:opengis:def:crs:",20))
1993 360 : return importFromURN( pszDefinition );
1994 :
1995 350 : if( EQUALN(pszDefinition,"AUTO:",5) )
1996 0 : return importFromWMSAUTO( pszDefinition );
1997 :
1998 350 : if( EQUALN(pszDefinition,"OGC:",4) ) // WMS/WCS OGC codes like OGC:CRS84
1999 0 : return SetWellKnownGeogCS( pszDefinition+4 );
2000 :
2001 350 : if( EQUALN(pszDefinition,"CRS:",4) )
2002 2 : return SetWellKnownGeogCS( pszDefinition );
2003 :
2004 348 : if( EQUALN(pszDefinition,"DICT:",5)
2005 : && strstr(pszDefinition,",") )
2006 : {
2007 0 : char *pszFile = CPLStrdup(pszDefinition+5);
2008 0 : char *pszCode = strstr(pszFile,",") + 1;
2009 :
2010 0 : pszCode[-1] = '\0';
2011 :
2012 0 : err = importFromDict( pszFile, pszCode );
2013 0 : CPLFree( pszFile );
2014 :
2015 0 : if( err == OGRERR_NONE && bESRI )
2016 0 : err = morphFromESRI();
2017 :
2018 0 : return err;
2019 : }
2020 :
2021 348 : if( EQUAL(pszDefinition,"NAD27")
2022 : || EQUAL(pszDefinition,"NAD83")
2023 : || EQUAL(pszDefinition,"WGS84")
2024 : || EQUAL(pszDefinition,"WGS72") )
2025 : {
2026 216 : Clear();
2027 216 : return SetWellKnownGeogCS( pszDefinition );
2028 : }
2029 :
2030 132 : if( strstr(pszDefinition,"+proj") != NULL
2031 : || strstr(pszDefinition,"+init") != NULL )
2032 118 : return importFromProj4( pszDefinition );
2033 :
2034 14 : if( EQUALN(pszDefinition,"IGNF:", 5) )
2035 : {
2036 0 : char* pszProj4Str = (char*) CPLMalloc(6 + strlen(pszDefinition) + 1);
2037 0 : strcpy(pszProj4Str, "+init=");
2038 0 : strcat(pszProj4Str, pszDefinition);
2039 0 : err = importFromProj4( pszProj4Str );
2040 0 : CPLFree(pszProj4Str);
2041 :
2042 0 : return err;
2043 : }
2044 :
2045 14 : if( EQUALN(pszDefinition,"http://",7) )
2046 : {
2047 0 : return importFromUrl (pszDefinition);
2048 : }
2049 :
2050 14 : if( EQUAL(pszDefinition,"osgb:BNG") )
2051 : {
2052 2 : return importFromEPSG(27700);
2053 : }
2054 :
2055 : /* -------------------------------------------------------------------- */
2056 : /* Try to open it as a file. */
2057 : /* -------------------------------------------------------------------- */
2058 : FILE *fp;
2059 12 : int nBufMax = 100000;
2060 : char *pszBufPtr, *pszBuffer;
2061 : int nBytes;
2062 :
2063 12 : fp = VSIFOpen( pszDefinition, "rt" );
2064 12 : if( fp == NULL )
2065 6 : return OGRERR_CORRUPT_DATA;
2066 :
2067 6 : pszBuffer = (char *) CPLMalloc(nBufMax);
2068 6 : nBytes = VSIFRead( pszBuffer, 1, nBufMax-1, fp );
2069 6 : VSIFClose( fp );
2070 :
2071 6 : if( nBytes == nBufMax-1 )
2072 : {
2073 : CPLDebug( "OGR",
2074 : "OGRSpatialReference::SetFromUserInput(%s), opened file\n"
2075 : "but it is to large for our generous buffer. Is it really\n"
2076 0 : "just a WKT definition?", pszDefinition );
2077 0 : CPLFree( pszBuffer );
2078 0 : return OGRERR_FAILURE;
2079 : }
2080 :
2081 6 : pszBuffer[nBytes] = '\0';
2082 :
2083 6 : pszBufPtr = pszBuffer;
2084 12 : while( pszBufPtr[0] == ' ' || pszBufPtr[0] == '\n' )
2085 0 : pszBufPtr++;
2086 :
2087 6 : if( pszBufPtr[0] == '<' )
2088 0 : err = importFromXML( pszBufPtr );
2089 6 : else if( (strstr(pszBuffer,"+proj") != NULL
2090 : || strstr(pszBuffer,"+init") != NULL)
2091 : && (strstr(pszBuffer,"EXTENSION") == NULL
2092 : && strstr(pszBuffer,"extension") == NULL) )
2093 0 : err = importFromProj4( pszBufPtr );
2094 : else
2095 : {
2096 6 : if( EQUALN(pszBufPtr,"ESRI::",6) )
2097 : {
2098 4 : bESRI = TRUE;
2099 4 : pszBufPtr += 6;
2100 : }
2101 :
2102 6 : err = importFromWkt( &pszBufPtr );
2103 6 : if( err == OGRERR_NONE && bESRI )
2104 4 : err = morphFromESRI();
2105 : }
2106 :
2107 6 : CPLFree( pszBuffer );
2108 :
2109 6 : return err;
2110 : }
2111 :
2112 : /************************************************************************/
2113 : /* OSRSetFromUserInput() */
2114 : /************************************************************************/
2115 :
2116 : /**
2117 : * \brief Set spatial reference from various text formats.
2118 : *
2119 : * This function is the same as OGRSpatialReference::SetFromUserInput()
2120 : */
2121 534 : OGRErr CPL_STDCALL OSRSetFromUserInput( OGRSpatialReferenceH hSRS,
2122 : const char *pszDef )
2123 :
2124 : {
2125 534 : VALIDATE_POINTER1( hSRS, "OSRSetFromUserInput", CE_Failure );
2126 :
2127 534 : return ((OGRSpatialReference *) hSRS)->SetFromUserInput( pszDef );
2128 : }
2129 :
2130 :
2131 : /************************************************************************/
2132 : /* ImportFromUrl() */
2133 : /************************************************************************/
2134 :
2135 : /**
2136 : * \brief Set spatial reference from a URL.
2137 : *
2138 : * This method will download the spatial reference at a given URL and
2139 : * feed it into SetFromUserInput for you.
2140 : *
2141 : * This method does the same thing as the OSRImportFromUrl() function.
2142 : *
2143 : * @param pszUrl text definition to try to deduce SRS from.
2144 : *
2145 : * @return OGRERR_NONE on success, or an error code with the curl
2146 : * error message if it is unable to dowload data.
2147 : */
2148 :
2149 4 : OGRErr OGRSpatialReference::importFromUrl( const char * pszUrl )
2150 :
2151 : {
2152 :
2153 :
2154 4 : if( !EQUALN(pszUrl,"http://",7) )
2155 : {
2156 : CPLError( CE_Failure, CPLE_AppDefined,
2157 : "The given string is not recognized as a URL"
2158 0 : "starting with 'http://' -- %s", pszUrl );
2159 0 : return OGRERR_FAILURE;
2160 : }
2161 :
2162 : /* -------------------------------------------------------------------- */
2163 : /* Fetch the result. */
2164 : /* -------------------------------------------------------------------- */
2165 4 : CPLErrorReset();
2166 :
2167 4 : const char* pszHeaders = "HEADERS=Accept: application/x-ogcwkt";
2168 4 : const char* pszTimeout = "TIMEOUT=10";
2169 : char *apszOptions[] = {
2170 : (char *) pszHeaders,
2171 : (char *) pszTimeout,
2172 : NULL
2173 4 : };
2174 :
2175 4 : CPLHTTPResult *psResult = CPLHTTPFetch( pszUrl, apszOptions );
2176 :
2177 : /* -------------------------------------------------------------------- */
2178 : /* Try to handle errors. */
2179 : /* -------------------------------------------------------------------- */
2180 :
2181 4 : if ( psResult == NULL)
2182 0 : return OGRERR_FAILURE;
2183 4 : if( psResult->nDataLen == 0
2184 : || CPLGetLastErrorNo() != 0 || psResult->pabyData == NULL )
2185 : {
2186 0 : if (CPLGetLastErrorNo() == 0)
2187 : {
2188 : CPLError( CE_Failure, CPLE_AppDefined,
2189 0 : "No data was returned from the given URL" );
2190 : }
2191 0 : CPLHTTPDestroyResult( psResult );
2192 0 : return OGRERR_FAILURE;
2193 : }
2194 :
2195 4 : if (psResult->nStatus != 0)
2196 : {
2197 : CPLError( CE_Failure, CPLE_AppDefined,
2198 0 : "Curl reports error: %d: %s", psResult->nStatus, psResult->pszErrBuf );
2199 0 : CPLHTTPDestroyResult( psResult );
2200 0 : return OGRERR_FAILURE;
2201 : }
2202 :
2203 4 : if( EQUALN( (const char*) psResult->pabyData,"http://",7) )
2204 : {
2205 : CPLError( CE_Failure, CPLE_AppDefined,
2206 : "The data that was downloaded also starts with 'http://' "
2207 : "and cannot be passed into SetFromUserInput. Is this "
2208 0 : "really a spatial reference definition? ");
2209 0 : CPLHTTPDestroyResult( psResult );
2210 0 : return OGRERR_FAILURE;
2211 : }
2212 4 : if( OGRERR_NONE != SetFromUserInput( (const char *) psResult->pabyData )) {
2213 0 : CPLHTTPDestroyResult( psResult );
2214 0 : return OGRERR_FAILURE;
2215 : }
2216 :
2217 4 : CPLHTTPDestroyResult( psResult );
2218 4 : return OGRERR_NONE;
2219 : }
2220 :
2221 : /************************************************************************/
2222 : /* OSRimportFromUrl() */
2223 : /************************************************************************/
2224 :
2225 : /**
2226 : * \brief Set spatial reference from a URL.
2227 : *
2228 : * This function is the same as OGRSpatialReference::importFromUrl()
2229 : */
2230 4 : OGRErr OSRImportFromUrl( OGRSpatialReferenceH hSRS, const char *pszUrl )
2231 :
2232 : {
2233 4 : VALIDATE_POINTER1( hSRS, "OSRImportFromUrl", CE_Failure );
2234 :
2235 4 : return ((OGRSpatialReference *) hSRS)->importFromUrl( pszUrl );
2236 : }
2237 :
2238 : /************************************************************************/
2239 : /* importFromURNPart() */
2240 : /************************************************************************/
2241 720 : OGRErr OGRSpatialReference::importFromURNPart(const char* pszAuthority,
2242 : const char* pszCode,
2243 : const char* pszURN)
2244 : {
2245 :
2246 : /* -------------------------------------------------------------------- */
2247 : /* Is this an EPSG code? Note that we import it with EPSG */
2248 : /* preferred axis ordering for geographic coordinate systems! */
2249 : /* -------------------------------------------------------------------- */
2250 720 : if( EQUALN(pszAuthority,"EPSG:",5) )
2251 716 : return importFromEPSGA( atoi(pszCode) );
2252 :
2253 : /* -------------------------------------------------------------------- */
2254 : /* Is this an IAU code? Lets try for the IAU2000 dictionary. */
2255 : /* -------------------------------------------------------------------- */
2256 4 : if( EQUALN(pszAuthority,"IAU",3) )
2257 0 : return importFromDict( "IAU2000.wkt", pszCode );
2258 :
2259 : /* -------------------------------------------------------------------- */
2260 : /* Is this an OGC code? */
2261 : /* -------------------------------------------------------------------- */
2262 4 : if( !EQUALN(pszAuthority,"OGC:",4) )
2263 : {
2264 : CPLError( CE_Failure, CPLE_AppDefined,
2265 : "URN %s has unrecognised authority.",
2266 0 : pszURN );
2267 0 : return OGRERR_FAILURE;
2268 : }
2269 :
2270 4 : if( EQUALN(pszCode,"CRS84",5) )
2271 2 : return SetWellKnownGeogCS( pszCode );
2272 2 : else if( EQUALN(pszCode,"CRS83",5) )
2273 0 : return SetWellKnownGeogCS( pszCode );
2274 2 : else if( EQUALN(pszCode,"CRS27",5) )
2275 0 : return SetWellKnownGeogCS( pszCode );
2276 :
2277 : /* -------------------------------------------------------------------- */
2278 : /* Handle auto codes. We need to convert from format */
2279 : /* AUTO42001:99:8888 to format AUTO:42001,99,8888. */
2280 : /* -------------------------------------------------------------------- */
2281 2 : else if( EQUALN(pszCode,"AUTO",4) )
2282 : {
2283 : char szWMSAuto[100];
2284 : int i;
2285 :
2286 2 : if( strlen(pszCode) > sizeof(szWMSAuto)-2 )
2287 0 : return OGRERR_FAILURE;
2288 :
2289 2 : strcpy( szWMSAuto, "AUTO:" );
2290 2 : strcpy( szWMSAuto + 5, pszCode + 4 );
2291 28 : for( i = 5; szWMSAuto[i] != '\0'; i++ )
2292 : {
2293 26 : if( szWMSAuto[i] == ':' )
2294 4 : szWMSAuto[i] = ',';
2295 : }
2296 :
2297 2 : return importFromWMSAUTO( szWMSAuto );
2298 : }
2299 :
2300 : /* -------------------------------------------------------------------- */
2301 : /* Not a recognise OGC item. */
2302 : /* -------------------------------------------------------------------- */
2303 : CPLError( CE_Failure, CPLE_AppDefined,
2304 : "URN %s value not supported.",
2305 0 : pszURN );
2306 :
2307 0 : return OGRERR_FAILURE;
2308 : }
2309 :
2310 : /************************************************************************/
2311 : /* importFromURN() */
2312 : /* */
2313 : /* See OGC recommendation paper 06-023r1 or later for details. */
2314 : /************************************************************************/
2315 :
2316 : /**
2317 : * \brief Initialize from OGC URN.
2318 : *
2319 : * Initializes this spatial reference from a coordinate system defined
2320 : * by an OGC URN prefixed with "urn:ogc:def:crs:" per recommendation
2321 : * paper 06-023r1. Currently EPSG and OGC authority values are supported,
2322 : * including OGC auto codes, but not including CRS1 or CRS88 (NAVD88).
2323 : *
2324 : * This method is also support through SetFromUserInput() which can
2325 : * normally be used for URNs.
2326 : *
2327 : * @param pszURN the urn string.
2328 : *
2329 : * @return OGRERR_NONE on success or an error code.
2330 : */
2331 :
2332 718 : OGRErr OGRSpatialReference::importFromURN( const char *pszURN )
2333 :
2334 : {
2335 : const char *pszCur;
2336 :
2337 718 : if( EQUALN(pszURN,"urn:ogc:def:crs:",16) )
2338 698 : pszCur = pszURN + 16;
2339 20 : else if( EQUALN(pszURN,"urn:ogc:def:crs,crs:",20) )
2340 2 : pszCur = pszURN + 20;
2341 18 : else if( EQUALN(pszURN,"urn:x-ogc:def:crs:",18) )
2342 18 : pszCur = pszURN + 18;
2343 0 : else if( EQUALN(pszURN,"urn:opengis:crs:",16) )
2344 0 : pszCur = pszURN + 16;
2345 0 : else if( EQUALN(pszURN,"urn:opengis:def:crs:",20) )
2346 0 : pszCur = pszURN + 20;
2347 : else
2348 : {
2349 : CPLError( CE_Failure, CPLE_AppDefined,
2350 0 : "URN %s not a supported format.", pszURN );
2351 0 : return OGRERR_FAILURE;
2352 : }
2353 :
2354 : /* -------------------------------------------------------------------- */
2355 : /* Clear any existing definition. */
2356 : /* -------------------------------------------------------------------- */
2357 718 : if( GetRoot() != NULL )
2358 : {
2359 0 : delete poRoot;
2360 0 : poRoot = NULL;
2361 : }
2362 :
2363 : /* -------------------------------------------------------------------- */
2364 : /* Find code (ignoring version) out of string like: */
2365 : /* */
2366 : /* authority:[version]:code */
2367 : /* -------------------------------------------------------------------- */
2368 718 : const char *pszAuthority = pszCur;
2369 :
2370 : // skip authority
2371 4304 : while( *pszCur != ':' && *pszCur )
2372 2868 : pszCur++;
2373 718 : if( *pszCur == ':' )
2374 718 : pszCur++;
2375 :
2376 : // skip version
2377 718 : const char* pszBeforeVersion = pszCur;
2378 1536 : while( *pszCur != ':' && *pszCur )
2379 100 : pszCur++;
2380 718 : if( *pszCur == ':' )
2381 704 : pszCur++;
2382 : else
2383 : /* We come here in the case, the content to parse is authority:code (instead of authority::code) */
2384 : /* which is probably illegal according to http://www.opengeospatial.org/ogcUrnPolicy */
2385 : /* but such content is found for example in what is returned by GeoServer */
2386 14 : pszCur = pszBeforeVersion;
2387 :
2388 718 : const char *pszCode = pszCur;
2389 :
2390 718 : const char* pszComma = strchr(pszCur, ',');
2391 718 : if (pszComma == NULL)
2392 716 : return importFromURNPart(pszAuthority, pszCode, pszURN);
2393 :
2394 :
2395 : /* There's a second part with the vertical SRS */
2396 2 : pszCur = pszComma + 1;
2397 2 : if (strncmp(pszCur, "crs:", 4) != 0)
2398 : {
2399 : CPLError( CE_Failure, CPLE_AppDefined,
2400 0 : "URN %s not a supported format.", pszURN );
2401 0 : return OGRERR_FAILURE;
2402 : }
2403 :
2404 2 : pszCur += 4;
2405 :
2406 2 : char* pszFirstCode = CPLStrdup(pszCode);
2407 2 : pszFirstCode[pszComma - pszCode] = '\0';
2408 2 : OGRErr eStatus = importFromURNPart(pszAuthority, pszFirstCode, pszURN);
2409 2 : CPLFree(pszFirstCode);
2410 :
2411 : // Do we want to turn this into a compound definition
2412 : // with a vertical datum?
2413 2 : if( eStatus == OGRERR_NONE )
2414 : {
2415 2 : OGRSpatialReference oVertSRS;
2416 :
2417 : /* -------------------------------------------------------------------- */
2418 : /* Find code (ignoring version) out of string like: */
2419 : /* */
2420 : /* authority:[version]:code */
2421 : /* -------------------------------------------------------------------- */
2422 2 : pszAuthority = pszCur;
2423 :
2424 : // skip authority
2425 12 : while( *pszCur != ':' && *pszCur )
2426 8 : pszCur++;
2427 2 : if( *pszCur == ':' )
2428 2 : pszCur++;
2429 :
2430 : // skip version
2431 2 : pszBeforeVersion = pszCur;
2432 4 : while( *pszCur != ':' && *pszCur )
2433 0 : pszCur++;
2434 2 : if( *pszCur == ':' )
2435 2 : pszCur++;
2436 : else
2437 0 : pszCur = pszBeforeVersion;
2438 :
2439 2 : pszCode = pszCur;
2440 :
2441 2 : eStatus = oVertSRS.importFromURNPart(pszAuthority, pszCode, pszURN);
2442 2 : if( eStatus == OGRERR_NONE )
2443 : {
2444 2 : OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
2445 :
2446 2 : Clear();
2447 :
2448 2 : CPLString osName = poHorizSRS->GetChild(0)->GetValue();
2449 2 : osName += " + ";
2450 2 : osName += oVertSRS.GetRoot()->GetValue();
2451 :
2452 2 : SetNode( "COMPD_CS", osName );
2453 2 : GetRoot()->AddChild( poHorizSRS );
2454 2 : GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
2455 : }
2456 :
2457 2 : return eStatus;
2458 : }
2459 : else
2460 0 : return eStatus;
2461 : }
2462 :
2463 : /************************************************************************/
2464 : /* importFromWMSAUTO() */
2465 : /************************************************************************/
2466 :
2467 : /**
2468 : * \brief Initialize from WMSAUTO string.
2469 : *
2470 : * Note that the WMS 1.3 specification does not include the
2471 : * units code, while apparently earlier specs do. We try to
2472 : * guess around this.
2473 : *
2474 : * @param pszDefinition the WMSAUTO string
2475 : *
2476 : * @return OGRERR_NONE on success or an error code.
2477 : */
2478 2 : OGRErr OGRSpatialReference::importFromWMSAUTO( const char * pszDefinition )
2479 :
2480 : {
2481 : char **papszTokens;
2482 : int nProjId, nUnitsId;
2483 2 : double dfRefLong, dfRefLat = 0.0;
2484 :
2485 : /* -------------------------------------------------------------------- */
2486 : /* Tokenize */
2487 : /* -------------------------------------------------------------------- */
2488 2 : if( EQUALN(pszDefinition,"AUTO:",5) )
2489 2 : pszDefinition += 5;
2490 :
2491 2 : papszTokens = CSLTokenizeStringComplex( pszDefinition, ",", FALSE, TRUE );
2492 :
2493 2 : if( CSLCount(papszTokens) == 4 )
2494 : {
2495 0 : nProjId = atoi(papszTokens[0]);
2496 0 : nUnitsId = atoi(papszTokens[1]);
2497 0 : dfRefLong = CPLAtof(papszTokens[2]);
2498 0 : dfRefLat = CPLAtof(papszTokens[3]);
2499 : }
2500 2 : else if( CSLCount(papszTokens) == 3 && atoi(papszTokens[0]) == 42005 )
2501 : {
2502 0 : nProjId = atoi(papszTokens[0]);
2503 0 : nUnitsId = atoi(papszTokens[1]);
2504 0 : dfRefLong = CPLAtof(papszTokens[2]);
2505 0 : dfRefLat = 0.0;
2506 : }
2507 2 : else if( CSLCount(papszTokens) == 3 )
2508 : {
2509 2 : nProjId = atoi(papszTokens[0]);
2510 2 : nUnitsId = 9001;
2511 2 : dfRefLong = CPLAtof(papszTokens[1]);
2512 2 : dfRefLat = CPLAtof(papszTokens[2]);
2513 :
2514 : }
2515 0 : else if( CSLCount(papszTokens) == 2 && atoi(papszTokens[0]) == 42005 )
2516 : {
2517 0 : nProjId = atoi(papszTokens[0]);
2518 0 : nUnitsId = 9001;
2519 0 : dfRefLong = CPLAtof(papszTokens[1]);
2520 : }
2521 : else
2522 : {
2523 0 : CSLDestroy( papszTokens );
2524 : CPLError( CE_Failure, CPLE_AppDefined,
2525 : "AUTO projection has wrong number of arguments, expected\n"
2526 : "AUTO:proj_id,units_id,ref_long,ref_lat or"
2527 0 : "AUTO:proj_id,ref_long,ref_lat" );
2528 0 : return OGRERR_FAILURE;
2529 : }
2530 :
2531 2 : CSLDestroy( papszTokens );
2532 :
2533 : /* -------------------------------------------------------------------- */
2534 : /* Build coordsys. */
2535 : /* -------------------------------------------------------------------- */
2536 2 : Clear();
2537 :
2538 2 : switch( nProjId )
2539 : {
2540 : case 42001: // Auto UTM
2541 : SetUTM( (int) floor( (dfRefLong + 180.0) / 6.0 ) + 1,
2542 2 : dfRefLat >= 0.0 );
2543 2 : break;
2544 :
2545 : case 42002: // Auto TM (strangely very UTM-like).
2546 : SetTM( 0, dfRefLong, 0.9996,
2547 0 : 500000.0, (dfRefLat >= 0.0) ? 0.0 : 10000000.0 );
2548 0 : break;
2549 :
2550 : case 42003: // Auto Orthographic.
2551 0 : SetOrthographic( dfRefLat, dfRefLong, 0.0, 0.0 );
2552 0 : break;
2553 :
2554 : case 42004: // Auto Equirectangular
2555 0 : SetEquirectangular( dfRefLat, dfRefLong, 0.0, 0.0 );
2556 0 : break;
2557 :
2558 : case 42005:
2559 0 : SetMollweide( dfRefLong, 0.0, 0.0 );
2560 0 : break;
2561 :
2562 : default:
2563 : CPLError( CE_Failure, CPLE_AppDefined,
2564 : "Unsupported projection id in importFromWMSAUTO(): %d",
2565 0 : nProjId );
2566 0 : return OGRERR_FAILURE;
2567 : }
2568 :
2569 : /* -------------------------------------------------------------------- */
2570 : /* Set units. */
2571 : /* -------------------------------------------------------------------- */
2572 :
2573 2 : switch( nUnitsId )
2574 : {
2575 : case 9001:
2576 2 : SetLinearUnits( SRS_UL_METER, 1.0 );
2577 2 : break;
2578 :
2579 : case 9002:
2580 0 : SetLinearUnits( "Foot", 0.3048 );
2581 0 : break;
2582 :
2583 : case 9003:
2584 0 : SetLinearUnits( "US survey foot", CPLAtof(SRS_UL_US_FOOT_CONV) );
2585 0 : break;
2586 :
2587 : default:
2588 : CPLError( CE_Failure, CPLE_AppDefined,
2589 : "Unsupported units code (%d).",
2590 0 : nUnitsId );
2591 0 : return OGRERR_FAILURE;
2592 : break;
2593 : }
2594 :
2595 2 : SetAuthority( "PROJCS|UNIT", "EPSG", nUnitsId );
2596 :
2597 : /* -------------------------------------------------------------------- */
2598 : /* Set WGS84. */
2599 : /* -------------------------------------------------------------------- */
2600 2 : SetWellKnownGeogCS( "WGS84" );
2601 :
2602 2 : return OGRERR_NONE;
2603 : }
2604 :
2605 : /************************************************************************/
2606 : /* GetSemiMajor() */
2607 : /************************************************************************/
2608 :
2609 : /**
2610 : * \brief Get spheroid semi major axis.
2611 : *
2612 : * This method does the same thing as the C function OSRGetSemiMajor().
2613 : *
2614 : * @param pnErr if non-NULL set to OGRERR_FAILURE if semi major axis
2615 : * can be found.
2616 : *
2617 : * @return semi-major axis, or SRS_WGS84_SEMIMAJOR if it can't be found.
2618 : */
2619 :
2620 5124 : double OGRSpatialReference::GetSemiMajor( OGRErr * pnErr ) const
2621 :
2622 : {
2623 5124 : const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
2624 :
2625 5124 : if( pnErr != NULL )
2626 1878 : *pnErr = OGRERR_NONE;
2627 :
2628 5124 : if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
2629 : {
2630 5120 : return CPLAtof( poSpheroid->GetChild(1)->GetValue() );
2631 : }
2632 : else
2633 : {
2634 4 : if( pnErr != NULL )
2635 4 : *pnErr = OGRERR_FAILURE;
2636 :
2637 4 : return SRS_WGS84_SEMIMAJOR;
2638 : }
2639 : }
2640 :
2641 : /************************************************************************/
2642 : /* OSRGetSemiMajor() */
2643 : /************************************************************************/
2644 :
2645 : /**
2646 : * \brief Get spheroid semi major axis.
2647 : *
2648 : * This function is the same as OGRSpatialReference::GetSemiMajor()
2649 : */
2650 8 : double OSRGetSemiMajor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
2651 :
2652 : {
2653 8 : VALIDATE_POINTER1( hSRS, "OSRGetSemiMajor", 0 );
2654 :
2655 8 : return ((OGRSpatialReference *) hSRS)->GetSemiMajor( pnErr );
2656 : }
2657 :
2658 : /************************************************************************/
2659 : /* GetInvFlattening() */
2660 : /************************************************************************/
2661 :
2662 : /**
2663 : * \brief Get spheroid inverse flattening.
2664 : *
2665 : * This method does the same thing as the C function OSRGetInvFlattening().
2666 : *
2667 : * @param pnErr if non-NULL set to OGRERR_FAILURE if no inverse flattening
2668 : * can be found.
2669 : *
2670 : * @return inverse flattening, or SRS_WGS84_INVFLATTENING if it can't be found.
2671 : */
2672 :
2673 4828 : double OGRSpatialReference::GetInvFlattening( OGRErr * pnErr ) const
2674 :
2675 : {
2676 4828 : const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
2677 :
2678 4828 : if( pnErr != NULL )
2679 1878 : *pnErr = OGRERR_NONE;
2680 :
2681 4828 : if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
2682 : {
2683 4824 : return CPLAtof( poSpheroid->GetChild(2)->GetValue() );
2684 : }
2685 : else
2686 : {
2687 4 : if( pnErr != NULL )
2688 4 : *pnErr = OGRERR_FAILURE;
2689 :
2690 4 : return SRS_WGS84_INVFLATTENING;
2691 : }
2692 : }
2693 :
2694 : /************************************************************************/
2695 : /* OSRGetInvFlattening() */
2696 : /************************************************************************/
2697 :
2698 : /**
2699 : * \brief Get spheroid inverse flattening.
2700 : *
2701 : * This function is the same as OGRSpatialReference::GetInvFlattening()
2702 : */
2703 8 : double OSRGetInvFlattening( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
2704 :
2705 : {
2706 8 : VALIDATE_POINTER1( hSRS, "OSRGetInvFlattening", 0 );
2707 :
2708 8 : return ((OGRSpatialReference *) hSRS)->GetInvFlattening( pnErr );
2709 : }
2710 :
2711 : /************************************************************************/
2712 : /* GetSemiMinor() */
2713 : /************************************************************************/
2714 :
2715 : /**
2716 : * \brief Get spheroid semi minor axis.
2717 : *
2718 : * This method does the same thing as the C function OSRGetSemiMinor().
2719 : *
2720 : * @param pnErr if non-NULL set to OGRERR_FAILURE if semi minor axis
2721 : * can be found.
2722 : *
2723 : * @return semi-minor axis, or WGS84 semi minor if it can't be found.
2724 : */
2725 :
2726 364 : double OGRSpatialReference::GetSemiMinor( OGRErr * pnErr ) const
2727 :
2728 : {
2729 : double dfInvFlattening, dfSemiMajor;
2730 :
2731 364 : dfSemiMajor = GetSemiMajor( pnErr );
2732 364 : dfInvFlattening = GetInvFlattening( pnErr );
2733 :
2734 364 : if( ABS(dfInvFlattening) < 0.000000000001 )
2735 44 : return dfSemiMajor;
2736 : else
2737 320 : return dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
2738 : }
2739 :
2740 : /************************************************************************/
2741 : /* OSRGetSemiMinor() */
2742 : /************************************************************************/
2743 :
2744 : /**
2745 : * \brief Get spheroid semi minor axis.
2746 : *
2747 : * This function is the same as OGRSpatialReference::GetSemiMinor()
2748 : */
2749 6 : double OSRGetSemiMinor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
2750 :
2751 : {
2752 6 : VALIDATE_POINTER1( hSRS, "OSRGetSemiMinor", 0 );
2753 :
2754 6 : return ((OGRSpatialReference *) hSRS)->GetSemiMinor( pnErr );
2755 : }
2756 :
2757 : /************************************************************************/
2758 : /* SetLocalCS() */
2759 : /************************************************************************/
2760 :
2761 : /**
2762 : * \brief Set the user visible LOCAL_CS name.
2763 : *
2764 : * This method is the same as the C function OSRSetLocalCS().
2765 : *
2766 : * This method will ensure a LOCAL_CS node is created as the root,
2767 : * and set the provided name on it. It must be used before SetLinearUnits().
2768 : *
2769 : * @param pszName the user visible name to assign. Not used as a key.
2770 : *
2771 : * @return OGRERR_NONE on success.
2772 : */
2773 :
2774 82 : OGRErr OGRSpatialReference::SetLocalCS( const char * pszName )
2775 :
2776 : {
2777 82 : OGR_SRSNode *poCS = GetAttrNode( "LOCAL_CS" );
2778 :
2779 82 : if( poCS == NULL && GetRoot() != NULL )
2780 : {
2781 : CPLDebug( "OGR",
2782 : "OGRSpatialReference::SetLocalCS(%s) failed.\n"
2783 : "It appears an incompatible root node (%s) already exists.\n",
2784 0 : pszName, GetRoot()->GetValue() );
2785 0 : return OGRERR_FAILURE;
2786 : }
2787 : else
2788 : {
2789 82 : SetNode( "LOCAL_CS", pszName );
2790 82 : return OGRERR_NONE;
2791 : }
2792 : }
2793 :
2794 : /************************************************************************/
2795 : /* OSRSetLocalCS() */
2796 : /************************************************************************/
2797 :
2798 : /**
2799 : * \brief Set the user visible LOCAL_CS name.
2800 : *
2801 : * This function is the same as OGRSpatialReference::SetLocalCS()
2802 : */
2803 0 : OGRErr OSRSetLocalCS( OGRSpatialReferenceH hSRS, const char * pszName )
2804 :
2805 : {
2806 0 : VALIDATE_POINTER1( hSRS, "OSRSetLocalCS", CE_Failure );
2807 :
2808 0 : return ((OGRSpatialReference *) hSRS)->SetLocalCS( pszName );
2809 : }
2810 :
2811 : /************************************************************************/
2812 : /* SetGeocCS() */
2813 : /************************************************************************/
2814 :
2815 : /**
2816 : * \brief Set the user visible GEOCCS name.
2817 : *
2818 : * This method is the same as the C function OSRSetGeocCS().
2819 :
2820 : * This method will ensure a GEOCCS node is created as the root,
2821 : * and set the provided name on it. If used on a GEOGCS coordinate system,
2822 : * the DATUM and PRIMEM nodes from the GEOGCS will be tarnsferred over to
2823 : * the GEOGCS.
2824 : *
2825 : * @param pszName the user visible name to assign. Not used as a key.
2826 : *
2827 : * @return OGRERR_NONE on success.
2828 : *
2829 : * @since OGR 1.9.0
2830 : */
2831 :
2832 18 : OGRErr OGRSpatialReference::SetGeocCS( const char * pszName )
2833 :
2834 : {
2835 18 : OGR_SRSNode *poGeogCS = NULL;
2836 18 : OGR_SRSNode *poGeocCS = GetAttrNode( "GEOCCS" );
2837 :
2838 18 : if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
2839 : {
2840 4 : poGeogCS = poRoot;
2841 4 : poRoot = NULL;
2842 : }
2843 :
2844 18 : if( poGeocCS == NULL && GetRoot() != NULL )
2845 : {
2846 : CPLDebug( "OGR",
2847 : "OGRSpatialReference::SetGeocCS(%s) failed.\n"
2848 : "It appears an incompatible root node (%s) already exists.\n",
2849 2 : pszName, GetRoot()->GetValue() );
2850 2 : return OGRERR_FAILURE;
2851 : }
2852 :
2853 16 : SetNode( "GEOCCS", pszName );
2854 :
2855 16 : if( poGeogCS != NULL )
2856 : {
2857 4 : OGR_SRSNode *poDatum = poGeogCS->GetNode( "DATUM" );
2858 4 : OGR_SRSNode *poPRIMEM = poGeogCS->GetNode( "PRIMEM" );
2859 4 : if ( poDatum != NULL && poPRIMEM != NULL )
2860 : {
2861 2 : poRoot->InsertChild( poDatum->Clone(), 1 );
2862 2 : poRoot->InsertChild( poPRIMEM->Clone(), 2 );
2863 : }
2864 4 : delete poGeogCS;
2865 : }
2866 :
2867 16 : return OGRERR_NONE;
2868 : }
2869 :
2870 : /************************************************************************/
2871 : /* OSRSetGeocCS() */
2872 : /************************************************************************/
2873 :
2874 : /**
2875 : * \brief Set the user visible PROJCS name.
2876 : *
2877 : * This function is the same as OGRSpatialReference::SetGeocCS()
2878 : *
2879 : * @since OGR 1.9.0
2880 : */
2881 10 : OGRErr OSRSetGeocCS( OGRSpatialReferenceH hSRS, const char * pszName )
2882 :
2883 : {
2884 10 : VALIDATE_POINTER1( hSRS, "OSRSetGeocCS", CE_Failure );
2885 :
2886 10 : return ((OGRSpatialReference *) hSRS)->SetGeocCS( pszName );
2887 : }
2888 :
2889 : /************************************************************************/
2890 : /* SetVertCS() */
2891 : /************************************************************************/
2892 :
2893 : /**
2894 : * \brief Set the user visible VERT_CS name.
2895 : *
2896 : * This method is the same as the C function OSRSetVertCS().
2897 :
2898 : * This method will ensure a VERT_CS node is created if needed. If the
2899 : * existing coordinate system is GEOGCS or PROJCS rooted, then it will be
2900 : * turned into a COMPD_CS.
2901 : *
2902 : * @param pszVertCSName the user visible name of the vertical coordinate
2903 : * system. Not used as a key.
2904 : *
2905 : * @param pszVertDatumName the user visible name of the vertical datum. It
2906 : * is helpful if this matches the EPSG name.
2907 : *
2908 : * @param nVertDatumType the OGC vertical datum type, usually 2005.
2909 : *
2910 : * @return OGRERR_NONE on success.
2911 : *
2912 : * @since OGR 1.9.0
2913 : */
2914 :
2915 16 : OGRErr OGRSpatialReference::SetVertCS( const char * pszVertCSName,
2916 : const char * pszVertDatumName,
2917 : int nVertDatumType )
2918 :
2919 : {
2920 : /* -------------------------------------------------------------------- */
2921 : /* Handle the case where we want to make a compound coordinate */
2922 : /* system. */
2923 : /* -------------------------------------------------------------------- */
2924 16 : if( IsProjected() || IsGeographic() )
2925 : {
2926 0 : OGR_SRSNode *poNewRoot = new OGR_SRSNode( "COMPD_CS" );
2927 0 : poNewRoot->AddChild( poRoot );
2928 0 : poRoot = poNewRoot;
2929 : }
2930 :
2931 16 : else if( GetAttrNode( "VERT_CS" ) == NULL )
2932 16 : Clear();
2933 :
2934 : /* -------------------------------------------------------------------- */
2935 : /* If we already have a VERT_CS, wipe and recreate the root */
2936 : /* otherwise create the VERT_CS now. */
2937 : /* -------------------------------------------------------------------- */
2938 16 : OGR_SRSNode *poVertCS = GetAttrNode( "VERT_CS" );
2939 :
2940 16 : if( poVertCS != NULL )
2941 : {
2942 0 : poVertCS->ClearChildren();
2943 : }
2944 : else
2945 : {
2946 16 : poVertCS = new OGR_SRSNode( "VERT_CS" );
2947 16 : if( poRoot != NULL && EQUAL(poRoot->GetValue(),"COMPD_CS") )
2948 : {
2949 0 : poRoot->AddChild( poVertCS );
2950 : }
2951 : else
2952 16 : SetRoot( poVertCS );
2953 : }
2954 :
2955 : /* -------------------------------------------------------------------- */
2956 : /* Set the name, datumname, and type. */
2957 : /* -------------------------------------------------------------------- */
2958 : OGR_SRSNode *poVertDatum;
2959 :
2960 16 : poVertCS->AddChild( new OGR_SRSNode( pszVertCSName ) );
2961 :
2962 32 : poVertDatum = new OGR_SRSNode( "VERT_DATUM" );
2963 16 : poVertCS->AddChild( poVertDatum );
2964 :
2965 32 : poVertDatum->AddChild( new OGR_SRSNode( pszVertDatumName ) );
2966 :
2967 16 : CPLString osVertDatumType;
2968 16 : osVertDatumType.Printf( "%d", nVertDatumType );
2969 16 : poVertDatum->AddChild( new OGR_SRSNode( osVertDatumType ) );
2970 :
2971 : // add default axis node.
2972 16 : OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
2973 :
2974 32 : poAxis->AddChild( new OGR_SRSNode( "Up" ) );
2975 16 : poAxis->AddChild( new OGR_SRSNode( "UP" ) );
2976 :
2977 16 : poVertCS->AddChild( poAxis );
2978 :
2979 16 : return OGRERR_NONE;
2980 : }
2981 :
2982 : /************************************************************************/
2983 : /* OSRSetVertCS() */
2984 : /************************************************************************/
2985 :
2986 : /**
2987 : * \brief Setup the vertical coordinate system.
2988 : *
2989 : * This function is the same as OGRSpatialReference::SetVertCS()
2990 : *
2991 : * @since OGR 1.9.0
2992 : */
2993 0 : OGRErr OSRSetVertCS( OGRSpatialReferenceH hSRS,
2994 : const char * pszVertCSName,
2995 : const char * pszVertDatumName,
2996 : int nVertDatumType )
2997 :
2998 : {
2999 0 : VALIDATE_POINTER1( hSRS, "OSRSetVertCS", CE_Failure );
3000 :
3001 : return ((OGRSpatialReference *) hSRS)->SetVertCS( pszVertCSName,
3002 : pszVertDatumName,
3003 0 : nVertDatumType );
3004 : }
3005 :
3006 : /************************************************************************/
3007 : /* SetCompoundCS() */
3008 : /************************************************************************/
3009 :
3010 : /**
3011 : * \brief Setup a compound coordinate system.
3012 : *
3013 : * This method is the same as the C function OSRSetCompoundCS().
3014 :
3015 : * This method is replace the current SRS with a COMPD_CS coordinate system
3016 : * consisting of the passed in horizontal and vertical coordinate systems.
3017 : *
3018 : * @param pszName the name of the compound coordinate system.
3019 : *
3020 : * @param poHorizSRS the horizontal SRS (PROJCS or GEOGCS).
3021 : *
3022 : * @param poVertSRS the vertical SRS (VERT_CS).
3023 : *
3024 : * @return OGRERR_NONE on success.
3025 : */
3026 :
3027 : OGRErr
3028 2 : OGRSpatialReference::SetCompoundCS( const char *pszName,
3029 : const OGRSpatialReference *poHorizSRS,
3030 : const OGRSpatialReference *poVertSRS )
3031 :
3032 : {
3033 : /* -------------------------------------------------------------------- */
3034 : /* Verify these are legal horizontal and vertical coordinate */
3035 : /* systems. */
3036 : /* -------------------------------------------------------------------- */
3037 2 : if( !poVertSRS->IsVertical() )
3038 : {
3039 : CPLError( CE_Failure, CPLE_AppDefined,
3040 0 : "SetCompoundCS() fails, vertical component is not VERT_CS." );
3041 0 : return OGRERR_FAILURE;
3042 : }
3043 2 : if( !poHorizSRS->IsProjected()
3044 : && !poHorizSRS->IsGeographic() )
3045 : {
3046 : CPLError( CE_Failure, CPLE_AppDefined,
3047 0 : "SetCompoundCS() fails, horizontal component is not PROJCS or GEOGCS." );
3048 0 : return OGRERR_FAILURE;
3049 : }
3050 :
3051 : /* -------------------------------------------------------------------- */
3052 : /* Replace with compound srs. */
3053 : /* -------------------------------------------------------------------- */
3054 2 : Clear();
3055 :
3056 2 : poRoot = new OGR_SRSNode( "COMPD_CS" );
3057 4 : poRoot->AddChild( new OGR_SRSNode( pszName ) );
3058 2 : poRoot->AddChild( poHorizSRS->GetRoot()->Clone() );
3059 2 : poRoot->AddChild( poVertSRS->GetRoot()->Clone() );
3060 :
3061 2 : return OGRERR_NONE;
3062 : }
3063 :
3064 : /************************************************************************/
3065 : /* OSRSetCompoundCS() */
3066 : /************************************************************************/
3067 :
3068 : /**
3069 : * \brief Setup a compound coordinate system.
3070 : *
3071 : * This function is the same as OGRSpatialReference::SetCompoundCS()
3072 : */
3073 2 : OGRErr OSRSetCompoundCS( OGRSpatialReferenceH hSRS,
3074 : const char *pszName,
3075 : OGRSpatialReferenceH hHorizSRS,
3076 : OGRSpatialReferenceH hVertSRS )
3077 :
3078 : {
3079 2 : VALIDATE_POINTER1( hSRS, "OSRSetCompoundCS", CE_Failure );
3080 2 : VALIDATE_POINTER1( hHorizSRS, "OSRSetCompoundCS", CE_Failure );
3081 2 : VALIDATE_POINTER1( hVertSRS, "OSRSetCompoundCS", CE_Failure );
3082 :
3083 : return ((OGRSpatialReference *) hSRS)->
3084 : SetCompoundCS( pszName,
3085 : (OGRSpatialReference *) hHorizSRS,
3086 2 : (OGRSpatialReference *) hVertSRS );
3087 : }
3088 :
3089 : /************************************************************************/
3090 : /* SetProjCS() */
3091 : /************************************************************************/
3092 :
3093 : /**
3094 : * \brief Set the user visible PROJCS name.
3095 : *
3096 : * This method is the same as the C function OSRSetProjCS().
3097 : *
3098 : * This method will ensure a PROJCS node is created as the root,
3099 : * and set the provided name on it. If used on a GEOGCS coordinate system,
3100 : * the GEOGCS node will be demoted to be a child of the new PROJCS root.
3101 : *
3102 : * @param pszName the user visible name to assign. Not used as a key.
3103 : *
3104 : * @return OGRERR_NONE on success.
3105 : */
3106 :
3107 196 : OGRErr OGRSpatialReference::SetProjCS( const char * pszName )
3108 :
3109 : {
3110 196 : OGR_SRSNode *poGeogCS = NULL;
3111 196 : OGR_SRSNode *poProjCS = GetAttrNode( "PROJCS" );
3112 :
3113 196 : if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
3114 : {
3115 12 : poGeogCS = poRoot;
3116 12 : poRoot = NULL;
3117 : }
3118 :
3119 196 : if( poProjCS == NULL && GetRoot() != NULL )
3120 : {
3121 : CPLDebug( "OGR",
3122 : "OGRSpatialReference::SetProjCS(%s) failed.\n"
3123 : "It appears an incompatible root node (%s) already exists.\n",
3124 0 : pszName, GetRoot()->GetValue() );
3125 0 : return OGRERR_FAILURE;
3126 : }
3127 :
3128 196 : SetNode( "PROJCS", pszName );
3129 :
3130 196 : if( poGeogCS != NULL )
3131 12 : poRoot->InsertChild( poGeogCS, 1 );
3132 :
3133 196 : return OGRERR_NONE;
3134 : }
3135 :
3136 : /************************************************************************/
3137 : /* OSRSetProjCS() */
3138 : /************************************************************************/
3139 :
3140 : /**
3141 : * \brief Set the user visible PROJCS name.
3142 : *
3143 : * This function is the same as OGRSpatialReference::SetProjCS()
3144 : */
3145 4 : OGRErr OSRSetProjCS( OGRSpatialReferenceH hSRS, const char * pszName )
3146 :
3147 : {
3148 4 : VALIDATE_POINTER1( hSRS, "OSRSetProjCS", CE_Failure );
3149 :
3150 4 : return ((OGRSpatialReference *) hSRS)->SetProjCS( pszName );
3151 : }
3152 :
3153 : /************************************************************************/
3154 : /* SetProjection() */
3155 : /************************************************************************/
3156 :
3157 : /**
3158 : * \brief Set a projection name.
3159 : *
3160 : * This method is the same as the C function OSRSetProjection().
3161 : *
3162 : * @param pszProjection the projection name, which should be selected from
3163 : * the macros in ogr_srs_api.h, such as SRS_PT_TRANSVERSE_MERCATOR.
3164 : *
3165 : * @return OGRERR_NONE on success.
3166 : */
3167 :
3168 25260 : OGRErr OGRSpatialReference::SetProjection( const char * pszProjection )
3169 :
3170 : {
3171 25260 : OGR_SRSNode *poGeogCS = NULL;
3172 : OGRErr eErr;
3173 :
3174 25260 : if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
3175 : {
3176 246 : poGeogCS = poRoot;
3177 246 : poRoot = NULL;
3178 : }
3179 :
3180 25260 : if( !GetAttrNode( "PROJCS" ) )
3181 : {
3182 802 : SetNode( "PROJCS", "unnamed" );
3183 : }
3184 :
3185 25260 : eErr = SetNode( "PROJCS|PROJECTION", pszProjection );
3186 25260 : if( eErr != OGRERR_NONE )
3187 0 : return eErr;
3188 :
3189 25260 : if( poGeogCS != NULL )
3190 246 : poRoot->InsertChild( poGeogCS, 1 );
3191 :
3192 25260 : return OGRERR_NONE;
3193 : }
3194 :
3195 : /************************************************************************/
3196 : /* OSRSetProjection() */
3197 : /************************************************************************/
3198 :
3199 : /**
3200 : * \brief Set a projection name.
3201 : *
3202 : * This function is the same as OGRSpatialReference::SetProjection()
3203 : */
3204 0 : OGRErr OSRSetProjection( OGRSpatialReferenceH hSRS,
3205 : const char * pszProjection )
3206 :
3207 : {
3208 0 : return ((OGRSpatialReference *) hSRS)->SetProjection( pszProjection );
3209 : }
3210 :
3211 : /************************************************************************/
3212 : /* SetProjParm() */
3213 : /************************************************************************/
3214 :
3215 : /**
3216 : * \brief Set a projection parameter value.
3217 : *
3218 : * Adds a new PARAMETER under the PROJCS with the indicated name and value.
3219 : *
3220 : * This method is the same as the C function OSRSetProjParm().
3221 : *
3222 : * Please check http://www.remotesensing.org/geotiff/proj_list pages for
3223 : * legal parameter names for specific projections.
3224 : *
3225 : *
3226 : * @param pszParmName the parameter name, which should be selected from
3227 : * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN.
3228 : *
3229 : * @param dfValue value to assign.
3230 : *
3231 : * @return OGRERR_NONE on success.
3232 : */
3233 :
3234 130765 : OGRErr OGRSpatialReference::SetProjParm( const char * pszParmName,
3235 : double dfValue )
3236 :
3237 : {
3238 130765 : OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
3239 : OGR_SRSNode *poParm;
3240 : char szValue[64];
3241 :
3242 130765 : if( poPROJCS == NULL )
3243 4 : return OGRERR_FAILURE;
3244 :
3245 130761 : OGRPrintDouble( szValue, dfValue );
3246 :
3247 : /* -------------------------------------------------------------------- */
3248 : /* Try to find existing parameter with this name. */
3249 : /* -------------------------------------------------------------------- */
3250 922295 : for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
3251 : {
3252 791640 : poParm = poPROJCS->GetChild( iChild );
3253 :
3254 791640 : if( EQUAL(poParm->GetValue(),"PARAMETER")
3255 : && poParm->GetChildCount() == 2
3256 : && EQUAL(poParm->GetChild(0)->GetValue(),pszParmName) )
3257 : {
3258 106 : poParm->GetChild(1)->SetValue( szValue );
3259 106 : return OGRERR_NONE;
3260 : }
3261 : }
3262 :
3263 : /* -------------------------------------------------------------------- */
3264 : /* Otherwise create a new parameter and append. */
3265 : /* -------------------------------------------------------------------- */
3266 130655 : poParm = new OGR_SRSNode( "PARAMETER" );
3267 261310 : poParm->AddChild( new OGR_SRSNode( pszParmName ) );
3268 261310 : poParm->AddChild( new OGR_SRSNode( szValue ) );
3269 :
3270 130655 : poPROJCS->AddChild( poParm );
3271 :
3272 130655 : return OGRERR_NONE;
3273 : }
3274 :
3275 : /************************************************************************/
3276 : /* OSRSetProjParm() */
3277 : /************************************************************************/
3278 :
3279 : /**
3280 : * \brief Set a projection parameter value.
3281 : *
3282 : * This function is the same as OGRSpatialReference::SetProjParm()
3283 : */
3284 284 : OGRErr OSRSetProjParm( OGRSpatialReferenceH hSRS,
3285 : const char * pszParmName, double dfValue )
3286 :
3287 : {
3288 284 : VALIDATE_POINTER1( hSRS, "OSRSetProjParm", CE_Failure );
3289 :
3290 284 : return ((OGRSpatialReference *) hSRS)->SetProjParm( pszParmName, dfValue );
3291 : }
3292 :
3293 : /************************************************************************/
3294 : /* FindProjParm() */
3295 : /************************************************************************/
3296 :
3297 : /**
3298 : * \brief Return the child index of the named projection parameter on
3299 : * its parent PROJCS node.
3300 : *
3301 : * @param pszParameter projection parameter to look for
3302 : * @param poPROJCS projection CS node to look in. If NULL is passed,
3303 : * the PROJCS node of the SpatialReference object will be searched.
3304 : *
3305 : * @return the child index of the named projection parameter. -1 on failure
3306 : */
3307 340724 : int OGRSpatialReference::FindProjParm( const char *pszParameter,
3308 : const OGR_SRSNode *poPROJCS ) const
3309 :
3310 : {
3311 340724 : const OGR_SRSNode *poParameter = NULL;
3312 :
3313 340724 : if( poPROJCS == NULL )
3314 1928 : poPROJCS = GetAttrNode( "PROJCS" );
3315 :
3316 340724 : if( poPROJCS == NULL )
3317 1862 : return -1;
3318 :
3319 : /* -------------------------------------------------------------------- */
3320 : /* Search for requested parameter. */
3321 : /* -------------------------------------------------------------------- */
3322 : int iChild;
3323 :
3324 2176992 : for( iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
3325 : {
3326 2160348 : poParameter = poPROJCS->GetChild(iChild);
3327 :
3328 2160348 : if( EQUAL(poParameter->GetValue(),"PARAMETER")
3329 : && poParameter->GetChildCount() == 2
3330 : && EQUAL(poPROJCS->GetChild(iChild)->GetChild(0)->GetValue(),
3331 : pszParameter) )
3332 : {
3333 322218 : return iChild;
3334 : }
3335 : }
3336 :
3337 : /* -------------------------------------------------------------------- */
3338 : /* Try similar names, for selected parameters. */
3339 : /* -------------------------------------------------------------------- */
3340 16644 : iChild = -1;
3341 :
3342 16644 : if( EQUAL(pszParameter,SRS_PP_LATITUDE_OF_ORIGIN) )
3343 : {
3344 202 : iChild = FindProjParm( SRS_PP_LATITUDE_OF_CENTER, poPROJCS );
3345 : }
3346 16442 : else if( EQUAL(pszParameter,SRS_PP_CENTRAL_MERIDIAN) )
3347 : {
3348 82 : iChild = FindProjParm(SRS_PP_LONGITUDE_OF_CENTER, poPROJCS );
3349 82 : if( iChild == -1 )
3350 6 : iChild = FindProjParm(SRS_PP_LONGITUDE_OF_ORIGIN, poPROJCS );
3351 : }
3352 :
3353 16644 : return iChild;
3354 : }
3355 :
3356 : /************************************************************************/
3357 : /* GetProjParm() */
3358 : /************************************************************************/
3359 :
3360 : /**
3361 : * \brief Fetch a projection parameter value.
3362 : *
3363 : * NOTE: This code should be modified to translate non degree angles into
3364 : * degrees based on the GEOGCS unit. This has not yet been done.
3365 : *
3366 : * This method is the same as the C function OSRGetProjParm().
3367 : *
3368 : * @param pszName the name of the parameter to fetch, from the set of
3369 : * SRS_PP codes in ogr_srs_api.h.
3370 : *
3371 : * @param dfDefaultValue the value to return if this parameter doesn't exist.
3372 : *
3373 : * @param pnErr place to put error code on failure. Ignored if NULL.
3374 : *
3375 : * @return value of parameter.
3376 : */
3377 :
3378 333794 : double OGRSpatialReference::GetProjParm( const char * pszName,
3379 : double dfDefaultValue,
3380 : OGRErr *pnErr ) const
3381 :
3382 : {
3383 333794 : const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
3384 :
3385 333794 : if( pnErr != NULL )
3386 41782 : *pnErr = OGRERR_NONE;
3387 :
3388 : /* -------------------------------------------------------------------- */
3389 : /* Find the desired parameter. */
3390 : /* -------------------------------------------------------------------- */
3391 333794 : int iChild = FindProjParm( pszName, poPROJCS );
3392 :
3393 333794 : if( iChild != -1 )
3394 : {
3395 316502 : const OGR_SRSNode *poParameter = NULL;
3396 316502 : poParameter = poPROJCS->GetChild(iChild);
3397 316502 : return CPLAtof(poParameter->GetChild(1)->GetValue());
3398 : }
3399 :
3400 : /* -------------------------------------------------------------------- */
3401 : /* Return default value on failure. */
3402 : /* -------------------------------------------------------------------- */
3403 17292 : if( pnErr != NULL )
3404 74 : *pnErr = OGRERR_FAILURE;
3405 :
3406 17292 : return dfDefaultValue;
3407 : }
3408 :
3409 : /************************************************************************/
3410 : /* OSRGetProjParm() */
3411 : /************************************************************************/
3412 :
3413 : /**
3414 : * \brief Fetch a projection parameter value.
3415 : *
3416 : * This function is the same as OGRSpatialReference::GetProjParm()
3417 : */
3418 17288 : double OSRGetProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
3419 : double dfDefaultValue, OGRErr *pnErr )
3420 :
3421 : {
3422 17288 : VALIDATE_POINTER1( hSRS, "OSRGetProjParm", 0 );
3423 :
3424 : return ((OGRSpatialReference *) hSRS)->
3425 17288 : GetProjParm(pszName, dfDefaultValue, pnErr);
3426 : }
3427 :
3428 : /************************************************************************/
3429 : /* GetNormProjParm() */
3430 : /************************************************************************/
3431 :
3432 : /**
3433 : * \brief Fetch a normalized projection parameter value.
3434 : *
3435 : * This method is the same as GetProjParm() except that the value of
3436 : * the parameter is "normalized" into degrees or meters depending on
3437 : * whether it is linear or angular.
3438 : *
3439 : * This method is the same as the C function OSRGetNormProjParm().
3440 : *
3441 : * @param pszName the name of the parameter to fetch, from the set of
3442 : * SRS_PP codes in ogr_srs_api.h.
3443 : *
3444 : * @param dfDefaultValue the value to return if this parameter doesn't exist.
3445 : *
3446 : * @param pnErr place to put error code on failure. Ignored if NULL.
3447 : *
3448 : * @return value of parameter.
3449 : */
3450 :
3451 41782 : double OGRSpatialReference::GetNormProjParm( const char * pszName,
3452 : double dfDefaultValue,
3453 : OGRErr *pnErr ) const
3454 :
3455 : {
3456 : double dfRawResult;
3457 : OGRErr nError;
3458 :
3459 41782 : if( pnErr == NULL )
3460 41782 : pnErr = &nError;
3461 :
3462 41782 : GetNormInfo();
3463 :
3464 41782 : dfRawResult = GetProjParm( pszName, dfDefaultValue, pnErr );
3465 :
3466 : // If we got the default just return it unadjusted.
3467 41782 : if( *pnErr != OGRERR_NONE )
3468 74 : return dfRawResult;
3469 :
3470 41708 : if( dfToDegrees != 1.0 && IsAngularParameter(pszName) )
3471 12 : dfRawResult *= dfToDegrees;
3472 :
3473 41708 : if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
3474 304 : return dfRawResult * dfToMeter;
3475 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
3476 : else if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
3477 : return dfRawResult + dfFromGreenwich;
3478 : #endif
3479 : else
3480 41404 : return dfRawResult;
3481 : }
3482 :
3483 : /************************************************************************/
3484 : /* OSRGetNormProjParm() */
3485 : /************************************************************************/
3486 :
3487 : /**
3488 : * \brief This function is the same as OGRSpatialReference::
3489 : *
3490 : * This function is the same as OGRSpatialReference::GetNormProjParm()
3491 : */
3492 0 : double OSRGetNormProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
3493 : double dfDefaultValue, OGRErr *pnErr )
3494 :
3495 : {
3496 0 : VALIDATE_POINTER1( hSRS, "OSRGetNormProjParm", 0 );
3497 :
3498 : return ((OGRSpatialReference *) hSRS)->
3499 0 : GetNormProjParm(pszName, dfDefaultValue, pnErr);
3500 : }
3501 :
3502 : /************************************************************************/
3503 : /* SetNormProjParm() */
3504 : /************************************************************************/
3505 :
3506 : /**
3507 : * \brief Set a projection parameter with a normalized value.
3508 : *
3509 : * This method is the same as SetProjParm() except that the value of
3510 : * the parameter passed in is assumed to be in "normalized" form (decimal
3511 : * degrees for angular values, meters for linear values. The values are
3512 : * converted in a form suitable for the GEOGCS and linear units in effect.
3513 : *
3514 : * This method is the same as the C function OSRSetNormProjParm().
3515 : *
3516 : * @param pszName the parameter name, which should be selected from
3517 : * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN.
3518 : *
3519 : * @param dfValue value to assign.
3520 : *
3521 : * @return OGRERR_NONE on success.
3522 : */
3523 :
3524 130395 : OGRErr OGRSpatialReference::SetNormProjParm( const char * pszName,
3525 : double dfValue )
3526 :
3527 : {
3528 130395 : GetNormInfo();
3529 :
3530 130395 : if( (dfToDegrees != 1.0 || dfFromGreenwich != 0.0)
3531 : && IsAngularParameter(pszName) )
3532 : {
3533 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
3534 : if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
3535 : dfValue -= dfFromGreenwich;
3536 : #endif
3537 :
3538 1148 : dfValue /= dfToDegrees;
3539 : }
3540 129247 : else if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
3541 6628 : dfValue /= dfToMeter;
3542 :
3543 130395 : return SetProjParm( pszName, dfValue );
3544 : }
3545 :
3546 : /************************************************************************/
3547 : /* OSRSetNormProjParm() */
3548 : /************************************************************************/
3549 :
3550 : /**
3551 : * \brief Set a projection parameter with a normalized value.
3552 : *
3553 : * This function is the same as OGRSpatialReference::SetNormProjParm()
3554 : */
3555 0 : OGRErr OSRSetNormProjParm( OGRSpatialReferenceH hSRS,
3556 : const char * pszParmName, double dfValue )
3557 :
3558 : {
3559 0 : VALIDATE_POINTER1( hSRS, "OSRSetNormProjParm", CE_Failure );
3560 :
3561 : return ((OGRSpatialReference *) hSRS)->
3562 0 : SetNormProjParm( pszParmName, dfValue );
3563 : }
3564 :
3565 : /************************************************************************/
3566 : /* SetTM() */
3567 : /************************************************************************/
3568 :
3569 18381 : OGRErr OGRSpatialReference::SetTM( double dfCenterLat, double dfCenterLong,
3570 : double dfScale,
3571 : double dfFalseEasting,
3572 : double dfFalseNorthing )
3573 :
3574 : {
3575 18381 : SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
3576 18381 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
3577 18381 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
3578 18381 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
3579 18381 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3580 18381 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3581 :
3582 18381 : return OGRERR_NONE;
3583 : }
3584 :
3585 : /************************************************************************/
3586 : /* OSRSetTM() */
3587 : /************************************************************************/
3588 :
3589 0 : OGRErr OSRSetTM( OGRSpatialReferenceH hSRS,
3590 : double dfCenterLat, double dfCenterLong,
3591 : double dfScale,
3592 : double dfFalseEasting,
3593 : double dfFalseNorthing )
3594 :
3595 : {
3596 0 : VALIDATE_POINTER1( hSRS, "OSRSetTM", CE_Failure );
3597 :
3598 : return ((OGRSpatialReference *) hSRS)->SetTM(
3599 : dfCenterLat, dfCenterLong,
3600 : dfScale,
3601 0 : dfFalseEasting, dfFalseNorthing );
3602 : }
3603 :
3604 : /************************************************************************/
3605 : /* SetTMVariant() */
3606 : /************************************************************************/
3607 :
3608 0 : OGRErr OGRSpatialReference::SetTMVariant(
3609 : const char *pszVariantName,
3610 : double dfCenterLat, double dfCenterLong,
3611 : double dfScale,
3612 : double dfFalseEasting,
3613 : double dfFalseNorthing )
3614 :
3615 : {
3616 0 : SetProjection( pszVariantName );
3617 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
3618 0 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
3619 0 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
3620 0 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3621 0 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3622 :
3623 0 : return OGRERR_NONE;
3624 : }
3625 :
3626 : /************************************************************************/
3627 : /* OSRSetTMVariant() */
3628 : /************************************************************************/
3629 :
3630 0 : OGRErr OSRSetTMVariant( OGRSpatialReferenceH hSRS,
3631 : const char *pszVariantName,
3632 : double dfCenterLat, double dfCenterLong,
3633 : double dfScale,
3634 : double dfFalseEasting,
3635 : double dfFalseNorthing )
3636 :
3637 : {
3638 0 : VALIDATE_POINTER1( hSRS, "OSRSetTMVariant", CE_Failure );
3639 :
3640 : return ((OGRSpatialReference *) hSRS)->SetTMVariant(
3641 : pszVariantName,
3642 : dfCenterLat, dfCenterLong,
3643 : dfScale,
3644 0 : dfFalseEasting, dfFalseNorthing );
3645 : }
3646 :
3647 : /************************************************************************/
3648 : /* SetTMSO() */
3649 : /************************************************************************/
3650 :
3651 180 : OGRErr OGRSpatialReference::SetTMSO( double dfCenterLat, double dfCenterLong,
3652 : double dfScale,
3653 : double dfFalseEasting,
3654 : double dfFalseNorthing )
3655 :
3656 : {
3657 180 : SetProjection( SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED );
3658 180 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
3659 180 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
3660 180 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
3661 180 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3662 180 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3663 :
3664 180 : return OGRERR_NONE;
3665 : }
3666 :
3667 : /************************************************************************/
3668 : /* SetTPED() */
3669 : /************************************************************************/
3670 :
3671 4 : OGRErr OGRSpatialReference::SetTPED( double dfLat1, double dfLong1,
3672 : double dfLat2, double dfLong2,
3673 : double dfFalseEasting,
3674 : double dfFalseNorthing )
3675 :
3676 : {
3677 4 : SetProjection( SRS_PT_TWO_POINT_EQUIDISTANT );
3678 4 : SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
3679 4 : SetNormProjParm( SRS_PP_LONGITUDE_OF_1ST_POINT, dfLong1 );
3680 4 : SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
3681 4 : SetNormProjParm( SRS_PP_LONGITUDE_OF_2ND_POINT, dfLong2 );
3682 4 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3683 4 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3684 :
3685 4 : return OGRERR_NONE;
3686 : }
3687 :
3688 : /************************************************************************/
3689 : /* OSRSetTPED() */
3690 : /************************************************************************/
3691 :
3692 0 : OGRErr OSRSetTPED( OGRSpatialReferenceH hSRS,
3693 : double dfLat1, double dfLong1,
3694 : double dfLat2, double dfLong2,
3695 : double dfFalseEasting, double dfFalseNorthing )
3696 :
3697 : {
3698 0 : VALIDATE_POINTER1( hSRS, "OSRSetTPED", CE_Failure );
3699 :
3700 : return ((OGRSpatialReference *) hSRS)->SetTPED(
3701 : dfLat1, dfLong1, dfLat2, dfLong2,
3702 0 : dfFalseEasting, dfFalseNorthing );
3703 : }
3704 :
3705 : /************************************************************************/
3706 : /* OSRSetTMSO() */
3707 : /************************************************************************/
3708 :
3709 0 : OGRErr OSRSetTMSO( OGRSpatialReferenceH hSRS,
3710 : double dfCenterLat, double dfCenterLong,
3711 : double dfScale,
3712 : double dfFalseEasting,
3713 : double dfFalseNorthing )
3714 :
3715 : {
3716 0 : VALIDATE_POINTER1( hSRS, "OSRSetTMSO", CE_Failure );
3717 :
3718 : return ((OGRSpatialReference *) hSRS)->SetTMSO(
3719 : dfCenterLat, dfCenterLong,
3720 : dfScale,
3721 0 : dfFalseEasting, dfFalseNorthing );
3722 : }
3723 :
3724 : /************************************************************************/
3725 : /* SetTMG() */
3726 : /************************************************************************/
3727 :
3728 : OGRErr
3729 6 : OGRSpatialReference::SetTMG( double dfCenterLat, double dfCenterLong,
3730 : double dfFalseEasting, double dfFalseNorthing )
3731 :
3732 : {
3733 6 : SetProjection( SRS_PT_TUNISIA_MINING_GRID );
3734 6 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
3735 6 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
3736 6 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3737 6 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3738 :
3739 6 : return OGRERR_NONE;
3740 : }
3741 :
3742 : /************************************************************************/
3743 : /* OSRSetTMG() */
3744 : /************************************************************************/
3745 :
3746 0 : OGRErr OSRSetTMG( OGRSpatialReferenceH hSRS,
3747 : double dfCenterLat, double dfCenterLong,
3748 : double dfFalseEasting,
3749 : double dfFalseNorthing )
3750 :
3751 : {
3752 0 : VALIDATE_POINTER1( hSRS, "OSRSetTMG", CE_Failure );
3753 :
3754 : return ((OGRSpatialReference *) hSRS)->SetTMG(
3755 : dfCenterLat, dfCenterLong,
3756 0 : dfFalseEasting, dfFalseNorthing );
3757 : }
3758 :
3759 : /************************************************************************/
3760 : /* SetACEA() */
3761 : /************************************************************************/
3762 :
3763 210 : OGRErr OGRSpatialReference::SetACEA( double dfStdP1, double dfStdP2,
3764 : double dfCenterLat, double dfCenterLong,
3765 : double dfFalseEasting,
3766 : double dfFalseNorthing )
3767 :
3768 : {
3769 210 : SetProjection( SRS_PT_ALBERS_CONIC_EQUAL_AREA );
3770 210 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
3771 210 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
3772 210 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
3773 210 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
3774 210 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3775 210 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3776 :
3777 210 : return OGRERR_NONE;
3778 : }
3779 :
3780 : /************************************************************************/
3781 : /* OSRSetACEA() */
3782 : /************************************************************************/
3783 :
3784 0 : OGRErr OSRSetACEA( OGRSpatialReferenceH hSRS,
3785 : double dfStdP1, double dfStdP2,
3786 : double dfCenterLat, double dfCenterLong,
3787 : double dfFalseEasting,
3788 : double dfFalseNorthing )
3789 :
3790 : {
3791 0 : VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
3792 :
3793 : return ((OGRSpatialReference *) hSRS)->SetACEA(
3794 : dfStdP1, dfStdP2,
3795 : dfCenterLat, dfCenterLong,
3796 0 : dfFalseEasting, dfFalseNorthing );
3797 : }
3798 :
3799 : /************************************************************************/
3800 : /* SetAE() */
3801 : /************************************************************************/
3802 :
3803 44 : OGRErr OGRSpatialReference::SetAE( double dfCenterLat, double dfCenterLong,
3804 : double dfFalseEasting,
3805 : double dfFalseNorthing )
3806 :
3807 : {
3808 44 : SetProjection( SRS_PT_AZIMUTHAL_EQUIDISTANT );
3809 44 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
3810 44 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
3811 44 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3812 44 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3813 :
3814 44 : return OGRERR_NONE;
3815 : }
3816 :
3817 : /************************************************************************/
3818 : /* OSRSetAE() */
3819 : /************************************************************************/
3820 :
3821 0 : OGRErr OSRSetAE( OGRSpatialReferenceH hSRS,
3822 : double dfCenterLat, double dfCenterLong,
3823 : double dfFalseEasting,
3824 : double dfFalseNorthing )
3825 :
3826 : {
3827 0 : VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
3828 :
3829 : return ((OGRSpatialReference *) hSRS)->SetAE(
3830 : dfCenterLat, dfCenterLong,
3831 0 : dfFalseEasting, dfFalseNorthing );
3832 : }
3833 :
3834 : /************************************************************************/
3835 : /* SetBonne() */
3836 : /************************************************************************/
3837 :
3838 2 : OGRErr OGRSpatialReference::SetBonne(
3839 : double dfStdP1, double dfCentralMeridian,
3840 : double dfFalseEasting, double dfFalseNorthing )
3841 :
3842 : {
3843 2 : SetProjection( SRS_PT_BONNE );
3844 2 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
3845 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
3846 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3847 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3848 :
3849 2 : return OGRERR_NONE;
3850 : }
3851 :
3852 : /************************************************************************/
3853 : /* OSRSetBonne() */
3854 : /************************************************************************/
3855 :
3856 0 : OGRErr OSRSetBonne( OGRSpatialReferenceH hSRS,
3857 : double dfStdP1, double dfCentralMeridian,
3858 : double dfFalseEasting, double dfFalseNorthing )
3859 :
3860 : {
3861 0 : VALIDATE_POINTER1( hSRS, "OSRSetBonne", CE_Failure );
3862 :
3863 : return ((OGRSpatialReference *) hSRS)->SetBonne(
3864 : dfStdP1, dfCentralMeridian,
3865 0 : dfFalseEasting, dfFalseNorthing );
3866 : }
3867 :
3868 : /************************************************************************/
3869 : /* SetCEA() */
3870 : /************************************************************************/
3871 :
3872 44 : OGRErr OGRSpatialReference::SetCEA( double dfStdP1, double dfCentralMeridian,
3873 : double dfFalseEasting,
3874 : double dfFalseNorthing )
3875 :
3876 : {
3877 44 : SetProjection( SRS_PT_CYLINDRICAL_EQUAL_AREA );
3878 44 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
3879 44 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
3880 44 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3881 44 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3882 :
3883 44 : return OGRERR_NONE;
3884 : }
3885 :
3886 : /************************************************************************/
3887 : /* OSRSetCEA() */
3888 : /************************************************************************/
3889 :
3890 0 : OGRErr OSRSetCEA( OGRSpatialReferenceH hSRS,
3891 : double dfStdP1, double dfCentralMeridian,
3892 : double dfFalseEasting, double dfFalseNorthing )
3893 :
3894 : {
3895 0 : VALIDATE_POINTER1( hSRS, "OSRSetCEA", CE_Failure );
3896 :
3897 : return ((OGRSpatialReference *) hSRS)->SetCEA(
3898 : dfStdP1, dfCentralMeridian,
3899 0 : dfFalseEasting, dfFalseNorthing );
3900 : }
3901 :
3902 : /************************************************************************/
3903 : /* SetCS() */
3904 : /************************************************************************/
3905 :
3906 134 : OGRErr OGRSpatialReference::SetCS( double dfCenterLat, double dfCenterLong,
3907 : double dfFalseEasting,
3908 : double dfFalseNorthing )
3909 :
3910 : {
3911 134 : SetProjection( SRS_PT_CASSINI_SOLDNER );
3912 134 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
3913 134 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
3914 134 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3915 134 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3916 :
3917 134 : return OGRERR_NONE;
3918 : }
3919 :
3920 : /************************************************************************/
3921 : /* OSRSetCS() */
3922 : /************************************************************************/
3923 :
3924 0 : OGRErr OSRSetCS( OGRSpatialReferenceH hSRS,
3925 : double dfCenterLat, double dfCenterLong,
3926 : double dfFalseEasting,
3927 : double dfFalseNorthing )
3928 :
3929 : {
3930 0 : VALIDATE_POINTER1( hSRS, "OSRSetCS", CE_Failure );
3931 :
3932 : return ((OGRSpatialReference *) hSRS)->SetCS(
3933 : dfCenterLat, dfCenterLong,
3934 0 : dfFalseEasting, dfFalseNorthing );
3935 : }
3936 :
3937 : /************************************************************************/
3938 : /* SetEC() */
3939 : /************************************************************************/
3940 :
3941 6 : OGRErr OGRSpatialReference::SetEC( double dfStdP1, double dfStdP2,
3942 : double dfCenterLat, double dfCenterLong,
3943 : double dfFalseEasting,
3944 : double dfFalseNorthing )
3945 :
3946 : {
3947 6 : SetProjection( SRS_PT_EQUIDISTANT_CONIC );
3948 6 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
3949 6 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
3950 6 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
3951 6 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
3952 6 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
3953 6 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
3954 :
3955 6 : return OGRERR_NONE;
3956 : }
3957 :
3958 : /************************************************************************/
3959 : /* OSRSetEC() */
3960 : /************************************************************************/
3961 :
3962 0 : OGRErr OSRSetEC( OGRSpatialReferenceH hSRS,
3963 : double dfStdP1, double dfStdP2,
3964 : double dfCenterLat, double dfCenterLong,
3965 : double dfFalseEasting,
3966 : double dfFalseNorthing )
3967 :
3968 : {
3969 0 : VALIDATE_POINTER1( hSRS, "OSRSetEC", CE_Failure );
3970 :
3971 : return ((OGRSpatialReference *) hSRS)->SetEC(
3972 : dfStdP1, dfStdP2,
3973 : dfCenterLat, dfCenterLong,
3974 0 : dfFalseEasting, dfFalseNorthing );
3975 : }
3976 :
3977 : /************************************************************************/
3978 : /* SetEckert() */
3979 : /************************************************************************/
3980 :
3981 14 : OGRErr OGRSpatialReference::SetEckert( int nVariation /* 1-6 */,
3982 : double dfCentralMeridian,
3983 : double dfFalseEasting,
3984 : double dfFalseNorthing )
3985 :
3986 : {
3987 14 : if( nVariation == 1 )
3988 2 : SetProjection( SRS_PT_ECKERT_I );
3989 12 : else if( nVariation == 2 )
3990 2 : SetProjection( SRS_PT_ECKERT_II );
3991 10 : else if( nVariation == 3 )
3992 2 : SetProjection( SRS_PT_ECKERT_III );
3993 8 : else if( nVariation == 4 )
3994 4 : SetProjection( SRS_PT_ECKERT_IV );
3995 4 : else if( nVariation == 5 )
3996 2 : SetProjection( SRS_PT_ECKERT_V );
3997 2 : else if( nVariation == 6 )
3998 2 : SetProjection( SRS_PT_ECKERT_VI );
3999 : else
4000 : {
4001 : CPLError( CE_Failure, CPLE_AppDefined,
4002 : "Unsupported Eckert variation (%d).",
4003 0 : nVariation );
4004 0 : return OGRERR_UNSUPPORTED_SRS;
4005 : }
4006 :
4007 14 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4008 14 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4009 14 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4010 :
4011 14 : return OGRERR_NONE;
4012 : }
4013 :
4014 : /************************************************************************/
4015 : /* OSRSetEckert() */
4016 : /************************************************************************/
4017 :
4018 0 : OGRErr OSRSetEckert( OGRSpatialReferenceH hSRS,
4019 : int nVariation,
4020 : double dfCentralMeridian,
4021 : double dfFalseEasting,
4022 : double dfFalseNorthing )
4023 :
4024 : {
4025 0 : VALIDATE_POINTER1( hSRS, "OSRSetEckert", CE_Failure );
4026 :
4027 : return ((OGRSpatialReference *) hSRS)->SetEckert(
4028 : nVariation, dfCentralMeridian,
4029 0 : dfFalseEasting, dfFalseNorthing );
4030 : }
4031 :
4032 : /************************************************************************/
4033 : /* SetEckertIV() */
4034 : /* */
4035 : /* Deprecated */
4036 : /************************************************************************/
4037 :
4038 0 : OGRErr OGRSpatialReference::SetEckertIV( double dfCentralMeridian,
4039 : double dfFalseEasting,
4040 : double dfFalseNorthing )
4041 :
4042 : {
4043 0 : SetProjection( SRS_PT_ECKERT_IV );
4044 0 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4045 0 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4046 0 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4047 :
4048 0 : return OGRERR_NONE;
4049 : }
4050 :
4051 : /************************************************************************/
4052 : /* OSRSetEckertIV() */
4053 : /************************************************************************/
4054 :
4055 0 : OGRErr OSRSetEckertIV( OGRSpatialReferenceH hSRS,
4056 : double dfCentralMeridian,
4057 : double dfFalseEasting,
4058 : double dfFalseNorthing )
4059 :
4060 : {
4061 0 : VALIDATE_POINTER1( hSRS, "OSRSetEckertIV", CE_Failure );
4062 :
4063 : return ((OGRSpatialReference *) hSRS)->SetEckertIV(
4064 : dfCentralMeridian,
4065 0 : dfFalseEasting, dfFalseNorthing );
4066 : }
4067 :
4068 : /************************************************************************/
4069 : /* SetEckertVI() */
4070 : /* */
4071 : /* Deprecated */
4072 : /************************************************************************/
4073 :
4074 0 : OGRErr OGRSpatialReference::SetEckertVI( double dfCentralMeridian,
4075 : double dfFalseEasting,
4076 : double dfFalseNorthing )
4077 :
4078 : {
4079 0 : SetProjection( SRS_PT_ECKERT_VI );
4080 0 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4081 0 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4082 0 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4083 :
4084 0 : return OGRERR_NONE;
4085 : }
4086 :
4087 : /************************************************************************/
4088 : /* OSRSetEckertVI() */
4089 : /************************************************************************/
4090 :
4091 0 : OGRErr OSRSetEckertVI( OGRSpatialReferenceH hSRS,
4092 : double dfCentralMeridian,
4093 : double dfFalseEasting,
4094 : double dfFalseNorthing )
4095 :
4096 : {
4097 0 : VALIDATE_POINTER1( hSRS, "OSRSetEckertVI", CE_Failure );
4098 :
4099 : return ((OGRSpatialReference *) hSRS)->SetEckertVI(
4100 : dfCentralMeridian,
4101 0 : dfFalseEasting, dfFalseNorthing );
4102 : }
4103 :
4104 : /************************************************************************/
4105 : /* SetEquirectangular() */
4106 : /************************************************************************/
4107 :
4108 34 : OGRErr OGRSpatialReference::SetEquirectangular(
4109 : double dfCenterLat, double dfCenterLong,
4110 : double dfFalseEasting,
4111 : double dfFalseNorthing )
4112 :
4113 : {
4114 34 : SetProjection( SRS_PT_EQUIRECTANGULAR );
4115 34 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4116 34 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4117 34 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4118 34 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4119 :
4120 34 : return OGRERR_NONE;
4121 : }
4122 :
4123 : /************************************************************************/
4124 : /* OSRSetEquirectangular() */
4125 : /************************************************************************/
4126 :
4127 0 : OGRErr OSRSetEquirectangular( OGRSpatialReferenceH hSRS,
4128 : double dfCenterLat, double dfCenterLong,
4129 : double dfFalseEasting,
4130 : double dfFalseNorthing )
4131 :
4132 : {
4133 0 : VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular", CE_Failure );
4134 :
4135 : return ((OGRSpatialReference *) hSRS)->SetEquirectangular(
4136 : dfCenterLat, dfCenterLong,
4137 0 : dfFalseEasting, dfFalseNorthing );
4138 : }
4139 :
4140 : /************************************************************************/
4141 : /* SetEquirectangular2() */
4142 : /* Generalized form */
4143 : /************************************************************************/
4144 :
4145 28 : OGRErr OGRSpatialReference::SetEquirectangular2(
4146 : double dfCenterLat, double dfCenterLong,
4147 : double dfStdParallel1,
4148 : double dfFalseEasting,
4149 : double dfFalseNorthing )
4150 :
4151 : {
4152 28 : SetProjection( SRS_PT_EQUIRECTANGULAR );
4153 28 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4154 28 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4155 28 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdParallel1 );
4156 28 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4157 28 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4158 :
4159 28 : return OGRERR_NONE;
4160 : }
4161 :
4162 : /************************************************************************/
4163 : /* OSRSetEquirectangular2() */
4164 : /************************************************************************/
4165 :
4166 0 : OGRErr OSRSetEquirectangular2( OGRSpatialReferenceH hSRS,
4167 : double dfCenterLat, double dfCenterLong,
4168 : double dfStdParallel1,
4169 : double dfFalseEasting,
4170 : double dfFalseNorthing )
4171 :
4172 : {
4173 0 : VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular2", CE_Failure );
4174 :
4175 : return ((OGRSpatialReference *) hSRS)->SetEquirectangular2(
4176 : dfCenterLat, dfCenterLong,
4177 : dfStdParallel1,
4178 0 : dfFalseEasting, dfFalseNorthing );
4179 : }
4180 :
4181 : /************************************************************************/
4182 : /* SetGS() */
4183 : /************************************************************************/
4184 :
4185 6 : OGRErr OGRSpatialReference::SetGS( double dfCentralMeridian,
4186 : double dfFalseEasting,
4187 : double dfFalseNorthing )
4188 :
4189 : {
4190 6 : SetProjection( SRS_PT_GALL_STEREOGRAPHIC );
4191 6 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4192 6 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4193 6 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4194 :
4195 6 : return OGRERR_NONE;
4196 : }
4197 :
4198 : /************************************************************************/
4199 : /* OSRSetGS() */
4200 : /************************************************************************/
4201 :
4202 2 : OGRErr OSRSetGS( OGRSpatialReferenceH hSRS,
4203 : double dfCentralMeridian,
4204 : double dfFalseEasting,
4205 : double dfFalseNorthing )
4206 :
4207 : {
4208 2 : VALIDATE_POINTER1( hSRS, "OSRSetGS", CE_Failure );
4209 :
4210 : return ((OGRSpatialReference *) hSRS)->SetGS(
4211 : dfCentralMeridian,
4212 2 : dfFalseEasting, dfFalseNorthing );
4213 : }
4214 :
4215 : /************************************************************************/
4216 : /* SetGH() */
4217 : /************************************************************************/
4218 :
4219 6 : OGRErr OGRSpatialReference::SetGH( double dfCentralMeridian,
4220 : double dfFalseEasting,
4221 : double dfFalseNorthing )
4222 :
4223 : {
4224 6 : SetProjection( SRS_PT_GOODE_HOMOLOSINE );
4225 6 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4226 6 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4227 6 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4228 :
4229 6 : return OGRERR_NONE;
4230 : }
4231 :
4232 : /************************************************************************/
4233 : /* OSRSetGH() */
4234 : /************************************************************************/
4235 :
4236 0 : OGRErr OSRSetGH( OGRSpatialReferenceH hSRS,
4237 : double dfCentralMeridian,
4238 : double dfFalseEasting,
4239 : double dfFalseNorthing )
4240 :
4241 : {
4242 0 : VALIDATE_POINTER1( hSRS, "OSRSetGH", CE_Failure );
4243 :
4244 : return ((OGRSpatialReference *) hSRS)->SetGH(
4245 : dfCentralMeridian,
4246 0 : dfFalseEasting, dfFalseNorthing );
4247 : }
4248 :
4249 : /************************************************************************/
4250 : /* SetIGH() */
4251 : /************************************************************************/
4252 :
4253 2 : OGRErr OGRSpatialReference::SetIGH()
4254 :
4255 : {
4256 2 : SetProjection( SRS_PT_IGH );
4257 :
4258 2 : return OGRERR_NONE;
4259 : }
4260 :
4261 : /************************************************************************/
4262 : /* OSRSetIGH() */
4263 : /************************************************************************/
4264 :
4265 0 : OGRErr OSRSetIGH( OGRSpatialReferenceH hSRS )
4266 :
4267 : {
4268 0 : VALIDATE_POINTER1( hSRS, "OSRSetIGH", CE_Failure );
4269 :
4270 0 : return ((OGRSpatialReference *) hSRS)->SetIGH();
4271 : }
4272 :
4273 : /************************************************************************/
4274 : /* SetGEOS() */
4275 : /************************************************************************/
4276 :
4277 2 : OGRErr OGRSpatialReference::SetGEOS( double dfCentralMeridian,
4278 : double dfSatelliteHeight,
4279 : double dfFalseEasting,
4280 : double dfFalseNorthing )
4281 :
4282 : {
4283 2 : SetProjection( SRS_PT_GEOSTATIONARY_SATELLITE );
4284 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4285 2 : SetNormProjParm( SRS_PP_SATELLITE_HEIGHT, dfSatelliteHeight );
4286 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4287 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4288 :
4289 2 : return OGRERR_NONE;
4290 : }
4291 :
4292 : /************************************************************************/
4293 : /* OSRSetGEOS() */
4294 : /************************************************************************/
4295 :
4296 0 : OGRErr OSRSetGEOS( OGRSpatialReferenceH hSRS,
4297 : double dfCentralMeridian,
4298 : double dfSatelliteHeight,
4299 : double dfFalseEasting,
4300 : double dfFalseNorthing )
4301 :
4302 : {
4303 0 : VALIDATE_POINTER1( hSRS, "OSRSetGEOS", CE_Failure );
4304 :
4305 : return ((OGRSpatialReference *) hSRS)->SetGEOS(
4306 : dfCentralMeridian, dfSatelliteHeight,
4307 0 : dfFalseEasting, dfFalseNorthing );
4308 : }
4309 :
4310 : /************************************************************************/
4311 : /* SetGaussSchreiberTMercator() */
4312 : /************************************************************************/
4313 :
4314 2 : OGRErr OGRSpatialReference::SetGaussSchreiberTMercator(
4315 : double dfCenterLat, double dfCenterLong,
4316 : double dfScale,
4317 : double dfFalseEasting,
4318 : double dfFalseNorthing )
4319 :
4320 : {
4321 2 : SetProjection( SRS_PT_GAUSSSCHREIBERTMERCATOR );
4322 2 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4323 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4324 2 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4325 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4326 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4327 :
4328 2 : return OGRERR_NONE;
4329 : }
4330 :
4331 : /************************************************************************/
4332 : /* OSRSetGaussSchreiberTMercator() */
4333 : /************************************************************************/
4334 :
4335 0 : OGRErr OSRSetGaussSchreiberTMercator( OGRSpatialReferenceH hSRS,
4336 : double dfCenterLat, double dfCenterLong,
4337 : double dfScale,
4338 : double dfFalseEasting,
4339 : double dfFalseNorthing )
4340 :
4341 : {
4342 : return ((OGRSpatialReference *) hSRS)->SetGaussSchreiberTMercator(
4343 : dfCenterLat, dfCenterLong, dfScale,
4344 0 : dfFalseEasting, dfFalseNorthing );
4345 : }
4346 :
4347 : /************************************************************************/
4348 : /* SetGnomonic() */
4349 : /************************************************************************/
4350 :
4351 2 : OGRErr OGRSpatialReference::SetGnomonic(
4352 : double dfCenterLat, double dfCenterLong,
4353 : double dfFalseEasting,
4354 : double dfFalseNorthing )
4355 :
4356 : {
4357 2 : SetProjection( SRS_PT_GNOMONIC );
4358 2 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4359 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4360 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4361 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4362 :
4363 2 : return OGRERR_NONE;
4364 : }
4365 :
4366 : /************************************************************************/
4367 : /* OSRSetGnomonic() */
4368 : /************************************************************************/
4369 :
4370 0 : OGRErr OSRSetGnomonic( OGRSpatialReferenceH hSRS,
4371 : double dfCenterLat, double dfCenterLong,
4372 : double dfFalseEasting,
4373 : double dfFalseNorthing )
4374 :
4375 : {
4376 0 : VALIDATE_POINTER1( hSRS, "OSRSetGnomonic", CE_Failure );
4377 :
4378 : return ((OGRSpatialReference *) hSRS)->SetGnomonic(
4379 : dfCenterLat, dfCenterLong,
4380 0 : dfFalseEasting, dfFalseNorthing );
4381 : }
4382 :
4383 : /************************************************************************/
4384 : /* SetHOMAC() */
4385 : /************************************************************************/
4386 :
4387 : /**
4388 : * \brief Set an Hotine Oblique Mercator Azimuth Center projection using
4389 : * azimuth angle.
4390 : *
4391 : * This projection corresponds to EPSG projection method 9815, also
4392 : * sometimes known as hotine oblique mercator (variant B).
4393 : *
4394 : * This method does the same thing as the C function OSRSetHOMAC().
4395 : *
4396 : * @param dfCenterLat Latitude of the projection origin.
4397 : * @param dfCenterLong Longitude of the projection origin.
4398 : * @param dfAzimuth Azimuth, measured clockwise from North, of the projection
4399 : * centerline.
4400 : * @param dfRectToSkew ?.
4401 : * @param dfScale Scale factor applies to the projection origin.
4402 : * @param dfFalseEasting False easting.
4403 : * @param dfFalseNorthing False northing.
4404 : *
4405 : * @return OGRERR_NONE on success.
4406 : */
4407 :
4408 90 : OGRErr OGRSpatialReference::SetHOMAC( double dfCenterLat, double dfCenterLong,
4409 : double dfAzimuth, double dfRectToSkew,
4410 : double dfScale,
4411 : double dfFalseEasting,
4412 : double dfFalseNorthing )
4413 :
4414 : {
4415 90 : SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER );
4416 90 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4417 90 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
4418 90 : SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
4419 90 : SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
4420 90 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4421 90 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4422 90 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4423 :
4424 90 : return OGRERR_NONE;
4425 : }
4426 :
4427 : /************************************************************************/
4428 : /* OSRSetHOMAC() */
4429 : /************************************************************************/
4430 :
4431 : /**
4432 : * \brief Set an Oblique Mercator projection using azimuth angle.
4433 : *
4434 : * This is the same as the C++ method OGRSpatialReference::SetHOMAC()
4435 : */
4436 0 : OGRErr OSRSetHOMAC( OGRSpatialReferenceH hSRS,
4437 : double dfCenterLat, double dfCenterLong,
4438 : double dfAzimuth, double dfRectToSkew,
4439 : double dfScale,
4440 : double dfFalseEasting,
4441 : double dfFalseNorthing )
4442 :
4443 : {
4444 0 : VALIDATE_POINTER1( hSRS, "OSRSetHOMAC", CE_Failure );
4445 :
4446 : return ((OGRSpatialReference *) hSRS)->SetHOMAC(
4447 : dfCenterLat, dfCenterLong,
4448 : dfAzimuth, dfRectToSkew,
4449 : dfScale,
4450 0 : dfFalseEasting, dfFalseNorthing );
4451 : }
4452 :
4453 : /************************************************************************/
4454 : /* SetHOM() */
4455 : /************************************************************************/
4456 :
4457 : /**
4458 : * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
4459 : *
4460 : * This projection corresponds to EPSG projection method 9812, also
4461 : * sometimes known as hotine oblique mercator (variant A)..
4462 : *
4463 : * This method does the same thing as the C function OSRSetHOM().
4464 : *
4465 : * @param dfCenterLat Latitude of the projection origin.
4466 : * @param dfCenterLong Longitude of the projection origin.
4467 : * @param dfAzimuth Azimuth, measured clockwise from North, of the projection
4468 : * centerline.
4469 : * @param dfRectToSkew ?.
4470 : * @param dfScale Scale factor applies to the projection origin.
4471 : * @param dfFalseEasting False easting.
4472 : * @param dfFalseNorthing False northing.
4473 : *
4474 : * @return OGRERR_NONE on success.
4475 : */
4476 :
4477 82 : OGRErr OGRSpatialReference::SetHOM( double dfCenterLat, double dfCenterLong,
4478 : double dfAzimuth, double dfRectToSkew,
4479 : double dfScale,
4480 : double dfFalseEasting,
4481 : double dfFalseNorthing )
4482 :
4483 : {
4484 82 : SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR );
4485 82 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4486 82 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
4487 82 : SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
4488 82 : SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
4489 82 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4490 82 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4491 82 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4492 :
4493 82 : return OGRERR_NONE;
4494 : }
4495 :
4496 : /************************************************************************/
4497 : /* OSRSetHOM() */
4498 : /************************************************************************/
4499 : /**
4500 : * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
4501 : *
4502 : * This is the same as the C++ method OGRSpatialReference::SetHOM()
4503 : */
4504 0 : OGRErr OSRSetHOM( OGRSpatialReferenceH hSRS,
4505 : double dfCenterLat, double dfCenterLong,
4506 : double dfAzimuth, double dfRectToSkew,
4507 : double dfScale,
4508 : double dfFalseEasting,
4509 : double dfFalseNorthing )
4510 :
4511 : {
4512 0 : VALIDATE_POINTER1( hSRS, "OSRSetHOM", CE_Failure );
4513 :
4514 : return ((OGRSpatialReference *) hSRS)->SetHOM(
4515 : dfCenterLat, dfCenterLong,
4516 : dfAzimuth, dfRectToSkew,
4517 : dfScale,
4518 0 : dfFalseEasting, dfFalseNorthing );
4519 : }
4520 :
4521 : /************************************************************************/
4522 : /* SetHOM2PNO() */
4523 : /************************************************************************/
4524 :
4525 : /**
4526 : * \brief Set a Hotine Oblique Mercator projection using two points on projection
4527 : * centerline.
4528 : *
4529 : * This method does the same thing as the C function OSRSetHOM2PNO().
4530 : *
4531 : * @param dfCenterLat Latitude of the projection origin.
4532 : * @param dfLat1 Latitude of the first point on center line.
4533 : * @param dfLong1 Longitude of the first point on center line.
4534 : * @param dfLat2 Latitude of the second point on center line.
4535 : * @param dfLong2 Longitude of the second point on center line.
4536 : * @param dfScale Scale factor applies to the projection origin.
4537 : * @param dfFalseEasting False easting.
4538 : * @param dfFalseNorthing False northing.
4539 : *
4540 : * @return OGRERR_NONE on success.
4541 : */
4542 :
4543 0 : OGRErr OGRSpatialReference::SetHOM2PNO( double dfCenterLat,
4544 : double dfLat1, double dfLong1,
4545 : double dfLat2, double dfLong2,
4546 : double dfScale,
4547 : double dfFalseEasting,
4548 : double dfFalseNorthing )
4549 :
4550 : {
4551 0 : SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN );
4552 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4553 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_1, dfLat1 );
4554 0 : SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_1, dfLong1 );
4555 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_2, dfLat2 );
4556 0 : SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_2, dfLong2 );
4557 0 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4558 0 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4559 0 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4560 :
4561 0 : return OGRERR_NONE;
4562 : }
4563 :
4564 : /************************************************************************/
4565 : /* OSRSetHOM2PNO() */
4566 : /************************************************************************/
4567 : /**
4568 : * \brief Set a Hotine Oblique Mercator projection using two points on projection
4569 : * centerline.
4570 : *
4571 : * This is the same as the C++ method OGRSpatialReference::SetHOM2PNO()
4572 : */
4573 0 : OGRErr OSRSetHOM2PNO( OGRSpatialReferenceH hSRS,
4574 : double dfCenterLat,
4575 : double dfLat1, double dfLong1,
4576 : double dfLat2, double dfLong2,
4577 : double dfScale,
4578 : double dfFalseEasting, double dfFalseNorthing )
4579 :
4580 : {
4581 0 : VALIDATE_POINTER1( hSRS, "OSRSetHOM2PNO", CE_Failure );
4582 :
4583 : return ((OGRSpatialReference *) hSRS)->SetHOM2PNO(
4584 : dfCenterLat,
4585 : dfLat1, dfLong1,
4586 : dfLat2, dfLong2,
4587 : dfScale,
4588 0 : dfFalseEasting, dfFalseNorthing );
4589 : }
4590 :
4591 : /************************************************************************/
4592 : /* SetIWMPolyconic() */
4593 : /************************************************************************/
4594 :
4595 2 : OGRErr OGRSpatialReference::SetIWMPolyconic(
4596 : double dfLat1, double dfLat2,
4597 : double dfCenterLong,
4598 : double dfFalseEasting, double dfFalseNorthing )
4599 :
4600 : {
4601 2 : SetProjection( SRS_PT_IMW_POLYCONIC );
4602 2 : SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
4603 2 : SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
4604 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4605 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4606 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4607 :
4608 2 : return OGRERR_NONE;
4609 : }
4610 :
4611 : /************************************************************************/
4612 : /* OSRSetIWMPolyconic() */
4613 : /************************************************************************/
4614 :
4615 0 : OGRErr OSRSetIWMPolyconic( OGRSpatialReferenceH hSRS,
4616 : double dfLat1, double dfLat2,
4617 : double dfCenterLong,
4618 : double dfFalseEasting, double dfFalseNorthing )
4619 :
4620 : {
4621 0 : VALIDATE_POINTER1( hSRS, "OSRSetIWMPolyconic", CE_Failure );
4622 :
4623 : return ((OGRSpatialReference *) hSRS)->SetIWMPolyconic(
4624 : dfLat1, dfLat2, dfCenterLong,
4625 0 : dfFalseEasting, dfFalseNorthing );
4626 : }
4627 :
4628 : /************************************************************************/
4629 : /* SetKrovak() */
4630 : /************************************************************************/
4631 :
4632 144 : OGRErr OGRSpatialReference::SetKrovak( double dfCenterLat, double dfCenterLong,
4633 : double dfAzimuth,
4634 : double dfPseudoStdParallel1,
4635 : double dfScale,
4636 : double dfFalseEasting,
4637 : double dfFalseNorthing )
4638 :
4639 : {
4640 144 : SetProjection( SRS_PT_KROVAK );
4641 144 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4642 144 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
4643 144 : SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
4644 144 : SetNormProjParm( SRS_PP_PSEUDO_STD_PARALLEL_1, dfPseudoStdParallel1 );
4645 144 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4646 144 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4647 144 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4648 :
4649 144 : return OGRERR_NONE;
4650 : }
4651 :
4652 : /************************************************************************/
4653 : /* OSRSetKrovak() */
4654 : /************************************************************************/
4655 :
4656 0 : OGRErr OSRSetKrovak( OGRSpatialReferenceH hSRS,
4657 : double dfCenterLat, double dfCenterLong,
4658 : double dfAzimuth, double dfPseudoStdParallel1,
4659 : double dfScale,
4660 : double dfFalseEasting,
4661 : double dfFalseNorthing )
4662 :
4663 : {
4664 0 : VALIDATE_POINTER1( hSRS, "OSRSetKrovak", CE_Failure );
4665 :
4666 : return ((OGRSpatialReference *) hSRS)->SetKrovak(
4667 : dfCenterLat, dfCenterLong,
4668 : dfAzimuth, dfPseudoStdParallel1,
4669 : dfScale,
4670 0 : dfFalseEasting, dfFalseNorthing );
4671 : }
4672 :
4673 : /************************************************************************/
4674 : /* SetLAEA() */
4675 : /************************************************************************/
4676 :
4677 108 : OGRErr OGRSpatialReference::SetLAEA( double dfCenterLat, double dfCenterLong,
4678 : double dfFalseEasting,
4679 : double dfFalseNorthing )
4680 :
4681 : {
4682 108 : SetProjection( SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA );
4683 108 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4684 108 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
4685 108 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4686 108 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4687 :
4688 108 : return OGRERR_NONE;
4689 : }
4690 :
4691 : /************************************************************************/
4692 : /* OSRSetLAEA() */
4693 : /************************************************************************/
4694 :
4695 0 : OGRErr OSRSetLAEA( OGRSpatialReferenceH hSRS,
4696 : double dfCenterLat, double dfCenterLong,
4697 : double dfFalseEasting, double dfFalseNorthing )
4698 :
4699 : {
4700 0 : VALIDATE_POINTER1( hSRS, "OSRSetLAEA", CE_Failure );
4701 :
4702 : return ((OGRSpatialReference *) hSRS)->SetLAEA(
4703 : dfCenterLat, dfCenterLong,
4704 0 : dfFalseEasting, dfFalseNorthing );
4705 : }
4706 :
4707 : /************************************************************************/
4708 : /* SetLCC() */
4709 : /************************************************************************/
4710 :
4711 4078 : OGRErr OGRSpatialReference::SetLCC( double dfStdP1, double dfStdP2,
4712 : double dfCenterLat, double dfCenterLong,
4713 : double dfFalseEasting,
4714 : double dfFalseNorthing )
4715 :
4716 : {
4717 4078 : SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP );
4718 4078 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
4719 4078 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
4720 4078 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4721 4078 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4722 4078 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4723 4078 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4724 :
4725 4078 : return OGRERR_NONE;
4726 : }
4727 :
4728 : /************************************************************************/
4729 : /* OSRSetLCC() */
4730 : /************************************************************************/
4731 :
4732 4 : OGRErr OSRSetLCC( OGRSpatialReferenceH hSRS,
4733 : double dfStdP1, double dfStdP2,
4734 : double dfCenterLat, double dfCenterLong,
4735 : double dfFalseEasting, double dfFalseNorthing )
4736 :
4737 : {
4738 4 : VALIDATE_POINTER1( hSRS, "OSRSetLCC", CE_Failure );
4739 :
4740 : return ((OGRSpatialReference *) hSRS)->SetLCC(
4741 : dfStdP1, dfStdP2,
4742 : dfCenterLat, dfCenterLong,
4743 4 : dfFalseEasting, dfFalseNorthing );
4744 : }
4745 :
4746 : /************************************************************************/
4747 : /* SetLCC1SP() */
4748 : /************************************************************************/
4749 :
4750 490 : OGRErr OGRSpatialReference::SetLCC1SP( double dfCenterLat, double dfCenterLong,
4751 : double dfScale,
4752 : double dfFalseEasting,
4753 : double dfFalseNorthing )
4754 :
4755 : {
4756 490 : SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP );
4757 490 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4758 490 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4759 490 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4760 490 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4761 490 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4762 :
4763 490 : return OGRERR_NONE;
4764 : }
4765 :
4766 : /************************************************************************/
4767 : /* OSRSetLCC1SP() */
4768 : /************************************************************************/
4769 :
4770 0 : OGRErr OSRSetLCC1SP( OGRSpatialReferenceH hSRS,
4771 : double dfCenterLat, double dfCenterLong,
4772 : double dfScale,
4773 : double dfFalseEasting, double dfFalseNorthing )
4774 :
4775 : {
4776 0 : VALIDATE_POINTER1( hSRS, "OSRSetLCC1SP", CE_Failure );
4777 :
4778 : return ((OGRSpatialReference *) hSRS)->SetLCC1SP(
4779 : dfCenterLat, dfCenterLong,
4780 : dfScale,
4781 0 : dfFalseEasting, dfFalseNorthing );
4782 : }
4783 :
4784 : /************************************************************************/
4785 : /* SetLCCB() */
4786 : /************************************************************************/
4787 :
4788 6 : OGRErr OGRSpatialReference::SetLCCB( double dfStdP1, double dfStdP2,
4789 : double dfCenterLat, double dfCenterLong,
4790 : double dfFalseEasting,
4791 : double dfFalseNorthing )
4792 :
4793 : {
4794 6 : SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM );
4795 6 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
4796 6 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
4797 6 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4798 6 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4799 6 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4800 6 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4801 :
4802 6 : return OGRERR_NONE;
4803 : }
4804 :
4805 : /************************************************************************/
4806 : /* OSRSetLCCB() */
4807 : /************************************************************************/
4808 :
4809 0 : OGRErr OSRSetLCCB( OGRSpatialReferenceH hSRS,
4810 : double dfStdP1, double dfStdP2,
4811 : double dfCenterLat, double dfCenterLong,
4812 : double dfFalseEasting, double dfFalseNorthing )
4813 :
4814 : {
4815 0 : VALIDATE_POINTER1( hSRS, "OSRSetLCCB", CE_Failure );
4816 :
4817 : return ((OGRSpatialReference *) hSRS)->SetLCCB(
4818 : dfStdP1, dfStdP2,
4819 : dfCenterLat, dfCenterLong,
4820 0 : dfFalseEasting, dfFalseNorthing );
4821 : }
4822 :
4823 : /************************************************************************/
4824 : /* SetMC() */
4825 : /************************************************************************/
4826 :
4827 4 : OGRErr OGRSpatialReference::SetMC( double dfCenterLat, double dfCenterLong,
4828 : double dfFalseEasting,
4829 : double dfFalseNorthing )
4830 :
4831 : {
4832 4 : SetProjection( SRS_PT_MILLER_CYLINDRICAL );
4833 4 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
4834 4 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
4835 4 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4836 4 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4837 :
4838 4 : return OGRERR_NONE;
4839 : }
4840 :
4841 : /************************************************************************/
4842 : /* OSRSetMC() */
4843 : /************************************************************************/
4844 :
4845 0 : OGRErr OSRSetMC( OGRSpatialReferenceH hSRS,
4846 : double dfCenterLat, double dfCenterLong,
4847 : double dfFalseEasting, double dfFalseNorthing )
4848 :
4849 : {
4850 0 : VALIDATE_POINTER1( hSRS, "OSRSetMC", CE_Failure );
4851 :
4852 : return ((OGRSpatialReference *) hSRS)->SetMC(
4853 : dfCenterLat, dfCenterLong,
4854 0 : dfFalseEasting, dfFalseNorthing );
4855 : }
4856 :
4857 : /************************************************************************/
4858 : /* SetMercator() */
4859 : /************************************************************************/
4860 :
4861 221 : OGRErr OGRSpatialReference::SetMercator( double dfCenterLat, double dfCenterLong,
4862 : double dfScale,
4863 : double dfFalseEasting,
4864 : double dfFalseNorthing )
4865 :
4866 : {
4867 221 : SetProjection( SRS_PT_MERCATOR_1SP );
4868 :
4869 221 : if( dfCenterLat != 0.0 )
4870 10 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4871 :
4872 221 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4873 221 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
4874 221 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4875 221 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4876 :
4877 221 : return OGRERR_NONE;
4878 : }
4879 :
4880 : /************************************************************************/
4881 : /* OSRSetMercator() */
4882 : /************************************************************************/
4883 :
4884 0 : OGRErr OSRSetMercator( OGRSpatialReferenceH hSRS,
4885 : double dfCenterLat, double dfCenterLong,
4886 : double dfScale,
4887 : double dfFalseEasting, double dfFalseNorthing )
4888 :
4889 : {
4890 0 : VALIDATE_POINTER1( hSRS, "OSRSetMercator", CE_Failure );
4891 :
4892 : return ((OGRSpatialReference *) hSRS)->SetMercator(
4893 : dfCenterLat, dfCenterLong,
4894 : dfScale,
4895 0 : dfFalseEasting, dfFalseNorthing );
4896 : }
4897 :
4898 : /************************************************************************/
4899 : /* SetMercator2SP() */
4900 : /************************************************************************/
4901 :
4902 30 : OGRErr OGRSpatialReference::SetMercator2SP(
4903 : double dfStdP1,
4904 : double dfCenterLat, double dfCenterLong,
4905 : double dfFalseEasting,
4906 : double dfFalseNorthing )
4907 :
4908 : {
4909 30 : SetProjection( SRS_PT_MERCATOR_2SP );
4910 :
4911 30 : SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
4912 30 : if( dfCenterLat != 0.0 )
4913 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4914 :
4915 30 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4916 30 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4917 30 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4918 :
4919 30 : return OGRERR_NONE;
4920 : }
4921 :
4922 : /************************************************************************/
4923 : /* OSRSetMercator2SP() */
4924 : /************************************************************************/
4925 :
4926 0 : OGRErr OSRSetMercator2SP( OGRSpatialReferenceH hSRS,
4927 : double dfStdP1,
4928 : double dfCenterLat, double dfCenterLong,
4929 : double dfFalseEasting, double dfFalseNorthing )
4930 :
4931 : {
4932 0 : VALIDATE_POINTER1( hSRS, "OSRSetMercator2SP", CE_Failure );
4933 :
4934 : return ((OGRSpatialReference *) hSRS)->SetMercator2SP(
4935 : dfStdP1,
4936 : dfCenterLat, dfCenterLong,
4937 0 : dfFalseEasting, dfFalseNorthing );
4938 : }
4939 :
4940 : /************************************************************************/
4941 : /* SetMollweide() */
4942 : /************************************************************************/
4943 :
4944 2 : OGRErr OGRSpatialReference::SetMollweide( double dfCentralMeridian,
4945 : double dfFalseEasting,
4946 : double dfFalseNorthing )
4947 :
4948 : {
4949 2 : SetProjection( SRS_PT_MOLLWEIDE );
4950 2 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
4951 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4952 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4953 :
4954 2 : return OGRERR_NONE;
4955 : }
4956 :
4957 : /************************************************************************/
4958 : /* OSRSetMollweide() */
4959 : /************************************************************************/
4960 :
4961 0 : OGRErr OSRSetMollweide( OGRSpatialReferenceH hSRS,
4962 : double dfCentralMeridian,
4963 : double dfFalseEasting, double dfFalseNorthing )
4964 :
4965 : {
4966 0 : VALIDATE_POINTER1( hSRS, "OSRSetMollweide", CE_Failure );
4967 :
4968 : return ((OGRSpatialReference *) hSRS)->SetMollweide(
4969 : dfCentralMeridian,
4970 0 : dfFalseEasting, dfFalseNorthing );
4971 : }
4972 :
4973 : /************************************************************************/
4974 : /* SetNZMG() */
4975 : /************************************************************************/
4976 :
4977 20 : OGRErr OGRSpatialReference::SetNZMG( double dfCenterLat, double dfCenterLong,
4978 : double dfFalseEasting,
4979 : double dfFalseNorthing )
4980 :
4981 : {
4982 20 : SetProjection( SRS_PT_NEW_ZEALAND_MAP_GRID );
4983 20 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
4984 20 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
4985 20 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
4986 20 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
4987 :
4988 20 : return OGRERR_NONE;
4989 : }
4990 :
4991 : /************************************************************************/
4992 : /* OSRSetNZMG() */
4993 : /************************************************************************/
4994 :
4995 0 : OGRErr OSRSetNZMG( OGRSpatialReferenceH hSRS,
4996 : double dfCenterLat, double dfCenterLong,
4997 : double dfFalseEasting, double dfFalseNorthing )
4998 :
4999 : {
5000 0 : VALIDATE_POINTER1( hSRS, "OSRSetNZMG", CE_Failure );
5001 :
5002 : return ((OGRSpatialReference *) hSRS)->SetNZMG(
5003 : dfCenterLat, dfCenterLong,
5004 0 : dfFalseEasting, dfFalseNorthing );
5005 : }
5006 :
5007 : /************************************************************************/
5008 : /* SetOS() */
5009 : /************************************************************************/
5010 :
5011 152 : OGRErr OGRSpatialReference::SetOS( double dfOriginLat, double dfCMeridian,
5012 : double dfScale,
5013 : double dfFalseEasting,
5014 : double dfFalseNorthing )
5015 :
5016 : {
5017 152 : SetProjection( SRS_PT_OBLIQUE_STEREOGRAPHIC );
5018 152 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
5019 152 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
5020 152 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
5021 152 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5022 152 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5023 :
5024 152 : return OGRERR_NONE;
5025 : }
5026 :
5027 : /************************************************************************/
5028 : /* OSRSetOS() */
5029 : /************************************************************************/
5030 :
5031 0 : OGRErr OSRSetOS( OGRSpatialReferenceH hSRS,
5032 : double dfOriginLat, double dfCMeridian,
5033 : double dfScale,
5034 : double dfFalseEasting, double dfFalseNorthing )
5035 :
5036 : {
5037 0 : VALIDATE_POINTER1( hSRS, "OSRSetOS", CE_Failure );
5038 :
5039 : return ((OGRSpatialReference *) hSRS)->SetOS(
5040 : dfOriginLat, dfCMeridian,
5041 : dfScale,
5042 0 : dfFalseEasting, dfFalseNorthing );
5043 : }
5044 :
5045 : /************************************************************************/
5046 : /* SetOrthographic() */
5047 : /************************************************************************/
5048 :
5049 24 : OGRErr OGRSpatialReference::SetOrthographic(
5050 : double dfCenterLat, double dfCenterLong,
5051 : double dfFalseEasting, double dfFalseNorthing )
5052 :
5053 : {
5054 24 : SetProjection( SRS_PT_ORTHOGRAPHIC );
5055 24 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
5056 24 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
5057 24 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5058 24 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5059 :
5060 24 : return OGRERR_NONE;
5061 : }
5062 :
5063 : /************************************************************************/
5064 : /* OSRSetOrthographic() */
5065 : /************************************************************************/
5066 :
5067 0 : OGRErr OSRSetOrthographic( OGRSpatialReferenceH hSRS,
5068 : double dfCenterLat, double dfCenterLong,
5069 : double dfFalseEasting, double dfFalseNorthing )
5070 :
5071 : {
5072 0 : VALIDATE_POINTER1( hSRS, "OSRSetOrthographic", CE_Failure );
5073 :
5074 : return ((OGRSpatialReference *) hSRS)->SetOrthographic(
5075 : dfCenterLat, dfCenterLong,
5076 0 : dfFalseEasting, dfFalseNorthing );
5077 : }
5078 :
5079 : /************************************************************************/
5080 : /* SetPolyconic() */
5081 : /************************************************************************/
5082 :
5083 36 : OGRErr OGRSpatialReference::SetPolyconic(
5084 : double dfCenterLat, double dfCenterLong,
5085 : double dfFalseEasting, double dfFalseNorthing )
5086 :
5087 : {
5088 : // note: it seems that by some definitions this should include a
5089 : // scale_factor parameter.
5090 :
5091 36 : SetProjection( SRS_PT_POLYCONIC );
5092 36 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
5093 36 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
5094 36 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5095 36 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5096 :
5097 36 : return OGRERR_NONE;
5098 : }
5099 :
5100 : /************************************************************************/
5101 : /* OSRSetPolyconic() */
5102 : /************************************************************************/
5103 :
5104 0 : OGRErr OSRSetPolyconic( OGRSpatialReferenceH hSRS,
5105 : double dfCenterLat, double dfCenterLong,
5106 : double dfFalseEasting, double dfFalseNorthing )
5107 :
5108 : {
5109 0 : VALIDATE_POINTER1( hSRS, "OSRSetPolyconic", CE_Failure );
5110 :
5111 : return ((OGRSpatialReference *) hSRS)->SetPolyconic(
5112 : dfCenterLat, dfCenterLong,
5113 0 : dfFalseEasting, dfFalseNorthing );
5114 : }
5115 :
5116 : /************************************************************************/
5117 : /* SetPS() */
5118 : /************************************************************************/
5119 :
5120 244 : OGRErr OGRSpatialReference::SetPS(
5121 : double dfCenterLat, double dfCenterLong,
5122 : double dfScale,
5123 : double dfFalseEasting, double dfFalseNorthing )
5124 :
5125 : {
5126 244 : SetProjection( SRS_PT_POLAR_STEREOGRAPHIC );
5127 244 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
5128 244 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
5129 244 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
5130 244 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5131 244 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5132 :
5133 244 : return OGRERR_NONE;
5134 : }
5135 :
5136 : /************************************************************************/
5137 : /* OSRSetPS() */
5138 : /************************************************************************/
5139 :
5140 0 : OGRErr OSRSetPS( OGRSpatialReferenceH hSRS,
5141 : double dfCenterLat, double dfCenterLong,
5142 : double dfScale,
5143 : double dfFalseEasting, double dfFalseNorthing )
5144 :
5145 : {
5146 0 : VALIDATE_POINTER1( hSRS, "OSRSetPS", CE_Failure );
5147 :
5148 : return ((OGRSpatialReference *) hSRS)->SetPS(
5149 : dfCenterLat, dfCenterLong,
5150 : dfScale,
5151 0 : dfFalseEasting, dfFalseNorthing );
5152 : }
5153 :
5154 : /************************************************************************/
5155 : /* SetRobinson() */
5156 : /************************************************************************/
5157 :
5158 2 : OGRErr OGRSpatialReference::SetRobinson( double dfCenterLong,
5159 : double dfFalseEasting,
5160 : double dfFalseNorthing )
5161 :
5162 : {
5163 2 : SetProjection( SRS_PT_ROBINSON );
5164 2 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
5165 2 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5166 2 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5167 :
5168 2 : return OGRERR_NONE;
5169 : }
5170 :
5171 : /************************************************************************/
5172 : /* OSRSetRobinson() */
5173 : /************************************************************************/
5174 :
5175 0 : OGRErr OSRSetRobinson( OGRSpatialReferenceH hSRS,
5176 : double dfCenterLong,
5177 : double dfFalseEasting, double dfFalseNorthing )
5178 :
5179 : {
5180 0 : VALIDATE_POINTER1( hSRS, "OSRSetRobinson", CE_Failure );
5181 :
5182 : return ((OGRSpatialReference *) hSRS)->SetRobinson(
5183 : dfCenterLong,
5184 0 : dfFalseEasting, dfFalseNorthing );
5185 : }
5186 :
5187 : /************************************************************************/
5188 : /* SetSinusoidal() */
5189 : /************************************************************************/
5190 :
5191 22 : OGRErr OGRSpatialReference::SetSinusoidal( double dfCenterLong,
5192 : double dfFalseEasting,
5193 : double dfFalseNorthing )
5194 :
5195 : {
5196 22 : SetProjection( SRS_PT_SINUSOIDAL );
5197 22 : SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
5198 22 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5199 22 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5200 :
5201 22 : return OGRERR_NONE;
5202 : }
5203 :
5204 : /************************************************************************/
5205 : /* OSRSetSinusoidal() */
5206 : /************************************************************************/
5207 :
5208 0 : OGRErr OSRSetSinusoidal( OGRSpatialReferenceH hSRS,
5209 : double dfCenterLong,
5210 : double dfFalseEasting, double dfFalseNorthing )
5211 :
5212 : {
5213 0 : VALIDATE_POINTER1( hSRS, "OSRSetSinusoidal", CE_Failure );
5214 :
5215 : return ((OGRSpatialReference *) hSRS)->SetSinusoidal(
5216 : dfCenterLong,
5217 0 : dfFalseEasting, dfFalseNorthing );
5218 : }
5219 :
5220 : /************************************************************************/
5221 : /* SetStereographic() */
5222 : /************************************************************************/
5223 :
5224 22 : OGRErr OGRSpatialReference::SetStereographic(
5225 : double dfOriginLat, double dfCMeridian,
5226 : double dfScale,
5227 : double dfFalseEasting,
5228 : double dfFalseNorthing )
5229 :
5230 : {
5231 22 : SetProjection( SRS_PT_STEREOGRAPHIC );
5232 22 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
5233 22 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
5234 22 : SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
5235 22 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5236 22 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5237 :
5238 22 : return OGRERR_NONE;
5239 : }
5240 :
5241 : /************************************************************************/
5242 : /* OSRSetStereographic() */
5243 : /************************************************************************/
5244 :
5245 0 : OGRErr OSRSetStereographic( OGRSpatialReferenceH hSRS,
5246 : double dfOriginLat, double dfCMeridian,
5247 : double dfScale,
5248 : double dfFalseEasting, double dfFalseNorthing )
5249 :
5250 : {
5251 0 : VALIDATE_POINTER1( hSRS, "OSRSetStereographic", CE_Failure );
5252 :
5253 : return ((OGRSpatialReference *) hSRS)->SetStereographic(
5254 : dfOriginLat, dfCMeridian,
5255 : dfScale,
5256 0 : dfFalseEasting, dfFalseNorthing );
5257 : }
5258 :
5259 : /************************************************************************/
5260 : /* SetSOC() */
5261 : /* */
5262 : /* NOTE: This definition isn't really used in practice any more */
5263 : /* and should be considered deprecated. It seems that swiss */
5264 : /* oblique mercator is now define as Hotine_Oblique_Mercator */
5265 : /* with an azimuth of 90 and a rectified_grid_angle of 90. See */
5266 : /* EPSG:2056 and Bug 423. */
5267 : /************************************************************************/
5268 :
5269 0 : OGRErr OGRSpatialReference::SetSOC( double dfLatitudeOfOrigin,
5270 : double dfCentralMeridian,
5271 : double dfFalseEasting,
5272 : double dfFalseNorthing )
5273 :
5274 : {
5275 0 : SetProjection( SRS_PT_SWISS_OBLIQUE_CYLINDRICAL );
5276 0 : SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfLatitudeOfOrigin );
5277 0 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
5278 0 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5279 0 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5280 :
5281 0 : return OGRERR_NONE;
5282 : }
5283 :
5284 : /************************************************************************/
5285 : /* OSRSetSOC() */
5286 : /************************************************************************/
5287 :
5288 0 : OGRErr OSRSetSOC( OGRSpatialReferenceH hSRS,
5289 : double dfLatitudeOfOrigin, double dfCentralMeridian,
5290 : double dfFalseEasting, double dfFalseNorthing )
5291 :
5292 : {
5293 0 : VALIDATE_POINTER1( hSRS, "OSRSetSOC", CE_Failure );
5294 :
5295 : return ((OGRSpatialReference *) hSRS)->SetSOC(
5296 : dfLatitudeOfOrigin, dfCentralMeridian,
5297 0 : dfFalseEasting, dfFalseNorthing );
5298 : }
5299 :
5300 : /************************************************************************/
5301 : /* SetVDG() */
5302 : /************************************************************************/
5303 :
5304 8 : OGRErr OGRSpatialReference::SetVDG( double dfCMeridian,
5305 : double dfFalseEasting,
5306 : double dfFalseNorthing )
5307 :
5308 : {
5309 8 : SetProjection( SRS_PT_VANDERGRINTEN );
5310 8 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
5311 8 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5312 8 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5313 :
5314 8 : return OGRERR_NONE;
5315 : }
5316 :
5317 : /************************************************************************/
5318 : /* OSRSetVDG() */
5319 : /************************************************************************/
5320 :
5321 0 : OGRErr OSRSetVDG( OGRSpatialReferenceH hSRS,
5322 : double dfCentralMeridian,
5323 : double dfFalseEasting, double dfFalseNorthing )
5324 :
5325 : {
5326 0 : VALIDATE_POINTER1( hSRS, "OSRSetVDG", CE_Failure );
5327 :
5328 : return ((OGRSpatialReference *) hSRS)->SetVDG(
5329 : dfCentralMeridian,
5330 0 : dfFalseEasting, dfFalseNorthing );
5331 : }
5332 :
5333 : /************************************************************************/
5334 : /* SetUTM() */
5335 : /************************************************************************/
5336 :
5337 : /**
5338 : * \brief Set UTM projection definition.
5339 : *
5340 : * This will generate a projection definition with the full set of
5341 : * transverse mercator projection parameters for the given UTM zone.
5342 : * If no PROJCS[] description is set yet, one will be set to look
5343 : * like "UTM Zone %d, {Northern, Southern} Hemisphere".
5344 : *
5345 : * This method is the same as the C function OSRSetUTM().
5346 : *
5347 : * @param nZone UTM zone.
5348 : *
5349 : * @param bNorth TRUE for northern hemisphere, or FALSE for southern
5350 : * hemisphere.
5351 : *
5352 : * @return OGRERR_NONE on success.
5353 : */
5354 :
5355 352 : OGRErr OGRSpatialReference::SetUTM( int nZone, int bNorth )
5356 :
5357 : {
5358 352 : SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
5359 352 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0 );
5360 352 : SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, nZone * 6 - 183 );
5361 352 : SetNormProjParm( SRS_PP_SCALE_FACTOR, 0.9996 );
5362 352 : SetNormProjParm( SRS_PP_FALSE_EASTING, 500000.0 );
5363 :
5364 352 : if( bNorth )
5365 286 : SetNormProjParm( SRS_PP_FALSE_NORTHING, 0 );
5366 : else
5367 66 : SetNormProjParm( SRS_PP_FALSE_NORTHING, 10000000 );
5368 :
5369 352 : if( EQUAL(GetAttrValue("PROJCS"),"unnamed") )
5370 : {
5371 : char szUTMName[128];
5372 :
5373 340 : if( bNorth )
5374 276 : sprintf( szUTMName, "UTM Zone %d, Northern Hemisphere", nZone );
5375 : else
5376 64 : sprintf( szUTMName, "UTM Zone %d, Southern Hemisphere", nZone );
5377 :
5378 340 : SetNode( "PROJCS", szUTMName );
5379 : }
5380 :
5381 352 : SetLinearUnits( SRS_UL_METER, 1.0 );
5382 :
5383 352 : return OGRERR_NONE;
5384 : }
5385 :
5386 : /************************************************************************/
5387 : /* OSRSetUTM() */
5388 : /************************************************************************/
5389 :
5390 : /**
5391 : * \brief Set UTM projection definition.
5392 : *
5393 : * This is the same as the C++ method OGRSpatialReference::SetUTM()
5394 : */
5395 20 : OGRErr OSRSetUTM( OGRSpatialReferenceH hSRS, int nZone, int bNorth )
5396 :
5397 : {
5398 20 : VALIDATE_POINTER1( hSRS, "OSRSetUTM", CE_Failure );
5399 :
5400 20 : return ((OGRSpatialReference *) hSRS)->SetUTM( nZone, bNorth );
5401 : }
5402 :
5403 : /************************************************************************/
5404 : /* GetUTMZone() */
5405 : /* */
5406 : /* Returns zero if it isn't UTM. */
5407 : /************************************************************************/
5408 :
5409 : /**
5410 : * \brief Get utm zone information.
5411 : *
5412 : * This is the same as the C function OSRGetUTMZone().
5413 : *
5414 : * In SWIG bindings (Python, Java, etc) the GetUTMZone() method returns a
5415 : * zone which is negative in the southern hemisphere instead of having the
5416 : * pbNorth flag used in the C and C++ interface.
5417 : *
5418 : * @param pbNorth pointer to in to set to TRUE if northern hemisphere, or
5419 : * FALSE if southern.
5420 : *
5421 : * @return UTM zone number or zero if this isn't a UTM definition.
5422 : */
5423 :
5424 30612 : int OGRSpatialReference::GetUTMZone( int * pbNorth ) const
5425 :
5426 : {
5427 30612 : const char *pszProjection = GetAttrValue( "PROJECTION" );
5428 :
5429 30612 : if( pszProjection == NULL
5430 : || !EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
5431 12482 : return 0;
5432 :
5433 18130 : if( GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) != 0.0 )
5434 4486 : return 0;
5435 :
5436 13644 : if( GetProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) != 0.9996 )
5437 6274 : return 0;
5438 :
5439 7370 : if( fabs(GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 )-500000.0) > 0.001 )
5440 292 : return 0;
5441 :
5442 7078 : double dfFalseNorthing = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0);
5443 :
5444 7078 : if( dfFalseNorthing != 0.0
5445 : && fabs(dfFalseNorthing-10000000.0) > 0.001 )
5446 16 : return 0;
5447 :
5448 7062 : if( pbNorth != NULL )
5449 6980 : *pbNorth = (dfFalseNorthing == 0);
5450 :
5451 : double dfCentralMeridian = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
5452 7062 : 0.0);
5453 7062 : double dfZone = ( dfCentralMeridian + 186.0 ) / 6.0;
5454 :
5455 7062 : if( ABS(dfZone - (int) dfZone - 0.5 ) > 0.00001
5456 : || dfCentralMeridian < -177.00001
5457 : || dfCentralMeridian > 177.000001 )
5458 148 : return 0;
5459 : else
5460 6914 : return (int) dfZone;
5461 : }
5462 :
5463 : /************************************************************************/
5464 : /* OSRGetUTMZone() */
5465 : /************************************************************************/
5466 :
5467 : /**
5468 : * \brief Get utm zone information.
5469 : *
5470 : * This is the same as the C++ method OGRSpatialReference::GetUTMZone()
5471 : */
5472 4 : int OSRGetUTMZone( OGRSpatialReferenceH hSRS, int *pbNorth )
5473 :
5474 : {
5475 4 : VALIDATE_POINTER1( hSRS, "OSRGetUTMZone", 0 );
5476 :
5477 4 : return ((OGRSpatialReference *) hSRS)->GetUTMZone( pbNorth );
5478 : }
5479 :
5480 : /************************************************************************/
5481 : /* SetWagner() */
5482 : /************************************************************************/
5483 :
5484 14 : OGRErr OGRSpatialReference::SetWagner( int nVariation /* 1 -- 7 */,
5485 : double dfCenterLat,
5486 : double dfFalseEasting,
5487 : double dfFalseNorthing )
5488 :
5489 : {
5490 14 : if( nVariation == 1 )
5491 2 : SetProjection( SRS_PT_WAGNER_I );
5492 12 : else if( nVariation == 2 )
5493 2 : SetProjection( SRS_PT_WAGNER_II );
5494 10 : else if( nVariation == 3 )
5495 : {
5496 2 : SetProjection( SRS_PT_WAGNER_III );
5497 2 : SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
5498 : }
5499 8 : else if( nVariation == 4 )
5500 2 : SetProjection( SRS_PT_WAGNER_IV );
5501 6 : else if( nVariation == 5 )
5502 2 : SetProjection( SRS_PT_WAGNER_V );
5503 4 : else if( nVariation == 6 )
5504 2 : SetProjection( SRS_PT_WAGNER_VI );
5505 2 : else if( nVariation == 7 )
5506 2 : SetProjection( SRS_PT_WAGNER_VII );
5507 : else
5508 : {
5509 : CPLError( CE_Failure, CPLE_AppDefined,
5510 0 : "Unsupported Wagner variation (%d).", nVariation );
5511 0 : return OGRERR_UNSUPPORTED_SRS;
5512 : }
5513 :
5514 14 : SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
5515 14 : SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
5516 :
5517 14 : return OGRERR_NONE;
5518 : }
5519 :
5520 : /************************************************************************/
5521 : /* OSRSetWagner() */
5522 : /************************************************************************/
5523 :
5524 0 : OGRErr OSRSetWagner( OGRSpatialReferenceH hSRS,
5525 : int nVariation, double dfCenterLat,
5526 : double dfFalseEasting,
5527 : double dfFalseNorthing )
5528 :
5529 : {
5530 0 : VALIDATE_POINTER1( hSRS, "OSRSetWagner", CE_Failure );
5531 :
5532 : return ((OGRSpatialReference *) hSRS)->SetWagner(
5533 0 : nVariation, dfCenterLat, dfFalseEasting, dfFalseNorthing );
5534 : }
5535 :
5536 : /************************************************************************/
5537 : /* SetAuthority() */
5538 : /************************************************************************/
5539 :
5540 : /**
5541 : * \brief Set the authority for a node.
5542 : *
5543 : * This method is the same as the C function OSRSetAuthority().
5544 : *
5545 : * @param pszTargetKey the partial or complete path to the node to
5546 : * set an authority on. ie. "PROJCS", "GEOGCS" or "GEOGCS|UNIT".
5547 : *
5548 : * @param pszAuthority authority name, such as "EPSG".
5549 : *
5550 : * @param nCode code for value with this authority.
5551 : *
5552 : * @return OGRERR_NONE on success.
5553 : */
5554 :
5555 236138 : OGRErr OGRSpatialReference::SetAuthority( const char *pszTargetKey,
5556 : const char * pszAuthority,
5557 : int nCode )
5558 :
5559 : {
5560 : /* -------------------------------------------------------------------- */
5561 : /* Find the node below which the authority should be put. */
5562 : /* -------------------------------------------------------------------- */
5563 236138 : OGR_SRSNode *poNode = GetAttrNode( pszTargetKey );
5564 :
5565 236138 : if( poNode == NULL )
5566 8 : return OGRERR_FAILURE;
5567 :
5568 : /* -------------------------------------------------------------------- */
5569 : /* If there is an existing AUTHORITY child blow it away before */
5570 : /* trying to set a new one. */
5571 : /* -------------------------------------------------------------------- */
5572 236130 : int iOldChild = poNode->FindChild( "AUTHORITY" );
5573 236130 : if( iOldChild != -1 )
5574 0 : poNode->DestroyChild( iOldChild );
5575 :
5576 : /* -------------------------------------------------------------------- */
5577 : /* Create a new authority node. */
5578 : /* -------------------------------------------------------------------- */
5579 : char szCode[32];
5580 : OGR_SRSNode *poAuthNode;
5581 :
5582 236130 : sprintf( szCode, "%d", nCode );
5583 :
5584 236130 : poAuthNode = new OGR_SRSNode( "AUTHORITY" );
5585 472260 : poAuthNode->AddChild( new OGR_SRSNode( pszAuthority ) );
5586 472260 : poAuthNode->AddChild( new OGR_SRSNode( szCode ) );
5587 :
5588 236130 : poNode->AddChild( poAuthNode );
5589 :
5590 236130 : return OGRERR_NONE;
5591 : }
5592 :
5593 : /************************************************************************/
5594 : /* OSRSetAuthority() */
5595 : /************************************************************************/
5596 :
5597 : /**
5598 : * \brief Set the authority for a node.
5599 : *
5600 : * This function is the same as OGRSpatialReference::SetAuthority().
5601 : */
5602 0 : OGRErr OSRSetAuthority( OGRSpatialReferenceH hSRS,
5603 : const char *pszTargetKey,
5604 : const char * pszAuthority,
5605 : int nCode )
5606 :
5607 : {
5608 0 : VALIDATE_POINTER1( hSRS, "OSRSetAuthority", CE_Failure );
5609 :
5610 : return ((OGRSpatialReference *) hSRS)->SetAuthority( pszTargetKey,
5611 : pszAuthority,
5612 0 : nCode );
5613 : }
5614 :
5615 : /************************************************************************/
5616 : /* GetAuthorityCode() */
5617 : /************************************************************************/
5618 :
5619 : /**
5620 : * \brief Get the authority code for a node.
5621 : *
5622 : * This method is used to query an AUTHORITY[] node from within the
5623 : * WKT tree, and fetch the code value.
5624 : *
5625 : * While in theory values may be non-numeric, for the EPSG authority all
5626 : * code values should be integral.
5627 : *
5628 : * This method is the same as the C function OSRGetAuthorityCode().
5629 : *
5630 : * @param pszTargetKey the partial or complete path to the node to
5631 : * get an authority from. ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to
5632 : * search for an authority node on the root element.
5633 : *
5634 : * @return value code from authority node, or NULL on failure. The value
5635 : * returned is internal and should not be freed or modified.
5636 : */
5637 :
5638 : const char *
5639 11462 : OGRSpatialReference::GetAuthorityCode( const char *pszTargetKey ) const
5640 :
5641 : {
5642 : /* -------------------------------------------------------------------- */
5643 : /* Find the node below which the authority should be put. */
5644 : /* -------------------------------------------------------------------- */
5645 : const OGR_SRSNode *poNode;
5646 :
5647 11462 : if( pszTargetKey == NULL )
5648 484 : poNode = poRoot;
5649 : else
5650 10978 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
5651 :
5652 11462 : if( poNode == NULL )
5653 18 : return NULL;
5654 :
5655 : /* -------------------------------------------------------------------- */
5656 : /* Fetch AUTHORITY child if there is one. */
5657 : /* -------------------------------------------------------------------- */
5658 11444 : if( poNode->FindChild("AUTHORITY") == -1 )
5659 1152 : return NULL;
5660 :
5661 10292 : poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
5662 :
5663 : /* -------------------------------------------------------------------- */
5664 : /* Create a new authority node. */
5665 : /* -------------------------------------------------------------------- */
5666 10292 : if( poNode->GetChildCount() < 2 )
5667 0 : return NULL;
5668 :
5669 10292 : return poNode->GetChild(1)->GetValue();
5670 : }
5671 :
5672 : /************************************************************************/
5673 : /* OSRGetAuthorityCode() */
5674 : /************************************************************************/
5675 :
5676 : /**
5677 : * \brief Get the authority code for a node.
5678 : *
5679 : * This function is the same as OGRSpatialReference::GetAuthorityCode().
5680 : */
5681 2630 : const char *OSRGetAuthorityCode( OGRSpatialReferenceH hSRS,
5682 : const char *pszTargetKey )
5683 :
5684 : {
5685 2630 : VALIDATE_POINTER1( hSRS, "OSRGetAuthorityCode", NULL );
5686 :
5687 2630 : return ((OGRSpatialReference *) hSRS)->GetAuthorityCode( pszTargetKey );
5688 : }
5689 :
5690 : /************************************************************************/
5691 : /* GetAuthorityName() */
5692 : /************************************************************************/
5693 :
5694 : /**
5695 : * \brief Get the authority name for a node.
5696 : *
5697 : * This method is used to query an AUTHORITY[] node from within the
5698 : * WKT tree, and fetch the authority name value.
5699 : *
5700 : * The most common authority is "EPSG".
5701 : *
5702 : * This method is the same as the C function OSRGetAuthorityName().
5703 : *
5704 : * @param pszTargetKey the partial or complete path to the node to
5705 : * get an authority from. ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to
5706 : * search for an authority node on the root element.
5707 : *
5708 : * @return value code from authority node, or NULL on failure. The value
5709 : * returned is internal and should not be freed or modified.
5710 : */
5711 :
5712 : const char *
5713 87550 : OGRSpatialReference::GetAuthorityName( const char *pszTargetKey ) const
5714 :
5715 : {
5716 : /* -------------------------------------------------------------------- */
5717 : /* Find the node below which the authority should be put. */
5718 : /* -------------------------------------------------------------------- */
5719 : const OGR_SRSNode *poNode;
5720 :
5721 87550 : if( pszTargetKey == NULL )
5722 322 : poNode = poRoot;
5723 : else
5724 87228 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
5725 :
5726 87550 : if( poNode == NULL )
5727 5902 : return NULL;
5728 :
5729 : /* -------------------------------------------------------------------- */
5730 : /* Fetch AUTHORITY child if there is one. */
5731 : /* -------------------------------------------------------------------- */
5732 81648 : if( poNode->FindChild("AUTHORITY") == -1 )
5733 33064 : return NULL;
5734 :
5735 48584 : poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
5736 :
5737 : /* -------------------------------------------------------------------- */
5738 : /* Create a new authority node. */
5739 : /* -------------------------------------------------------------------- */
5740 48584 : if( poNode->GetChildCount() < 2 )
5741 0 : return NULL;
5742 :
5743 48584 : return poNode->GetChild(0)->GetValue();
5744 : }
5745 :
5746 : /************************************************************************/
5747 : /* OSRGetAuthorityName() */
5748 : /************************************************************************/
5749 :
5750 : /**
5751 : * \brief Get the authority name for a node.
5752 : *
5753 : * This function is the same as OGRSpatialReference::GetAuthorityName().
5754 : */
5755 136 : const char *OSRGetAuthorityName( OGRSpatialReferenceH hSRS,
5756 : const char *pszTargetKey )
5757 :
5758 : {
5759 136 : VALIDATE_POINTER1( hSRS, "OSRGetAuthorityName", NULL );
5760 :
5761 136 : return ((OGRSpatialReference *) hSRS)->GetAuthorityName( pszTargetKey );
5762 : }
5763 :
5764 : /************************************************************************/
5765 : /* StripVertical() */
5766 : /************************************************************************/
5767 :
5768 : /**
5769 : * \brief Convert a compound cs into a horizontal CS.
5770 : *
5771 : * If this SRS is of type COMPD_CS[] then the vertical CS and the root COMPD_CS
5772 : * nodes are stripped resulting and only the horizontal coordinate system
5773 : * portion remains (normally PROJCS, GEOGCS or LOCAL_CS).
5774 : *
5775 : * If this is not a compound coordinate system then nothing is changed.
5776 : *
5777 : * @since OGR 1.8.0
5778 : */
5779 :
5780 71064 : OGRErr OGRSpatialReference::StripVertical()
5781 :
5782 : {
5783 71064 : if( GetRoot() == NULL
5784 : || !EQUAL(GetRoot()->GetValue(),"COMPD_CS") )
5785 71062 : return OGRERR_NONE;
5786 :
5787 2 : OGR_SRSNode *poHorizontalCS = GetRoot()->GetChild( 1 );
5788 2 : if( poHorizontalCS != NULL )
5789 2 : poHorizontalCS = poHorizontalCS->Clone();
5790 2 : SetRoot( poHorizontalCS );
5791 :
5792 2 : return OGRERR_NONE;
5793 : }
5794 :
5795 : /************************************************************************/
5796 : /* StripCTParms() */
5797 : /************************************************************************/
5798 :
5799 : /**
5800 : * \brief Strip OGC CT Parameters.
5801 : *
5802 : * This method will remove all components of the coordinate system
5803 : * that are specific to the OGC CT Specification. That is it will attempt
5804 : * to strip it down to being compatible with the Simple Features 1.0
5805 : * specification.
5806 : *
5807 : * This method is the same as the C function OSRStripCTParms().
5808 : *
5809 : * @param poCurrent node to operate on. NULL to operate on whole tree.
5810 : *
5811 : * @return OGRERR_NONE on success or an error code.
5812 : */
5813 :
5814 71062 : OGRErr OGRSpatialReference::StripCTParms( OGR_SRSNode * poCurrent )
5815 :
5816 : {
5817 71062 : if( poCurrent == NULL )
5818 : {
5819 71062 : StripVertical();
5820 71062 : poCurrent = GetRoot();
5821 : }
5822 :
5823 71062 : if( poCurrent == NULL )
5824 0 : return OGRERR_NONE;
5825 :
5826 71062 : if( poCurrent == GetRoot() && EQUAL(poCurrent->GetValue(),"LOCAL_CS") )
5827 : {
5828 0 : delete poCurrent;
5829 0 : poRoot = NULL;
5830 :
5831 0 : return OGRERR_NONE;
5832 : }
5833 :
5834 71062 : if( poCurrent == NULL )
5835 0 : return OGRERR_NONE;
5836 :
5837 71062 : poCurrent->StripNodes( "AUTHORITY" );
5838 71062 : poCurrent->StripNodes( "TOWGS84" );
5839 71062 : poCurrent->StripNodes( "AXIS" );
5840 71062 : poCurrent->StripNodes( "EXTENSION" );
5841 :
5842 71062 : return OGRERR_NONE;
5843 : }
5844 :
5845 : /************************************************************************/
5846 : /* OSRStripCTParms() */
5847 : /************************************************************************/
5848 :
5849 : /**
5850 : * \brief Strip OGC CT Parameters.
5851 : *
5852 : * This function is the same as OGRSpatialReference::StripCTParms().
5853 : */
5854 33386 : OGRErr OSRStripCTParms( OGRSpatialReferenceH hSRS )
5855 :
5856 : {
5857 33386 : VALIDATE_POINTER1( hSRS, "OSRStripCTParms", CE_Failure );
5858 :
5859 33386 : return ((OGRSpatialReference *) hSRS)->StripCTParms( NULL );
5860 : }
5861 :
5862 : /************************************************************************/
5863 : /* IsCompound() */
5864 : /************************************************************************/
5865 :
5866 : /**
5867 : * \brief Check if coordinate system is compound.
5868 : *
5869 : * This method is the same as the C function OSRIsCompound().
5870 : *
5871 : * @return TRUE if this is rooted with a COMPD_CS node.
5872 : */
5873 :
5874 2 : int OGRSpatialReference::IsCompound() const
5875 :
5876 : {
5877 2 : if( poRoot == NULL )
5878 0 : return FALSE;
5879 :
5880 2 : return EQUAL(poRoot->GetValue(),"COMPD_CS");
5881 : }
5882 :
5883 : /************************************************************************/
5884 : /* OSRIsCompound() */
5885 : /************************************************************************/
5886 :
5887 : /**
5888 : * \brief Check if the coordinate system is compound.
5889 : *
5890 : * This function is the same as OGRSpatialReference::IsCompound().
5891 : */
5892 2 : int OSRIsCompound( OGRSpatialReferenceH hSRS )
5893 :
5894 : {
5895 2 : VALIDATE_POINTER1( hSRS, "OSRIsCompound", 0 );
5896 :
5897 2 : return ((OGRSpatialReference *) hSRS)->IsCompound();
5898 : }
5899 :
5900 : /************************************************************************/
5901 : /* IsProjected() */
5902 : /************************************************************************/
5903 :
5904 : /**
5905 : * \brief Check if projected coordinate system.
5906 : *
5907 : * This method is the same as the C function OSRIsProjected().
5908 : *
5909 : * @return TRUE if this contains a PROJCS node indicating a it is a
5910 : * projected coordinate system.
5911 : */
5912 :
5913 99250 : int OGRSpatialReference::IsProjected() const
5914 :
5915 : {
5916 99250 : if( poRoot == NULL )
5917 582 : return FALSE;
5918 :
5919 98668 : if( EQUAL(poRoot->GetValue(),"PROJCS") )
5920 73178 : return TRUE;
5921 25490 : else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
5922 36 : return GetAttrNode( "PROJCS" ) != NULL;
5923 : else
5924 25454 : return FALSE;
5925 : }
5926 :
5927 : /************************************************************************/
5928 : /* OSRIsProjected() */
5929 : /************************************************************************/
5930 : /**
5931 : * \brief Check if projected coordinate system.
5932 : *
5933 : * This function is the same as OGRSpatialReference::IsProjected().
5934 : */
5935 12 : int OSRIsProjected( OGRSpatialReferenceH hSRS )
5936 :
5937 : {
5938 12 : VALIDATE_POINTER1( hSRS, "OSRIsProjected", 0 );
5939 :
5940 12 : return ((OGRSpatialReference *) hSRS)->IsProjected();
5941 : }
5942 :
5943 : /************************************************************************/
5944 : /* IsGeocentric() */
5945 : /************************************************************************/
5946 :
5947 : /**
5948 : * \brief Check if geocentric coordinate system.
5949 : *
5950 : * This method is the same as the C function OSRIsGeocentric().
5951 : *
5952 : * @return TRUE if this contains a GEOCCS node indicating a it is a
5953 : * geocentric coordinate system.
5954 : *
5955 : * @since OGR 1.9.0
5956 : */
5957 :
5958 58332 : int OGRSpatialReference::IsGeocentric() const
5959 :
5960 : {
5961 58332 : if( poRoot == NULL )
5962 16628 : return FALSE;
5963 :
5964 41704 : if( EQUAL(poRoot->GetValue(),"GEOCCS") )
5965 24 : return TRUE;
5966 : else
5967 41680 : return FALSE;
5968 : }
5969 :
5970 : /************************************************************************/
5971 : /* OSRIsGeocentric() */
5972 : /************************************************************************/
5973 : /**
5974 : * \brief Check if geocentric coordinate system.
5975 : *
5976 : * This function is the same as OGRSpatialReference::IsGeocentric().
5977 : *
5978 : * @since OGR 1.9.0
5979 : */
5980 4 : int OSRIsGeocentric( OGRSpatialReferenceH hSRS )
5981 :
5982 : {
5983 4 : VALIDATE_POINTER1( hSRS, "OSRIsGeocentric", 0 );
5984 :
5985 4 : return ((OGRSpatialReference *) hSRS)->IsGeocentric();
5986 : }
5987 :
5988 : /************************************************************************/
5989 : /* IsGeographic() */
5990 : /************************************************************************/
5991 :
5992 : /**
5993 : * \brief Check if geographic coordinate system.
5994 : *
5995 : * This method is the same as the C function OSRIsGeographic().
5996 : *
5997 : * @return TRUE if this spatial reference is geographic ... that is the
5998 : * root is a GEOGCS node.
5999 : */
6000 :
6001 7916 : int OGRSpatialReference::IsGeographic() const
6002 :
6003 : {
6004 7916 : if( GetRoot() == NULL )
6005 18 : return FALSE;
6006 :
6007 7898 : if( EQUAL(poRoot->GetValue(),"GEOGCS") )
6008 6112 : return TRUE;
6009 1786 : else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
6010 : return GetAttrNode( "GEOGCS" ) != NULL
6011 4 : && GetAttrNode( "PROJCS" ) == NULL;
6012 : else
6013 1782 : return FALSE;
6014 : }
6015 :
6016 : /************************************************************************/
6017 : /* OSRIsGeographic() */
6018 : /************************************************************************/
6019 : /**
6020 : * \brief Check if geographic coordinate system.
6021 : *
6022 : * This function is the same as OGRSpatialReference::IsGeographic().
6023 : */
6024 88 : int OSRIsGeographic( OGRSpatialReferenceH hSRS )
6025 :
6026 : {
6027 88 : VALIDATE_POINTER1( hSRS, "OSRIsGeographic", 0 );
6028 :
6029 88 : return ((OGRSpatialReference *) hSRS)->IsGeographic();
6030 : }
6031 :
6032 : /************************************************************************/
6033 : /* IsLocal() */
6034 : /************************************************************************/
6035 :
6036 : /**
6037 : * \brief Check if local coordinate system.
6038 : *
6039 : * This method is the same as the C function OSRIsLocal().
6040 : *
6041 : * @return TRUE if this spatial reference is local ... that is the
6042 : * root is a LOCAL_CS node.
6043 : */
6044 :
6045 31052 : int OGRSpatialReference::IsLocal() const
6046 :
6047 : {
6048 31052 : if( GetRoot() == NULL )
6049 28 : return FALSE;
6050 :
6051 31024 : return EQUAL(GetRoot()->GetValue(),"LOCAL_CS");
6052 : }
6053 :
6054 : /************************************************************************/
6055 : /* OSRIsLocal() */
6056 : /************************************************************************/
6057 : /**
6058 : * \brief Check if local coordinate system.
6059 : *
6060 : * This function is the same as OGRSpatialReference::IsLocal().
6061 : */
6062 2 : int OSRIsLocal( OGRSpatialReferenceH hSRS )
6063 :
6064 : {
6065 2 : VALIDATE_POINTER1( hSRS, "OSRIsLocal", 0 );
6066 :
6067 2 : return ((OGRSpatialReference *) hSRS)->IsLocal();
6068 : }
6069 :
6070 : /************************************************************************/
6071 : /* IsVertical() */
6072 : /************************************************************************/
6073 :
6074 : /**
6075 : * \brief Check if vertical coordinate system.
6076 : *
6077 : * This method is the same as the C function OSRIsVertical().
6078 : *
6079 : * @return TRUE if this contains a VERT_CS node indicating a it is a
6080 : * vertical coordinate system.
6081 : *
6082 : * @since OGR 1.8.0
6083 : */
6084 :
6085 31812 : int OGRSpatialReference::IsVertical() const
6086 :
6087 : {
6088 31812 : if( poRoot == NULL )
6089 100 : return FALSE;
6090 :
6091 31712 : if( EQUAL(poRoot->GetValue(),"VERT_CS") )
6092 2 : return TRUE;
6093 31710 : else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
6094 10 : return GetAttrNode( "VERT_CS" ) != NULL;
6095 : else
6096 31700 : return FALSE;
6097 : }
6098 :
6099 : /************************************************************************/
6100 : /* OSRIsVertical() */
6101 : /************************************************************************/
6102 : /**
6103 : * \brief Check if vertical coordinate system.
6104 : *
6105 : * This function is the same as OGRSpatialReference::IsVertical().
6106 : *
6107 : * @since OGR 1.8.0
6108 : */
6109 0 : int OSRIsVertical( OGRSpatialReferenceH hSRS )
6110 :
6111 : {
6112 0 : VALIDATE_POINTER1( hSRS, "OSRIsVertical", 0 );
6113 :
6114 0 : return ((OGRSpatialReference *) hSRS)->IsVertical();
6115 : }
6116 :
6117 : /************************************************************************/
6118 : /* CloneGeogCS() */
6119 : /************************************************************************/
6120 :
6121 : /**
6122 : * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
6123 : *
6124 : * @return a new SRS, which becomes the responsibility of the caller.
6125 : */
6126 9054 : OGRSpatialReference *OGRSpatialReference::CloneGeogCS() const
6127 :
6128 : {
6129 : const OGR_SRSNode *poGeogCS;
6130 : OGRSpatialReference * poNewSRS;
6131 :
6132 : /* -------------------------------------------------------------------- */
6133 : /* We have to reconstruct the GEOGCS node for geocentric */
6134 : /* coordinate systems. */
6135 : /* -------------------------------------------------------------------- */
6136 9054 : if( IsGeocentric() )
6137 : {
6138 0 : const OGR_SRSNode *poDatum = GetAttrNode( "DATUM" );
6139 0 : const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
6140 : OGR_SRSNode *poGeogCS;
6141 :
6142 0 : if( poDatum == NULL || poPRIMEM == NULL )
6143 0 : return NULL;
6144 :
6145 0 : poGeogCS = new OGR_SRSNode( "GEOGCS" );
6146 0 : poGeogCS->AddChild( new OGR_SRSNode( "unnamed" ) );
6147 0 : poGeogCS->AddChild( poDatum->Clone() );
6148 0 : poGeogCS->AddChild( poPRIMEM->Clone() );
6149 :
6150 0 : poNewSRS = new OGRSpatialReference();
6151 0 : poNewSRS->SetRoot( poGeogCS );
6152 :
6153 0 : poNewSRS->SetAngularUnits( "degree", CPLAtof(SRS_UA_DEGREE_CONV) );
6154 :
6155 0 : return poNewSRS;
6156 : }
6157 :
6158 : /* -------------------------------------------------------------------- */
6159 : /* For all others we just search the tree, and duplicate. */
6160 : /* -------------------------------------------------------------------- */
6161 9054 : poGeogCS = GetAttrNode( "GEOGCS" );
6162 9054 : if( poGeogCS == NULL )
6163 2 : return NULL;
6164 :
6165 9052 : poNewSRS = new OGRSpatialReference();
6166 9052 : poNewSRS->SetRoot( poGeogCS->Clone() );
6167 :
6168 9052 : return poNewSRS;
6169 : }
6170 :
6171 : /************************************************************************/
6172 : /* OSRCloneGeogCS() */
6173 : /************************************************************************/
6174 : /**
6175 : * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
6176 : *
6177 : * This function is the same as OGRSpatialReference::CloneGeogCS().
6178 : */
6179 138 : OGRSpatialReferenceH CPL_STDCALL OSRCloneGeogCS( OGRSpatialReferenceH hSource )
6180 :
6181 : {
6182 138 : VALIDATE_POINTER1( hSource, "OSRCloneGeogCS", NULL );
6183 :
6184 : return (OGRSpatialReferenceH)
6185 138 : ((OGRSpatialReference *) hSource)->CloneGeogCS();
6186 : }
6187 :
6188 : /************************************************************************/
6189 : /* IsSameGeogCS() */
6190 : /************************************************************************/
6191 :
6192 : /**
6193 : * \brief Do the GeogCS'es match?
6194 : *
6195 : * This method is the same as the C function OSRIsSameGeogCS().
6196 : *
6197 : * @param poOther the SRS being compared against.
6198 : *
6199 : * @return TRUE if they are the same or FALSE otherwise.
6200 : */
6201 :
6202 38032 : int OGRSpatialReference::IsSameGeogCS( const OGRSpatialReference *poOther ) const
6203 :
6204 : {
6205 : const char *pszThisValue, *pszOtherValue;
6206 :
6207 : /* -------------------------------------------------------------------- */
6208 : /* Does the datum name match? Note that we assume */
6209 : /* compatibility if either is missing a datum. */
6210 : /* -------------------------------------------------------------------- */
6211 38032 : pszThisValue = this->GetAttrValue( "DATUM" );
6212 38032 : pszOtherValue = poOther->GetAttrValue( "DATUM" );
6213 :
6214 38032 : if( pszThisValue != NULL && pszOtherValue != NULL
6215 : && !EQUAL(pszThisValue,pszOtherValue) )
6216 430 : return FALSE;
6217 :
6218 : /* -------------------------------------------------------------------- */
6219 : /* Do the datum TOWGS84 values match if present? */
6220 : /* -------------------------------------------------------------------- */
6221 : double adfTOWGS84[7], adfOtherTOWGS84[7];
6222 : int i;
6223 :
6224 37602 : this->GetTOWGS84( adfTOWGS84, 7 );
6225 37602 : poOther->GetTOWGS84( adfOtherTOWGS84, 7 );
6226 :
6227 300816 : for( i = 0; i < 7; i++ )
6228 : {
6229 263214 : if( fabs(adfTOWGS84[i] - adfOtherTOWGS84[i]) > 0.00001 )
6230 0 : return FALSE;
6231 : }
6232 :
6233 : /* -------------------------------------------------------------------- */
6234 : /* Do the prime meridians match? If missing assume a value of zero.*/
6235 : /* -------------------------------------------------------------------- */
6236 37602 : pszThisValue = this->GetAttrValue( "PRIMEM", 1 );
6237 37602 : if( pszThisValue == NULL )
6238 2 : pszThisValue = "0.0";
6239 :
6240 37602 : pszOtherValue = poOther->GetAttrValue( "PRIMEM", 1 );
6241 37602 : if( pszOtherValue == NULL )
6242 2 : pszOtherValue = "0.0";
6243 :
6244 37602 : if( CPLAtof(pszOtherValue) != CPLAtof(pszThisValue) )
6245 190 : return FALSE;
6246 :
6247 : /* -------------------------------------------------------------------- */
6248 : /* Do the units match? */
6249 : /* -------------------------------------------------------------------- */
6250 37412 : pszThisValue = this->GetAttrValue( "GEOGCS|UNIT", 1 );
6251 37412 : if( pszThisValue == NULL )
6252 6 : pszThisValue = SRS_UA_DEGREE_CONV;
6253 :
6254 37412 : pszOtherValue = poOther->GetAttrValue( "GEOGCS|UNIT", 1 );
6255 37412 : if( pszOtherValue == NULL )
6256 230 : pszOtherValue = SRS_UA_DEGREE_CONV;
6257 :
6258 37412 : if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
6259 8 : return FALSE;
6260 :
6261 : /* -------------------------------------------------------------------- */
6262 : /* Does the spheroid match. Check semi major, and inverse */
6263 : /* flattening. */
6264 : /* -------------------------------------------------------------------- */
6265 37404 : pszThisValue = this->GetAttrValue( "SPHEROID", 1 );
6266 37404 : pszOtherValue = poOther->GetAttrValue( "SPHEROID", 1 );
6267 37404 : if( pszThisValue != NULL && pszOtherValue != NULL
6268 : && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.01 )
6269 24 : return FALSE;
6270 :
6271 37380 : pszThisValue = this->GetAttrValue( "SPHEROID", 2 );
6272 37380 : pszOtherValue = poOther->GetAttrValue( "SPHEROID", 2 );
6273 37380 : if( pszThisValue != NULL && pszOtherValue != NULL
6274 : && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.0001 )
6275 40 : return FALSE;
6276 :
6277 37340 : return TRUE;
6278 : }
6279 :
6280 : /************************************************************************/
6281 : /* OSRIsSameGeogCS() */
6282 : /************************************************************************/
6283 :
6284 : /**
6285 : * \brief Do the GeogCS'es match?
6286 : *
6287 : * This function is the same as OGRSpatialReference::IsSameGeogCS().
6288 : */
6289 0 : int OSRIsSameGeogCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
6290 :
6291 : {
6292 0 : VALIDATE_POINTER1( hSRS1, "OSRIsSameGeogCS", 0 );
6293 0 : VALIDATE_POINTER1( hSRS2, "OSRIsSameGeogCS", 0 );
6294 :
6295 : return ((OGRSpatialReference *) hSRS1)->IsSameGeogCS(
6296 0 : (OGRSpatialReference *) hSRS2 );
6297 : }
6298 :
6299 : /************************************************************************/
6300 : /* IsSameVertCS() */
6301 : /************************************************************************/
6302 :
6303 : /**
6304 : * \brief Do the VertCS'es match?
6305 : *
6306 : * This method is the same as the C function OSRIsSameVertCS().
6307 : *
6308 : * @param poOther the SRS being compared against.
6309 : *
6310 : * @return TRUE if they are the same or FALSE otherwise.
6311 : */
6312 :
6313 10 : int OGRSpatialReference::IsSameVertCS( const OGRSpatialReference *poOther ) const
6314 :
6315 : {
6316 : const char *pszThisValue, *pszOtherValue;
6317 :
6318 : /* -------------------------------------------------------------------- */
6319 : /* Does the datum name match? */
6320 : /* -------------------------------------------------------------------- */
6321 10 : pszThisValue = this->GetAttrValue( "VERT_DATUM" );
6322 10 : pszOtherValue = poOther->GetAttrValue( "VERT_DATUM" );
6323 :
6324 10 : if( pszThisValue == NULL || pszOtherValue == NULL
6325 : || !EQUAL(pszThisValue, pszOtherValue) )
6326 0 : return FALSE;
6327 :
6328 : /* -------------------------------------------------------------------- */
6329 : /* Do the units match? */
6330 : /* -------------------------------------------------------------------- */
6331 10 : pszThisValue = this->GetAttrValue( "VERT_CS|UNIT", 1 );
6332 10 : if( pszThisValue == NULL )
6333 0 : pszThisValue = "1.0";
6334 :
6335 10 : pszOtherValue = poOther->GetAttrValue( "VERT_CS|UNIT", 1 );
6336 10 : if( pszOtherValue == NULL )
6337 0 : pszOtherValue = "1.0";
6338 :
6339 10 : if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
6340 0 : return FALSE;
6341 :
6342 10 : return TRUE;
6343 : }
6344 :
6345 : /************************************************************************/
6346 : /* OSRIsSameVertCS() */
6347 : /************************************************************************/
6348 :
6349 : /**
6350 : * \brief Do the VertCS'es match?
6351 : *
6352 : * This function is the same as OGRSpatialReference::IsSameVertCS().
6353 : */
6354 0 : int OSRIsSameVertCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
6355 :
6356 : {
6357 0 : VALIDATE_POINTER1( hSRS1, "OSRIsSameVertCS", 0 );
6358 0 : VALIDATE_POINTER1( hSRS2, "OSRIsSameVertCS", 0 );
6359 :
6360 : return ((OGRSpatialReference *) hSRS1)->IsSameVertCS(
6361 0 : (OGRSpatialReference *) hSRS2 );
6362 : }
6363 :
6364 : /************************************************************************/
6365 : /* IsSame() */
6366 : /************************************************************************/
6367 :
6368 : /**
6369 : * \brief Do these two spatial references describe the same system ?
6370 : *
6371 : * @param poOtherSRS the SRS being compared to.
6372 : *
6373 : * @return TRUE if equivalent or FALSE otherwise.
6374 : */
6375 :
6376 29310 : int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const
6377 :
6378 : {
6379 29310 : if( GetRoot() == NULL && poOtherSRS->GetRoot() == NULL )
6380 16 : return TRUE;
6381 29294 : else if( GetRoot() == NULL || poOtherSRS->GetRoot() == NULL )
6382 0 : return FALSE;
6383 :
6384 : /* -------------------------------------------------------------------- */
6385 : /* Compare geographic coordinate system. */
6386 : /* -------------------------------------------------------------------- */
6387 29294 : if( !IsSameGeogCS( poOtherSRS ) )
6388 156 : return FALSE;
6389 :
6390 : /* -------------------------------------------------------------------- */
6391 : /* Do the have the same root types? Ie. is one PROJCS and one */
6392 : /* GEOGCS or perhaps LOCALCS? */
6393 : /* -------------------------------------------------------------------- */
6394 29138 : if( !EQUAL(GetRoot()->GetValue(),poOtherSRS->GetRoot()->GetValue()) )
6395 12 : return FALSE;
6396 :
6397 : /* -------------------------------------------------------------------- */
6398 : /* Compare projected coordinate system. */
6399 : /* -------------------------------------------------------------------- */
6400 29126 : if( IsProjected() )
6401 : {
6402 : const char *pszValue1, *pszValue2;
6403 23956 : const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
6404 :
6405 23956 : pszValue1 = this->GetAttrValue( "PROJECTION" );
6406 23956 : pszValue2 = poOtherSRS->GetAttrValue( "PROJECTION" );
6407 23956 : if( pszValue1 == NULL || pszValue2 == NULL
6408 : || !EQUAL(pszValue1,pszValue2) )
6409 4 : return FALSE;
6410 :
6411 244766 : for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
6412 : {
6413 : const OGR_SRSNode *poNode;
6414 :
6415 220822 : poNode = poPROJCS->GetChild( iChild );
6416 220822 : if( !EQUAL(poNode->GetValue(),"PARAMETER")
6417 : || poNode->GetChildCount() != 2 )
6418 96070 : continue;
6419 :
6420 : /* this this eventually test within some epsilon? */
6421 124752 : if( this->GetProjParm( poNode->GetChild(0)->GetValue() )
6422 : != poOtherSRS->GetProjParm( poNode->GetChild(0)->GetValue() ) )
6423 8 : return FALSE;
6424 : }
6425 : }
6426 :
6427 : /* -------------------------------------------------------------------- */
6428 : /* If they are LOCALCS/PROJCS, do they have the same units? */
6429 : /* -------------------------------------------------------------------- */
6430 29114 : if( IsLocal() || IsProjected() )
6431 : {
6432 23946 : if( GetLinearUnits() != 0.0 )
6433 : {
6434 : double dfRatio;
6435 :
6436 23946 : dfRatio = poOtherSRS->GetLinearUnits() / GetLinearUnits();
6437 23946 : if( dfRatio < 0.9999999999 || dfRatio > 1.000000001 )
6438 0 : return FALSE;
6439 : }
6440 : }
6441 :
6442 : /* -------------------------------------------------------------------- */
6443 : /* Compare vertical coordinate system. */
6444 : /* -------------------------------------------------------------------- */
6445 29114 : if( IsVertical() && !IsSameVertCS( poOtherSRS ) )
6446 0 : return FALSE;
6447 :
6448 29114 : return TRUE;
6449 : }
6450 :
6451 : /************************************************************************/
6452 : /* OSRIsSame() */
6453 : /************************************************************************/
6454 :
6455 : /**
6456 : * \brief Do these two spatial references describe the same system ?
6457 : *
6458 : * This function is the same as OGRSpatialReference::IsSame().
6459 : */
6460 29004 : int OSRIsSame( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
6461 :
6462 : {
6463 29004 : VALIDATE_POINTER1( hSRS1, "OSRIsSame", 0 );
6464 29004 : VALIDATE_POINTER1( hSRS2, "OSRIsSame", 0 );
6465 :
6466 : return ((OGRSpatialReference *) hSRS1)->IsSame(
6467 29004 : (OGRSpatialReference *) hSRS2 );
6468 : }
6469 :
6470 : /************************************************************************/
6471 : /* SetTOWGS84() */
6472 : /************************************************************************/
6473 :
6474 : /**
6475 : * \brief Set the Bursa-Wolf conversion to WGS84.
6476 : *
6477 : * This will create the TOWGS84 node as a child of the DATUM. It will fail
6478 : * if there is no existing DATUM node. Unlike most OGRSpatialReference
6479 : * methods it will insert itself in the appropriate order, and will replace
6480 : * an existing TOWGS84 node if there is one.
6481 : *
6482 : * The parameters have the same meaning as EPSG transformation 9606
6483 : * (Position Vector 7-param. transformation).
6484 : *
6485 : * This method is the same as the C function OSRSetTOWGS84().
6486 : *
6487 : * @param dfDX X child in meters.
6488 : * @param dfDY Y child in meters.
6489 : * @param dfDZ Z child in meters.
6490 : * @param dfEX X rotation in arc seconds (optional, defaults to zero).
6491 : * @param dfEY Y rotation in arc seconds (optional, defaults to zero).
6492 : * @param dfEZ Z rotation in arc seconds (optional, defaults to zero).
6493 : * @param dfPPM scaling factor (parts per million).
6494 : *
6495 : * @return OGRERR_NONE on success.
6496 : */
6497 :
6498 222 : OGRErr OGRSpatialReference::SetTOWGS84( double dfDX, double dfDY, double dfDZ,
6499 : double dfEX, double dfEY, double dfEZ,
6500 : double dfPPM )
6501 :
6502 : {
6503 : OGR_SRSNode *poDatum, *poTOWGS84;
6504 : int iPosition;
6505 : char szValue[64];
6506 :
6507 222 : poDatum = GetAttrNode( "DATUM" );
6508 222 : if( poDatum == NULL )
6509 0 : return OGRERR_FAILURE;
6510 :
6511 222 : if( poDatum->FindChild( "TOWGS84" ) != -1 )
6512 62 : poDatum->DestroyChild( poDatum->FindChild( "TOWGS84" ) );
6513 :
6514 222 : iPosition = poDatum->GetChildCount();
6515 222 : if( poDatum->FindChild("AUTHORITY") != -1 )
6516 : {
6517 116 : iPosition = poDatum->FindChild("AUTHORITY");
6518 : }
6519 :
6520 222 : poTOWGS84 = new OGR_SRSNode("TOWGS84");
6521 :
6522 222 : OGRPrintDouble( szValue, dfDX );
6523 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6524 :
6525 222 : OGRPrintDouble( szValue, dfDY );
6526 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6527 :
6528 222 : OGRPrintDouble( szValue, dfDZ );
6529 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6530 :
6531 222 : OGRPrintDouble( szValue, dfEX );
6532 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6533 :
6534 222 : OGRPrintDouble( szValue, dfEY );
6535 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6536 :
6537 222 : OGRPrintDouble( szValue, dfEZ );
6538 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6539 :
6540 222 : OGRPrintDouble( szValue, dfPPM );
6541 444 : poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
6542 :
6543 222 : poDatum->InsertChild( poTOWGS84, iPosition );
6544 :
6545 222 : return OGRERR_NONE;
6546 : }
6547 :
6548 : /************************************************************************/
6549 : /* OSRSetTOWGS84() */
6550 : /************************************************************************/
6551 :
6552 : /**
6553 : * \brief Set the Bursa-Wolf conversion to WGS84.
6554 : *
6555 : * This function is the same as OGRSpatialReference::SetTOWGS84().
6556 : */
6557 44 : OGRErr OSRSetTOWGS84( OGRSpatialReferenceH hSRS,
6558 : double dfDX, double dfDY, double dfDZ,
6559 : double dfEX, double dfEY, double dfEZ,
6560 : double dfPPM )
6561 :
6562 : {
6563 44 : VALIDATE_POINTER1( hSRS, "OSRSetTOWGS84", CE_Failure );
6564 :
6565 : return ((OGRSpatialReference *) hSRS)->SetTOWGS84( dfDX, dfDY, dfDZ,
6566 : dfEX, dfEY, dfEZ,
6567 44 : dfPPM );
6568 : }
6569 :
6570 : /************************************************************************/
6571 : /* GetTOWGS84() */
6572 : /************************************************************************/
6573 :
6574 : /**
6575 : * \brief Fetch TOWGS84 parameters, if available.
6576 : *
6577 : * @param padfCoeff array into which up to 7 coefficients are placed.
6578 : * @param nCoeffCount size of padfCoeff - defaults to 7.
6579 : *
6580 : * @return OGRERR_NONE on success, or OGRERR_FAILURE if there is no
6581 : * TOWGS84 node available.
6582 : */
6583 :
6584 77190 : OGRErr OGRSpatialReference::GetTOWGS84( double * padfCoeff,
6585 : int nCoeffCount ) const
6586 :
6587 : {
6588 77190 : const OGR_SRSNode *poNode = GetAttrNode( "TOWGS84" );
6589 :
6590 77190 : memset( padfCoeff, 0, sizeof(double) * nCoeffCount );
6591 :
6592 77190 : if( poNode == NULL )
6593 76366 : return OGRERR_FAILURE;
6594 :
6595 6592 : for( int i = 0; i < nCoeffCount && i < poNode->GetChildCount(); i++ )
6596 : {
6597 5768 : padfCoeff[i] = CPLAtof(poNode->GetChild(i)->GetValue());
6598 : }
6599 :
6600 824 : return OGRERR_NONE;
6601 : }
6602 :
6603 : /************************************************************************/
6604 : /* OSRGetTOWGS84() */
6605 : /************************************************************************/
6606 :
6607 : /**
6608 : * \brief Fetch TOWGS84 parameters, if available.
6609 : *
6610 : * This function is the same as OGRSpatialReference::GetTOWGS84().
6611 : */
6612 6 : OGRErr OSRGetTOWGS84( OGRSpatialReferenceH hSRS,
6613 : double * padfCoeff, int nCoeffCount )
6614 :
6615 : {
6616 6 : VALIDATE_POINTER1( hSRS, "OSRGetTOWGS84", CE_Failure );
6617 :
6618 6 : return ((OGRSpatialReference *) hSRS)->GetTOWGS84( padfCoeff, nCoeffCount);
6619 : }
6620 :
6621 : /************************************************************************/
6622 : /* IsAngularParameter() */
6623 : /* */
6624 : /* Is the passed projection parameter an angular one? */
6625 : /************************************************************************/
6626 :
6627 2794 : int OGRSpatialReference::IsAngularParameter( const char *pszParameterName )
6628 :
6629 : {
6630 2794 : if( EQUALN(pszParameterName,"long",4)
6631 : || EQUALN(pszParameterName,"lati",4)
6632 : || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN)
6633 : || EQUALN(pszParameterName,"standard_parallel",17)
6634 : || EQUAL(pszParameterName,SRS_PP_AZIMUTH)
6635 : || EQUAL(pszParameterName,SRS_PP_RECTIFIED_GRID_ANGLE) )
6636 1160 : return TRUE;
6637 : else
6638 1634 : return FALSE;
6639 : }
6640 :
6641 : /************************************************************************/
6642 : /* IsLongitudeParameter() */
6643 : /* */
6644 : /* Is the passed projection parameter an angular longitude */
6645 : /* (relative to a prime meridian)? */
6646 : /************************************************************************/
6647 :
6648 0 : int OGRSpatialReference::IsLongitudeParameter( const char *pszParameterName )
6649 :
6650 : {
6651 0 : if( EQUALN(pszParameterName,"long",4)
6652 : || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN) )
6653 0 : return TRUE;
6654 : else
6655 0 : return FALSE;
6656 : }
6657 :
6658 : /************************************************************************/
6659 : /* IsLinearParameter() */
6660 : /* */
6661 : /* Is the passed projection parameter an linear one measured in */
6662 : /* meters or some similar linear measure. */
6663 : /************************************************************************/
6664 :
6665 20478 : int OGRSpatialReference::IsLinearParameter( const char *pszParameterName )
6666 :
6667 : {
6668 20478 : if( EQUALN(pszParameterName,"false_",6)
6669 : || EQUAL(pszParameterName,SRS_PP_SATELLITE_HEIGHT) )
6670 6972 : return TRUE;
6671 : else
6672 13506 : return FALSE;
6673 : }
6674 :
6675 : /************************************************************************/
6676 : /* GetNormInfo() */
6677 : /************************************************************************/
6678 :
6679 : /**
6680 : * \brief Set the internal information for normalizing linear, and angular values.
6681 : */
6682 172177 : void OGRSpatialReference::GetNormInfo(void) const
6683 :
6684 : {
6685 172177 : if( bNormInfoSet )
6686 128449 : return;
6687 :
6688 : /* -------------------------------------------------------------------- */
6689 : /* Initialize values. */
6690 : /* -------------------------------------------------------------------- */
6691 43728 : OGRSpatialReference *poThis = (OGRSpatialReference *) this;
6692 :
6693 43728 : poThis->bNormInfoSet = TRUE;
6694 :
6695 43728 : poThis->dfFromGreenwich = GetPrimeMeridian(NULL);
6696 43728 : poThis->dfToMeter = GetLinearUnits(NULL);
6697 43728 : poThis->dfToDegrees = GetAngularUnits(NULL) / CPLAtof(SRS_UA_DEGREE_CONV);
6698 43728 : if( fabs(poThis->dfToDegrees-1.0) < 0.000000001 )
6699 43582 : poThis->dfToDegrees = 1.0;
6700 : }
6701 :
6702 : /************************************************************************/
6703 : /* FixupOrdering() */
6704 : /************************************************************************/
6705 :
6706 : /**
6707 : * \brief Correct parameter ordering to match CT Specification.
6708 : *
6709 : * Some mechanisms to create WKT using OGRSpatialReference, and some
6710 : * imported WKT fail to maintain the order of parameters required according
6711 : * to the BNF definitions in the OpenGIS SF-SQL and CT Specifications. This
6712 : * method attempts to massage things back into the required order.
6713 : *
6714 : * This method is the same as the C function OSRFixupOrdering().
6715 : *
6716 : * @return OGRERR_NONE on success or an error code if something goes
6717 : * wrong.
6718 : */
6719 :
6720 68010 : OGRErr OGRSpatialReference::FixupOrdering()
6721 :
6722 : {
6723 68010 : if( GetRoot() != NULL )
6724 68010 : return GetRoot()->FixupOrdering();
6725 : else
6726 0 : return OGRERR_NONE;
6727 : }
6728 :
6729 : /************************************************************************/
6730 : /* OSRFixupOrdering() */
6731 : /************************************************************************/
6732 :
6733 : /**
6734 : * \brief Correct parameter ordering to match CT Specification.
6735 : *
6736 : * This function is the same as OGRSpatialReference::FixupOrdering().
6737 : */
6738 0 : OGRErr OSRFixupOrdering( OGRSpatialReferenceH hSRS )
6739 :
6740 : {
6741 0 : VALIDATE_POINTER1( hSRS, "OSRFixupOrdering", CE_Failure );
6742 :
6743 0 : return ((OGRSpatialReference *) hSRS)->FixupOrdering();
6744 : }
6745 :
6746 : /************************************************************************/
6747 : /* Fixup() */
6748 : /************************************************************************/
6749 :
6750 : /**
6751 : * \brief Fixup as needed.
6752 : *
6753 : * Some mechanisms to create WKT using OGRSpatialReference, and some
6754 : * imported WKT, are not valid according to the OGC CT specification. This
6755 : * method attempts to fill in any missing defaults that are required, and
6756 : * fixup ordering problems (using OSRFixupOrdering()) so that the resulting
6757 : * WKT is valid.
6758 : *
6759 : * This method should be expected to evolve over time to as problems are
6760 : * discovered. The following are amoung the fixup actions this method will
6761 : * take:
6762 : *
6763 : * - Fixup the ordering of nodes to match the BNF WKT ordering, using
6764 : * the FixupOrdering() method.
6765 : *
6766 : * - Add missing linear or angular units nodes.
6767 : *
6768 : * This method is the same as the C function OSRFixup().
6769 : *
6770 : * @return OGRERR_NONE on success or an error code if something goes
6771 : * wrong.
6772 : */
6773 :
6774 29624 : OGRErr OGRSpatialReference::Fixup()
6775 :
6776 : {
6777 : /* -------------------------------------------------------------------- */
6778 : /* Ensure linear units defaulted to METER if missing for PROJCS, */
6779 : /* GEOCCS or LOCAL_CS. */
6780 : /* -------------------------------------------------------------------- */
6781 29624 : const OGR_SRSNode *poCS = GetAttrNode( "PROJCS" );
6782 :
6783 29624 : if( poCS == NULL )
6784 5462 : poCS = GetAttrNode( "LOCAL_CS" );
6785 :
6786 29624 : if( poCS == NULL )
6787 5460 : poCS = GetAttrNode( "GEOCCS" );
6788 :
6789 29624 : if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
6790 30 : SetLinearUnits( SRS_UL_METER, 1.0 );
6791 :
6792 : /* -------------------------------------------------------------------- */
6793 : /* Ensure angular units defaulted to degrees on the GEOGCS. */
6794 : /* -------------------------------------------------------------------- */
6795 29624 : poCS = GetAttrNode( "GEOGCS" );
6796 29624 : if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
6797 0 : SetAngularUnits( SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV) );
6798 :
6799 29624 : return FixupOrdering();
6800 : }
6801 :
6802 : /************************************************************************/
6803 : /* OSRFixup() */
6804 : /************************************************************************/
6805 :
6806 : /**
6807 : * \brief Fixup as needed.
6808 : *
6809 : * This function is the same as OGRSpatialReference::Fixup().
6810 : */
6811 2 : OGRErr OSRFixup( OGRSpatialReferenceH hSRS )
6812 :
6813 : {
6814 2 : VALIDATE_POINTER1( hSRS, "OSRFixup", CE_Failure );
6815 :
6816 2 : return ((OGRSpatialReference *) hSRS)->Fixup();
6817 : }
6818 :
6819 : /************************************************************************/
6820 : /* GetExtension() */
6821 : /************************************************************************/
6822 :
6823 : /**
6824 : * \brief Fetch extension value.
6825 : *
6826 : * Fetch the value of the named EXTENSION item for the identified
6827 : * target node.
6828 : *
6829 : * @param pszTargetKey the name or path to the parent node of the EXTENSION.
6830 : * @param pszName the name of the extension being fetched.
6831 : * @param pszDefault the value to return if the extension is not found.
6832 : *
6833 : * @return node value if successful or pszDefault on failure.
6834 : */
6835 :
6836 8624 : const char *OGRSpatialReference::GetExtension( const char *pszTargetKey,
6837 : const char *pszName,
6838 : const char *pszDefault ) const
6839 :
6840 : {
6841 : /* -------------------------------------------------------------------- */
6842 : /* Find the target node. */
6843 : /* -------------------------------------------------------------------- */
6844 : const OGR_SRSNode *poNode;
6845 :
6846 8624 : if( pszTargetKey == NULL )
6847 0 : poNode = poRoot;
6848 : else
6849 8624 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
6850 :
6851 8624 : if( poNode == NULL )
6852 2328 : return NULL;
6853 :
6854 : /* -------------------------------------------------------------------- */
6855 : /* Fetch matching EXTENSION if there is one. */
6856 : /* -------------------------------------------------------------------- */
6857 38540 : for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
6858 : {
6859 32424 : const OGR_SRSNode *poChild = poNode->GetChild(i);
6860 :
6861 32424 : if( EQUAL(poChild->GetValue(),"EXTENSION")
6862 : && poChild->GetChildCount() >= 2 )
6863 : {
6864 324 : if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
6865 180 : return poChild->GetChild(1)->GetValue();
6866 : }
6867 : }
6868 :
6869 6116 : return pszDefault;
6870 : }
6871 :
6872 : /************************************************************************/
6873 : /* SetExtension() */
6874 : /************************************************************************/
6875 : /**
6876 : * \brief Set extension value.
6877 : *
6878 : * Set the value of the named EXTENSION item for the identified
6879 : * target node.
6880 : *
6881 : * @param pszTargetKey the name or path to the parent node of the EXTENSION.
6882 : * @param pszName the name of the extension being fetched.
6883 : * @param pszValue the value to set
6884 : *
6885 : * @return OGRERR_NONE on success
6886 : */
6887 :
6888 99 : OGRErr OGRSpatialReference::SetExtension( const char *pszTargetKey,
6889 : const char *pszName,
6890 : const char *pszValue )
6891 :
6892 : {
6893 : /* -------------------------------------------------------------------- */
6894 : /* Find the target node. */
6895 : /* -------------------------------------------------------------------- */
6896 : OGR_SRSNode *poNode;
6897 :
6898 99 : if( pszTargetKey == NULL )
6899 0 : poNode = poRoot;
6900 : else
6901 99 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
6902 :
6903 99 : if( poNode == NULL )
6904 0 : return OGRERR_FAILURE;
6905 :
6906 : /* -------------------------------------------------------------------- */
6907 : /* Fetch matching EXTENSION if there is one. */
6908 : /* -------------------------------------------------------------------- */
6909 825 : for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
6910 : {
6911 726 : OGR_SRSNode *poChild = poNode->GetChild(i);
6912 :
6913 726 : if( EQUAL(poChild->GetValue(),"EXTENSION")
6914 : && poChild->GetChildCount() >= 2 )
6915 : {
6916 0 : if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
6917 : {
6918 0 : poChild->GetChild(1)->SetValue( pszValue );
6919 0 : return OGRERR_NONE;
6920 : }
6921 : }
6922 : }
6923 :
6924 : /* -------------------------------------------------------------------- */
6925 : /* Create a new EXTENSION node. */
6926 : /* -------------------------------------------------------------------- */
6927 : OGR_SRSNode *poAuthNode;
6928 :
6929 99 : poAuthNode = new OGR_SRSNode( "EXTENSION" );
6930 198 : poAuthNode->AddChild( new OGR_SRSNode( pszName ) );
6931 198 : poAuthNode->AddChild( new OGR_SRSNode( pszValue ) );
6932 :
6933 99 : poNode->AddChild( poAuthNode );
6934 :
6935 99 : return OGRERR_NONE;
6936 : }
6937 :
6938 : /************************************************************************/
6939 : /* OSRCleanup() */
6940 : /************************************************************************/
6941 :
6942 : CPL_C_START
6943 : void CleanupESRIDatumMappingTable();
6944 : CPL_C_END
6945 :
6946 : /**
6947 : * \brief Cleanup cached SRS related memory.
6948 : *
6949 : * This function will attempt to cleanup any cache spatial reference
6950 : * related information, such as cached tables of coordinate systems.
6951 : */
6952 1977 : void OSRCleanup( void )
6953 :
6954 : {
6955 1977 : CleanupESRIDatumMappingTable();
6956 1977 : CSVDeaccess( NULL );
6957 1977 : }
6958 :
6959 : /************************************************************************/
6960 : /* GetAxis() */
6961 : /************************************************************************/
6962 :
6963 : /**
6964 : * \brief Fetch the orientation of one axis.
6965 : *
6966 : * Fetches the the request axis (iAxis - zero based) from the
6967 : * indicated portion of the coordinate system (pszTargetKey) which
6968 : * should be either "GEOGCS" or "PROJCS".
6969 : *
6970 : * No CPLError is issued on routine failures (such as not finding the AXIS).
6971 : *
6972 : * This method is equivalent to the C function OSRGetAxis().
6973 : *
6974 : * @param pszTargetKey the coordinate system part to query ("PROJCS" or "GEOGCS").
6975 : * @param iAxis the axis to query (0 for first, 1 for second).
6976 : * @param peOrientation location into which to place the fetch orientation, may be NULL.
6977 : *
6978 : * @return the name of the axis or NULL on failure.
6979 : */
6980 :
6981 : const char *
6982 2 : OGRSpatialReference::GetAxis( const char *pszTargetKey, int iAxis,
6983 : OGRAxisOrientation *peOrientation ) const
6984 :
6985 : {
6986 2 : if( peOrientation != NULL )
6987 0 : *peOrientation = OAO_Other;
6988 :
6989 : /* -------------------------------------------------------------------- */
6990 : /* Find the target node. */
6991 : /* -------------------------------------------------------------------- */
6992 : OGR_SRSNode *poNode;
6993 :
6994 2 : if( pszTargetKey == NULL )
6995 2 : poNode = poRoot;
6996 : else
6997 0 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
6998 :
6999 2 : if( poNode == NULL )
7000 0 : return NULL;
7001 :
7002 : /* -------------------------------------------------------------------- */
7003 : /* Find desired child AXIS. */
7004 : /* -------------------------------------------------------------------- */
7005 2 : OGR_SRSNode *poAxis = NULL;
7006 2 : int iChild, nChildCount = poNode->GetChildCount();
7007 :
7008 20 : for( iChild = 0; iChild < nChildCount; iChild++ )
7009 : {
7010 20 : OGR_SRSNode *poChild = poNode->GetChild( iChild );
7011 :
7012 20 : if( !EQUAL(poChild->GetValue(),"AXIS") )
7013 18 : continue;
7014 :
7015 2 : if( iAxis == 0 )
7016 : {
7017 2 : poAxis = poChild;
7018 2 : break;
7019 : }
7020 0 : iAxis--;
7021 : }
7022 :
7023 2 : if( poAxis == NULL )
7024 0 : return NULL;
7025 :
7026 2 : if( poAxis->GetChildCount() < 2 )
7027 0 : return NULL;
7028 :
7029 : /* -------------------------------------------------------------------- */
7030 : /* Extract name and orientation if possible. */
7031 : /* -------------------------------------------------------------------- */
7032 2 : if( peOrientation != NULL )
7033 : {
7034 0 : const char *pszOrientation = poAxis->GetChild(1)->GetValue();
7035 :
7036 0 : if( EQUAL(pszOrientation,"NORTH") )
7037 0 : *peOrientation = OAO_North;
7038 0 : else if( EQUAL(pszOrientation,"EAST") )
7039 0 : *peOrientation = OAO_East;
7040 0 : else if( EQUAL(pszOrientation,"SOUTH") )
7041 0 : *peOrientation = OAO_South;
7042 0 : else if( EQUAL(pszOrientation,"WEST") )
7043 0 : *peOrientation = OAO_West;
7044 0 : else if( EQUAL(pszOrientation,"UP") )
7045 0 : *peOrientation = OAO_Up;
7046 0 : else if( EQUAL(pszOrientation,"DOWN") )
7047 0 : *peOrientation = OAO_Down;
7048 0 : else if( EQUAL(pszOrientation,"OTHER") )
7049 0 : *peOrientation = OAO_Other;
7050 : else
7051 : {
7052 : CPLDebug( "OSR", "Unrecognised orientation value '%s'.",
7053 0 : pszOrientation );
7054 : }
7055 : }
7056 :
7057 2 : return poAxis->GetChild(0)->GetValue();
7058 : }
7059 :
7060 : /************************************************************************/
7061 : /* OSRGetAxis() */
7062 : /************************************************************************/
7063 :
7064 : /**
7065 : * \brief Fetch the orientation of one axis.
7066 : *
7067 : * This method is the equivalent of the C++ method OGRSpatialReference::GetAxis
7068 : */
7069 0 : const char *OSRGetAxis( OGRSpatialReferenceH hSRS,
7070 : const char *pszTargetKey, int iAxis,
7071 : OGRAxisOrientation *peOrientation )
7072 :
7073 : {
7074 0 : VALIDATE_POINTER1( hSRS, "OSRGetAxis", NULL );
7075 :
7076 : return ((OGRSpatialReference *) hSRS)->GetAxis( pszTargetKey, iAxis,
7077 0 : peOrientation );
7078 : }
7079 :
7080 : /************************************************************************/
7081 : /* OSRAxisEnumToName() */
7082 : /************************************************************************/
7083 :
7084 : /**
7085 : * \brief Return the string representation for the OGRAxisOrientation enumeration.
7086 : *
7087 : * For example "NORTH" for OAO_North.
7088 : *
7089 : * @return an internal string
7090 : */
7091 329814 : const char *OSRAxisEnumToName( OGRAxisOrientation eOrientation )
7092 :
7093 : {
7094 329814 : if( eOrientation == OAO_North )
7095 89236 : return "NORTH";
7096 240578 : if( eOrientation == OAO_East )
7097 89232 : return "EAST";
7098 151346 : if( eOrientation == OAO_South )
7099 30456 : return "SOUTH";
7100 120890 : if( eOrientation == OAO_West )
7101 30456 : return "WEST";
7102 90434 : if( eOrientation == OAO_Up )
7103 30142 : return "UP";
7104 60292 : if( eOrientation == OAO_Down )
7105 30142 : return "DOWN";
7106 30150 : if( eOrientation == OAO_Other )
7107 30150 : return "OTHER";
7108 :
7109 0 : return "UNKNOWN";
7110 : }
7111 :
7112 : /************************************************************************/
7113 : /* SetAxes() */
7114 : /************************************************************************/
7115 :
7116 : /**
7117 : * \brief Set the axes for a coordinate system.
7118 : *
7119 : * Set the names, and orientations of the axes for either a projected
7120 : * (PROJCS) or geographic (GEOGCS) coordinate system.
7121 : *
7122 : * This method is equivalent to the C function OSRSetAxes().
7123 : *
7124 : * @param pszTargetKey either "PROJCS" or "GEOGCS", must already exist in SRS.
7125 : * @param pszXAxisName name of first axis, normally "Long" or "Easting".
7126 : * @param eXAxisOrientation normally OAO_East.
7127 : * @param pszYAxisName name of second axis, normally "Lat" or "Northing".
7128 : * @param eYAxisOrientation normally OAO_North.
7129 : *
7130 : * @return OGRERR_NONE on success or an error code.
7131 : */
7132 :
7133 : OGRErr
7134 59404 : OGRSpatialReference::SetAxes( const char *pszTargetKey,
7135 : const char *pszXAxisName,
7136 : OGRAxisOrientation eXAxisOrientation,
7137 : const char *pszYAxisName,
7138 : OGRAxisOrientation eYAxisOrientation )
7139 :
7140 : {
7141 : /* -------------------------------------------------------------------- */
7142 : /* Find the target node. */
7143 : /* -------------------------------------------------------------------- */
7144 : OGR_SRSNode *poNode;
7145 :
7146 59404 : if( pszTargetKey == NULL )
7147 0 : poNode = poRoot;
7148 : else
7149 59404 : poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
7150 :
7151 59404 : if( poNode == NULL )
7152 0 : return OGRERR_FAILURE;
7153 :
7154 : /* -------------------------------------------------------------------- */
7155 : /* Strip any existing AXIS children. */
7156 : /* -------------------------------------------------------------------- */
7157 118808 : while( poNode->FindChild( "AXIS" ) >= 0 )
7158 0 : poNode->DestroyChild( poNode->FindChild( "AXIS" ) );
7159 :
7160 : /* -------------------------------------------------------------------- */
7161 : /* Insert desired axes */
7162 : /* -------------------------------------------------------------------- */
7163 59404 : OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
7164 :
7165 118808 : poAxis->AddChild( new OGR_SRSNode( pszXAxisName ) );
7166 118808 : poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eXAxisOrientation) ));
7167 :
7168 59404 : poNode->AddChild( poAxis );
7169 :
7170 118808 : poAxis = new OGR_SRSNode( "AXIS" );
7171 :
7172 118808 : poAxis->AddChild( new OGR_SRSNode( pszYAxisName ) );
7173 118808 : poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eYAxisOrientation) ));
7174 :
7175 59404 : poNode->AddChild( poAxis );
7176 :
7177 59404 : return OGRERR_NONE;
7178 : }
7179 :
7180 : /************************************************************************/
7181 : /* OSRSetAxes() */
7182 : /************************************************************************/
7183 : /**
7184 : * \brief Set the axes for a coordinate system.
7185 : *
7186 : * This method is the equivalent of the C++ method OGRSpatialReference::SetAxes
7187 : */
7188 0 : OGRErr OSRSetAxes( OGRSpatialReferenceH hSRS,
7189 : const char *pszTargetKey,
7190 : const char *pszXAxisName,
7191 : OGRAxisOrientation eXAxisOrientation,
7192 : const char *pszYAxisName,
7193 : OGRAxisOrientation eYAxisOrientation )
7194 : {
7195 0 : VALIDATE_POINTER1( hSRS, "OSRSetAxes", OGRERR_FAILURE );
7196 :
7197 : return ((OGRSpatialReference *) hSRS)->SetAxes( pszTargetKey,
7198 : pszXAxisName,
7199 : eXAxisOrientation,
7200 : pszYAxisName,
7201 0 : eYAxisOrientation );
7202 : }
7203 :
7204 : #ifdef HAVE_MITAB
7205 : char CPL_DLL *MITABSpatialRef2CoordSys( OGRSpatialReference * );
7206 : OGRSpatialReference CPL_DLL * MITABCoordSys2SpatialRef( const char * );
7207 : #endif
7208 :
7209 : /************************************************************************/
7210 : /* OSRExportToMICoordSys() */
7211 : /************************************************************************/
7212 : /**
7213 : * \brief Export coordinate system in Mapinfo style CoordSys format.
7214 : *
7215 : * This method is the equivalent of the C++ method OGRSpatialReference::exportToMICoordSys
7216 : */
7217 2 : OGRErr OSRExportToMICoordSys( OGRSpatialReferenceH hSRS, char ** ppszReturn )
7218 :
7219 : {
7220 2 : VALIDATE_POINTER1( hSRS, "OSRExportToMICoordSys", CE_Failure );
7221 :
7222 2 : *ppszReturn = NULL;
7223 :
7224 2 : return ((OGRSpatialReference *) hSRS)->exportToMICoordSys( ppszReturn );
7225 : }
7226 :
7227 : /************************************************************************/
7228 : /* exportToMICoordSys() */
7229 : /************************************************************************/
7230 :
7231 : /**
7232 : * \brief Export coordinate system in Mapinfo style CoordSys format.
7233 : *
7234 : * Note that the returned WKT string should be freed with OGRFree() or
7235 : * CPLFree() when no longer needed. It is the responsibility of the caller.
7236 : *
7237 : * This method is the same as the C function OSRExportToMICoordSys().
7238 : *
7239 : * @param ppszResult pointer to which dynamically allocated Mapinfo CoordSys
7240 : * definition will be assigned.
7241 : *
7242 : * @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
7243 : * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
7244 : */
7245 :
7246 4 : OGRErr OGRSpatialReference::exportToMICoordSys( char **ppszResult ) const
7247 :
7248 : {
7249 : #ifdef HAVE_MITAB
7250 4 : *ppszResult = MITABSpatialRef2CoordSys( (OGRSpatialReference *) this );
7251 4 : if( *ppszResult != NULL && strlen(*ppszResult) > 0 )
7252 4 : return OGRERR_NONE;
7253 : else
7254 0 : return OGRERR_FAILURE;
7255 : #else
7256 : CPLError( CE_Failure, CPLE_NotSupported,
7257 : "MITAB not available, CoordSys support disabled." );
7258 :
7259 : return OGRERR_UNSUPPORTED_OPERATION;
7260 : #endif
7261 : }
7262 :
7263 : /************************************************************************/
7264 : /* OSRImportFromMICoordSys() */
7265 : /************************************************************************/
7266 : /**
7267 : * \brief Import Mapinfo style CoordSys definition.
7268 : *
7269 : * This method is the equivalent of the C++ method OGRSpatialReference::importFromMICoordSys
7270 : */
7271 :
7272 2 : OGRErr OSRImportFromMICoordSys( OGRSpatialReferenceH hSRS,
7273 : const char *pszCoordSys )
7274 :
7275 : {
7276 2 : VALIDATE_POINTER1( hSRS, "OSRImportFromMICoordSys", CE_Failure );
7277 :
7278 2 : return ((OGRSpatialReference *)hSRS)->importFromMICoordSys( pszCoordSys );
7279 : }
7280 :
7281 : /************************************************************************/
7282 : /* importFromMICoordSys() */
7283 : /************************************************************************/
7284 :
7285 : /**
7286 : * \brief Import Mapinfo style CoordSys definition.
7287 : *
7288 : * The OGRSpatialReference is initialized from the passed Mapinfo style CoordSys definition string.
7289 : *
7290 : * This method is the equivalent of the C function OSRImportFromMICoordSys().
7291 : *
7292 : * @param pszCoordSys Mapinfo style CoordSys definition string.
7293 : *
7294 : * @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
7295 : * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
7296 : */
7297 :
7298 6 : OGRErr OGRSpatialReference::importFromMICoordSys( const char *pszCoordSys )
7299 :
7300 : {
7301 : #ifdef HAVE_MITAB
7302 6 : OGRSpatialReference *poResult = MITABCoordSys2SpatialRef( pszCoordSys );
7303 :
7304 6 : if( poResult == NULL )
7305 0 : return OGRERR_FAILURE;
7306 :
7307 6 : *this = *poResult;
7308 6 : delete poResult;
7309 :
7310 6 : return OGRERR_NONE;
7311 : #else
7312 : CPLError( CE_Failure, CPLE_NotSupported,
7313 : "MITAB not available, CoordSys support disabled." );
7314 :
7315 : return OGRERR_UNSUPPORTED_OPERATION;
7316 : #endif
7317 : }
|