[GRASS-SVN] r60080 - grass-addons/grass6/general/g.infer
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun May 4 15:46:16 PDT 2014
Author: hamish
Date: 2014-05-04 15:46:16 -0700 (Sun, 04 May 2014)
New Revision: 60080
Modified:
grass-addons/grass6/general/g.infer/g.infer
Log:
fix newlines; only read region, don't alter WIND file (#2230)
Modified: grass-addons/grass6/general/g.infer/g.infer
===================================================================
--- grass-addons/grass6/general/g.infer/g.infer 2014-05-04 21:57:22 UTC (rev 60079)
+++ grass-addons/grass6/general/g.infer/g.infer 2014-05-04 22:46:16 UTC (rev 60080)
@@ -1,996 +1,996 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-############################################################################
-#
-# MODULE: g.infer.clips
-# AUTHOR(S): Peter Loewe loewe at gisix.com
-#
-# PURPOSE: GRASS interface to the CLIPS inference engine
-# COPYRIGHT: (C) 2011,2012,2013 by Peter Loewe
-#
-# This program is free software under the GNU General Public
-# License (>=v2). Read the file COPYING that comes with GRASS
-# for details.
-#############################################################################
-#############################################################################
-#BUGS
-# grass_run / grass_read has problems when executing off-the-shelf shell commands like "sleep 2s"
-#############################################################################
-#TESTED:
-#
-# in/out: RASTER without Labels: WORKS 2012-01-18
-# in/out: RASTER with Labels: WORKS 2012-01-18
-# in/out: VOLUMES without labels: WORKS 2012-01-23
-# in/out: Vector points 2D: WORK 2012-01-23
-# out: Create new vector point layer 2012-05-08 - broken - reconifmred: 2013-01-15
-# in/out: Vector points 3D: 2012-06-07
-# in/out: facts:
-# in/out: COOL-objects:
-#
-# GRASS modules on RHS:
-# GENERAL
-# g.list: (python-call grass_run_command "g.list" "f" "type=rast,vect")
-# g.version: (python-call grass_run_command "g.version" "c")
-
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## GRASS g.infer module description
-#####################################################
-
-#%module
-#% description: GRASS GIS interface to the CLIPS inference engine
-#% keywords: inference, reseasoning, knowledge-based
-#%end
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## GRASS GUI: Flags
-#####################################################
-
-#%flag
-#% key: d
-#% description: Activate CLIPS dribble option.
-#% guisection: CLIPS
-#%end
-
-#%flag
-#% key: e
-#% description: Traceback of CLIPS error messages.
-#% guisection: CLIPS
-#%end
-
-#%flag
-#% key: i
-#% description: Interactive CLIPS shell
-#% guisection: CLIPS
-#%end
-
-#%flag
-#% key: l
-#% description: Raster input: Ignore raster labels (default: labels are imported).
-#% guisection: Input
-#%end
-
-#DEPRECATED: In most cases this will halt the module as lots and lots of GIS layer derived facts would have to be printed.
-## #%flag
-## #% key: p
-## #% description: Print applicable facts (pre-loaded) for the inference run (default: off).
-## #% guisection: CLIPS
-## #%end
-
-# #%flag
-# #% key: k
-# #% description: Provide a built-in knowledge base of application examples.
-# #% guisection: CLIPS
-# #%end
-
-#%flag
-#% key: x
-#% description: Stop execution just prior to inference run.
-#% guisection: CLIPS
-#%end
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## GRASS GUI: Options
-#####################################################
-
-#%option
-#% key: rulebase
-#% type: string
-#% key_desc: name
-#% description: Rule base file (ASCII).
-#% gisprompt: old_file,file,input
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: load_instances
-#% type: string
-#% key_desc: load_instances
-#% description: Load instances from ASCII file
-#% gisprompt: old_file,file,input
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: bload_instances
-#% type: string
-#% key_desc: bload_instances
-#% description: Load instances from binary file
-#% gisprompt: old_file,file,input
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: rast
-#% type: string
-#% gisprompt: old,cell,raster
-#% description: Raster input map(s)
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: rast3d
-#% type: string
-#% gisprompt: old,raster3,raster3
-#% description: Raster3d input map(s)
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: vector
-#% type: string
-#% gisprompt: old,vector,vector
-#% description: Vector input map(s)
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: facts
-#% type: string
-#% gisprompt: old_file,file,file
-#% description: CLIPS facts input
-#% multiple : no
-#% key_desc : facts
-#% required : no
-#% guisection: Input
-#%end
-
-#%option
-#% key: library
-#% type: string
-#% description: Built-in CLIPS rulebases which are included in g.infer. The spearfish rulebase requires the Spearfish location.
-#% options: reference,spearfish
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Input
-#%end
-
-#############################################
-##General g.infer output-related options
-
-#%option
-#% key: export
-#% type: string
-#% description: Export of maps (a subset of the maps selected as input layers)
-#% key_desc : name
-#% required : no
-#% multiple : yes
-#% guisection: Output
-#%end
-
-#%option
-#% key: output
-#% type: string
-#% description: new vector output map
-#% key_desc : name
-#% required : no
-#% multiple : yes
-#% guisection: Output
-#%end
-
-#%option
-#% key: save_instances
-#% type: string
-#% description: ASCII output of COOL instances
-#% key_desc : instances_ascii_output_name
-#% required : no
-#% guisection: Output
-#%end
-
-#%option
-#% key: bsave_instances
-#% type: string
-#% description: Binary output of COOL instances
-#% key_desc : instances_binary_output_name
-#% required : no
-#% guisection: Output
-#%end
-
-#%option
-#% key: columns
-#% type: string
-#% description: Attribute column structure for output vector
-#% key_desc : name
-#% required : no
-#% guisection: Output
-#%end
-
-#%option
-#% key: save_rulebase
-#% type: string
-#% description: CLIPS entities to be saved to ASCII file
-#% options: constructs,facts,instances
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Output
-#%end
-
-#%option
-#% key: bsave_rulebase
-#% type: string
-#% description: CLIPS entities to be saved to binary file
-#% options: constructs,facts,instances
-#% multiple : yes
-#% key_desc : name
-#% required : no
-#% guisection: Output
-#%end
-
-
-################################
-## CLIPS-related OPTIONS
-
-#%option
-#% key: strategy
-#% type: string
-#% description: Inference Strategy
-#% key_desc : Select the inference strategy (default: depth)
-#% options: breadth,complexity,depth,lex,mea,simplicity,random
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: limit
-#% type: string
-#% description: Maximum number of inferences
-#% key_desc : Upper limit for inference runs
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: salience
-#% type: string
-#% description: Salience behaviour
-#% key_desc : Select the salience behaviour strategy (default: when-defined)
-#% options: when-defined,when-activated,every-cycle
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: module
-#% type: string
-#% description: Rule base module(s) to be on te focus stack for inference launch (default: MAIN)
-#% key_desc : Module(s) (group(s= of rules) to be specificaly put the focus stack for the inference run.
-#% required : no
-#% multiple : yes
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: watch
-#% type: string
-#% options: activations,compilations,facts,functions,genericfunctions,globals,methods,messagehandlers,messages,rules,slots,statistics,all
-#% multiple : yes
-#% description: Watch options for CLIPS engine
-#% key_desc : Watch options for CLIPS engine.
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: print
-#% type: string
-#% options: agenda,breakpoints,classes,deffacts,definstances,facts,focusstack,functions,generics,globals,instances,messagehandlers,modules,rules,templates
-#% multiple : yes
-#% description: Prints CLIPS items prior to inference run.
-#% key_desc : Prints CLIPS items prior to inference run.
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: config
-#% type: string
-#% options: auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset-globals,sequence-operator-recognition,static-constraint-checking
-#% multiple : yes
-#% description: Configuration options for CLIPS engine
-#% key_desc : Configuration options for CLIPS engine.
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#%option
-#% key: classdefault
-#% type: string
-#% options: convenience,conservation
-#% multiple : no
-#% description: Class default of CLIPS engine
-#% key_desc : Class default of CLIPS engine.
-#% required : no
-#% guisection: CLIPS
-#%end
-
-#######################################################################
-#######################################################################
-#######################################################################
-## Import Python Modules
-#######################################################################
-
-def module_exists(the_module,as_name = False):
- """! TBD"""
- the_module_name = str(the_module)
- try:
- if as_name:
- import the_module_name as as_name
- else:
- __import__(the_module_name)
-
- except ImportError:
- error_message=str("[module_exists] Import Error:" + str(the_module))
- grass.fatal(_(error_message))
- return True
-
-
-import grass.script as grass
-from grass.lib import vector as grassvect
-
-from grass.lib.gis import *
-from ctypes import *
-import grass.script.array as garray
-#module_exists("grass.script.array","garray")
-import clips
-#module_exists('clips')
-#ISSUE: see below. same case.
-import sys
-import os
-import atexit
-import random
-import time
-import string as _string
-import types
-#module_exists(str("types"))
-#^^^^ There is some issue: Global name types is not defined.
-module_exists('numpy')
-module_exists(str("os.path"))
-
-#######################################################################
-#######################################################################
-#######################################################################
-## Global Variables
-#######################################################################
-
-##################################################
-#A placeholder for the NULL substitute for vector export
-# must be improved to support FLOATS for NULLS during export.
-FACT_NULL = -2147483648
-FACT_NULL_FLOAT = "nan"
-
-# Reality check:
-# Integer maps, NULLs -> (value -2147483648)
-# Float maps: NULL -> (value nan)
-
-##################################################
-# Set up dictionaries to manage all relevant aspects of GRASS-(input)-layers
-##################################################
-
-#################################################
-# Dictionary to store v.in.ascii-string for vector layers
-layers_vector_vinascii={}
-
-#################################################
-# Dictionary to store template for vector layer
-layers_template={}
-
-#################################################
-# Dictionary to store attribute column structure for vector layers
-layers_vector_columns={}
-
-#################################################
-# Dictionary to store numeric type of raster layers
-layers_raster_type={}
-
-#################################################
-# Dictionary to store 2D slice names for 3D rast3d volume layers
-layers_raster3d_slices={}
-
-##################################################
-# Access to central dictionaries
-
-def global_layers_template_put(the_layer,the_template):
- """! Put a layer template in the layer template dictionary under its layer name"""
- global the_layers_template
- layers_template[the_layer]=the_template
-
-def global_layers_raster_type_put(the_layer,the_type):
- """! Put a raster layers typ in the raster type dictionary under its layer name"""
- global layers_raster_type
- layers_raster_type[the_layer]=the_type
-
-def global_layers_vector_vinascii_put(the_layer,the_string):
- """! Put a vector layer v.in.ascii string in the layer v.in.ascii dictionary under its layer name"""
- global layers_vector_vinascii
- layers_vector_vinascii[the_layer]=the_string
-
-def global_layers_vector_columns_put(the_layer,the_columns):
- """! Put a vector layers columns description in the vector column dictionary under its layer name"""
- global layers_vector_columns
- layers_vector_columns[the_layer]=the_columns
-
-def global_layers_rast3d_slices_put(the_layer,the_slices):
- """! Put a slices info (list?) of a volume layer in the volume layer slices dictionary under its layer name"""
- global layers_raster3d_slices
- layers_raster3d_slices[the_layer] = the_slices
-
-def global_layers_template_get(the_layer):
- """! Retrieve a layer template from the layer template dictionary by its layer name"""
- global the_layers_template
- return layers_template[the_layer]
-
-def global_layers_raster_type_get(the_layer):
- """! Retrieve a raster layer type from the raster type dictionary by its layer name"""
- global layers_raster_type
- return layers_raster_type[the_layer]
-
-def global_layers_vector_vinascii_get(the_layer):
- """! Retrieve a vector layer v.in.ascii string from the vector v.in.ascii dictionary by the layer name"""
- global layers_vector_vinascii
- return layers_vector_vinascii[the_layer]
-
-def global_layers_vector_columns_get(the_layer):
- """! Retrieve a vector layer column string from the vector column dictionary by the layer name"""
- global layers_vector_columns
- return layers_vector_columns[the_layer]
-
-
-def global_layers_rast3d_slices_get(the_layer):
- """! Retrieve the slices info (list?) of a volume layer from the volume layer slices dictionary by its layer name"""
- global layers_raster3d_slices
- return layers_raster3d_slices[the_layer]
-
-
-
-#######################################################################
-#######################################################################
-#######################################################################
-## Program cleanup epilogue
-#######################################################################
-
-
-def cleanup():
- """!Function: Final cleanup routine of g.infer module"""
- # tbd: Ensure that all temp files are removed.
- grass.debug(_("[cleanup] g.infer: completed"))
-
-
-
-
-#######################################################################
-#######################################################################
-#######################################################################
-## TOOLS
-#######################################################################
-
-
-######################################################################
-# General Sanity Checks for input data:
-# Ensure that all input parameters are valid and don't contradict each other
-
-def sanity_checks_input_layers(facts_rasters,facts_raster3ds,facts_vectors,facts_file,rulebase_file):
- """!Ensure that sufficient input layers are provided to process by g.infer"""
- fact_sources = 4
- # fact sources can be either raster,volumes, vector layers or fact files.
- if not facts_rasters: fact_sources = fact_sources -1
- if not facts_raster3ds: fact_sources = fact_sources -1
- if not facts_vectors: fact_sources = fact_sources -1
- if not facts_file: fact_sources = fact_sources -1
- if (fact_sources == 0):
- grass.fatal(_("None of the parameters <raster>, <raster3d> or <vector> is set."))
- return "ok"
-
-def detect_input_layer(string_list,set_a,set_b):
- """! Naming conflict detection: Each layer name (coming from vector/raster/voxel input layers) must be unique."""
- this_count = 0
- this_list = []
- for this_item in str(string_list).split(','):
- this_count = this_count + 1
- this_list.append(this_item)
- if (this_item in set_a) or (this_item in set_b):
- grass.fatal(_("Naming conflict: Layer " + this_item + " can not be used as raster, raster3d and vector input source simultanously. Renaming is recommended."))
- this_set=set(this_list)
- return this_count,this_set
-
-def norules_nofacts_noservice():
- """! A failsafe to stop the g.infer module if neither rules nor facts are available"""
- #Note: the built-in reference knowledgebase (2013) contains both rules and facts, which overrides the requirements of this function
- rules_sum = len(GLOBAL_CLIPS__ENVIRONMENT.RuleList())
- facts_sum = len(GLOBAL_CLIPS__ENVIRONMENT.FactList())
- #if not reference_knowledgebase:
- if (facts_sum < 1):
- grass.fatal(_("Execution terminated: No facts available "))
- sys.exit()
- if (rules_sum < 1):
- grass.fatal(_("Execution terminated: No rules available "))
- sys.exit()
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## PyCLips related wrappers (for use at the CLIPS prompt).
-#####################################################
-
-# Scope: The wrappers can be used in PyCLIPS functions and via the CLIPS prompt
-
-#####################################################
-# Wrapper for SendCommand [PyCLIPS-API] for usage in CLIPS shell
-def pyclips_send_command(this_command):
- """! Wrapper for CLIPS-command execution on the (interactive) PyCLIPS shell"""
- grass.message(_("[pyclips_send_command]: " + str(this_command)))
- clips.SendCommand(str(this_command)) # works.
-
-
- #works: (python-call pyclips_send_command (assert (foo bar)))
- #works: (python-call pyclips_send_command "(assert (bar))")
-
- # Issue:
- #CLIPS[19/1]> (python-call pyclips_send_command (load 'upload_test.clp'))
- #[ARGACCES2] Function load was unable to open file 'upload_test.clp'.
- #nil
- #CLIPS[20/1]> (python-call pyclips_send_command (load #'/home/loewe/Dokumente/g.infer/2013/upload_test.clp'))
- #[ARGACCES2] Function load was unable to open file #'/home/loewe/Dokumente/g.infer/2013/upload_test.clp'.
- # returns nil but thats ok
-
-#####################################################
-# Wrapper for load/Batchstar for usage in CLIPS shell
-def pyclips_batchstar(this_file):
- """! Wrapper for load/Batchstar [CLIPS-command] for usage in CLIPS shell"""
- grass.message(_("[pyclips_batchstar: " + str(this_file)))
- ingest_rulebase_file(str(this_command))
-# internal name (might change) is mapped to reference name for clips shell use.
-# Works: (python-call ingest_rulebase_file baz.clp)
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## GRASS Python-API related wrappers (for use at the CLIPS prompt).
-#####################################################
-
-#######################################################################
-## GRASS region 3D support:
-## (TAKEN and CHANGED from (GRASS) CORE.py)
-def region3():
- """!Returns the output from running the GRASS command "g.region -g", as a
- dictionary. Example:
-
- \code
- >>> region = grass.region()
- >>> [region[key] for key in "nsew"]
- [228500.0, 215000.0, 645000.0, 630000.0]
- >>> (region['nsres'], region['ewres'])
- (10.0, 10.0)
- \endcode
-
- @return dictionary of region values
- """
- s = grass.read_command("g.region", flags='3g')
- reg = grass.parse_key_val(s, val_type = float)
- for k in ['rows', 'cols']:
- reg[k] = int(reg[k])
- return reg
-
-#####################################################
-# Wrapper for grass.run [GRASS-Python-API] for usage in CLIPS
-def grass_run_command(command,*args):
- """! Run a GRASS command on Python level- and return the results"""
- thekw = {}
- theargs = ""
- foo = ""
- for arg in args:
- if "=" in str(arg):
- thekey,thevalue=arg.split('=')
- thekw[thekey.strip(' ')]=thevalue.strip(' ')
- else:
- theargs += arg.lstrip('-').strip(' ')
- #argstuple = tuple(theargs)
- #WORKS: grass.run_command("r.stats","cl",input="geology",fs="_")
- result = grass.run_command(command,theargs, **thekw)
-
-#
-# WORKS !!! (python-call grass_run_command "g.list" "f" "type=rast,vect")
-# WORKS !!! (python-call grass_run_command "r.stats" "cl" "input=geology" "fs=_")
-
-#works: (python-call grass_run_command "g.version")
-#works: (python-call grass_run_command "g.version" "c")
-
-def grass_read_command(command,*args):
- """! Read a GRASS command [GRASS-Python-API] on Python level - and return the results"""
- thekw = {}
- theargs = ""
- foo = ""
- for arg in args:
- if "=" in str(arg):
- thekey,thevalue=arg.split('=')
- thekw[thekey.strip(' ')]=thevalue.strip(' ')
- else:
- theargs += arg.lstrip('-').strip(' ')
- result = grass.read_command(command,theargs, **thekw)
- return result
-
-#####################################################
-# Wrapper for grass.start for usage in CLIPS
-
-def grass_start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs):
- """! Start a GRASS command [GRASS-Python-API] on Python level- and return the results"""
- grass.start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs)
-
- # @param prog GRASS module
- # @param flags flags to be used (given as a string)
- # @param overwrite True to enable overwriting the output (<tt>--o</tt>)
- # @param quiet True to run quietly (<tt>--q</tt>)
- # @param verbose True to run verbosely (<tt>--v</tt>)
- # @param kwargs module's parameters
-
- #Role model:
- #clips.RegisterPythonFunction(pyread)
- #
- #py_printout1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_printout","?logical-name $?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg)))""")
- #
- #bashstar_printout1="(deffunction ginfer_printout (?logical-name $?args)(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg))))"
- #prelude_upload(bashstar_printout1)
-
-# like this:
-#py_grass_run =
-# GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_grassrun","$?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintoutRUN $?args) else (progn$ (?arg $?args)(printoutRUN ?arg)))""")
-# ... triffts nicht.
-
-
-
-#####################################################
-### Raster Layer Category Dictionary:
-def raster_categories(the_raster):
- """Returns a dictionary of all categories of a GRASS raster layer """
-
- # the VAL option must be used for FLOAT maps.
- # evtl stattdessen r.stats -il (mit labeln und floats als int betrachten)
-
- #p = grass.pipe_command('r.category',map=the_raster,fs=':', quiet='TRUE')
- p = grass.pipe_command('r.stats',flags = 'il',input=the_raster,fs=':', quiet='TRUE')
- result = {}
- count = 0
- category_list=""
- raster_category_dictionary=dict()
- for line in p.stdout:
- the_cat = line.split(':')
- raster_category_dictionary.update({the_cat[0]:the_cat[1].rstrip()})
- return raster_category_dictionary
-
-
-#####################################################
-# Wrapper for grass.raster.info [GRASS-Python-API] for usage in CLIPS
-def grass_raster_info(the_raster):
- """! Print info abouta GRASS raster layer on Python level"""
- grass.raster_info(the_raster)
-
-
-#####################################################
-# Wrapper for grass.message [GRASS-Python-API] for usage in CLIPS
-def grass_message(the_message):
- """! Wrapper for GRASS message construct (for use in PYCLIPS/Prompt)"""
- grass.message(_(the_message))
-
-#####################################################
-# Wrapper for grass.fatal for usage in CLIPS
-def grass_fatal(the_message):
- """! Wrapper for grass.fatal [GRASS-Python-API] for usage in CLIPS"""
- grass.fatal(_(the_message))
-
-#####################################################
-# Wrapper for grass.message [GRASS-Python-API] for usage in CLIPS
-def grass_debug(the_message):
- """! Wrapper for GRASS debug message"""
- grass.debug(_(the_message))
-
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## Tools for CLIPS-facts
-#####################################################
-
-
-
-def facts_total(atemplate):
- """! Provide the overall number of facts for a template"""
- count = 0
- try:
- position = fact_first(atemplate)
- count=count+1
- while (fact_next_exists(atemplate, position) == 1):
- count=count+1
- position=fact_next(atemplate, position)
- #print count
- return count
- except TypeError:
- count = (count - 1)
- # count one down as the first + 1 increment for fact_first seems to be executed even if the rest croaks.
- return count
- except AttributeError:
- count = (count - 1)
- return count
-
-def facts_any(atemplate):
- """! Check whether any facts exist for a specific template """
- count = 0
- try:
- position = fact_first(atemplate)
- count=count+1
- return True
- except TypeError:
- return False
-
-def printable_fact(afact):
- """! PrettyPrint the fact"""
- return afact.CleanPPForm()
-
-def fact_first(atemplate):
- """! Return the first fact of the template"""
- try:
- a = atemplate.InitialFact()
- return a
- except TypeError:
- return 0
-
-def fact_first_retract(atemplate):
- """! Return the content of the first known fact of the template and retract it"""
- try:
- a = atemplate.InitialFact()
- atemplate.InitialFact().Retract()
- return 1
- except TypeError:
- return 0
-
-def fact_next(atemplate, afact):
- """! Return the next fact for a template which follows on the provided fact."""
- try:
- a = atemplate.NextFact(afact)
- return a
- #return atemplate.NextFact(afact)
- except TypeError:
- return 0
-
-def fact_next_exists(atemplate, afact):
- """! Tests for the template whether another fact remains after the provided fact"""
- try:
- while atemplate.NextFact(afact):
- return 1
- except TypeError:
- return 0
-
-def get_slot(thefact,theslot):
- """! Returns the actual value of a given slot for a fact."""
- try:
- return thefact.Slots[theslot]
- except TypeError:
- return False
-
-def facts_all_integer(atemplate,aslot):
- """! Check for all facts by the template whether a given slot contains exclusively integer values."""
- all_integer = True
- try:
-
- position = fact_first(atemplate)
- slotvalue = get_slot(position,aslot)
- if not is_null_integer(slotvalue):
- all_integer = False
- # printable_fact(position)
- while (fact_next_exists(atemplate, position) == 1):
- position=fact_next(atemplate, position)
- slotvalue = get_slot(position,aslot)
- if not is_null_integer(slotvalue):
- all_integer = False
- return all_integer
-
- except TypeError:
- return False
-#tbd: Build similar for isfloat and isnumber !
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## Tools for strings (Python)
-#####################################################
-
-def cat_filter (catstring):
- """! Replace all 'cat'-strings by 'cat_' in agiven string and return result """
- return catstring.replace(' cat ', ' cat_ ')
-
-def vectorimport_get_name_type_payload(i):
- """! Split a payload string in three segments (name/type/length) and return these"""
- i=i.replace('[','')
- i=i.replace(']','')
- i=i.strip()
- attr_name,attr_type,attr_length=i.split(",")
- attr_name=attr_name.strip("'")
- attr_type=attr_type.rstrip("'").lstrip(" '")
- return attr_name,attr_type,attr_length
-
-
-
-
-#####################################################
-#####################################################
-#####################################################
-#####################################################
-## Tools for numbers (Python)
-#####################################################
-
-def is_integer(number):
- """! Check whether a number is a) a number and b) it's an Integer. Returns True or False."""
- try:
- thefloat = float(number)
- theint = int(number)
- if thefloat - theint != 0.0:
- return False
- else:
- return True
- except ValueError:
- return False
-
-def is_null_integer(number):
- """! Check whether a number is a) a number and b) it's an Integer. Returns True or False. If a NULL value is given, INTEGER is considered as true."""
- if is_null(number):
- return True
- else:
- return is_integer(number)
-
-def is_float(number):
- """! Check whether a number is a) a number and b) it's an Float. Returns True or False."""
- try:
- thefloat = float(number)
- theint = int(number)
- if thefloat - theint != 0.0:
- return True
- else:
- return Flase
- except ValueError:
- return False
-
-def is_number(number):
- """! Check whether a (float) number is a) a number. Returns True or False."""
- try:
- thefloat = float(number)
- return True
- except ValueError:
- return False
-
-def is_null(number):
- """! Check whether a value is a GRASS NULL valuer ("*"). Returns True or False."""
- if number == "*":
- return True
- else:
- return False
-
-
-
-
-###########################################################################
-###########################################################################
-###########################################################################
-###########################################################################
-###########################################################################
-## IMPORT
-###########################################################################
-###########################################################################
-
-
-def import_layer_test(the_layer,the_type):
- """! Test whether a vector|rast|rast -typed input GRASS layer exists"""
- layer_exists=""
- result = grass.find_file(name = the_layer, element = the_type)
- layer_exists=str(result['file'])
- if (layer_exists == ""):
- grass_fatal("Input map not found: " + str(the_layer))
- return 0
-
-def import_vector_test(the_layer):
- """! Test whether a vector input GRASS layer exists"""
- import_layer_test(the_layer,'vector')
-
-def import_raster_test(the_layer):
- """! Test whether a raster input GRASS layer exists"""
- import_layer_test(the_layer,'cell')
-
-# The mechanism used in import_layer|vector test does not work for raster. Here comes a workaround
-def import_rast3d_test(the_layer):
- """! Test whether a rast3d input GRASS layer exists"""
- #import_layer_test(the_layer,'rast3d')
- gisenv = grass.gisenv()
- gisenv_mapset = gisenv['MAPSET']
- listofmaps=grass.list_grouped('rast3d')[gisenv_mapset]
- if (the_layer) not in listofmaps:
- grass_fatal("Rast3d layer does not exist:" + str(the_layer))
- sys.exit(1)
-
-
-
-########################################################################
-####VECTOR IMPORT
-########################################################################
-
-
-
-def ingest_facts_vectors(facts_vectors,inference_map):
- """! Ingestion of all user-provided GRASS vector layers, and (optional) an output vector layer to be created in GRASS"""
- inference_map_vinascii_string = ""
- #^^^^ Failsafe to ensure that no empty string will be returned.
- vectors_list = str(facts_vectors).split(',')
- for index in range(0,len(vectors_list)):
- this_vector = vectors_list[index]
- import_layer_test(this_vector,'vector')
-
- if grassvector_test_valid(this_vector):
- if grassvector_ensure_points(this_vector):
- assert_vector_metadata(this_vector)
- voutascii_columns,attribute_list=grassvector2factlayer(this_vector, vector_get_attribute_structure(this_vector))
- grassvector2factlayer_assert(this_vector,voutascii_columns,attribute_list)
- #### This is a potential ISSUE: grassvector2factlayer_assert ingests the real point data.
- #### What if this is an empty inference-result vector ?
- #### Outdated logic ?
- if vectors_list[index] == inference_map:
- #Remember ths visnascci_sequence for the output layer.
- inference_map_vinascii_string = the_vinascii_string
- else:
- grass.message(_("Unable to open vector map "+this_vector+": The map must contain only points-data. " ))
- return inference_map_vinascii_string #IS THIS EVER NEEDED ??
-
-
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE: g.infer.clips
+# AUTHOR(S): Peter Loewe loewe at gisix.com
+#
+# PURPOSE: GRASS interface to the CLIPS inference engine
+# COPYRIGHT: (C) 2011,2012,2013 by Peter Loewe
+#
+# This program is free software under the GNU General Public
+# License (>=v2). Read the file COPYING that comes with GRASS
+# for details.
+#############################################################################
+#############################################################################
+#BUGS
+# grass_run / grass_read has problems when executing off-the-shelf shell commands like "sleep 2s"
+#############################################################################
+#TESTED:
+#
+# in/out: RASTER without Labels: WORKS 2012-01-18
+# in/out: RASTER with Labels: WORKS 2012-01-18
+# in/out: VOLUMES without labels: WORKS 2012-01-23
+# in/out: Vector points 2D: WORK 2012-01-23
+# out: Create new vector point layer 2012-05-08 - broken - reconifmred: 2013-01-15
+# in/out: Vector points 3D: 2012-06-07
+# in/out: facts:
+# in/out: COOL-objects:
+#
+# GRASS modules on RHS:
+# GENERAL
+# g.list: (python-call grass_run_command "g.list" "f" "type=rast,vect")
+# g.version: (python-call grass_run_command "g.version" "c")
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## GRASS g.infer module description
+#####################################################
+
+#%module
+#% description: GRASS GIS interface to the CLIPS inference engine
+#% keywords: inference, reseasoning, knowledge-based
+#%end
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## GRASS GUI: Flags
+#####################################################
+
+#%flag
+#% key: d
+#% description: Activate CLIPS dribble option.
+#% guisection: CLIPS
+#%end
+
+#%flag
+#% key: e
+#% description: Traceback of CLIPS error messages.
+#% guisection: CLIPS
+#%end
+
+#%flag
+#% key: i
+#% description: Interactive CLIPS shell
+#% guisection: CLIPS
+#%end
+
+#%flag
+#% key: l
+#% description: Raster input: Ignore raster labels (default: labels are imported).
+#% guisection: Input
+#%end
+
+#DEPRECATED: In most cases this will halt the module as lots and lots of GIS layer derived facts would have to be printed.
+## #%flag
+## #% key: p
+## #% description: Print applicable facts (pre-loaded) for the inference run (default: off).
+## #% guisection: CLIPS
+## #%end
+
+# #%flag
+# #% key: k
+# #% description: Provide a built-in knowledge base of application examples.
+# #% guisection: CLIPS
+# #%end
+
+#%flag
+#% key: x
+#% description: Stop execution just prior to inference run.
+#% guisection: CLIPS
+#%end
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## GRASS GUI: Options
+#####################################################
+
+#%option
+#% key: rulebase
+#% type: string
+#% key_desc: name
+#% description: Rule base file (ASCII).
+#% gisprompt: old_file,file,input
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: load_instances
+#% type: string
+#% key_desc: load_instances
+#% description: Load instances from ASCII file
+#% gisprompt: old_file,file,input
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: bload_instances
+#% type: string
+#% key_desc: bload_instances
+#% description: Load instances from binary file
+#% gisprompt: old_file,file,input
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: rast
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: Raster input map(s)
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: rast3d
+#% type: string
+#% gisprompt: old,raster3,raster3
+#% description: Raster3d input map(s)
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: vector
+#% type: string
+#% gisprompt: old,vector,vector
+#% description: Vector input map(s)
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: facts
+#% type: string
+#% gisprompt: old_file,file,file
+#% description: CLIPS facts input
+#% multiple : no
+#% key_desc : facts
+#% required : no
+#% guisection: Input
+#%end
+
+#%option
+#% key: library
+#% type: string
+#% description: Built-in CLIPS rulebases which are included in g.infer. The spearfish rulebase requires the Spearfish location.
+#% options: reference,spearfish
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Input
+#%end
+
+#############################################
+##General g.infer output-related options
+
+#%option
+#% key: export
+#% type: string
+#% description: Export of maps (a subset of the maps selected as input layers)
+#% key_desc : name
+#% required : no
+#% multiple : yes
+#% guisection: Output
+#%end
+
+#%option
+#% key: output
+#% type: string
+#% description: new vector output map
+#% key_desc : name
+#% required : no
+#% multiple : yes
+#% guisection: Output
+#%end
+
+#%option
+#% key: save_instances
+#% type: string
+#% description: ASCII output of COOL instances
+#% key_desc : instances_ascii_output_name
+#% required : no
+#% guisection: Output
+#%end
+
+#%option
+#% key: bsave_instances
+#% type: string
+#% description: Binary output of COOL instances
+#% key_desc : instances_binary_output_name
+#% required : no
+#% guisection: Output
+#%end
+
+#%option
+#% key: columns
+#% type: string
+#% description: Attribute column structure for output vector
+#% key_desc : name
+#% required : no
+#% guisection: Output
+#%end
+
+#%option
+#% key: save_rulebase
+#% type: string
+#% description: CLIPS entities to be saved to ASCII file
+#% options: constructs,facts,instances
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Output
+#%end
+
+#%option
+#% key: bsave_rulebase
+#% type: string
+#% description: CLIPS entities to be saved to binary file
+#% options: constructs,facts,instances
+#% multiple : yes
+#% key_desc : name
+#% required : no
+#% guisection: Output
+#%end
+
+
+################################
+## CLIPS-related OPTIONS
+
+#%option
+#% key: strategy
+#% type: string
+#% description: Inference Strategy
+#% key_desc : Select the inference strategy (default: depth)
+#% options: breadth,complexity,depth,lex,mea,simplicity,random
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: limit
+#% type: string
+#% description: Maximum number of inferences
+#% key_desc : Upper limit for inference runs
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: salience
+#% type: string
+#% description: Salience behaviour
+#% key_desc : Select the salience behaviour strategy (default: when-defined)
+#% options: when-defined,when-activated,every-cycle
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: module
+#% type: string
+#% description: Rule base module(s) to be on te focus stack for inference launch (default: MAIN)
+#% key_desc : Module(s) (group(s= of rules) to be specificaly put the focus stack for the inference run.
+#% required : no
+#% multiple : yes
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: watch
+#% type: string
+#% options: activations,compilations,facts,functions,genericfunctions,globals,methods,messagehandlers,messages,rules,slots,statistics,all
+#% multiple : yes
+#% description: Watch options for CLIPS engine
+#% key_desc : Watch options for CLIPS engine.
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: print
+#% type: string
+#% options: agenda,breakpoints,classes,deffacts,definstances,facts,focusstack,functions,generics,globals,instances,messagehandlers,modules,rules,templates
+#% multiple : yes
+#% description: Prints CLIPS items prior to inference run.
+#% key_desc : Prints CLIPS items prior to inference run.
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: config
+#% type: string
+#% options: auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset-globals,sequence-operator-recognition,static-constraint-checking
+#% multiple : yes
+#% description: Configuration options for CLIPS engine
+#% key_desc : Configuration options for CLIPS engine.
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#%option
+#% key: classdefault
+#% type: string
+#% options: convenience,conservation
+#% multiple : no
+#% description: Class default of CLIPS engine
+#% key_desc : Class default of CLIPS engine.
+#% required : no
+#% guisection: CLIPS
+#%end
+
+#######################################################################
+#######################################################################
+#######################################################################
+## Import Python Modules
+#######################################################################
+
+def module_exists(the_module,as_name = False):
+ """! TBD"""
+ the_module_name = str(the_module)
+ try:
+ if as_name:
+ import the_module_name as as_name
+ else:
+ __import__(the_module_name)
+
+ except ImportError:
+ error_message=str("[module_exists] Import Error:" + str(the_module))
+ grass.fatal(_(error_message))
+ return True
+
+
+import grass.script as grass
+from grass.lib import vector as grassvect
+
+from grass.lib.gis import *
+from ctypes import *
+import grass.script.array as garray
+#module_exists("grass.script.array","garray")
+import clips
+#module_exists('clips')
+#ISSUE: see below. same case.
+import sys
+import os
+import atexit
+import random
+import time
+import string as _string
+import types
+#module_exists(str("types"))
+#^^^^ There is some issue: Global name types is not defined.
+module_exists('numpy')
+module_exists(str("os.path"))
+
+#######################################################################
+#######################################################################
+#######################################################################
+## Global Variables
+#######################################################################
+
+##################################################
+#A placeholder for the NULL substitute for vector export
+# must be improved to support FLOATS for NULLS during export.
+FACT_NULL = -2147483648
+FACT_NULL_FLOAT = "nan"
+
+# Reality check:
+# Integer maps, NULLs -> (value -2147483648)
+# Float maps: NULL -> (value nan)
+
+##################################################
+# Set up dictionaries to manage all relevant aspects of GRASS-(input)-layers
+##################################################
+
+#################################################
+# Dictionary to store v.in.ascii-string for vector layers
+layers_vector_vinascii={}
+
+#################################################
+# Dictionary to store template for vector layer
+layers_template={}
+
+#################################################
+# Dictionary to store attribute column structure for vector layers
+layers_vector_columns={}
+
+#################################################
+# Dictionary to store numeric type of raster layers
+layers_raster_type={}
+
+#################################################
+# Dictionary to store 2D slice names for 3D rast3d volume layers
+layers_raster3d_slices={}
+
+##################################################
+# Access to central dictionaries
+
+def global_layers_template_put(the_layer,the_template):
+ """! Put a layer template in the layer template dictionary under its layer name"""
+ global the_layers_template
+ layers_template[the_layer]=the_template
+
+def global_layers_raster_type_put(the_layer,the_type):
+ """! Put a raster layers typ in the raster type dictionary under its layer name"""
+ global layers_raster_type
+ layers_raster_type[the_layer]=the_type
+
+def global_layers_vector_vinascii_put(the_layer,the_string):
+ """! Put a vector layer v.in.ascii string in the layer v.in.ascii dictionary under its layer name"""
+ global layers_vector_vinascii
+ layers_vector_vinascii[the_layer]=the_string
+
+def global_layers_vector_columns_put(the_layer,the_columns):
+ """! Put a vector layers columns description in the vector column dictionary under its layer name"""
+ global layers_vector_columns
+ layers_vector_columns[the_layer]=the_columns
+
+def global_layers_rast3d_slices_put(the_layer,the_slices):
+ """! Put a slices info (list?) of a volume layer in the volume layer slices dictionary under its layer name"""
+ global layers_raster3d_slices
+ layers_raster3d_slices[the_layer] = the_slices
+
+def global_layers_template_get(the_layer):
+ """! Retrieve a layer template from the layer template dictionary by its layer name"""
+ global the_layers_template
+ return layers_template[the_layer]
+
+def global_layers_raster_type_get(the_layer):
+ """! Retrieve a raster layer type from the raster type dictionary by its layer name"""
+ global layers_raster_type
+ return layers_raster_type[the_layer]
+
+def global_layers_vector_vinascii_get(the_layer):
+ """! Retrieve a vector layer v.in.ascii string from the vector v.in.ascii dictionary by the layer name"""
+ global layers_vector_vinascii
+ return layers_vector_vinascii[the_layer]
+
+def global_layers_vector_columns_get(the_layer):
+ """! Retrieve a vector layer column string from the vector column dictionary by the layer name"""
+ global layers_vector_columns
+ return layers_vector_columns[the_layer]
+
+
+def global_layers_rast3d_slices_get(the_layer):
+ """! Retrieve the slices info (list?) of a volume layer from the volume layer slices dictionary by its layer name"""
+ global layers_raster3d_slices
+ return layers_raster3d_slices[the_layer]
+
+
+
+#######################################################################
+#######################################################################
+#######################################################################
+## Program cleanup epilogue
+#######################################################################
+
+
+def cleanup():
+ """!Function: Final cleanup routine of g.infer module"""
+ # tbd: Ensure that all temp files are removed.
+ grass.debug(_("[cleanup] g.infer: completed"))
+
+
+
+
+#######################################################################
+#######################################################################
+#######################################################################
+## TOOLS
+#######################################################################
+
+
+######################################################################
+# General Sanity Checks for input data:
+# Ensure that all input parameters are valid and don't contradict each other
+
+def sanity_checks_input_layers(facts_rasters,facts_raster3ds,facts_vectors,facts_file,rulebase_file):
+ """!Ensure that sufficient input layers are provided to process by g.infer"""
+ fact_sources = 4
+ # fact sources can be either raster,volumes, vector layers or fact files.
+ if not facts_rasters: fact_sources = fact_sources -1
+ if not facts_raster3ds: fact_sources = fact_sources -1
+ if not facts_vectors: fact_sources = fact_sources -1
+ if not facts_file: fact_sources = fact_sources -1
+ if (fact_sources == 0):
+ grass.fatal(_("None of the parameters <raster>, <raster3d> or <vector> is set."))
+ return "ok"
+
+def detect_input_layer(string_list,set_a,set_b):
+ """! Naming conflict detection: Each layer name (coming from vector/raster/voxel input layers) must be unique."""
+ this_count = 0
+ this_list = []
+ for this_item in str(string_list).split(','):
+ this_count = this_count + 1
+ this_list.append(this_item)
+ if (this_item in set_a) or (this_item in set_b):
+ grass.fatal(_("Naming conflict: Layer " + this_item + " can not be used as raster, raster3d and vector input source simultanously. Renaming is recommended."))
+ this_set=set(this_list)
+ return this_count,this_set
+
+def norules_nofacts_noservice():
+ """! A failsafe to stop the g.infer module if neither rules nor facts are available"""
+ #Note: the built-in reference knowledgebase (2013) contains both rules and facts, which overrides the requirements of this function
+ rules_sum = len(GLOBAL_CLIPS__ENVIRONMENT.RuleList())
+ facts_sum = len(GLOBAL_CLIPS__ENVIRONMENT.FactList())
+ #if not reference_knowledgebase:
+ if (facts_sum < 1):
+ grass.fatal(_("Execution terminated: No facts available "))
+ sys.exit()
+ if (rules_sum < 1):
+ grass.fatal(_("Execution terminated: No rules available "))
+ sys.exit()
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## PyCLips related wrappers (for use at the CLIPS prompt).
+#####################################################
+
+# Scope: The wrappers can be used in PyCLIPS functions and via the CLIPS prompt
+
+#####################################################
+# Wrapper for SendCommand [PyCLIPS-API] for usage in CLIPS shell
+def pyclips_send_command(this_command):
+ """! Wrapper for CLIPS-command execution on the (interactive) PyCLIPS shell"""
+ grass.message(_("[pyclips_send_command]: " + str(this_command)))
+ clips.SendCommand(str(this_command)) # works.
+
+
+ #works: (python-call pyclips_send_command (assert (foo bar)))
+ #works: (python-call pyclips_send_command "(assert (bar))")
+
+ # Issue:
+ #CLIPS[19/1]> (python-call pyclips_send_command (load 'upload_test.clp'))
+ #[ARGACCES2] Function load was unable to open file 'upload_test.clp'.
+ #nil
+ #CLIPS[20/1]> (python-call pyclips_send_command (load #'/home/loewe/Dokumente/g.infer/2013/upload_test.clp'))
+ #[ARGACCES2] Function load was unable to open file #'/home/loewe/Dokumente/g.infer/2013/upload_test.clp'.
+ # returns nil but thats ok
+
+#####################################################
+# Wrapper for load/Batchstar for usage in CLIPS shell
+def pyclips_batchstar(this_file):
+ """! Wrapper for load/Batchstar [CLIPS-command] for usage in CLIPS shell"""
+ grass.message(_("[pyclips_batchstar: " + str(this_file)))
+ ingest_rulebase_file(str(this_command))
+# internal name (might change) is mapped to reference name for clips shell use.
+# Works: (python-call ingest_rulebase_file baz.clp)
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## GRASS Python-API related wrappers (for use at the CLIPS prompt).
+#####################################################
+
+#######################################################################
+## GRASS region 3D support:
+## (TAKEN and CHANGED from (GRASS) CORE.py)
+def region3():
+ """!Returns the output from running the GRASS command "g.region -gu", as a
+ dictionary. Example:
+
+ \code
+ >>> region = grass.region()
+ >>> [region[key] for key in "nsew"]
+ [228500.0, 215000.0, 645000.0, 630000.0]
+ >>> (region['nsres'], region['ewres'])
+ (10.0, 10.0)
+ \endcode
+
+ @return dictionary of region values
+ """
+ s = grass.read_command("g.region", flags='3gu')
+ reg = grass.parse_key_val(s, val_type = float)
+ for k in ['rows', 'cols']:
+ reg[k] = int(reg[k])
+ return reg
+
+#####################################################
+# Wrapper for grass.run [GRASS-Python-API] for usage in CLIPS
+def grass_run_command(command,*args):
+ """! Run a GRASS command on Python level- and return the results"""
+ thekw = {}
+ theargs = ""
+ foo = ""
+ for arg in args:
+ if "=" in str(arg):
+ thekey,thevalue=arg.split('=')
+ thekw[thekey.strip(' ')]=thevalue.strip(' ')
+ else:
+ theargs += arg.lstrip('-').strip(' ')
+ #argstuple = tuple(theargs)
+ #WORKS: grass.run_command("r.stats","cl",input="geology",fs="_")
+ result = grass.run_command(command,theargs, **thekw)
+
+#
+# WORKS !!! (python-call grass_run_command "g.list" "f" "type=rast,vect")
+# WORKS !!! (python-call grass_run_command "r.stats" "cl" "input=geology" "fs=_")
+
+#works: (python-call grass_run_command "g.version")
+#works: (python-call grass_run_command "g.version" "c")
+
+def grass_read_command(command,*args):
+ """! Read a GRASS command [GRASS-Python-API] on Python level - and return the results"""
+ thekw = {}
+ theargs = ""
+ foo = ""
+ for arg in args:
+ if "=" in str(arg):
+ thekey,thevalue=arg.split('=')
+ thekw[thekey.strip(' ')]=thevalue.strip(' ')
+ else:
+ theargs += arg.lstrip('-').strip(' ')
+ result = grass.read_command(command,theargs, **thekw)
+ return result
+
+#####################################################
+# Wrapper for grass.start for usage in CLIPS
+
+def grass_start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs):
+ """! Start a GRASS command [GRASS-Python-API] on Python level- and return the results"""
+ grass.start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs)
+
+ # @param prog GRASS module
+ # @param flags flags to be used (given as a string)
+ # @param overwrite True to enable overwriting the output (<tt>--o</tt>)
+ # @param quiet True to run quietly (<tt>--q</tt>)
+ # @param verbose True to run verbosely (<tt>--v</tt>)
+ # @param kwargs module's parameters
+
+ #Role model:
+ #clips.RegisterPythonFunction(pyread)
+ #
+ #py_printout1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_printout","?logical-name $?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg)))""")
+ #
+ #bashstar_printout1="(deffunction ginfer_printout (?logical-name $?args)(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg))))"
+ #prelude_upload(bashstar_printout1)
+
+# like this:
+#py_grass_run =
+# GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_grassrun","$?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintoutRUN $?args) else (progn$ (?arg $?args)(printoutRUN ?arg)))""")
+# ... triffts nicht.
+
+
+
+#####################################################
+### Raster Layer Category Dictionary:
+def raster_categories(the_raster):
+ """Returns a dictionary of all categories of a GRASS raster layer """
+
+ # the VAL option must be used for FLOAT maps.
+ # evtl stattdessen r.stats -il (mit labeln und floats als int betrachten)
+
+ #p = grass.pipe_command('r.category',map=the_raster,fs=':', quiet='TRUE')
+ p = grass.pipe_command('r.stats',flags = 'il',input=the_raster,fs=':', quiet='TRUE')
+ result = {}
+ count = 0
+ category_list=""
+ raster_category_dictionary=dict()
+ for line in p.stdout:
+ the_cat = line.split(':')
+ raster_category_dictionary.update({the_cat[0]:the_cat[1].rstrip()})
+ return raster_category_dictionary
+
+
+#####################################################
+# Wrapper for grass.raster.info [GRASS-Python-API] for usage in CLIPS
+def grass_raster_info(the_raster):
+ """! Print info abouta GRASS raster layer on Python level"""
+ grass.raster_info(the_raster)
+
+
+#####################################################
+# Wrapper for grass.message [GRASS-Python-API] for usage in CLIPS
+def grass_message(the_message):
+ """! Wrapper for GRASS message construct (for use in PYCLIPS/Prompt)"""
+ grass.message(_(the_message))
+
+#####################################################
+# Wrapper for grass.fatal for usage in CLIPS
+def grass_fatal(the_message):
+ """! Wrapper for grass.fatal [GRASS-Python-API] for usage in CLIPS"""
+ grass.fatal(_(the_message))
+
+#####################################################
+# Wrapper for grass.message [GRASS-Python-API] for usage in CLIPS
+def grass_debug(the_message):
+ """! Wrapper for GRASS debug message"""
+ grass.debug(_(the_message))
+
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## Tools for CLIPS-facts
+#####################################################
+
+
+
+def facts_total(atemplate):
+ """! Provide the overall number of facts for a template"""
+ count = 0
+ try:
+ position = fact_first(atemplate)
+ count=count+1
+ while (fact_next_exists(atemplate, position) == 1):
+ count=count+1
+ position=fact_next(atemplate, position)
+ #print count
+ return count
+ except TypeError:
+ count = (count - 1)
+ # count one down as the first + 1 increment for fact_first seems to be executed even if the rest croaks.
+ return count
+ except AttributeError:
+ count = (count - 1)
+ return count
+
+def facts_any(atemplate):
+ """! Check whether any facts exist for a specific template """
+ count = 0
+ try:
+ position = fact_first(atemplate)
+ count=count+1
+ return True
+ except TypeError:
+ return False
+
+def printable_fact(afact):
+ """! PrettyPrint the fact"""
+ return afact.CleanPPForm()
+
+def fact_first(atemplate):
+ """! Return the first fact of the template"""
+ try:
+ a = atemplate.InitialFact()
+ return a
+ except TypeError:
+ return 0
+
+def fact_first_retract(atemplate):
+ """! Return the content of the first known fact of the template and retract it"""
+ try:
+ a = atemplate.InitialFact()
+ atemplate.InitialFact().Retract()
+ return 1
+ except TypeError:
+ return 0
+
+def fact_next(atemplate, afact):
+ """! Return the next fact for a template which follows on the provided fact."""
+ try:
+ a = atemplate.NextFact(afact)
+ return a
+ #return atemplate.NextFact(afact)
+ except TypeError:
+ return 0
+
+def fact_next_exists(atemplate, afact):
+ """! Tests for the template whether another fact remains after the provided fact"""
+ try:
+ while atemplate.NextFact(afact):
+ return 1
+ except TypeError:
+ return 0
+
+def get_slot(thefact,theslot):
+ """! Returns the actual value of a given slot for a fact."""
+ try:
+ return thefact.Slots[theslot]
+ except TypeError:
+ return False
+
+def facts_all_integer(atemplate,aslot):
+ """! Check for all facts by the template whether a given slot contains exclusively integer values."""
+ all_integer = True
+ try:
+
+ position = fact_first(atemplate)
+ slotvalue = get_slot(position,aslot)
+ if not is_null_integer(slotvalue):
+ all_integer = False
+ # printable_fact(position)
+ while (fact_next_exists(atemplate, position) == 1):
+ position=fact_next(atemplate, position)
+ slotvalue = get_slot(position,aslot)
+ if not is_null_integer(slotvalue):
+ all_integer = False
+ return all_integer
+
+ except TypeError:
+ return False
+#tbd: Build similar for isfloat and isnumber !
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## Tools for strings (Python)
+#####################################################
+
+def cat_filter (catstring):
+ """! Replace all 'cat'-strings by 'cat_' in agiven string and return result """
+ return catstring.replace(' cat ', ' cat_ ')
+
+def vectorimport_get_name_type_payload(i):
+ """! Split a payload string in three segments (name/type/length) and return these"""
+ i=i.replace('[','')
+ i=i.replace(']','')
+ i=i.strip()
+ attr_name,attr_type,attr_length=i.split(",")
+ attr_name=attr_name.strip("'")
+ attr_type=attr_type.rstrip("'").lstrip(" '")
+ return attr_name,attr_type,attr_length
+
+
+
+
+#####################################################
+#####################################################
+#####################################################
+#####################################################
+## Tools for numbers (Python)
+#####################################################
+
+def is_integer(number):
+ """! Check whether a number is a) a number and b) it's an Integer. Returns True or False."""
+ try:
+ thefloat = float(number)
+ theint = int(number)
+ if thefloat - theint != 0.0:
+ return False
+ else:
+ return True
+ except ValueError:
+ return False
+
+def is_null_integer(number):
+ """! Check whether a number is a) a number and b) it's an Integer. Returns True or False. If a NULL value is given, INTEGER is considered as true."""
+ if is_null(number):
+ return True
+ else:
+ return is_integer(number)
+
+def is_float(number):
+ """! Check whether a number is a) a number and b) it's an Float. Returns True or False."""
+ try:
+ thefloat = float(number)
+ theint = int(number)
+ if thefloat - theint != 0.0:
+ return True
+ else:
+ return Flase
+ except ValueError:
+ return False
+
+def is_number(number):
+ """! Check whether a (float) number is a) a number. Returns True or False."""
+ try:
+ thefloat = float(number)
+ return True
+ except ValueError:
+ return False
+
+def is_null(number):
+ """! Check whether a value is a GRASS NULL valuer ("*"). Returns True or False."""
+ if number == "*":
+ return True
+ else:
+ return False
+
+
+
+
+###########################################################################
+###########################################################################
+###########################################################################
+###########################################################################
+###########################################################################
+## IMPORT
+###########################################################################
+###########################################################################
+
+
+def import_layer_test(the_layer,the_type):
+ """! Test whether a vector|rast|rast -typed input GRASS layer exists"""
+ layer_exists=""
+ result = grass.find_file(name = the_layer, element = the_type)
+ layer_exists=str(result['file'])
+ if (layer_exists == ""):
+ grass_fatal("Input map not found: " + str(the_layer))
+ return 0
+
+def import_vector_test(the_layer):
+ """! Test whether a vector input GRASS layer exists"""
+ import_layer_test(the_layer,'vector')
+
+def import_raster_test(the_layer):
+ """! Test whether a raster input GRASS layer exists"""
+ import_layer_test(the_layer,'cell')
+
+# The mechanism used in import_layer|vector test does not work for raster. Here comes a workaround
+def import_rast3d_test(the_layer):
+ """! Test whether a rast3d input GRASS layer exists"""
+ #import_layer_test(the_layer,'rast3d')
+ gisenv = grass.gisenv()
+ gisenv_mapset = gisenv['MAPSET']
+ listofmaps=grass.list_grouped('rast3d')[gisenv_mapset]
+ if (the_layer) not in listofmaps:
+ grass_fatal("Rast3d layer does not exist:" + str(the_layer))
+ sys.exit(1)
+
+
+
+########################################################################
+####VECTOR IMPORT
+########################################################################
+
+
+
+def ingest_facts_vectors(facts_vectors,inference_map):
+ """! Ingestion of all user-provided GRASS vector layers, and (optional) an output vector layer to be created in GRASS"""
+ inference_map_vinascii_string = ""
+ #^^^^ Failsafe to ensure that no empty string will be returned.
+ vectors_list = str(facts_vectors).split(',')
+ for index in range(0,len(vectors_list)):
+ this_vector = vectors_list[index]
+ import_layer_test(this_vector,'vector')
+
+ if grassvector_test_valid(this_vector):
+ if grassvector_ensure_points(this_vector):
+ assert_vector_metadata(this_vector)
+ voutascii_columns,attribute_list=grassvector2factlayer(this_vector, vector_get_attribute_structure(this_vector))
+ grassvector2factlayer_assert(this_vector,voutascii_columns,attribute_list)
+ #### This is a potential ISSUE: grassvector2factlayer_assert ingests the real point data.
+ #### What if this is an empty inference-result vector ?
+ #### Outdated logic ?
+ if vectors_list[index] == inference_map:
+ #Remember ths visnascci_sequence for the output layer.
+ inference_map_vinascii_string = the_vinascii_string
+ else:
+ grass.message(_("Unable to open vector map "+this_vector+": The map must contain only points-data. " ))
+ return inference_map_vinascii_string #IS THIS EVER NEEDED ??
+
+
+
+
def grassvector_new(the_vector, attributelist):
"""! Creates (touch) a new empty GRASS vector (to contain inference results)"""
# v.in.ascii -e
@@ -998,1892 +998,1892 @@
grass.run_command("v.in.ascii","e",input='-',output=the_vector, x=1, y=2, columns=attributelist, overwrite='True', quiet='TRUE')
#grass_message(str("*** GRASSVECTOR: " + str(the_vector) + " HAS BEEN CREATED ***"))
-
-def grassvector2factlayer(the_vector,the_attributelist):
- """! Import a GRASS vector and create a custom fact-template according to the vectors database attributes"""
-
- #tbd: Extension for an optional attribute as an addtitional paramater needed 1)Name 2)Type 3)Value
- gisenv = grass.gisenv()
- gisenv_mapset = gisenv['MAPSET']
+
+def grassvector2factlayer(the_vector,the_attributelist):
+ """! Import a GRASS vector and create a custom fact-template according to the vectors database attributes"""
+
+ #tbd: Extension for an optional attribute as an addtitional paramater needed 1)Name 2)Type 3)Value
+ gisenv = grass.gisenv()
+ gisenv_mapset = gisenv['MAPSET']
- #mymessage="grassvector2factlayer: " + str(the_vector)+ " columns = " + str(the_attributelist)
- #grass.message(_(mymessage))
- voutascii_columns=""
- vinascii_columns=""
- columns_list=[]
-
- if grassvector_test_3d(the_vector):
- z_column = True
- else:
- z_column = False
-
- # construct strings to generate templates both on pyclips and clips level:
- buildtemplate_template = "(slot x)(slot y)"
- if z_column:
- buildtemplate_template += "(slot z)"
- bashstar_template = "(deftemplate " + the_vector + " (slot x)(slot y)"
-
- if z_column:
- bashstar_template += "(slot z)"
-
- attribute_list = []
- attribute_list.append("x")
- attribute_list.append("y")
-
- if z_column:
- attribute_list.append("z")
-
- attribute_list.append("numcat")
-
- attributes = the_attributelist
-
- if isinstance(the_attributelist, types.ListType):
- #iterate over all existing attributes and append them to the template-construction-strings
- for i in attributes:
- i=i.replace('[','')
- i=i.replace(']','')
- i=i.strip()
- attr_name,attr_type,attr_length=i.split(",")
- attr_name=attr_name.strip("'")
- attr_type=attr_type.rstrip("'").lstrip(" '")
-
- if ((attr_name != 'x') and (attr_name != 'y')) and (attr_name != 'z'):
- attr_length=attr_length.rstrip("'").lstrip(" '")
- buildtemplate_template = buildtemplate_template + "(multislot "+ attr_name +")"
- bashstar_template = bashstar_template + "(multislot "+ attr_name +")"
- voutascii_columns = voutascii_columns + attr_name + ","
- attribute_list.append(attr_name)
-
- if attr_type == 'INTEGER':
- export_type = 'int'
- elif attr_type == 'DOUBLE PRECISION':
- export_type = 'double precision'
- elif attr_type == 'CHARACTER':
- export_type = 'varchar('+attr_length+')'
- else:
- grass.fatal(_("Unkown attribute type: "+attr_type))
- else:
- print ""
- #print "[grassvector2factlayer] Filtered out: " + attr_name + " " + attr_type
-
- vinascii_columns = vinascii_columns + " " + attr_name + " " + export_type + ","
- columns_list.append(attr_name)
-
- elif isinstance(the_attributelist, types.StringTypes):
- attributeline=str(attributes).strip("'")
- attributelist=attributeline.split(',')
- #^^^ husk single quotes
-
- for i in attributelist:
- attr_name,ignore,attr_type = i.strip().partition(" ")
- attr_name.strip()
- attr_type.strip()
- export_type='double precision'
- #^^^--- fallback option: works for x and y
- if ((attr_name != 'x') and (attr_name != 'y')) and (attr_name != 'z'):
- buildtemplate_template = buildtemplate_template + "(multislot "+ attr_name +")"
- bashstar_template = bashstar_template + "(multislot "+ attr_name +")"
- voutascii_columns = voutascii_columns + attr_name + ","
- attribute_list.append(attr_name)
- if attr_type == 'int':
- export_type = 'int'
- elif attr_type == 'double precision':
- export_type = 'double precision'
- elif attr_type.startswith('varchar'):
- #tbd: filter out actual length !!!!!
- export_type = 'varchar(255)'
- else:
- grass.fatal(_("Unkown attribute type:"+attr_type))
-
- else:
- grass.message(_(" "))
- columns_list.append(attr_name)
-
- vinascii_columns = vinascii_columns + " " + attr_name + " " + export_type + ","
-
-
- voutascii_columns = voutascii_columns.rstrip(",")
- #strip trailing comma
- #-> is needed to assert cector data wird
-
- vinascii_columns = "'"+vinascii_columns.rstrip(",")+"'"
- #strip trailing comma and add quotation
-
- bashstar_template = bashstar_template + ")"
-
- #Instantiate the new template in PyClips
- quoted_template = buildtemplate_template
-
- the_new_template = GLOBAL_CLIPS__ENVIRONMENT.BuildTemplate(the_vector,quoted_template,"GRASS VECTOR")
-
- #Instantiate the new template in Clips
- prelude_upload(bashstar_template)
- # !!! REFACTORING: prelude_upload uses a write to tempfile approach. Better alternative: Use the here document function !
-
- global_layers_template_put(the_vector,the_new_template)
- global_layers_vector_vinascii_put(the_vector,vinascii_columns)
- global_layers_vector_columns_put(the_vector,columns_list)
-
- return voutascii_columns,attribute_list
-
-
-
-def grassvector2factlayer_internal(the_vector):
- """! Internal Version: Import a GRASS vector and create a custom fact-template according to the vectors database attributes"""
- grassvector2factlayer(the_vector,vector_get_attribute_structure(the_vector))
- return True
-
-
-
-def grassvector_KB_load_vector(the_vector):
- """! Creates a template and asserts the facts for a GRASS vector - to be used with internal knowledgebases """
- if grassvector_test_valid(thie_vector):
- if grassvector_ensure_points(thie_vector):
- assert_vector_metadata(the_vector)
- print str(vector_get_attribute_structure(the_vector))
- voutascii_columns,attribute_list = grassvector2factlayer(the_vector, vector_get_attribute_structure(the_vector))
- grassvector2factlayer_assert(the_vector,voutascii_columns,attribute_list)
- else:
- grass.message(_("[grassvector_KB_load_vector]: Unable to open vector map "+this_vector+": The map must contain only points-data. " ))
- else:
- grass.message(_("[grassvector_KB_load_vector]: Unable to open vector map "+this_vector+": Invalid vector. " ))
-
-def grassvector_ensure_points(the_vector):
- """! Checks a GRASS vector layer whether all geometry objects are points. Returns false otherwise """
-#REFACTORING OPPORTUNITY: pipe stuff ...
- #p = grass.pipe_command('v.info',flags='t',map=the_vector, quiet='TRUE')
- #result = {}
- #count = 0
- #vinfo={}
- #for line in p.stdout:
- # the_line = line.strip().split("=")
- # vinfo[the_line[0]]=the_line[1]
- vinfo = grass.vector_info_topo(the_vector)
- points_count=vinfo['points']
- primitives_count=vinfo['primitives']
- if points_count == primitives_count:
- return True
- else:
- return False
-
-def grassvector_test_3d(the_vector):
- """! Tests a GRASS vector layer for the 3d attribute (-> z column exists) . Returns false otherwise """
- vinfo = grass.vector_info_topo(the_vector)
+ #mymessage="grassvector2factlayer: " + str(the_vector)+ " columns = " + str(the_attributelist)
+ #grass.message(_(mymessage))
+ voutascii_columns=""
+ vinascii_columns=""
+ columns_list=[]
+
+ if grassvector_test_3d(the_vector):
+ z_column = True
+ else:
+ z_column = False
+
+ # construct strings to generate templates both on pyclips and clips level:
+ buildtemplate_template = "(slot x)(slot y)"
+ if z_column:
+ buildtemplate_template += "(slot z)"
+ bashstar_template = "(deftemplate " + the_vector + " (slot x)(slot y)"
+
+ if z_column:
+ bashstar_template += "(slot z)"
+
+ attribute_list = []
+ attribute_list.append("x")
+ attribute_list.append("y")
+
+ if z_column:
+ attribute_list.append("z")
+
+ attribute_list.append("numcat")
+
+ attributes = the_attributelist
+
+ if isinstance(the_attributelist, types.ListType):
+ #iterate over all existing attributes and append them to the template-construction-strings
+ for i in attributes:
+ i=i.replace('[','')
+ i=i.replace(']','')
+ i=i.strip()
+ attr_name,attr_type,attr_length=i.split(",")
+ attr_name=attr_name.strip("'")
+ attr_type=attr_type.rstrip("'").lstrip(" '")
+
+ if ((attr_name != 'x') and (attr_name != 'y')) and (attr_name != 'z'):
+ attr_length=attr_length.rstrip("'").lstrip(" '")
+ buildtemplate_template = buildtemplate_template + "(multislot "+ attr_name +")"
+ bashstar_template = bashstar_template + "(multislot "+ attr_name +")"
+ voutascii_columns = voutascii_columns + attr_name + ","
+ attribute_list.append(attr_name)
+
+ if attr_type == 'INTEGER':
+ export_type = 'int'
+ elif attr_type == 'DOUBLE PRECISION':
+ export_type = 'double precision'
+ elif attr_type == 'CHARACTER':
+ export_type = 'varchar('+attr_length+')'
+ else:
+ grass.fatal(_("Unkown attribute type: "+attr_type))
+ else:
+ print ""
+ #print "[grassvector2factlayer] Filtered out: " + attr_name + " " + attr_type
+
+ vinascii_columns = vinascii_columns + " " + attr_name + " " + export_type + ","
+ columns_list.append(attr_name)
+
+ elif isinstance(the_attributelist, types.StringTypes):
+ attributeline=str(attributes).strip("'")
+ attributelist=attributeline.split(',')
+ #^^^ husk single quotes
+
+ for i in attributelist:
+ attr_name,ignore,attr_type = i.strip().partition(" ")
+ attr_name.strip()
+ attr_type.strip()
+ export_type='double precision'
+ #^^^--- fallback option: works for x and y
+ if ((attr_name != 'x') and (attr_name != 'y')) and (attr_name != 'z'):
+ buildtemplate_template = buildtemplate_template + "(multislot "+ attr_name +")"
+ bashstar_template = bashstar_template + "(multislot "+ attr_name +")"
+ voutascii_columns = voutascii_columns + attr_name + ","
+ attribute_list.append(attr_name)
+ if attr_type == 'int':
+ export_type = 'int'
+ elif attr_type == 'double precision':
+ export_type = 'double precision'
+ elif attr_type.startswith('varchar'):
+ #tbd: filter out actual length !!!!!
+ export_type = 'varchar(255)'
+ else:
+ grass.fatal(_("Unkown attribute type:"+attr_type))
+
+ else:
+ grass.message(_(" "))
+ columns_list.append(attr_name)
+
+ vinascii_columns = vinascii_columns + " " + attr_name + " " + export_type + ","
+
+
+ voutascii_columns = voutascii_columns.rstrip(",")
+ #strip trailing comma
+ #-> is needed to assert cector data wird
+
+ vinascii_columns = "'"+vinascii_columns.rstrip(",")+"'"
+ #strip trailing comma and add quotation
+
+ bashstar_template = bashstar_template + ")"
+
+ #Instantiate the new template in PyClips
+ quoted_template = buildtemplate_template
+
+ the_new_template = GLOBAL_CLIPS__ENVIRONMENT.BuildTemplate(the_vector,quoted_template,"GRASS VECTOR")
+
+ #Instantiate the new template in Clips
+ prelude_upload(bashstar_template)
+ # !!! REFACTORING: prelude_upload uses a write to tempfile approach. Better alternative: Use the here document function !
+
+ global_layers_template_put(the_vector,the_new_template)
+ global_layers_vector_vinascii_put(the_vector,vinascii_columns)
+ global_layers_vector_columns_put(the_vector,columns_list)
+
+ return voutascii_columns,attribute_list
+
+
+
+def grassvector2factlayer_internal(the_vector):
+ """! Internal Version: Import a GRASS vector and create a custom fact-template according to the vectors database attributes"""
+ grassvector2factlayer(the_vector,vector_get_attribute_structure(the_vector))
+ return True
+
+
+
+def grassvector_KB_load_vector(the_vector):
+ """! Creates a template and asserts the facts for a GRASS vector - to be used with internal knowledgebases """
+ if grassvector_test_valid(thie_vector):
+ if grassvector_ensure_points(thie_vector):
+ assert_vector_metadata(the_vector)
+ print str(vector_get_attribute_structure(the_vector))
+ voutascii_columns,attribute_list = grassvector2factlayer(the_vector, vector_get_attribute_structure(the_vector))
+ grassvector2factlayer_assert(the_vector,voutascii_columns,attribute_list)
+ else:
+ grass.message(_("[grassvector_KB_load_vector]: Unable to open vector map "+this_vector+": The map must contain only points-data. " ))
+ else:
+ grass.message(_("[grassvector_KB_load_vector]: Unable to open vector map "+this_vector+": Invalid vector. " ))
+
+def grassvector_ensure_points(the_vector):
+ """! Checks a GRASS vector layer whether all geometry objects are points. Returns false otherwise """
+#REFACTORING OPPORTUNITY: pipe stuff ...
+ #p = grass.pipe_command('v.info',flags='t',map=the_vector, quiet='TRUE')
+ #result = {}
+ #count = 0
+ #vinfo={}
+ #for line in p.stdout:
+ # the_line = line.strip().split("=")
+ # vinfo[the_line[0]]=the_line[1]
+ vinfo = grass.vector_info_topo(the_vector)
+ points_count=vinfo['points']
+ primitives_count=vinfo['primitives']
+ if points_count == primitives_count:
+ return True
+ else:
+ return False
+
+def grassvector_test_3d(the_vector):
+ """! Tests a GRASS vector layer for the 3d attribute (-> z column exists) . Returns false otherwise """
+ vinfo = grass.vector_info_topo(the_vector)
#grass_message("GRASSVECTOR_TEST_3D: " + str(the_vector) + " " + str(vinfo))
- is_map3d = vinfo['map3d']
-
- #[grassvector_test_3d]:{'kernels': 0, 'lines': 0, 'centroids': 0, 'boundaries': 0, 'points': 25, 'faces': 0, 'primitives': 25, 'islands': 0, 'nodes': 25, 'map3d': False, 'areas': 0}
-
- if (str(is_map3d) == "False"):
- return False
- else:
- return True
- #Important: False can indicate a broken vector topology !
- #Criteria: A vector lacking any nodes would be inavlid
-
-def grassvector_test_valid(the_vector):
- """! Tests a GRASS vector layer for the 3d attribute (-> z column exists) . Returns false otherwise """
-
- vinfo = grass.vector_info_topo(the_vector)
- if 'nodes' in vinfo:
- return True
- else:
- grass.message(_("grassvector_test_valid ERROR: "+ str(the_vector)))
- return False
-
-def grassvector2factlayer_assert(the_vector,voutascii_columns,attribute_list):
- """! Asserts facts for a GRASS vector via v.out.ascii (after the custom template for the vector has been previously defined) """
- #GRASS String attributes concatining whitespaces are correctly asserted.
- p = grass.pipe_command('v.out.ascii',columns=voutascii_columns,input=the_vector, quiet='TRUE')
- result = {}
- count = 0
- for line in p.stdout:
- count = count + 1
- the_line = line.strip().split("|")
- to_assert="(" + the_vector + " "
- for index in range(len(attribute_list)):
- if not attribute_list[index] == "numcat":
- # numcat is a workaround for the dual cat provision by v.out.ascii
- # it is filtered out as it is not defined (or used) in the template defined above..
- to_assert=to_assert+"("+attribute_list[index]+" "+the_line[index] + ")"
- to_assert=to_assert+" )"
- GLOBAL_CLIPS__ENVIRONMENT.Assert(to_assert)
-
-
-def vector_get_attribute_structure(the_vector):
- """! Return attribute structure of a vector"""
- dbdescribe = grass.db_describe(the_vector)
- #ingest the attribute structure information
- line = str(dbdescribe).strip("{}")
- nrows,ignore,cdrline = line.partition(",")
- cdrline,ingore,ncols = cdrline.rpartition(",")
- ignore,ignore,attributes = cdrline.partition(":")
- attributes = attributes.split("],")
- return attributes
-
-
-
-########################################################################
-#### SET VECTOR METADATA FACTS
-########################################################################
-
- #grass.vector_columns('soils')
-
- #grass.vector_db('soils')
- # Prints the database connection
-
- #grass.vector_db_select('soils')
- # Prints the range of existing values.
-
- #grass.db_describe('soils')
- # Describes the attribute table
- # >> grass.db_describe('soils')
- # >> {'nrows': 54, 'cols': [['cat', 'INTEGER', '11'], ['label', 'CHARACTER', '13']], 'ncols': 2}
- # !!! For type CHAR the maximum string length is returned.
-
-
-def assert_vector_metadata(thevector):
- """!Assert the metadata for a GRASS vector layer as facts in the CLIPS environment
- #grass.vector_info_topo('soils')
- # Lists, numbers of Boundaries, Points, Primitives, Islands, Lines, Centroids, Nodes
- """
- if grassvector_test_valid(thevector):
-
- topology = grass.vector_info_topo(thevector)
- topo_nodes = topology['nodes']
- topo_points = topology['points']
- #topo_lines = topology['lines']
- #topo_boundaries = topology['boundaries']
- #topo_centroids = topology['centroids']
- #topo_areas = topology['areas']
- #topo_islands = topology['islands']
- #topo_faces = topology['faces']
- #topo_kernels = topology['kernels']
- topo_primitives = topology['primitives']
- topo_map3d = topology['map3d']
- assert_t_nodes = "( TOPOLOGY_NODES " + thevector +" " + str(topo_nodes) + " )"
- assert_t_points = "( TOPOLOGY_POINTS " + thevector +" " + str(topo_points) + " )"
- #assert_t_lines = "( TOPOLOGY_LINES " + thevector +" " + str(topo_lines) + " )"
- #assert_t_boundaries = "( TOPOLOGY_BOUNDARIES " + thevector +" " + str(topo_boundaries) + " )"
- #assert_t_centroids = "( TOPOLOGY_CENTROIDS " + thevector +" " + str(topo_centroids) + " )"
- #assert_t_areas = "( TOPOLOGY_AREAS " + thevector +" " + str(topo_areas) + " )"
- #assert_t_islands = "( TOPOLOGY_ISLANDS " + thevector +" " + str(topo_islands) + " )"
- #assert_t_faces = "( TOPOLOGY_FACES " + thevector +" " + str(topo_faces) + " )"
- #assert_t_kernels = "( TOPOLOGY_KERNELS " + thevector +" " + str(topo_kernels) + " )"
- assert_t_primitives = "( TOPOLOGY_PRIMITIVES " + thevector +" " + str(topo_primitives) + " )"
- assert_t_map3d = "( TOPOLOGY_MAP3D " + thevector +" " + str(topo_map3d) + " )"
-
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_nodes )
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_points)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_lines)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_boundaries)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_centroids)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_areas)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_islands)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_faces)
- #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_kernels)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_primitives)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_map3d)
-
- #dto:
- dbconnection = grass.vector_db(thevector)
- mymessage="*** vector_dbconncetion = " + str(dbconnection)
- grass.debug(_(mymessage))
-
- columns = grass.vector_columns(thevector)
-
- mymessage="*** vector columns = " + str(columns)
- grass.debug(_(mymessage))
- #?? Is there a similar API interface to v.info -g (vectors region). ??
- else:
- #grass.message(_("g.infer: Something really wrong with vector" + str(thevector)))
- sys.exit(1)
-
-
-
-#######################################################################
-## RASTER IMPORT
-#######################################################################
-
-
-def ingest_facts_rasters(facts_rasters,ignore_raster_labels):
- """! Ingestion of all user-provided GRASS raster layers. Option: Ignore GRASS raster labels"""
- facts_rasters_list=[]
- count_maps = 0
- gisenv = grass.gisenv()
- gisenv_mapset = gisenv['MAPSET']
- for this_facts_raster in str(facts_rasters).split(','):
- grass.debug(_("Ingesting Raster: "+this_facts_raster))
- count_maps = count_maps + 1
-
- #gisenv = grass.gisenv()
- #gisenv_mapset = gisenv['MAPSET']
- #listofmaps=grass.list_grouped('rast')[gisenv_mapset]
- #if (this_facts_raster) not in listofmaps:
- # grass_fatal("g.infer: Raster layer does not exist:" + str(this_facts_raster))
- # sys.exit(1)
-
- import_raster_test(this_facts_raster)
-
- is_elevation_level = False
- facts_rasters_list.append(this_facts_raster)
- grassraster2factlayer(this_facts_raster,"GRASS RASTER",ignore_raster_labels,is_elevation_level)
- return set(facts_rasters_list)
-
-
-
-
-def grassraster2factlayer(the_raster,the_comment_string="GRASS RASTER",ignore_raster_labels=False,elevationlevel=False):
- """! Generate facts from a GRASS raster layer including the coordinates, the digital number AND the value attribute
- test for categories: r.category --quiet geology fs=: 0> 1:metamorphic or 1:
- """
-
- #TO BE INCLUDED:
- ## test for input raster map
- #result = grass.find_file(name = map_name, element = 'cell', quiet = True)
- #if not result['file']
- #grass.fatal("Raster map <%s> not found" % map_name)
-
- #check for category strings:
- raster_with_labels = True
- the_categories = raster_categories(the_raster)
- if len(the_categories) < 1:
- raster_with_labels = False
- # find map in search path
- mapset = G_find_cell2(the_raster, '')
-
- #Attribute recognition doesnt work for rast3d rasters
-
- # determine the inputmap type (CELL/FCELL/DCELL)
- typename = 'undefined'
- data_type = G_raster_map_type(the_raster, mapset)
- if data_type == CELL_TYPE:
- ptype = POINTER(c_int)
- type_name = 'CELL'
- elif data_type == FCELL_TYPE:
- ptype = POINTER(c_float)
- type_name = 'FCELL'
- elif data_type == DCELL_TYPE:
- ptype = POINTER(c_double)
- type_name = 'DCELL'
-
- # construct strings to generate templates both on pyclips and clips level:
-
- buildtemplate_template = "(slot x)(slot y)"
- bashstar_template = "(deftemplate " + the_raster + " (slot x)(slot y)"
-
- attribute_list = []
- attribute_list.append("x")
- attribute_list.append("y")
-
- if elevationlevel:
- buildtemplate_template = buildtemplate_template + "(slot z)"
- bashstar_template = bashstar_template + "(slot z)"
- attribute_list.append("z")
- #Append a column for elevation if this raster layer stems from a rast3d layer, aka has a z-Value constant attached to it
-
- attr_name_value = 'value'
-
- attr_name_attribute = 'attribute'
-
- if type_name == 'CELL':
- export_type_value = 'integer'
- ### UNTESTED !!!!
- else:
- export_type_value = 'double precision'
- ###^^^--- The datdtype is defined below: CELL/FCELL/DCELL -> fix !
-
- #export_type_attribute = "varchar(" + str(GLOBAL_ATTRIBUTE_TYPE) + ")"
-
- # generate low level GRASS structures
-
- infd = G_open_cell_old(the_raster, mapset)
- inrast = G_allocate_raster_buf(data_type)
- inrast = cast(c_void_p(inrast), ptype)
-
- rows = G_window_rows()
- cols = G_window_cols()
-
- hd=struct_Cell_head()
- G_get_cellhd(the_raster,mapset,byref(hd))
-
-
- ###############################
-
- if raster_with_labels and not ignore_raster_labels:
- buildtemplate_template = buildtemplate_template + "(slot "+ attr_name_value +")"+ "(multislot "+ attr_name_attribute +")"
- bashstar_template = bashstar_template + "(slot "+ attr_name_value +")" + "(multislot "+ attr_name_attribute +")"+")"
- attribute_list.append(attr_name_value)
- attribute_list.append(attr_name_attribute)
- else:
- buildtemplate_template = buildtemplate_template + "(slot "+ attr_name_value +")"
- bashstar_template = bashstar_template + "(slot "+ attr_name_value +") )"
- attribute_list.append(attr_name_value)
-
-
- #Instantiate the new template in PyClips
- the_new_template = GLOBAL_CLIPS__ENVIRONMENT.BuildTemplate(the_raster,buildtemplate_template,the_comment_string)
- #Instantiate the new template in Clips
- prelude_upload(bashstar_template)
-
- for rown in xrange(rows):
- therow = G_get_raster_row(infd, inrast, rown, data_type)
-
- for coln in xrange(cols):
- coo_col = G_col_to_easting(coln, byref(hd))
- coo_row = G_row_to_northing(rown, byref(hd))
- the_value=inrast[coln]
- fallback=''
- the_category=the_categories.get(str(the_value),fallback)
- to_assert = "(" + the_raster + " (x " + str(coo_col) + ") (y " + str(coo_row) + ")"
- if elevationlevel:
- to_assert = to_assert + "(z "+ str (elevationlevel) + ")"
-
- to_assert = to_assert + "(value " + str(the_value) + ")"
- if raster_with_labels and not ignore_raster_labels:
- to_assert = to_assert + "(attribute " + str(the_category) + ")"
-
- to_assert = to_assert + ")"
- GLOBAL_CLIPS__ENVIRONMENT.Assert(to_assert)
-
- G_close_cell(infd)
- G_free(inrast)
-
- global_layers_template_put(the_raster,the_new_template)
- global_layers_raster_type_put(the_raster,type_name)
-
- return
-
-
-def grassraster_KB_load_raster(the_raster):
- """! Creates a template and asserts the facts for a GRASS raster - to be used with internal knowledgebases """
- ### !!! Requires a failsafe to test whether the layer exists at all !
- is_elevation_level = False
- ignore_raster_labels = FALSE
- #facts_rasters_set = set(facts_rasters_list.append(the_raster))
- #^^ is only set otherwise during explicit raster upload in MAIN.
- # !!!allow for update option
- grassraster2factlayer(the_raster,"GRASS RASTER",ignore_raster_labels,is_elevation_level)
-
-
-########################################################################
-#### RASTER METADATA FACTS
-########################################################################
-
-#TBD: Provide the metadata for a GRASS raster as CLIPS facts for use in the inference process.
-
-
-# grass.raster_info
-# grass.raster_history
-
-# tbd: Actual region/coverage a raster layer: r.region
-# tbd: r.support
-# tbd: stats: r.median, r.quantile, r.statistics, r.univar
-# tbd: number format (integer, floats, etc)
-# r.info ?
-
-
-#######################################################################
-## VOLUME IMPORT
-#######################################################################
-
-
-def ingest_factsraster3ds(facts_raster3ds):
- """! Ingestion of all user-provided GRASS raster3D (volume) layers"""
- facts_raster3ds_list=[]
- count_maps = 0
-
- for this_facts_raster3d in str(facts_raster3ds).split(','):
- grass.message(_("Ingesting Raster3D: "+this_facts_raster3d))
- import_rast3d_test(this_facts_raster3d)
- #listofmaps=grass.list_grouped('rast3')[gisenv_mapset]
- #if (this_facts_raster) not in listofmaps:
- # grass_fatal("g.infer: Raster layer does not exist:" + str(this_facts_raster))
- # sys.exit(1)
- count_maps = count_maps + 1
- facts_raster3ds_list.append(this_facts_raster3d)
- grassvolume2factlayer(this_facts_raster3d)
- return set(facts_raster3ds_list)
-
-
-
-def grassvolume2factlayer(the_volume):
- """! Generate facts from a GRASS volume layer including the 3d coordinates and the digital number"""
- the_raster = str(the_volume)+"_slice_"
-
- #the_layers_template = global_layers_template_get(the_volume)
-
- #layers_raster_type = global_layers_raster_type_get(the_volume)
-
- #global_layers_rast3d_slices_get(the_volume)
-
- p = grass.pipe_command('r3.to.rast',flags='rm',input=the_volume, output=the_raster.rstrip("_"), quiet='TRUE')
- # tbd: replace the_raster by a randomly generated name.
-
- grass.debug("grassvolume2factlayer: Sleeping 10 sec")
- time.sleep(10)
- #SLEEP to ensure that the pipe returns in time. This is ugly and need to be improved.
- # get height of layerstack
- region = region3()
- stack_height=region['depths']
- stack_res=region['tbres']
-
- this_raster3d_raster_slices_list = []
- #create a container for all raster_file_names for this raster3d volume
-
- #ITERATE OVER THE stack of raster layerswhich were creared
- for level in range(1, int(stack_height)):
- if level < 10:
- levelstring="0000"+str(level)
- elif level < 100:
- levelstring="000"+str(level)
- elif level < 1000:
- levelstring="00"+str(level)
- elif level < 10000:
- levelstring="0"+str(level)
- current_raster=the_raster+levelstring
- #^^ use the real elevations ( not the levels) level*elevationelta=ELEVATIONVARIABLE
-
-
- grass.debug("Raster-Level: "+current_raster)
- this_raster3d_raster_slices_list.append(current_raster)
- this_elevation=stack_res * level
- the_ignore_label_flag = True
- #the_template,raster_type = grassraster2factlayer(current_raster,"GRASS VOLUME",the_ignore_label_flag,this_elevation)
-
- #the_layers_template[current_raster]=the_template
- #layers_raster_type[current_raster]=raster_type
- grassraster2factlayer(current_raster,"GRASS VOLUME",the_ignore_label_flag,this_elevation)
-
- ###^^ to be returned !
- #global_layers_template_put(the_volume,the_layers_template)
-
- #global_layers_raster_type_put(the_volume,layers_raster_type)
-
- global_layers_rast3d_slices_put(the_volume,this_raster3d_raster_slices_list)
-
- #return the_layers_template, layers_raster_type, this_raster3d_raster_slices_list
-
-
-
-def grassvolume2factlayer_internal(the_volume):
- """! Internal Use: Generate facts from a GRASS volume layer including the 3d coordinates and the digital number"""
- grassvolume2factlayer(the_volume)
-
-########################################################################
-#### VOLUME METADATA FACTS
-########################################################################
-
-#TBD: Provide the metadata for a GRASS raster3D volume as CLIPS facts for use in the inference process.
-
-# r3.timestamp
-# r3.stats
-# r3.univar
-
-
-
-
-##############################################################
-##############################################################
-##############################################################
-##############################################################
-##############################################################
-##############################################################
-## METADATA
-##############################################################
-##############################################################
-
-##########################################################
-## GRASS SESSION METADATA to FACTS
-##########################################################
-
-def assert_region():
- """! Creates facts for all GRASS region parameters"""
- region = region3()
- region_rows = region['rows']
- region_cols = region['cols']
- region_cells = region['cells']
- region_ewres = region['ewres']
- region_nsres = region['nsres']
- region_n = region['n']
- region_s = region['s']
- region_e = region['e']
- region_w = region['w']
-
- # Accomodate for 3D region parameters:
- region_t = region['t']
- region_b = region['b']
- region_tbres = region['tbres']
- region_ewres3 = region['ewres3']
- region_nsres3 = region['nsres3']
- region_rows3 = region['rows3']
- region_cols3 = region['cols3']
- region_depths = region['depths']
- region_cells3 = region['cells3']
-
-
- assert_region_rows = "( REGION_ROWS " + str(region_rows) + " )"
- assert_region_cols = "( REGION_COLS " + str(region_cols) + " )"
- assert_region_cells = "( REGION_CELLS " + str(region_cells) + " )"
- assert_region_ewres = "( REGION_EWRES " + str(region_ewres) + " )"
- assert_region_nsres = "( REGION_NSRES " + str(region_nsres) + " )"
- assert_region_n = "( REGION_N " + str(region_n) + " )"
- assert_region_s = "( REGION_S " + str(region_s) + " )"
- assert_region_e = "( REGION_E " + str(region_e) + " )"
- assert_region_w = "( REGION_W " + str(region_w) + " )"
-
- # Region 3D parameters:
- assert_region_rows3 = "( REGION_ROWS3 " + str(region_rows3) + " )"
- assert_region_cols3 = "( REGION_COLS3 " + str(region_cols3) + " )"
- assert_region_cells3 = "( REGION_CELLS3 " + str(region_cells3) + " )"
- assert_region_ewres3 = "( REGION_EWRES3 " + str(region_ewres3) + " )"
- assert_region_nsres3 = "( REGION_NSRES3 " + str(region_nsres3) + " )"
- assert_region_tbres = "( REGION_TBRES " + str(region_tbres) + " )"
- assert_region_t = "( REGION_T " + str(region_t) + " )"
- assert_region_b = "( REGION_B " + str(region_b) + " )"
- assert_region_depths = "( REGION_DEPTHS " + str(region_depths) + " )"
-
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_rows)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cols)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cells)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_nsres)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_ewres)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_n)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_s)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_e)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_w)
-
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_rows3)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cols3)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cells3)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_nsres3)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_ewres3)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_tbres)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_t)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_b)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_depths)
-
-
-
-def assert_gisenv():
- """!Assert all GRASS environmental variables (GISENV / Location / Mapset) as facts in the CLIPS environment"""
- gisenv = grass.gisenv()
- gisenv_gisdbase = gisenv['GISDBASE']
- gisenv_location_name = gisenv['LOCATION_NAME']
- gisenv_mapset = gisenv['MAPSET']
- gisenv_grass_gui = gisenv['GRASS_GUI']
-
- assert_gisdbase = "( GISDBASE " + gisenv_gisdbase + " )"
- assert_location_name = "( LOCATION_NAME " + gisenv_location_name + " )"
- assert_mapset = "( MAPSET " + gisenv_mapset + " )"
- assert_grass_gui= "( GRASS_GUI " + gisenv_grass_gui + " )"
-
- # More variables to be included !
-
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_gisdbase)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_location_name)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_mapset)
- GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_grass_gui)
-
-
-
-
-########################################################################
-#### GRASS7 TEMPORAL METADATA FACTS
-########################################################################
-
-# tbd: no python support yet
-
-########################################################################
-#### DATABASE CONNECTIVITY METADATA FACTS
-########################################################################
-
-#TBD: Integrate this metadata as CLIPS facts for use in the inference process.
-
-# grass.db_connection
-# grass.db_describe
-# grass.db_select
-
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## EXPORT from CLIPS constructs to GRASS layers
-##########################################################################
-##########################################################################
-
-
-# Export sanity checks needed ?
-
-
-def fact2rastercell(afact,raster_name,integer_case):
- """! Returns for a (raster-) fact the structured content of a GRASS - raster cell"""
- the_x = float(afact.Slots['x'])
- the_y = float(afact.Slots['y'])
- if integer_case:
- the_value = int(afact.Slots['value'])
- else:
- the_value = float(afact.Slots['value'])
- ###^^ not everything is FLOAT !
-
- if 'attribute' in afact.Slots.keys():
- #the_attribute=afact.Slots['attribute']
- #alternative to deal with multiple string content - works for vector, untested here.
- the_attribute=""
- multifield_list = afact.Slots['attribute']
- allitems=""
- for item in multifield_list:
- the_attribute=the_attribute + str(item).rstrip() + " "
- the_attribute.rstrip(" ")
- else:
- the_attribute=False
-
- if 'z' in afact.Slots.keys():
- the_elevation = float(afact.Slots['z'])
- else:
- the_elevation=False
- return the_x,the_y,the_value,the_attribute,the_elevation
-
-#######################################################################
-## RASTER EXPORT
-#######################################################################
-
-def factslayer_fromraster2grassraster_internal(rastername,ignore_labels=False):
- """! Internal Use: Exports a grassraster facts to GRASS vector (point) layer which are transformed into a GRASS raster layer"""
- factslayer_fromraster2grassraster(rastername,ignore_labels,False)
-
-
-def factslayer_fromraster2grassraster(rastername,ignore_labels=False,raster_type=False):
- """! Exports a grassraster facts to GRASS vector (point) layer which are transformed into a GRASS raster layer"""
- ### tbd: take care of Z-column for rast3d !
-
- ### start a dictionary to track all attribute/value pairs
-
-# global layers_template
- thetemplate = global_layers_template_get(rastername)
- raster_type = global_layers_raster_type_get(rastername)
-
-# test: if exists: use ELSE: False
- layers_raster_type[rastername] = raster_type
- #??? is this the right ordering ?
-
- attribute_dict = {}
-
- #Check for number types:
- if raster_type:
- if raster_type == "CELL":
- integer_case = TRUE
- grass.debug("[factslayer_fromraster2grassraster] INTEGER LIKE INPUT MAP")
- else:
- integer_case = FALSE
- grass.debug("[factslayer_fromraster2grassraster] FLOAT LIKE INPUT MAP")
- # we don't care what kind of float it is
- else:
- # no raster type provided, we must check the facts to figure it out.
- grass.message("[factslayer_fromraster2grassraster] No raster map type defined: PROBING FACTS TO DEFINE OUTPUT MAP TYPE")
- integer_case = facts_all_integer(thetemplate,'value')
-
- #define array to collect random access info from facts
- if integer_case:
- raster_output = garray.array(dtype=numpy.int32)
- grass.debug("[factslayer_fromraster2grassraster] Integer Array")
- else:
- grass.debug("[factslayer_fromraster2grassraster] Float Array")
- raster_output = garray.array()
-
- #### GRASS LOW LEVEL COMMANDS start here
- #setup GRASS helpers to transform coordinates into columns and rows.
- mapset = G_find_cell2(rastername, '')
- hd=struct_Cell_head()
- G_get_cellhd(rastername,mapset,byref(hd))
-
- thisfact = fact_first(thetemplate)
-
- if thisfact:
- now_x,now_y,now_value,now_attribute,now_elevation = fact2rastercell(thisfact,rastername,integer_case)
- # now_elevation is currently not used further.
- # the z-component is ignored -> the z/level info is also part of the template name.
- coo_col = int(G_easting_to_col(now_x, byref(hd)))
- coo_row = int(G_northing_to_row(now_y, byref(hd)))
- if now_attribute:
- attribute_dict.update({str(now_attribute):now_value})
- # push attribute into attribute dictionary if is does not exist yet.
- if integer_case:
- raster_output[coo_row,coo_col] = numpy.int32(now_value)
- else:
- raster_output[coo_row,coo_col] = float(now_value)
-
- count = 1
- carry_on = 1
-
- while carry_on:
- count = count +1
- thisfact = fact_next(thetemplate, thisfact)
- if thisfact:
- now_x,now_y,now_value,now_attribute,now_elevation = fact2rastercell(thisfact,rastername,integer_case)
- coo_col = int(G_easting_to_col(now_x, byref(hd)))
- coo_row = int(G_northing_to_row(now_y, byref(hd)))
- if now_attribute:
- attribute_dict.update({str(now_attribute):now_value})
- if integer_case:
- raster_output[coo_row,coo_col] = numpy.int32(now_value)
- else:
- raster_output[coo_row,coo_col] = float(now_value)
- else:
- carry_on = 0
- #!!! coordinate skew is still there !: add +0.5 ?
-
- # Remove previous version of layer in GRASS domain:
- grass.run_command('g.remove', rast=rastername, quiet='TRUE')
-
- #write changed raster out
- raster_output.write(rastername)
-
- #writeout attributes if any exist
- if attribute_dict.keys():
- grassfeed = grass.feed_command("r.category",rules='-',map=rastername, quiet='TRUE')
- for key in attribute_dict.keys():
- this_attribute = str(int(attribute_dict[key])) + ":" + str(key)+"\n"
- grassfeed.stdin.write(this_attribute)
- grassfeed.stdin.close()
-
- #get rid of NULL values (untested) #FACTNULL ist der UGLY interne Wert !
- grass.run_command('r.null', map=rastername, setnull=FACT_NULL, quiet='TRUE')
-
- #IF INTEGER: ^^^^
- # IF FLOAT: Handle * => nan case for NULL value
-
-
-
-########################################################################
-####VECTOR EXPORT
-########################################################################
-
-
-
-def vector_facts2grassvector_string(afact,thecolumnslist):
- """!Builds and returns a GRASS-formatted string from the facts associated to a GRASS vector """
- #(grassraster (name foo) (x 596203) (y 4915149)(hanni 42)(nanni 43))
-
- myresult = str(afact.Slots['x'])+"|"+ str(afact.Slots['y'])
- multifield_list = list()
- #^^dummy-define variable for later use
-
- for column in thecolumnslist:
- if (column != 'x')and( column !='y'):
- multifield_list = afact.Slots[column]
- allitems=""
- if (len(multifield_list) > 0):
- for item in multifield_list:
- allitems=allitems + str(item).rstrip() + " "
- myresult = myresult+"|"+ allitems.rstrip(" ")
-
- grass.debug(_("vector_facts2grassvector_string:" + myresult))
- myresult = myresult + "\n"
- return myresult
-
-
-def factslayer2grassvector_internal(vectorname):
- """! Internal Use: Creates a GRASS vector from a factslayer"""
- factslayer2grassvector(vectorname)
- # ^^^Untested !
-
-
-
-def factslayer2grassvector(vectorname):
- """! Creates a GRASS vector from a factslayer"""
- #!! To be considered: Shall the name of a newly to be created output vector is to be included ?
- #
-
- #!! In case that a OUTPUT layer has been created with COLUMNS, but remains empty:
- # v.in.ascii -e creates only an empty layer.
- count = 0
- thetemplate = global_layers_template_get(vectorname) # --> Could cause a problem in a "new vector (Xanadu)" case. Otherwise: optional argument ?
- the_columns = global_layers_vector_vinascii_get(vectorname)
- the_columns_list = global_layers_vector_columns_get(vectorname)
- #complete_columns= cat_filter('x double precision, y double precision,' + the_columns.strip("\'"))
- #^^^ original version: assumes that x/y columns are NOT provided by the user.
- complete_columns= cat_filter('' + the_columns.strip("\'"))
- # works for now ^^^
- #20120508: This must be discussed:
- # is it a good thing if the user has to define X and Y columns when entering the columns-description ?
- # con: x/X y/Y can be misleading -> internal import assumes that x/y are the needed coordinates.
- #!!!
- #print str(vectorname) +" Facts => "+str(facts_total(thetemplate))
- if (facts_total(thetemplate) < 1):
- # ^^^^FACTS_TOTAL needs a FAILSAFE for the NULL case !
- #g.message(_("Export stopped: No facts found for export vector: " + the_template))
- grass.message(_("[factslayer2grassvector]: No facts found for export vector: " + str(vectorname) + " --> EMPTY VECTOR CREATED"))
- grass.run_command("v.in.ascii","e",input='-',output=vectorname, x=1, y=2, columns=complete_columns, overwrite='True', quiet='TRUE')
-
- else:
- mystring = str(vectorname) + "-facts-count: "+ str(facts_total(thetemplate))
- #g.message(_("Export continues: " + mystring))
- grassfeed = grass.feed_command("v.in.ascii",input='-',output=vectorname, x=1, y=2, columns=complete_columns, overwrite='True', quiet='TRUE')
-
-
- firstfact = fact_first(thetemplate)
- thisfact = firstfact
- if thisfact:
- carry_on = 1
- grassfeed.stdin.write(vector_facts2grassvector_string(firstfact,the_columns_list))
- count = 1
- while carry_on:
- count = count +1
- thisfact = fact_next(thetemplate, thisfact)
- if thisfact:
- grassfeed.stdin.write(vector_facts2grassvector_string(thisfact,the_columns_list))
- else:
- carry_on = 0
- grassfeed.stdin.close()
- return count
-
-#######################################################################
-## VOLUME EXPORT
-#######################################################################
-
-### !!! The foofact.Slot.keys() mechanism allows to check whether a Z-value exists
-### -> for now none is handed over.
-### Volume import/export could not be achieved via 2D rasters otherwise.
-
-def factslayer_fromraster3d2grassraster3d_internal(the_inference_map):
- """! Internal USe: Update an existing GRASS volume layer from its CLIPS facts representation"""
- factslayer_fromraster3d2grassraster3d(the_inference_map)
-# ^^ UNTESTED !
-
-
-def factslayer_fromraster3d2grassraster3d(the_inference_map):
- """! Update an existing GRASS volume layer from its CLIPS facts representation"""
- # for each item in the slices list:
- # get the corresponding template from the vinasciss/templates list
- # launch GRASSRASTER generation processess
- # bundle rasters into a raster3d
-
- #global_layers_raster_type_get(the_volume)
- # shouldn't this one be handed over, too ?
-
- the_slices_list = global_layers_rast3d_slices_get(the_inference_map)
- slices_list_string=""
- for this_slice in the_slices_list:
- layers_templates = global_layers_template_get(this_slice)
- slices_list_string=slices_list_string+","+str(this_slice)
- #generate raster slice:
- factslayer_fromraster2grassraster(this_slice,False)
-
- slices_list_string.lstrip(',')
- #^^^remove leading comma
- p = grass.pipe_command('r.to.rast3',input=slices_list_string, output=the_inference_map, quiet='TRUE', overwrite='TRUE')
-
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## CLIPS Engine Settings
-##########################################################################
-##########################################################################
-
-#######################################################################
-## CLIPS Save options for knowledge items
-
-
-def clips_save(inference_map,save_option):
- """! Write CLIPS information to file"""
-
- if save_option.find("facts") > -1:
- grass.debug(_("SAVE: Facts"))
- forensics_facts=inference_map+"_facts.clips"
- GLOBAL_CLIPS__ENVIRONMENT.SaveFacts(forensics_facts)
-
- if save_option.find("constructs") > -1:
- grass.debug(_("SAVE: Constructs"))
- forensics_constructs=inference_map+"_constructs.clips"
- GLOBAL_CLIPS__ENVIRONMENT.Save(forensics_constructs)
-
- if save_option.find("instances") > -1:
- grass.debug(_("SAVE: Instances"))
- forensics_instances=inference_map+"_instances.clips"
- GLOBAL_CLIPS__ENVIRONMENT.SaveInstances(forensics_instances)
-
-def clips_bsave(inference_map,save_option):
- """! Write CLIPS information to file"""
- binary_export = 0
-
- if save_option.find("facts") > -1:
- grass.debug(_("BSAVE: Facts"))
- forensics_facts=inference_map+"_facts.clips"
- GLOBAL_CLIPS__ENVIRONMENT.SaveFacts(forensics_facts)
-
- if save_option.find("constructs") > -1:
- grass.debug(_("BSAVE: Constructs"))
- forensics_constructs=inference_map+"_constructs.bin"
- GLOBAL_CLIPS__ENVIRONMENT.BSave(forensics_constructs)
-
- if save_option.find("instances") > -1:
- grass.debug(_("BSAVE: Instances"))
- forensics_instances=inference_map+"_instances.bin"
- GLOBAL_CLIPS__ENVIRONMENT.BSaveInstances(forensics_instances)
-
-#######################################################################
-## CLIPS Set Config
-
-def clips_config(config_option):
- """! Set CLIPS engine config-setting"""
- config_string = "auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset- globals,sequence-operator-recognition,static-constraint-checking"
- config_list = str(config_string).split(',')
- for item in config_list:
- if watch_option.find(item) > -1:
- grass.message(_("(set-"+str(item)+" TRUE )"))
- now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-"+str(item)+" TRUE )")
-
-#######################################################################
-## CLIPS Set Watch
-
-def clips_watch(watch_option):
- """! Set CLIPS engine watch-setting"""
- watch_string = "activations,compilations,facts,functions,genericfunctions,globals,methods,messagehandlers,messages,rules,slots,statistics,all"
- watch_list = str(watch_string).split(',')
- for item in watch_list:
- if watch_option.find(item) > -1:
- grass.message(_("(watch "+ str(item)+" )"))
- now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(watch "+ str(item)+" )")
-
-#######################################################################
-## CLIPS Set list
-
-def clips_list(list_option):
- """! Set CLIPS engine option-settings"""
- if list_option.find("agenda") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintAgenda()
- if list_option.find("breakpoints") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintBreakpoints()
- if list_option.find("classes") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintClasses()
- if list_option.find("deffacts") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintDeffacts()
- if list_option.find("definstances") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintDefinstances()
- if list_option.find("facts") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintFacts()
- if list_option.find("focusstack") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintFocusStack()
- if list_option.find("functions") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintFunctions()
- if list_option.find("generics") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintGenerics()
- if list_option.find("globals") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.ShowGlobals()
- #"show" display the variables AND their values
- if list_option.find("instances") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintInstances()
- if list_option.find("messagehandlers") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintMessagehandlers()
- if list_option.find("modules") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintModules()
- if list_option.find("rules") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintRules()
- if list_option.find("templates") > -1:
- GLOBAL_CLIPS__ENVIRONMENT.PrintTemplates()
-
-#######################################################################
-## CLIPS Set dribble
-
-def clips_dribble(inference_map,toggle_dribble):
- """! Set CLIPS engine dribble-setting"""
- if toggle_dribble:
- grass.message(_("(dribble-on "+str(inference_map)+".dribble )"))
- now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(dribble-on "+str(inference_map)+".dribble )")
-
-
-#######################################################################
-## CLIPS Set external traceback
-
-def clips_external_traceback(toggle_external_traceback):
- """! Toggle CLIPS engine traceback-setting"""
- if toggle_external_traceback:
- clips.SetExternalTraceback(True)
- #WORKS: confirmed 20120302
-
-#######################################################################
-## CLIPS Module stack seeding
-
-def clips_module_stack(inference_focus_module):
- """! Set CLIPS engine focus-setting on a specific KB module"""
- if inference_focus_module:
- #iterate over comma seperated inference_focus_module AAA,BBB,CCCC and build up "focus AAA BBB CCC" string.
- grass.message(_("clips_module_stack: Under development"))
- clips.PrintFocusStack()
- ### clips command: (focus AAA BB CC)
- focus = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(focus AAA BBB CCC )")
-
-
- #FindModule($modulename) !! - finds an existing module
- # BuildModule
- #popFocus
- #printFocusStack
- #
- #clips.SetCurrent() / SetFocus / PopFocus
- #CLIPS: (list-focus-stack) (clear-focus-stack) (focus fi fa fo)
- #tbd: strip string "inference_focus_module" off commata ("A,B,C") -> "A B C" and assign GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(focus "+str(STTINGSANSCOMMATA)+".dribble )")
- else:
- grass.message(_("CLIPS_MODULE_STACK => ELSE:this should not happen"))
-
-#######################################################################
-## CLIPS Set class-default
-
-def clips_classdefault(classdefault_option):
- """! Set CLIPS engine class-default-setting"""
- #(set‑class-defaults-mode <mode>)
- if classdefault_option.find("convenience") > -1:
- now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("( set‑class-defaults-mode convenience)")
- if classdefault_option.find("conservation") > -1:
- now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("( set‑class-defaults-mode conservation)")
-
-
-#######################################################################
-###########SET DEBUG SETTING#########################
- ###?? GLOBAL_CLIPS__ENVIRONMENT.Memory[Options] Object P42 pyclips manual
-
- #CLIPS Debug Settings which could be provided to the user for forensics.
-
- # Conserve: TRUE / False
- # EnvironmentErrosEnabled
- # Free()
- # PPBuffersize
- # Requests: readonly!
- # Used: readonly !
- # NumberOffEnvironmenst
-
-
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## INFERENCE RUN
-##########################################################################
-##########################################################################
-
-
-##########################################################
-# Interactive mode.
-# code snippet adapted from http://pyclips.sourceforge.net/web/?q=node/19 author: franzg
-##########################################################
-
-# Description: TBD
-
-# needed: uo/down keys to navigate a history similar to the bash shell history.
-
-class interactive_shell(object):
- """an interactive CLIPS prompt activated via the i-Flag"""
-
- def __init__(self):
- self.__ps1 = "g.infer CLIPS prompt[%(cmdno)s/%(lineno)s] (Exit: Ctrl-D)> "
- self.__ps2 = "g.infer CLIPS prompt[%(cmdno)s/%(lineno)s] (Exit: Ctrl-D): "
- self.__cmdno = 1
- self.__lineno = 1
-
- def __cmdcomplete(self, cms):
- """check if CLIPS command is complete (stolen from 'commline.c')"""
- def eat_ws(s, i):
- """eat up whitespace"""
- while i < len(s) and s[i] in _string.whitespace: i += 1
- return i
- def eat_string(s, i):
- """eat up strings"""
- if s[i] != '"' or i >= len(s): return i
- i += 1
- while i < len(s):
- if s[i] == '"': return i + 1
- else:
- if s[i] == '\\': i += 1
- i += 1
- if i > len(s): raise ValueError, "non-terminated string"
- return i
- def eat_comment(s, i):
- """eat up comments"""
- if s[i] != ';' or i >= len(s): return i
- while i < len(s) and s[i] not in '\n\r': i += 1
- return i + 1
- s = cms.strip()
- if len(s) == 0: return False
- depth = 0
- i = 0
- while i < len(s):
- c = s[i]
- if c in '\n\r' and depth == 0: return True
- elif c == '"': i = eat_string(s, i)
- elif c == ';': i = eat_comment(s, i)
- elif c == '(': depth += 1; i += 1
- elif c == ')': depth -= 1; i += 1
- elif c in _string.whitespace: i = eat_ws(s, i)
- else: i += 1
- if depth < 0: raise ValueError, "invalid command"
- if depth == 0: return True
- else: return False
-
- def Run(self):
- """start or resume an interactive CLIPS shell"""
- exitflag = False
- while not exitflag:
- self.__lineno = 1
- s = ""
- dic = { 'cmdno': self.__cmdno, 'lineno': self.__lineno }
- prompt = self.__ps1 % dic
- try:
- while not self.__cmdcomplete(s):
- if s: s += " "
- s += raw_input(prompt).strip()
- self.__lineno += 1
- dic = { 'cmdno': self.__cmdno, 'lineno': self.__lineno }
- prompt = self.__ps2 % dic
- except ValueError, e:
- sys.stderr.write("[SHELL] %s\n" % str(e))
- except EOFError:
- clips.ErrorStream.Read()
- exitflag = True
- # tbd: allow also an "graceful" exit using a (exit) command!
- try:
- if not exitflag:
- GLOBAL_CLIPS__ENVIRONMENT.SendCommand(s, True)
- except clips.ClipsError, e:
- sys.stderr.write("[PYCLIPS] %s\n" % str(e))
- self.__cmdno += 1
- r0 = clips.StdoutStream.Read()
- r1 = clips.DisplayStream.Read()
- tx = clips.TraceStream.Read()
- r = ""
- if r0: r += r0
- if r1: r += r1
- t = clips.ErrorStream.Read()
- if r: r = "%s\n" % r.rstrip()
- if t: t = "%s\n" % t.rstrip()
- if tx: t = "%s\n" % tx.rstrip() + t
- #^^^2013_Feb19: This throws an error if WATCH is not set:
- # TypeError: cannot concatenate 'str' and 'NoneType' objects
-
-
- if t: sys.stderr.write(t)
- if r: sys.stdout.write(r)
-
-##########################################################################
-# CLI Interface code
-# taken from http://commentsarelies.blogspot.de/2008/07/using-printout-and-readline-in-pyclips.html
-# Author: Johan Lindberg, 2008-07-14
-
-# Description: code to provide an interactive CLIPS shell for g.infer sessions.
-
-def pyprintout(*args):
- """! TBD"""
- for arg in args[1]:
- if arg.cltypename().upper() == "SYMBOL":
- if arg.upper() == "CRLF":
- print
- elif arg.upper() == "TAB":
- print "\t",
- else:
- print arg,
-
- else:
- print arg,
-
-
-def pyreadline(*args):
- """! TBD"""
- return raw_input()
-
-def pyread(*args):
- """! TBD"""
- return raw_input()
-
-#######################################################################
-## CLIPS LAYER BATCHSTAR SEEDING
-
-
-def prelude_upload(the_string):
- """! CReate a tempfile on the GRASS_level,and announce this file at the CLIPS level for BatchSTar usage?"""
- #generate prelude for batchstar and write it out to a tempfile
- tempfile = grass.read_command('g.tempfile',pid=random.randint(1,1000000))
- file = open(tempfile, 'w')
- file.write(the_string)
- file.close()
- # Make the template definitions available on the BatchStar level.
- GLOBAL_CLIPS__ENVIRONMENT.BatchStar(tempfile)
- # Remove the template
- os.remove(tempfile)
-
-
-#######################################################################
-## Set CLIPS engine options
-
-def set_inference_strategy(inference_strategy):
- """! Set CLIPS engine inference strategy accoring to user input"""
- global GLOBAL_CLIPS__ENVIRONMENT
- strategy_was = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.Strategy
- istrat = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-strategy "+str(inference_strategy)+")")
- strategy_is = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.Strategy
- mymessage = "Inference strategy="+str(inference_strategy)
- grass.debug(_(mymessage))
-
-def set_salience_evaluation_behaviour(salience_evaluation_behaviour):
- """! Set CLIPS salience evaluation accoring to user input"""
- global GLOBAL_CLIPS__ENVIRONMENT
- behaviour_was = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.SalienceEvaluation
- is_behave = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-salience-evaluation "+str(salience_evaluation_behaviour)+")")
- mymessage = "Salience evaluation strategy="+str(salience_evaluation_behaviour)
- grass.debug(_(mymessage))
-
-
-#######################################################################
-## Ingest knowledge data: rulebases, facts, instances
-
-
-def ingest_rulebase_file(rulebase_file):
- """! Ingestion of a user-provided rulebase file (KB)"""
- global GLOBAL_CLIPS__ENVIRONMENT
- if os.path.isfile(rulebase_file):
- GLOBAL_CLIPS__ENVIRONMENT.BatchStar(rulebase_file)
- else:
- grass.fatal(_("File does not exist: " + rulebase_file))
-
-def ingest_facts_file(facts_file):
- """! Ingestion of all user-provided facts file"""
- global GLOBAL_CLIPS__ENVIRONMENT
- if os.path.isfile(facts_file):
- GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
- grass.debug(_("[ingest_facts_file] Facts ingested from: " + facts_file))
- else:
- grass.fatal(_("File does not exist: " + facts_file))
-
-def ingest_instances_ascii_file(instances_ascii_file):
- """! Ingestion of all user-provided ASCII instances (COOL, etc) file"""
- global GLOBAL_CLIPS__ENVIRONMENT
- GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
- if os.path.isfile(instances_ascii_file):
- GLOBAL_CLIPS__ENVIRONMENT.LoadInstances(instances_ascii_file)
- grass.message(_("Instances (ascii) ingested from: " + instances_ascii_file))
- else:
- grass.fatal(_("File does not exist: " + instances_ascii_file))
-
-def ingest_instances_binary_file(instances_binary_file):
- """! Ingestion of all user-provided binary instances (COOL, etc) file"""
- global GLOBAL_CLIPS__ENVIRONMENT
- GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
- if os.path.isfile(instances_binary_file):
- GLOBAL_CLIPS__ENVIRONMENT.BLoadInstances(instances_binary_file)
- grass.message(_("Instances (binary) ingested from: " + instances_binary_file))
- else:
- grass.fatal(_("File does not exist: " + instances_binary_file))
-
-#######################################################################
-## Invoke inference process
-
-def launch_inference(max_rule_firing=False):
- """! Invoke inference process, with the option to limit the maximum number of firing rules"""
- global GLOBAL_CLIPS__ENVIRONMENT
- grass.debug(_("[launch_inference]-----Inference starts-------"))
- if max_rule_firing:
- GLOBAL_CLIPS__ENVIRONMENT.Run(int(max_rule_firing))
- else:
- GLOBAL_CLIPS__ENVIRONMENT.Run()
- grass.debug(_("[launch_inference]-----Inference stops-------"))
-
-
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## KNOWLEDGEBASES
-##########################################################################
-##########################################################################
-
-
-#2013-01-16: Exported into seperate files
-# tbd: Provide mechanisms to manage external KB as simple text-files (not *.PY)
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## G.INFER SESSION SETUP
-##########################################################################
-##########################################################################
-
-####################
-# Clips to Python/GRASS downlink tools:
-
-def register_grass_functions_in_clips():
- """! Register several GRASS-related functions for use on the Rule level."""
- #Usage: GLOBAL_CLIPS__ENVIRONMENT.Eval("python-call g.message _(/"hello world/") "))
-
- # pyCLIPS CLI i/o code:
- clips.RegisterPythonFunction(pyprintout)
- clips.RegisterPythonFunction(pyreadline)
- clips.RegisterPythonFunction(pyread)
-
- # !!! Keep an eye on this stuff and how it works (documenatation!)
- # The functions (below) rely on the already registered Python functions (right above).
- ############################################
- #Build CLIPS function: GINFER_PRINTOUT (on the CLIPS and pyCLIPS levels)
- py_printout1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_printout","?logical-name $?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg)))""")
- bashstar_printout1="(deffunction ginfer_printout (?logical-name $?args)(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg))))"
- prelude_upload(bashstar_printout1)
-
- ############################################
- #Build CLIPS function: GINFER_READLINE (on the CLIPS and pyCLIPS levels)
- py_readline1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_readline","$?logical-name","""(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (funcall python-call pyreadline ?logical-name) else (readline ?logical-name))) """)
- bashstar_readline1 = "(deffunction ginfer_readline ($?logical-name)"
- bashstar_readline1 = bashstar_readline1 + "(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t))"
- bashstar_readline1=bashstar_readline1 + "(if (member$ python-call (get-function-list)) then (funcall python-call pyreadline ?logical-name) else (readline ?logical-name)))"
- prelude_upload(bashstar_readline1)
-
- ############################################
- #Build CLIPS function: GINFER_READ (on the CLIPS and pyCLIPS levels)
- py_read1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_read","$?logical-name","""(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (eval (funcall python-call pyread ?logical-name)) else (read ?logical-name))) """)
- bashstar_read1="(deffunction ginfer_read ($?logical-name) (if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (eval (funcall python-call pyread ?logical-name)) else (read ?logical-name)))"
- prelude_upload(bashstar_read1)
-
- #############################################
- # Pyclips stuff (to be accessible in rules and on the CLIPS prompt
- # issue a grass(?) command:
- clips.RegisterPythonFunction(pyclips_send_command)
- #upload and execute facts/rules/whatnot from a file
- clips.RegisterPythonFunction(pyclips_batchstar)
-
- # GRASS stuff:
- clips.RegisterPythonFunction(grass_message)
- clips.RegisterPythonFunction(grass_fatal)
- #clips.RegisterPythonFunction(grass.message)
- clips.RegisterPythonFunction(assert_vector_metadata)
- clips.RegisterPythonFunction(grassvector2factlayer)
- clips.RegisterPythonFunction(grassvector2factlayer_internal)
- clips.RegisterPythonFunction(grassraster2factlayer)
- #clips.RegisterPythonFunction(grassraster2factlayer_internal) #removed 2013-05-16
- clips.RegisterPythonFunction(grassvolume2factlayer)
- clips.RegisterPythonFunction(grassvolume2factlayer_internal)
- #clips.RegisterPythonFunction(factslayer_fromraster2grassraster_internal)
- #clips.RegisterPythonFunction(factslayer_fromraster3d2grassraster3d_internal)
- #clips.RegisterPythonFunction(factslayer2grassvector_internal)
- #^^^ These functions require a central storgae place for INPUT INFORMATION
- clips.RegisterPythonFunction(assert_region)
- clips.RegisterPythonFunction(assert_gisenv)
-
- clips.RegisterPythonFunction(grass.mapcalc)
- clips.RegisterPythonFunction(grass_raster_info)
- clips.RegisterPythonFunction(grass_run_command)
- clips.RegisterPythonFunction(grass_read_command)
-
- clips.RegisterPythonFunction(grass_start_command)
- #clips.RegisterPythonFunction(LOADFACTS)
- #clips.RegisterPythonFunction(ASSERT_RASTER_METADATA)
- #clips.RegisterPythonFunction(DATENBANKZEUGS)
- #clips.RegisterPythonFunction(MAPCALC)
- #clips.RegisterPythonFunction("GRASS_LAMBDA")
- #tbd:
- # r.mapcalc
- # raster/vector layer import
- # database queries
-
-#####################################################
-## EXPERIMENTAL:
-
-#def KB_layers_spearfish():
- #these KB layers will be imported BEFORE the rulebase is loaded.
- #this assures that the rules can become valid as the templates they are referring to
- #have already been instantiated.
- #
- #2013-02-19: Currently the check for the Spearfish location is done as rule #1.
- # the check needs to be executed BEFORE the Spearfish layers are attempted to be uploaded.
- #
- # Maybe a simple failsafe in grassraster_KB_load_raster: Test for existance of layer.
- #
-
-
- ################SPEARFISH Raster Layers#########################################
- #grass.message(_("SPEARFISH RASTER LAYER RUSHMORE: Loading"))
- #grassraster_KB_load_raster("geology")
- #grassraster_KB_load_raster("rushmore")
- #grassraster_KB_load_raster("landuse")
- #grassraster_KB_load_raster("soils")
- #grassraster_KB_load_raster("vegcover")
-
- ################SPEARFISH Vector Layers#########################################
- #grass.message(_(""SPEARFISH VECTOR LAYER bugsites: starting..."))
- #grassvector_KB_load_vector("archsites")
- #grassvector_KB_load_vector("bugsites") #Mountain Pine Beetle Damage
-##
-#####################################################
-
+ is_map3d = vinfo['map3d']
+ #[grassvector_test_3d]:{'kernels': 0, 'lines': 0, 'centroids': 0, 'boundaries': 0, 'points': 25, 'faces': 0, 'primitives': 25, 'islands': 0, 'nodes': 25, 'map3d': False, 'areas': 0}
+ if (str(is_map3d) == "False"):
+ return False
+ else:
+ return True
+ #Important: False can indicate a broken vector topology !
+ #Criteria: A vector lacking any nodes would be inavlid
+def grassvector_test_valid(the_vector):
+ """! Tests a GRASS vector layer for the 3d attribute (-> z column exists) . Returns false otherwise """
+
+ vinfo = grass.vector_info_topo(the_vector)
+ if 'nodes' in vinfo:
+ return True
+ else:
+ grass.message(_("grassvector_test_valid ERROR: "+ str(the_vector)))
+ return False
+def grassvector2factlayer_assert(the_vector,voutascii_columns,attribute_list):
+ """! Asserts facts for a GRASS vector via v.out.ascii (after the custom template for the vector has been previously defined) """
+ #GRASS String attributes concatining whitespaces are correctly asserted.
+ p = grass.pipe_command('v.out.ascii',columns=voutascii_columns,input=the_vector, quiet='TRUE')
+ result = {}
+ count = 0
+ for line in p.stdout:
+ count = count + 1
+ the_line = line.strip().split("|")
+ to_assert="(" + the_vector + " "
+ for index in range(len(attribute_list)):
+ if not attribute_list[index] == "numcat":
+ # numcat is a workaround for the dual cat provision by v.out.ascii
+ # it is filtered out as it is not defined (or used) in the template defined above..
+ to_assert=to_assert+"("+attribute_list[index]+" "+the_line[index] + ")"
+ to_assert=to_assert+" )"
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(to_assert)
+def vector_get_attribute_structure(the_vector):
+ """! Return attribute structure of a vector"""
+ dbdescribe = grass.db_describe(the_vector)
+ #ingest the attribute structure information
+ line = str(dbdescribe).strip("{}")
+ nrows,ignore,cdrline = line.partition(",")
+ cdrline,ingore,ncols = cdrline.rpartition(",")
+ ignore,ignore,attributes = cdrline.partition(":")
+ attributes = attributes.split("],")
+ return attributes
+########################################################################
+#### SET VECTOR METADATA FACTS
+########################################################################
+ #grass.vector_columns('soils')
+
+ #grass.vector_db('soils')
+ # Prints the database connection
+
+ #grass.vector_db_select('soils')
+ # Prints the range of existing values.
+
+ #grass.db_describe('soils')
+ # Describes the attribute table
+ # >> grass.db_describe('soils')
+ # >> {'nrows': 54, 'cols': [['cat', 'INTEGER', '11'], ['label', 'CHARACTER', '13']], 'ncols': 2}
+ # !!! For type CHAR the maximum string length is returned.
+def assert_vector_metadata(thevector):
+ """!Assert the metadata for a GRASS vector layer as facts in the CLIPS environment
+ #grass.vector_info_topo('soils')
+ # Lists, numbers of Boundaries, Points, Primitives, Islands, Lines, Centroids, Nodes
+ """
+ if grassvector_test_valid(thevector):
+
+ topology = grass.vector_info_topo(thevector)
+ topo_nodes = topology['nodes']
+ topo_points = topology['points']
+ #topo_lines = topology['lines']
+ #topo_boundaries = topology['boundaries']
+ #topo_centroids = topology['centroids']
+ #topo_areas = topology['areas']
+ #topo_islands = topology['islands']
+ #topo_faces = topology['faces']
+ #topo_kernels = topology['kernels']
+ topo_primitives = topology['primitives']
+ topo_map3d = topology['map3d']
+ assert_t_nodes = "( TOPOLOGY_NODES " + thevector +" " + str(topo_nodes) + " )"
+ assert_t_points = "( TOPOLOGY_POINTS " + thevector +" " + str(topo_points) + " )"
+ #assert_t_lines = "( TOPOLOGY_LINES " + thevector +" " + str(topo_lines) + " )"
+ #assert_t_boundaries = "( TOPOLOGY_BOUNDARIES " + thevector +" " + str(topo_boundaries) + " )"
+ #assert_t_centroids = "( TOPOLOGY_CENTROIDS " + thevector +" " + str(topo_centroids) + " )"
+ #assert_t_areas = "( TOPOLOGY_AREAS " + thevector +" " + str(topo_areas) + " )"
+ #assert_t_islands = "( TOPOLOGY_ISLANDS " + thevector +" " + str(topo_islands) + " )"
+ #assert_t_faces = "( TOPOLOGY_FACES " + thevector +" " + str(topo_faces) + " )"
+ #assert_t_kernels = "( TOPOLOGY_KERNELS " + thevector +" " + str(topo_kernels) + " )"
+ assert_t_primitives = "( TOPOLOGY_PRIMITIVES " + thevector +" " + str(topo_primitives) + " )"
+ assert_t_map3d = "( TOPOLOGY_MAP3D " + thevector +" " + str(topo_map3d) + " )"
+
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_nodes )
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_points)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_lines)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_boundaries)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_centroids)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_areas)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_islands)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_faces)
+ #GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_kernels)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_primitives)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_t_map3d)
-
-
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-##########################################################################
-## MAIN
-##########################################################################
-
-def main():
-
-
- #################################################
- ##### Sanity Check 1: Ensure that g.infer is run within a GRASS environment
- if "GISBASE" not in os.environ:
- print "You must be in GRASS GIS to run this program."
- sys.exit(1)
-
- #################################################
- #### Import parameters provided from the GRASS GUI
-
-
- #################################################
- #### GRASS GUI Flags
-
- toggle_dribble = flags['d']
- toggle_external_traceback = flags['e']
- interactive_mode = flags['i']
- ignore_raster_labels = flags['l']
- toggle_suddendeath_mode = flags['x']
-
- #################################################
- #### GRASS GUI Options
-
- ## GRASS input layers
- facts_rasters = options['rast']
- facts_vectors = options['vector']
- facts_raster3ds = options['rast3d']
-
- # CLIPS knowledge items
- facts_file = options['facts']
- instances_binary_file = options['bload_instances']
- instances_ascii_file = options['load_instances']
-
- instances_binary_output = options['bsave_instances']
- instances_ascii_output = options['save_instances']
-
- ## GRASS output layers
- inference_map = options['output']
- output_maps = options['export']
- result_columns = options['columns']
-
- ## CLIPS parameters
- max_rule_firing = options['limit']
- inference_strategy = options['strategy']
- salience_evaluation_behaviour = options['salience']
- inference_focus_module = options['module']
- #^^^--- tbd: remains to be switched on & tested
- # CLIPS: (set-current-module FOO)
- # (focus module2 module1 )
-
- save_option = options['save_rulebase']
- bsave_option = options['bsave_rulebase']
- config_option = options['config']
- watch_option = options['watch']
- print_option = options['print']
- classdefault_option = options['classdefault']
- #^-tbd
- #structure can be either default (builtin template) or custom (user-provided template - this requries a proper SQL description in the payload file)
- # even better: remove the XOR option: Its either a deafault with a defined value, OR a STRUCTstring has to be provided
-
- ## Knowledge bases
- rulebase_file = options['rulebase']
- builtin_rulesbase_files = options['library']
-
-
- #################################################
- #Set Variables and Data Structures
- #################################################
-
- #Initialize dictionary to keep the attribute structures for all vectors:
- global layers_vector_vinascii
-
- global layers_template
- global layers_vector_columns
- global layers_raster_type
- global layers_raster3d_slices
-
- facts_vectors_set={}
- facts_rasters_set={}
- facts_raster3ds_set={}
-
- ###^^^^ REFACTOR !
-
-
-
- #################################################
- ##### Invoke GRASS Ctype low level interface
- #################################################
- G_gisinit('g.infer')
-
-
-
- #################################################
- ## Initialize the CLIPS session
- #################################################
- global GLOBAL_CLIPS__ENVIRONMENT
- xps = clips.Environment()
- GLOBAL_CLIPS__ENVIRONMENT=xps
-
- #################################################
- ## Register additional Python modules with CLIPS session
- register_grass_functions_in_clips()
-
- #################################################
- ## change inference strategy
- if inference_strategy:
- set_inference_strategy(inference_strategy)
-
- #################################################
- ## set salience evaluation behaviour
- if salience_evaluation_behaviour:
- set_salience_evaluation_behaviour(salience_evaluation_behaviour)
-
-
- #################################################
- ## load knowledge base module stack
- if inference_focus_module:
- focus_string = "(focus"
- for this_module in str(inference_focus_module).split(','):
- grass.message(_("> Module: "+this_module))
- focus_string += " "+this_module
- focus_string += ")"
- #GLOBAL_CLIPS__ENVIRONMENT.SendCommand(focus_string)
- ### ^^^Refactor / Encapsulate
-
- #################################################
- ##### CLIPS options
- clips_dribble(inference_map,toggle_dribble)
-
- clips_external_traceback(toggle_external_traceback)
-
- if save_option:
- clips_save(inference_map,save_option)
-
- if bsave_option:
- clips_bsave(inference_map,save_option)
-
- if config_option:
- clips_config(config_option)
-
- if watch_option:
- clips_watch(watch_option)
-
- if print_option:
- clips_list(print_option)
-
- if classdefault_option:
- clips_classdefault(classdefault_option)
-
-
- #################################################
- ## Sanity Checks of Input Layers
- #################################################
- sanity_checks_input_layers(facts_rasters,facts_raster3ds,facts_vectors,facts_file,rulebase_file)
-
-
-
- #################################################
- ## DETECT VECTORS
- #################################################
- #Iterate over all input vector layers (if existing): create a set and count total
- if facts_vectors > "":
- count_vectors,facts_vectors_set=detect_input_layer(facts_vectors,facts_rasters_set,facts_raster3ds_set)
-
- #################################################
- ## DETECT RASTER
- #################################################
- #Iterate over all input raster layers (if existing): create a set and count total
- if facts_rasters > "":
- count_maps,facts_rasters_set=detect_input_layer(facts_rasters,facts_vectors_set,facts_raster3ds_set)
-
- #################################################
- ## DETECT RASTER3D (Volume)
- #################################################
- #Iterate over all input raster layers (if existing): create a set and count total
-
- if facts_raster3ds > "":
- count_maps,facts_raster3ds_set=detect_input_layer(facts_raster3ds,facts_vectors_set,facts_rasters_set)
-
-
- #################################################
- # DETECT AND ACCESS OUTPUT MAP
- #################################################
-
- if inference_map:
- if not result_columns:
- grass.fatal(_("Unable to create output vector map: Parameter <columns> missing."))
- else:
- create_vector=TRUE
+ #dto:
+ dbconnection = grass.vector_db(thevector)
+ mymessage="*** vector_dbconncetion = " + str(dbconnection)
+ grass.debug(_(mymessage))
+
+ columns = grass.vector_columns(thevector)
+
+ mymessage="*** vector columns = " + str(columns)
+ grass.debug(_(mymessage))
+ #?? Is there a similar API interface to v.info -g (vectors region). ??
+ else:
+ #grass.message(_("g.infer: Something really wrong with vector" + str(thevector)))
+ sys.exit(1)
+
+
+
+#######################################################################
+## RASTER IMPORT
+#######################################################################
+
+
+def ingest_facts_rasters(facts_rasters,ignore_raster_labels):
+ """! Ingestion of all user-provided GRASS raster layers. Option: Ignore GRASS raster labels"""
+ facts_rasters_list=[]
+ count_maps = 0
+ gisenv = grass.gisenv()
+ gisenv_mapset = gisenv['MAPSET']
+ for this_facts_raster in str(facts_rasters).split(','):
+ grass.debug(_("Ingesting Raster: "+this_facts_raster))
+ count_maps = count_maps + 1
+
+ #gisenv = grass.gisenv()
+ #gisenv_mapset = gisenv['MAPSET']
+ #listofmaps=grass.list_grouped('rast')[gisenv_mapset]
+ #if (this_facts_raster) not in listofmaps:
+ # grass_fatal("g.infer: Raster layer does not exist:" + str(this_facts_raster))
+ # sys.exit(1)
+
+ import_raster_test(this_facts_raster)
+
+ is_elevation_level = False
+ facts_rasters_list.append(this_facts_raster)
+ grassraster2factlayer(this_facts_raster,"GRASS RASTER",ignore_raster_labels,is_elevation_level)
+ return set(facts_rasters_list)
+
+
+
+
+def grassraster2factlayer(the_raster,the_comment_string="GRASS RASTER",ignore_raster_labels=False,elevationlevel=False):
+ """! Generate facts from a GRASS raster layer including the coordinates, the digital number AND the value attribute
+ test for categories: r.category --quiet geology fs=: 0> 1:metamorphic or 1:
+ """
+
+ #TO BE INCLUDED:
+ ## test for input raster map
+ #result = grass.find_file(name = map_name, element = 'cell', quiet = True)
+ #if not result['file']
+ #grass.fatal("Raster map <%s> not found" % map_name)
+
+ #check for category strings:
+ raster_with_labels = True
+ the_categories = raster_categories(the_raster)
+ if len(the_categories) < 1:
+ raster_with_labels = False
+ # find map in search path
+ mapset = G_find_cell2(the_raster, '')
+
+ #Attribute recognition doesnt work for rast3d rasters
+
+ # determine the inputmap type (CELL/FCELL/DCELL)
+ typename = 'undefined'
+ data_type = G_raster_map_type(the_raster, mapset)
+ if data_type == CELL_TYPE:
+ ptype = POINTER(c_int)
+ type_name = 'CELL'
+ elif data_type == FCELL_TYPE:
+ ptype = POINTER(c_float)
+ type_name = 'FCELL'
+ elif data_type == DCELL_TYPE:
+ ptype = POINTER(c_double)
+ type_name = 'DCELL'
+
+ # construct strings to generate templates both on pyclips and clips level:
+
+ buildtemplate_template = "(slot x)(slot y)"
+ bashstar_template = "(deftemplate " + the_raster + " (slot x)(slot y)"
+
+ attribute_list = []
+ attribute_list.append("x")
+ attribute_list.append("y")
+
+ if elevationlevel:
+ buildtemplate_template = buildtemplate_template + "(slot z)"
+ bashstar_template = bashstar_template + "(slot z)"
+ attribute_list.append("z")
+ #Append a column for elevation if this raster layer stems from a rast3d layer, aka has a z-Value constant attached to it
+
+ attr_name_value = 'value'
+
+ attr_name_attribute = 'attribute'
+
+ if type_name == 'CELL':
+ export_type_value = 'integer'
+ ### UNTESTED !!!!
+ else:
+ export_type_value = 'double precision'
+ ###^^^--- The datdtype is defined below: CELL/FCELL/DCELL -> fix !
+
+ #export_type_attribute = "varchar(" + str(GLOBAL_ATTRIBUTE_TYPE) + ")"
+
+ # generate low level GRASS structures
+
+ infd = G_open_cell_old(the_raster, mapset)
+ inrast = G_allocate_raster_buf(data_type)
+ inrast = cast(c_void_p(inrast), ptype)
+
+ rows = G_window_rows()
+ cols = G_window_cols()
+
+ hd=struct_Cell_head()
+ G_get_cellhd(the_raster,mapset,byref(hd))
+
+
+ ###############################
+
+ if raster_with_labels and not ignore_raster_labels:
+ buildtemplate_template = buildtemplate_template + "(slot "+ attr_name_value +")"+ "(multislot "+ attr_name_attribute +")"
+ bashstar_template = bashstar_template + "(slot "+ attr_name_value +")" + "(multislot "+ attr_name_attribute +")"+")"
+ attribute_list.append(attr_name_value)
+ attribute_list.append(attr_name_attribute)
+ else:
+ buildtemplate_template = buildtemplate_template + "(slot "+ attr_name_value +")"
+ bashstar_template = bashstar_template + "(slot "+ attr_name_value +") )"
+ attribute_list.append(attr_name_value)
+
+
+ #Instantiate the new template in PyClips
+ the_new_template = GLOBAL_CLIPS__ENVIRONMENT.BuildTemplate(the_raster,buildtemplate_template,the_comment_string)
+ #Instantiate the new template in Clips
+ prelude_upload(bashstar_template)
+
+ for rown in xrange(rows):
+ therow = G_get_raster_row(infd, inrast, rown, data_type)
+
+ for coln in xrange(cols):
+ coo_col = G_col_to_easting(coln, byref(hd))
+ coo_row = G_row_to_northing(rown, byref(hd))
+ the_value=inrast[coln]
+ fallback=''
+ the_category=the_categories.get(str(the_value),fallback)
+ to_assert = "(" + the_raster + " (x " + str(coo_col) + ") (y " + str(coo_row) + ")"
+ if elevationlevel:
+ to_assert = to_assert + "(z "+ str (elevationlevel) + ")"
+
+ to_assert = to_assert + "(value " + str(the_value) + ")"
+ if raster_with_labels and not ignore_raster_labels:
+ to_assert = to_assert + "(attribute " + str(the_category) + ")"
+
+ to_assert = to_assert + ")"
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(to_assert)
+
+ G_close_cell(infd)
+ G_free(inrast)
+
+ global_layers_template_put(the_raster,the_new_template)
+ global_layers_raster_type_put(the_raster,type_name)
+
+ return
+
+
+def grassraster_KB_load_raster(the_raster):
+ """! Creates a template and asserts the facts for a GRASS raster - to be used with internal knowledgebases """
+ ### !!! Requires a failsafe to test whether the layer exists at all !
+ is_elevation_level = False
+ ignore_raster_labels = FALSE
+ #facts_rasters_set = set(facts_rasters_list.append(the_raster))
+ #^^ is only set otherwise during explicit raster upload in MAIN.
+ # !!!allow for update option
+ grassraster2factlayer(the_raster,"GRASS RASTER",ignore_raster_labels,is_elevation_level)
+
+
+########################################################################
+#### RASTER METADATA FACTS
+########################################################################
+
+#TBD: Provide the metadata for a GRASS raster as CLIPS facts for use in the inference process.
+
+
+# grass.raster_info
+# grass.raster_history
+
+# tbd: Actual region/coverage a raster layer: r.region
+# tbd: r.support
+# tbd: stats: r.median, r.quantile, r.statistics, r.univar
+# tbd: number format (integer, floats, etc)
+# r.info ?
+
+
+#######################################################################
+## VOLUME IMPORT
+#######################################################################
+
+
+def ingest_factsraster3ds(facts_raster3ds):
+ """! Ingestion of all user-provided GRASS raster3D (volume) layers"""
+ facts_raster3ds_list=[]
+ count_maps = 0
+
+ for this_facts_raster3d in str(facts_raster3ds).split(','):
+ grass.message(_("Ingesting Raster3D: "+this_facts_raster3d))
+ import_rast3d_test(this_facts_raster3d)
+ #listofmaps=grass.list_grouped('rast3')[gisenv_mapset]
+ #if (this_facts_raster) not in listofmaps:
+ # grass_fatal("g.infer: Raster layer does not exist:" + str(this_facts_raster))
+ # sys.exit(1)
+ count_maps = count_maps + 1
+ facts_raster3ds_list.append(this_facts_raster3d)
+ grassvolume2factlayer(this_facts_raster3d)
+ return set(facts_raster3ds_list)
+
+
+
+def grassvolume2factlayer(the_volume):
+ """! Generate facts from a GRASS volume layer including the 3d coordinates and the digital number"""
+ the_raster = str(the_volume)+"_slice_"
+
+ #the_layers_template = global_layers_template_get(the_volume)
+
+ #layers_raster_type = global_layers_raster_type_get(the_volume)
+
+ #global_layers_rast3d_slices_get(the_volume)
+
+ p = grass.pipe_command('r3.to.rast',flags='rm',input=the_volume, output=the_raster.rstrip("_"), quiet='TRUE')
+ # tbd: replace the_raster by a randomly generated name.
+
+ grass.debug("grassvolume2factlayer: Sleeping 10 sec")
+ time.sleep(10)
+ #SLEEP to ensure that the pipe returns in time. This is ugly and need to be improved.
+ # get height of layerstack
+ region = region3()
+ stack_height=region['depths']
+ stack_res=region['tbres']
+
+ this_raster3d_raster_slices_list = []
+ #create a container for all raster_file_names for this raster3d volume
+
+ #ITERATE OVER THE stack of raster layerswhich were creared
+ for level in range(1, int(stack_height)):
+ if level < 10:
+ levelstring="0000"+str(level)
+ elif level < 100:
+ levelstring="000"+str(level)
+ elif level < 1000:
+ levelstring="00"+str(level)
+ elif level < 10000:
+ levelstring="0"+str(level)
+ current_raster=the_raster+levelstring
+ #^^ use the real elevations ( not the levels) level*elevationelta=ELEVATIONVARIABLE
+
+
+ grass.debug("Raster-Level: "+current_raster)
+ this_raster3d_raster_slices_list.append(current_raster)
+ this_elevation=stack_res * level
+ the_ignore_label_flag = True
+ #the_template,raster_type = grassraster2factlayer(current_raster,"GRASS VOLUME",the_ignore_label_flag,this_elevation)
+
+ #the_layers_template[current_raster]=the_template
+ #layers_raster_type[current_raster]=raster_type
+ grassraster2factlayer(current_raster,"GRASS VOLUME",the_ignore_label_flag,this_elevation)
+
+ ###^^ to be returned !
+ #global_layers_template_put(the_volume,the_layers_template)
+
+ #global_layers_raster_type_put(the_volume,layers_raster_type)
+
+ global_layers_rast3d_slices_put(the_volume,this_raster3d_raster_slices_list)
+
+ #return the_layers_template, layers_raster_type, this_raster3d_raster_slices_list
+
+
+
+def grassvolume2factlayer_internal(the_volume):
+ """! Internal Use: Generate facts from a GRASS volume layer including the 3d coordinates and the digital number"""
+ grassvolume2factlayer(the_volume)
+
+########################################################################
+#### VOLUME METADATA FACTS
+########################################################################
+
+#TBD: Provide the metadata for a GRASS raster3D volume as CLIPS facts for use in the inference process.
+
+# r3.timestamp
+# r3.stats
+# r3.univar
+
+
+
+
+##############################################################
+##############################################################
+##############################################################
+##############################################################
+##############################################################
+##############################################################
+## METADATA
+##############################################################
+##############################################################
+
+##########################################################
+## GRASS SESSION METADATA to FACTS
+##########################################################
+
+def assert_region():
+ """! Creates facts for all GRASS region parameters"""
+ region = region3()
+ region_rows = region['rows']
+ region_cols = region['cols']
+ region_cells = region['cells']
+ region_ewres = region['ewres']
+ region_nsres = region['nsres']
+ region_n = region['n']
+ region_s = region['s']
+ region_e = region['e']
+ region_w = region['w']
+
+ # Accomodate for 3D region parameters:
+ region_t = region['t']
+ region_b = region['b']
+ region_tbres = region['tbres']
+ region_ewres3 = region['ewres3']
+ region_nsres3 = region['nsres3']
+ region_rows3 = region['rows3']
+ region_cols3 = region['cols3']
+ region_depths = region['depths']
+ region_cells3 = region['cells3']
+
+
+ assert_region_rows = "( REGION_ROWS " + str(region_rows) + " )"
+ assert_region_cols = "( REGION_COLS " + str(region_cols) + " )"
+ assert_region_cells = "( REGION_CELLS " + str(region_cells) + " )"
+ assert_region_ewres = "( REGION_EWRES " + str(region_ewres) + " )"
+ assert_region_nsres = "( REGION_NSRES " + str(region_nsres) + " )"
+ assert_region_n = "( REGION_N " + str(region_n) + " )"
+ assert_region_s = "( REGION_S " + str(region_s) + " )"
+ assert_region_e = "( REGION_E " + str(region_e) + " )"
+ assert_region_w = "( REGION_W " + str(region_w) + " )"
+
+ # Region 3D parameters:
+ assert_region_rows3 = "( REGION_ROWS3 " + str(region_rows3) + " )"
+ assert_region_cols3 = "( REGION_COLS3 " + str(region_cols3) + " )"
+ assert_region_cells3 = "( REGION_CELLS3 " + str(region_cells3) + " )"
+ assert_region_ewres3 = "( REGION_EWRES3 " + str(region_ewres3) + " )"
+ assert_region_nsres3 = "( REGION_NSRES3 " + str(region_nsres3) + " )"
+ assert_region_tbres = "( REGION_TBRES " + str(region_tbres) + " )"
+ assert_region_t = "( REGION_T " + str(region_t) + " )"
+ assert_region_b = "( REGION_B " + str(region_b) + " )"
+ assert_region_depths = "( REGION_DEPTHS " + str(region_depths) + " )"
+
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_rows)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cols)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cells)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_nsres)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_ewres)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_n)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_s)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_e)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_w)
+
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_rows3)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cols3)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_cells3)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_nsres3)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_ewres3)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_tbres)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_t)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_b)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_region_depths)
+
+
+
+def assert_gisenv():
+ """!Assert all GRASS environmental variables (GISENV / Location / Mapset) as facts in the CLIPS environment"""
+ gisenv = grass.gisenv()
+ gisenv_gisdbase = gisenv['GISDBASE']
+ gisenv_location_name = gisenv['LOCATION_NAME']
+ gisenv_mapset = gisenv['MAPSET']
+ gisenv_grass_gui = gisenv['GRASS_GUI']
+
+ assert_gisdbase = "( GISDBASE " + gisenv_gisdbase + " )"
+ assert_location_name = "( LOCATION_NAME " + gisenv_location_name + " )"
+ assert_mapset = "( MAPSET " + gisenv_mapset + " )"
+ assert_grass_gui= "( GRASS_GUI " + gisenv_grass_gui + " )"
+
+ # More variables to be included !
+
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_gisdbase)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_location_name)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_mapset)
+ GLOBAL_CLIPS__ENVIRONMENT.Assert(assert_grass_gui)
+
+
+
+
+########################################################################
+#### GRASS7 TEMPORAL METADATA FACTS
+########################################################################
+
+# tbd: no python support yet
+
+########################################################################
+#### DATABASE CONNECTIVITY METADATA FACTS
+########################################################################
+
+#TBD: Integrate this metadata as CLIPS facts for use in the inference process.
+
+# grass.db_connection
+# grass.db_describe
+# grass.db_select
+
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## EXPORT from CLIPS constructs to GRASS layers
+##########################################################################
+##########################################################################
+
+
+# Export sanity checks needed ?
+
+
+def fact2rastercell(afact,raster_name,integer_case):
+ """! Returns for a (raster-) fact the structured content of a GRASS - raster cell"""
+ the_x = float(afact.Slots['x'])
+ the_y = float(afact.Slots['y'])
+ if integer_case:
+ the_value = int(afact.Slots['value'])
+ else:
+ the_value = float(afact.Slots['value'])
+ ###^^ not everything is FLOAT !
+
+ if 'attribute' in afact.Slots.keys():
+ #the_attribute=afact.Slots['attribute']
+ #alternative to deal with multiple string content - works for vector, untested here.
+ the_attribute=""
+ multifield_list = afact.Slots['attribute']
+ allitems=""
+ for item in multifield_list:
+ the_attribute=the_attribute + str(item).rstrip() + " "
+ the_attribute.rstrip(" ")
+ else:
+ the_attribute=False
+
+ if 'z' in afact.Slots.keys():
+ the_elevation = float(afact.Slots['z'])
+ else:
+ the_elevation=False
+ return the_x,the_y,the_value,the_attribute,the_elevation
+
+#######################################################################
+## RASTER EXPORT
+#######################################################################
+
+def factslayer_fromraster2grassraster_internal(rastername,ignore_labels=False):
+ """! Internal Use: Exports a grassraster facts to GRASS vector (point) layer which are transformed into a GRASS raster layer"""
+ factslayer_fromraster2grassraster(rastername,ignore_labels,False)
+
+
+def factslayer_fromraster2grassraster(rastername,ignore_labels=False,raster_type=False):
+ """! Exports a grassraster facts to GRASS vector (point) layer which are transformed into a GRASS raster layer"""
+ ### tbd: take care of Z-column for rast3d !
+
+ ### start a dictionary to track all attribute/value pairs
+
+# global layers_template
+ thetemplate = global_layers_template_get(rastername)
+ raster_type = global_layers_raster_type_get(rastername)
+
+# test: if exists: use ELSE: False
+ layers_raster_type[rastername] = raster_type
+ #??? is this the right ordering ?
+
+ attribute_dict = {}
+
+ #Check for number types:
+ if raster_type:
+ if raster_type == "CELL":
+ integer_case = TRUE
+ grass.debug("[factslayer_fromraster2grassraster] INTEGER LIKE INPUT MAP")
+ else:
+ integer_case = FALSE
+ grass.debug("[factslayer_fromraster2grassraster] FLOAT LIKE INPUT MAP")
+ # we don't care what kind of float it is
+ else:
+ # no raster type provided, we must check the facts to figure it out.
+ grass.message("[factslayer_fromraster2grassraster] No raster map type defined: PROBING FACTS TO DEFINE OUTPUT MAP TYPE")
+ integer_case = facts_all_integer(thetemplate,'value')
+
+ #define array to collect random access info from facts
+ if integer_case:
+ raster_output = garray.array(dtype=numpy.int32)
+ grass.debug("[factslayer_fromraster2grassraster] Integer Array")
+ else:
+ grass.debug("[factslayer_fromraster2grassraster] Float Array")
+ raster_output = garray.array()
+
+ #### GRASS LOW LEVEL COMMANDS start here
+ #setup GRASS helpers to transform coordinates into columns and rows.
+ mapset = G_find_cell2(rastername, '')
+ hd=struct_Cell_head()
+ G_get_cellhd(rastername,mapset,byref(hd))
+
+ thisfact = fact_first(thetemplate)
+
+ if thisfact:
+ now_x,now_y,now_value,now_attribute,now_elevation = fact2rastercell(thisfact,rastername,integer_case)
+ # now_elevation is currently not used further.
+ # the z-component is ignored -> the z/level info is also part of the template name.
+ coo_col = int(G_easting_to_col(now_x, byref(hd)))
+ coo_row = int(G_northing_to_row(now_y, byref(hd)))
+ if now_attribute:
+ attribute_dict.update({str(now_attribute):now_value})
+ # push attribute into attribute dictionary if is does not exist yet.
+ if integer_case:
+ raster_output[coo_row,coo_col] = numpy.int32(now_value)
+ else:
+ raster_output[coo_row,coo_col] = float(now_value)
+
+ count = 1
+ carry_on = 1
+
+ while carry_on:
+ count = count +1
+ thisfact = fact_next(thetemplate, thisfact)
+ if thisfact:
+ now_x,now_y,now_value,now_attribute,now_elevation = fact2rastercell(thisfact,rastername,integer_case)
+ coo_col = int(G_easting_to_col(now_x, byref(hd)))
+ coo_row = int(G_northing_to_row(now_y, byref(hd)))
+ if now_attribute:
+ attribute_dict.update({str(now_attribute):now_value})
+ if integer_case:
+ raster_output[coo_row,coo_col] = numpy.int32(now_value)
+ else:
+ raster_output[coo_row,coo_col] = float(now_value)
+ else:
+ carry_on = 0
+ #!!! coordinate skew is still there !: add +0.5 ?
+
+ # Remove previous version of layer in GRASS domain:
+ grass.run_command('g.remove', rast=rastername, quiet='TRUE')
+
+ #write changed raster out
+ raster_output.write(rastername)
+
+ #writeout attributes if any exist
+ if attribute_dict.keys():
+ grassfeed = grass.feed_command("r.category",rules='-',map=rastername, quiet='TRUE')
+ for key in attribute_dict.keys():
+ this_attribute = str(int(attribute_dict[key])) + ":" + str(key)+"\n"
+ grassfeed.stdin.write(this_attribute)
+ grassfeed.stdin.close()
+
+ #get rid of NULL values (untested) #FACTNULL ist der UGLY interne Wert !
+ grass.run_command('r.null', map=rastername, setnull=FACT_NULL, quiet='TRUE')
+
+ #IF INTEGER: ^^^^
+ # IF FLOAT: Handle * => nan case for NULL value
+
+
+
+########################################################################
+####VECTOR EXPORT
+########################################################################
+
+
+
+def vector_facts2grassvector_string(afact,thecolumnslist):
+ """!Builds and returns a GRASS-formatted string from the facts associated to a GRASS vector """
+ #(grassraster (name foo) (x 596203) (y 4915149)(hanni 42)(nanni 43))
+
+ myresult = str(afact.Slots['x'])+"|"+ str(afact.Slots['y'])
+ multifield_list = list()
+ #^^dummy-define variable for later use
+
+ for column in thecolumnslist:
+ if (column != 'x')and( column !='y'):
+ multifield_list = afact.Slots[column]
+ allitems=""
+ if (len(multifield_list) > 0):
+ for item in multifield_list:
+ allitems=allitems + str(item).rstrip() + " "
+ myresult = myresult+"|"+ allitems.rstrip(" ")
+
+ grass.debug(_("vector_facts2grassvector_string:" + myresult))
+ myresult = myresult + "\n"
+ return myresult
+
+
+def factslayer2grassvector_internal(vectorname):
+ """! Internal Use: Creates a GRASS vector from a factslayer"""
+ factslayer2grassvector(vectorname)
+ # ^^^Untested !
+
+
+
+def factslayer2grassvector(vectorname):
+ """! Creates a GRASS vector from a factslayer"""
+ #!! To be considered: Shall the name of a newly to be created output vector is to be included ?
+ #
+
+ #!! In case that a OUTPUT layer has been created with COLUMNS, but remains empty:
+ # v.in.ascii -e creates only an empty layer.
+ count = 0
+ thetemplate = global_layers_template_get(vectorname) # --> Could cause a problem in a "new vector (Xanadu)" case. Otherwise: optional argument ?
+ the_columns = global_layers_vector_vinascii_get(vectorname)
+ the_columns_list = global_layers_vector_columns_get(vectorname)
+ #complete_columns= cat_filter('x double precision, y double precision,' + the_columns.strip("\'"))
+ #^^^ original version: assumes that x/y columns are NOT provided by the user.
+ complete_columns= cat_filter('' + the_columns.strip("\'"))
+ # works for now ^^^
+ #20120508: This must be discussed:
+ # is it a good thing if the user has to define X and Y columns when entering the columns-description ?
+ # con: x/X y/Y can be misleading -> internal import assumes that x/y are the needed coordinates.
+ #!!!
+ #print str(vectorname) +" Facts => "+str(facts_total(thetemplate))
+ if (facts_total(thetemplate) < 1):
+ # ^^^^FACTS_TOTAL needs a FAILSAFE for the NULL case !
+ #g.message(_("Export stopped: No facts found for export vector: " + the_template))
+ grass.message(_("[factslayer2grassvector]: No facts found for export vector: " + str(vectorname) + " --> EMPTY VECTOR CREATED"))
+ grass.run_command("v.in.ascii","e",input='-',output=vectorname, x=1, y=2, columns=complete_columns, overwrite='True', quiet='TRUE')
+
+ else:
+ mystring = str(vectorname) + "-facts-count: "+ str(facts_total(thetemplate))
+ #g.message(_("Export continues: " + mystring))
+ grassfeed = grass.feed_command("v.in.ascii",input='-',output=vectorname, x=1, y=2, columns=complete_columns, overwrite='True', quiet='TRUE')
+
+
+ firstfact = fact_first(thetemplate)
+ thisfact = firstfact
+ if thisfact:
+ carry_on = 1
+ grassfeed.stdin.write(vector_facts2grassvector_string(firstfact,the_columns_list))
+ count = 1
+ while carry_on:
+ count = count +1
+ thisfact = fact_next(thetemplate, thisfact)
+ if thisfact:
+ grassfeed.stdin.write(vector_facts2grassvector_string(thisfact,the_columns_list))
+ else:
+ carry_on = 0
+ grassfeed.stdin.close()
+ return count
+
+#######################################################################
+## VOLUME EXPORT
+#######################################################################
+
+### !!! The foofact.Slot.keys() mechanism allows to check whether a Z-value exists
+### -> for now none is handed over.
+### Volume import/export could not be achieved via 2D rasters otherwise.
+
+def factslayer_fromraster3d2grassraster3d_internal(the_inference_map):
+ """! Internal USe: Update an existing GRASS volume layer from its CLIPS facts representation"""
+ factslayer_fromraster3d2grassraster3d(the_inference_map)
+# ^^ UNTESTED !
+
+
+def factslayer_fromraster3d2grassraster3d(the_inference_map):
+ """! Update an existing GRASS volume layer from its CLIPS facts representation"""
+ # for each item in the slices list:
+ # get the corresponding template from the vinasciss/templates list
+ # launch GRASSRASTER generation processess
+ # bundle rasters into a raster3d
+
+ #global_layers_raster_type_get(the_volume)
+ # shouldn't this one be handed over, too ?
+
+ the_slices_list = global_layers_rast3d_slices_get(the_inference_map)
+ slices_list_string=""
+ for this_slice in the_slices_list:
+ layers_templates = global_layers_template_get(this_slice)
+ slices_list_string=slices_list_string+","+str(this_slice)
+ #generate raster slice:
+ factslayer_fromraster2grassraster(this_slice,False)
+
+ slices_list_string.lstrip(',')
+ #^^^remove leading comma
+ p = grass.pipe_command('r.to.rast3',input=slices_list_string, output=the_inference_map, quiet='TRUE', overwrite='TRUE')
+
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## CLIPS Engine Settings
+##########################################################################
+##########################################################################
+
+#######################################################################
+## CLIPS Save options for knowledge items
+
+
+def clips_save(inference_map,save_option):
+ """! Write CLIPS information to file"""
+
+ if save_option.find("facts") > -1:
+ grass.debug(_("SAVE: Facts"))
+ forensics_facts=inference_map+"_facts.clips"
+ GLOBAL_CLIPS__ENVIRONMENT.SaveFacts(forensics_facts)
+
+ if save_option.find("constructs") > -1:
+ grass.debug(_("SAVE: Constructs"))
+ forensics_constructs=inference_map+"_constructs.clips"
+ GLOBAL_CLIPS__ENVIRONMENT.Save(forensics_constructs)
+
+ if save_option.find("instances") > -1:
+ grass.debug(_("SAVE: Instances"))
+ forensics_instances=inference_map+"_instances.clips"
+ GLOBAL_CLIPS__ENVIRONMENT.SaveInstances(forensics_instances)
+
+def clips_bsave(inference_map,save_option):
+ """! Write CLIPS information to file"""
+ binary_export = 0
+
+ if save_option.find("facts") > -1:
+ grass.debug(_("BSAVE: Facts"))
+ forensics_facts=inference_map+"_facts.clips"
+ GLOBAL_CLIPS__ENVIRONMENT.SaveFacts(forensics_facts)
+
+ if save_option.find("constructs") > -1:
+ grass.debug(_("BSAVE: Constructs"))
+ forensics_constructs=inference_map+"_constructs.bin"
+ GLOBAL_CLIPS__ENVIRONMENT.BSave(forensics_constructs)
+
+ if save_option.find("instances") > -1:
+ grass.debug(_("BSAVE: Instances"))
+ forensics_instances=inference_map+"_instances.bin"
+ GLOBAL_CLIPS__ENVIRONMENT.BSaveInstances(forensics_instances)
+
+#######################################################################
+## CLIPS Set Config
+
+def clips_config(config_option):
+ """! Set CLIPS engine config-setting"""
+ config_string = "auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset- globals,sequence-operator-recognition,static-constraint-checking"
+ config_list = str(config_string).split(',')
+ for item in config_list:
+ if watch_option.find(item) > -1:
+ grass.message(_("(set-"+str(item)+" TRUE )"))
+ now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-"+str(item)+" TRUE )")
+
+#######################################################################
+## CLIPS Set Watch
+
+def clips_watch(watch_option):
+ """! Set CLIPS engine watch-setting"""
+ watch_string = "activations,compilations,facts,functions,genericfunctions,globals,methods,messagehandlers,messages,rules,slots,statistics,all"
+ watch_list = str(watch_string).split(',')
+ for item in watch_list:
+ if watch_option.find(item) > -1:
+ grass.message(_("(watch "+ str(item)+" )"))
+ now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(watch "+ str(item)+" )")
+
+#######################################################################
+## CLIPS Set list
+
+def clips_list(list_option):
+ """! Set CLIPS engine option-settings"""
+ if list_option.find("agenda") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintAgenda()
+ if list_option.find("breakpoints") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintBreakpoints()
+ if list_option.find("classes") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintClasses()
+ if list_option.find("deffacts") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintDeffacts()
+ if list_option.find("definstances") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintDefinstances()
+ if list_option.find("facts") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintFacts()
+ if list_option.find("focusstack") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintFocusStack()
+ if list_option.find("functions") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintFunctions()
+ if list_option.find("generics") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintGenerics()
+ if list_option.find("globals") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.ShowGlobals()
+ #"show" display the variables AND their values
+ if list_option.find("instances") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintInstances()
+ if list_option.find("messagehandlers") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintMessagehandlers()
+ if list_option.find("modules") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintModules()
+ if list_option.find("rules") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintRules()
+ if list_option.find("templates") > -1:
+ GLOBAL_CLIPS__ENVIRONMENT.PrintTemplates()
+
+#######################################################################
+## CLIPS Set dribble
+
+def clips_dribble(inference_map,toggle_dribble):
+ """! Set CLIPS engine dribble-setting"""
+ if toggle_dribble:
+ grass.message(_("(dribble-on "+str(inference_map)+".dribble )"))
+ now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(dribble-on "+str(inference_map)+".dribble )")
+
+
+#######################################################################
+## CLIPS Set external traceback
+
+def clips_external_traceback(toggle_external_traceback):
+ """! Toggle CLIPS engine traceback-setting"""
+ if toggle_external_traceback:
+ clips.SetExternalTraceback(True)
+ #WORKS: confirmed 20120302
+
+#######################################################################
+## CLIPS Module stack seeding
+
+def clips_module_stack(inference_focus_module):
+ """! Set CLIPS engine focus-setting on a specific KB module"""
+ if inference_focus_module:
+ #iterate over comma seperated inference_focus_module AAA,BBB,CCCC and build up "focus AAA BBB CCC" string.
+ grass.message(_("clips_module_stack: Under development"))
+ clips.PrintFocusStack()
+ ### clips command: (focus AAA BB CC)
+ focus = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(focus AAA BBB CCC )")
+
+
+ #FindModule($modulename) !! - finds an existing module
+ # BuildModule
+ #popFocus
+ #printFocusStack
+ #
+ #clips.SetCurrent() / SetFocus / PopFocus
+ #CLIPS: (list-focus-stack) (clear-focus-stack) (focus fi fa fo)
+ #tbd: strip string "inference_focus_module" off commata ("A,B,C") -> "A B C" and assign GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(focus "+str(STTINGSANSCOMMATA)+".dribble )")
+ else:
+ grass.message(_("CLIPS_MODULE_STACK => ELSE:this should not happen"))
+
+#######################################################################
+## CLIPS Set class-default
+
+def clips_classdefault(classdefault_option):
+ """! Set CLIPS engine class-default-setting"""
+ #(set‑class-defaults-mode <mode>)
+ if classdefault_option.find("convenience") > -1:
+ now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("( set‑class-defaults-mode convenience)")
+ if classdefault_option.find("conservation") > -1:
+ now = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("( set‑class-defaults-mode conservation)")
+
+
+#######################################################################
+###########SET DEBUG SETTING#########################
+ ###?? GLOBAL_CLIPS__ENVIRONMENT.Memory[Options] Object P42 pyclips manual
+
+ #CLIPS Debug Settings which could be provided to the user for forensics.
+
+ # Conserve: TRUE / False
+ # EnvironmentErrosEnabled
+ # Free()
+ # PPBuffersize
+ # Requests: readonly!
+ # Used: readonly !
+ # NumberOffEnvironmenst
+
+
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## INFERENCE RUN
+##########################################################################
+##########################################################################
+
+
+##########################################################
+# Interactive mode.
+# code snippet adapted from http://pyclips.sourceforge.net/web/?q=node/19 author: franzg
+##########################################################
+
+# Description: TBD
+
+# needed: uo/down keys to navigate a history similar to the bash shell history.
+
+class interactive_shell(object):
+ """an interactive CLIPS prompt activated via the i-Flag"""
+
+ def __init__(self):
+ self.__ps1 = "g.infer CLIPS prompt[%(cmdno)s/%(lineno)s] (Exit: Ctrl-D)> "
+ self.__ps2 = "g.infer CLIPS prompt[%(cmdno)s/%(lineno)s] (Exit: Ctrl-D): "
+ self.__cmdno = 1
+ self.__lineno = 1
+
+ def __cmdcomplete(self, cms):
+ """check if CLIPS command is complete (stolen from 'commline.c')"""
+ def eat_ws(s, i):
+ """eat up whitespace"""
+ while i < len(s) and s[i] in _string.whitespace: i += 1
+ return i
+ def eat_string(s, i):
+ """eat up strings"""
+ if s[i] != '"' or i >= len(s): return i
+ i += 1
+ while i < len(s):
+ if s[i] == '"': return i + 1
+ else:
+ if s[i] == '\\': i += 1
+ i += 1
+ if i > len(s): raise ValueError, "non-terminated string"
+ return i
+ def eat_comment(s, i):
+ """eat up comments"""
+ if s[i] != ';' or i >= len(s): return i
+ while i < len(s) and s[i] not in '\n\r': i += 1
+ return i + 1
+ s = cms.strip()
+ if len(s) == 0: return False
+ depth = 0
+ i = 0
+ while i < len(s):
+ c = s[i]
+ if c in '\n\r' and depth == 0: return True
+ elif c == '"': i = eat_string(s, i)
+ elif c == ';': i = eat_comment(s, i)
+ elif c == '(': depth += 1; i += 1
+ elif c == ')': depth -= 1; i += 1
+ elif c in _string.whitespace: i = eat_ws(s, i)
+ else: i += 1
+ if depth < 0: raise ValueError, "invalid command"
+ if depth == 0: return True
+ else: return False
+
+ def Run(self):
+ """start or resume an interactive CLIPS shell"""
+ exitflag = False
+ while not exitflag:
+ self.__lineno = 1
+ s = ""
+ dic = { 'cmdno': self.__cmdno, 'lineno': self.__lineno }
+ prompt = self.__ps1 % dic
+ try:
+ while not self.__cmdcomplete(s):
+ if s: s += " "
+ s += raw_input(prompt).strip()
+ self.__lineno += 1
+ dic = { 'cmdno': self.__cmdno, 'lineno': self.__lineno }
+ prompt = self.__ps2 % dic
+ except ValueError, e:
+ sys.stderr.write("[SHELL] %s\n" % str(e))
+ except EOFError:
+ clips.ErrorStream.Read()
+ exitflag = True
+ # tbd: allow also an "graceful" exit using a (exit) command!
+ try:
+ if not exitflag:
+ GLOBAL_CLIPS__ENVIRONMENT.SendCommand(s, True)
+ except clips.ClipsError, e:
+ sys.stderr.write("[PYCLIPS] %s\n" % str(e))
+ self.__cmdno += 1
+ r0 = clips.StdoutStream.Read()
+ r1 = clips.DisplayStream.Read()
+ tx = clips.TraceStream.Read()
+ r = ""
+ if r0: r += r0
+ if r1: r += r1
+ t = clips.ErrorStream.Read()
+ if r: r = "%s\n" % r.rstrip()
+ if t: t = "%s\n" % t.rstrip()
+ if tx: t = "%s\n" % tx.rstrip() + t
+ #^^^2013_Feb19: This throws an error if WATCH is not set:
+ # TypeError: cannot concatenate 'str' and 'NoneType' objects
+
+
+ if t: sys.stderr.write(t)
+ if r: sys.stdout.write(r)
+
+##########################################################################
+# CLI Interface code
+# taken from http://commentsarelies.blogspot.de/2008/07/using-printout-and-readline-in-pyclips.html
+# Author: Johan Lindberg, 2008-07-14
+
+# Description: code to provide an interactive CLIPS shell for g.infer sessions.
+
+def pyprintout(*args):
+ """! TBD"""
+ for arg in args[1]:
+ if arg.cltypename().upper() == "SYMBOL":
+ if arg.upper() == "CRLF":
+ print
+ elif arg.upper() == "TAB":
+ print "\t",
+ else:
+ print arg,
+
+ else:
+ print arg,
+
+
+def pyreadline(*args):
+ """! TBD"""
+ return raw_input()
+
+def pyread(*args):
+ """! TBD"""
+ return raw_input()
+
+#######################################################################
+## CLIPS LAYER BATCHSTAR SEEDING
+
+
+def prelude_upload(the_string):
+ """! CReate a tempfile on the GRASS_level,and announce this file at the CLIPS level for BatchSTar usage?"""
+ #generate prelude for batchstar and write it out to a tempfile
+ tempfile = grass.read_command('g.tempfile',pid=random.randint(1,1000000))
+ file = open(tempfile, 'w')
+ file.write(the_string)
+ file.close()
+ # Make the template definitions available on the BatchStar level.
+ GLOBAL_CLIPS__ENVIRONMENT.BatchStar(tempfile)
+ # Remove the template
+ os.remove(tempfile)
+
+
+#######################################################################
+## Set CLIPS engine options
+
+def set_inference_strategy(inference_strategy):
+ """! Set CLIPS engine inference strategy accoring to user input"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ strategy_was = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.Strategy
+ istrat = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-strategy "+str(inference_strategy)+")")
+ strategy_is = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.Strategy
+ mymessage = "Inference strategy="+str(inference_strategy)
+ grass.debug(_(mymessage))
+
+def set_salience_evaluation_behaviour(salience_evaluation_behaviour):
+ """! Set CLIPS salience evaluation accoring to user input"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ behaviour_was = GLOBAL_CLIPS__ENVIRONMENT.EngineConfig.SalienceEvaluation
+ is_behave = GLOBAL_CLIPS__ENVIRONMENT.SendCommand("(set-salience-evaluation "+str(salience_evaluation_behaviour)+")")
+ mymessage = "Salience evaluation strategy="+str(salience_evaluation_behaviour)
+ grass.debug(_(mymessage))
+
+
+#######################################################################
+## Ingest knowledge data: rulebases, facts, instances
+
+
+def ingest_rulebase_file(rulebase_file):
+ """! Ingestion of a user-provided rulebase file (KB)"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ if os.path.isfile(rulebase_file):
+ GLOBAL_CLIPS__ENVIRONMENT.BatchStar(rulebase_file)
+ else:
+ grass.fatal(_("File does not exist: " + rulebase_file))
+
+def ingest_facts_file(facts_file):
+ """! Ingestion of all user-provided facts file"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ if os.path.isfile(facts_file):
+ GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
+ grass.debug(_("[ingest_facts_file] Facts ingested from: " + facts_file))
+ else:
+ grass.fatal(_("File does not exist: " + facts_file))
+
+def ingest_instances_ascii_file(instances_ascii_file):
+ """! Ingestion of all user-provided ASCII instances (COOL, etc) file"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
+ if os.path.isfile(instances_ascii_file):
+ GLOBAL_CLIPS__ENVIRONMENT.LoadInstances(instances_ascii_file)
+ grass.message(_("Instances (ascii) ingested from: " + instances_ascii_file))
+ else:
+ grass.fatal(_("File does not exist: " + instances_ascii_file))
+
+def ingest_instances_binary_file(instances_binary_file):
+ """! Ingestion of all user-provided binary instances (COOL, etc) file"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ GLOBAL_CLIPS__ENVIRONMENT.LoadFacts(facts_file)
+ if os.path.isfile(instances_binary_file):
+ GLOBAL_CLIPS__ENVIRONMENT.BLoadInstances(instances_binary_file)
+ grass.message(_("Instances (binary) ingested from: " + instances_binary_file))
+ else:
+ grass.fatal(_("File does not exist: " + instances_binary_file))
+
+#######################################################################
+## Invoke inference process
+
+def launch_inference(max_rule_firing=False):
+ """! Invoke inference process, with the option to limit the maximum number of firing rules"""
+ global GLOBAL_CLIPS__ENVIRONMENT
+ grass.debug(_("[launch_inference]-----Inference starts-------"))
+ if max_rule_firing:
+ GLOBAL_CLIPS__ENVIRONMENT.Run(int(max_rule_firing))
+ else:
+ GLOBAL_CLIPS__ENVIRONMENT.Run()
+ grass.debug(_("[launch_inference]-----Inference stops-------"))
+
+
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## KNOWLEDGEBASES
+##########################################################################
+##########################################################################
+
+
+#2013-01-16: Exported into seperate files
+# tbd: Provide mechanisms to manage external KB as simple text-files (not *.PY)
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## G.INFER SESSION SETUP
+##########################################################################
+##########################################################################
+
+####################
+# Clips to Python/GRASS downlink tools:
+
+def register_grass_functions_in_clips():
+ """! Register several GRASS-related functions for use on the Rule level."""
+ #Usage: GLOBAL_CLIPS__ENVIRONMENT.Eval("python-call g.message _(/"hello world/") "))
+
+ # pyCLIPS CLI i/o code:
+ clips.RegisterPythonFunction(pyprintout)
+ clips.RegisterPythonFunction(pyreadline)
+ clips.RegisterPythonFunction(pyread)
+
+ # !!! Keep an eye on this stuff and how it works (documenatation!)
+ # The functions (below) rely on the already registered Python functions (right above).
+ ############################################
+ #Build CLIPS function: GINFER_PRINTOUT (on the CLIPS and pyCLIPS levels)
+ py_printout1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_printout","?logical-name $?args","""(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg)))""")
+ bashstar_printout1="(deffunction ginfer_printout (?logical-name $?args)(if (member$ python-call (get-function-list)) then (funcall python-call pyprintout ?logical-name $?args) else (progn$ (?arg $?args)(printout ?logical-name ?arg))))"
+ prelude_upload(bashstar_printout1)
+
+ ############################################
+ #Build CLIPS function: GINFER_READLINE (on the CLIPS and pyCLIPS levels)
+ py_readline1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_readline","$?logical-name","""(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (funcall python-call pyreadline ?logical-name) else (readline ?logical-name))) """)
+ bashstar_readline1 = "(deffunction ginfer_readline ($?logical-name)"
+ bashstar_readline1 = bashstar_readline1 + "(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t))"
+ bashstar_readline1=bashstar_readline1 + "(if (member$ python-call (get-function-list)) then (funcall python-call pyreadline ?logical-name) else (readline ?logical-name)))"
+ prelude_upload(bashstar_readline1)
+
+ ############################################
+ #Build CLIPS function: GINFER_READ (on the CLIPS and pyCLIPS levels)
+ py_read1 = GLOBAL_CLIPS__ENVIRONMENT.BuildFunction("ginfer_read","$?logical-name","""(if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (eval (funcall python-call pyread ?logical-name)) else (read ?logical-name))) """)
+ bashstar_read1="(deffunction ginfer_read ($?logical-name) (if (> (length$ $?logical-name) 0) then (bind ?logical-name (first$ $?logical-name)) else (bind ?logical-name t)) (if (member$ python-call (get-function-list)) then (eval (funcall python-call pyread ?logical-name)) else (read ?logical-name)))"
+ prelude_upload(bashstar_read1)
+
+ #############################################
+ # Pyclips stuff (to be accessible in rules and on the CLIPS prompt
+ # issue a grass(?) command:
+ clips.RegisterPythonFunction(pyclips_send_command)
+ #upload and execute facts/rules/whatnot from a file
+ clips.RegisterPythonFunction(pyclips_batchstar)
+
+ # GRASS stuff:
+ clips.RegisterPythonFunction(grass_message)
+ clips.RegisterPythonFunction(grass_fatal)
+ #clips.RegisterPythonFunction(grass.message)
+ clips.RegisterPythonFunction(assert_vector_metadata)
+ clips.RegisterPythonFunction(grassvector2factlayer)
+ clips.RegisterPythonFunction(grassvector2factlayer_internal)
+ clips.RegisterPythonFunction(grassraster2factlayer)
+ #clips.RegisterPythonFunction(grassraster2factlayer_internal) #removed 2013-05-16
+ clips.RegisterPythonFunction(grassvolume2factlayer)
+ clips.RegisterPythonFunction(grassvolume2factlayer_internal)
+ #clips.RegisterPythonFunction(factslayer_fromraster2grassraster_internal)
+ #clips.RegisterPythonFunction(factslayer_fromraster3d2grassraster3d_internal)
+ #clips.RegisterPythonFunction(factslayer2grassvector_internal)
+ #^^^ These functions require a central storgae place for INPUT INFORMATION
+ clips.RegisterPythonFunction(assert_region)
+ clips.RegisterPythonFunction(assert_gisenv)
+
+ clips.RegisterPythonFunction(grass.mapcalc)
+ clips.RegisterPythonFunction(grass_raster_info)
+ clips.RegisterPythonFunction(grass_run_command)
+ clips.RegisterPythonFunction(grass_read_command)
+
+ clips.RegisterPythonFunction(grass_start_command)
+ #clips.RegisterPythonFunction(LOADFACTS)
+ #clips.RegisterPythonFunction(ASSERT_RASTER_METADATA)
+ #clips.RegisterPythonFunction(DATENBANKZEUGS)
+ #clips.RegisterPythonFunction(MAPCALC)
+ #clips.RegisterPythonFunction("GRASS_LAMBDA")
+ #tbd:
+ # r.mapcalc
+ # raster/vector layer import
+ # database queries
+
+#####################################################
+## EXPERIMENTAL:
+
+#def KB_layers_spearfish():
+ #these KB layers will be imported BEFORE the rulebase is loaded.
+ #this assures that the rules can become valid as the templates they are referring to
+ #have already been instantiated.
+ #
+ #2013-02-19: Currently the check for the Spearfish location is done as rule #1.
+ # the check needs to be executed BEFORE the Spearfish layers are attempted to be uploaded.
+ #
+ # Maybe a simple failsafe in grassraster_KB_load_raster: Test for existance of layer.
+ #
+
+
+ ################SPEARFISH Raster Layers#########################################
+ #grass.message(_("SPEARFISH RASTER LAYER RUSHMORE: Loading"))
+ #grassraster_KB_load_raster("geology")
+ #grassraster_KB_load_raster("rushmore")
+ #grassraster_KB_load_raster("landuse")
+ #grassraster_KB_load_raster("soils")
+ #grassraster_KB_load_raster("vegcover")
+
+ ################SPEARFISH Vector Layers#########################################
+ #grass.message(_(""SPEARFISH VECTOR LAYER bugsites: starting..."))
+ #grassvector_KB_load_vector("archsites")
+ #grassvector_KB_load_vector("bugsites") #Mountain Pine Beetle Damage
+##
+#####################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+##########################################################################
+## MAIN
+##########################################################################
+
+def main():
+
+
+ #################################################
+ ##### Sanity Check 1: Ensure that g.infer is run within a GRASS environment
+ if "GISBASE" not in os.environ:
+ print "You must be in GRASS GIS to run this program."
+ sys.exit(1)
+
+ #################################################
+ #### Import parameters provided from the GRASS GUI
+
+
+ #################################################
+ #### GRASS GUI Flags
+
+ toggle_dribble = flags['d']
+ toggle_external_traceback = flags['e']
+ interactive_mode = flags['i']
+ ignore_raster_labels = flags['l']
+ toggle_suddendeath_mode = flags['x']
+
+ #################################################
+ #### GRASS GUI Options
+
+ ## GRASS input layers
+ facts_rasters = options['rast']
+ facts_vectors = options['vector']
+ facts_raster3ds = options['rast3d']
+
+ # CLIPS knowledge items
+ facts_file = options['facts']
+ instances_binary_file = options['bload_instances']
+ instances_ascii_file = options['load_instances']
+
+ instances_binary_output = options['bsave_instances']
+ instances_ascii_output = options['save_instances']
+
+ ## GRASS output layers
+ inference_map = options['output']
+ output_maps = options['export']
+ result_columns = options['columns']
+
+ ## CLIPS parameters
+ max_rule_firing = options['limit']
+ inference_strategy = options['strategy']
+ salience_evaluation_behaviour = options['salience']
+ inference_focus_module = options['module']
+ #^^^--- tbd: remains to be switched on & tested
+ # CLIPS: (set-current-module FOO)
+ # (focus module2 module1 )
+
+ save_option = options['save_rulebase']
+ bsave_option = options['bsave_rulebase']
+ config_option = options['config']
+ watch_option = options['watch']
+ print_option = options['print']
+ classdefault_option = options['classdefault']
+ #^-tbd
+ #structure can be either default (builtin template) or custom (user-provided template - this requries a proper SQL description in the payload file)
+ # even better: remove the XOR option: Its either a deafault with a defined value, OR a STRUCTstring has to be provided
+
+ ## Knowledge bases
+ rulebase_file = options['rulebase']
+ builtin_rulesbase_files = options['library']
+
+
+ #################################################
+ #Set Variables and Data Structures
+ #################################################
+
+ #Initialize dictionary to keep the attribute structures for all vectors:
+ global layers_vector_vinascii
+
+ global layers_template
+ global layers_vector_columns
+ global layers_raster_type
+ global layers_raster3d_slices
+
+ facts_vectors_set={}
+ facts_rasters_set={}
+ facts_raster3ds_set={}
+
+ ###^^^^ REFACTOR !
+
+
+
+ #################################################
+ ##### Invoke GRASS Ctype low level interface
+ #################################################
+ G_gisinit('g.infer')
+
+
+
+ #################################################
+ ## Initialize the CLIPS session
+ #################################################
+ global GLOBAL_CLIPS__ENVIRONMENT
+ xps = clips.Environment()
+ GLOBAL_CLIPS__ENVIRONMENT=xps
+
+ #################################################
+ ## Register additional Python modules with CLIPS session
+ register_grass_functions_in_clips()
+
+ #################################################
+ ## change inference strategy
+ if inference_strategy:
+ set_inference_strategy(inference_strategy)
+
+ #################################################
+ ## set salience evaluation behaviour
+ if salience_evaluation_behaviour:
+ set_salience_evaluation_behaviour(salience_evaluation_behaviour)
+
+
+ #################################################
+ ## load knowledge base module stack
+ if inference_focus_module:
+ focus_string = "(focus"
+ for this_module in str(inference_focus_module).split(','):
+ grass.message(_("> Module: "+this_module))
+ focus_string += " "+this_module
+ focus_string += ")"
+ #GLOBAL_CLIPS__ENVIRONMENT.SendCommand(focus_string)
+ ### ^^^Refactor / Encapsulate
+
+ #################################################
+ ##### CLIPS options
+ clips_dribble(inference_map,toggle_dribble)
+
+ clips_external_traceback(toggle_external_traceback)
+
+ if save_option:
+ clips_save(inference_map,save_option)
+
+ if bsave_option:
+ clips_bsave(inference_map,save_option)
+
+ if config_option:
+ clips_config(config_option)
+
+ if watch_option:
+ clips_watch(watch_option)
+
+ if print_option:
+ clips_list(print_option)
+
+ if classdefault_option:
+ clips_classdefault(classdefault_option)
+
+
+ #################################################
+ ## Sanity Checks of Input Layers
+ #################################################
+ sanity_checks_input_layers(facts_rasters,facts_raster3ds,facts_vectors,facts_file,rulebase_file)
+
+
+
+ #################################################
+ ## DETECT VECTORS
+ #################################################
+ #Iterate over all input vector layers (if existing): create a set and count total
+ if facts_vectors > "":
+ count_vectors,facts_vectors_set=detect_input_layer(facts_vectors,facts_rasters_set,facts_raster3ds_set)
+
+ #################################################
+ ## DETECT RASTER
+ #################################################
+ #Iterate over all input raster layers (if existing): create a set and count total
+ if facts_rasters > "":
+ count_maps,facts_rasters_set=detect_input_layer(facts_rasters,facts_vectors_set,facts_raster3ds_set)
+
+ #################################################
+ ## DETECT RASTER3D (Volume)
+ #################################################
+ #Iterate over all input raster layers (if existing): create a set and count total
+
+ if facts_raster3ds > "":
+ count_maps,facts_raster3ds_set=detect_input_layer(facts_raster3ds,facts_vectors_set,facts_rasters_set)
+
+
+ #################################################
+ # DETECT AND ACCESS OUTPUT MAP
+ #################################################
+
+ if inference_map:
+ if not result_columns:
+ grass.fatal(_("Unable to create output vector map: Parameter <columns> missing."))
+ else:
+ create_vector=TRUE
#grass_message(str("[MAIN: INFERENCE MAP DETECTED] Export Vector: " + inference_map + " columns = " + result_columns))
grassvector_new(inference_map,result_columns)
- grassvector2factlayer(inference_map,result_columns)
+ grassvector2factlayer(inference_map,result_columns)
#grass_message(str("*** [MAIN: INFERENCE MAP CREATED !] *** "))
-
- #################################################
- ## INGEST VECTORS
- #################################################
- # Iterate over all vector layers and create grassvector-facts for each one from the provided attribute
-
- if facts_vectors:
- ingest_facts_vectors(facts_vectors,inference_map)
-
- #################################################
- ## INGEST RASTER
- #################################################
- # Iterate over all raster layers and create grassraster-facts for each one and return total count as list
- if facts_rasters:
- facts_rasters_set = ingest_facts_rasters(facts_rasters,ignore_raster_labels)
-
- #################################################
- ## INGEST RASTER3D
- #################################################
- # Iterate over all raster3d layers and create grassraster-facts for each one and return total count as list
- if facts_raster3ds:
- facts_raster3ds_set = ingest_factsraster3ds(facts_raster3ds)
-
- #################################################
- ## Ingest GRASS Session Metadata facts
- #################################################
- region3() #ensure the 3d settings are available
- assert_region()
- assert_gisenv()
-
-
- #################################################
- ## load built-in knowledge bases
- #################################################
-
- if builtin_rulesbase_files:
- #grass.debug(_(""PREBUILT KB BEING LOADED !"))
- this_count = 0
- for this_kb in str(builtin_rulesbase_files).split(','):
- this_count = this_count + 1
- __import__(this_kb)
- kb_mods=sys.modules[this_kb]
- grass.message(_("[g.infer Main] Using library KB: " + str(this_kb)))
- prelude_upload(kb_mods.knowledgebase())
- if interactive_mode:
- grass.message(_("[-i Flag:]: Built-in knowledgebase has been loaded:"))
- grass.message(_("[-i Flag:]: Enter (run) on the CLIPS prompt to start."))
- grass.message(_("[-i Flag:]: [Ctrl-D to leave CLIPS-prompt]"))
-
- #################################################
- ## INGEST RULEBASE
- #################################################
- #### Upload rulebase payload into CLIPS space
- if rulebase_file:
- ingest_rulebase_file(rulebase_file)
-
-
- #################################################
- ## INGEST FACTS
- #################################################
- # This has to be done AFTER the payload has been ingested -> payload (may) have to include fact templates first !
- if facts_file:
- ingest_facts_file(facts_file)
-
- #################################################
- ## INGEST INSTANCES
- #################################################
- # This has to be done AFTER the has been ingested -> payload (may) have to include object definitions for instances !
-
- if instances_ascii_file:
- ingest_instances_ascii_file(instances_ascii_file)
-
- if instances_binary_file:
- ingest_instances_binary_file(instances_binary_file)
-
-
- #################################################
- ##### Interactive mode
- if interactive_mode:
- grass.debug(_("[i-Flag]: Entering interactive mode "))
- clips_shell = interactive_shell()
- clips_shell.Run()
-
-
- #################################################
- ##### "No rules, no facts, no inference" abort option:
- norules_nofacts_noservice()
-
- #################################################
- ##### Pre-Inference Early Abort
- if toggle_suddendeath_mode:
- grass.message(_("Pre-inference abort by user request (s-flag)"))
- sys.exit()
-
- #################################################
- ##### Start Main Inference Loop
- launch_inference(max_rule_firing)
-
- #################################################
- ## SAVE INSTANCES
- #################################################
- if instances_ascii_output:
- GLOBAL_CLIPS__ENVIRONMENT.SaveInstances(instances_ascii_output)
- grass.message(_("Instances saved to ASCII-file: " + instances_ascii_output))
-
- if instances_binary_output:
- GLOBAL_CLIPS__ENVIRONMENT.BLoadInstances(instances_binary_output)
- grass.message(_("Instances saved to binary file: " + instances_binary_output))
-
- #################################################
- ##### Create new output or updates of an input layer ?
- #################################################
- if output_maps:
- for export_map in str(output_maps).split(','):
- if export_map in facts_raster3ds_set:
- factslayer_fromraster3d2grassraster3d(export_map)
- elif export_map in facts_rasters_set:
- factslayer_fromraster2grassraster(export_map,ignore_raster_labels)
- elif export_map in facts_vectors_set:
- factslayer2grassvector(export_map)
- else:
- grass.fatal(_("g.infer [MAIN]: Strange Export Map Error: this should never happen."))
- ### ^^^ REFACTOR / ENCAPSLUATE
-
-
- if inference_map:
- #grass.message(_(""MAIN: commencing EXPORT-Layer writeout " + inference_map))
- factslayer2grassvector(inference_map)
-
-if __name__ == "__main__":
- options, flags = grass.parser()
- atexit.register(cleanup)
- sys.exit(main())
- main()
-
-
-
-
-
-
-
-
+
+ #################################################
+ ## INGEST VECTORS
+ #################################################
+ # Iterate over all vector layers and create grassvector-facts for each one from the provided attribute
+
+ if facts_vectors:
+ ingest_facts_vectors(facts_vectors,inference_map)
+
+ #################################################
+ ## INGEST RASTER
+ #################################################
+ # Iterate over all raster layers and create grassraster-facts for each one and return total count as list
+ if facts_rasters:
+ facts_rasters_set = ingest_facts_rasters(facts_rasters,ignore_raster_labels)
+
+ #################################################
+ ## INGEST RASTER3D
+ #################################################
+ # Iterate over all raster3d layers and create grassraster-facts for each one and return total count as list
+ if facts_raster3ds:
+ facts_raster3ds_set = ingest_factsraster3ds(facts_raster3ds)
+
+ #################################################
+ ## Ingest GRASS Session Metadata facts
+ #################################################
+ region3() #ensure the 3d settings are available
+ assert_region()
+ assert_gisenv()
+
+
+ #################################################
+ ## load built-in knowledge bases
+ #################################################
+
+ if builtin_rulesbase_files:
+ #grass.debug(_(""PREBUILT KB BEING LOADED !"))
+ this_count = 0
+ for this_kb in str(builtin_rulesbase_files).split(','):
+ this_count = this_count + 1
+ __import__(this_kb)
+ kb_mods=sys.modules[this_kb]
+ grass.message(_("[g.infer Main] Using library KB: " + str(this_kb)))
+ prelude_upload(kb_mods.knowledgebase())
+ if interactive_mode:
+ grass.message(_("[-i Flag:]: Built-in knowledgebase has been loaded:"))
+ grass.message(_("[-i Flag:]: Enter (run) on the CLIPS prompt to start."))
+ grass.message(_("[-i Flag:]: [Ctrl-D to leave CLIPS-prompt]"))
+
+ #################################################
+ ## INGEST RULEBASE
+ #################################################
+ #### Upload rulebase payload into CLIPS space
+ if rulebase_file:
+ ingest_rulebase_file(rulebase_file)
+
+
+ #################################################
+ ## INGEST FACTS
+ #################################################
+ # This has to be done AFTER the payload has been ingested -> payload (may) have to include fact templates first !
+ if facts_file:
+ ingest_facts_file(facts_file)
+
+ #################################################
+ ## INGEST INSTANCES
+ #################################################
+ # This has to be done AFTER the has been ingested -> payload (may) have to include object definitions for instances !
+
+ if instances_ascii_file:
+ ingest_instances_ascii_file(instances_ascii_file)
+
+ if instances_binary_file:
+ ingest_instances_binary_file(instances_binary_file)
+
+
+ #################################################
+ ##### Interactive mode
+ if interactive_mode:
+ grass.debug(_("[i-Flag]: Entering interactive mode "))
+ clips_shell = interactive_shell()
+ clips_shell.Run()
+
+
+ #################################################
+ ##### "No rules, no facts, no inference" abort option:
+ norules_nofacts_noservice()
+
+ #################################################
+ ##### Pre-Inference Early Abort
+ if toggle_suddendeath_mode:
+ grass.message(_("Pre-inference abort by user request (s-flag)"))
+ sys.exit()
+
+ #################################################
+ ##### Start Main Inference Loop
+ launch_inference(max_rule_firing)
+
+ #################################################
+ ## SAVE INSTANCES
+ #################################################
+ if instances_ascii_output:
+ GLOBAL_CLIPS__ENVIRONMENT.SaveInstances(instances_ascii_output)
+ grass.message(_("Instances saved to ASCII-file: " + instances_ascii_output))
+
+ if instances_binary_output:
+ GLOBAL_CLIPS__ENVIRONMENT.BLoadInstances(instances_binary_output)
+ grass.message(_("Instances saved to binary file: " + instances_binary_output))
+
+ #################################################
+ ##### Create new output or updates of an input layer ?
+ #################################################
+ if output_maps:
+ for export_map in str(output_maps).split(','):
+ if export_map in facts_raster3ds_set:
+ factslayer_fromraster3d2grassraster3d(export_map)
+ elif export_map in facts_rasters_set:
+ factslayer_fromraster2grassraster(export_map,ignore_raster_labels)
+ elif export_map in facts_vectors_set:
+ factslayer2grassvector(export_map)
+ else:
+ grass.fatal(_("g.infer [MAIN]: Strange Export Map Error: this should never happen."))
+ ### ^^^ REFACTOR / ENCAPSLUATE
+
+
+ if inference_map:
+ #grass.message(_(""MAIN: commencing EXPORT-Layer writeout " + inference_map))
+ factslayer2grassvector(inference_map)
+
+if __name__ == "__main__":
+ options, flags = grass.parser()
+ atexit.register(cleanup)
+ sys.exit(main())
+ main()
+
+
+
+
+
+
+
+
Property changes on: grass-addons/grass6/general/g.infer/g.infer
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
More information about the grass-commit
mailing list