How to easily create a heatmap layer from a pre-existing vector layer of points in OpenLayers 3?

3.8k views Asked by At

Like the title said I have a vector of points on a OpenLayers map that I need to turn into a heatmap. I already have this code below (which works just fine for me) but I need to add thousands of more points(in a different data file) and be able to visualize it with a density/heatmap. Its current state is a simple open street map with one layer of locations plotted on a world map! I would post an image but reputation rules...

<!DOCTYPE HTML>
<html>
<head>
<title>AIS Map Template</title>

<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
  function init() {
    map = new OpenLayers.Map("mapdiv");
    var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);
//  ADD POINTS TO A LAYER
    var pois = new OpenLayers.Layer.Vector("Ships", 
    {
    projection: new OpenLayers.Projection("EPSG:4326"),
    strategies: [new OpenLayers.Strategy.Fixed()],
    protocol:   new OpenLayers.Protocol.HTTP(
        {
        url:        "./AISdecoded.txt",
        format:     new OpenLayers.Format.Text(
            {
            extractStyles: true,
            extractAttributes: true
            })
        })
    });
//  ADD POINTS LAYER TO MAP
map.addLayer(pois);

var layer_switcher= new OpenLayers.Control.LayerSwitcher({});
    map.addControl(layer_switcher);
    var lonlat = new OpenLayers.LonLat(0,0).transform(
        new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
        new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator
      );

    var zoom = 1;


    map.setCenter(lonlat, zoom);
  }
</script>

<style>
#mapdiv { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>

</head>

<body onload="init();">
<p>AIS Map Data</p>
<div id="mapdiv"></div>
</body>
</html>

The testing data looks like this:

lat lon title   description icon    iconSize    iconOffset  
49.4756 0.13138 227006760   Navigation Status: 0    ship_sea_ocean.png  16,16   -8,-8   
51.2377 4.41944 205448890   Navigation Status: 0    ship_sea_ocean.png  16,16   -8,-8   

I have tried various methods to try and get a heatmap produced but unfortunaetly I'm a little lacking on the Javascript/HTML side of things. I have looked at the examples online including the earthquake example provided by OpenLayers but 99% of them deal with KML files and since I need this application to run offline on a localhost server I cannot do it that way. I have attempted this without success, among other flailing:

       var heatmapLayer = new ol.layer.Heatmap({
            source: new OpenLayers.Layer.Vector("Ships", 
    {
    projection: new OpenLayers.Projection("EPSG:4326"),
    strategies: [new OpenLayers.Strategy.Fixed()],
    protocol:   new OpenLayers.Protocol.HTTP(
        {
        url:        "./AISdecoded.txt",
        format:     new OpenLayers.Format.Text(
            {
            extractStyles: true,
            extractAttributes: true
            })
        })
    }),
            opacity: 0.9
        });

        // Create a tile layer from OSM
        var osmLayer = new ol.layer.Tile({
            source: new ol.source.OSM()
        });

        // Create the map with the previous layers
        var map = new ol.Map({
            target: 'map',  // The DOM element that will contains the map
            renderer: 'canvas', // Force the renderer to be used
            layers: [osmLayer, heatmapLayer],
            // Create a view centered on the specified location and zoom level
            view: new ol.View({
                center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
                zoom: 4
            })
        });

I have a feeling this is much easier than I think it is but I have been trying to do this for about a week now and my patience is nearing its end. If you know how to do this specifically that's awesome! But if you don't, can you push me in the right direction? Any help is much appreciated, thanks!

EDIT

OK so I edited the code a bit to be fully OL3 and use a geoJSON approach. It now looks like this:

<!DOCTYPE HTML>
<html>
 <head>
<title>AIS Map Template</title>
<script src="http://openlayers.org/en/v3.5.0/build/ol.js" type="text/javascript"></script>
<link rel='stylesheet' href='http://ol3js.org/en/master/css/ol.css'>
<script>
  function init() {

var vector = new ol.layer.Heatmap({
  source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
  }),
    opacity: .9
 });

    var osmLayer = new ol.layer.Tile({
            source: new ol.source.OSM()
        });

        // Create the map with the previous layers
        var map = new ol.Map({
            target: 'map',  // The DOM element that will contain the map
            renderer: 'canvas', // Force the renderer to be used
            layers: [osmLayer,vector],
            // Create a view centered on the specified location and zoom level
            view: new ol.View({
                center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
                zoom: 4
            })
        });
  }
</script>

<style>
#map { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>

</head>

 <body onload="init();">
  <p>AIS Map Data</p>
  <div id="map"></div>
 </body>
 </html>

But it's still not working, only a map, no layer. This is the way I found how to do via examples like this one. Firebug is saying "TypeError: ol.source.GeoJSON is not a constructor" but I don't know how to do this any other way. pls halp, thanks!

1

There are 1 answers

0
jojojohn On

Change this:

var vector = new ol.layer.Heatmap({
source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
}),

to:

 var vector = new ol.layer.Heatmap({
   source: new ol.source.Vector({
   url: './AISdecoded.geojson',
   projection: 'EPSG:3857',
   format: new ol.format.GeoJSON()
   }),