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