Personal tools
You are here: Home Members Joaquin del Cerro gvSIG Scripting - raster Notas 2 Como abordar la implementacion del API
Document Actions

Como abordar la implementacion del API

by Joaquin Jose del Cerro Murciano last modified 2013-07-13 23:44

La idea principal es añadir los metodos que hemos definido que debe tener nuestro API de scripting a la clase FLyrRaster.

Como para gestionar la implementacion precisamos de propiedades y metodos, he metido las nuevas propiedades junto con los metodos que las manejan en una clase "RasterLayerExtensions" y cuando necesito acceder a ellas creo una instancia y la mantengo en un map asociada a la clase FLyrRaster.

Para hacer las pruebas con comodidad trabajaremos con un script desde el composer, pero luego generaremos un fichero gvsig_raster.py junto al gvsig.py.

No he llegado a probar el codigo, puede tener errores, de sintaxis y de ejecucion.

Cuando tenga otro rato intentare probarlo y añadir mas explicaciones al codigo.

Ya me comentas como lo ves y si puedes o no continuar por ahi. Espero comentatios sobre el codigo:

  • Que te parece
  • Que entiendes y que no (describe con detalle lo que no entiendas).
  • Si lo harias de otra forma, y en ese caso describela.
from gvsig import *

#--------------------------------------------------------------
# This code will go to the module gvsig_raster.py 
# Now is here to debug more easily
# Begin module gvsig_raster

from org.gvsig.fmap.dal.coverage import RasterLocator
from org.gvsig.fmap.dal import DALLocator
from org.gvsig.fmap.dal.coverage.dataset import Buffer, BufferParam
from org.gvsig.raster.fmap.layers import FLyrRaster
from java.lang import Byte, Short, Integer, Float, Double

from os.path import splitext

def loadRasterLayer(rasterfile ,mode="r"):
  """
  Load a raster file in a layer
  """
  if not isinstance(rasterfile, File):
    rasterfile = File(rasterfile)

  name, ext = splitext(rasterfile.getName())[0]
  
  # Get the manager to use
  dalManager = DALLocator.getDataManager()

  if ext.lower() == ".ecw" or ext.lower() == ".jp2" :
    # FIXME
    pass
  elif ext.lower() == ".mrsid":
    # FIXME
    pass
  else:
    # Create the parameters to open the raster store based in GDAL
    params = dalManager.createStoreParameters("Gdal Store")
    params.setFile()

  # Create the raster store 
  dataStore = dalManager.createStore(params)

  # Create a raster layer based in this raster store
  layer = mapContextManager.createLayer(name, dataStore);

  return layer

rasterLayerExtensions = dict()


class RasterLayerExtensions(object):
  """
  This class hold aditional properties and operations need to manage the scripting raster layer
  (query, buffer, values....)
  """
  def __init__(self, store=None):
    self.store = store
    self.buffer = None
    self.query = None
    self.values = None
    self.kernel = None
    self.setElem = None
    self.getElem = None

  def prepareQuery(self):
    ## See RasterManager in javadocs for more info
    self.query = RasterLocator.getManager().createQuery();
    ## See RasterQuery in javadocs for more info
    self.query.setAllDrawableBands()
    self.query.setAreaOfInterest()
    self.buffer = None
    self.values = None
    self.kernel = None

  def createBuffer(self):
    self.buffer = self.store.query(self.getQuery())

  def createNewBuffer(with,height,bandcount, datatype):
    if self.store != None:
      raise RuntimeException("Can't create a new buffer associated to a store")
      
    # FIXME: workaround to work with a jython bug passing byte, short and 
    # double values as parameters
    if datatype in (Buffer.TYPE_BYTE, Buffer.TYPE_SHORT, Buffer.TYPE_INT):
      datatype = Buffer.TYPE_INT
    else:
      Buffer.TYPE_FLOAT
    # End workaround
    
    params = RasterLocator.getManager().getBufferFactory().createBufferParams(
      width, 
      height,
      bandcount,
      datatype, 
      BufferParam.CACHED
    )
    self.buffer = RasterLocator.getManager().getBufferFactory().createBuffer(params)
    self.prepareBuffer()
        
  def prepareBuffer(self):
    def setElemByte(buffer, line, col, band, data):
      buffer.setElem(line, col, band, Byte(data).byteValue())

    def setElemShort(buffer, line, col, band, data):
      buffer.setElem(line, col, band, Short(data).shortValue())
    
    def setElemInt(buffer, line, col, band, data):
      buffer.setElem(line, col, band, Integer(data).intValue())
    
    def setElemFloat(buffer, line, col, band, data):
      buffer.setElem(line, col, band, Float(data).floatValue())
    
    def setElemDouble(buffer, line, col, band, data):
      buffer.setElem(line, col, band, Double(data).doubleValue())
      
    t = buffer.getDataType()
    if t == Buffer.TYPE_BYTE:
      this.getElem = this.buffer.getElemByte
      this.setElem = setElemByte
    elif t == Buffer.TYPE__SHORT or t == Buffer.TYPE__USHORT:
      this.getElem = this.buffer.getElemShort
      this.setElem = setElemShort
    elif t == Buffer.TYPE__INT:
      this.getElem = this.buffer.getElemInt
      this.setElem = setElemInt
    elif t == Buffer.TYPE__FLOAT:
      this.getElem = this.buffer.getElemFloat
      this.setElem = setElemFloat
    elif t == Buffer.TYPE__DOUBLE:
      this.getElem = this.buffer.getElemDouble
      this.setElem = setElemDouble
    self.values = [0] * this.buffer.getBandCount()
    self.kernel = [[self.values * 3 ] * 3

  def getQuery(self):
    if self.query == None:
      self.prepareQuery()
    return self.query
      
  def getBuffer(self, store):
    if self.buffer == None:
      self.createBuffer()
      self.prepareBuffer()
    return self.buffer

  def getValue(self, band, row, column):
    if self.getElem == None:
      self.createBuffer()
      self.prepareBuffer()
    return self.getElem(row,column,band)

  def getBandValues(row, column):
    if self.getElem == None:
      self.createBuffer()
      self.prepareBuffer()
    for b in xrange(self.buffer.getBancCount()):
      self.values[b] = self.getElem(row, column, b)
    return self.values

  def setBandValues(row,column,values):
    for b in xrange(self.buffer.getBancCount()):
      self.setElem(self.buffer, row, column, b, values[b])
    
  def saveBuffer(filename):
    manager = DALLocator.getDataManager()
    eparams = manager.createServerExplorerParameters("FilesystemExplorer")
    eparams.setDynValue("initialpath", "/tmp")
    serverExplorer = manager.openServerExplorer(eparams.getExplorerName(), eparams)
  
    sparams = (NewRasterStoreParameters)serverExplorer.getAddParameters("Gdal Store")
    sparams.setFileName(filename)
    sparams.setBuffer(buffer)
  
    serverExplorer.add("Gdal Store", sparams, True)
  

  
def getExtensions(self):
  global rasterLayerExtensions
  extensions = rasterLayerExtensions.get(self.hashCode(),None)
  if extensions == None :
    extensions = RasterLayerExtensions(self.getDataStore())
    rasterLayerExtensions[self.hashCode()] = extensions
  return extensions
      
def getBandsCount(self):
  return self.getDataStore().getBandCount()

def getWidth(self):
  return self.getDataStore().getWidth()
  
def getHeight(self):
  return self.getDataStore().getHeight()
  
def getDataType(self):
  return self.getDataStore().getDataType()

def getData(self, band, row, column):
  return self.getExtensions().getValue(band, row, column)

def walk(self, operation):
  extension = self.getExtensions()
  store = self.getDataStore()
  for band in xrange(store.getBandCount()):
    for line in xrange(store.getHeight()):
      for column in xrange(store.getWidth()):
        operation(extension.getBandValues(line, column))
      
def walkKernel(self, operation):
  pass

def filter(self, filter, targetfilename, targetdatatype=None, targetbandcount=None):
  extension = self.getExtensions()
  store = self.getDataStore()
  targetExtension = RasterLayerExtensions()
  targetExtension.createNewBuffer(
    store.getWidth(), 
    store.getHeight(),
    targetbandcount,
    targetdatatype
  )
  for band in xrange(store.getBandCount()):
    for line in xrange(store.getHeight()):
      for column in xrange(store.getWidth()):
        values = filter(extension.getBandValues(line, column))
        targetExtension.setBandValues(line, column, values)
  targetExtension.saveBuffer(targetfilename);
    
def filterKernel(self, filter, targetfilename, targettype):
  pass
  
def operation(self, oepration, layer2, targetfilename, targettype):
  pass

def operationKernel(self, oepration, layer2, targetfilename, targettype):
  pass

#
# Inject new methods in the class FLyrRaster
#
FLyrRaster.getExtensions = getExtensions
FLyrRaster.getBandsCount = getBandsCount
FLyrRaster.getWidth = getWidth
FLyrRaster.getHeight = getHeight
FLyrRaster.getDataType = getDataType
FLyrRaster.getData = getData
FLyrRaster.walk = walk
FLyrRaster.walkKernel = walkKernel
FLyrRaster.filter = filter
FLyrRaster.filterKernel = filterKernel
FLyrRaster.operation = operation
FLyrRaster.operationKernel = operationKernel

#
# end module gvsig_raster.py
#-------------------------------------------------------------


#
# Here, code to test the new API.
# 

def incrShine(values):
  x = list()
  for value in values:
    x.append(value+20)
  return x


def main():
  layer = loadRasterLayer("/tmp/Costa1.tif")
  layer.filter(incrShine, "/tmp/Costa1-B.tif")

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: