Simple instantiation of an OpenLayers map loading tiles from CARTO Maps API.
Last active
July 31, 2018 22:30
-
-
Save jsanz/89a63b2533fbc13089da987bab881a6d to your computer and use it in GitHub Desktop.
#CARTO Maps API & #OpenLayers with #cartojs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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