CodeSnippets: ogr_kml.pl

File ogr_kml.pl, 16.4 kB (added by darkblueB, 8 months ago)

OGR_KML test - port of python version to perl

Line 
1 #!/usr/bin/perl
2 ## Perl test of reading a sample KML file
3 ## based on the Python version of the same
4 ##
5 ## GDAL v1.5
6 ##
7
8 use Carp;
9
10 use Geo::OGR;
11 use Geo::GDAL;
12
13 ##==================================================================
14 my $test_kml_ds = 0;
15
16 ##==================================================================
17 sub ogr_kml_datastore {
18        
19         my $tDataFilePath = '/Users/Shared/srcs/kml_tester/data/samples.kml';
20         if (not -r $tDataFilePath) {croak "KML data file not found or not readable: $tDataFilePath";}
21         $test_kml_ds = Geo::OGR::Open( $tDataFilePath );
22         if (not $test_kml_ds) {croak "KML Driver Open() failed ";}
23
24         my $tLyrCnt = $test_kml_ds->GetLayerCount();
25         if ( $tLyrCnt != 6 ) {
26                 print "GetLayerCount() expected 6, got $tLyrCnt\n";
27                 return 'fail';
28         }
29        
30         return 'success';
31 }
32
33 ##==================================================================
34 sub ogr_kml_attributes_1 {
35
36     my $lyr = $test_kml_ds->GetLayerByName('Placemarks');
37     my $feat = $lyr->GetNextFeature();
38     my $tFld;
39
40     if ($feat->GetField('Name') ne 'Simple placemark') {
41         print( 'Wrong name field value ' );
42         return 'fail';
43     }
44
45     $tFld = $feat->GetField('description');
46     if ( 0 == $tFld =~ tr/Attached to the ground.// ) {
47         print( 'Wrong description field value ' );
48         return 'fail';
49         }
50        
51     $feat = $lyr->GetNextFeature();
52     if ( !defined $feat ) {
53         print( 'expected feature not found. ' );
54         return 'fail';
55     }
56
57     if ($feat->GetField('Name') ne 'Floating placemark') {
58         print( 'Wrong name field value ' );
59         return 'fail';
60     }
61
62     $tFld = $feat->GetField('description');
63     if ( 0 == $tFld =~ tr/Floats a defined distance// ) {
64         print( 'Wrong description field value ' );
65         return 'fail';
66     }
67    
68     $feat = $lyr->GetNextFeature();
69     if ( !defined $feat ) {
70         print( 'expected feature not found. ' );
71         return 'fail';
72     }
73
74     if ( $feat->GetField('Name') ne 'Extruded placemark' ) {
75         print( 'Wrong name field value ' );
76         return 'fail';
77     }
78
79     $tFld = $feat->GetField('description') ;
80     if ( $tFld
81         ne 'Tethered to the ground by a customizable " tail "' ) {
82         print( 'Wrong description field value ' );
83         return 'fail';
84     }
85
86     return 'success';
87
88 }
89
90 ##==================================================================
91 sub ogr_kml_attributes_2 {
92    
93     my $lyr = $test_kml_ds->GetLayerByName('Highlighted Icon');
94     my $feat = $lyr->GetNextFeature();
95
96     if ($feat->GetField('Name') ne 'Roll over this icon') {
97         print( 'Wrong name field value' );
98         return 'fail';
99     }
100
101     if  ($feat->GetField('description') ne '') {
102         print( 'Wrong description field value' );
103         return 'fail';
104     }
105
106     $feat = $lyr->GetNextFeature();
107     if ( defined $feat ) {
108         print( 'unexpected feature found.' );
109         return 'fail';
110     }
111
112     return 'success'
113 }
114
115 ###############################################################################
116 # Test reading attributes for another layer (linestring).
117 #
118 sub ogr_kml_attributes_3 {
119    
120    my $lyr = $test_kml_ds->GetLayerByName('Paths');
121  
122    my $feat = $lyr->GetNextFeature();
123    if ( !defined $feat) {
124         print( 'Feature not found' );
125         return 'fail';
126     }
127
128
129     if ($feat->GetField('Name') ne 'Tessellated' ) {
130         print( 'Wrong name field value' );
131         return 'fail';
132     }
133
134     if  ($feat->GetField('description') ne
135         'If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain' ) {
136         print( 'Wrong description field value' );
137         return 'fail';
138     }
139
140     $feat = $lyr->GetNextFeature();
141     if ( !defined $feat ) {
142         print( 'expected feature not found.' );
143         return 'fail';
144     }
145    
146     if  ($feat->GetField('Name') ne 'Untessellated') {
147         print( 'Wrong name field value' );
148         return 'fail';
149     }
150
151
152     if  ($feat->GetField('description') ne
153         'If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point' ) {
154         print( 'Wrong description field value' );
155         return 'fail';
156     }
157    
158     $feat = $lyr->GetNextFeature();
159     if ( !defined $feat ) {
160         print( 'expected feature not found.' );
161         return 'fail';
162     }
163    
164     ##---- Get Geometry Ref
165     my $tStr;
166     my $tGeomRef = $feat->GetGeometryRef();
167     my $tCnt = $tGeomRef->GetPointCount();
168     for ( my $tInd=0; $tInd<$tCnt; $tInd++ ) {
169         $tStr .= $tGeomRef->GetX( $tInd) . " "
170                         . $tGeomRef->GetY( $tInd) . " "
171                         . $tGeomRef->GetZ( $tInd) . ",";
172     }
173     chop $tStr; # remove last comma
174     $tStr = 'LINESTRING(' . $tStr . ')';
175         if (check_feature_geometry( $feat, $tStr)){
176                 print( 'LINESTRING doesnt match: GetX/GetY ');
177                 return 'fail';
178         }
179
180     my $wktStr = $tGeomRef->ExportToWkt;
181         if (check_feature_geometry( $feat, $wktStr)){
182                 print( 'LINESTRING doesnt match: ExportToWkt ');
183                 return 'fail';
184         }
185    
186  
187     return 'success';
188 }
189
190 ###############################################################################
191 # Test reading attributes for another layer (polygon).
192 #
193 sub ogr_kml_attributes_4 {
194    
195    my $lyr = $test_kml_ds->GetLayerByName('Google Campus');
196  
197    my $feat = $lyr->GetNextFeature();
198    if ( !defined $feat) {
199         print( 'Feature not found' );
200         return 'fail';
201     }
202
203     my $i = 40;
204     while ($feat) {
205         my $name = 'Building ' . $i;
206         if ( $feat->GetField('Name') ne $name ){
207             print( 'Wrong name field value ' );
208             return 'fail';
209         }
210
211         if ( $feat->GetField('description') ne '' ) {
212             print( 'Wrong description field value ' );
213             return 'fail';
214         }
215
216         $i++;
217         $feat = $lyr->GetNextFeature();
218     }
219
220     return 'success';
221 }
222
223 ###############################################################################
224 # Test reading of KML point geometry
225 #
226 sub ogr_kml_point_read {
227    
228         my $wkt;
229         my $lyr = $test_kml_ds->GetLayerByName('Placemarks');
230         $lyr->ResetReading();
231         my $feat = $lyr->GetNextFeature();
232         if ( !defined $feat) {
233                 print( 'Feature not found' );
234                 return 'fail';
235         }
236        
237         $wkt ='POINT(-122.0822035425683 37.42228990140251)';
238         if (check_feature_geometry( $feat, $wkt)){
239                 return 'fail';
240         }
241        
242         $feat = $lyr->GetNextFeature();
243         if (!defined $feat){
244                 print( 'expected feature not found. ' );
245                 return 'fail';
246         }   
247        
248         $wkt ='POINT(-122.084075 37.4220033612141 50)';
249        
250         if (check_feature_geometry( $feat, $wkt)){
251                 return 'fail';
252         }   
253        
254         $feat = $lyr->GetNextFeature();
255         if (!defined $feat){
256                 print( 'expected feature not found. ' );
257                 return 'fail';
258         }   
259         $wkt ='POINT(-122.0857667006183 37.42156927867553 50)';
260        
261         if (check_feature_geometry( $feat, $wkt)){
262                 return 'fail';
263         }
264        
265         return 'success';
266 }
267
268 ###############################################################################
269 # Test reading of KML linestring geometry
270 #
271 sub ogr_kml_linestring_read {
272    
273         my $wkt;
274         my $lyr = $test_kml_ds->GetLayerByName('Paths');
275         $lyr->ResetReading();
276         my $feat = $lyr->GetNextFeature();
277         if ( !defined $feat) {
278                 print( 'Feature not found ' );
279                 return 'fail';
280         }
281
282     $wkt = 'LINESTRING (-112.081423783034495 36.106778704771372 0, -112.087026775269294 36.0905099328766 0)';
283     if (check_feature_geometry( $feat, $wkt) ) {
284         return 'fail';
285     }
286    
287     $feat = $lyr->GetNextFeature();
288     if ( !defined $feat) {
289         print( 'expected feature not found.' );
290         return 'fail';
291     }
292  
293     $wkt = 'LINESTRING (-112.080622229594994 36.106734600079953 0,-112.085242575314993 36.090495986124218 0)';
294     if (check_feature_geometry( $feat, $wkt) ) {
295         return 'fail';
296     }
297    
298     $feat = $lyr->GetNextFeature();
299     if ( !defined $feat) {
300         print( 'expected feature not found.' );
301         return 'fail';
302     }
303  
304     $wkt = 'LINESTRING (-112.265654928602004 36.094476726025462 2357,-112.266038452823807 36.093426088386707 2357,-112.266813901345301 36.092510587768807 2357,-112.267782683444494 36.091898273579957 2357,-112.268855751095202 36.091313794118697 2357,-112.269481071721899 36.090367720752099 2357,-112.269526855561097 36.089321714872852 2357,-112.269014456727604 36.088509160604723 2357,-112.268152881533894 36.087538135979557 2357,-112.2670588176031 36.086826852625677 2357,-112.265737458732104 36.086463123013033 2357)';
305     if (check_feature_geometry( $feat, $wkt) ) {
306         return 'fail';
307     }
308    
309     return 'success';
310 }
311
312 ###############################################################################
313 # Test reading of KML polygon geometry
314 #
315 sub ogr_kml_polygon_read {
316    
317         my $wkt;
318         my $lyr = $test_kml_ds->GetLayerByName('Google Campus');
319         $lyr->ResetReading();
320         my $feat = $lyr->GetNextFeature();
321         if ( !defined $feat) {
322                 print( 'Feature not found ' );
323                 return 'fail';
324         }
325
326
327     $wkt = 'POLYGON ((-122.084893845961204 37.422571240447859 17,-122.084958097919795 37.422119226268563 17,-122.084746957304702 37.42207183952619 17,-122.084572538096197 37.422090067296757 17,-122.084595488672306 37.422159327008949 17,-122.0838521118269 37.422272785643713 17,-122.083792243334997 37.422035391120843 17,-122.0835076656616 37.422090069571063 17,-122.083470946415204 37.422009873951609 17,-122.083122108574798 37.422104649494599 17,-122.082924737457205 37.422265039903863 17,-122.082933916938501 37.422312428430942 17,-122.083383735973698 37.422250460876178 17,-122.083360785424802 37.422341592287452 17,-122.083420455164202 37.42237075460644 17,-122.083659133885007 37.422512920110009 17,-122.083975843895203 37.422658730937812 17,-122.084237474333094 37.422651439725207 17,-122.0845036949503 37.422651438643499 17,-122.0848020460801 37.422611339163147 17,-122.084788275051494 37.422563950551208 17,-122.084893845961204 37.422571240447859 17))';
328     if (check_feature_geometry( $feat, $wkt) ) {
329         return 'fail';
330     }
331    
332     $feat = $lyr->GetNextFeature();
333     if ( !defined $feat) {
334         print( 'expected feature not found.' );
335         return 'fail';
336     }
337  
338     $wkt = 'POLYGON ((-122.085741277148301 37.422270331552568 17,-122.085816976848093 37.422314088323461 17,-122.085852582875006 37.422303374697442 17,-122.085879994563896 37.422256861387893 17,-122.085886010140896 37.422231107613797 17,-122.085806915728796 37.422202501738553 17,-122.085837954265301 37.42214027058678 17,-122.085673264051906 37.422086902144081 17,-122.085602292640701 37.42214885429042 17,-122.085590277843593 37.422128290487002 17,-122.085584167223701 37.422081719672462 17,-122.085485206574106 37.42210455874995 17,-122.085506726435199 37.422142679498243 17,-122.085443071291493 37.422127838461719 17,-122.085099071490404 37.42251282407603 17,-122.085676981863202 37.422818153236513 17,-122.086016227378295 37.422449188587223 17,-122.085726032700407 37.422292396042529 17,-122.085741277148301 37.422270331552568 17))';
339     if (check_feature_geometry( $feat, $wkt) ) {
340         return 'fail';
341     }
342    
343     $feat = $lyr->GetNextFeature();
344     if ( !defined $feat) {
345         print( 'expected feature not found.');
346         return 'fail';
347     }
348  
349     $wkt = 'POLYGON ((-122.085786228724203 37.421362088869692 25,-122.085731299060299 37.421369359894811 25,-122.085731299291794 37.421409349109027 25,-122.085607707367899 37.421383901665649 25,-122.085580242651602 37.42137299550869 25,-122.085218622197104 37.421372995043157 25,-122.085227776563897 37.421616565082651 25,-122.085259818934702 37.421605658944031 25,-122.085259818549901 37.421682001560001 25,-122.085236931147804 37.421700178603459 25,-122.085264395782801 37.421761979825753 25,-122.085323903274599 37.421761980139067 25,-122.085355945432397 37.421852864451999 25,-122.085410875246296 37.421889218237339 25,-122.085479537935697 37.42189285337048 25,-122.085543622981902 37.421889217975462 25,-122.085626017804202 37.421860134999257 25,-122.085937287963006 37.421860134536047 25,-122.085942871866607 37.42160898590042 25,-122.085965546986102 37.421579927591438 25,-122.085864046234093 37.421471150029568 25,-122.0858548911215 37.421405713261841 25,-122.085809116276806 37.4214057134039 25,-122.085786228724203 37.421362088869692 25))';
350     if (check_feature_geometry( $feat, $wkt) ) {
351         return 'fail';
352     }
353    
354     $feat = $lyr->GetNextFeature();
355     if ( !defined $feat) {
356         print( 'expected feature not found.');
357         return 'fail';
358     }
359  
360     $wkt = 'POLYGON ((-122.084437112828397 37.421772530030907 19,-122.084511885574599 37.421911115428962 19,-122.0850470999805 37.421787551215353 19,-122.085071991339106 37.421436630231611 19,-122.084916406231997 37.421372378221157 19,-122.084219386816699 37.421372378016258 19,-122.084219386589993 37.421476171614962 19,-122.083808641999099 37.4214613409357 19,-122.083789972856394 37.421313064107963 19,-122.083279653469802 37.421293288405927 19,-122.083260981920702 37.421392139442979 19,-122.082937362173695 37.421372363998763 19,-122.082906242566693 37.421515697788713 19,-122.082850226966499 37.421762825764652 19,-122.082943578863507 37.421767769696352 19,-122.083217411188002 37.421792485526858 19,-122.0835970430103 37.421748007445601 19,-122.083945555677104 37.421693642376027 19,-122.084007789463698 37.421762838158529 19,-122.084113587521003 37.421748011043917 19,-122.084076247378405 37.421713412923751 19,-122.084144704773905 37.421678815345693 19,-122.084144704222993 37.421817206601972 19,-122.084250333307395 37.421817070044597 19,-122.084437112828397 37.421772530030907 19))';
361     if (check_feature_geometry( $feat, $wkt) ) {
362         return 'fail';
363     }
364  
365     return 'success';
366 }
367
368 ###############################################################################
369 sub max { my $m = shift; $_ > $m and $m = $_ foreach @_; return $m;  }
370 sub check_feature_geometry {
371
372         my ($feat, $geom, $max_error) = @_;
373         if (!defined $max_error) { $max_error = 0.0001; }
374         my ($f_geom);
375        
376     eval{ $f_geom = $feat->GetGeometryRef() };
377     if ( $@ ) { $f_geom = $feat; }
378
379         # Python Port.. testing the type of a var is hard!
380         # test for a string or numeric
381         # my $t = $geom & ~$geom; #string true, number false
382         # $x ^ $x eq "0" #number true, string false
383     #-- well, actually, different kind of test is needed
384     #my $tType; eval{ $tType = $geom->GeometryType() };
385     #if ( $@ ) { $tType = 'WKT'; }
386     
387     # better test for Geo::OGR::Geometry, or a WKT string
388     if ( ref( $geom ) eq "") {
389         $geom = Geo::OGR::CreateGeometryFromWkt( $geom );
390     } else  {
391         $geom = $geom->Clone();
392     }
393
394     if ( defined $f_geom &&  !defined $geom ) {
395         print ( 'expected NULL geometry but got one. ' );
396         return 1;
397     }
398
399     if ( !defined $f_geom && defined $geom ) {
400         print( 'expected geometry but got NULL. ' );
401         return 1;
402     }
403        
404     if ( $f_geom->GetGeometryName( ) ne $geom->GetGeometryName() ) {
405         print( 'geometry names do not match ' );
406         return 1;
407     }
408
409         # GetGeometryCount() is Perl Only, and only valid on Multi Geometries ??
410     #if ($f_geom->GetGeometryCount() ne $geom->GetGeometryCount() ) {
411     #    print( 'sub-geometry counts do not match ' );
412     #    return 1;
413     #}  ##  doesnt return ??
414
415     if ($f_geom->GetPointCount() ne $geom->GetPointCount() ) {
416         print( 'point counts do not match ' );
417         return 1;
418     }
419
420     if ($f_geom->GetGeometryCount() > 0 ) {
421         $count = $f_geom->GetGeometryCount();
422         for ($i=0; $i<$count; $i++ ) {
423             $result = check_feature_geometry( $f_geom->GetGeometryRef($i),
424                                              $geom->GetGeometryRef($i),
425                                              $max_error );
426             if ( $result != 0 ) {
427                 return $result;
428             }
429         }
430            
431     } else  {
432         $count = $f_geom->GetPointCount();
433        
434         for ($i=0; $i<$count; $i++ ) {
435             my $x_dist = abs($f_geom->GetX($i) - $geom->GetX($i));
436             my $y_dist = abs($f_geom->GetY($i) - $geom->GetY($i));
437             my $z_dist = abs($f_geom->GetZ($i) - $geom->GetZ($i));
438
439                         my $off = max( $x_dist, $y_dist, $z_dist);
440             if  ( $off > $max_error ) {
441                 print( "Error in vertex $i, off by $off." );
442                 return 1;
443             }
444         }
445     }
446
447     $geom->DESTROY();
448     return 0;
449 }
450
451
452 ##==================================================================
453 ##-- Run_All
454
455         print 'ogr_kml_datastore: '             . ogr_kml_datastore() . "\n";
456         print 'ogr_kml_attributes_1: '  . ogr_kml_attributes_1() . "\n";
457         print 'ogr_kml_attributes_2: '  . ogr_kml_attributes_2() . "\n";
458         print 'ogr_kml_attributes_3: '  . ogr_kml_attributes_3() . "\n";
459         print 'ogr_kml_attributes_4: '  . ogr_kml_attributes_4() . "\n";
460         print 'ogr_kml_point_read: '    . ogr_kml_point_read() . "\n";
461         print 'ogr_kml_linestring_read: ' . ogr_kml_linestring_read() . "\n";
462         print 'ogr_kml_polygon_read: '  . ogr_kml_polygon_read() . "\n";
463