Skip to content

help to make a map on R

5 messages · Ronaldo Reis Jr., Magnus Lie Hetland, Ott Toomet +2 more

#
Hi all,
I need a little help for construct an state's map on R.

The first problem is to get the data.

I have a datafile of longitude and latitude in the follow format:

trajectory	latitude	longtude
T		-22.045618	-51.287056
T		-22.067078	-51.265888
T		-22.067039	-51.207249

T		-22.059690	-48.089695
T		-22.075529	-48.074608
T		-22.072460	-48.044472

T		-22.062767	-48.298473
T		-22.077349	-48.322140
T		-22.047001	-48.347443
T		-22.054266	-48.369331
T		-22.042810	-48.392612
T		-22.064812	-48.422195
T		-22.062544	-48.443497

To read a file is simple, but I need that R change the value of
trajectory after a blank line, reading something like this:

trajectory	latitude	longitude
T1		-22.045618	-51.287056
T1		-22.067078	-51.265888
T1		-22.067039	-51.207249
T2		-22.059690	-48.089695
T2		-22.075529	-48.074608
T2		-22.072460	-48.044472
T3		-22.062767	-48.298473
T3		-22.077349	-48.322140
T3		-22.047001	-48.347443
T3		-22.054266	-48.369331
T3		-22.042810	-48.392612
T3		-22.064812	-48.422195
T3		-22.062544	-48.443497

Each trajectory is a line that is a little piece of my map.

After this, to make a map I execute:

tapply() for separate the coordinates for each trajectory, something like 
this:
$T1
[1] -51.2871 -51.2659 -51.2072

$T2
[1] -48.0897 -48.0746 -48.0445

$T3
[1] -48.2985 -48.3221 -48.3474 -48.3693 -48.3926 -48.4222 -48.4435
$T1
[1] -22.0456 -22.0671 -22.0670

$T2
[1] -22.0597 -22.0755 -22.0725

$T3
[1] -22.0628 -22.0773 -22.0470 -22.0543 -22.0428 -22.0648 -22.0625

The nest step is to make a plot with the coordinates.
And finally plot the lines for each trajectory, and all lines together, 
make a Sao Paulo's map and your cities limits.
How can I make to automatized this process? Because I can about 3000 
trajectory.

Any other idea for make this is welcome.


Thanks for all

Inte mais
Ronaldo
#
Ronaldo Reis Jr. <chrysopa at insecta.ufv.br>:
[snip]
[snip]

Not sure if this is heresy ;) but this sort of thing would be very
easy to do with a programming language such as Python, Ruby, or Perl
(or even awk) as a preprocessing step.

For example (in Python):

----------------------------------------------------------------------
num = 1
lines = iter(open('map.data'))
print lines.next(),
for line in lines:
    if line.isspace():
        num += 1
    else:
        fields = line.split()
        fields[0] += str(num)
	print '\t'.join(fields)
----------------------------------------------------------------------

Just a thought :)
#
On Wed, 2 Oct 2002, Ronaldo Reis Jr. wrote:
|Hi all,
  |I need a little help for construct an state's map on R.

I strongly recommend to take a look at package maps
(ftp://ftp.mcs.vuw.ac.nz/pub/statistics/map/), as suggested before.  It
includes maps of US (states and counties), UK (counties), New-Zealand and
China.  A pretty good descritption can be found at ,,Constructing a
geographical database'' by Richard Becker nad Allan Wilks, it is available
at web.

The problem in your case seem to be that you have not defined polylines and
polygons as are needed for the map() function.  Basically, the database
needs the definitions of line segments (borders, coastlines etc.), one
definition for one line.  Therafter you need definitions of polugons
(administrative units, lakes, cities...) desrcribed by the line segments
above.  And last, you need names for each of the polygon (you may be happy
with dummy names only).  From your description it seems to me that you don't
have descriptions of polygons.  If you have copirighted data, it is perhaps
not worth of so much work, but it depends on how much polyugons do you have.

----

If you don't want to use the package, I would suggest something following:

  |I have a datafile of longitude and latitude in the follow format:
  |
  |trajectory	latitude	longtude
  |T		-22.045618	-51.287056
  |T		-22.067078	-51.265888
  |T		-22.067039	-51.207249
  |
  |T		-22.059690	-48.089695
  |T		-22.075529	-48.074608
  |T		-22.072460	-48.044472
  |
  |T		-22.062767	-48.298473

I would perhaps use perl to transform the original file to a new one where I
give unique name for every trajectory (you may let me know if you are not
familiar with perl).

  |To read a file is simple, but I need that R change the value of
  |trajectory after a blank line, reading something like this:
  |
  |trajectory	latitude	longitude
  |T1		-22.045618	-51.287056
  |T1		-22.067078	-51.265888
  |T1		-22.067039	-51.207249
  |T2		-22.059690	-48.089695
  |T2		-22.075529	-48.074608

...

  |tapply() for separate the coordinates for each trajectory, something like 
  |this:
  |
  |> longitude <- tapply(longitude,trajectory,c)
  |> latitude <- tapply(latitude,trajectory,c)
  |The nest step is to make a plot with the coordinates.
  |
  |> plot(longitude,latitude, asp = 1, type = "n")

What about (not tested)

plot(1:2, xlim=range(unlist(longitude)), ylim=range(unlist(latitude)),
type="n")
lapply(1:length(unique(trajectory)), FUN=function(i) {
	lines(longitude[[1]], latitude[[i]])
	NULL
	}


Ott

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
"Ronaldo Reis Jr." wrote:
Hi Ronaldo,

ReadCoord <- function(file){
  ext <- readLines(con = file, n = -1)
  nam <- unlist(strsplit(ext[1], split = " "))
  nam <- nam[nam != ""]
  ext <- ext[-1]
  List <- list()
  j <- 1
  for (i in seq(along = ext)) {
    ok <- T
    coord <- character(0)
    while(ok){
      val <- unlist(strsplit(ext[i], split = " "))
      val <- val[val != ""]
      if(length(val) != 3) ok <- F
      else{
        coord <- c(coord, paste(val[1], j, sep = ""), val[2:3])
        i <- i + 1
        }
      }
    mat <- matrix(coord, ncol = 3, byrow = T)
    List[[j]] <- mat
    j <- j +1
  }
  df <- as.data.frame(do.call("rbind", List))
  names(df) <- nam
  df[,2] <- as.numeric(as.character(df[,2]))
  df[,3] <- as.numeric(as.character(df[,3]))
  dimnames(df)[[1]] <- as.character(seq(nrow(df)))
  df
}

Data <- ReadCoord("d:/analyses/travail/data/coord.txt")
attach(Data)
plot(longitude, latitude, asp = 1, type = "n")
tapply(seq(nrow(Data)),
       Data[,1],
       function(x, data) lines(data[x, "longitude"], data[x,
"latitude"]),
       data = Data)
detach()


Hope this helps,

Renaud
#
If I understand the question correctly, the solution is simpler than 
some of the other suggestions. Here is what I would do.

First, here is an example data file:

traj	lat	long
T	2.1	3.4
T	4.2	5.1
T	3.6	6.2
T	4.2	5.1

T	11.4	12.3
T	13.2	14.8
T	9.3	11.2

T	19.4	20.3
T	21.3	16.8
T	22.3	15.6
T	23.1	14.4

T	34.2	32.3
T	39.2	34.8
T	39.3	31.2

Next, here is a script to make the plot:

## read the data (the delimiter is tab character in this example)
dat <- read.delim('junk.dat',colClasses=c('character','numeric','numeric'),
                   blank.lines.skip=FALSE)

## change "T" to "T1", "T2" etc.
rl <- rle(dat$traj)
dat <- dat[dat$traj != '',]
lens <- rl$lengths[rl$lengths != 1]
dat$traj <- paste(dat$traj,
                   rep(1:lens),lens),
                   sep='')

## function for plotting lines
lfun <- function(df) lines(df$long,df$lat)

## prepare an empty plot with the correct range
ylm <- range(dat$lat)
xlm <- range(dat$long)
plot(xlm,ylm,type='n')

## add the lines to the plot, one line for each trajectory
lapply(split(dat,dat$traj),lfun)

Since you have about 3000 trajectories, the lapply() step may take a long time.

The essential steps are the use of the rle() and rep() functions. 
That, and including the blank lines while reading the data file.

Very important warning: this method assumes that whenever there is a 
blank line there is only one blank line. Never two or more blank 
lines next to each other.

I hope this helps
-Don
At 4:26 PM -0300 10/2/02, Ronaldo Reis Jr. wrote: