Skip to content.
Logo tecnoteca

Portale Tecnoteca.it

Logo tecnoteca

Vai al sito aziendale Tecnoteca.com


 

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)


Tesi di Laurea:
"Sviluppo funzionalità gis su portale Zope"
di Marco Celotti


- Università degli studi di Udine -
-  Facoltà di Scienze Matematiche Fisiche e Naturali  -
- Dicembre 2004 -


Slide Tesi.ppt


Video Tesi.zip  [913 KB formato AVI]