Nov 042014
 

“Isolated apps are out; “micro-moments” are in”

In a recent report, technology analysts Forrester Research are predicting that big changes are coming in in mobile development.

They are predicting 8 significant changes to the mobile development ‘market’ in 2015:

  1. Standalone apps will lose their luster
  2. Hardware-driven innovation will enable new opportunities
  3. Mobile competition will shift to accessories and ecosystems
  4. Composition will dominate front-end mobile experiences
  5. The merger of physical and digital worlds accelerates
  6. Mobile context becomes high-def
  7. Service virtualization and API design tools will appear in every development toolbox
  8. Low-code platforms will move into the aggregation tier, but struggle to go mainstream

They see the driver for these is users moving

“… away from apps, and toward more contextually relevant micro-moments, delivered across families of devices, that are personalized to anticipate unique customer needs.”

There is a summary article on ‘readwrite’ here  and the full report is available here.

Oct 312014
 

A new generation of sensors, powered by a low-energy flavor of Bluetooth, stand to give our phones a rich awareness of the physical world.

 Estimote’s new indoor location app makes it easy for developers to build on top of beacons’ promise. 

From WIRED – Full Article Here 

The EDINA Mobile Internet project has purchased a  number of Estimote Beacons and researching their potential for use in future projects

Exploring Data on your iPhone

 Assets, FtGB, Guide, iOS, iPAD, iPhone, Upload  Comments Off on Exploring Data on your iPhone
Apr 012014
 

This post describes a methodology for exploring the data on your iPhone/iPad that you have captured using Fieldtrip GB.  Why might you want to do this?  Well there are a couple of reasons:

  • You have cleaned your Dropbox account and deleted the records
  • Some of the data didn’t seem to upload to Dropbox*

* we have had 1 user report that some of their photos did not transfer to DropBox during “Upload Records”.  This is odd and may be as a result of a patchy data connection.

iExplore

iExplore

  1. Download iExplore - this is a free utility for your desktop that allows you to explore the file system on your iPhone
  2. Instal iExplore 
  3. Open iExplore - click continue with Demo
  4. Connect iPhone/iPad to your computer
  5. In the navigation on the left select Apps –> Fieldtrip GB –> Documents –> Edina –> Assets
  6. You should see a folder for each asset you have created.
  7. You can copy these to your Desktop or directly to Dropbox if you have a Dropbox folder on your Desktop

This should allow Apple users to find and retrieve data that they have collected using Fieldtrip GB without having to use the Upload Records function.  However, we would still strongly recommend using the Upload Records function and then access the data through the FtGB Authoring Tool.

 

Integrating Openlayers and HTML5 Canvas (Revisited)

 cartography, html5, openlayers html5 canvas  Comments Off on Integrating Openlayers and HTML5 Canvas (Revisited)
Jan 282014
 

The WordPress stats tell me there is still a lot of interest in our previous post on integrating OpenLayers and HTML5 Canvas from way back in 2010.
Time has passed, technology has moved on and I’ve started buying shoes in bulk like Mr Magorium. So below, I provide an update on how I integrate OL and HTML5 Canvas 3 years on.

Previously my approach was to replace each individual tile image with a corresponding canvas element, the same size as the tile (typically 256*256). Also we used JQuery to capture tile rendering events. The updated approach is to capture tile images as they are rendered by OpenLayers using OL built in event listeners and then draw these onto a single HTML5 canvas element.
Apart from being more efficient and producing cleaner, more robust code, this approach has the advantage that you can use HTML5 to draw shapes, lines and manipulate pixels on a single canvas tile, crossing tile boundaries. This is particularly useful for drawing lines and shapes using paths (e.g. lineTo() , moveTo() functions).

To demonstrate this I’ve set up a simple demo that shows the HTML5 Canvas adjacent to a simple OpenLayers map, where the canvas version (on the right hand side) is manipulated to show a grayscale and inverted version of the original map image (grayscale is triggered by loadend and the invert function by moveend) The source code is available on EDINAs gitHub page. (https://github.com/edina/geomobile) and on JS Fiddle page.
The solution hinges on using the OpenLayers.Layer loadend event to capture the tiles when OpenLayers has finished loading all the tiles for a layer, and also the OpenLayers.Map moveend event, which OpenLayers triggers when it has dealt with the user panning the map. The former is shown in the code snippet below:
// register loadend event for the layer so that once OL has loaded all tiles we can redraw them on the canvas. Triggered by zooming and page refresh.

layer.events.register("loadend", layer, function()
{

// create a canvas if not already created

....

var mapCanvas = document.getElementById("mapcvs" ) ; // get the canvas element
var mapContainer = document.getElementById("OpenLayers.Map_2_OpenLayers_Container") ; // WARNING: Brittle to changes in OL

if(mapCanvas !== null)
{
var ctx = mapCanvas.getContext("2d") ;
var layers = document.getElementsByClassName("olLayerDiv") ; // WARNING: Brittle to changes in OL

// loop through layers starting with base layer
for(var i = 0 ; i < layers.length ; i++)
{

var layertiles = layers[i].getElementsByClassName("olTileImage") ; // WARNING: Brittle to changes on OL

// loop through the tiles loaded for this layer
for(var j = 0 ; j < layertiles.length ; j++ )

{
var tileImg = layertiles[j] ;
// get position of tile relative to map container
var offsetLeft = tileImg.offsetLeft;
var offsetTop = tileImg.offsetTop ;
// get postion of map container
var left = Number(mapContainer.style.left.slice(0, mapContainer.style.left.indexOf("p"))) ; // extract value from style e.g. left: 30px
var top = Number(mapContainer.style.top.slice(0, mapContainer.style.top.indexOf("p"))) ;
// draw the tile on the canvas in same relative postion it appears in OL map
ctx.drawImage(tileImg, offsetLeft + left, offsetTop + top) ;

}

greyscale(mapCanvas, 0, 0, mapCanvas.width, mapCanvas.height) ;
// uncomment below to toggle OL map on /off can only be done after layer has loaded
// mapDiv.style.display = "none" ;

}
}
});


Note that some of the code here comes with a health warning. The DOM functions used to navigate the OpenLayers hierarchy is susceptible to changes in the Open Layers API so you need to use a local copy of OpenLayers (as is case in GitHub sample) rather than point to the OpenLayers URL (as is case in the JS Fiddle version).  Also note that all layers are drawn to the Canvas, not just the one that Open Layers triggered the loadend event for. This is necessary to ensure that the order of layers is maintained. Another issue to be aware of when using Canvas drawing methods on maps  is the likelihood of a CrossOrigin tainting error. This is due to map images being loaded from a different domain to that of the HTML5 code. The error will not get triggered simply by drawing the tiles to canvas using the drawImage() function, but does fail when you attempt pixel manipulation using functions such as putImageData() . OpenLayers handles this using the Cross-Origin-Resource-Sharing protocol which by default is set to ‘anonymous’ as below. So long as the map server you are pointing to is configured to handle CORS requests from anonymous sources you will be fine.

layer.tileOptions = {crossOriginKeyword: ‘anonymous’} ;

Would be interested to hear if others are doing similar or have other solutions to doing Canvasy things with OpenLayers.

OpenLayers Canvas Capture


Create a linear buffer tool for Digimap for Schools

 jsclipper, line buffer, openlayers  Comments Off on Create a linear buffer tool for Digimap for Schools
Dec 202013
 

I’m working on the development of a new linear buffer tool for the Digimap for Schools service. Linear buffering is a common feature in GIS applications.

line-buffer-example

200 meters buffer on a part of river clyde in Glasgow

In geometrical terms such an operation on polygons is also known as Minkowski sum and offsetting.

I was looking of a Javascript library that would offer such functionality as OpenLayers 2.13, currently used by Digimap for Schools, does not offer this as part of its codebase.

I came across 2 libraries that would offer this sort of functionality. One is JSTS and jsclipper the former being a port of the famous Java JTS Topology suite and the later being a port of the C++, C# and Delpi Clipper. I finally decided to go for jsclipper due to being unable to build a custom cut-down version of the huge JSTS library.

The resulting tool made use of jsclipper to calculate the buffer polygon along with OpenLayers, used to draw the buffer polygon and the inner linear path.

A standalone example along with the code, making use of EDINA’s OpenStream service, can be found here:  (Full screen here)

One of the challenges encountered was jaggy rounded ends on low buffer widths which is due to the way jsclipper handles floats. Fortunately jsclipper provides a method to scale up coordinates before passing them to jsclipper for offsetting and then scaling them down again before drawing. The Lighten and CleanPolygons functions also provided a way to remove unnecessary points and merge too-near points of the resulting buffer polygon.

All in all, jsclipper is a light, fast and robust library for polygon offsetting and would recommend having a look at it: https://sourceforge.net/p/jsclipper


FtGB supports Android 4.4

 Android, Android 4.4  Comments Off on FtGB supports Android 4.4
Dec 092013
 
KitKat

Android 4.4

Fieldtrip GB version 1.3.2 has just been released. This update means that Fieldtrip GB will now support Android 4.4 (KitKat).  If you have set the app to auto-update then you may not even notice.  If you have a new(ish) Android device that runs KitKat and have tried to download FtGB but couldn’t find it in the Play Store, you should now be able to see it (note- still restricted to UK store).

Creating a transparent overlay map with mapbox-ios-sdk.

 iOS, mapbox, mobile  Comments Off on Creating a transparent overlay map with mapbox-ios-sdk.
Dec 022013
 

I am working on a historic map overlay, where the user can adjust the transparency of the historic map. The user can then see the how the land use has changed over time by using the slider.

opacity-map-overlay

I am going to use the map-box fork of route me. Looks like a good bug fixed version of Route-me and map-box do seem to have great some great products.

Unfortunately it doesn’t have an have an API to dynamically change the opacity of a tile source out the box. So I added it.

Its pretty easy to add. Each tileSource has a RMMapTileLayerView container when added to the map. Within that can manipulate the CALayer.opacity to get the desired effect.

I added a fork to github for testing

https://github.com/murrayk/mapbox-ios-sdk/

And example of use – the code is in github. Do a ‘git clone –recursive’ to install the submodules.

https://github.com/murrayk/mapbox-overlay-opacity-example

And example of use. In the  main view controller.

- (void)viewDidLoad
{
    [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    RMOpenStreetMapSource * openStreetMap = [[RMOpenStreetMapSource alloc] init];
    RMGenericMapSource * weatherMap = [[RMGenericMapSource alloc] initWithHost:@"tile.openweathermap.org/map/clouds" tileCacheKey:@"cloudCover" minZoom:0 maxZoom:18];

    self.mapView.tileSource = openStreetMap;

    [self.mapView addTileSource:weatherMap];

    self.overlay = weatherMap;
    // rough bb W = -30.0 degrees; E = 50.0 degrees; S = +35.0 degrees; N = +70.0 degrees
    NSLog(@"zooming to europe");
    CLLocationCoordinate2D northEastEurope = CLLocationCoordinate2DMake(70,-30);
    CLLocationCoordinate2D southWestEurope= CLLocationCoordinate2DMake(35,50);
    [self.mapView zoomWithLatitudeLongitudeBoundsSouthWest:southWestEurope northEast:northEastEurope animated:YES];

    [self.mapView setOpacity:0.5 forTileSource: self.overlay];

}

//hook up a slider to manipulate the opacity.  

- (IBAction)changeOverlayOpacity:(UISlider *)sender {

    NSLog(@"Slider value changed %f", sender.value );
    [self.mapView setOpacity:sender.value forTileSource: self.overlay];

}

Fieldtrip GB Group data collection crib guide

 Android, Fieldtrip GB, FtGB, Guide, help  Comments Off on Fieldtrip GB Group data collection crib guide
Nov 152013
 

We thought we would put together a brief crib guide to help run data collection projects using Fieldtrip GB with a small group.  The idea is to create a form and get the group to download this to their devices, then collect data before uploading it to a central place and visualising the groups data.  This technique can be used to great effect to collect lots of data in a short period of time, or to get groups of school children to collect data on short field class exercises.

Intro
1. Navigate to Fieldtrip GB blog
2. Show the new which has some example of what can be done and the Help
3. Click the Authoring tool link and again
4. Login – you are logging into Dropbox at this point.
5. Explain the menus at the top of the page:
a. Create – create a new form
b. Record viewer – visualise/edit the data you have captured
c. Editors Gallery – some example forms
d. My Editors – a list of forms you have created

Create a new form
6. Create a Form
a. Get the group to decide what to collect (keep it simple – trees, birds, litter, building)
b. Create the form and try to use at least drop down lists, photos, range and text box
7. Save the form – this saves it to the Dropbox account that you logged in to

Download form to device
8. Get the group to start the app on their devices
9. Get them to log in to the shared Dropbox account
10. Select Download from the footer and then select Download Forms
11. You are now ready to collect data, you will find the new form in the Capture Tab (select it in the footer)

Upload data from devices to Dropbox
12. Once we have collected data, select Download tab
13. Press Upload Records – the data will now be pushed from the device to Dropbox

Visualise and export collected data
14. On a desktop/laptop – go back to the Authoring Tool
15. Select Record Viewer
16. Use the Filter Records section to select the form we have just used
17. Press Get Records – they should appear on the map
18. To view/edit the records – press Show Table above the map, you can view/edit each record
19. To export the records, you have several options:
a. GeoJSON – ideal for web mapping/coders
b. KML – Google Earth and easy to get into GIS (ArcGIS/QGIS)
c. CSV – for Excel and GIS
20. To export, select the format and press Export. The data that is exported will reflect the filter you have applied. In most cases you will be exporting all data collected using a particular form, but you could apply a date range filter if you wanted.

That’s it.  Really quite easy isn’t it.  Click here to download the guide as a PDF.

Oct 242013
 

By Fiona Hemsley-Flint (GIS Engineer)

Whilst developing the background mapping for the Fieldtrip GB App, it became clear that there was going to have to be some cartographic compromises between urban and rural areas at larger scales; Since we were restricted to using OS Open products, we had a choice between Streetview and Vector Map District (VMD) – Streetview works nicely in urban environments, but not so much in rural areas, where VMD works best  (with the addition of some nice EDINA–crafted relief mapping) . This contrast can be seen in images below.

streetview1VectorMapDistrict1

Streetview (L) and Vector Map District (R) maps in an urban area.

streetview2VectorMapDistrict2

Streetview (L) and Vector Map District (R) maps in a rural area.

In an off-the-cuff comment, Ben set me a challenge – “It would be good if we could have the Streetview maps in urban areas, and VMD maps in rural areas “.

I laughed.

Since these products are continuous over the whole of the country, I didn’t see how we could have two different maps showing at the same time.

Then, because I like a challenge, I thought about it some more and found that the newer versions of MapServer (from 6.2) support something called “Mask Layersâ€�  – where one layer is only displayed in places where it intersects another layer.

I realised if I could define something that constitutes an ‘Urban’ area, then I could create a mask layer of these, which could then be used to only display the Streetview mapping in those areas, and all other areas could display a different map – in this case Vector Map District (we used the beta product although are currently updating to the latest version).

I used the Strategi ‘Large Urban Areas’ classification as my means of defining an ‘Urban’ area – with a buffer to take into account suburbia and differences in scale between Strategi and Streetview products.

The resulting set of layers (simplified!) looks a bit like this:

masking example

Using Mask layers in MapServer 6.2 to display only certain parts of a raster image.

Although this doesn’t necessarily look very pretty in the borders between the two products, I feel that the overall result meets the challenge – in urban areas it is now possible to view street names and building details, and in rural areas, contours and other topographic features are more visible. This hopefully provides a flexibility  for users on different types of field trips to successfully implement the background mapping.

Here’s a snippet of the mapfile showing the implementation of the masking, in case you’re really keen…

#VMD_layer(s) defined before mask

LAYER

…..

END

#Streetview mask layer

LAYER

NAME “Streetview_Mask”

METADATA

…..

END

#Data comes from a shapefile (polygons of urban areas only):

DATA “streetview_mask”

TYPE POLYGON

STATUS OFF

END

#Streetview

LAYER

NAME “Streetview”

METADATA

…..

END

#Data is a series of tiff files, location stored in a tileindex

TYPE Raster

STATUS off

TILEINDEX “streetview.shp”

TILEITEM “Location”

#*****The important bit – setting the mask for the layer*****

MASK “Streetview_Mask”

POSTLABELCACHE TRUE

END


What Women Intent

 Uncategorized  Comments Off on What Women Intent
Jul 262013
 

I noticed a recent BBC news report stating that more women than men in the UK now own a tablet. It seems that the days when an iPad was most frequently coveted by middle-aged men such as me have long gone.

One question this raised in my mind though is why tablets are particularly popular with women in a way that laptops and netbooks were not. Does this tell us anything about the mobile revolution? Does it tell us anything about men and women? Probably not! Perhaps it is just natural that something as convenient as a tablet computer is popular with both men and women.

However I’ll ignore that perfectly reasonable explanation and speculate on the gender angle.

So, certainly in my household the opportunity to sit down at a laptop for, say, thirty minutes uninterrupted is a luxury mostly enjoyed by, well, er… me. My partner has commented that my ability to filter out bickering kids, ignore a saucepan boiling over, forget I started the kids’ bath running and completely not hear the important information she is telling me about the school run tomorrow is nothing short of a supernatural gift. An ability to remain sitting down at a computer when all that is going on is certainly not something I’ve observed in her or other women I know.

So my theory is that tablets are popular with women because they are designed to cope with interruptions (the tablets I mean, not the women). Or at least, the smartphones from which the tablets inherited their OS were designed to be interrupted – by phone calls specifically.

People think of operating systems such as Android as a set of Apps, but really they are a set of interruptible views called Activities (View-Controllers in iOS). The only difference is that the initial Activity in an App has an icon on the Home screen.

Developers are required to implement life-cycle methods on each Activity (AppDelegate in iOS) to ensure that if the OS interrupts the action at any point, the user can pick up again exactly where they left off. This is so critical that in Android the transition from one activity to another is encapsulated in a class of its own called an “Intentâ€�. The name reminds the developer that they might be intending a change in application state but the OS can butt in at any time – so they must make sure it stores everything from the previous Activity first.

This explanation is helpful to me in understanding the success of tablets. When the iPad first came out I have to admit I didn’t think it would be anywhere as popular as the ubiquitous iPhone. At the time, I thought the meteoric success of smartphones was down to their portability and geo-location capabilities. I loved the shiny beauty of the iPad design but couldn’t help thinking it was a bunch of iPhones stuck together. I wondered why I’d want one when I could get a more powerful netbook with a proper keyboard built in. But netbooks are less portable, they take more time to boot up and you have to save what you are doing to ensure you don’t lose your data. The batteries do not last as long and using a keyboard and mouse requires you to sit down. Not good for the interruptible computer user.

This all could be seen as a reason to avoid web apps or hybrid apps that use a WebView embedded into the app. As the Web View or Web Browser uses the stateless HTTP protocol, there are no activity life-cycle methods for developers to honour and maintaining the state between activities is much trickier to get right. So web-based apps could break the interruptible App and annoy users. Especially those who are being constantly interrupted.