/[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 2856 - (show annotations)
Sun Jul 27 04:51:22 2008 UTC (16 years, 7 months ago) by elachuni
File MIME type: text/x-python
File size: 50022 byte(s)
Applying patch #688 (Bugfixes for umn_mapserver extension)


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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26