Skip to content

Instantly share code, notes, and snippets.

@rochoa
Last active March 16, 2017 13:00
Show Gist options
  • Save rochoa/9a6cac40104f88009975 to your computer and use it in GitHub Desktop.
Save rochoa/9a6cac40104f88009975 to your computer and use it in GitHub Desktop.
[CARTO] Static Maps API examples
var mapConfigEditor = CodeMirror.fromTextArea(document.getElementById('map_config_editor'), {
theme: 'monokai',
lineNumbers: true,
mode: "javascript",
height: "200px",
lineWrapping: true,
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
});
function format(str) {
for(var i = 1; i < arguments.length; ++i) {
var attrs = arguments[i];
for(var attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
str = str.replace(new RegExp('\\{' + attr + '\\}', 'g'), attrs[attr]);
}
}
}
return str;
}
function updateStaticPreview(options) {
options = options || {};
var example = examples[examplesSelector.value];
// hack to reference example in examples
layers.example.config = {
"type": example.type || "mapnik",
"options": {
"sql": example.sql,
"cartocss": format(example.cartocss, {bufferSize: inputValue('torque_buffer_size')}),
"cartocss_version": "2.2.0"
}
};
var checkedLayerElements = layersElement.querySelectorAll('input:checked'),
checkedLayers = [];
for (var i = 0, len = checkedLayerElements.length; i < len; i++) {
checkedLayers.push(layers[checkedLayerElements[i].value].config);
}
var config = {
"version": "1.3.0",
"layers": checkedLayers
};
if (!checkedLayers.length) {
return;
}
var jsonMapConfig = JSON.stringify(config, null, 2);
if (!!options.fromEditor) {
jsonMapConfig = mapConfigEditor.getValue();
} else {
mapConfigEditor.setValue(jsonMapConfig);
}
var request = new XMLHttpRequest();
request.open('POST', currentEndpoint(), true);
request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
var layergroup = JSON.parse(this.response);
document.getElementById('preview').src = previewUrl(layergroup);
inputValue('preview_url', previewUrl(layergroup));
} else {
throw 'Error calling server: Error ' + this.status + ' -> ' + this.response;
}
};
request.send(jsonMapConfig);
}
function previewUrl(layergroup) {
return checkboxChecked('bbox')
? bboxUrl(layergroup)
: centerUrl(layergroup);
}
function bboxUrl(layergroup) {
var path = [
currentEndpoint(),
'static',
'bbox',
layergroup.layergroupid,
[
inputValue('west'),
inputValue('south'),
inputValue('east'),
inputValue('north')
].join(','),
inputValue('width'),
inputValue('height')
].join('/');
return path + '.png';
}
function centerUrl(layergroup) {
var path = [
currentEndpoint(),
'static',
'center',
layergroup.layergroupid,
inputValue('zoom'),
inputValue('lat'),
inputValue('lng'),
inputValue('width'),
inputValue('height')
].join('/');
return path + '.png';
}
function currentEndpoint() {
return inputValue('endpoint');
}
function inputValue(elementId, value) {
if (typeof value !== 'undefined') {
document.getElementById(elementId).value = value;
}
return document.getElementById(elementId).value;
}
function checkboxChecked(elementId) {
return document.getElementById(elementId).checked;
}
function loadExample() {
var example = examples[examplesSelector.value];
inputValue('lat', example.center[0]);
inputValue('lng', example.center[1]);
if (example.bbox) {
inputValue('west', example.bbox.west);
inputValue('south', example.bbox.south);
inputValue('east', example.bbox.east);
inputValue('north', example.bbox.north);
}
inputValue('zoom', example.zoom);
updateStaticPreview();
}
CodeMirror.commands.save = function() {
updateStaticPreview({fromEditor: true});
};
var examplesSelector = document.getElementById('examples');
examplesSelector.addEventListener('change', loadExample, false);
Object.keys(examples).forEach(function(k) {
var option = document.createElement('option');
option.value = k;
option.innerText = examples[k].name;
examplesSelector.appendChild(option);
});
[
'zoom',
'torque_buffer_size',
'lat',
'lng',
'west',
'south',
'east',
'north',
'width',
'height'
].forEach(function(elementId) {
document.getElementById(elementId).addEventListener('blur', updateStaticPreview, false);
});
['endpoint'].forEach(function(elementId) {
document.getElementById(elementId).addEventListener('blur', updateStaticPreview, false);
});
document.getElementById('bbox').addEventListener('click', function() {
updateForm();
updateStaticPreview();
}, false);
function updateForm() {
var centerElementsCollection = document.getElementsByClassName('center');
var bboxElementsCollection = document.getElementsByClassName('bbox');
if (checkboxChecked('bbox')) {
apply(centerElementsCollection, function(element) {
element.style.display = 'none';
});
apply(bboxElementsCollection, function(element) {
element.style.display = 'inline-block';
});
} else {
apply(centerElementsCollection, function(element) {
element.style.display = 'inline-block';
});
apply(bboxElementsCollection, function(element) {
element.style.display = 'none';
});
}
}
function apply(htmlCollection, func) {
for (var i = 0, len = htmlCollection.length; i < len; i++) {
func(htmlCollection[i]);
}
}
var layersElement = document.getElementById('layers');
Object.keys(layers).forEach(function(layerName) {
var checkBoxElement = layerCheckboxElement(layerName, layers[layerName].checked);
layersElement.appendChild(checkBoxElement);
checkBoxElement.addEventListener('click', updateStaticPreview, false);
layersElement.appendChild(layerCheckboxLabel(layerName));
});
function layerCheckboxElement(layerName, checked) {
var checkboxElement = document.createElement('input');
checkboxElement.name = layerName;
checkboxElement.id = layerName;
checkboxElement.value = layerName;
checkboxElement.type = 'checkbox';
checkboxElement.checked = checked;
return checkboxElement;
}
function layerCheckboxLabel(layerName) {
var labelElement = document.createElement('label');
labelElement.setAttribute('for', layerName);
labelElement.innerText = layerName;
labelElement.id = layerName + '_label';
return labelElement;
}
updateForm();
loadExample();
function getCartoCss(id, rules) {
return '#' + id + ' {\n\t' +
rules.join('\n\t')
+ '\n}'
}
var examples = {
nyc: {
name: 'NYC',
sql: 'select null::geometry the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0;',
'line-color: #333;',
'line-width: 0;',
'line-opacity: 0;'
]),
center: [40.71502926732618, -73.96039009094238],
bbox: {
west: 6,
south: 49,
east: 9,
north: 52
},
zoom: 14
},
torque_heatmap: {
name: 'torque heatmap',
"type": "torque",
"sql": "SELECT * FROM ne_10m_populated_places_simple",
"cartocss": [
'Map {',
' buffer-size:{bufferSize};',
' -torque-frame-count:1;',
' -torque-animation-duration:10;',
' -torque-time-attribute:\"cartodb_id\";',
' -torque-aggregation-function:\"count(cartodb_id)\";',
' -torque-resolution:1;',
' -torque-data-aggregation:linear;',
'}',
'',
'#ne_10m_populated_places_simple{',
' image-filters: colorize-alpha(blue, cyan, lightgreen, yellow , orange, red);',
' marker-file: url(http://s3.amazonaws.com/com.cartodb.assets.static/alphamarker.png);',
' marker-fill-opacity: 0.4;',
' marker-width: 12;',
'}',
'#ne_10m_populated_places_simple[frame-offset=1] {',
' marker-width:14;',
' marker-fill-opacity:0.2; ',
'}',
'#ne_10m_populated_places_simple[frame-offset=2] {',
' marker-width:16;',
' marker-fill-opacity:0.1; ',
'}'
].join('\n'),
center: [35, 0],
bbox: {
west: -8,
south: 50,
east: 3,
north: 55
},
zoom: 2
},
torque_marker_file: {
name: 'Torque Marker file',
type: 'torque',
sql: 'select * from ne_10m_populated_places_simple',
cartocss: [
'Map {',
'buffer-size:{bufferSize};',
'-torque-frame-count:1;',
'-torque-animation-duration:30;',
'-torque-time-attribute:"cartodb_id";',
'-torque-aggregation-function:"count(cartodb_id)";',
'-torque-resolution:1;',
'-torque-data-aggregation:linear;',
'}',
'',
'#ne_10m_populated_places_simple{',
' marker-fill-opacity: 0.9;',
' marker-line-color: #FFF;',
' marker-line-opacity: 1;',
' marker-placement: point;',
' marker-type: ellipse;',
' marker-width: 12;',
' marker-fill: #F84F40;',
' marker-file: url(http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Map_marker_font_awesome.svg/24px-Map_marker_font_awesome.svg.png);',
' marker-allow-overlap: true;',
'}'
].join('\n'),
center: [35, 0],
bbox: {
west: -8,
south: 50,
east: 3,
north: 55
},
zoom: 2
},
torque_populated: {
name: 'THE TORQUE',
type: 'torque',
sql: 'select * from ne_10m_populated_places_simple',
cartocss: 'Map {\nbuffer-size:{bufferSize};\n-torque-frame-count:1;\n-torque-animation-duration:30;\n-torque-time-attribute:"cartodb_id";\n-torque-aggregation-function:"count(cartodb_id)";\n-torque-resolution:2;\n-torque-data-aggregation:linear;\n}\n\n#ne_10m_populated_places_simple_3{\n comp-op: lighter;\n marker-fill-opacity: 0.9;\n marker-line-color: #2167AB;\n marker-line-width: 5;\n marker-line-opacity: 1;\n marker-type: ellipse;\n marker-width: 6;\n marker-fill: #FF9900;\n}\n#ne_10m_populated_places_simple_3[frame-offset=1] {\n marker-width:8;\n marker-fill-opacity:0.45; \n}\n#ne_10m_populated_places_simple_3[frame-offset=2] {\n marker-width:10;\n marker-fill-opacity:0.225; \n}',
center: [35, 0],
bbox: {
west: -8,
south: 50,
east: 3,
north: 55
},
zoom: 2
},
bbox_torque: {
name: 'Bounding box + centroid',
sql: 'select ST_Transform(ST_MakeEnvelope(-5, 51, 2, 54, 4326), 3857) the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FFF;',
'polygon-opacity: 0.7;',
'line-color: #333;',
'line-width: 1;',
'line-opacity: 1.0;'
]),
center: [42, -2],
bbox: {
west: -8,
south: 50,
east: 3,
north: 55
},
zoom: 1
},
bbox_centroid: {
name: 'Bounding box + centroid',
sql: 'select ST_Transform(ST_MakeEnvelope(6, 49, 9, 52, 4326), 3857) the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0.7;',
'line-color: #333;',
'line-width: 1;',
'line-opacity: 0.2;'
]),
center: [42, -2],
bbox: {
west: 6,
south: 49,
east: 9,
north: 52
},
zoom: 1
},
bbox: {
name: 'Bounding box',
sql: 'select ST_Transform(ST_MakeEnvelope(-124.7625, 24.521, -66.9326, 49.3845, 4326), 3857) the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0.7;',
'line-color: #333;',
'line-width: 1;',
'line-opacity: 0.2;'
]),
center: [42, -2],
bbox: {
west: -124.7625,
south: 24.5210,
east: -66.9326,
north: 49.3845
},
zoom: 1
},
world_borders: {
name: 'World Borders Polygons',
sql: 'select * from world_borders_public',
cartocss: getCartoCss('world_borders_public', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0.7;',
'line-color: #FFF;',
'line-width: 0.3;',
'line-opacity: 1;'
]),
center: [42, -2],
bbox: {
west: -124.7625,
south: 24.5210,
east: -66.9326,
north: 49.3845
},
zoom: 0
},
nurburgring_multipolygons: {
name: 'Nürburgring Multipolygons',
sql: 'select * from nurburgring_area_multipolygons',
cartocss: getCartoCss('nurburgring_area_multipolygons', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0.7;',
'line-color: #FFF;',
'line-width: 0.3;',
'line-opacity: 1;'
]),
center: [50.4, 7],
bbox: {
west: -12,
south: 36,
east: 10,
north: 52
},
zoom: 10
},
office_maps_nyc: {
name: 'Office map NYC',
sql: 'select null::geometry the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0;',
'line-color: #333;',
'line-width: 0;',
'line-opacity: 0;'
]),
center: [40.71502926732618, -73.96039009094238],
bbox: {
west: 6,
south: 49,
east: 9,
north: 52
},
zoom: 18
},
office_maps: {
name: 'Office map',
sql: 'select null::geometry the_geom_webmercator',
cartocss: getCartoCss('layer', [
'polygon-fill: #FF3300;',
'polygon-opacity: 0;',
'line-color: #333;',
'line-width: 0;',
'line-opacity: 0;'
]),
center: [40.4347, -3.7004],
bbox: {
west: 6,
south: 49,
east: 9,
north: 52
},
zoom: 18
}
};
var layers = {
plain: {
config: {
"type": "plain",
"options": {
"color": "#fabada"
}
},
checked: false
},
labels_basemap_light: {
config: {
"type": "http",
"options": {
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
"subdomains": ["a", "b", "c"]
}
},
checked: false
},
basemap_light: {
config: {
"type": "http",
"options": {
"urlTemplate": "http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
"subdomains": ["a", "b", "c"]
}
},
checked: false
},
labels_basemap_dark: {
config: {
"type": "http",
"options": {
"urlTemplate": "http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
"subdomains": ["a", "b", "c"]
}
},
checked: false
},
basemap_dark: {
config: {
"type": "http",
"options": {
"urlTemplate": "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
"subdomains": ["a", "b", "c"]
}
},
checked: true
},
example: {
checked: true
},
urban_areas: {
config: {
"type": "mapnik",
"options": {
"sql": 'SELECT * FROM ne_50m_urban_areas',
"cartocss": [
'#ne_50m_urban_areas{',
' polygon-fill: #c33;',
' polygon-opacity: 0.7;',
' line-color: #FFF;',
' line-width: 1;',
' line-opacity: 1;',
'}'
].join(' '),
"interactivity": "cartodb_id",
"cartocss_version": "2.2.0"
}
},
checked: false
},
torque: {
config: {
"type": "torque",
options: {
sql: "select *, (CASE WHEN \"road_type\" = '6' THEN 1 WHEN \"road_type\" = '3' THEN 2 WHEN \"road_type\" = '1' THEN 3 WHEN \"road_type\" = '2' THEN 4 WHEN \"road_type\" = '7' THEN 5 WHEN \"road_type\" = '9' THEN 6 ELSE 7 END) as torque_category FROM (SELECT to_timestamp(date || ' ' || time, 'DD/MM/YYYY HH24:MI') date_time, * FROM dftroadsafety_accidents_3) _cdb_wrap",
cartocss: [
'Map {',
'-torque-frame-count:512;',
'-torque-animation-duration:30;',
'-torque-time-attribute:"date_time";',
'-torque-aggregation-function:"CDB_Math_Mode(torque_category)";',
'-torque-resolution:1;',
'-torque-data-aggregation:linear;',
'}',
'',
'#dftroadsafety_accidents_3{',
' comp-op: multiply;',
' marker-fill-opacity: 0.9;',
' marker-line-color: #FFF;',
' marker-line-width: 0;',
' marker-line-opacity: 1;',
' marker-type: ellipse;',
' marker-width: 3;',
' marker-fill: #FF9900;',
'}',
'#dftroadsafety_accidents_3[frame-offset=1] {',
' marker-width:5;',
' marker-fill-opacity:0.45; ',
'}',
'#dftroadsafety_accidents_3[frame-offset=2] {',
' marker-width:7;',
' marker-fill-opacity:0.225; ',
'}',
'#dftroadsafety_accidents_3[value=1] {',
' marker-fill: #A6CEE3;',
'}',
'#dftroadsafety_accidents_3[value=2] {',
' marker-fill: #1F78B4;',
'}',
'#dftroadsafety_accidents_3[value=3] {',
' marker-fill: #B2DF8A;',
'}',
'#dftroadsafety_accidents_3[value=4] {',
' marker-fill: #33A02C;',
'}',
'#dftroadsafety_accidents_3[value=5] {',
' marker-fill: #FB9A99;',
'}',
'#dftroadsafety_accidents_3[value=6] {',
' marker-fill: #E31A1C;',
'}'
].join(' '),
cartocss_version: "1.0.0",
step: 128
}
},
checked: false
},
labels: {
config: {
"type": "http",
"options": {
"urlTemplate": "http://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.png",
"subdomains": ["a", "b", "c"]
}
},
checked: false
},
named: {
config: {
"type": "named",
"options": {
"name": "world_borders"
}
},
checked: false
},
nycha_developments_july2011: {
config: {
"type": "cartodb",
"options": {
"sql": "select * from nycha_developments_july2011",
"cartocss": "/** simple visualization */\n\n#nycha_developments_july2011{\n polygon-fill: #5CA2D1;\n polygon-opacity: 0.7;\n line-color: #FFF;\n line-width: 0;\n line-opacity: 1;\n}",
"cartocss_version": "2.1.1"
}
},
checked: true
}
};
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" />
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/codemirror.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/theme/monokai.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/addon/fold/foldgutter.css">
<style>
body {
margin: 16px;
padding: 0;
border: 0;
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
textarea {
padding: 0;
margin: 0;
border: solid 1px #999;
height: 64px;
}
.wrap {
width: 960px;
margin: 0 auto;
}
.loader, .preview, .output {
border-bottom: solid 1px #666;
padding: 16px 0;
}
.loader label {
margin-right: 10px;
}
.loader select {
margin-right: 10px;
}
.loader input[type=text] {
width: 320px;
}
.output input {
width: 100%;
}
.preview input {
width: 48px;
}
.CodeMirror {
width: 640px;
height: 200px;
font-size: smaller;
}
.options, .editor {
float: left;
}
.options {
width: 300px;
padding: 0 10px;
}
.clear {
clear: both;
}
.bbox {
display: none;
}
#example_label {
color: #c33;
}
</style>
</head>
<body>
<div class="wrap">
Load an Example from the select box and play with different layers and options.
Or modify MapConfig manually and Cmd/Ctrl+S to apply.
<form class="loader">
<p>
<label for="examples">Example</label>
<select name="examples" id="examples"></select>
<label for="endpoint">Maps API endpoint</label>
<!--<input type="text" name="endpoint" id="endpoint" value="http://development.localhost.lan:8181/api/v1/map">-->
<!--<input type="text" name="endpoint" id="endpoint" value="http://rochoa-st.cartodb-staging.com/api/v1/map">-->
<!--<input type="text" name="endpoint" id="endpoint" value="http://santiago-st.cartodb-staging.com/api/v1/map">-->
<input type="text" name="endpoint" id="endpoint" value="http://rochoa.cartodb.com/api/v1/map">
</p>
<div id="layers"></div>
</form>
<form class="preview">
<div class="editor">
<label for="map_config_editor" class="editor">MapConfig</label>
<textarea id="map_config_editor" class="code"></textarea>
</div>
<div class="options">
Options
<p>
<label for="width">Width</label>
<input type="text" name="width" id="width" value="960">
<label for="height">Height</label>
<input type="text" name="height" id="height" value="600">
</p>
<p>
<label for="bbox">BBox?</label>
<!--<input type="checkbox" name="bbox" id="bbox" checked="checked">-->
<input type="checkbox" name="bbox" id="bbox">
<label for="torque_buffer_size">Torque buffer</label>
<input type="text" name="torque_buffer_size" id="torque_buffer_size" value="32">
</p>
<label for="lng" class="center">Longitude</label>
<input type="text" name="lng" id="lng" value="-2" class="center">
<label for="lat" class="center">Latitude</label>
<input type="text" name="lat" id="lat" value="42" class="center">
<p>
<label for="zoom" class="center">Zoom</label>
<input type="text" name="zoom" id="zoom" value="0" class="center">
</p>
<label for="west" class="bbox">West</label>
<input type="text" name="west" id="west" value="-124.7625" class="bbox">
<label for="south" class="bbox">South</label>
<input type="text" name="south" id="south" value="24.5210" class="bbox">
<p>
<label for="east" class="bbox">East</label>
<input type="text" name="east" id="east" value="-66.9326" class="bbox">
<label for="north" class="bbox">North</label>
<input type="text" name="north" id="north" value="49.3845" class="bbox">
</p>
</div>
<div class="clear"></div>
</form>
<form class="output">
<label for="preview_url">Preview URL</label>
<input type="text" name="preview_url" id="preview_url" value="">
</form>
<form class="editor" style="display: none;">
<label for="sql_editor">MapConfig</label>
<label for="css_editor">CartoCSS</label>
<textarea id="sql_editor" class="code"></textarea>
<textarea id="css_editor" class="code"></textarea>
<div class="clear"></div>
</form>
<p>Image</p>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" id="preview"/>
</div>
</body>
<script src="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/codemirror.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/addon/fold/foldcode.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/addon/fold/foldgutter.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/addon/fold/brace-fold.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/codemirror/4.7.0/mode/javascript/javascript.min.js"></script>
<script src="examples.js"></script>
<script src="app.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment