You are here:
tecnoteca.it
Tesi on line
Sviluppo funzionalità gis su portale ZOPE
Sviluppo
Sviluppo codice Python
Python e ZMapServer
Python e ZMapServer
Un aspetto che va trattato a parte in questo progetto è sicuramente lo scripting del prodotto ZMapServer (e tutte le sue classi: mappa, layer, scala, mappa di riferimento etc.), in quanto è alla base del motore attraverso il quale viene fornita l'interattività con la mappa.ZOPE nella versione attuale (2.7) non fornisce ancora un modo per conoscere tutti i metodi e le variabili pubbliche delle classi; questa è una forte limitazione nel momento in cui si prova un primo approccio ad una nuova classe poiché non si è messi nella condizione di vedere chiaramente tutte le caratteristiche in modo funzionale.
Lo stesso problema si è presentato in fase iniziale con il prodotto ZMapServer e le sue classi; dopo una accurata ricerca di informazioni a riguardo si è preferito procedere con l'analisi dei file sorgenti del prodotto ZMapServer per avere una panoramica delle funzioni disponibili.
Un'operazione questa non certo facile e comunque dispendiosa in termini di tempo.
Ad ogni modo una volta acquisite queste informazioni il percorso di scripting è stato molto più immediato, poiché non vincolato a problemi extra-programmazione.
Il prodotto ZMapServer mette a disposizione una serie di classi e metodi che permettono una vasta gamma di operazioni sulla mappa, sui layer, sulla scala, etc.
Di seguito si riporta la sezione di definizione di tutti i metodi dell'oggetto ZMapServer Map (quindi tutti i metodi richiamabili all'oggetto Mappa), che sono stati sicuramente i più utilizzati; da non dimenticare l'esistenza e la possibilità di scripting di altre classi del prodotto ZMapServer
class ZSessionMap(ZSessionProxy):
"""Interface to the session mapObj"""
# Security declarations
security = ClassSecurityInfo()
security.declareProtected('View', 'getStatus', 'getImageType', 'getWidth',
'getHeight', 'getImageColor', 'getUnits', 'getName', 'getExtent',
'getProjection')
security.declareProtected('View', 'setStatus', 'setImageType', 'setWidth',
'setHeight', 'setImageColor', 'setUnits', 'setName', 'setExtent',
'setProjection')
security.declareProtected('View', 'getLayersDrawingOrder', 'transformPixel',
'zoom', 'pan', 'center', 'getPermittedLayerItemsDrawingOrdered')
def getSessionSubject(self, mapobj):
return mapobj
def setStatus(self, status):
"""Set Session Map status"""
self.sSet('status', status)
def getStatus(self):
"""Get current Map status"""
return self.sGet('status')
def setImageType(self, imagetype):
"""Set output format type"""
self.sSet('imagetype', imagetype)
def getImageType(self):
"""Get output format image type"""
return self.sGet('imagetype')
def setWidth(self, width):
"""Set image width in pixels"""
self.sSet('width', width)
def getWidth(self):
"""Get current map image width"""
return self.sGet('width')
def setHeight(self, height):
"""Set image height in lines"""
self.sSet('height', height)
def getHeight(self):
"""Get current map image height"""
return self.sGet('height')
def setExtent(self, extent):
"""Set map extent in map units"""
rect = mapscript.rectObj()
if hasattr(extent, 'getattr'): # Is a record object
rect.minx = extent.minx
rect.miny = extent.miny
rect.maxx = extent.maxx
rect.maxy = extent.maxy
else: # Assume is a dict
rect.minx = extent['minx']
rect.miny = extent['miny']
rect.maxx = extent['maxx']
rect.maxy = extent['maxy']
self.sSet('extent', rect)
def getExtent(self):
"""Get current extent in map units as a tuple"""
mapobj = self.getSessionMapObj()
rect = mapobj.extent
#rect = self.sGet('extent')
return {'minx': rect.minx,
'miny': rect.miny,
'maxx': rect.maxx,
'maxy': rect.maxy}
def setImageColor(self, color):
"""Set image color to a tuple of RGB values"""
rgb = self.colorZopeToMapServer(color)
self.sSet('imagecolor', rgb)
def getImageColor(self):
"""Get current image color as tuple of RGB values"""
rgb = self.sGet('imagecolor')
return self.colorMapServerToZope(rgb)
def setUnits(self, units):
"""Set map units"""
self.sSet('units', units)
def getUnits(self):
"""Get current units"""
return self.sGet('units')
def setName(self, name):
"""Set map name"""
self.sSet('name', name)
def getName(self):
"""Get Map name"""
return self.sGet('name')
def getProjection(self):
"""get map projection"""
mapobj = self.getSessionMapObj()
return mapobj.getProjection()
def setProjection(self, value):
"""set map projection"""
mapobj = self.getSessionMapObj()
mapobj.setProjection(value)
self.setSessionMapObj(mapobj)
def getLayersDrawingOrder(self):
"""Return list of layer names in drawing order"""
mapobj = self.getSessionMapObj()
draworder = mapobj.getLayerOrder()
order = []
for i in draworder:
order.append(mapobj.getLayer(i).name)
return order
def getPermittedLayerItemsDrawingOrdered(self):
"Return sequence of permitted ZMapLayers in drawing order"
items = []
for id in self.getLayersDrawingOrder():
try:
zlayer = self.restrictedTraverse(id)
items.append(zlayer)
except:
pass
return items
def transformPixel(self, pixel, line):
"""transform pixel/line coordinates to map coordinates"""
mapobj = self.getSessionMapObj()
extent = (mapobj.extent.minx,
mapobj.extent.miny,
mapobj.extent.maxx,
mapobj.extent.maxy )
width = mapobj.width
height = mapobj.height
pxsize = (extent[2]-extent[0])/width
pysize = (extent[3]-extent[1])/height
point = {}
point['x'] = extent[0] + pixel*pxsize
point['y'] = extent[3] - line*pysize
return point
def zoom(self, zoom_factor):
"""Zoom Map Extents in or out, preserving the image center
Called only through the web."""
# Create a mapObj in Session if needed
mapobj = self.getSessionMapObj()
# Zoom map extent
extent = (mapobj.extent.minx,
mapobj.extent.miny,
mapobj.extent.maxx,
mapobj.extent.maxy )
width = extent[2] - extent[0]
height = extent[3] - extent[1]
zoomed_width = width * zoom_factor
zoomed_height = height * zoom_factor
xshift = (zoomed_width - width)/2
yshift = (zoomed_height - height)/2
mapobj.extent.minx = extent[0] - xshift
mapobj.extent.miny = extent[1] - yshift
mapobj.extent.maxx = extent[2] + xshift
mapobj.extent.maxy = extent[3] + yshift
# Update Session data
self.setSessionMapObj(mapobj)
def pan(self, shift):
"""Pan Map by a shift vector in map units"""
# Create a mapObj in Session if needed
mapobj = self.getSessionMapObj()
# Pan map extents by a shift vector`
extent = (mapobj.extent.minx,
mapobj.extent.miny,
mapobj.extent.maxx,
mapobj.extent.maxy )
mapobj.extent.minx = extent[0] + shift[0]
mapobj.extent.miny = extent[1] + shift[1]
mapobj.extent.maxx = extent[2] + shift[0]
mapobj.extent.maxy = extent[3] + shift[1]
# Update Session data
self.setSessionMapObj(mapobj)
def center(self, imgxy):
"""Recenters the map extents so that the pixel location given
in the tuple argument imgxy is the new center"""
# If we don't have a mapObj in the Session, create a new one
mapobj = self.getSessionMapObj()
# Center on image point imgxy
extent = (mapobj.extent.minx,
mapobj.extent.miny,
mapobj.extent.maxx,
mapobj.extent.maxy )
width = mapobj.width
height = mapobj.height
pxsize = (extent[2]-extent[0])/width
pysize = (extent[3]-extent[1])/height
mapobj.extent.minx = extent[0] + pxsize*(imgxy[0] - width/2)
mapobj.extent.miny = extent[1] - pysize*(imgxy[1] - height/2)
mapobj.extent.maxx = extent[2] + pxsize*(imgxy[0] - width/2)
mapobj.extent.maxy = extent[3] - pysize*(imgxy[1] - height/2)
# Update Session data
self.setSessionMapObj(mapobj)
def session_draw(self):
"""Return imagery drawn from the SESSION mapObj"""
mapobj = self.getSessionMapObj()
imgobj = mapobj.prepareImage()
imgobj.thisown = 1
for zlayer in self.getPermittedLayerItemsDrawingOrdered():
if not zlayer.sGet('postlabelcache') \
and not zlayer.sGet('status') == mapscript.MS_OFF:
zlayer.session_draw(imgobj)
mapobj.drawLabelCache(imgobj)
# Draw the postlabelcache layers
for zlayer in self.getPermittedLayerItemsDrawingOrdered():
if zlayer.sGet('postlabelcache') \
and not zlayer.sGet('status') == mapscript.MS_OFF:
zlayer.session_draw(imgobj)
data = imgobj.saveToString()
self.REQUEST.RESPONSE.setHeader('Content-Type', imgobj.format.mimetype)
self.REQUEST.RESPONSE.write(data)