function plotOpenStreetMap(filename,lat,long)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plotOpenStreetMap(filename,lat,long)
%
% filename = name of the output HTML file
% lat      = vector of lat values in degrees
% long     = vector of long values in degrees
%
% Desc: 
%  Inspired by Matplotlib library "mppleaflet" discovered on the 
%  internet by Will Lentz
%
% Overlays the lat/long data onto a HTML page with an open street map
% map as the background. Open the HTML file in a browser and you can 
% zoom in / zoom out.
%
% Pen-up/Pen-down:
%  If you provide a vector where all elements are numbers the code will
% draw a single continuous line for the vehicle track. To create a
% pen-up/pen-down insert a single NaN in Lat/Long at each point you want
% a pen-up/pen-down. If there are more than one adjacent NaNs the
% sequence will be found and reduced to a single NaN, the code will also
% remove NaNs that are trailing at the end of the vector. You can have
% more than one NaN in the vecotr to generate multiple segments, for 
% example:
%
% lat = [37 37.1 37.2 37.3 NaN 38 38.1 38.2 NaN 37.3 37.4 37.5]
%
% Obviously the long must be in sync with the lat.
%
% Will result in 3 seperate line segments with a pen-up/pen-down where
% the NaN's are located in the vector.
%
% Copyright 2017 Trimble Inc.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fid = fopen(filename,'w');

% Force into a row
lat  = lat(:)';
long = long(:)';

% Get a unique identifier
tmp = ['map',tempname];
i = find( (tmp == '\') | (tmp == '/') );
if(length(i) > 0)
  UUID = tmp((i(end) + 1):end);
else
  UUID = tmp;
end

fprintf(fid,'<head>\n');
fprintf(fid,'    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/leaflet.js"></script>\n');
fprintf(fid,'    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/leaflet.css" />\n');
fprintf(fid,'  <style>#%s { height:100%%; }</style>\n',UUID);
fprintf(fid,'</head>\n');
fprintf(fid,'<body>\n');
fprintf(fid,'  <div id="%s"></div>\n',UUID);
fprintf(fid,'<script text="text/javascript">\n');
% Satellite layer
fprintf(fid,'  var satellite = L.tileLayer( "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png",\n');
fprintf(fid,'   {maxZoom:19, attribution: ''Inspired by <a href="https://github.com/jwass/mplleaflet">mplleaflet</a> | Map data (c) <a href="http://www.esri.com">ESRI</a> | Platform data (c) <a href="http://www.trimble.com">Trimble</a>''});\n');
% Road layer
fprintf(fid,'  var road = L.tileLayer( "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",\n');
fprintf(fid,'   {maxZoom:19, attribution: ''Inspired by <a href="https://github.com/jwass/mplleaflet">mplleaflet</a> | Map data (c) <a href="http://openstreetmap.org">OpenStreetMap</a> contributors | Platform data (c) <a href="http://www.trimble.com">Trimble</a>''});\n');
% Create the map with the satellite as the default layer
fprintf(fid,'  var map = L.map("%s", { layers: [satellite] });\n',UUID);
% Setup the road and satellite layer selection
fprintf(fid,'  var baseLayers = { "Satellite": satellite, "Roads": road };\n');
fprintf(fid,'  L.control.layers(baseLayers).addTo(map);\n');
% Create the GeoJSON data object containing the platform track from the
% Lat/Long data
fprintf(fid,'  var gjData = {"type": "FeatureCollection", "features": [\n');

% Find the NaNs - we want to perform a pen-up / pen-down
i = find(isnan(lat));
if(i > 0)
  % Remave a NaN at the end if it exists
  if(i(end) == length(lat))
    lat = lat(1:(end-1));
    long = long(1:(end-1));
    if(length(i) > 1)
      i = i(1:(end-1));
    else
      i = [];
    end
  end


  j = find(diff(i) == 1);
  if(length(j) > 0)
    disp('adjacent NaNs - Needs updating');
  end

  % Find the NaN's and generate a list of the start/stop times for each
  % segment
  NumSegments = length(i) + 1;

  if(NumSegments > 1)
    Start(1) = 1;
    Start(2:(NumSegments)) = i + 1;
    Stop(1:(NumSegments-1)) = i;
    Stop(NumSegments) = length(long);
  else
    Start(1) = 1;
    Stop(1) = length(long);
  end
else
  NumSegments = 1;
  Start(1) = 1;
  Stop(1) = length(lat);
end

for j=1:NumSegments
  
  %disp([num2str(Start(j)),' ',num2str(Stop(j))]);

  % Do all the work of outputting the position data
  fprintf(fid,'{"geometry": {"type": "LineString", "coordinates":\n');
  fprintf(fid,'[\n');
  for i=Start(j):Stop(j)
    if( (lat(i) <= 90) & (abs(long(i)) <=180))
      if(i == Stop(j))
        fprintf(fid,'[%.13f, %.13f]\n',long(i),lat(i));
      else
        fprintf(fid,'[%.13f, %.13f],\n',long(i),lat(i));
      end
    end
  end
  fprintf(fid,']\n');
  fprintf(fid,'},"type": "Feature", "properties": {"color": "#FF0000", "opacity": 1, "weight": 3.0}}');
  if(j ~= NumSegments)
    fprintf(fid,',');
  end
end

fprintf(fid,']};\n');

fprintf(fid,'if (gjData.features.length != 0) {\n');
fprintf(fid,'  var gj = L.geoJson(gjData, {\n');
fprintf(fid,'    smoothFactor: 0.1,\n');
fprintf(fid,'    style: function (feature) {\n');
fprintf(fid,'      return feature.properties;\n');
fprintf(fid,'    },\n');
fprintf(fid,'    pointToLayer: function (feature, latlng) {\n');
fprintf(fid,'      var icon = L.divIcon({"html": feature.properties.html, \n');
fprintf(fid,'        iconAnchor: [feature.properties.anchor_x, \n');
fprintf(fid,'                     feature.properties.anchor_y], \n');
fprintf(fid,'          className: "empty"});\n');
fprintf(fid,'      return L.marker(latlng, {icon: icon});\n');
fprintf(fid,'    }\n');
fprintf(fid,'  });\n');
fprintf(fid,'  gj.addTo(map);\n');
fprintf(fid,'  map.fitBounds(gj.getBounds());\n');
fprintf(fid,'} else {\n');
fprintf(fid,'  map.setView([0, 0], 1);\n');
fprintf(fid,'}\n');
fprintf(fid,'</script>\n');
fprintf(fid,'</body>\n');

fclose(fid);

