03 Geographic scripting in uDig - halfway between user and developer


Published on

Part 03 - Geographic scripting in uDig - halfway
between user and developer

Course I gave at the University of Potsdam about Geoscripting in uDig.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

03 Geographic scripting in uDig - halfway between user and developer

  1. 1. Open Source GISGeographic scripting in uDig - halfway between user and developer Geoinformation Research Group, Department of Geography University of Potsdam March 2013 The scripting console Tutor: Andrea Antonello ydroloGIS nvironmental ngineering HydroloGIS S.r.l. - Via Siemens, 19 - 39100 Bolzano www.hydrologis.com
  2. 2. The Geoscript editorScritping is one of the powerful things in GIS. Non developers have thepossibility to create great automatisations through it.uDigs scripting console is based on the groovy java scripting language.The geoscript geographic scripting engine can be used from within uDig.
  3. 3. Open the consoleTwo icons can be used to open the scripting editor: one for creating a newempty script and one to open an existing script.
  4. 4. Lets create a new one. The user will be prompted to save the new script tofile and an empty editor is opened.There are a few tool inside the editor, needed to start and stop scripts, or setthe heap memory allowed to be used by a script or enable logging.
  5. 5. Script away, with command completion and syntax coloringInside the editor some basic command completion is available. For geoscriptobjects, as for example the widely use Geometry:
  6. 6. but also for methods, as for example the fromWKT, a handy way to creategeometries on the fly:
  7. 7. The base language: be Groovy!In order to be able exploit 100% the console and scripting engine, it ismandatory to get a good insight of the base language that can be used in theconsole.Before we start with the geo part, we will investigate a bit groovy.Lets create a new script to do so. We should find ourself in front of a niceempty editor.
  8. 8. Writing stringsTo run your first script, simply write the following in the editor // write a string println "This is a string"and push the play button.The result should be the following inside the console window: Process started: 2013-02-10 18:02:03 This is a string Process finished: 2013-02-10 18:02:04The script simply prints the string in the console. It also gives informationabout the start and end timestamps of the script execution.Note that the editor executes only the selected text inside the editor. Ifnothing is selected, all of it is used.
  9. 9. Also more complex strings can be used, by surrounding text with triplequotes: // write a complex string println """Inside triple quotes you can do almost anything. It is kind of an advanced string!"""Select only the second part and see if it is executed properly.
  10. 10. Variables// define variables// a stringdef name = "Luis"// a numberdef age = 25/* * insert the variables into a string template * through the use of ${} */def myTemplate1 = "Hi, my name is ${name} and Im ${age}."println myTemplate1// strings and numbers can also be concatenated through the + signdef myTemplate2 = "Hi, my name is " + name + " and Im " + age + "."println myTemplate2
  11. 11. Lists// working with lists// create a list of stringsdef list = ["Merano", "Bolzano", "Trento"];println list;// how to access the elements?println "The elements start at position 0: " + list[0]// how to add an element to the list?list << "Potsdam"println list;// how to remove an element from the list?// by object?list.remove("Potsdam")println list;// better by indexlist.remove(0)println list;
  12. 12. Lists magic - part 1// lists magic - part 1def list = ["Merano", "Bolzano", "Trento"];// to loop over a list the default it can be usedlist.each { println it}// ...or your very own variable...list.each{ myVar -> println "This a town: " + myVar}// ...or you can use an index, toolist.eachWithIndex{myVar, i -> println "${myVar} is town N.${i}"}
  13. 13. Lists magic - part 2// lists magic - part 2def list = ["Merano", "Bolzano", "Trento"];println "This is the original list: " + list// lists can be sortedlist.sort();println "This is the sorted list: " + list// and reverse sorteddef revList = list.reverse();// note that while sort changes the original list, reverse makes a copyprintln "This is list after the sorting: " + listprintln "This is reverse list: " + revListprintln "This is list after the reverse sorting: " + list
  14. 14. Lists magic - part 3// lists magic - part 3// concatenate listdef abc = ["a", "b", "c"]def cde = ["c", "d", "e"]def newabcde = abc + cdeprintln newabcde// through join the list can be concatenated to one single stringprintln newabcde.join(",")println newabcde.join(" | ")// if we are talking about numbers, some functions applydef nums = [1.0, 2, 3.5]println nums.max()println nums.min()println nums.sum()
  15. 15. Lists magic - part 4// lists magic - part 4// modify each element of the list with collectdef abc = ["a", "b", "c"]println "Original abc: " + abcabc = abc.collect{ it += " is a letter"}println "Modified abc: " + abc// flatten nested listsdef abc = ["a", "b", "c"]def cde = ["c", "d", "e"]abc << cdeprintln abcprintln abc.flatten()
  16. 16. Maps (Hash)Groovy speaking a Map is a container of key and value pairs. // working with maps // create a map // key1:value1, key2:value2, ... def townsProvinceMap = [merano:"BZ", bolzano:"BZ", trento:"TN"] println townsProvinceMap // ways of accessing the values of a map // implicit println townsProvinceMap.merano // the "array" way println townsProvinceMap["merano"] // through the "getter" println townsProvinceMap.get("merano") // ways to add an element // implicit townsProvinceMap.lagundo = "BZ" println townsProvinceMap // through the put method townsProvinceMap.put("Postdam", "BR") println townsProvinceMap
  17. 17. Maps magic// maps magicdef townsProvinceMap = [merano:"BZ", bolzano:"BZ", trento:"TN"]// iterate the thing with the default value...townsProvinceMap.each{ println it}// ...or with key and value separated...townsProvinceMap.each{ println "${it.key} is in province of ${it.value}"}// ...or with own varstownsProvinceMap.each{key, value -> println "${key} is in province of ${value}"}
  18. 18. RangesRange can be seen at first as a sequence, but there is much more behind it. // working with ranges // create a range def range = 1..3 // do some iterations range.each{ println it } range.each{ println "what?" } // and what about dates? def now = new Date(); def nextWeek = now + 7; (now..nextWeek).each{ println it } // since ranges have a from, to and size... println "A range from " + range.from + " to " + range.to + " of size " + range.size() // ...you can use them in for loops... for (i in 1..3){ println "step number: ${i}" } // ...which ovbiously could be done like the following (1..3).each{ println "closure step number: ${it}" }
  19. 19. Groovy: working with files & filesystemGroovy allows to access the OS-environment and read the filesystem. // working with the filesystem // get system info System.env.each{ println it} // get the home folder def userHome = System.getenv("HOME") println userHome // list a folders content def home = new File(userHome) println "The contents of " + home.absolutePath + " are:" home.eachFile{ file -> println "t" + file } // list only folders println "...of which folders:" home.eachDir{ dir -> println "t" + dir } // list only files println "...of which files:" home.eachFile{ file -> if(file.isFile()) println "t" + file } // recursive list content println "Recursive folders content:" home.eachDirRecurse{ dir -> println "t" + dir }
  20. 20. Reading Files// reading files// start with creating a new file to be read afterwardsdef newFile = new File(System.getenv("HOME") + "/testFileToBeRemoved.txt");// one way to writ text to filenewFile.write("""A new header.A new testline.A second testline.""")// read the file line by linenewFile.eachLine{ line, index -> println "line " + index + ". " + line}// read the file into a string variabledef content = newFile.textprintln content
  21. 21. Writing Files// writing filesdef file = new File(System.getenv("HOME") + "/testFileToBeRemoved.txt");println file.text// append some contentfile << "Some text after the last line is appended!"println file.text// merge filesdef file2 = new File(file.absolutePath + "2")file2.write("Content of file 2");println file2.textdef mergedFile = new File(file.absolutePath + "_merged")mergedFile << file.textmergedFile << file2.textprintln "nThe merged file:"println mergedFile.text// delete the filesfile.delete()file2.delete()mergedFile.delete()
  22. 22. Reading CSV Files// read values from a csv file// create a sample csv filedef file = new File(System.getenv("HOME") + "/sample.csv");file.write("""# id, lat, lon, elev1, 11.0, 46.0, 2502, 11.1, 46.1, 2513, 11.2, 46.2, 252""")println file.text// read the csv valuesdef recordsList = []file.eachLine{ if(it.trim().length() == 0) { println "Empty line hit." } else if(it.startsWith("#")) { println "Comment line hit." } else { def lineSplit = it.split(",") println "Values: ${lineSplit[0]}, ${lineSplit[1]}, ${lineSplit[2]}, ${lineSplit[3]}" }}
  23. 23. Groovy: Data structures for complex scripts// working with data structures// create a data structureclass Record { def id def lat def lon def elev public String toString(){ "Values: [${id}, ${lat}, ${lon}, ${elev}]" }}// read the csv into a list of recordsdef file = new File(System.getenv("HOME") + "/sample.csv");def recordsList = []file.eachLine{ if(it.trim().length() > 0 && !it.startsWith("#")) { def lineSplit = it.split(",") def record = new Record() record.id = lineSplit[0] record.lat = lineSplit[1] record.lon = lineSplit[2] record.elev = lineSplit[3] recordsList << record }}println recordsList
  24. 24. Groovy: most important conditions and loopsIf-then-else: def x = false def y = false if ( x ) { x = false } else { y = true }Ternary operator: def y = 5 def x = (y > 1) ? "worked" : "failed"While loop: def x = 0 def y = 5 while ( y-- > 0 ) { x++ }
  25. 25. For loop: for (int i = 0; i < 5; i++) { ... } def x = 0 for ( i in 0..9 ) { x += i } x = 0 for ( i in [0, 1, 2, 3, 4] ) { x += i }Loop with closures: def stringList = [ "java", "perl", "python", "ruby", "c#", "cobol", "groovy", "jython", "smalltalk", "prolog", "m", "yacc" ]; stringList.each() { print " ${it}" }
  26. 26. This work is released under Creative Commons Attribution ShareAlike (CC-BY-SA)Much of the knowledge needed to create this training material hasbeen produced by the sparkling knights of the GeoTools, JTS,Geoscript and uDig community. Their community websites are full oflearning material that can be use to grow knowledge beyond theboundaries of this set of tutorials.The Groovy examples base on the great documentation available onGroovys homepage.Another essential source has been the Wikipedia community effort.Particular thanks go to those friends that directly or indirectly helpedout in the creation and review of this series of handbooks.This tutorial is brought to you by HydroloGIS.