using ggplot's "annotation_raster" and reached R's "memory ceiling" - r

I am using R to create a floorplan of a house with several layers like below, starting from the bottom layer:
basemap: a scanned version of the floorplan which I put it at the bottom layer to aid the reading
bed: the house have several dozens of beds, scattered in different rooms of the house, they have different colours based on the characteristics of the residents
piechart: each bed has a piechart of top of it, again the piecharts are created based on the residents' other set of characteristics, some beds have piecharts, some don't.
The bed and piechart were created based on the shp file created based on the basemap (i.e. I use Mapwindow the create a vector layer, import the basemap as raster layer and put it at the bottom, then draw the beds one by one. The bed shp file is then imported into R, the bed polygons' centroid are calculated and that centroid helps to position the piecharts)
I used read.jpeg to import the basemap to imagematrix object, then use the new annotation_raster function in ggplot2 0.9 to put the basemap at the bottom map layer, since the bed layer is created based on the basemap also, the bed layer superimpose on the basemap layer perfectly in ggplot2.
I can create the map without problem - if the basemap is small enough (3000 x 3000 pixels), now I have a basemap of 8000+ x 3000+ pixels (object.size 241823624 bytes), I did not aware of the R memory issue when I was creating the shp file, the ggplot object can be compiled if I have the annotation_raster disabled, but R keeps saying that I can allocate memory with xxxMB when I try to include the basemap into the ggplot object.
I think this is nothing to do with the compression of the jpg files, as the dimension is not changed even I further compress the jpg file. But I can't resize the jpg file as my bed layer is created based on the original jpg file's dimension.
Can anyone help to shrink the size of the basemap's imagematrix, without changing the jpeg's dimension, or some other tricks to deal the R's memory limitation? Thanks.

I fixed it.
I first created a new basemap image file with width and height halved, then in the annotation_raster I did the following:
chart <- chart + annotation_raster(db$temp.basemap,
xmin=0,
xmax=basemap.xlength*2, # I stretched the image in R
ymin=0,
ymax=basemap.ylength*2) # I stretched the image in R
Now the map can be compiled within R's memory limit, the drawback I can think of is the reduce in image quality, but that is bearable, as it was 8000 x 3000 originally.

Related

How to fill map boundaries with external images?

I am creating a map of Brazil with its state boundaries, which is straight forward to achieve using ggplot2 and geom_sf.
However, this time around, instead of color filling each state with data, I want to fill each state's boundaries with an external image (png), similar to this example of the largest employer in each state.
I have tried a few settings of geom_image and even geom_flag to no avail (hence why I am not posting any code here).
Are there any suggestions on how to approach this problem?
You can try cartography::getPngLayer/pngLayer. These two functions takes a png as input, geotag and crop it to the shape of a given polygon and creates a rasterbrick object (as a tile) that you can manipulate and plot:
https://dieghernan.github.io/cartographyvignette#png-layer

How to create irregular raster with gdal using csv points

I am trying to create a irregular shaped .tiff from a csv list of points (xyz data). I am doing this using gdal_grid.
I can seem to generate the .tiff file no problem but I cannot preserve the outline / shape of the original csv points.
Everytime I generate the .tiff file it creates a raster with the size of (xmax-xmin) x (ymax-ymin) and assigns interpolated values to pixels that fall far away from my initial points.
Is it possible to generate a .tiff file of ONLY the points I provide?
For context, I am trying to generate a raster of xyz data for a river, and only want the raster in the river (not the entire bounding box of the river). I am only providing xyz data in the river.
I tried playing with the -nodata flag, and limiting -max_points to the number of points I've provided.
My final code (once everything is imported and declared):
gdal_grid -a invdist:power=2.0:smoothing=1.0:nodata=-999:max_points=2128164 -txe 582387.4 591069.4 -tye 4505028.08 4515344.079999999 -outsize 50 50 -zfield "z" -of GTiff -ot Float64 -l Book2 Book2.vrt Book2.tiff
Welcome to Stack Overflow, Derek!
Maybe there is a creation option inside gdal_grid that would do it, but I think that you will have to achieve desired result with additional calculation:
Run the gdal_grid as you have it.
Create a concave hull from the given points. If this is a one time job, I suggest using QGIS (with grass tools), because there is some tweaking of concave hull parameters required.
Cut the raster with the created shapefile by using gdalwarp.
Let me know if this got you through!

Slight mismatch with R rasterization process

I'm working on a large project that involves creating a node-and-link network between cities and then gridding that data onto a preset grid. I've used the R raster library for this process.
Currently, the rasterized data do not quite match up with where I expect them to be (i.e. the grid cells that are supposed to cover cities don't match up with exactly where the cities actually are).
The dark red grid cells are supposed to be on top of the black dots, but they all seem to be shifted one grid cell to the west.
I suspect that there is something I'm missing in terms of the projection and the 'crs' option in the raster library, but I'm having trouble figuring out what I did wrong, and how to fix it.
Update: I don't think I can pick out a single chunk of code that gets at the problem, but my raster process looks like this:
rasterize(SpLin, fine.raster, field=*a number*, crs="proj=longlat", background=0)
And the image came from this (slightly trimmed):
pC <- ggplot(aes(x=long, y=lat, fill=value), data=dat_grid) + # dat_grid is the rasterized data
geom_tile() + scale_fill_gradient(low="white",high="red") +
geom_polygon(data=maine_state,aes(x=long,y=lat,group=group),colour="grey",fill="white",alpha=0) +
... (trimmed)
geom_point(data=points.df,aes(long,lat),size=2) # the black dots marking the cities

How to create interactive online map with contour (filled) plot layer?

I would like to create an online interactive map with filled contour plot layer like the ones can be seen on openweathermaps (I would like to use my own data for the plots).
What I need is also similar to the Leaflet heatmap (heatmap.js) but without dynamically changing the colors and the extent of the graphical objects (as in case of heatmap.js). Let's call them static heat maps.
I would like to know which mapping code/library can be used to produce such maps.
I am really newbie to these things, so please bear with me.
I tried Leaflet but did not find any plugin which would create filled contour map layers (static heatmap). I created the following map with Leaflet where the rectangles are geojson polylines and the color is based on some assigned values to every rectangle (elevation)
my leaflet attempt
The problem with this approach is that if higher resolution (smaller and more rectangles) is needed the site would really slow down.
I checked OpenLayers but did not see any similar examples.
I have the data in a matrix format:
Lat; Long; Value
.
.
Values are given in every gridpoints.
(if needed I would convert into other formats, like in case of the above attempt into geojson format)
The data is static, would be saved on the server.
So what I basically want to accomplish is a site where some spatial data is represented as filled contour map (static heatmap) and it is plotted over a map.
Here is my solution to the problem using open-source programs and free, online service:
(1) Processing the data in a GIS program. I used QGIS. I interpolated my data which is in grid points to get a high resolution raster map.
(2) Save the post-processed raster map as a georeferenced *.tif image.
(3) Import the image into TileMill. Remove the basemap and keep only the image as the only layer (style it).
(4) Export the 'map' from TileMill as MBTiles. This will save numerous *.png files (tiles) corresponding to different zoom levels. These are the same type as google or openstreetmap use for their online maps.
(5) Create a free account at Mapbox and create a new map project. Upload the MBTiles created by TileMill (can be directly uploaded from it). Style it.
(6) Use the Map ID corresponding to your created project to embed the map into html sites, e.g. the javascript code:
// Provide your access token
L.mapbox.accessToken = 'Mapbox will generate this for you';
// Create a map in the div #map
var map = L.mapbox.map('map', 'username.mapid', {
minZoom: 5,
maxZoom: 10
}).setView([47, 20], 8);
Example hosted on Mapbox
Sample image(I do not how long will the above link live):
In retrospect, the question would have been better fit to GIS stack exchange.

Adding Boundaries to Spatial Polygons Object

I have the following SpatialPolygonsDataFrame.
require(raster)
usa <- getData('GADM', country='USA', level=2)
metro <- subset(usa, NAME_1=="Nebraska" & NAME_2 %in% c("Dodge","Douglas","Sarpy","Washington"))
plot(metro)
I would like to be able to replicate the following map boundaries (defined by the colors):
Does anyone know a good plan of attack? I realize this is a somewhat manual process. I have already downloaded all US Census files that are of a more detailed geography. I was hoping that a more detailed level of geography could be aggregated to answer the above question, but unfortunately the districts do not line up the same.
Is there a R function already out there that would be helpful in assisting this manual process? At the very minimum, I would like to be able to leverage the perimeter of the 4-county area.
Use writeOGR from the rgdal package to create a shapefile of your metro object. Then install QGIS (http://www.qgis.org/), a free and open-source GIS, and load the shapefile as a new layer.
Then you can edit the layer, add new polygons, edit lines etc, then save as a shapefile to read back into R.
Additionally, you may be able to "georeference" your image (by identifying known lat-long points on the image) and load that into QGIS as a raster layer. That makes it easier to digitise your new areas. All you need for that is a few lat-long coordinates of specific points, such as the corners of polygons or line intersections, and then QGIS has a georeferencing plugin that can do it.
I don't think you'll find any R code as suitable for digitising new geometries over an image as good as QGIS.
After half an hour (and twenty years experience, not all of which you'll need) I've got this:
I didn't precisely digitise your new boundaries though, just roughly for speed. That QGIS screen cap shows the five coloured areas under the four metro areas.
Step one was georeferencing. This screengrab shows how the PNG has been georeferenced - the red line is the metro area shapefile drawn with transparency over the PNG after the PNG has been converted to a GeoTIFF by matching control points.
Step two was then using QGIS editing tools to split, join, and create new polygons. Then I just coloured them and added labelling to pretty it up.
I could probably bundle these files all up for you to neaten, but it really doesn't take that long and you'll learn a lot from doing it. Also, this is probably a gis.stackexchange.com question...

Resources