Skip to content

Instantly share code, notes, and snippets.

@jsanz
Last active July 31, 2018 22:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsanz/89a63b2533fbc13089da987bab881a6d to your computer and use it in GitHub Desktop.
Save jsanz/89a63b2533fbc13089da987bab881a6d to your computer and use it in GitHub Desktop.
#CARTO Maps API & #OpenLayers with #cartojs

Simple instantiation of an OpenLayers map loading tiles from CARTO Maps API.

<!DOCTYPE html>
<html>
<head>
<title>XYZ</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol-debug.css" type="text/css">
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol-debug.js"></script>
<style>
#map{
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
}
#info{
background-color: #fce94f;
padding: 10px;
}
#info p{
margin: 0;
font-size: 0.8em;
}
#info-type{
font-style: italic;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<div style="display: none;">
<!-- Overlay with the country info -->
<div id="info">
<p id="info-name"></p>
<p id="info-type"></p>
</div>
</div>
<script>
var /* basemap style */
basemap_style = 'https://d.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png',
/* labels overlay layer */
labels_style = 'https://a.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png'
/* carto.com user name */
username = "jsanz",
/* query to render*/
sql = 'SELECT * FROM jsanz.osm_amenities',
/* cartocss to apply */
carto_css = `#layer {
marker-width: 7;
marker-fill: ramp([value], (#5F4690, #1D6996, #38A6A5, #0F8554, #73AF48, #EDAD08, #E17C05, #CC503E), ("bank", "pharmacy", "school", "atm", "clinic", "college", "hospital", "childcare"), "=");
marker-fill-opacity: 1;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #FFFFFF;
marker-line-opacity: 1;
}`,
interactivity = ['cartodb_id','name','type','value']
/* Maps API named map end point */
maps_api_url = `https://${username}.carto.com/api/v1/map/`,
/* mapbox gl map initial settings */
map_center = [-3.696,40.427],
map_zoom = 14;
/* Instantiate the Maps API*/
var maps_api_config = {
"layers":[{
"type":"cartodb",
"options":{
"sql": sql,
"cartocss": carto_css,
"cartocss_version":"2.1.0",
"interactivity" : interactivity
}
}]
},
url = maps_api_url + '?config=' + encodeURIComponent(JSON.stringify(maps_api_config));
/* using html fetch API */
fetch(url, {
method: "GET",
headers: new Headers({ "Content-Type": "application/json" })
})
.then(res => res.json())
.catch(error => console.error("Error:", error))
.then(function(response) {
var hack_urls = x => x.replace('layer0','0'),
base_json = response.metadata.layers['0'].tilejson.raster,
carto_raster_tiles = base_json.tiles.map(hack_urls)
// generate an array of OL raster tile layers
layers = [
[basemap_style],
carto_raster_tiles,
[labels_style]
].map(url => new ol.layer.Tile({source: new ol.source.XYZ({urls: url})}));
/* OL UTF Grid objects */
var grid_source = new ol.source.TileUTFGrid({
tileJSON: {
'tilejson' : '2.2.0',
'grids': base_json.grids.map(hack_urls)
}
});
var grid_layer = new ol.layer.Tile({source: grid_source});
/* We'll use the view later */
var view = new ol.View({
center: ol.proj.fromLonLat(map_center),
zoom: map_zoom
});
/* Instantiate OL map */
var map = new ol.Map({
target: 'map',
layers: layers.concat(grid_layer),
view: view
});
/* Interactivity objects */
var mapElement = document.getElementById('map'),
infoElement = document.getElementById('info'),
nameElement = document.getElementById('info-name'),
typeElement = document.getElementById('info-type'),
infoOverlay = new ol.Overlay({
element: infoElement,
offset: [15, 15],
stopEvent: false
});
map.addOverlay(infoOverlay);
/* Function to render the interactivity UI */
var displayInfo = function(coordinate) {
var view_resolution = /** @type {number} */ (view.getResolution());
grid_source.forDataAtCoordinateAndResolution(coordinate, view_resolution,
function(data) {
mapElement.style.cursor = data ? 'pointer' : '';
if (data) {
nameElement.innerHTML = data['name'];
typeElement.innerHTML = data['type'];
infoOverlay.setPosition(data ? coordinate : undefined);
}
infoOverlay.setPosition(data ? coordinate : undefined);
});
};
/* Assign interactivity events*/
map.on('pointermove', function(evt) {
if (evt.dragging) { return; }
var coordinate = map.getEventCoordinate(evt.originalEvent);
displayInfo(coordinate);
});
map.on('click', function(evt) {
displayInfo(evt.coordinate);
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment