1 : /******************************************************************************
2 : *
3 : * Project: KML Translator
4 : * Purpose: Implements OGRLIBKMLDriver
5 : * Author: Brian Case, rush at winkey dot org
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2010, Brian Case
9 : *
10 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : *****************************************************************************/
28 :
29 : #include <ogr_geometry.h>
30 : #include "ogr_p.h"
31 : #include <kml/dom.h>
32 :
33 : using kmldom::KmlFactory;
34 : using kmldom::CoordinatesPtr;
35 : using kmldom::PointPtr;
36 : using kmldom::LatLonBoxPtr;
37 : using kmldom::LineStringPtr;
38 : using kmldom::LinearRingPtr;
39 : using kmldom::OuterBoundaryIsPtr;
40 : using kmldom::InnerBoundaryIsPtr;
41 : using kmldom::PolygonPtr;
42 : using kmldom::MultiGeometryPtr;
43 : using kmldom::GeometryPtr;
44 : using kmldom::ElementPtr;
45 : using kmldom::GeometryPtr;
46 : using kmldom::GxLatLonQuadPtr;
47 :
48 : using kmlbase::Vec3;
49 :
50 : #include "ogrlibkmlgeometry.h"
51 :
52 : /******************************************************************************
53 : funtion to write out a ogr geometry to kml
54 :
55 : args:
56 : poOgrGeom the ogr geometry
57 : extra used in recursion, just pass -1
58 : wkb25D used in recursion, just pass 0
59 : poKmlFactory pointer to the libkml dom factory
60 :
61 : returns:
62 : ElementPtr to the geometry created
63 :
64 : ******************************************************************************/
65 :
66 69 : ElementPtr geom2kml (
67 : OGRGeometry * poOgrGeom,
68 : int extra,
69 : int wkb25D,
70 : KmlFactory * poKmlFactory )
71 : {
72 : int i;
73 :
74 69 : if ( !poOgrGeom ) {
75 0 : return NULL;
76 : }
77 :
78 : /***** ogr geom vars *****/
79 :
80 69 : OGRPoint *poOgrPoint = NULL;
81 : OGRLineString *poOgrLineString;
82 : OGRPolygon *poOgrPolygon;
83 : OGRGeometryCollection *poOgrMultiGeom;
84 :
85 : /***** libkml geom vars *****/
86 :
87 69 : CoordinatesPtr coordinates;
88 69 : PointPtr poKmlPoint;
89 69 : LineStringPtr poKmlLineString;
90 69 : LinearRingPtr poKmlLinearRing;
91 69 : OuterBoundaryIsPtr poKmlOuterRing;
92 69 : InnerBoundaryIsPtr poKmlInnerRing;
93 69 : PolygonPtr poKmlPolygon;
94 69 : MultiGeometryPtr poKmlMultiGeometry;
95 :
96 69 : ElementPtr poKmlGeometry;
97 69 : ElementPtr poKmlTmpGeometry;
98 :
99 : /***** other vars *****/
100 :
101 : double x,
102 : y,
103 : z;
104 :
105 69 : int numpoints = 0;
106 : int nGeom;
107 69 : int type = poOgrGeom->getGeometryType ( );
108 :
109 69 : wkb25D = type & wkb25DBit;
110 :
111 69 : switch ( type ) {
112 :
113 : case wkbPoint:
114 :
115 12 : poOgrPoint = ( OGRPoint * ) poOgrGeom;
116 12 : if (poOgrPoint->getCoordinateDimension() == 0)
117 : {
118 0 : poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( );
119 : }
120 : else
121 : {
122 12 : x = poOgrPoint->getX ( );
123 12 : y = poOgrPoint->getY ( );
124 :
125 12 : if ( x > 180 )
126 0 : x -= 360;
127 :
128 12 : coordinates = poKmlFactory->CreateCoordinates ( );
129 12 : coordinates->add_latlng ( y, x );
130 12 : poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( );
131 12 : poKmlPoint->set_coordinates ( coordinates );
132 : }
133 :
134 12 : break;
135 :
136 : case wkbPoint25D:
137 6 : poOgrPoint = ( OGRPoint * ) poOgrGeom;
138 :
139 6 : x = poOgrPoint->getX ( );
140 6 : y = poOgrPoint->getY ( );
141 6 : z = poOgrPoint->getZ ( );
142 :
143 6 : if ( x > 180 )
144 0 : x -= 360;
145 :
146 6 : coordinates = poKmlFactory->CreateCoordinates ( );
147 6 : coordinates->add_latlngalt ( y, x, z );
148 6 : poKmlGeometry = poKmlPoint = poKmlFactory->CreatePoint ( );
149 6 : poKmlPoint->set_coordinates ( coordinates );
150 :
151 6 : break;
152 :
153 : case wkbLineString:
154 12 : poOgrLineString = ( OGRLineString * ) poOgrGeom;
155 :
156 12 : coordinates = poKmlFactory->CreateCoordinates ( );
157 :
158 12 : numpoints = poOgrLineString->getNumPoints ( );
159 12 : poOgrPoint = new OGRPoint ( );
160 :
161 36 : for ( i = 0; i < numpoints; i++ ) {
162 24 : poOgrLineString->getPoint ( i, poOgrPoint );
163 :
164 24 : x = poOgrPoint->getX ( );
165 24 : y = poOgrPoint->getY ( );
166 :
167 24 : if ( x > 180 )
168 0 : x -= 360;
169 :
170 24 : coordinates->add_latlng ( y, x );
171 : }
172 12 : delete poOgrPoint;
173 :
174 : /***** check if its a wkbLinearRing *****/
175 :
176 12 : if ( extra < 0 ) {
177 :
178 : poKmlGeometry = poKmlLineString =
179 12 : poKmlFactory->CreateLineString ( );
180 12 : poKmlLineString->set_coordinates ( coordinates );
181 :
182 12 : break;
183 : }
184 :
185 : /***** fallthough *****/
186 :
187 : case wkbLinearRing: //this case is for readability only
188 :
189 0 : poKmlLinearRing = poKmlFactory->CreateLinearRing ( );
190 0 : poKmlLinearRing->set_coordinates ( coordinates );
191 :
192 0 : if ( !extra ) {
193 0 : poKmlOuterRing = poKmlFactory->CreateOuterBoundaryIs ( );
194 0 : poKmlOuterRing->set_linearring ( poKmlLinearRing );
195 0 : poKmlGeometry = poKmlOuterRing;
196 : }
197 : else {
198 : poKmlGeometry = poKmlInnerRing =
199 0 : poKmlFactory->CreateInnerBoundaryIs ( );
200 0 : poKmlInnerRing->set_linearring ( poKmlLinearRing );
201 : }
202 :
203 : case wkbLineString25D:
204 :
205 18 : poOgrLineString = ( OGRLineString * ) poOgrGeom;
206 :
207 18 : coordinates = poKmlFactory->CreateCoordinates ( );
208 18 : poOgrPoint = new OGRPoint ( );
209 36 : numpoints = poOgrLineString->getNumPoints ( );
210 90 : for ( i = 0; i < numpoints; i++ ) {
211 72 : poOgrLineString->getPoint ( i, poOgrPoint );
212 :
213 72 : x = poOgrPoint->getX ( );
214 72 : y = poOgrPoint->getY ( );
215 72 : z = poOgrPoint->getZ ( );
216 :
217 72 : if ( x > 180 )
218 0 : x -= 360;
219 :
220 72 : coordinates->add_latlngalt ( y, x, z );
221 : }
222 18 : delete poOgrPoint;
223 :
224 : /***** check if its a wkbLinearRing *****/
225 :
226 18 : if ( extra < 0 ) {
227 :
228 : poKmlGeometry = poKmlLineString =
229 0 : poKmlFactory->CreateLineString ( );
230 0 : poKmlLineString->set_coordinates ( coordinates );
231 :
232 0 : break;
233 : }
234 : /***** fallthough *****/
235 :
236 : //case wkbLinearRing25D: // this case is for readability only
237 :
238 18 : poKmlLinearRing = poKmlFactory->CreateLinearRing ( );
239 18 : poKmlLinearRing->set_coordinates ( coordinates );
240 :
241 18 : if ( !extra ) {
242 : poKmlGeometry = poKmlOuterRing =
243 9 : poKmlFactory->CreateOuterBoundaryIs ( );
244 9 : poKmlOuterRing->set_linearring ( poKmlLinearRing );
245 : }
246 : else {
247 : poKmlGeometry = poKmlInnerRing =
248 9 : poKmlFactory->CreateInnerBoundaryIs ( );
249 9 : poKmlInnerRing->set_linearring ( poKmlLinearRing );
250 : }
251 :
252 18 : break;
253 :
254 : case wkbPolygon:
255 :
256 0 : poOgrPolygon = ( OGRPolygon * ) poOgrGeom;
257 :
258 0 : poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon ( );
259 :
260 : poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing ( ),
261 0 : 0, wkb25D, poKmlFactory );
262 : poKmlPolygon->
263 0 : set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );
264 :
265 0 : nGeom = poOgrPolygon->getNumInteriorRings ( );
266 0 : for ( i = 0; i < nGeom; i++ ) {
267 : poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
268 0 : i + 1, wkb25D, poKmlFactory );
269 : poKmlPolygon->
270 0 : add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
271 : }
272 :
273 0 : break;
274 :
275 : case wkbPolygon25D:
276 :
277 9 : poOgrPolygon = ( OGRPolygon * ) poOgrGeom;
278 :
279 9 : poKmlGeometry = poKmlPolygon = poKmlFactory->CreatePolygon ( );
280 :
281 : poKmlTmpGeometry = geom2kml ( poOgrPolygon->getExteriorRing ( ),
282 9 : 0, wkb25D, poKmlFactory );
283 : poKmlPolygon->
284 9 : set_outerboundaryis ( AsOuterBoundaryIs ( poKmlTmpGeometry ) );
285 :
286 9 : nGeom = poOgrPolygon->getNumInteriorRings ( );
287 18 : for ( i = 0; i < nGeom; i++ ) {
288 : poKmlTmpGeometry = geom2kml ( poOgrPolygon->getInteriorRing ( i ),
289 9 : i + 1, wkb25D, poKmlFactory );
290 : poKmlPolygon->
291 9 : add_innerboundaryis ( AsInnerBoundaryIs ( poKmlTmpGeometry ) );
292 : }
293 :
294 9 : break;
295 :
296 : case wkbMultiPoint:
297 : case wkbMultiLineString:
298 : case wkbMultiPolygon:
299 : case wkbGeometryCollection:
300 : case wkbMultiPoint25D:
301 : case wkbMultiLineString25D:
302 : case wkbMultiPolygon25D:
303 : case wkbGeometryCollection25D:
304 :
305 12 : poOgrMultiGeom = ( OGRGeometryCollection * ) poOgrGeom;
306 :
307 : poKmlGeometry = poKmlMultiGeometry =
308 12 : poKmlFactory->CreateMultiGeometry ( );
309 :
310 12 : nGeom = poOgrMultiGeom->getNumGeometries ( );
311 36 : for ( i = 0; i < nGeom; i++ ) {
312 : poKmlTmpGeometry = geom2kml ( poOgrMultiGeom->getGeometryRef ( i ),
313 24 : -1, wkb25D, poKmlFactory );
314 : poKmlMultiGeometry->
315 24 : add_geometry ( AsGeometry ( poKmlTmpGeometry ) );
316 : }
317 :
318 : break;
319 :
320 : case wkbUnknown:
321 : case wkbNone:
322 : default:
323 : break;
324 :
325 : }
326 :
327 69 : return poKmlGeometry;
328 : }
329 :
330 : /******************************************************************************
331 : recursive function to read a kml geometry and translate to ogr
332 :
333 : Args:
334 : poKmlGeometry pointer to the kml geometry to translate
335 : poOgrSRS pointer to the spatial ref to set on the geometry
336 :
337 : Returns:
338 : pointer to the new ogr geometry object
339 :
340 : ******************************************************************************/
341 :
342 557 : OGRGeometry *kml2geom_rec (
343 : GeometryPtr poKmlGeometry,
344 : OGRSpatialReference *poOgrSRS)
345 :
346 : {
347 :
348 : /***** ogr geom vars *****/
349 :
350 : OGRPoint *poOgrPoint;
351 : OGRLineString *poOgrLineString;
352 : OGRLinearRing *poOgrLinearRing;
353 : OGRPolygon *poOgrPolygon;
354 : OGRGeometryCollection *poOgrMultiGeometry;
355 557 : OGRGeometry *poOgrGeometry = NULL;
356 557 : OGRGeometry *poOgrTmpGeometry = NULL;
357 :
358 :
359 : /***** libkml geom vars *****/
360 :
361 557 : CoordinatesPtr poKmlCoordinates;
362 557 : PointPtr poKmlPoint;
363 557 : LineStringPtr poKmlLineString;
364 557 : LinearRingPtr poKmlLinearRing;
365 557 : OuterBoundaryIsPtr poKmlOuterRing;
366 557 : InnerBoundaryIsPtr poKmlInnerRing;
367 557 : PolygonPtr poKmlPolygon;
368 557 : MultiGeometryPtr poKmlMultiGeometry;
369 557 : GeometryPtr poKmlTmpGeometry;
370 :
371 557 : Vec3 oKmlVec;
372 :
373 : size_t nRings,
374 : nCoords,
375 : nGeom,
376 : i;
377 :
378 557 : switch ( poKmlGeometry->Type ( ) ) {
379 : case kmldom::Type_Point:
380 91 : poKmlPoint = AsPoint ( poKmlGeometry );
381 91 : if ( poKmlPoint->has_coordinates ( ) ) {
382 90 : poKmlCoordinates = poKmlPoint->get_coordinates ( );
383 90 : nCoords = poKmlCoordinates->get_coordinates_array_size ( );
384 90 : if (nCoords > 0)
385 : {
386 89 : oKmlVec = poKmlCoordinates->get_coordinates_array_at ( 0 );
387 :
388 89 : if ( oKmlVec.has_altitude ( ) )
389 : poOgrPoint = new OGRPoint ( oKmlVec.get_longitude ( ),
390 : oKmlVec.get_latitude ( ),
391 84 : oKmlVec.get_altitude ( ) );
392 : else
393 : poOgrPoint = new OGRPoint ( oKmlVec.get_longitude ( ),
394 5 : oKmlVec.get_latitude ( ) );
395 :
396 89 : poOgrGeometry = poOgrPoint;
397 : }
398 : else
399 : {
400 1 : poOgrGeometry = new OGRPoint();
401 : }
402 : }
403 : else
404 : {
405 1 : poOgrGeometry = new OGRPoint();
406 : }
407 :
408 91 : break;
409 :
410 : case kmldom::Type_LineString:
411 105 : poKmlLineString = AsLineString ( poKmlGeometry );
412 105 : poOgrLineString = new OGRLineString ( );
413 210 : if ( poKmlLineString->has_coordinates ( ) ) {
414 104 : poKmlCoordinates = poKmlLineString->get_coordinates ( );
415 :
416 104 : nCoords = poKmlCoordinates->get_coordinates_array_size ( );
417 796 : for ( i = 0; i < nCoords; i++ ) {
418 692 : oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
419 692 : if ( oKmlVec.has_altitude ( ) )
420 : poOgrLineString->
421 : addPoint ( oKmlVec.get_longitude ( ),
422 : oKmlVec.get_latitude ( ),
423 686 : oKmlVec.get_altitude ( ) );
424 : else
425 : poOgrLineString->
426 : addPoint ( oKmlVec.get_longitude ( ),
427 6 : oKmlVec.get_latitude ( ) );
428 : }
429 : }
430 105 : poOgrGeometry = poOgrLineString;
431 :
432 105 : break;
433 : case kmldom::Type_LinearRing:
434 186 : poKmlLinearRing = AsLinearRing ( poKmlGeometry );
435 186 : poOgrLinearRing = new OGRLinearRing ( );
436 372 : if ( poKmlLinearRing->has_coordinates ( ) ) {
437 183 : poKmlCoordinates = poKmlLinearRing->get_coordinates ( );
438 :
439 183 : nCoords = poKmlCoordinates->get_coordinates_array_size ( );
440 2318 : for ( i = 0; i < nCoords; i++ ) {
441 2135 : oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
442 2135 : if ( oKmlVec.has_altitude ( ) )
443 : poOgrLinearRing->
444 : addPoint ( oKmlVec.get_longitude ( ),
445 : oKmlVec.get_latitude ( ),
446 2098 : oKmlVec.get_altitude ( ) );
447 : else
448 : poOgrLinearRing->
449 : addPoint ( oKmlVec.get_longitude ( ),
450 37 : oKmlVec.get_latitude ( ) );
451 : }
452 : }
453 186 : poOgrGeometry = poOgrLinearRing;
454 :
455 186 : break;
456 : case kmldom::Type_Polygon:
457 156 : poKmlPolygon = AsPolygon ( poKmlGeometry );
458 :
459 156 : poOgrPolygon = new OGRPolygon ( );
460 312 : if ( poKmlPolygon->has_outerboundaryis ( ) ) {
461 :
462 155 : poKmlOuterRing = poKmlPolygon->get_outerboundaryis ( );
463 155 : poKmlLinearRing = poKmlOuterRing->get_linearring ( );
464 155 : if (poKmlLinearRing)
465 : {
466 154 : poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );
467 :
468 : poOgrPolygon->
469 154 : addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
470 : }
471 :
472 : }
473 156 : nRings = poKmlPolygon->get_innerboundaryis_array_size ( );
474 186 : for ( i = 0; i < nRings; i++ ) {
475 30 : poKmlInnerRing = poKmlPolygon->get_innerboundaryis_array_at ( i );
476 30 : poKmlLinearRing = poKmlInnerRing->get_linearring ( );
477 30 : if (poKmlLinearRing)
478 : {
479 29 : poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS );
480 :
481 : poOgrPolygon->
482 29 : addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry );
483 : }
484 : }
485 156 : poOgrGeometry = poOgrPolygon;
486 :
487 156 : break;
488 : case kmldom::Type_MultiGeometry:
489 : {
490 19 : poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
491 19 : nGeom = poKmlMultiGeometry->get_geometry_array_size ( );
492 :
493 : /* Detect subgeometry type to instanciate appropriate Multi geometry type */
494 19 : kmldom::KmlDomType type = kmldom::Type_Unknown;
495 46 : for ( i = 0; i < nGeom; i++ ) {
496 31 : poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
497 31 : if (type == kmldom::Type_Unknown)
498 17 : type = poKmlTmpGeometry->Type();
499 14 : else if (type != poKmlTmpGeometry->Type())
500 : {
501 4 : type = kmldom::Type_Unknown;
502 4 : break;
503 : }
504 : }
505 :
506 19 : if (type == kmldom::Type_Point)
507 5 : poOgrMultiGeometry = new OGRMultiPoint();
508 14 : else if (type == kmldom::Type_LineString)
509 4 : poOgrMultiGeometry = new OGRMultiLineString();
510 10 : else if (type == kmldom::Type_Polygon)
511 4 : poOgrMultiGeometry = new OGRMultiPolygon();
512 : else
513 6 : poOgrMultiGeometry = new OGRGeometryCollection ();
514 :
515 50 : for ( i = 0; i < nGeom; i++ ) {
516 31 : poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i );
517 31 : poOgrTmpGeometry = kml2geom_rec ( poKmlTmpGeometry, poOgrSRS );
518 :
519 31 : poOgrMultiGeometry->addGeometryDirectly ( poOgrTmpGeometry );
520 : }
521 19 : poOgrGeometry = poOgrMultiGeometry;
522 : break;
523 : }
524 : default:
525 : break;
526 : }
527 :
528 557 : if (poOgrGeometry)
529 557 : poOgrGeometry->assignSpatialReference(poOgrSRS);
530 :
531 557 : return poOgrGeometry;
532 : }
533 :
534 : static
535 18 : OGRGeometry *kml2geom_latlonbox_int (
536 : LatLonBoxPtr poKmlLatLonBox,
537 : OGRSpatialReference *poOgrSRS)
538 :
539 : {
540 : OGRPolygon *poOgrPolygon;
541 : double north, south, east, west;
542 18 : poOgrPolygon = new OGRPolygon ( );
543 36 : if ( !poKmlLatLonBox->has_north ( ) ||
544 : !poKmlLatLonBox->has_south ( ) ||
545 : !poKmlLatLonBox->has_east ( ) ||
546 : !poKmlLatLonBox->has_west ( ) ) {
547 :
548 0 : return NULL;
549 : }
550 18 : north = poKmlLatLonBox->get_north ( );
551 18 : south = poKmlLatLonBox->get_south ( );
552 18 : east = poKmlLatLonBox->get_east ( );
553 18 : west = poKmlLatLonBox->get_west ( );
554 18 : OGRLinearRing* poOgrRing = new OGRLinearRing ( );
555 18 : poOgrRing->addPoint ( east, north, 0.0 );
556 18 : poOgrRing->addPoint ( east, south, 0.0 );
557 18 : poOgrRing->addPoint ( west, south, 0.0 );
558 18 : poOgrRing->addPoint ( west, north, 0.0 );
559 18 : poOgrRing->addPoint ( east, north, 0.0 );
560 : poOgrPolygon->
561 18 : addRingDirectly ( poOgrRing );
562 18 : poOgrPolygon->assignSpatialReference(poOgrSRS);
563 :
564 18 : return poOgrPolygon;
565 : }
566 :
567 : static
568 0 : OGRGeometry *kml2geom_latlonquad_int (
569 : GxLatLonQuadPtr poKmlLatLonQuad,
570 : OGRSpatialReference *poOgrSRS)
571 :
572 : {
573 0 : if( !poKmlLatLonQuad->has_coordinates() )
574 0 : return NULL;
575 :
576 : const CoordinatesPtr& poKmlCoordinates =
577 0 : poKmlLatLonQuad->get_coordinates();
578 :
579 0 : OGRLinearRing* poOgrLinearRing = new OGRLinearRing ( );
580 :
581 0 : size_t nCoords = poKmlCoordinates->get_coordinates_array_size ( );
582 0 : for ( size_t i = 0; i < nCoords; i++ ) {
583 0 : Vec3 oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i );
584 0 : if ( oKmlVec.has_altitude ( ) )
585 : poOgrLinearRing->
586 : addPoint ( oKmlVec.get_longitude ( ),
587 : oKmlVec.get_latitude ( ),
588 0 : oKmlVec.get_altitude ( ) );
589 : else
590 : poOgrLinearRing->
591 : addPoint ( oKmlVec.get_longitude ( ),
592 0 : oKmlVec.get_latitude ( ) );
593 : }
594 0 : poOgrLinearRing->closeRings();
595 :
596 0 : OGRPolygon *poOgrPolygon = new OGRPolygon();
597 : poOgrPolygon->
598 0 : addRingDirectly ( poOgrLinearRing );
599 0 : poOgrPolygon->assignSpatialReference(poOgrSRS);
600 :
601 0 : return poOgrPolygon;
602 : }
603 :
604 : /******************************************************************************
605 : main function to read a kml geometry and translate to ogr
606 :
607 : Args:
608 : poKmlGeometry pointer to the kml geometry to translate
609 : poOgrSRS pointer to the spatial ref to set on the geometry
610 :
611 : Returns:
612 : pointer to the new ogr geometry object
613 :
614 : ******************************************************************************/
615 :
616 343 : OGRGeometry *kml2geom (
617 : GeometryPtr poKmlGeometry,
618 : OGRSpatialReference *poOgrSRS)
619 :
620 : {
621 :
622 : /***** get the geometry *****/
623 :
624 343 : OGRGeometry *poOgrGeometry = kml2geom_rec (poKmlGeometry, poOgrSRS);
625 :
626 : /***** split the geometry at the dateline? *****/
627 :
628 343 : const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
629 343 : if (CSLTestBoolean(pszWrap)) {
630 :
631 0 : char **papszTransformOptions = NULL;
632 : papszTransformOptions = CSLAddString( papszTransformOptions,
633 0 : "WRAPDATELINE=YES");
634 :
635 : /***** transform *****/
636 :
637 : OGRGeometry *poOgrDstGeometry =
638 : OGRGeometryFactory::transformWithOptions(poOgrGeometry,
639 : NULL,
640 0 : papszTransformOptions);
641 :
642 : /***** replace the original geom *****/
643 :
644 0 : if (poOgrDstGeometry) {
645 0 : delete poOgrGeometry;
646 0 : poOgrGeometry = poOgrDstGeometry;
647 : }
648 :
649 0 : CSLDestroy(papszTransformOptions);
650 : }
651 :
652 343 : return poOgrGeometry;
653 : }
654 :
655 18 : OGRGeometry *kml2geom_latlonbox (
656 : LatLonBoxPtr poKmlLatLonBox,
657 : OGRSpatialReference *poOgrSRS)
658 :
659 : {
660 :
661 : /***** get the geometry *****/
662 :
663 18 : OGRGeometry *poOgrGeometry = kml2geom_latlonbox_int (poKmlLatLonBox, poOgrSRS);
664 :
665 : /***** split the geometry at the dateline? *****/
666 :
667 18 : const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
668 18 : if (CSLTestBoolean(pszWrap)) {
669 :
670 0 : char **papszTransformOptions = NULL;
671 : papszTransformOptions = CSLAddString( papszTransformOptions,
672 0 : "WRAPDATELINE=YES");
673 :
674 : /***** transform *****/
675 :
676 : OGRGeometry *poOgrDstGeometry =
677 : OGRGeometryFactory::transformWithOptions(poOgrGeometry,
678 : NULL,
679 0 : papszTransformOptions);
680 :
681 : /***** replace the original geom *****/
682 :
683 0 : if (poOgrDstGeometry) {
684 0 : delete poOgrGeometry;
685 0 : poOgrGeometry = poOgrDstGeometry;
686 : }
687 :
688 0 : CSLDestroy(papszTransformOptions);
689 : }
690 :
691 18 : return poOgrGeometry;
692 : }
693 :
694 0 : OGRGeometry *kml2geom_latlonquad (
695 : GxLatLonQuadPtr poKmlLatLonQuad,
696 : OGRSpatialReference *poOgrSRS)
697 :
698 : {
699 :
700 : /***** get the geometry *****/
701 :
702 0 : OGRGeometry *poOgrGeometry = kml2geom_latlonquad_int (poKmlLatLonQuad, poOgrSRS);
703 :
704 : /***** split the geometry at the dateline? *****/
705 :
706 0 : const char *pszWrap = CPLGetConfigOption ( "LIBKML_WRAPDATELINE", "no" );
707 0 : if (CSLTestBoolean(pszWrap)) {
708 :
709 0 : char **papszTransformOptions = NULL;
710 : papszTransformOptions = CSLAddString( papszTransformOptions,
711 0 : "WRAPDATELINE=YES");
712 :
713 : /***** transform *****/
714 :
715 : OGRGeometry *poOgrDstGeometry =
716 : OGRGeometryFactory::transformWithOptions(poOgrGeometry,
717 : NULL,
718 0 : papszTransformOptions);
719 :
720 : /***** replace the original geom *****/
721 :
722 0 : if (poOgrDstGeometry) {
723 0 : delete poOgrGeometry;
724 0 : poOgrGeometry = poOgrDstGeometry;
725 : }
726 :
727 0 : CSLDestroy(papszTransformOptions);
728 : }
729 :
730 0 : return poOgrGeometry;
731 : }
|