Open Layers Test

Simple Alternative to Highmaps and Mapbox

by Jayson Buquia

HTML

<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css">
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map"></div>

SCSS

#map {
  width: 100%;
  height: 100vh;
  position: relative;
}

.ol-overlaycontainer {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}

.marker {
  width: 0;
  height: 0;
  overflow: visible;
  position: absolute;
  
  &__tooltip {
     position: absolute;
     top: 0;
     left: -50%;
     padding: 5px;
     background-color: gray;
     color: white;
     opacity: 0;
     transition: opacity .3s;
     pointer-events: none;
     font-family: sans-serif;
     font-family: 10px;
     white-space: nowrap;
     
     .marker:hover & {
       opacity: 1;
     }
  }
  
  &::before {
    content: '';
    display: block;
    width: 30px;
    height: 30px;
    position: absolute;
    top: -15px;
    left: -15px;
    background-color: rgba(teal, .35);
    border-radius: 50%;
    overflow: hidden;
  }
  
  &::after {
    content: '';
    display: block;
    position: absolute;
    width: 10px;
    height: 10px;
    top: -5px;
    left: -5px;
    background-color: rgba(teal, .5);
    border-radius: 50%;
    overflow: hidden;
    cursor: pointer;
  }
}

JavaScript

class MapCoordinate {
	constructor(name, lat, long, fullName = name) {
  	this.lat = lat;
    this.long = long;
    this.name = name;
    this.fullName = fullName;
	}
  
  get longLat() {
  	return [this.long, this.lat];
	}
  
  get longLatParsed() {
  	return ol.proj.fromLonLat(this.longLat);
	}
}

function createMarker(coordinateInstance) {
	const markerElement =	Object.assign(document.createElement('div'), { className: 'marker' });
	const markerTooltipElement = Object.assign(document.createElement('div'), { className: 'marker__tooltip' });
	markerElement.appendChild(markerTooltipElement);
  markerTooltipElement.textContent = coordinateInstance.fullName;
	return markerElement;
}

const mapContainer = document.getElementById('map');

// [ name, lat, long ]
const coordinates = [
	['center', 	20, 30, 'Center'],
	['ny', 40.69785166022126, -73.935242, 'New York'],
  ['manila', 14.599512, 120.984222, 'Manila'],
  ['cebu', 10.318107, 123.891640, 'Cebu'],
  ['paris', 48.864716,	2.349014, 'Paris, France']
].reduce((all, [name, lat, long, fullName]) => {
	all[name] = new MapCoordinate(name, lat, long, fullName);
  return all;
}, {});

const map = new ol.Map({
  target: mapContainer,
  layers: [
    new ol.layer.Vector({
      source: ol.format.GeoJSON(),
      style: new ol.style.Style({
      	fill: new ol.style.Fill({
        	color: '#aaa'
        }),
        stroke: new ol.style.Stroke({
        	color: '#aaa',
          width: 1,
        })
      })
    })
  ],
  view: new ol.View({
    center: coordinates.center.longLatParsed,
    zoom: 1.2
  })
});

/* Plot the cities */
Object.values(coordinates).slice(1).forEach(coordinate => {
	map.addOverlay(new ol.Overlay({
      position: coordinate.longLatParsed,
      positioning: 'center-center',
      element: createMarker(coordinate),
      stopEvent: false
  }));
});