Using SQLite in R

Working on big data requires a clean and robust approach on storing and accessing the data. SQLite is an all inclusive server-less database system in a single file. This is very convenient for data exchange between colleagues. Here is a workflow of SQLite data accessing and data storing in R.

Connect to an SQLite database file and get a table directly to a data.frame data-type. Useful when handling big chunks of data or when analyzing subsets of data which can be retrieved via an SQLite query.

  1. library("RSQLite")
  2. # connect to the sqlite file
  3. con = dbConnect(drv="SQLite", dbname="country.sqlite")
  4. # get a list of all tables
  5. alltables = dbListTables(con)
  6. # get the populationtable as a data.frame
  7. p1 = dbGetQuery( con,'select * from populationtable' )
  8. # count the areas in the SQLite table
  9. p2 = dbGetQuery( con,'select count(*) from areastable' )
  10. # find entries of the DB from the last week
  11. p3 = dbGetQuery(con, "SELECT population WHERE DATE(timeStamp) < DATE('now', 'weekday 0', '-7 days')")
  12. #Clear the results of the last query
  13. dbClearResult(p3)
  14. #Select population with managerial type of job
  15. p4 = dbGetQuery(con, "select * from populationtable where jobdescription like '%manager%'")

Shapefile Java Class

A simple Java class for reading/writing (IO) shapefiles. It uses the geotools library and the vividsolutions geometry library. Useful for various geo-spatial applications such as editing shapefile atributes and exporting.

  1. import;
  2. import;
  3. import;
  4. import;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.Hashtable;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Set;
  12. import;
  13. import;
  14. import;
  15. import;
  16. import;
  17. import;
  18. import;
  19. import;
  20. import;
  21. import org.geotools.feature.FeatureCollection;
  22. import org.geotools.feature.FeatureCollections;
  23. import org.geotools.feature.FeatureIterator;
  24. import org.geotools.feature.simple.SimpleFeatureBuilder;
  25. import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
  26. import org.opengis.feature.simple.SimpleFeature;
  27. import org.opengis.feature.simple.SimpleFeatureType;
  29. import com.vividsolutions.jts.geom.Geometry;
  31. /**
  32.  * Represents a shape file (used by ArcGIS). Basically a convenience function to simplify the
  33.  * tasks of reading/writing shapefiles (using GeoTools). Most of the shapefile reading/writing/editing
  34.  * code has been copied or adapted from the GeoTools tutorials which come with the GeoToolssoftware.
  35.  * <p>
  36.  * Typical usage (reads a shapefile, get an attribute, adds a new attribute column, then writes it):<br>
  37.  * <code>
  38.  * Shapefile s = new Shapefile("ObjectIDs", "myShapefile.shp");<br>
  39.  * s.readShapefile();<br>
  40.  * int anAttributeValue = s.getAttribute(featureID, "anAttribute", Integer.class);<br>
  41.  * s.addAttribute("newAttribute", Double.class, valuesTable)
  42.  * s.writeShapefile("newShapefile");
  43.  * </code>
  44.  *
  45.  */
  46. public class Shapefile {
  48. /** The geometries of the objects in this Shapefile, stored along with object ids.*/
  49. private Map<Integer, Geometry> geometries;
  51. /** The features associated with each object in this Shapefile, stored along with object ids. */
  52. private Map<Integer, SimpleFeature> features;
  54. /** The actual file which this shapefile has been created from */
  55. private File file;
  57. /** The FeatureSource for this shapefile, required as a template for writing shapefiles */
  58. private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
  60. /** Optional column used to store object ids (by default will use FID). */
  61. private String idColumn = null;
  63. /**
  64. * Create a new Shapefile object.
  65. * @param idColumn
  66. * @param file
  67. */
  68. public Shapefile(String idColumn, File file) {
  69. this.geometries = new Hashtable<Integer, Geometry>();
  70. this.features = new Hashtable<Integer, SimpleFeature>();
  71. this.idColumn = idColumn;
  72. this.file = file;
  73. }
  75. /**
  76. * Get the value of an attribute.
  77. * @param featureID The ID of the object to get the attribute value from.
  78. * @param attributeName The name of the attribute.
  79. * @param clazz The class of the obect to be returned.
  80. * @return The attribute as an Object or
  81. */
  82. @SuppressWarnings("unchecked")
  83. public <T> T getAttribute(int featureID, String attributeName, Class<T> clazz) {
  84. if (this.checkFeatures()) { // Check there are some features in this Shapefile
  85. SimpleFeature feature = this.features.get(featureID);
  86. if (feature == null) {
  87. System.err.println("Shapefile.getAttribute() error: no feature with id: "+featureID+
  88. " in this Shapefile");
  89. return null;
  90. }
  91. Object attribute = feature.getAttribute(attributeName);
  92. T a = null; // The attribute cast to it's correct class.
  93. if (clazz.isAssignableFrom(clazz)) {
  94. a = (T) attribute;
  95. }
  96. else {
  97. System.err.println("The attribute "+attributeName+" cannot be assigned to a "+
  98. clazz.getName()+", it is a: "+attribute.getClass().getName());
  99. }
  100. return a;
  101. }
  102. else { // No features in this Shapefile
  103. return null;
  104. }
  105. }
  107. /**
  108. * Add a new attribute to this Shapefile.
  109. * @param attributeName The name of the attribute to add.
  110. * @param valuesClass The class of the values to be added.
  111. * @param attributeValues A map of the IDs of each feature and the associated value of the
  112. * new attribute
  113. * @return True if the operation was successful, false otherwise.
  114. */
  115. public boolean addAttribute(String attributeName, Class<?> valuesClass, Map<Integer, Object> attributeValues) {
  116. if (!this.checkFeatures()) {
  117. return false;
  118. }
  119. // Check the input values are ok
  120. List<Integer> badIDs = new ArrayList<Integer>();
  121. for (Integer i:attributeValues.keySet())
  122. if (!this.features.containsKey(i))
  123. badIDs.add(i);
  124. if (badIDs.size()>0) {
  125. System.err.println("Shapefile.addAttribute() error: could not find features associated " +
  126. "with the following IDs: "+badIDs.toString());
  127. return false;
  128. } // if badIDs
  129. /* Method works be re-building all features with the new attributed added */
  130. // Create a feature type builder to create new features with the added attribute
  131. SimpleFeatureTypeBuilder featureTypeBuilder = new SimpleFeatureTypeBuilder();
  132. // Use first feature to initialise the feature builder
  133. featureTypeBuilder.init(features.values().iterator().next().getFeatureType());
  134. // Add the new attribute
  135. featureTypeBuilder.add(attributeName, valuesClass);
  136. // Create a feature builder to create the new features
  137. SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureTypeBuilder.buildFeatureType());
  138. // Iterate over all existing features, creating new ones with the added attribute
  139. Map<Integer, SimpleFeature> newFeatures = new Hashtable<Integer, SimpleFeature>();
  140. for (Integer id:this.features.keySet()) {
  141. SimpleFeature newFeature = featureBuilder.buildFeature(String.valueOf(id));
  142. SimpleFeature existingFeature = this.features.get(id);
  143. // Add all existing attributes to the new feature
  144. for (int i = 0; i < existingFeature.getAttributeCount(); i++) {
  145. newFeature.setAttribute(i, existingFeature.getAttribute(i));
  146. }
  147. // Add the new attribute to the new feature
  148. newFeature.setAttribute(attributeName, attributeValues.get(id));
  149. // Replace the existing feature with the new one
  150. newFeatures.put(id, newFeature);
  151. }
  152. // Finally replace all old features with the old ones
  153. for (Integer id:this.features.keySet()) {
  154. this.features.put(id, newFeatures.get(id));
  155. }
  156. return true;
  157. }
  159. /** Make sure there are some features in this Shapefile, return fals if not. */
  160. private boolean checkFeatures() {
  161. if (this.features==null || this.features.size()==0)
  162. return false;
  163. else
  164. return true;
  165. }
  167. /**
  168. * Read in all objects stored in the shapefile, adding them to this Shapefile object.
  169. * @return true if everything was read in successfully, false otherwise.
  170. */
  171. public boolean readShapefile() {
  173. this.clear(); // Clear all objects from this Shapefile
  175. // Connection to the shapefile
  176. Map<String, Serializable> connectParameters = new HashMap<String, Serializable>();
  178. try {
  179. connectParameters.put("url", this.file.toURI().toURL());
  180. connectParameters.put("create spatial index", true);
  181. DataStore dataStore = DataStoreFinder.getDataStore(connectParameters);
  183. // we are now connected
  184. String[] typeNames = dataStore.getTypeNames();
  185. String typeName = typeNames[0];
  187. this.featureSource = dataStore.getFeatureSource(typeName);
  188. FeatureCollection<SimpleFeatureType, SimpleFeature> collection = featureSource.getFeatures();
  189. FeatureIterator<SimpleFeature> iterator = collection.features();
  191. try {
  192. while (iterator.hasNext()) {
  193. SimpleFeature feature =;
  194. // Set the feature's ID
  195. int id = 0;
  196. try {
  197. if (this.idColumn!=null)
  198. id = (Integer)feature.getAttribute(this.idColumn);
  199. else
  200. id = Integer.parseInt(feature.getID());
  201. }
  202. catch (ClassCastException e) {
  203. System.err.println("Shapfile.readObjects() error: cannot read integer ids from the " +
  204. "column: "+this.idColumn+". Check this column stores unique integer IDs.");
  205. return false;
  206. }
  207. catch (NullPointerException e) {
  208. System.err.println("Shapfile.readObjects() error: cannot read integer ids from the" +
  209. "column: "+this.idColumn+". Check this column stores unique integer IDs.");
  210. return false;
  211. }
  212. catch (NumberFormatException e) {
  213. System.err.println("Shapfile.readObjects() error: cannot cast this feature's " +
  214. "ID to an integer. (?)");
  215. return false;
  216. }
  218. if (features.containsKey(id)) {
  219. System.err.println("Shapefile.readObjects() error: this feature's ID ("+id
  220. +")is not unique ");
  221. return false;
  222. }
  223. features.put(id, feature);
  224. Geometry geometry = (Geometry) feature.getDefaultGeometry();
  225. geometries.put(id, geometry);
  226. } // while iterator.hasNext()
  227. } finally {
  228. if (iterator != null) {
  229. iterator.close();
  230. }
  231. }
  232. } catch (MalformedURLException e) {
  233. e.printStackTrace();
  234. return false;
  235. } catch (IOException e) {
  236. e.printStackTrace();
  237. return false;
  238. }
  239. return true;
  240. } // readShapefile
  242. /**
  243. * Write out all the features stored in this Shapefile to a shapefile.
  244. * @param outputFileName The name of the shapefile to write to.
  245. * @return True if the operation was a success, false otherwise.
  246. */
  247. public boolean writeShapefile(String outputFileName) {
  248. if (!this.checkFeatures()) {
  249. return false;
  250. }
  251. // Check the output file can be written to
  252. File outFile = new File(outputFileName);
  253. // if (!outFile.canWrite()) {
  254. // System.err.println("Shapefile.writeShapefile() error: cannot write to the shapefile: "+outputFileName);
  255. // return false;
  256. // }
  257. // Create a feature collection to write the features out to
  258. FeatureCollection<SimpleFeatureType, SimpleFeature> outFeatures = FeatureCollections.newCollection();
  259. for (SimpleFeature f:this.features.values()) {
  260. outFeatures.add(f);
  261. }
  262. try {
  263. // Don't really get the rest, copied from the GeoTools tutorial.
  264. DataStoreFactorySpi factory = new ShapefileDataStoreFactory();
  265. Map<String, Serializable> create = new HashMap<String, Serializable>();
  266. create.put("url", outFile.toURI().toURL());
  267. create.put("create spatial index", Boolean.TRUE);
  268. ShapefileDataStore newDataStore = (ShapefileDataStore) factory.createNewDataStore(create);
  269. newDataStore.createSchema(outFeatures.getSchema());
  270. Transaction transaction = new DefaultTransaction("create");
  271. String typeName = newDataStore.getTypeNames()[0];
  272. FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
  273. featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) newDataStore.getFeatureSource(typeName);
  274. featureStore.setTransaction(transaction);
  275. try {
  276. featureStore.addFeatures(outFeatures);
  277. transaction.commit();
  278. } catch (Exception problem) {
  279. System.out.println("Shapefile.writeShapefile() caught a problem trying to write: "+problem.toString());
  280. problem.printStackTrace();
  281. transaction.rollback();
  282. return false;
  283. } finally {
  284. transaction.close();
  285. }
  287. } catch (IOException e) {
  288. System.err.println("Shapefile.writeShapefile() caught an IOException trying to write shapefile.");
  289. e.printStackTrace();
  290. return false;
  291. }
  292. return true;
  293. }
  295. /**
  296. * Clears all objects from this Shapefile, useful for when the shape file is going to be re-read.
  297. */
  298. private void clear() {
  299. this.geometries.clear();
  300. this.features.clear();
  301. }
  303. /**
  304. * Resets this <code>Shapefile</code> by removing all existing features and re-reading the original
  305. * shapefile.
  306. */
  307. public void reset() {
  308. this.clear();
  309. this.readShapefile();
  310. }
  312. /**
  313. * Return the ID's of all the features in this shapfile. This can be used to iterate over all
  314. * <code>SimpleFeature</code>s or all <code>Geometry</code>s.
  315. * @return The ID of every feature currently in this <code>Shapefile</code>.
  316. */
  317. public Set<Integer> getFeatureIDs() {
  318. return this.features.keySet();
  319. }
  321. /**
  322. * Get the feature with the associated ID.
  323. * @param id
  324. * @return The Feature or null if no feature is found.
  325. */
  326. public SimpleFeature getFeature(int id) {
  327. if (!this.features.containsKey(id)) {
  328. System.out.println("Shapefile.getFeature() error, no feature found with ID: "+id);
  329. }
  330. return this.features.get(id);
  331. }
  333. /**
  334. * Get the geometry of the object with the associated ID.
  335. * @param id
  336. * @return The Geometry or null if no feature is found.
  337. */
  338. public Geometry getGeometry(int id) {
  339. if (!this.geometries.containsKey(id)) {
  340. System.out.println("Shapefile.getFeature() error, no feature found with ID: "+id);
  341. }
  342. return this.geometries.get(id);
  343. }
  345. }

New book chapter: “Open Source Approach to Contemporary Research: The Case of Geo-Information Technology”

Here is the link for my new book chapter which talks about open source technologies. The chapter “Open Source Approach to Contemporary Research: The Case of Geo-Information Technology” talks about the influence of open source paradigm in modern economic arena. It focus on scientific research and elaborates on examples from the geo-information world such as OpenStreetMap. It is a description of open scientific research and explains the links with open source software movement.
In case you read it, I am open to comments and critique. We live in an open world after-all.

R library for spatial microsimulation

Spatial microsimulation is a method where we construct small area population data from the combination of various data sources. In order to perform this combination of census and survey data, we need an R library to standardize the procedure.

I’ve recently developed “sms” R library which combines census and survey data by using Simulated Annealing or Hill Climbing algorithms. Here are the links of the library:

Barplot in R with subtitle

bar plot imageThis is a simple barplot with subtitle describing the sample. Elegant and efficient.

  1. ##' Create Barplot of a table and add a lable with value (absolute or percentage)
  2. ##'
  3. ##' @title doBarPlots
  4. ##' @param inTable
  5. ##' @param percentage
  6. ##' @param subtitle
  7. ##' @param main
  8. ##' @param ylab
  9. ##' @return
  10. ##' @author Dimtiris Kavroudakis,
  11. doBarPlots = function(inTable, percentage=F, subtitle=T,main="This is the bar plot", ylab="ylab"){
  12. barpos=barplot(inTable,
  13. main=main,
  14. ylab=ylab,
  15. names.arg=unlist(dimnames(inTable)),
  16. border="blue", density=c(80) )
  18. sub=paste(length(inTable),"categories | ",sum(inTable),"cases")
  19. if(subtitle){mtext(sub, side=3, line=0.3, cex=0.9)}
  21. library(plotrix)
  22. if (percentage){
  23. labels=inTable/(sum(inTable)/100)
  24. boxed.labels(barpos,inTable/2, paste(formatC(labels, 1, format="f"), "%", sep="") )
  25. } else {
  26. labels=inTable
  27. boxed.labels(barpos,inTable/2, formatC(labels) )
  28. }
  29. box()
  30. }
  32. x = c(3,4,3,3,3,4,1,2,2,2,3,1,4)
  33. xtable=table(x)
  34. doBarPlots(xtable)

Simple distribution plot in R

plot distribution of a sample

Plot the distribution of a sample as bars and add a histogram line for visualizing the sample characteristics.

  1. ##' Plot distribution of a sample with bars, lines and rug.
  2. ##' @title
  3. ##' @param x
  4. ##' @return
  5. ##' @author Dimtiris Kavroudakis,,
  6. plotDistribution = function (x) {
  7. N = length(x)
  8. hist( x,col = "light blue",
  9. probability = TRUE)
  10. lines(density(x), col = "red", lwd = 3)
  11. rug(x)
  12. }
  14. x = c(3,4,4,4,7,5,5,5,6,8,4,2)
  15. plotDistribution(x)

Εγκατάσταση πακέτων της R και πρόβλημα με το proj_api.h

Κατά την προσπάθεια εγκατάστασης κάποιων χωρικών πακέτων της R, όπως η rgdal και το sqlitemap, μπορεί αυτή να αποτύχει διότι δεν μπορεί να βρεθεί το proj_api.h.

Το proj_api.h όπως φαίνεται δεν έρχεται μαζί με τα αρχεία του r-base ή κάποιου άλλου πακέτου και ανήκει στην κατηγορία των  header files. Η λύση όμως είναι πάρα πολύ εύκολη. Για να μπορέσουν να εγκατασταθούν αυτά τα πακέτα δεν χρειάζονται μόνο τα  αρχεία του proj-bin πακέτου (τα οποία χρησιμοποιούνται για να λειτουργεί κάποιο λογισμικό με γεωχωρικές δυνατότητες) αλλά είναι απαραίτητα και τα αρχεία ανάπτυξης (-dev) του “proj”, οπότε απλά εγκαθιστάμε το libproj-dev πακέτο από το αποθετήριο και τέλος!

Annotation αρχείων .pdf σε Linux

Deutsch: Logo des Adobe Portable Document Format

Image via Wikipedia

Αυτό το ζήτημα είναι πραγματικά ζωτικής σημασίας  για όσους εργάζονται σ’ ένα γραφείο και ιδιαίτερα όλους εμάς στον ακαδημαϊκό χώρο, οι οποίοι χρειάζεται να διατρέχουμε σε πάρα πολλά αρχεία .pdf καθημερινά, και τα οποία σημειώνουμε και μοιραζόμαστε. Όταν όμως συνδυάσουμε την επιθυμία να χρησιμοποιήσουμε το αγαπημένο μας λειτουργικό σύστημα Linux με την ανάγκη μας για βασικές διαδικασίες επεξεργασίας των αρχείων .pdf, συναντάμε πολλούς μικρούς τοίχους, όσον αφορά τις δυνατότητες επεξεργασίας αυτών των αρχείων από τα διάφορα, διαθέσιμα, ανοιχτού κώδικα λογισμικά. Κάθε λογισμικό μπορεί να κάνει κάποια διαδικασία αλλά στερείται κάποιας άλλης, ενώ πολλές φορές είναι αρκετά επίπονη η διαδικασία επεξεργασίας ενός τέτοιου αρχείου. Δε θα μιλήσω για πολλά λογισμικά, παρά μόνο για τρία: Okular, Xournal και JPDF Bookmarks.

Ο στόχος ήταν να μπορώ να επισημαίνω (annotate) κάποιο κείμενο σε αρχεία .pdf και παράλληλα να μπορώ να δημιουργώ εύκολα

penguin Tux, the Linux Mascot

Image via Wikipedia

σελιδοδείκτες μέσα σ’ αυτά. Το Okular είναι πραγματικά ένα καταπληκτικό πρόγραμμα (για μένα, τουλάχιστον…), το οποίο είναι γρήγορο, απλό, έξυπνο,  με αυτόματες διαδικασίες στο παρασκήνιο, αποτελεσματικά εργαλεία εξαγωγής κειμένου και εικόνας, αρκετά και χρήσιμα εργαλεία επισήμανσης κειμένου! Αλλά! Οι επισημάνσεις δεν γράφονται πάνω στο αρχικό αρχείο, αλλά αποθηκεύονται σε ένα φάκελο ρυθμίσεων του προγράμματος, οπότε αν θα ήθελε κάποιος να μετακινήσει τα αρχεία του ή να τα μοιραστεί, θα έπρεπε να τα συνοδεύει και από τον φάκελο των ρυθμίσεων καθώς και από το Okular. Κι όμως δεν με ενοχλεί αυτό. Οπότε προχωράω παρακάτω και έρχομαι στο  JPDF Bookmarks, το οποίο μπορεί να δημιουργήσει σελιδοδείκτες και μάλιστα με τη δυνατότητα επιλογής κειμένου από το αρχείο. Διαθέτει, δηλαδή, ένα εργαλείο επιλογής κειμένου και χρησιμοποιεί το επιλεγμένο κείμενο ως όνομα του σελιδοδείκτη. Καταπληκτικό! Διότι έτσι μπορώ να χρησιμοποιήσω το αρχείο .pdf στα mindmaps που κατασκευάζω (χρησιμοποιώ το Sciplore) και οι σελιδοδείκτες-κείμενο να αποτελούν τα “κλαδιά” του χάρτη μου.

Το πρόβλημα. Όταν κάποιο άλλο πρόγραμμα γράψει ένα .pdf αρχείο, ακόμα και με το ίδιο όνομα, στον ίδιο φάκελο,  το Okular θεωρεί ότι είναι ένα εντελώς καινούργιο αρχείο, γράφει ένα νέο αρχείο ρυθμίσεων και επισημάνσεων για το .pdf κι έτσι χάνονται οι επισημάνσεις που είχαν γίνει μέχρι τότε! Αυτό περιπλέκει κατά πολύ τα πράγματα. Κι εδώ μπαίνει το Xournal. Τις δυνατότητές του, οφείλω να πω, ότι μου τις υπέδειξε ο Σταύρος  Δαλιακόπουλος, κατά την τελευταία συνάντηση χρηστών Linux στη Μυτιλήνη.

Το Xournal είναι ένα πρόγραμμα για σημειώσεις και σχεδίαση με πένα, πρωτίστως, αλλά δευτερευόντως διαθέτει τη δυνατότητα επισήμανσης αρχείων .pdf. Διαθέτει μολύβι για ελεύθερο σχέδιο, εργαλείο επισήμανσης σε διάφορα χρώματα με διαφάνεια, δυνατότητα εύκολης προσθήκης κειμένου καθώς και εικόνας, οπουδήποτε στο αρχείο ή σαν παρασκήνιο. Δεν είναι τόσο εύκολη η επισήμανση όσο με το Okular αλλά το συγκεκριμένο πρόγραμμα έχει τη δυνατότητα να εξάγει σε αρχείο .pdf με όλες τις προσθήκες του χρήστη ενσωματωμένες. Αν, παρόλα αυτά, δε θέλω να αλλοιώσω αρχικό αρχείο ή δε θέλω να δημιουργήσω ένα νέο, μπορώ να αποθηκεύσω όλες τις προσθήκες μου στην εγγενή μορφή αρχείο .xoj, το οποίο μπορώ να επεξεργαστώ ξανά και το εξάγω σε μορφή αρχείου .pdf σε κάποια άλλη μελλοντική στιγμή.  Το σημαντικό όμως είναι ότι μπορώ να αποθηκεύσω τις προσθήκες μου στο αρχικό αρχείο και παράλληλα ν’ αποθηκεύσω τους σελιδοδείκτες από το JPDF Bookmarks και όλα να είναι εκεί, όπως τα θέλω.

Όποιος και αν είναι ο σκοπός του χρήστη, το Xournal θεωρώ ότι είναι ο πιο εύκολος και φιλικός τρόπος επισήμανσης αρχείων .pdf σε περιβάλλον Linux. Για όσους αποφασίσουν να του δώσουν μια ευκαιρία, παραθέτω κάποιες αλλαγές που μπορεί κάποιος να κάνει μία φορά στο αρχείο ρυθμίσεων του προγράμματος για την διευκόλυνσή του κάθε φορά που έχει να επισημάνει ένα κείμενο. Το αρχείο ρυθμίσεων βρίσκεται στο  /home/.xournal/config. Αν δεν υπάρχει, θα πρέπει να επιλέξετε από “Options > Save Preferences” ώστε να δημιουργηθεί.

Ο χάρακας θα πρέπει να είναι ενεργοποιημένος ώστε το εργαλείο επισήμανσης να δημιουργεί ίσιες γραμμές.


Για να ξεκινά το εργαλείο επισήμανσης από προεπιλογή.


Για να ξεκινά το πρόγραμμα μεγιστοποιημένο με ζουμ 150%.


Οι επόμενες ρυθμίσεις αφορούν το εργαλείο επισήμανσης. Ρυθμίζονται οι προεπιλογές για το πάχος της γραμμής επισήμανσης, το ίδιο το πάχος, το χρώμα και η διαφάνεια, αντίστοιχα.


Οι ρυθμίσεις προέρχονται από εδώ

Οδηγίες σύνδεσης VPN Πανεπιστημίου Αιγαίου σε Linux (Ubuntu)

Μερικές φορές (…) οι χρήστες Linux βρισκόμαστε στη δυσάρεστη θέση να συνειδητοποιούμε ότι κάποιοι μας ξέχασαν. Μια τέτοια περίπτωση ήταν  όταν προσπάθησα για πρώτη φορά να συνδεθώ με το Ιδιωτικό Εικονικό Δίκτυο (VPN) του πανεπιστημίου μου και διαπίστωσα με έκπληξη ότι, ενώ υπήρχαν οδηγίες βήμα-βήμα για την ρύθμιση του VPN για Windows, όταν προσπάθησα να δω τις αντίστοιχες για Linux ο σύνδεσμος με παρέπεμπε σε μια αγγλική σελίδα γεμάτη τεχνικότητες.

Βήμα 1: Άνοιγμα “Συνδέσεις Δικτύου” από τις ρυθμίσεις.

Βήμα 2: Μετάβαση στη καρτέλα “VPN” και “Προσθήκη” νέας σύνδεσης VPN.

Στο παράθυρο που εμφανίζεται επιλέγεται το πρωτόκολλο PPTP επειδή είναι συμβατό με τον server του Πανεπιστημίου Αιγαίου. Επιλέγεται η “Δημιουργία”.


Βήμα 3: Ρύθμιση της σύνδεσης

Αφού συμπληρωθούν τα πεδία:

  • Όνομα σύνδεσης
  • Gateway
  • Username (με ή χωρίς το “aegean/” μπροστά από το username σας αναλόγως ιδιότητας)
  • Συνθηματικό,

επιλέγετε το κουμπί “Advanced”


Βήμα 4: Ρύθμιση των μεθόδων πιστοποίησης στο παράθυρο “PPTP Advanced Options”

Απενεργοποιούμε “EAP” και  “PAP”.

Μετά την επιλογή του “Εντάξει” και του “Αποθήκευση” στο προηγούμενο παράθυρο, η σύνδεση θα πρέπει να λειτουργεί.


Αυτές οι ρυθμίσεις ανταποκρίνονται στην διαδικασία πιστοποίησης για το Πανεπιστήμιο Αιγαίου, αλλά μπορείτε να το δοκιμάσετε  και για άλλα ιδιωτικά δίκτυα. Αν δεν λειτουργεί, τότε θα πρέπει να αλλάξετε αυτές τις τελευταίες ρυθμίσεις πιστοποίησης για τον οργανισμό/εταιρεία σας.

Aναπτυξιακή προοπτική των τουριστικών υπηρεσιών

Η τουριστική οικονομική δραστηριότητα χαρακτηρίζεται ως προσφορά υπηρεσιών οι οποίες έχουν συμπληρωματικό χαρακτήρα. Η παροχή ενός τουριστικού προϊόντος προϋποθέτει και την παροχή κάποιου αλλού. Έτσι λοιπόν για να ενοικιαστεί ένα δωμάτιο σε μια περιοχή του νησιού μας, προϋποτίθεται η ύπαρξη μεταφορών (δρόμων και μέσων), ενός τουριστικού αξιοθέατου (παραλία, αρχαιολογικός χώρος) αλλά και σε κάποιες περιπτώσεις η παρουσία ενός σημείου διασκέδασης (εστιατόριο, ταβέρνα, καφέ). Αυτός ο συμπληρωματικός χαρακτήρας, κάνει το τουριστικό προϊόν πιο ευάλωτο σε προβλήματα καθώς ακόμα και ένας κρίκος της αλυσίδας να είναι προβληματικός, τότε επηρεάζεται συνολικά η αξιοπιστία όλης της αλυσίδας.

Είναι λοιπόν κατανοητό πως για να διασφαλιστεί η άνοδος της τουριστικής δραστηριότητας σε ενα νησί, προϋποτίθεται η σωστή επίβλεψη και διαχείριση αυτής της ιδιότυπης αλυσίδας τουριστικών υπηρεσιών έτσι ώστε να υπάρχει “ομαλή ροή” υπηρεσιών χωρίς απρόοπτα σε κανένα επιμέρους στάδιο και να διασφαλίζεται η σύμπραξη και συνέργεια των τουριστικών ενεργειών.

Η σύμπραξη είναι όταν δυο ή περισσότερες επιχειρήσεις δουλεύουν μαζί, συγχρόνως, για την παραγωγή ενός προϊόντος. Η διατήρηση της σύμπραξης από τοπικές επιχειρήσεις μπορεί να αποβεί εξαιρετικά κερδοφόρα για την τοπική οικονομία. Δηλαδή, αν οι τουριστικές επιχειρήσεις, συστηματικά επιλέγουν να συμπράττουν με άλλες τοπικές επιχειρήσεις και όχι με επιχειρήσεις εκτός νησιού, τότε η τοπική οικονομία ενεργοποιείται και ενδυναμώνετε.

Η έννοια της συνέργειας, αναφέρεται στην συνδυασμένη δράση προς την υλοποίηση ενός σκοπού. Στην τουριστική δραστηριότητα αυτό μεταφράζεται ως την συνδυασμένη επιχειρηματική δράση τοπικών επιχειρήσεων ώστε να παρέχουν ολοκληρωμένο τουριστικό προϊόν. Παράδειγμα αποτελεί μια πιθανή συνεργασία ακτοπλοϊκών γραμμών με την διοργάνωση ενός υποτιθέμενου ποδηλατικού αγώνα και την σύμπραξη μιας ομάδας ξενοδοχείων και εστιατορίων. Αυτό το μπουκέτο υπηρεσιών, προσφέρει συμπληρωματικές υπηρεσίες καθώς εκεί που τελειώνουν οι υπηρεσίες του ενός φορέα, ξεκινάν αυτές του επόμενου. Η συνέργεια λοιπόν τοπικών επιχειρήσεων είναι κάτι που θα ενεργοποιήσει τη τουριστική δραστηριότητα και επιπροσθέτως θα διασφαλίσει οικονομικά οφέλη σε τοπικό επίπεδο.

Ο σχεδιασμός και η εφαρμογή αυτών των δράσεων, εγείρει θέματα ποιότητας και ποικιλίας τοπικών προϊόντων καθώς και ερωτήματα για την ετοιμότητα και επιθυμία τοπικών επιχειρήσεων να συμπράξουν και να συνεργαστούν.


The Annual meeting, of Eurogeo (2-5 June 2011, Athens, Greece) finished. I presented at Friday 3 of June. The presentation was good. This was an oportunity to meet with european geographers and listen to some intresting presentations on various GIS, geography topics.

Programming task list

todo image

In a daily programming routine, when switching from project to project and from library to library, it is very common to need some extra time to re-adjust yourself to the state of the project you left it last month. This situation is very common when you develop various software or you contribute to a development process where you are not the only developer. This switch-on / switch-off is difficult. This is why a to-do list is needed. A task queue is very useful:

  • to have a hierarchy in the tasks (what is more important than other)
  • to remember where you left it
  • to remember what need to be done

This process is very essential for the development of average and large projects. Nobody ever developed a software all-in-once. The programming process is a repetitive (every week, every day) one, and needs a “glue” for the linkage between the events. A clean and robust hierarchy of tasks and problems is a good tool to help you re-adjust your mind and boost your productivity.

.odt Statistics (nautilus script)


Just created a nautilus script to get text statistics from an ODT file (OpenOffice Writer). Creates a context menu (right click) and then a Tk windows appears with the statistics. Simple and effective.
Download here
Installation: Execute “”
Licence: GPL-3

ODF extension – MSOffice

Open Document Format (ODF) is an open standard file format and others use. File extensions include .odt (text), .ods (spreadsheet), and .odp (presentation). It is a well recognised global file extension. You can also unzip the file and see its contents. By default, Microsoft Office does not open these file formats. In order to help the market penetration of Open Office documents you can use an MSOffice plugin which enables you to open ODF. Of course the best solution is to use which can be easily installed in both Windows and Linux systems.
Office 2003
Download and install the Sun ODF Plugin should just work. You can download the Sun ODF Plugin from here.
Office 2007

  1. First you need to Install Service Pack 1 for Office 2007
  2. Install Sun ODF Plugin for Microsoft Office
  3. Open ODT document via File – Open
  • If you don’t have administrator privileges to install software, you can try an online converter such as Zamzar or Media Convert. You can also upload ODT documents to Google Docs or Zoho Writer.
  • If you want to open ODT documents locally but want to stay away from MS Office, try the lightweight, cross-platform Abiword or the full-blown suite of

Συνάντηση φίλων ελ/λακ-Linux στη Μυτιλήνη

Συνάντηση φίλων ελεύθερου λογισμικού – Linux στη Μυτιλήνη σήμερα Σάββατο 13 Νοεμβρίου 14:00
καφέ “Πανελλήνιον”.
Θα υπάρχει και ελεύθερο Wifi.

Mitilini Linux User Group