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