/[thuban]/trunk/thuban/Extensions/umn_mapserver/mapfile.py
ViewVC logotype

Contents of /trunk/thuban/Extensions/umn_mapserver/mapfile.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2858 - (show annotations)
Tue Jul 29 06:17:34 2008 UTC (16 years, 7 months ago) by elachuni
File MIME type: text/x-python
File size: 51654 byte(s)
Fixing a couple of uncaught exceptions when using the umn_mapserver extension.
(bug #694)

1 # -*- coding:latin1 -*-
2 # Copyright (C) 2004 by Intevation GmbH
3 # Authors:
4 # Jan Schüngel <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with Thuban for details.
8
9 """
10 Classes to represent '.map'-file Objects.
11
12 The following Classes, which are implemented in
13 mapscript are not implemented yet in this extension:
14
15 DBFInfo, errorObj, fontSetObj, graticuleObj, imageObj, itemObj,
16 labelCacheMemberObj, labelCacheObj,
17 markerCacheMembet, msTiledSHPLayerInfo, queryMapObj,
18 referenzMapObj, resultCacheMemberObj, resultCacheObj,
19 shapefileObj, shapeObj, VectorObj
20
21 the following are only used to create a necessary object. They are not
22 realy created as a MF_Object.
23
24 lineObj, pointObj
25 """
26
27 __version__ = "$Revision$"
28 # $Source$
29 # $Id$
30
31
32 # ##################################################
33 #
34 # import necessary modules from python and/or thuban
35 #
36 # ##################################################
37
38 import os
39
40 from Thuban.Model.color import Color, Transparent
41
42 from Thuban.Model.classification import ClassGroupDefault, \
43 ClassGroupSingleton, ClassGroupRange
44
45 import mapscript
46 from mapscript import layerObj, classObj, colorObj, styleObj, rectObj, symbolObj, \
47 pointObj, lineObj
48
49 from Thuban.Model.layer import RasterLayer
50
51 # ###################################
52 #
53 # Definition of dictionaries
54 #
55 # the dictonaries are like in mapscript and are used to make it
56 # easear to unterstand the key from mapscript for the settings
57 #
58 # ###################################
59
60 shp_type = { 0:'point',
61 1:'line',
62 2:'polygon',
63 3:'raster',
64 4:'annotation',
65 5:'circle',
66 6:'query'}
67
68 unit_type = { 0:"inches",
69 1:"feet",
70 2:"miles",
71 3:"meters",
72 4:"kilometers",
73 5:"dd"}
74
75 legend_status_type = { 0:"OFF",
76 1:"ON",
77 3:"embed" }
78 # 2 = Default but is not allowed here
79
80 scalebar_status_type = { 0:"OFF",
81 1:"ON",
82 3:"embed" }
83 # 2 = Default but is not allowed here
84
85 scalebar_style_type = { 0:"0",
86 1:"1" }
87
88 scalebar_position_type = { mapscript.MS_UL:"ul",
89 mapscript.MS_LR:"lr",
90 mapscript.MS_UR:"ur",
91 mapscript.MS_LL:"ll",
92 mapscript.MS_UC:"uc",
93 mapscript.MS_LC:"lc"}
94
95 layer_status_type = { 0:"OFF",
96 1:"ON",
97 2:"default"}
98
99 layer_connection_type = { mapscript.MS_INLINE:"inline",
100 mapscript.MS_SHAPEFILE:"shapefile",
101 mapscript.MS_TILED_SHAPEFILE:"tiled shapefile",
102 mapscript.MS_SDE:"sde",
103 mapscript.MS_OGR:"ogr",
104 mapscript.MS_POSTGIS:"postgis",
105 mapscript.MS_WMS:"wms",
106 mapscript.MS_ORACLESPATIAL:"oracle spatial",
107 mapscript.MS_WFS:"wfs",
108 mapscript.MS_GRATICULE:"graticule",
109 mapscript.MS_MYGIS:"mygis",
110 mapscript.MS_RASTER:"raster"}
111
112 legend_position_type = { 0:"ul",
113 1:"lr",
114 2:"ur",
115 3:"ll",
116 6:"uc",
117 7:"lc"}
118
119 label_size_type = { 0:"tiny",
120 1:"small",
121 2:"medium",
122 3:"large",
123 4:"giant" }
124
125 #TODO: build in truetype (0:"truetype") support
126 label_font_type = { 1:"bitmap" }
127
128 label_position_type = { 0:"ul",
129 1:"lr",
130 2:"ur",
131 3:"ll",
132 4:"cr",
133 5:"cl",
134 6:"uc",
135 7:"lc",
136 8:"cc",
137 10:"auto"}
138
139
140 # ##################################################
141 #
142 # Class Definition
143 #
144 # ##################################################
145
146 # ##################################################
147 # General Classes that are not all explicitly defined through
148 # a mapfile, but rather some helper-classes.
149
150 class MF_Rectangle:
151 """
152 Represents an rectanle with the bottom left
153 and top right corner.
154 """
155 def __init__(self,mf_rect):
156 self._rect = mf_rect
157
158 def get_minx(self):
159 return self._rect.minx
160
161 def get_miny(self):
162 return self._rect.miny
163
164 def get_maxx(self):
165 return self._rect.maxx
166
167 def get_maxy(self):
168 return self._rect.maxy
169
170 def get_rect(self):
171 return (self._rect.minx,self._rect.miny,self._rect.maxx,self._rect.maxy)
172
173 def set_rect(self, minx, miny, maxx, maxy):
174 self._rect.minx = minx
175 self._rect.miny = miny
176 self._rect.maxx = maxx
177 self._rect.maxy = maxy
178
179 class MF_Color:
180 """
181 The corresponding MapScript object contains also the
182 attribute pen which defines the stroke of the feature.
183 But this actually has nothing to do with the color and
184 therefore is not support here.
185
186 It needs to be discussed with the MapServer developers
187 whether pen would better be moved to another class.
188
189 The hex color definition which is also supported by
190 mapscript and Thuban is not supported as it does
191 not add any capability.
192
193 color is definied as RGB 0..255
194 """
195 def __init__(self, mf_color):
196 self._color = mf_color
197 self._tbc_red = (float(self.get_red())/255)
198 self._tbc_green = (float(self.get_green())/255)
199 self._tbc_blue = (float(self.get_blue())/255)
200 self._thubancolor = Color(self._tbc_red,
201 self._tbc_green,
202 self._tbc_blue)
203
204 # TODO : Check if it is necessary to use rgb colors alone
205 # or whether it is sufficient to only use the Thuban Color.
206 # In some it is necessary as red == -1 indicates that no color
207 # is set.
208 def get_red(self):
209 return self._color.red
210
211 def get_green(self):
212 return self._color.green
213
214 def get_blue(self):
215 return self._color.blue
216
217 def set_rgbcolor(self, red, green, blue):
218 self._color.red = red
219 self._color.green = green
220 self._color.blue = blue
221
222 self._tbc_red = (float(self.get_red())/255)
223 self._tbc_green = (float(self.get_green())/255)
224 self._tbc_blue = (float(self.get_blue())/255)
225 self._thubancolor = Color(self._tbc_red,
226 self._tbc_green,
227 self._tbc_blue)
228
229 def get_mfcolor(self):
230 return self._color
231
232 def get_thubancolor(self):
233 return self._thubancolor
234
235 def set_thubancolor(self, thuban_color):
236 if thuban_color != Transparent:
237 self._color.red = int(thuban_color.red * 255)
238 self._color.green = int(thuban_color.green * 255)
239 self._color.blue = int(thuban_color.blue * 255)
240 self._thubancolor = thuban_color
241
242
243 class MF_Metadata:
244 """
245 Metadata is not a Object in mapscript witch can be used
246 by ease. Only the infos can get with the functions
247 "getFirstMetaDataKey", "getNextMetaDataKey" and "getMetaData".
248 To get some special Metadata you need a key. So there is a special
249 function which create a list of the metadatakeys.
250 """
251 def __init__(self, mapobj):
252 self.mapobj = mapobj
253
254 def remove_allmetadata(self):
255 keylist = self.get_metadatakeys()
256 if keylist:
257 for key in keylist:
258 self.mapobj.removeMetaData(key)
259
260 def get_metadatakeys(self):
261 keylist = []
262 try:
263 metafkey =self.mapobj.getFirstMetaDataKey()
264 keylist.append(metafkey)
265 except:
266 return None
267 else:
268 if metafkey:
269 while metafkey:
270 metafkey = self.mapobj.getNextMetaDataKey(metafkey)
271 if metafkey:
272 keylist.append(metafkey)
273 return keylist
274
275 def get_metadata(self):
276 keylist = self.get_metadatakeys()
277 metadatalist = []
278 if keylist:
279 for key in keylist:
280 metadatalist.append([key,self.mapobj.getMetaData(key)])
281 return metadatalist
282 else:
283 return None
284
285 def get_metadatabykey(self, key):
286 return self.mapobj.getMetaData(key)
287
288 def remove_metadatabykey(self, key):
289 self.mapobj.removeMetaData(key)
290
291 def add_metadata(self, key, data):
292 self.mapobj.setMetaData(key,data)
293
294 # ################################################
295 # Classes for MapServer Objects as they are
296 # explicitly defined in a mapfile
297
298 class MF_Outputformat:
299 """
300 The Outputformat defines which and how the image is
301 created by the mapserver.
302
303 The following settings are used:
304 name
305
306 The following settings are not used:
307 mimetye, driver, extension, renderer, imagemode, transparent,
308 bands, numfrotmatoptions, formatoptions, refcount, inmapfile
309 setExtension(), setMimetype(), setOption(), getOption()
310 """
311 def __init__(self, mf_outputformat):
312 self._outputformat = mf_outputformat
313
314 def get_name(self):
315 return self._outputformat.name
316
317
318 class MF_Symbol:
319 """
320 defines a single symbol which is used in the Symbolset
321
322 the following settings are used:
323 name, type,
324
325 the following settings are not used:
326 sizex, sizey, points, numpoints, filled, stylelength,
327 style, imagepath, transparent, transparentcolor, character, antialias,
328 font, gap, position, linecap, linejoin, linejoinmaxsize, setPoints(),
329 getPoints(), setStyle()
330 """
331 def __init__(self, mf_symbol = "newone"):
332 # create a circle Object like shown in Thuban
333 # because Thuban don't support other symbols
334
335 # TODO: include the options to create a symbol, but
336 # first implement a methode to edit Symbols in Thuban
337 if mf_symbol == "newone":
338 mf_symbol = symbolObj("")
339 newpoint = pointObj()
340 newpoint.x = 1
341 newpoint.y = 1
342 newline = lineObj()
343 newline.add(newpoint)
344 mf_symbol.setPoints(newline)
345
346 self._symbol = mf_symbol
347
348 def get_symbolObj(self):
349 return self._symbol
350
351 def get_name(self):
352 return self._symbol.name
353
354 def set_name(self, new_name):
355 self._symbol.name = new_name
356
357 def get_type(self):
358 return self._symbol.type
359
360 def set_type(self, new_type):
361 # TODO include a function to set the type by a string
362 self._symbol.type = new_type
363
364 def get_filled(self):
365 return self._symbol.filled
366
367 def set_filled(self, new_filled):
368 if new_filled:
369 self._symbol.filled = 1
370 else:
371 self._symbol.filled = 0
372
373
374 class MF_SymbolSet:
375 """
376 defines a set of symbols, may be there can only be one
377
378 the following settings are used:
379 numsymbols,
380 appendSymbol()
381
382 filename, imagecachesize, symbol, getSymbol(),
383 getSymbolByName(), index(), removeSymbol(),
384 save()
385 """
386 def __init__(self, mf_symbolset):
387 self._symbolset = mf_symbolset
388
389 # Initial Symbol List
390 self._symbols = []
391 self._i = 1
392 while self._i < self._symbolset.numsymbols:
393 self._symbols.append(MF_Symbol(self._symbolset.getSymbol(self._i)))
394 self._i += 1
395
396 def add_symbol(self, new_symbol):
397 self._symbolset.appendSymbol(new_symbol.get_symbolObj())
398 self._symbols.append(new_symbol)
399 # the save function must be run to set the symbols to the
400 # mapfile. I don't know why this ist so but it must be.
401 # the file is empty then an we can delete it
402 self._symbolset.save("tempsymbol")
403 os.remove("tempsymbol")
404
405 def get_symbol(self, symbolnr):
406 if symbolnr < self._symbolset.numsymbols:
407 return self._symbols[symbolnr-1]
408 else:
409 return None
410
411
412 class MF_Class:
413 """
414 The following parameters and functions, which the mapscript style obj
415 contains, are used:
416 styles, numstyles, name, status, keyimage, layer,
417 getExpressionString(), setExpression(), getMetaData(), getFirstMetaDataKey(),
418 getNextMetaDataKey(), getStyle()
419
420 The following parameters and functions are not used:
421 label, title, template, type, minscale, maxscale, debug,
422 setExpression(), setText(), setMetaData(), drawLegendIcon(),
423 createLegendIcon(), insertStyle(), removeStyle(), moveStyleUp(),
424 moveStyleDown()
425 """
426 def __init__(self, mf_class):
427 """
428 Initialized a class from them given mapscript Class Object
429 with a list of the included styles.
430 Metadata Object will be created from the Metadata informations
431 wich are holt as a List i think.
432 """
433 self._clazz = mf_class
434 self._styles = []
435 self._numstyles = mf_class.numstyles
436 for i in range(0,self._numstyles,1):
437 self._styles.append(MF_Style(mf_class.getStyle(i)))
438
439 if self._clazz.getExpressionString() == '"(null)"':
440 self._expression = None
441 else:
442 self._expression = self._clazz.getExpressionString()
443
444 self.metadata = MF_Metadata(self._clazz)
445
446 def get_styles(self):
447 return self._styles
448
449 def get_name(self):
450 return self._clazz.name
451
452 def get_keyimage(self):
453 return self._clazz.keyimage
454
455 def get_expressionstring(self):
456 return self._expression
457
458 def set_name(self, newname):
459 self._clazz.name = newname
460
461 def set_expressionstring(self, newstring):
462 self._clazz.setExpression(newstring)
463 self._expression = self._clazz.getExpressionString()
464
465 def get_status(self):
466 if self._clazz.status == 1:
467 return True
468 else:
469 return False
470
471 def set_status(self, new_status):
472 if new_status:
473 self._clazz.status = 1
474 else:
475 self._clazz.status = 0
476
477 def add_thubanstyle(self, tb_style, type="default"):
478 """
479 added a thuban style object to the mapobject
480 """
481 new_styleobj = MF_Style(styleObj(self._clazz))
482 if type == "line":
483 new_styleobj.set_color(tb_style.GetLineColor())
484 elif type == "point":
485 # set a default symbol to show circles not only a small dot
486 # symbol "circle" must create before
487 # TODO: create a Symbol (more see MF_SymbolSet)
488 # first the default symbol circle will be created and the size 8
489 new_styleobj.set_symbolname('circle')
490 new_styleobj.set_size(8)
491 if tb_style.GetLineColor() != Transparent:
492 new_styleobj.set_linecolor(tb_style.GetLineColor())
493 new_styleobj.set_color(tb_style.GetFill())
494 else:
495 new_styleobj.set_size(tb_style.GetLineWidth())
496 if tb_style.GetLineColor() != Transparent:
497 new_styleobj.set_linecolor(tb_style.GetLineColor())
498 new_styleobj.set_color(tb_style.GetFill())
499
500
501
502 class MF_Layer:
503 """
504 The following parameters and functions, which the mapscript style obj
505 contains, are used:
506
507 classitem, numclasses, name, data, type
508 getClass(), getProjection(), getExtent(), getMetaData(),
509 getFirstMetaDataKey(), getNextMetaDataKey(), status,
510
511
512 The following paramters and functions are not used:
513 index, map, header, footer, template, groupe, tolerance,
514 toleranceunits, symbolscale, minscale, maxscale, labelminscale
515 labelmaxscale, sizeunits, maxfeatures, offsite, transform, labelcache
516 postlabelcache, labelitem, labelsizeitem, labelangleitem, labelitemindex
517 labelsizeitemindex, labelangleitemindex, tileitem, tileindex, units
518 numitems, filteritem, styleitem, requires
519 labelrequires, transparency, dump, debug, numprocessing, numjoins,
520 removeClass(), open(), close(), getShape(), getNumResults(), getResult()
521 getItem(), promote(), demote(), draw(), drawQuery(), queryByAttributes()
522 queryByPoint(), queryByRect(), queryByFeatures(), queryByShape(),
523 setFilter(), setFilterString(), setWKTProjection(), setProjection()
524 addFeature(), getNumFeatures(), setMetaData(), removeMetaData(),
525 getWMSFeatureInfoURL(), executeWFSGetFeature(), applySLD(), applySLDURL()
526 enerateSLD(), moveClassUp(), moveClassDown(), setProcessing(),
527 getProcessing(), clearProcessing()
528 """
529
530 def __init__(self, mf_layer):
531 """
532 Creates the Layer Object from the mapscript Layer Object.
533 the class objects in the layer object will be stored in
534 an array. The metadata are created as a new object.
535 """
536 self._mf_layer = mf_layer
537
538 # Create Classes
539 # there could be more then 1
540 self._classes = []
541 for i in range (self._mf_layer.numclasses):
542 self._classes.append(MF_Class(self._mf_layer.getClass(i)))
543
544 self._projection = MF_Projection(self._mf_layer.getProjection())
545
546 # Create Metadata
547 self._metadata = MF_Metadata(self._mf_layer)
548
549 def get_index(self):
550 return self._mf_layer.index
551
552 def get_name(self):
553 return self._mf_layer.name
554
555 def get_data(self):
556 return self._mf_layer.data
557
558 def get_connection(self):
559 return self._mf_layer.connnection
560
561 def get_connectiontype(self):
562 return self._mf_layer.connectiontype
563
564 def get_classes(self):
565 return self._classes
566
567 def set_classes(self, new_classes):
568 self._classes = new_classes
569
570 def get_metadata(self):
571 return self._metadata
572
573 def set_metadata(self, new_metadata):
574 self._metadata = new_metadata
575
576 def get_type(self):
577 return shp_type[self._mf_layer.type]
578
579 def get_classitem(self):
580 return self._mf_layer.classitem
581
582 def get_projection(self):
583 return self._projection
584
585 def get_status(self):
586 # returns a integer value
587 # 0 = off, 1 = on, 2 = default(always on)
588 if self._mf_layer.status == 0:
589 return False
590 else:
591 return True
592
593 def get_group(self):
594 return self._mf_layer.group
595
596 def set_group(self, new_group):
597 self._mf_layer.group = new_group
598
599 def set_name(self, newname):
600 self._mf_layer.name = newname
601
602 def set_data(self, newdata, type="shape"):
603 if type == "shape":
604 self._mf_layer.data = newdata[:-4]
605 else:
606 self._mf_layer.data = newdata
607
608 def set_connection (self, newconnection):
609 self._mf_layer.connection = newconnection
610
611 def set_connectiontype (self, newtype):
612 self._mf_layer.connectiontype = newtype
613
614 def set_status(self, newstatus):
615 # status can set to true or false from thuban.
616 # but mapserver supports the default value
617 self._mf_layer.status = newstatus
618
619 def set_classitem(self, tb_field):
620 self._mf_layer.classitem = tb_field
621
622 def set_type(self, tb_type):
623 # if type = arc its a in shapetype line
624 if tb_type == "arc":
625 self._mf_layer.type = 1
626 if tb_type == "raster":
627 self._mf_layer.type = 3
628 if shp_type.has_key(tb_type):
629 self._mf_layer.type = tb_type
630 else:
631 for shp_paar_nr in shp_type:
632 if shp_type[shp_paar_nr] == tb_type:
633 self._mf_layer.type = shp_paar_nr
634 return
635
636 def set_projection(self, newprojection):
637 self._mfnewprojstring = ""
638 if newprojection:
639 self._newparams = newprojection.GetAllParameters()
640 for field in self._newparams:
641 self._mfnewprojstring = self._mfnewprojstring+ "," + field
642 self._mf_layer.setProjection(self._mfnewprojstring[1:])
643 self._projection.set_projection(newprojection)
644
645 def add_thubanclass(self, tb_class, type=""):
646 """
647 Add a thuban class object
648 """
649 new_class = MF_Class(classObj(self._mf_layer))
650 self._classes.append(new_class)
651 # set the class name to the Label form thuban if given,
652 # else set it to the value
653 if tb_class.GetLabel() != "":
654 new_class.set_name(tb_class.GetLabel())
655 else:
656 if isinstance(tb_class, ClassGroupDefault):
657 new_class.set_name("default")
658 elif isinstance(tb_class, ClassGroupSingleton):
659 new_class.set_name(str(tb_class.GetValue()))
660 else:
661 new_class.set_name(None)
662 if self.get_type() == "line":
663 new_class.add_thubanstyle(tb_class.GetProperties(), type="line")
664 elif self.get_type() == "point":
665 new_class.add_thubanstyle(tb_class.GetProperties(), type="point")
666 else:
667 new_class.add_thubanstyle(tb_class.GetProperties())
668 if (type == "default"):
669 return
670 # removed the following two lines to check if the expressionstring
671 # is needed for points, because if expressionstring is a range type,
672 # no expressionstring in the default group is allowed
673 elif (tb_class.Matches("DEFAULT")):
674 return
675 # new_class.set_expressionstring('/./')
676 else:
677 #check which type of expression
678 if isinstance(tb_class, ClassGroupRange):
679 # get the needed infos from the Range-String
680 self._range_begin = tb_class.GetRange()[0]
681 self._range_min = str(tb_class.GetMin())
682 self._range_max = str(tb_class.GetMax())
683 self._range_end = tb_class.GetRange()[len(tb_class.GetRange())-1]
684 self._range_umn = ""
685 self._range_classitem = self.get_classitem()
686 # generate the operator
687 if self._range_begin == "[":
688 self._range_op1 = ">="
689 elif self._range_begin == "]":
690 self._range_op1 = ">"
691 else:
692 print "error in Thuban class properties"
693 #build op1 string for the lower limit
694 self._range_op1 = "[" + self._range_classitem + "] " + \
695 self._range_op1 + " " +\
696 self._range_min
697 # build op2 string for the upper limit
698 if self._range_end == "[":
699 self._range_op2 = "<"
700 elif self._range_end == "]":
701 self._range_op2 = "<="
702 else:
703 print "error in Thuban class properties"
704
705 self._range_op2 = "[" + self._range_classitem + "] " + \
706 self._range_op2 + " " +\
707 self._range_max
708 # we only need AND here at the moment, becaus of the limits
709 # in thuban
710 self._range_combine = "AND"
711 # check if the one limit is set to inf and then
712 # remove the second expression becaus is not needed.
713 if self._range_min == "-inf":
714 self._range_combine = ""
715 self._range_op1 = ""
716 elif self._range_max == "inf":
717 self._range_combine = ""
718 self._range_op2 = ""
719 # build the expression together
720 self._range_umn = "(" + self._range_umn + \
721 self._range_op1 + " " +\
722 self._range_combine + \
723 self._range_op2 + " )"
724
725 #set the expression to the mapscript
726 new_class.set_expressionstring(self._range_umn)
727 else:
728 new_class.set_expressionstring(str(tb_class.GetValue()))
729 new_class.set_status(tb_class.IsVisible())
730
731 def remove_allclasses(self):
732 for i in range(0,len(self.get_classes()), 1):
733 self._mf_layer.removeClass(i)
734 self.set_classes([])
735
736 class MF_Scalebar:
737 """
738 Represent the scalebar for a map
739
740 The following settings are used:
741 label, color, imagecolor, style, intervals, units,
742 status, position, height, width
743
744 The following settings are (not) used:
745 backgroundcolor,outlinecolor, postlabelcache
746 """
747 def __init__(self, mf_scalebar):
748 self._scalebar = mf_scalebar
749 self._color = MF_Color(self._scalebar.color)
750 self._imagecolor = MF_Color(self._scalebar.imagecolor)
751 self._label = MF_Label(self._scalebar.label)
752
753 def get_label(self):
754 return self._label
755
756 def get_color(self):
757 return self._color
758
759 def get_imagecolor(self):
760 return self._imagecolor
761
762 def get_style(self):
763 return self._scalebar.style
764
765 def set_style(self, new_style):
766 self._scalebar.style = new_style
767
768 def get_size(self):
769 #returns the size
770 return (self._scalebar.width, self._scalebar.height)
771
772 def set_size(self, new_width, new_height):
773 self._scalebar.width = new_width
774 self._scalebar.height = new_height
775
776 def get_intervals(self):
777 return self._scalebar.intervals
778
779 def set_intervals(self, new_intervals):
780 self._scalebar.intervals = new_intervals
781
782 def get_units(self):
783 #returns the unittype
784 return unit_type[self._scalebar.units]
785
786 def set_units(self, units):
787 if unit_type.has_key(units):
788 self._scalebar.units = units
789 else:
790 for unit_paar_nr in unit_type:
791 if unit_type[unit_paar_nr] == units:
792 self._scalebar.units = unit_paar_nr
793
794 def get_status(self, mode="integer"):
795 if mode == "string":
796 return scalebar_status_type[self._scalebar.status]
797 else:
798 return self._scalebar.status
799
800 def set_status(self, new_status):
801 if scalebar_status_type.has_key(new_status):
802 self._scalebar.status = new_status
803 else:
804 for scalebar_status_type_nr in scalebar_status_type:
805 if scalebar_status_type[scalebar_status_type_nr] == new_status:
806 self._scalebar.status = scalebar_status_type_nr
807
808 def get_position(self, mode="integer"):
809 if mode == "string":
810 return scalebar_position_type[self._scalebar.position]
811 else:
812 return self._scalebar.position
813
814 def set_position(self, new_position):
815 if scalebar_position_type.has_key(new_position):
816 self._scalebar.position = new_position
817 else:
818 for scalebar_position_type_nr in legend_position_type:
819 if scalebar_position_type[scalebar_position_type_nr] \
820 == new_position:
821 self._scalebar.position = scalebar_position_type_nr
822
823
824 class MF_Map:
825 """
826 The following parameters and functions, which the mapscript style obj
827 contains, are used:
828
829 name, numlayers, extent, shapepath, imagecolor, imagetype, units, getLayer,
830 status, getProjection, getMetaData, getFirstMetaDataKey, getNextMetaDataKey,
831 save(), setExtent(), height, width, setProjection(), setImageType(),
832
833 The following parameters and functions are not used:
834 maxsize, layers, symbolset, fontset, labelcache,
835 transparent, interlace, imagequality, cellsize, debug, datapattern,
836 templatepattern, configoptions
837 zoomPoint(), zoomRectangle(), zoomScale(), getLayerOrder(), setLayerOrder(),
838 clone(), removeLayer(), getLayerByName(), getSymbolByName(),
839 prepareQuery(), prepareImage(), setOutputFormat(), draw(),
840 drawQuery(), drawLegend(), drawScalebar(), embedLegend(), drawLabelCache(),
841 nextLabel(), queryByPoint(), queryByRecht(), queryByFeatures(),
842 queryByShape(), setWKTProjection(), saveQuery(), saveQueryASGML(),
843 setMetaData(), removeMetaData(), setSymbolSet(), getNumSymbols(),
844 setFontSet(), saveMapContext(), loadMapContext(), moveLayerUp(),
845 moveLayerDown(), getLayersDrawingOrder(), setLayersDrawingOrder(),
846 setConfigOption(), getConfigOption(), applyConfigOptions(), applySLD(),
847 applySLDURL(), gernerateSLD(), procecssTemplate(), processLegemdTemplate(), processQueryTemplate(),
848 getOutputFormatByName(), appendOutputFormat(), removeOutputFormat(),
849 """
850 def __init__(self, mf_map):
851 """
852 Create the map object from the mapfile mapobject which is given.
853
854 All layers in the mapfile will be written to an array.
855 """
856 self._mf_map = mf_map
857 self._extent = MF_Rectangle(self._mf_map.extent)
858 self._imagecolor = MF_Color(self._mf_map.imagecolor)
859 self._web = MF_Web(self._mf_map.web)
860 self._legend = MF_Legend(self._mf_map.legend)
861 self._scalebar = MF_Scalebar(self._mf_map.scalebar)
862
863 # TODO: generate the list dynamical by alle supported formats.
864 # At the moment outputformat only get by name, but in a next
865 # version there may be a function to get the outputformat by id
866 # then there is no need to define the formattypes here
867 image_types = ['gif', 'png', 'png24', 'jpeg', 'wbmp', \
868 'swf', 'pdf', 'imagemap']
869 self._alloutputformats = []
870 self._imagetype = self._mf_map.imagetype
871 # create a temp imagtype, because the function getOutputFormatByName()
872 # set the imagetype to the received OutputFormat
873 for fmtname in image_types:
874 theformat = self._mf_map.getOutputFormatByName(fmtname)
875 if theformat:
876 self._alloutputformats.append(MF_Outputformat(theformat))
877 self._mf_map.setImageType(self._imagetype)
878
879 self._outputformat = MF_Outputformat(self._mf_map.outputformat)
880
881 # symbols
882 self._symbolset = MF_SymbolSet(self._mf_map.symbolset)
883
884 # if the map name is not set it will return a MS string.
885 if self._mf_map.name != "MS":
886 self._name = self._mf_map.name
887 else:
888 self._name = None
889
890 self._projection = MF_Projection(self._mf_map.getProjection())
891
892 # Initial Layer List
893 self._layers = []
894 self._i = 0
895 while self._i < self._mf_map.numlayers:
896 self._layers.append(MF_Layer(self._mf_map.getLayer(self._i)))
897 self._i += 1
898
899 # Shapepath if not set, shapepath will be empty
900 if self._mf_map.shapepath:
901 self._shapepath = self._mf_map.shapepath
902 else:
903 self._shapepath = ""
904
905 # Create Metadata
906 self._metadata = MF_Metadata(self._mf_map)
907
908 def create_new_layer(self):
909 """
910 the new layer must create inside the mapobj, because mapscript
911 need the mapscript object as parameter for layerObj
912 """
913 new_layer = MF_Layer(layerObj(self._mf_map))
914 self._layers.append(new_layer)
915 # the new created layer must remove from the mapobject
916 # because all layer will create new in export.
917 #self._mf_map.removeLayer(self._mf_map.numlayers-1)
918 return new_layer
919
920 def get_mappath(self):
921 return self._mf_map.mappath
922
923 def set_mappath(self, new_mappath):
924 self._mf_map.mappath = new_mappath
925
926 def get_outputformat(self):
927 return self._outputformat
928
929 def get_alloutputformats(self):
930 return self._alloutputformats
931
932 def get_imagetype(self):
933 return self._mf_map.imagetype
934
935 def set_imagetype(self, new_imagetype):
936 self._mf_map.setImageType(new_imagetype)
937
938 def get_symbolset(self):
939 return self._symbolset
940
941 def get_status(self):
942 if self._mf_map.status == 1:
943 return True
944 else:
945 return False
946
947 def set_status(self, new_status):
948 if new_status:
949 self._mf_map.status = 1
950 else:
951 self._mf_map.status = 0
952
953 def get_scalebar(self):
954 return self._scalebar
955
956 def get_web(self):
957 return self._web
958
959 def get_legend(self):
960 return self._legend
961
962 def get_extent(self):
963 return self._extent
964
965 def get_layers(self):
966 return self._layers
967
968 def get_numlayers(self):
969 return self._mf_map.numlayers
970
971 def get_projection(self):
972 return self._projection
973
974 def get_name(self):
975 return self._name
976
977 def get_shapepath(self):
978 # where are the shape files located.
979 return self._shapepath
980
981 def set_shapepath(self, new_shapepath):
982 # where are the shape files located..
983 self._shapepath = new_shapepath
984
985 def get_imagetype(self):
986 return self._mf_map.imagetype
987
988 def get_layerorder(self):
989 # shows the order of layer as list
990 return self._mf_map.getLayerOrder()
991
992 def set_layerorder(self, new_order):
993 self._mf_map.setLayerOrder(new_order)
994
995 def get_size(self):
996 #returns the size
997 return (self._mf_map.width, self._mf_map.height)
998
999 def get_units(self):
1000 #returns the unittype
1001 return unit_type[self._mf_map.units]
1002
1003 def get_imagecolor(self):
1004 return self._imagecolor
1005
1006 def set_name(self, newname):
1007 # whitespace musst be replaced, either no
1008 # mapfile will be shown in the mapserver
1009 if newname:
1010 newname = newname.replace(" ","_")
1011 self._name = newname
1012 self._mf_map.name = newname
1013
1014 def set_extent(self, newextent):
1015 """ Set the map's extent. The map's size should already have been
1016 set when you call this function, so this function will fail
1017 if not. Setting the size after the extent produces undesired
1018 results anyway. """
1019 width, height = self.get_size()
1020 if width <= 0 or height <= 0:
1021 raise mapscript.MapServerError, \
1022 "No size set before calling set_extent"
1023 if newextent:
1024 self._newrect = MF_Rectangle(rectObj(*newextent))
1025 self._mf_map.setExtent(*newextent)
1026
1027 def set_size(self, newwidth, newheight):
1028 self._mf_map.width = newwidth
1029 self._mf_map.height = newheight
1030
1031 def set_projection(self, projection):
1032 self._mfnewprojstring = ""
1033 self._newparams = projection.GetAllParameters()
1034 for field in self._newparams:
1035 self._mfnewprojstring = self._mfnewprojstring+ "," + field
1036 self._mf_map.setProjection(self._mfnewprojstring[1:])
1037 self._projection.set_projection(projection)
1038
1039 def set_units(self, units):
1040 if unit_type.has_key(units):
1041 self._mf_map.units = units
1042 else:
1043 for unit_paar_nr in unit_type:
1044 if unit_type[unit_paar_nr] == units:
1045 self._mf_map.units = unit_paar_nr
1046
1047 def get_metadata(self):
1048 return self._metadata
1049
1050 def add_thubanlayer(self, tb_layer):
1051 """
1052 Add a thuban layer
1053 """
1054 # this import statement placed here, because if it is placed at the
1055 # beginning of this file, it produced the following error:
1056 # NameError: global name 'AnnotationLayer' is not defined
1057 # don't know why this error is produced and why it works
1058 # if it is placed here instead of the beginning.
1059 from Extensions.umn_mapserver.mf_import import AnnotationLayer
1060 from Thuban.Model.postgisdb import PostGISShapeStore
1061 if hasattr(tb_layer,"extension_umn_layerobj"):
1062 #print tb_layer.extension_umn_layerobj
1063 #new_layer = MF_Layer(layerObj(self._mf_map))
1064 new_layer = tb_layer.extension_umn_layerobj
1065 else:
1066 new_layer = MF_Layer(layerObj(self._mf_map))
1067 self._layers.append(new_layer)
1068 tb_layer.extension_umn_layerobj = new_layer
1069 new_layer.remove_allclasses()
1070 # init a list to set the layerorder
1071 new_layer.get_index()
1072 new_layer.set_name(tb_layer.Title())
1073 # TODO: implement relative pathnames
1074 # yet only absolute pathnames in the LayerObj are set
1075 if isinstance(tb_layer, RasterLayer ):
1076 new_layer.set_data(tb_layer.GetImageFilename(), type="raster")
1077 new_layer.set_type("raster")
1078 new_layer.set_status(tb_layer.Visible())
1079 elif isinstance(tb_layer, AnnotationLayer):
1080 new_layer.set_type("annotation")
1081 new_layer.set_status(tb_layer.Visible())
1082 new_layer.set_data(tb_layer.ShapeStore().FileName())
1083 else:
1084 if isinstance (tb_layer.ShapeStore(), PostGISShapeStore):
1085 data = "%s from %s" % (tb_layer.ShapeStore().geometry_column,
1086 tb_layer.ShapeStore().tablename)
1087 new_layer.set_data (data, type="postgis")
1088 params = []
1089 for name in ("host", "port", "dbname", "user", "password"):
1090 val = getattr(tb_layer.ShapeStore().db, name)
1091 if val:
1092 params.append("%s=%s" % (name, val))
1093 new_layer.set_connection (" ".join(params))
1094 new_layer.set_connectiontype (mapscript.MS_POSTGIS)
1095 else:
1096 new_layer.set_data(tb_layer.ShapeStore().FileName())
1097 new_layer.set_status(tb_layer.Visible())
1098 new_layer.set_type(tb_layer.ShapeType())
1099 if tb_layer.GetClassificationColumn():
1100 new_layer.set_classitem(tb_layer.GetClassificationColumn())
1101 if tb_layer.GetProjection():
1102 new_layer.set_projection(tb_layer.GetProjection())
1103 if tb_layer.GetClassification().GetNumGroups() > 0:
1104 singletonexists = False
1105 for group in range(0, \
1106 tb_layer.GetClassification().GetNumGroups(), 1):
1107 if isinstance(tb_layer.GetClassification().GetGroup(group), \
1108 ClassGroupSingleton):
1109 singletonexists = True
1110 new_layer.add_thubanclass( \
1111 tb_layer.GetClassification().GetGroup(group))
1112 new_layer.add_thubanclass( \
1113 tb_layer.GetClassification().GetDefaultGroup())
1114 # remove the classitem if one singleton exists
1115 if singletonexists == False:
1116 new_layer.set_classitem(None)
1117 else:
1118 new_layer.add_thubanclass( \
1119 tb_layer.GetClassification().GetDefaultGroup(), \
1120 type="default")
1121 # set the projection to the layer.
1122 # if the layer has its own definition use it,
1123 # else use the main projection
1124 if tb_layer.GetProjection():
1125 new_layer.set_projection(tb_layer.GetProjection())
1126 else:
1127 new_layer.set_projection(self._projection.get_projection())
1128
1129 def remove_layer(self, delnr):
1130 if delnr < len(self._layers):
1131 # if a layer is removed, the links for the mapscript layer and
1132 # the metadata must set new
1133 # TODO: All other object in a layer obj must set a new, e.g proj.
1134 for ll in range(len(self._layers)-1, delnr, -1):
1135 self._layers[ll]._mf_layer = self._layers[ll-1]._mf_layer
1136 self._layers[ll].set_metadata(self._layers[ll-1].get_metadata())
1137
1138 self._mf_map.removeLayer(delnr)
1139 self._layers.pop(delnr)
1140
1141 def save_map(self, filepath):
1142 # save the Map
1143 # maybe an own saver can implement here
1144 self._mf_map.save(filepath)
1145
1146
1147 class MF_Web:
1148 """
1149 Save the Web settings
1150
1151 The following parametes are used:
1152 imagepath, imageurl, queryformat,
1153
1154 The following parameters are not used:
1155 log, map, template, header, footer, empty, error, extent,
1156 minscale, maxscale, mintemplate, maxtemplate
1157 """
1158 def __init__(self, mf_web):
1159 self._mf_web = mf_web
1160
1161 def get_imagepath(self):
1162 return self._mf_web.imagepath
1163
1164 def set_imagepath(self, new_imagepath):
1165 self._mf_web.imagepath = new_imagepath
1166
1167 def get_imageurl(self):
1168 return self._mf_web.imageurl
1169
1170 def get_template(self):
1171 return self._mf_web.template
1172
1173 def set_template(self, new_template):
1174 self._mf_web.template = new_template
1175
1176 def set_imageurl(self, new_imageurl):
1177 self._mf_web.imageurl = new_imageurl
1178
1179 def get_queryformat(self):
1180 return self._mf_web.queryformat
1181
1182 def set_queryformat(self, new_queryformat):
1183 self._mf_web.imagepath = new_queryformat
1184
1185
1186 class MF_Label:
1187 """
1188 The following parameters from mapscript are used:
1189 type, color, size, offsetx, offsety, partials, force, buffer,
1190 minfeaturesize, mindistance,
1191
1192 The following parameters are not used:
1193 font, outlinecolor, shadowcolor, shadowsizex, shadowsizey,
1194 backgroundcolor, backgroundshadowcolor, backgroundshadowsizex,
1195 backgroundshadowsizey, sizescaled, minsize, maxsize, position, angle,
1196 autoangle, antialias, wrap, autominfeaturesize,
1197 """
1198 def __init__(self, mf_label):
1199 """
1200 Create a legend obj from the existing mapfile
1201 """
1202 self._label = mf_label
1203 self._color = MF_Color(self._label.color)
1204
1205 def get_size(self):
1206 return self._label.size
1207
1208 def set_size(self, new_size):
1209 if label_size_type.has_key(new_size):
1210 self._label.size = new_size
1211 for label_size_type_nr in label_size_type:
1212 if label_size_type[label_size_type_nr] == new_size:
1213 self._label.size = label_size_type_nr
1214 else:
1215 self._label.size = new_size
1216
1217 def get_color(self):
1218 return self._color
1219
1220 def get_partials(self):
1221 if self._label.partials == 1:
1222 return True
1223 else:
1224 return False
1225
1226 def set_partials(self, new_partials):
1227 # if partials = True
1228 if new_partials:
1229 self._label.partials = 1
1230 elif new_partials == False:
1231 self._label.partials = 0
1232 else:
1233 print "must be boolean"
1234
1235 def get_buffer(self):
1236 return self._label.buffer
1237
1238 def set_buffer(self, new_buffer):
1239 self._label.buffer = new_buffer
1240
1241 def get_mindistance(self):
1242 return self._label.mindistance
1243
1244 def set_mindistance(self, new_mindistance):
1245 self._label.mindistance = new_mindistance
1246
1247 def get_minfeaturesize(self):
1248 return self._label.minfeaturesize
1249
1250 def set_minfeaturesize(self, new_minfeaturesize):
1251 self._label.minfeaturesize = new_minfeaturesize
1252
1253 def get_position(self, mode="integer"):
1254 if mode == "string":
1255 return label_position_type[self._label.position]
1256 else:
1257 return self._label.position
1258
1259 def set_position(self, new_position):
1260 if label_position_type.has_key(new_position):
1261 self._label.position = new_position
1262 else:
1263 for label_position_type_nr in label_position_type:
1264 if label_position_type[label_position_type_nr] == new_position:
1265 self._label.position = label_position_type_nr
1266
1267 def get_force(self):
1268 if self._label.force == 1:
1269 return True
1270 else:
1271 return False
1272
1273 def set_force(self, new_force):
1274 if new_force:
1275 self._label.force = 1
1276 else:
1277 self._label.force = 0
1278
1279 def get_type(self):
1280 return label_font_type[self._label.type]
1281
1282 def set_type(self, new_type):
1283 if label_font_type.has_key(new_type):
1284 self._label.type = new_type
1285 else:
1286 for label_font_type_nr in label_font_type:
1287 if label_font_type[label_font_type_nr] == new_type:
1288 self._label.type = label_font_type_nr
1289
1290 def get_offset(self):
1291 return (self._label.offsetx, self._label.offsety)
1292
1293 def set_offset(self, new_offsetx, new_offsety):
1294 self._label.offsetx = new_offsetx
1295 self._label.offsety = new_offsety
1296
1297
1298 class MF_Legend:
1299 """
1300 The following parameters are (not) used:
1301 imagecolor, label, keysizex, keysizey, status, position,
1302
1303 The following parameters are not used:
1304 keyspacingx, keyspacingy,
1305 outlinecolor, height, width, postlabelcache, template, map
1306 """
1307 def __init__(self, mf_legend):
1308 """
1309 Create a legend obj from the existing mapfile
1310 """
1311 self._mf_legend = mf_legend
1312 self._imagecolor = MF_Color(self._mf_legend.imagecolor)
1313 self._label = MF_Label(self._mf_legend.label)
1314
1315 def get_imagecolor(self):
1316 return self._imagecolor
1317
1318 def get_label(self):
1319 return self._label
1320
1321 def get_keysize(self):
1322 return (self._mf_legend.keysizex, self._mf_legend.keysizey)
1323
1324 def set_keysize(self, new_keysizex, new_keysizey):
1325 self._mf_legend.keysizex = new_keysizex
1326 self._mf_legend.keysizey = new_keysizey
1327
1328 def get_keyspacing(self):
1329 return (self._mf_legend.keyspacingx, self._mf_legend.keyspacingy)
1330
1331 def set_keyspacing(self, new_keyspacingx, new_keyspacingy):
1332 self._mf_legend.keyspacingx = new_keyspacingx
1333 self._mf_legend.keyspacingy = new_keyspacingy
1334
1335 def get_status(self, mode="integer"):
1336 if mode == "string":
1337 return legend_status_type[self._mf_legend.status]
1338 else:
1339 return self._mf_legend.status
1340
1341 def set_status(self, new_status):
1342 if legend_status_type.has_key(new_status):
1343 self._mf_legend.status = new_status
1344 else:
1345 for legend_status_type_nr in legend_status_type:
1346 if legend_status_type[legend_status_type_nr] == new_status:
1347 self._mf_legend.status = legend_status_type_nr
1348
1349 def get_position(self, mode="integer"):
1350 if mode == "string":
1351 return legend_position_type[self._mf_legend.position]
1352 else:
1353 return self._mf_legend.position
1354
1355 def set_position(self, new_position):
1356 if legend_position_type.has_key(new_position):
1357 self._mf_legend.position = new_position
1358 else:
1359 for legend_position_type_nr in legend_position_type:
1360 if legend_position_type[legend_position_type_nr]== new_position:
1361 self._mf_legend.position = legend_position_type_nr
1362
1363 class MF_Projection:
1364 """
1365 The following parameter, which the mapscript style obj contains is used:
1366
1367 numargs
1368 """
1369
1370 def __init__(self, mf_projection):
1371 """
1372 Create a projection object from the given mapscript projection
1373 object. If it is a epsg code the extracted from the string
1374 (e.g."init=epsg:xxxx"), else the projection parameters will
1375 be splitted and an array with the parameters will be creaded.
1376 """
1377 self._mfprojstring = mf_projection
1378 self._projstring = self._mfprojstring
1379 self._epsgcode = None
1380 self._params = None
1381 if self._mfprojstring:
1382 if self._mfprojstring.find("init=epsg:") != -1:
1383 self._initcode, self._epsgcode = self._mfprojstring.split(':')
1384 else:
1385 self._params = []
1386 self._params = [p.strip() for p in self._mfprojstring.split("+")]
1387 if self._params[0] == "":
1388 self._params.remove("")
1389
1390 def epsg_code_to_projection(self, epsg):
1391 """
1392 Find the projection for the given epsg code.
1393
1394 Copied from Extension/wms/layer.py
1395
1396 epsg -- EPSG code as string
1397 """
1398 #Needed only for this function
1399 from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE,\
1400 EPSG_DEPRECATED_PROJ_FILE
1401
1402 proj_file, warnings = get_system_proj_file(EPSG_PROJ_FILE)
1403
1404 for proj in proj_file.GetProjections():
1405 if proj.EPSGCode() == epsg:
1406 return proj
1407
1408 proj_file, warnings = get_system_proj_file(EPSG_DEPRECATED_PROJ_FILE)
1409 for proj in proj_file.GetProjections():
1410 if proj.EPSGCode() == epsg:
1411 return proj
1412 return None
1413
1414 def get_params(self):
1415 #Parameter from the mf_projectionstring as Array
1416 return self._params
1417
1418 def get_epsgcode(self):
1419 # returnes the epsg number
1420 return self._epsgcode
1421
1422 def get_epsgproj(self):
1423 # get an epsg projectionobject
1424 return self.epsg_code_to_projection(self._epsgcode)
1425
1426 def get_projection(self):
1427 return self._projstring
1428
1429 def set_projection(self, newprojection):
1430 self._projstring = newprojection
1431 self._params = newprojection.GetAllParameters()
1432 self._mfnewprojstring = ""
1433 for field in self._params:
1434 self._mfnewprojstring = self._mfnewprojstring+ "+" + field
1435 self._mfprojstring = self._mfnewprojstring
1436
1437
1438 class MF_Style:
1439 """
1440 The following parameters, which the mapscript style obj
1441 contains, are used:
1442 color, backgroundcolor, outlinecolor, size, symbolname
1443
1444 The following are not used:
1445 symbol, sizescaled, minsize, maxsize, offsetx, offsety,
1446 antialias
1447 """
1448
1449 def __init__(self, mf_style):
1450 """
1451 Create a style object from the given mapscript style object.
1452 The color Object from the color and the outlinecolor parameter
1453 will be created. if the color (red, green or blue) is -1 there
1454 is no definition in the mapfile and so there is no color object,
1455 it will set to 'None'.
1456 """
1457 self._style = mf_style
1458 if self._style.color.red == -1:
1459 self._color = None
1460 else:
1461 self._color = MF_Color(self._style.color)
1462 if self._style.outlinecolor.red == -1:
1463 self._outlinecolor = None
1464 else:
1465 self._outlinecolor = MF_Color(self._style.outlinecolor)
1466
1467 def get_color(self):
1468 return self._color
1469
1470 def get_outlinecolor(self):
1471 return self._outlinecolor
1472
1473 def get_size(self):
1474 return self._style.size
1475
1476 def set_linecolor(self, tb_color):
1477 self._color = tb_color
1478 new_linecolor = MF_Color(colorObj())
1479 new_linecolor.set_thubancolor(tb_color)
1480 self._outlinecolor = new_linecolor
1481 self._style.outlinecolor = new_linecolor.get_mfcolor()
1482
1483 def set_color(self, tb_color):
1484 self._color = tb_color
1485 new_color = MF_Color(colorObj())
1486 new_color.set_thubancolor(tb_color)
1487 self._color = new_color
1488 self._style.color = new_color.get_mfcolor()
1489
1490 def set_size(self, newsize):
1491 self._style.size = newsize
1492
1493 def set_symbolname(self, newsymbol):
1494 # its possible to use stringnames instead of numbers
1495 self._style.symbolname = newsymbol
1496

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26