CodeSnippets: KML_Driver_examples.pl

File KML_Driver_examples.pl, 9.4 kB (added by darkblueB, 7 months ago)

OGR KML driver scripting - in perl

Line 
1 #!/usr/bin/perl
2 ##
3 ##      KML Driver Test, using Perl and OGR
4 ##  written for GDAL/OGR v1.5
5 ##
6 ##      09Dec07  -bh
7 ##
8
9 ## -- If you want to use development libraries, add the path here
10 #use lib '/Users/Shared/srcs/gdal_trunk/swig/perl/blib/lib';
11 #use lib '/Users/Shared/srcs/gdal_trunk/swig/perl/blib/arch';
12 use Geo::Ogr;
13
14 ##==========================================================
15 ## main program
16
17 my $dstFilename = 'tmp/tKML' . rand(100) . '.kml';
18
19 my $driver = Geo::OGR::GetDriverByName( 'KML' )
20         or die( "Cant open driver KML $! $@" );
21 my $datasource = $driver->CreateDataSource( "/Users/Shared/srcs/ogrTutorial/$dstFilename" )
22         or die( "Cant open file $! $@" );
23
24 ##---------------------------
25 ## Now, make a few new layers
26         newGeom_Point();
27         newGeom_Polygon();
28         newGeom_Point25D();
29         newGeom_LineString();
30         newGeom_Unknown();
31
32
33 exit(0);
34
35 ##==========================================================
36 ##-- Supported Layer Types --
37         #Point
38         #Polygon
39         #LineString
40         #Unknown
41         
42 ## -- Unsupported Layer Types --
43         #MultiPoint             MultiPolygon            MultiLineString
44         #Point25D               Polygon25D                      LineString25D
45         #MultiPoint25D  MultiPolygon25D         MultiLineString25D
46         
47 ##==========================================================
48 sub newGeom_Point {
49         my ($tPt, $tStr, $type, $feature);
50
51         ## Create a Layer..
52         ##  the first param shows up as the Folder Name in KML
53         $type = 'Point';
54         my $layer = $datasource->CreateLayer( ($type . '_layer'), undef, $type );
55         $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
56         #my $dRef = $feature->GetDefnRef();
57         #print $dRef->GetGeomType();
58
59         ##---------------------------------------------------------
60         ## SetField(0,x) will set the KML Name of this feature
61         $feature->SetField( 'Name', "Remarkably Remote Rest Stop" );   
62         ## SetField(1,x) will set the KML Description of this feature
63         ## the description will generally accept minimal HTML,
64         ##  if escaped with CDATA. XML special chars will be escaped for you
65         ##  but this seems buggy right now.. see below for another example
66         $feature->SetField( 'Description', "top doggy" );
67         # this had problems for me
68         #$feature->SetField( 1, "top <doggy>" );       
69         
70         ## now create a new geometry from WKT
71         $tStr = 'POINT(' . (rand() - 122.0) . ' ' . (rand() + 35.0) . ')';
72         $tPt = Geo::OGR::CreateGeometryFromWkt( $tStr );
73         #print $tPt->ExportToWkt( );
74
75         # associate the geometry with the Feature
76         $feature->SetGeometry( $tPt );
77         # add the feature to the layer
78         $layer->CreateFeature( $feature);
79         #write to disk
80         $layer->SyncToDisk;
81        
82         # done with this Feature now
83         $feature->DESTROY();
84        
85         ##---------------------------------------------------------
86         # Make another feature
87         $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
88         $feature->SetField( 'Name', "Purposefull Point" );     
89         $feature->SetField( 'Description', "how can this be a useful description?" );   
90        
91         my $tPt2 =  Geo::OGR::Geometry->new( $Geo::OGR::wkbPoint );
92         # Make a new Geometry as an object, then AddPoint()
93         $tPt2->AddPoint( rand() - 122.0, rand() + 35.0  );
94         #write it to the Layer
95         writeGeom( $tPt2, $feature, $layer );
96
97         # Now use the same feature, but make a new geometry via create()
98         my $tPt3 =  Geo::OGR::Geometry->create( $type );
99         # AddPoint again
100         $tPt3->AddPoint( rand() - 122.0, rand() + 35.0  );
101         #write it to the layer, notice the Name and Decription are repeated
102         writeGeom( $tPt3, $feature, $layer );
103        
104         # done with this Feature now
105         $feature->DESTROY();
106        
107         ##---------------------------------------------------------
108         # Last feature
109         $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
110         $feature->SetField( 'Name', "Google Summer of Coder" );
111
112         # a try at complicated HTML content.. needs work
113 my $descStr = <<END0;
114 <![CDATA[<b>Name:</b> <i>Erik Pukinskis</i><br />
115       <b>Description:</b> <i>Working on... &lt;br /&gt;
116       &lt;i&gt;<a href=http://code.google.com/soc/abisource/about.html>abi</a><br />]]>
117 END0
118         $feature->SetField( 'Description', $descStr ); 
119        
120         my $tPt2 =  Geo::OGR::Geometry->new( $Geo::OGR::wkbPoint );
121         # Make a new Geometry as an object, then AddPoint()
122         $tPt2->AddPoint( -117.1610543131828, 32.74625975767101  );
123         #write it to the Layer
124         writeGeom( $tPt2, $feature, $layer );
125        
126         # Perl interfaces will auto-dispose any object with local scope
127         return;
128
129         ## other confusing stuff from the Perl interfaces
130         #my $tFtrDef = new Geo::OGR::FeatureDefn( "Homer" );
131         #$tFtrDef->Schema(
132         #       Fields=>[Geo::OGR::FieldDefn->create( Name=>'OneName',Description=>'desc')]);
133         # not at all the right call next
134         #$tFtrDef->AddFieldDefn( "Name", "fred" );
135 }
136
137 ##-------------------------------------------------------------------------
138 ## newGeom_Point25D -  make a 25D point in a POINT layer..
139 ##  write out to KML and notice the 25D point is intact.
140 ##  KML doesnt care about mixing 25D and others.. Other OGR drivers might.
141 ##  NOTE: still finding out new ways to manipulate Geometry, so
142 ##  suggestions are welcome..
143
144 sub newGeom_Point25D {
145         my ($tPt, $tStr, $type);
146
147         $type = 'Point';
148         my $layer = $datasource->CreateLayer( ($type . '_layer'), undef, $type );
149         my $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
150        
151         #my $dRef = $feature->GetDefnRef();
152         #print $dRef->GetGeomType();
153         
154         ## This works, 25D with WKT
155         $tStr = 'POINT(' . (rand() - 122.0) . ' ' . (rand() + 35.0) . ' ' . 155 . ')';
156         $tPt = Geo::OGR::CreateGeometryFromWkt( $tStr );
157         #print $tPt->ExportToWkt( );
158         writeGeom( $tPt, $feature, $layer );
159
160         # another Geometry object
161         my $tPt2 =  Geo::OGR::Geometry->new( $Geo::OGR::wkbPoint );
162         $tPt2->AddPoint( rand() - 122.0, rand() + 35.0 );
163         ##  AddPoint() doesnt like 25D, fails..
164         #$tPt2->AddPoint( rand() - 120.0, rand() + 35.0, 155 );
165         writeGeom( $tPt2, $feature, $layer );
166
167         my $tPt3 =  Geo::OGR::Geometry->create( $type );
168         $tPt3->AddPoint( rand() - 122.0, rand() + 35.0 );
169         ##  AddPoint() doesnt like 25D, fails..
170         #$tPt3->AddPoint( rand() - 110.0, rand() + 35.0, 155  );
171         writeGeom( $tPt3, $feature, $layer );
172        
173         return;
174 }
175
176 ##----------------------
177 sub newGeom_Unknown {
178         my ($tPt, $tStr, $type);
179
180         $type = 'Unknown';
181         my $layer = $datasource->CreateLayer( ($type . '_layer'), undef, $type );
182         if ( $@ ) { print $@; }
183         my $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
184         if ( $@ ) { print $@; }
185
186         ## try adding a LineString
187         my $limit = int(rand(3)) + 1;
188         my ($tNewPtX,$tNewPtY);
189         $tNewPtX = (rand() - 118.0);
190         $tNewPtY = (rand() + 32.0);
191         $tStr = 'LINESTRING(' . $tNewPtX . ' ' . $tNewPtY . ', ';
192         for ( 0..$limit ) {
193                 $tStr .=  ($tNewPtX + rand()) . ' ' . ($tNewPtY + rand()) . ',';
194         }
195         chop $tStr;
196         $tStr .= ')';
197         $tPt = Geo::OGR::CreateGeometryFromWkt( $tStr );
198         #print $tPt->ExportToWkt( );
199         writeGeom( $tPt, $feature, $layer );
200        
201         $feature->DESTROY();
202
203         ## and now a Point
204         $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
205
206         # Set the Name and Description fields
207         $feature->SetField( 'Name', "All Mixed Content Point" );       
208         $feature->SetField( 'Description', "draw it as I see it" );     
209        
210         my $tPt2 =  Geo::OGR::Geometry->new( $Geo::OGR::wkbPoint );
211         # Make a new Geometry as an object, then AddPoint()
212         $tPt2->AddPoint( -118.00, 32.78  );
213         #write it to the Layer
214         writeGeom( $tPt2, $feature, $layer );
215        
216         return;
217 }
218        
219 ##----------------------
220 sub newGeom_LineString {
221         my ($tPt, $tStr, $type);
222
223         $type = 'LineString';
224         my $layer = $datasource->CreateLayer( ($type . '_layer'), undef, $type );
225         if ( $@ ) { print $@; }
226         my $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
227         if ( $@ ) { print $@; }
228        
229         #my $dRef = $feature->GetDefnRef();
230         #print $dRef->GetGeomType();
231         
232         ## make the feature comments now
233         $feature->SetField( 'Name', "Long path to nowhere" );
234         ## xml escape chars translate correctly in the display
235         $feature->SetField( 'Description', "If the &lt;tessellate&gt; tag has a value of 0, the line follows a simple straight-line path from point to point" );       
236
237         my $limit = int(rand(10)) + 1;
238         my ($tNewPtX,$tNewPtY);
239         $tNewPtX = (rand() - 122.0);
240         $tNewPtY = (rand() + 35.0);
241         $tStr = 'LINESTRING(' . $tNewPtX . ' ' . $tNewPtY . ', ';
242         for ( 0..$limit ) {
243                 $tStr .=  ($tNewPtX + rand()) . ' ' . ($tNewPtY + rand()) . ',';
244         }
245         chop $tStr;
246         $tStr .= ')';
247         $tPt = Geo::OGR::CreateGeometryFromWkt( $tStr );
248         #print $tPt->ExportToWkt( );
249         writeGeom( $tPt, $feature, $layer );
250        
251         return;
252 }
253
254 ##--------------------------------------------------------------------------
255 ## newGeom_Polygon - make a Polygon Layer and sample geometry
256 ## TODO: figure out how to set the LineStyle and PolyStyle on the Polygon
257 sub newGeom_Polygon {
258         my ($tPt, $tStr, $type);
259
260         $type = 'Polygon';
261         my $layer = $datasource->CreateLayer( ($type . '_layer'), undef, $type );
262         my $feature = new Geo::OGR::Feature( $layer->GetLayerDefn() );
263        
264         #my $dRef = $feature->GetDefnRef();
265         #print $dRef->GetGeomType();
266         
267         $tStr = 'POLYGON((';
268         my $tOrigLat = (rand(2) + 35.0);
269         my $tOrigLon = (rand(2) - 122.0);
270         $tStr .= $tOrigLon . ' ' . $tOrigLat . ', ';
271         for (1..3) {
272                 $tStr .= (rand(2) - 122.0) . ' ' . (rand(2) + 35.0) . ',';
273         }
274         $tStr .= $tOrigLon . ' ' . $tOrigLat . ' ';
275         $tStr .= '))';
276         $tPt = Geo::OGR::CreateGeometryFromWkt( $tStr );
277         #print $tPt->ExportToWkt( );
278         writeGeom( $tPt, $feature, $layer );
279 }
280
281 ##=========================================================================
282 ## some misc support subs
283
284 sub writeGeom {
285         my ($geom,$feature,$layer) = @_;
286        
287         $feature->SetGeometry( $geom );
288         $layer->CreateFeature( $feature);
289         $layer->SyncToDisk;
290 }
291
292 ##-------------
293 sub printAllTypes {
294         my @types = Geo::OGR::GeometryType();
295        
296         my @tmp = @types;
297         @types = ();
298         # filter out a few of the types
299         for (@tmp) {
300                 #next if /25/;
301                 next if /Ring/;
302                 next if /None/;
303                 push @types, $_;
304         }
305         print @types;
306         exit(0);
307 }