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