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