Showing posts with label HTML5. Show all posts
Showing posts with label HTML5. Show all posts

Wednesday, October 19, 2011

Thoughts on vector based mapping

Traditional...wait, I have to put that in quotes..."Traditional" web mapping, as you see in pretty much any web mapping application, relies of raster tiles to convey the base map. The reason for this approach is pretty simple: You can convey a ton of information in a raster image simply by changing the colors of pixels. And it's highly performant. As many pixels in your image is as many points of information you can portray.

But there's been a lot of buzz for awhile about the possibility of vector based mapping. Vector mapping is essentially pushing the underlying data used to build a map to the client, instead of the fully assembled map. By pushing vectors to a client (browser or mobile application) you can push the assembly of the map into the client machine, saving quite a bit of work on the server side. But it also gives you a lot of capabilities that are absent from raster maps. For instance:


  1. Reprojection and restyling on the fly: If you are assembling a map based on vectors, you're just providing the base map data and allowing the local app handle constructing the map. That allows you to do interesting things like reproject and restyle a map in the client and on the fly.
  2. Graduated map drawing: You can draw the map while the user watches, instead of loading it tile by tile.
  3. Perspective changes: You can tilt maps, create 2.5D or 3D maps, do all sorts of things based with the data.
  4. Fluid transitions: Instead of jumping between zoom levels, you can have smoother transitions as you navigate a map.
This comes at a cost to the client of course, you have to have a device of sufficient power to assemble the map. Fortunately, a variety of new technologies in the browser are making that happen. Here's the basic approaches developers are taking:

Google Maps for Android: Google Maps for Android uses vectors to draw the maps. It uses a custom vector format and pushes it down to the application where it runs on the mobile device. If you have an Android phone, chances are you have vector mapping already on that device:

Scalable Vector Graphics (SVG): SVG has been around for awhile, and has even been used by Google for rendering overlays on Google Maps API maps. But it was always held back by the performance in the browser and lack of support by IE. IE9 finally gives support for SVG, and most modern browsers are now performant enough to use it. Polymaps, a JavaScript library, was the first major implementation of vector mapping for the web that I saw. It allows developers to draw maps using SVG and style them using CSS styling. I think SVG is still a little slow, but it is now widely supported and the CSS styling is a great way for developers to style maps.


Canvas: There's been a lot of hall-way talk at conferences like WhereCamps and FOSS4G about using HTML5 Canvas to render vectors, pushed down in a standard format. I haven't seen any great implementations, but Canvas is also widely supported in the browser and generally has good performance.


WebGL: WebGL gives the browser access to a machine's graphics card to do rendering, giving it some tremendous power. Browsers traditionally only had that kind of access through plugins like Flash. Google launched an experiment last week called MapsGL. It's pretty awesome. We've got buildings, smooth transitions, and nice animations of 45 degree imagery. The downside of WebGL is that it isn't widely supported yet in the browser. Currently only Chrome 14 and later versions of Firefox have good enough support for MapsGL. And currently Microsoft has no plans to support it. My hope is that WebGL will take off because of the power that graphics processor gives maps developers.


This isn't meant to be an exhaustive list, feel free to add other approaches you've seen or implemented. I'm really excited by vector mapping and want to see it succeed. I really feel like it's "The Future"

Thursday, August 25, 2011

Playing with the HTML5 Drag and Drop API

So another thing that inspired me during Sean Maday's talk at Google's Geospatial Awareness Day was his demonstration of using HTML5's drag and drop API to load a KML file into a Google Earth API site. In that sample, he loaded the KML file. The JS then parsed the KML and read it into the plugin. I immediately thought about using it with Maps, and adding in a GroundOverlay. So I wrote a quick sample to do just that. Of course, it doesn't work on older browsers, but if you're using later versions of Chrome, FF, or Safari it works just fine. I haven't tested it on IE9.


The code owes a lot to Riyad Kalla's HTML5 Drag and Drop Upload and File API Tutorial. He does a good job of explaining the API, so I'll leave that part to his post. All mine does is put any image in a GroundOverlay on a map. Drag any image from your computer into the little space at the top and it'll show up in a pre-defined place on the map. Next-up I'll work on a way to stretch and position the image. I'm also thinking I'll try to pull out any positioning in the EXIF headers to make a guess about location.


I'm thinking this would be useful for image upload and positioning sites. Say I want users to place images of old maps or more recent satellite imagery. They could position it on the map and then upload it to my server. Of course this doesn't take care of proper georeferencing or projections. Thoughts for another project.


Here's my code for creating the GroundOverlay:

function handleReaderLoadEnd(evt) {

  var imageBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.716216,-74.213393),
    new google.maps.LatLng(40.765641,-74.139235));
  var oldmap = new google.maps.GroundOverlay(evt.target.result,
    imageBounds);
oldmap.setMap(map);
}
  

Wednesday, August 24, 2011

HTML5 Input Range for a slider

I was at Google's Geospatial Awareness Day today, and Sean Maday did a demo of the new HTML5 input type of range, and I had a palm on forehead moment. Regular readers of the blog know I'm slightly obsessed with sliders, so I came home tonight and did a quick sample using a demo I did in Mexico City at the Esto es Google event. The example uses a FusionTablesLayer to show polygons from Natural Earth Data showing the boundaries of the Mexican states, and colors them using the populations, as found on Wikipedia.

Here's the sample, and here's the code for this sample.

function initialize() {
 
    var center = new google.maps.LatLng(23.99170847335287, -102.6702973539042);
 
    map = new google.maps.Map(document.getElementById('map_canvas'), {
      center: center,
      zoom: 5,
      mapTypeId: 'roadmap'
    });
 
    layer = new google.maps.FusionTablesLayer({
      query: {
        select: 'Shape',
        from: '1231298'
      }
    });
    layer.setMap(map);
  }
    function showValue(newValue)
{
  document.getElementById("range").innerHTML=newValue;
   layer.setOptions({query:{
      select: 'Shape',
      from: '1231298',
      where:"'2010'>" + newValue
    }}
      );
}
  </script> 
</head> 
<body onload="initialize()"> 
  <div id="map_canvas" style="height:75%">
  </div> 
  <input type="range" min="600000" max="15000000" value="600000" step="100000" onchange="showValue(this.value)" />
<span id="range">600000</span>