Donnerstag, 8. April 2010

Can not use an object as parameter to a method.

A nice example how XCode's Objective-C compiler gives greatly inscrutable compilation error descriptions:

error: can not use an object as parameter to a method.
Which means:
Objects, i.e. instances of classes, can only given to a function via a pointer (id). This is because in contrast to structs (e.g. CGRect) and basic data types (int, float, etc.), classes may have custom constructors and deconstructors which the compiler is not able to call for you when a copy shall be given to the function. So basically:

- (NSString) sayYeah { NSLog(@"YEAH"); }; // won't work

- (NSString*) sayMaan { NSLog(@"MAAN"); };  // will work, notice the *

Freitag, 19. März 2010

RSQLite Hints

I needed to convert a shapefile into a SQLite data base, which should be easy using R's rgdal/maptools and RSQLite packages, no? If you're new to R like me, you may run into some troubles, so here are some issues:

1. Basic RSQLite database interaction
The package RSQLite is (unfortunately) merely a driver for R's stanardized data base interface DBI, which is rather poorly documented and kind of unintuitive. This means that we need to use functions from the DBI package to interact with our database, which makes things unnecessarily complicated. But whatever, here is a basic interaction:

library(RSQLite)
library(DBI)


# set up SQLite DB connection
db <- dbConnect(dbDriver("SQLite"), dbname = "mydatabase.sqlite")

# query
addresses <- dbGetQuery(db, SELECT * FROM addresses")

# close
dbDisconnect(db)


If you google around a little, you'll see that we basically have to basic functions for those kinds of queries: dbGetQuery and dbSendQuery .. the difference here is that with the latter, you will have to catch the result and use the 'fetch' command to grab the data and then cleanup using the dbClearResult, i.e. you need three commands. This must be done after every SQL query, even if you don't care about the response like after a "INSERT INTO" command. In a nutshell: use dbGetQuery which does this all for you.


2. "CREATE DATABASE does not work!!"
I'm not sure if this is a SQLite thing, but at least you can not/don't need to do that in R's RSQLite interface. In other words, you can only have one single database per SQLite-file. So, no big thing, just start off with "CREATE TABLE". :I



3. Large Amounts of Data
When one uses a database, normally there is quite a few data in the game. What to do if you need to get a lot of data into or out of the data base? As soon as you start using for loops to add rows from your data base, you'll probably run into performance problems since apparently setting up the connection for each query takes considerable time. Two work arounds:


a. dbGetPreparedQuery with manual transaction:

dbBeginTransaction(db)
dbGetPreparedQuery(db, "INSERT INTO addresses (name, phone, address) VALUES (?,?,?)", bind.data=new_empolyee_data);
dbCommit(db)

This does not excecute the query until dbCommit, in other words, you fill something like a buffer. The dbGetPreparedQuery automatically fills out the "?"-fields in your query string and submit those strings to the database. Again, there is a dbSendPreparedQuery alternative, where you'll have to clear the result manually after the command.
The bind.data parameter requires a data frame (what is that? boo.). So if you get an error like:
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "dbGetPreparedQuery", for signature "SQLiteConnection", "character", "matrix"
.. convert it to a data frame using the as.data.frame(..) function, see example below.


b. write or read tables as a whole:

You can conveniently add a full table to the data base using the dbWriteTable command. The field names in SQL are taken from the column names of your matrix. Numeric values are stored in a 'REAL' field, strings in a general TEXT field. I don't know if you can customize this, it's rather quick and dirty, so to say.
# give the data matrix appropriate column names
colnames(addr) <- c("key", "empolyee", "phone", "address")
# add the table as data.frame to the db
dbWriteTable(db, "new_addresses", as.data.frame(addr))

Here again, this must be a data frame to work correctly.
If you want to insert something into an already existing data base you can use SQL to do that on the database itself:
INSERT INTO addresses (name, phone, address)
SELECT * FROM new_addresses

Montag, 1. März 2010

R maptools: Shapefile Polygons: Hole attribute

Problem: When I import a Shape File ( readShapePoly ) with the R package maptools, it does not seem to import that 'hole' attribute correctly. All the boolean values are set to 'FALSE'.

Solution: This attribute is not present in the shapefile itself, thus it cannot be imported. There is a function checkPolygonsHoles in the maptools package to fill out the attribute fields in your imported shapefile structure. I.e. you need to caluculate the value of that hole-field yourself, like so:

shp <- readShapePoly(...);
shp@polygons <- lapply(shp@polygons, checkPolygonsHoles);

R Search and Replace

How can one replace certain characters or sequences of characters in a string?

I searched for a function that does that for quite a while but to no avail. But, using the strsplit & paste functions, one can do it like this:

streplace <- function(string, searchterm, replacestring) {
    string <- paste(strsplit(string,paste("[",searchterm,"]", sep=""))[[1]], collapse=replacestring);
    return(string);
}

With the usage for example: htmlstring = streplace(mytext, "ä", "&auml;")

Montag, 1. Februar 2010

Tinn-R Error At Startup

(on WinXP)
When trying to connect to R or RGui with Tinn-R, one may get the following error: 

Die Anweisung in "0x00000000" verweist auf Speicher in "0x00000000". Der Vorgang "read" konnt nicht auf dem Speicher durchgeführt werden.

(Basically: The instruction in "0x0" referes to memory segment "0x0". The process "read" could not be executet on the memory.)

In my case, for some odd reason, this was resolved selecting the compatibility option "deactivate visual desings" ("Visuelle Designs deaktivieren) . I.e. right click the application executable or shortcut and selecting Properties. The setting can then be found in the "Compatibility" Tab.

Donnerstag, 28. Januar 2010

R - Open Source Statistics

[Intro Article.. R pretty much rocks. www.r-project.org , needs better GUI. ]

Basic Matlab Function Equivalents:

Matlab RDescription
ones(n,m)*a mat.or.vec(n,m)*a initialize matrix with values
rand(m)runif(n,min,max)n float random numbers between min&max.
  sample(min:max,n)picks n elements of the data given as first argument (i.e. integers!)
reshape(a,[n,m..])matrix(a,nrow=n,ncol=m)reshape data structure into a matrix
for i=1:30
    op(i);
end
for (i in 1:30); {
    op(i);
}
for loop!
function [x y z] = uvw(a,b,c=3)
    op(a,b,c);
end
uvw<-function(a,b,c=3) {
    op(a,b,c);
}
function definition 
a = [];a <- matrix(nrows=0,ncols=3)how to init a matrix to be grown dynamically
a = [b;c;d];a <- rbind(b,c)concatenate matrix vertically
a = [b,c,d];a <- cbind(b,c,d)concatenate matrix horizontally
......

Freitag, 15. Januar 2010

Google Earth: Move Camera to certain Viewpoint

Problem:
How do I move the camera to a certain viewpoint, given as [world coordinates, height, azimuth and elevation] in Google Earth?

I recently had to re-stage some perspective aerial photos, knowing the location and height of the plane, as well as the viewing direction. Unfortunately, the Google Earth (5.0) UI does not seem to offer a possibilty to just enter those viewpoint parameters.
Now, the trick is to use placemarks: set a placemark somewhere and open its properties dialog.
In this dialog, we can enter the exact coordinates, azimuth and elevation. So far so good, but it's not yet perfect:
We can also specify the height in this dialog, but this will only move the placemark up in the air - not our viewpoint! The camera will always hover around the projection of the placemark on the ground level. But again there is a dodge to get this working:
Save your viewpoint as KML (plaintext), and open it with a text editor. You will see the xml-structure of the KML file, containing all the information about our placemark including the viewing direction:


<?xml version="1.0" encoding="UTF-8"?>
<kml ...>
<Document>
    <name>aerialviewpoint.kml</name>
    <Placemark>
        <name>my point in the air</name>
        <open>1</open>
        <LookAt>
            <longitude>8.765</longitude>
            <latitude>47.474</latitude>
            <altitude>1000</altitude>
            <range>1</range>
            <tilt>85</tilt>
            <heading>120</heading>
            <altitudeMode>absolute</altitudeMode>
        </LookAt>
        <Point>
            <extrude>1</extrude>
            <altitudeMode>absolute</altitudeMode>
            <coordinates>8.765,47.474,1000</coordinates>
        </Point>
    </Placemark>
</Document>
</kml>

Here we can change the height of the viewpoint (field altitute in the -Tag) to our desired height. Then save and reopen the KML file with Google Earth, where we will fly directly to this viewpoint. []