{"id":1633,"date":"2013-09-05T14:25:03","date_gmt":"2013-09-05T12:25:03","guid":{"rendered":"http:\/\/sickel.net\/blogg\/?p=1633"},"modified":"2013-09-06T09:25:50","modified_gmt":"2013-09-06T07:25:50","slug":"client-based-web-mapping","status":"publish","type":"post","link":"http:\/\/sickel.net\/blogg\/?p=1633","title":{"rendered":"Client based web-mapping"},"content":{"rendered":"<p><a href=\"http:\/\/procomun.wordpress.com\/2012\/02\/23\/maps_with_r_3\/\">Maps with R &#8211; part III<\/a> shows how to make an active svg-map from R. In that example, a specialiced data set was used. I have redone it by using a map pulled in from postgis and also added on some more functionallity, some of it may be extened further to make a kind of client-based web-gis application. This examnple map uses a continous color scale for a map of discrete values. This is a bad idea, but is used here to simplify the example.<\/p>\n<p><iframe loading=\"lazy\" src=\"http:\/\/sickel.net\/misc\/Geilo_annomap.svg.html\" width=\"960\" height=\"350\">No iframe&#8230;  see <a href=\"http:\/\/sickel.net\/misc\/Geilo_annomap.svg.html\">http:\/\/sickel.net\/misc\/Geilo_annomap.svg.html&#8221;<\/a><\/iframe><\/p>\n<p>Moving the mouse pointer over the map shows a tooltip with some selected information for each polygon. When clicking on a polygon, the color changes and a callback to the web pages makes the web page show the ID of the polygon. This can of cource be used to show more information, possibly fetched through an ajax call. <\/p>\n<p>The svg-map is prepared through R. A number of pakages must be loaded:<br \/>\n<code>library(gridSVG)<br \/>\nlibrary(sp)<br \/>\nlibrary(lattice)<br \/>\nlibrary(latticeExtra)<br \/>\nlibrary(maptools)<br \/>\nlibrary(colorspace)<\/code><\/p>\n<p>I have a variable called &#8220;map&#8221; that is a map pulled in from a postgres database.<br \/>\n<code>map=readOGR(\"PG:dbname=database user=username password=password\",layer=&lt;name of the table in postgis&gt;)<\/code><\/p>\n<p>Some parts must be prepared before the svg-export can be run:<\/p>\n<p><code> grid.newpage()<br \/>\n  set_Polypath(FALSE)<br \/>\n  panel.str < - deparse(panel.polygonsplot, width=500)\n  panel.str <- sub(\"grid.polygon\\\\((.*)\\\\)\",\"grid.polygon(\\\\1, name=paste('ID', slot(map, 'data'\\\\)\\\\$gid\\\\[i\\\\], sep=':'))\", panel.str)\n  panel.polygonNames <- eval(parse(text=panel.str),envir=environment(panel.polygonsplot))\n  p <- spplot(map[\"category\"], panel=panel.polygonNames)\n  eval(p)\n  set_Polypath(TRUE) <\/code><\/p>\n<p>For other use, two lines must\/ may be altered:<br \/>\n<\/code><code>panel.str < - sub(\"grid.polygon\\\\((.*)\\\\)\",\"grid.polygon(\\\\1, name=paste('ID', slot(map, 'data'\\\\)\\\\ $gid\\\\[i\\\\], sep=':'))\", panel.str)<\/code><\/p>\n<p><em>map<\/em> is the name of the variable in which the map is stored.<br \/>\n<em>gid<\/em> is the name of the polygon id.<br \/>\nThis lines makes an ID of each polygon  that is made as \"ID:\" and the value of gid for each polygon.<\/p>\n<p><\/code><code>  p < - spplot(map[\"category\"], panel=panel.polygonNames)<\/code><\/p>\n<p>Again, <em>map<\/em> is the variable holding the map, <em>category<\/em> is the variable I want to be used for coloring the map.<\/p>\n<p>Thereafter, the graphical objects (grobs) that we want to work on has to be enumerated:<br \/>\n<\/code><code><br \/>\n## grobs in the graphical output<br \/>\ngrobs < - grid.ls()\n## only interested in those with \"ID:\" in the name\nnms <- grobs$name[grobs$type == \"grobListing\"]\nidxNames <- grep('ID:', nms)\nIDs <- nms[idxNames]\n<\/code><\/p>\n<p><\/code><code><br \/>\nfor (id in unique(IDs)){<br \/>\n  # Need to get back the gid-value<br \/>\n  x < - unlist(strsplit(id, 'ID:'))\n  i=as.numeric(x[2])\n  # Looks up the map element with the corresponding gid\n  n=which(map$gid==i)\n  # Picks out values of category and shape_area for making the tooltip\n  info=paste(id,\"->\",map$category[n],'(',map$shape_area[n],'m2 )')<br \/>\n  g < - grid.get(id)\n  ## attach SVG attributes\n  # Defines attributes for the respective polygons. the javascript functions is defined in \"tooltips.js\" (see below)\n  grid.garnish(id,\n               onmouseover=paste(\"showTooltip(evt, '\",info,\"')\"),\n               onmouseout=\"hideTooltip()\",\n               onclick=\"mark(evt)\",\n               class=paste('cc',map$categorycode[n],sep=''),\n               name=info)\n}\n# The file containing the javascript functions\ngrid.script(filename=\"tooltip.js\")\n\nsvgname=\"svgtest.svg\"\ngridToSVG(svgname)\n<\/code><\/p>\n<p>This will produce the svg-file svgtest.svg and a very simple (too simple) html-file, svgtest.svg.html. The file <a href=\"http:\/\/sickel.net\/misc\/tooltip.js\">tooltip.js<\/a> must be available in the same directry as the svg.<\/p>\n<p>The function <em>mark(evt)<\/em> is calling<br \/>\n<\/code><code> parent.showalert(txt);<\/code><br \/>\nThe parent object is the webpage that contains the svg-file, so the showalert(txt) function must be defined in that page. In this case, it is as simple as <code>function showalert(txt){<br \/>\n   document.getElementById('Showinfo').innerHTML=txt;<br \/>\n}<\/code> <\/p>\n<p>The page is available at <a href=\"http:\/\/sickel.net\/misc\/Geilo_annomap.svg.html\">http:\/\/sickel.net\/misc\/Geilo_annomap.svg.html<\/a><\/p>\n<p>Possible further development:<\/p>\n<p>* Click on an item in the legend to get all items of that class marked (they are already set to the same class)<br \/>\n* Fetch more information from a backend server when clicking (or for the tooltip)<br \/>\n* Change the color coding of the map (eg by fetching information from the backend<\/p>\n<p>If this is to be run under R v 2.x, (e.g. on an older Ubuntu LTS)  the available packages is lacking two functions, they may be provided through the following stubs:<\/p>\n<p><code><br \/>\ngrobDescent< -function(x=0,y=0,z=0){\n return(unit(1,\"npc\"))\n}\ngrobAscent<-function(x=0,y=0,z=0){\n return(unit(1,\"npc\"))\n}\n<\/code><br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Maps with R &#8211; part III shows how to make an active svg-map from R. In that example, a specialiced data set was used. I have redone it by using a map pulled in from postgis and also added on &hellip; <a href=\"http:\/\/sickel.net\/blogg\/?p=1633\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-1633","post","type-post","status-publish","format-standard","hentry","category-div"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pnVtD-ql","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/posts\/1633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1633"}],"version-history":[{"count":37,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/posts\/1633\/revisions"}],"predecessor-version":[{"id":1670,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=\/wp\/v2\/posts\/1633\/revisions\/1670"}],"wp:attachment":[{"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1633"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sickel.net\/blogg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}