source: trunk/gui/scripts/map.tcl @ 5281

Last change on this file since 5281 was 5281, checked in by ldelgass, 9 years ago

whitespace

File size: 16.0 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2# ----------------------------------------------------------------------
3#  COMPONENT: map - extracts data from an XML description of a field
4#
5#  This object represents a map of data in an XML description of
6#  simulator output.  A map is similar to a field, but a field is
7#  a quantity versus position in device.  A map is any quantity
8#  versus any other quantity.  This class simplifies the process of
9#  extracting data vectors that represent the map.
10# ======================================================================
11#  AUTHOR:  Michael McLennan, Purdue University
12#  Copyright (c) 2004-2012  HUBzero Foundation, LLC
13#
14#  See the file "license.terms" for information on usage and
15#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16# ======================================================================
17package require Itcl
18package require BLT
19
20namespace eval Rappture {
21    # forward declaration
22}
23
24itcl::class Rappture::Map {
25    private variable _tree "";         # Tree of information about the map.
26    private variable _isValid 0;
27    private common _nextLayer 0;       # Counter used to generate unique
28                                       # layer names.
29    private common _nextViewpoint 0;   # Counter used to generate unique
30                                       # viewpoint names.
31    private common _layerTypes
32    private common _mapTypes
33    array set _layerTypes {
34        "image"         0
35        "elevation"     1
36        "polygon"       2
37        "point"         3
38        "icon"          4
39        "line"          5
40        "label"         6
41    }
42    array set _mapTypes {
43        "geocentric"    0
44        "projected"     1
45    }
46    protected method Parse { xmlobj path }
47
48    constructor {xmlobj path} {
49        # defined below
50    }
51    destructor {
52        # defined below
53    }
54
55    public method earthfile {}
56    public method hints { args }
57    public method isGeocentric {}
58    public method isvalid {} {
59        return $_isValid;
60    }
61    public method layer { layerName }
62    public method layers {}
63    public method type { layerName }
64    public method viewpoint { viewpointName }
65    public method viewpoints {}
66}
67
68# ----------------------------------------------------------------------
69# CONSTRUCTOR
70# ----------------------------------------------------------------------
71itcl::body Rappture::Map::constructor {xmlobj path} {
72    if {![Rappture::library isvalid $xmlobj]} {
73        error "bad value \"$xmlobj\": should be LibraryObj"
74    }
75    Parse $xmlobj $path
76}
77
78# ----------------------------------------------------------------------
79# DESTRUCTOR
80# ----------------------------------------------------------------------
81itcl::body Rappture::Map::destructor {} {
82    if { $_tree != "" } {
83        blt::tree destroy $_tree
84    }
85}
86
87itcl::body Rappture::Map::hints { args } {
88    switch -- [llength $args] {
89        0 {
90            return [$_tree get root]
91        }
92        1 {
93            set field [lindex $args 0]
94            return [$_tree get root $field ""]
95        }
96        default {
97            error "wrong # args: should \"hints ?name?\""
98        }
99    }
100}
101
102#
103# Parse --
104#
105#   Parses the map description in the XML object.
106#
107itcl::body Rappture::Map::Parse { xmlobj path } {
108
109    set map [$xmlobj element -as object $path]
110
111    if { $_tree != "" } {
112        blt::tree destroy $_tree
113    }
114    set _tree [blt::tree create]
115    set parent [$_tree insert root -label "layers"]
116    set layers [$map element -as object "layers"]
117    foreach layer [$layers children -type layer] {
118        # Unique identifier for layer.
119        set name "layer[incr _nextLayer]"
120        set child [$_tree insert $parent -label $name]
121        set layerType [$layers get $layer.type]
122        if { ![info exists _layerTypes($layerType)] } {
123            error "invalid layer type \"$layerType\": should be one of [array names _layerTypes]"
124        }
125        $_tree set $child "name" $layer
126        $_tree set $child "type" $layerType
127        foreach key { label description attribution profile srs verticalDatum } {
128            $_tree set $child $key [$layers get $layer.$key]
129        }
130        # Common settings (for all layer types) with defaults
131        foreach { key defval } { visible 1 cache 1 } {
132            $_tree set $child $key $defval
133            set val [$layers get $layer.$key]
134            if {$val != ""} {
135                $_tree set $child $key $val
136            }
137        }
138        # These are settings for which there should be no default
139        # We want to know if they have been set by the user or not
140        # Not all layer types use these
141        foreach key { opacity content priority style } {
142            set val [$layers get $layer.$key]
143            if {$val != ""} {
144                $_tree set $child $key $val
145            }
146        }
147        $_tree set $child "driver" "debug"
148        set colorramp [$layers element -as type $layer.colorramp]
149        if { $colorramp != "" } {
150            $_tree set $child "colorramp.elevdriver" "gdal"
151            $_tree set $child "colorramp.colormap" "0 0 0 0 1 1 1 1 1 1"
152            set cmap [$layers get $layer.colorramp.colormap]
153            if {$cmap != ""} {
154                # Normalize whitespace
155                regsub -all "\[ \t\r\n\]+" [string trim $cmap] " " cmap
156                $_tree set $child "colorramp.colormap" $cmap
157            }
158            foreach key { url elevdriver } {
159                set value [$layers get $layer.colorramp.$key]
160                if {$value != ""} {
161                    $_tree set $child "colorramp.$key" $value
162                }
163            }
164            set file [$layers get $layer.colorramp.file]
165            if { $file != "" } {
166                # FIXME: Add test for valid file path
167                $_tree set $child "colorramp.url" $file
168            }
169            $_tree set $child "driver" "colorramp"
170        }
171        set gdal [$layers element -as type $layer.gdal]
172        if { $gdal != "" } {
173            foreach key { url } {
174                set value [$layers get $layer.gdal.$key]
175                $_tree set $child "gdal.$key" $value
176            }
177            set file [$layers get $layer.gdal.file]
178            if { $file != "" } {
179                # FIXME: Add test for valid file path
180                $_tree set $child "gdal.url" $file
181            }
182            $_tree set $child "driver" "gdal"
183        }
184        set ogr [$layers element -as type $layer.ogr]
185        if { $ogr != "" } {
186            foreach key { url } {
187                set value [$layers get $layer.ogr.$key]
188                $_tree set $child "ogr.$key" $value
189            }
190            set file [$layers get $layer.ogr.file]
191            if { $file != "" } {
192                # FIXME: Add test for valid file path
193                $_tree set $child "ogr.url" $file
194            }
195            $_tree set $child "driver" "ogr"
196        }
197        set tfs [$layers element -as type $layer.tfs]
198        if { $tfs != "" } {
199            foreach key { url format } {
200                set value [$layers get $layer.tfs.$key]
201                $_tree set $child "tfs.$key" $value
202            }
203            $_tree set $child "driver" "tfs"
204        }
205        set tms [$layers element -as type $layer.tms]
206        if { $tms != "" } {
207            foreach key { url tmsType format } {
208                set value [$layers get $layer.tms.$key]
209                $_tree set $child "tms.$key" $value
210            }
211            $_tree set $child "driver" "tms"
212        }
213        set wfs [$layers element -as type $layer.wfs]
214        if { $wfs != "" } {
215            foreach key { url typename outputformat maxfeatures request_buffer } {
216                set value [$layers get $layer.wfs.$key]
217                $_tree set $child "wfs.$key" $value
218            }
219            $_tree set $child "driver" "wfs"
220        }
221        set wms [$layers element -as type $layer.wms]
222        if { $wms != "" } {
223            foreach key { url layers format transparent } {
224                set value [$layers get $layer.wms.$key]
225                $_tree set $child "wms.$key" $value
226            }
227            $_tree set $child "driver" "wms"
228        }
229        set xyz [$layers element -as type $layer.xyz]
230        if { $xyz != "" } {
231            foreach key { url } {
232                set value [$layers get $layer.xyz.$key]
233                $_tree set $child "xyz.$key" $value
234            }
235            $_tree set $child "driver" "xyz"
236        }
237    }
238    $_tree set root "label"       [$map get "about.label"]
239    $_tree set root "attribution" [$map get "about.attribution"]
240    $_tree set root "style"       [$map get "style"]
241    $_tree set root "camera"      [$map get "camera"]
242    set parent [$_tree insert root -label "viewpoints"]
243    set viewpoints [$map element -as object "viewpoints"]
244    if { $viewpoints != "" } {
245        foreach viewpoint [$viewpoints children -type viewpoint] {
246            set name "viewpoint[incr _nextViewpoint]"
247            set child [$_tree insert $parent -label $name]
248            $_tree set $child "name" $viewpoint
249            set haveX 0
250            set haveZ 0
251            set haveSRS 0
252            set haveVertDatum 0
253            foreach key { label description x y z distance heading pitch srs verticalDatum } {
254                set val [$viewpoints get $viewpoint.$key]
255                if {$val != ""} {
256                    if {$key == "x"} {
257                        set haveX 1
258                    } elseif {$key == "z"} {
259                        set haveZ 1
260                    } elseif {$key == "srs"} {
261                        set haveSRS 1
262                    } elseif {$key == "verticalDatum"} {
263                        set haveVertDatum 1
264                    }
265                    $_tree set $child $key $val
266                }
267            }
268            if {!$haveX} {
269                set lat [$viewpoints get $viewpoint.latitude]
270                set long [$viewpoints get $viewpoint.longitude]
271                $_tree set $child x $long
272                $_tree set $child y $lat
273                if {!$haveSRS} {
274                    $_tree set $child srs wgs84
275                }
276                if {!$haveVertDatum} {
277                    $_tree set $child verticalDatum ""
278                }
279            }
280            if {!$haveZ} {
281                set z [$viewpoints get $viewpoint.altitude]
282                if {$z != ""} {
283                    $_tree set $child z $z
284                }
285            }
286        }
287    }
288
289    set projection [$map get "projection"]
290    set extents    [$map get "extents"]
291    if { $projection  == "" } {
292        if { $extents != "" } {
293            error "cannot specify extents without a projection"
294        }
295        set projection "global-mercator"; # Default projection.
296    } elseif { $projection == "geodetic" && $extents == "" } {
297        set projection "global-geodetic"
298    }
299    # FIXME: Verify projection is valid.
300    $_tree set root "projection" $projection
301    $_tree set root "extents"    $extents
302
303    set mapType [$map get "type"]
304    if { $mapType == "" } {
305        set mapType "projected";           # Default type is "projected".
306    }
307    if { ![info exists _mapTypes($mapType)] } {
308        error "unknown map type \"$mapType\": should be one of [array names _mapTypes]"
309    }
310    $_tree set root "type" $mapType
311
312    foreach {key path} {
313        toolid          tool.id
314        toolname        tool.name
315        toolcommand     tool.execute
316        tooltitle       tool.title
317        toolrevision    tool.version.application.revision
318    } {
319        set str [$xmlobj get $path]
320        if { "" != $str } {
321            $_tree set root $key $str
322        }
323    }
324    set _isValid 1
325}
326
327# ----------------------------------------------------------------------
328# USAGE: layers
329#
330# Returns a list of IDs for the layers in the map
331# ----------------------------------------------------------------------
332itcl::body Rappture::Map::layers {} {
333    set list {}
334    foreach node [$_tree children root->"layers"] {
335        lappend list [$_tree label $node]
336    }
337    return $list
338}
339
340# ----------------------------------------------------------------------
341# USAGE: viewpoints
342#
343# Returns a list of IDs for the viewpoints in the map
344# ----------------------------------------------------------------------
345itcl::body Rappture::Map::viewpoints {} {
346    set list {}
347    foreach node [$_tree children root->"viewpoints"] {
348        lappend list [$_tree label $node]
349    }
350    return $list
351}
352
353# ----------------------------------------------------------------------
354# USAGE: layer <layerName>
355#
356# Returns an array of settings for the named layer
357# ----------------------------------------------------------------------
358itcl::body Rappture::Map::layer { layerName } {
359    set id [$_tree findchild root->"layers" $layerName]
360    if { $id < 0 } {
361        error "unknown layer \"$layerName\""
362    }
363    return [$_tree get $id]
364}
365
366# ----------------------------------------------------------------------
367# USAGE: viewopint <viewopintName>
368#
369# Returns an array of settings for the named viewpoint
370# ----------------------------------------------------------------------
371itcl::body Rappture::Map::viewpoint { viewopintName } {
372    set id [$_tree findchild root->"viewpoints" $viewopintName]
373    if { $id < 0 } {
374        error "unknown viewpoint \"$viewpointName\""
375    }
376    return [$_tree get $id]
377}
378
379# ----------------------------------------------------------------------
380# USAGE: type <layerName>
381#
382# Returns the type of the named layer
383# ----------------------------------------------------------------------
384itcl::body Rappture::Map::type { layerName } {
385    set id [$_tree findchild root->"layers" $layerName]
386    if { $id < 0 } {
387        error "unknown layer \"$layerName\""
388    }
389    return [$_tree get $id "type" ""]
390}
391
392# ----------------------------------------------------------------------
393# USAGE: isGeocentric
394#
395# Returns if the map is geocentric (1) or projected (0)
396# ----------------------------------------------------------------------
397itcl::body Rappture::Map::isGeocentric {} {
398    return [expr {[hints "type"] eq "geocentric"}]
399}
400
401itcl::body Rappture::Map::earthfile {} {
402    array set info [$_tree get root]
403    append out "<map"
404    append out " name=\"$info(label)\""
405    append out " type=\"$info(type)\""
406    append out " version=\"2\""
407    append out ">\n"
408    # Profile is optional
409    if { [info exists info(projection)] } {
410        append out " <options>\n"
411        append out "  <profile"
412        append out " srs=\"$info(projection)\""
413        if { [info exists info(extents)] && $info(extents) != "" } {
414            foreach {x1 y1 x2 y2} $info(extents) break
415            append out " xmin=\"$x1\""
416            append out " ymin=\"$y1\""
417            append out " xmax=\"$x2\""
418            append out " ymax=\"$y2\""
419        }
420        append out "/>\n"
421        append out " </options>\n"
422    }
423    foreach node [$_tree children root->"layers"] {
424        array unset info
425        array set info [$_tree get $node]
426        set label [$_tree label $node]
427        switch -- $info(type) {
428            "image" {
429                append out " <image"
430                append out " name=\"$label\""
431                append out " driver=\"gdal\""
432                if { [info exists info(opacity)] } {
433                    append out " opacity=\"$info(opacity)\""
434                }
435                if { $info(visible) } {
436                    append out " visible=\"true\""
437                } else {
438                    append out " visible=\"false\""
439                }
440                append out ">\n"
441                append out "  <url>$info(url)</url>\n"
442                append out " </image>\n"
443            }
444            "elevation" {
445                append out " <elevation"
446                append out " name=\"$label\""
447                append out " driver=\"gdal\""
448                if { $info(visible) } {
449                    append out " visible=\"true\""
450                } else {
451                    append out " visible=\"false\""
452                }
453                append out ">\n"
454                append out "  <url>$info(url)</url>\n"
455                append out " </elevation>\n"
456            }
457            default {
458                puts stderr "Type $info(type) not implemented in earthfile"
459            }
460        }
461    }
462    append out "</map>\n"
463}
Note: See TracBrowser for help on using the repository browser.