Initial commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>App | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- TODO: add your code here -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>App | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- TODO: add your code here -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,178 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Custom search dataset | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
<style>
|
||||
#selectDrop {
|
||||
background-color: #d2eaef;
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
z-index: 9000;
|
||||
|
||||
}
|
||||
|
||||
#selectDrop input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div#results {
|
||||
background: #FFF;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div id="searchbox">
|
||||
<select id="selectDrop">
|
||||
<option selected value="">Please Select</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Look for data within your dataset</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Look for data within your dataset using dropdown menu.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
<script>
|
||||
let input;
|
||||
// set map with initial zoom and coodinates view
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 40, lng: 2 },
|
||||
zoom: 4,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
// populate dropdown menu
|
||||
populateDrowpDown()
|
||||
|
||||
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const source = new carto.source.SQL(`
|
||||
SELECT * FROM ne_adm0_europe
|
||||
`);
|
||||
// define CartoCSS code to style data on map
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#ne_adm0_europe {
|
||||
polygon-fill: #3E7BB6;
|
||||
polygon-opacity: 0.7;
|
||||
line-color: #FFF;
|
||||
line-width: 0.5;
|
||||
line-opacity: 1;
|
||||
}
|
||||
|
||||
#layer::labels {
|
||||
text-name: [admin];
|
||||
text-face-name: 'DejaVu Sans Book';
|
||||
text-size: 10;
|
||||
text-fill: #FFFFFF;
|
||||
text-label-position-tolerance: 0;
|
||||
text-halo-radius: 1;
|
||||
text-halo-fill: #6F808D;
|
||||
text-dy: -10;
|
||||
text-allow-overlap: true;
|
||||
text-placement: point;
|
||||
text-placement-type: dummy;
|
||||
}
|
||||
`);
|
||||
// create CARTO layer from source and style variables
|
||||
const Cartolayer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(Cartolayer);
|
||||
|
||||
// get tile from client and add them to the map object
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
|
||||
// function to get list of country names to populate dropdown menu
|
||||
function populateDrowpDown(){
|
||||
return fetch(
|
||||
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT the_geom, admin FROM ne_adm0_europe ORDER BY admin ASC`
|
||||
).then((resp) => resp.json())
|
||||
.then((response) => {
|
||||
return response['features'].map(function(feature){
|
||||
option = document.createElement("option")
|
||||
option.setAttribute("value", feature.properties.admin)
|
||||
option.textContent = feature.properties.admin
|
||||
document.getElementById("selectDrop").appendChild(option);
|
||||
});
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
// when select option from downdown menu, change bounding box of map
|
||||
// to geometry of the selected country
|
||||
document.getElementById('selectDrop').addEventListener("change", function (e) {
|
||||
input = e.currentTarget.selectedOptions[0].attributes[0].value;
|
||||
// calculate the xmax, ymax, xmin, ymin coordinates of the bounding box
|
||||
// of the country polygon of the CARTO dataset
|
||||
return fetch(
|
||||
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=
|
||||
WITH bbox as (
|
||||
SELECT ST_Envelope(the_geom) as the_geom
|
||||
FROM ne_adm0_europe
|
||||
WHERE admin Ilike '${input}'
|
||||
)
|
||||
SELECT the_geom, ST_Xmax(the_geom) as xmax,
|
||||
ST_Ymax(the_geom) as ymax,
|
||||
ST_Xmin(the_geom) as xmin,
|
||||
ST_Ymin(the_geom) as ymin
|
||||
FROM bbox
|
||||
`)
|
||||
.then((resp) => resp.json())
|
||||
.then((response) => {
|
||||
// get coordinates
|
||||
coordinates = response['features'][0].properties
|
||||
|
||||
// set LatLng objects from coordinates from CARTO
|
||||
let sw = new google.maps.LatLng(coordinates.ymin, coordinates.xmin);
|
||||
let ne = new google.maps.LatLng(coordinates.ymax, coordinates.xmax);
|
||||
|
||||
// instantiate Google bounds
|
||||
bounds = new google.maps.LatLngBounds(sw, ne)
|
||||
|
||||
// set bounds of map to the geometry from CARTO
|
||||
map.fitBounds(bounds);
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Custom search dataset | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
<style>
|
||||
#selectDrop {
|
||||
background-color: #d2eaef;
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 50px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
z-index: 9000;
|
||||
|
||||
}
|
||||
|
||||
#selectDrop input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div#results {
|
||||
background: #FFF;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div id="searchbox">
|
||||
<select id="selectDrop">
|
||||
<option selected value="">Please Select</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Look for data within your dataset</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Look for data within your dataset using dropdown menu.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
const map = L.map('map').setView([40, 2], 4);
|
||||
let input;
|
||||
// disable scroll wheel zoom
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
// populate dropdown menu
|
||||
populateDrowpDown()
|
||||
|
||||
// add basemaps to map
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const source = new carto.source.SQL(`
|
||||
SELECT * FROM ne_adm0_europe
|
||||
`);
|
||||
// define CartoCSS code to style data on map
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#ne_adm0_europe {
|
||||
polygon-fill: #3E7BB6;
|
||||
polygon-opacity: 0.7;
|
||||
line-color: #FFF;
|
||||
line-width: 0.5;
|
||||
line-opacity: 1;
|
||||
}
|
||||
|
||||
#layer::labels {
|
||||
text-name: [admin];
|
||||
text-face-name: 'DejaVu Sans Book';
|
||||
text-size: 10;
|
||||
text-fill: #FFFFFF;
|
||||
text-label-position-tolerance: 0;
|
||||
text-halo-radius: 1;
|
||||
text-halo-fill: #6F808D;
|
||||
text-dy: -10;
|
||||
text-allow-overlap: true;
|
||||
text-placement: point;
|
||||
text-placement-type: dummy;
|
||||
}
|
||||
`);
|
||||
// create CARTO layer from source and style variables
|
||||
const Cartolayer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(Cartolayer);
|
||||
|
||||
// get tile from client and add them to the map object
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
|
||||
// function to get list of country names to populate dropdown menu
|
||||
function populateDrowpDown(){
|
||||
return fetch(
|
||||
`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT the_geom, admin FROM ne_adm0_europe ORDER BY admin ASC`
|
||||
).then((resp) => resp.json())
|
||||
.then((response) => {
|
||||
return response['features'].map(function(feature){
|
||||
option = document.createElement("option")
|
||||
option.setAttribute("value", feature.properties.admin)
|
||||
option.textContent = feature.properties.admin
|
||||
document.getElementById("selectDrop").appendChild(option);
|
||||
});
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
// when select option from downdown menu, change bounding box of map
|
||||
// to geometry of the selected country
|
||||
document.getElementById('selectDrop').addEventListener("change", function (e) {
|
||||
input = e.currentTarget.selectedOptions[0].attributes[0].value;
|
||||
return fetch(`https://cartojs-test.carto.com/api/v2/sql?format=geojson&q=SELECT * FROM ne_adm0_europe where admin Ilike '${input}'`)
|
||||
.then((resp) => resp.json())
|
||||
.then((response) => {
|
||||
geojsonLayer = L.geoJson(response)
|
||||
map.fitBounds(geojsonLayer.getBounds());
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Edit SQL & CartoCSS | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Edit SQL & CartoCSS</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Edit manually the SQL query and the CartoCSS style.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">This example only uses one style and one layer whose content is changed.</p>
|
||||
<p class="open-sans">Since the style and source objects are the same they won't trigger events. You need to use the promise to handle
|
||||
errors.</p>
|
||||
</section>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">SQL</h2>
|
||||
<textarea id="sql" rows="3">SELECT * FROM ne_10m_populated_places_simple</textarea>
|
||||
<button class="button" onclick="updateSource()">UPDATE SQL</button>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">CartoCSS</h2>
|
||||
<textarea id="cartocss" rows="3">
|
||||
#layer {
|
||||
marker-fill: red;
|
||||
}
|
||||
</textarea>
|
||||
<button class="button-update button" onclick="updateStyle()">UPDATE STYLE</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 30, lng: 0 },
|
||||
zoom: 3,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL(getValue('#sql'));
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-fill-opacity: 0.9;
|
||||
marker-line-width: 0.5;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
function updateSource() {
|
||||
reset('#sql');
|
||||
populatedPlacesSource.setQuery(getValue('#sql'))
|
||||
.catch(cartoError => {
|
||||
error('#sql', cartoError);
|
||||
});
|
||||
}
|
||||
|
||||
function updateStyle() {
|
||||
reset('#cartocss')
|
||||
populatedPlacesStyle.setContent(getValue('#cartocss'))
|
||||
.catch(cartoError => {
|
||||
error('#cartocss', cartoError);
|
||||
});
|
||||
}
|
||||
|
||||
function getValue(id) {
|
||||
return document.querySelector(id).value
|
||||
}
|
||||
|
||||
function reset(id) {
|
||||
document.querySelector(id).style.background = 'white';
|
||||
}
|
||||
|
||||
function error(id, cartoError) {
|
||||
document.querySelector(id).style.border = '1px solid #E57373';
|
||||
alert(cartoError.message);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Edit SQL CARTOCSS | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Edit SQL & CartoCSS</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Edit manually the SQL query and the CartoCSS style.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">This example only uses one style and one layer whose content is changed.</p>
|
||||
<p class="open-sans">Since the style and source objects are the same they won't trigger events. You need to use the promise to handle errors.</p>
|
||||
</section>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">SQL</h2>
|
||||
<textarea id="sql" rows="3">SELECT * FROM ne_10m_populated_places_simple</textarea>
|
||||
<button class="button" onclick="updateSource()">UPDATE SQL</button>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">CartoCSS</h2>
|
||||
<textarea id="cartocss" rows="3">
|
||||
#layer {
|
||||
marker-fill: red;
|
||||
}
|
||||
</textarea>
|
||||
<button class="button-update button" onclick="updateStyle()">UPDATE STYLE</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL(getValue('#sql'));
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-fill-opacity: 0.9;
|
||||
marker-line-width: 0.5;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
function updateSource() {
|
||||
reset('#sql');
|
||||
populatedPlacesSource.setQuery(getValue('#sql'))
|
||||
.catch(cartoError => {
|
||||
error('#sql', cartoError);
|
||||
});
|
||||
}
|
||||
|
||||
function updateStyle() {
|
||||
reset('#cartocss')
|
||||
populatedPlacesStyle.setContent(getValue('#cartocss'))
|
||||
.catch(cartoError => {
|
||||
error('#cartocss', cartoError);
|
||||
});
|
||||
}
|
||||
|
||||
function getValue(id) {
|
||||
return document.querySelector(id).value
|
||||
}
|
||||
|
||||
function reset(id) {
|
||||
document.querySelector(id).style.border = 'default';
|
||||
}
|
||||
|
||||
function error(id, cartoError) {
|
||||
document.querySelector(id).style.border = '1px solid #E57373';
|
||||
alert(cartoError.message);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,201 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error handling | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Error handling</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Handle common errors in maps.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">In this example we handle the client error while calling the `addLayer` funciton.</p>
|
||||
<p class="open-sans">See `refreshLayer` function in the source code for an example on how to handle Promise errors.</p>
|
||||
</section>
|
||||
<div id="controls">
|
||||
<div id="info">
|
||||
<p class="mt-16 open-sans"></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">DATASET</h2>
|
||||
<textarea id="dataset-value" rows=2></textarea>
|
||||
<button id="dataset-button" class="button" onclick="updateDataset()">SET WRONG DATASET</button>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">STYLE</h2>
|
||||
<textarea id="style-value" rows="3"></textarea>
|
||||
<button id="style-button" class="button" onclick="updateStyle()">UPDATE STYLE</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// Setting up a Google Maps Map
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 50, lng: 15 },
|
||||
zoom: 4,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// State
|
||||
const state = {
|
||||
isDatasetValid: true,
|
||||
isStyleValid: true,
|
||||
errorMessage: '',
|
||||
updating: false
|
||||
};
|
||||
|
||||
// Datasets
|
||||
const validDataset = 'ne_10m_populated_places_simple';
|
||||
const wrongDataset = 'wrong_dataset';
|
||||
|
||||
// Style
|
||||
const validStyle = '#layer { marker-fill: red; }';
|
||||
const wrongStyle = '#layer { marker-fill: wrong-color; }';
|
||||
|
||||
let source = new carto.source.Dataset(validDataset);
|
||||
let style = new carto.style.CartoCSS(validStyle);
|
||||
let layer = new carto.layer.Layer(source, style);
|
||||
|
||||
// Adding the layers to the map
|
||||
client.addLayer(layer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
updateUI();
|
||||
|
||||
function refreshLayer(layer) {
|
||||
client.addLayer(layer)
|
||||
.then(function () {
|
||||
state.errorMessage = '';
|
||||
state.updating = false;
|
||||
updateUI();
|
||||
})
|
||||
.catch(function (error) {
|
||||
state.errorMessage = error.message;
|
||||
state.updating = false;
|
||||
updateUI();
|
||||
});
|
||||
}
|
||||
|
||||
function updateDataset() {
|
||||
client.removeLayer(layer);
|
||||
|
||||
state.isDatasetValid = !state.isDatasetValid;
|
||||
state.updating = true;
|
||||
|
||||
const dataset = state.isDatasetValid
|
||||
? validDataset
|
||||
: wrongDataset;
|
||||
|
||||
updateUI();
|
||||
|
||||
source = new carto.source.Dataset(dataset);
|
||||
layer = new carto.layer.Layer(source, style);
|
||||
refreshLayer(layer);
|
||||
}
|
||||
|
||||
function updateStyle() {
|
||||
client.removeLayer(layer);
|
||||
|
||||
state.isStyleValid = !state.isStyleValid;
|
||||
state.updating = true;
|
||||
|
||||
const styleContent = state.isStyleValid
|
||||
? validStyle
|
||||
: wrongStyle;
|
||||
|
||||
updateUI();
|
||||
|
||||
style = new carto.style.CartoCSS(styleContent);
|
||||
layer = new carto.layer.Layer(source, style);
|
||||
refreshLayer(layer);
|
||||
}
|
||||
|
||||
function updateUI() {
|
||||
const datasetValueEl = document.getElementById('dataset-value');
|
||||
const styleValueEl = document.getElementById('style-value');
|
||||
const datasetButtonEl = document.getElementById('dataset-button');
|
||||
const styleButtonEl = document.getElementById('style-button');
|
||||
const panelEl = document.querySelector('#info p');
|
||||
|
||||
datasetValueEl.value = state.isDatasetValid
|
||||
? validDataset
|
||||
: wrongDataset;
|
||||
|
||||
styleValueEl.value = state.isStyleValid
|
||||
? validStyle
|
||||
: wrongStyle;
|
||||
|
||||
datasetButtonEl.textContent = state.isDatasetValid
|
||||
? 'Set wrong dataset'
|
||||
: 'Revert to a valid dataset';
|
||||
|
||||
styleButtonEl.textContent = state.isStyleValid
|
||||
? 'Set wrong style'
|
||||
: 'Revert to a valid style';
|
||||
|
||||
panelEl.textContent = state.updating
|
||||
? 'Updating...'
|
||||
: state.errorMessage
|
||||
? state.errorMessage
|
||||
: 'Everything OK';
|
||||
|
||||
if (state.updating) {
|
||||
panelEl.classList.remove('bg-red');
|
||||
panelEl.classList.remove('bg-white');
|
||||
panelEl.classList.add('bg-orange');
|
||||
panelEl.classList.add('p-8');
|
||||
panelEl.classList.add('text-white');
|
||||
} else if (state.errorMessage) {
|
||||
panelEl.classList.add('bg-red');
|
||||
panelEl.classList.remove('bg-white');
|
||||
panelEl.classList.remove('bg-orange');
|
||||
panelEl.classList.add('p-8');
|
||||
panelEl.classList.add('text-white');
|
||||
} else {
|
||||
panelEl.classList.add('bg-white');
|
||||
panelEl.classList.remove('bg-red');
|
||||
panelEl.classList.remove('bg-orange');
|
||||
panelEl.classList.remove('p-8');
|
||||
panelEl.classList.remove('text-white');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,190 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error handling | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Error handling</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Handle common errors in maps.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">In this example we handle the client error while calling the `addLayer` funciton.</p>
|
||||
<p class="open-sans">See `refreshLayer` function in the source code for an example on how to handle Promise errors.</p>
|
||||
</section>
|
||||
<div id="controls">
|
||||
<div id="info"><p class="mt-16 open-sans"></p></div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">DATASET</h2>
|
||||
<textarea id="dataset-value" rows=2></textarea>
|
||||
<button id="dataset-button" class="button" onclick="updateDataset()">SET WRONG DATASET</button>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">STYLE</h2>
|
||||
<textarea id="style-value" rows="3"></textarea>
|
||||
<button id="style-button" class="button" onclick="updateStyle()">UPDATE STYLE</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// State
|
||||
const state = {
|
||||
isDatasetValid: true,
|
||||
isStyleValid: true,
|
||||
errorMessage: '',
|
||||
updating: false
|
||||
};
|
||||
|
||||
// Datasets
|
||||
const validDataset = 'ne_10m_populated_places_simple';
|
||||
const wrongDataset = 'wrong_dataset';
|
||||
|
||||
// Style
|
||||
const validStyle = '#layer { marker-fill: red; }';
|
||||
const wrongStyle = '#layer { marker-fill: wrong-color; }';
|
||||
|
||||
let source = new carto.source.Dataset(validDataset);
|
||||
let style = new carto.style.CartoCSS(validStyle);
|
||||
let layer = new carto.layer.Layer(source, style);
|
||||
|
||||
client.addLayer(layer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
updateUI();
|
||||
|
||||
function refreshLayer (layer) {
|
||||
client.addLayer(layer)
|
||||
.then(function () {
|
||||
state.errorMessage = '';
|
||||
state.updating = false;
|
||||
updateUI();
|
||||
})
|
||||
.catch(function (error) {
|
||||
state.errorMessage = error.message;
|
||||
state.updating = false;
|
||||
updateUI();
|
||||
});
|
||||
}
|
||||
|
||||
function updateDataset() {
|
||||
client.removeLayer(layer);
|
||||
|
||||
state.isDatasetValid = !state.isDatasetValid;
|
||||
state.updating = true;
|
||||
|
||||
const dataset = state.isDatasetValid
|
||||
? validDataset
|
||||
: wrongDataset;
|
||||
|
||||
updateUI();
|
||||
|
||||
source = new carto.source.Dataset(dataset);
|
||||
layer = new carto.layer.Layer(source, style);
|
||||
refreshLayer(layer);
|
||||
}
|
||||
|
||||
function updateStyle() {
|
||||
client.removeLayer(layer);
|
||||
|
||||
state.isStyleValid = !state.isStyleValid;
|
||||
state.updating = true;
|
||||
|
||||
const styleContent = state.isStyleValid
|
||||
? validStyle
|
||||
: wrongStyle;
|
||||
|
||||
updateUI();
|
||||
|
||||
style = new carto.style.CartoCSS(styleContent);
|
||||
layer = new carto.layer.Layer(source, style);
|
||||
refreshLayer(layer);
|
||||
}
|
||||
|
||||
function updateUI () {
|
||||
const datasetValueEl = document.getElementById('dataset-value');
|
||||
const styleValueEl = document.getElementById('style-value');
|
||||
const datasetButtonEl = document.getElementById('dataset-button');
|
||||
const styleButtonEl = document.getElementById('style-button');
|
||||
const panelEl = document.querySelector('#info p');
|
||||
|
||||
datasetValueEl.value = state.isDatasetValid
|
||||
? validDataset
|
||||
: wrongDataset;
|
||||
|
||||
styleValueEl.value = state.isStyleValid
|
||||
? validStyle
|
||||
: wrongStyle;
|
||||
|
||||
datasetButtonEl.textContent = state.isDatasetValid
|
||||
? 'Set wrong dataset'
|
||||
: 'Revert to a valid dataset';
|
||||
|
||||
styleButtonEl.textContent = state.isStyleValid
|
||||
? 'Set wrong style'
|
||||
: 'Revert to a valid style';
|
||||
|
||||
panelEl.textContent = state.updating
|
||||
? 'Updating...'
|
||||
: state.errorMessage
|
||||
? state.errorMessage
|
||||
: 'Everything OK';
|
||||
|
||||
if (state.updating) {
|
||||
panelEl.classList.remove('bg-red');
|
||||
panelEl.classList.remove('bg-white');
|
||||
panelEl.classList.add('bg-orange');
|
||||
panelEl.classList.add('p-8');
|
||||
panelEl.classList.add('text-white');
|
||||
} else if (state.errorMessage) {
|
||||
panelEl.classList.add('bg-red');
|
||||
panelEl.classList.remove('bg-white');
|
||||
panelEl.classList.remove('bg-orange');
|
||||
panelEl.classList.add('p-8');
|
||||
panelEl.classList.add('text-white');
|
||||
} else {
|
||||
panelEl.classList.add('bg-white');
|
||||
panelEl.classList.remove('bg-red');
|
||||
panelEl.classList.remove('bg-orange');
|
||||
panelEl.classList.remove('p-8');
|
||||
panelEl.classList.remove('text-white');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> Filter data on map | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&libraries=drawing&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Filter data based on drawn circle</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Filter data based on drawn circle.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
// and disabling scroll wheel zoom
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 40, lng: -80 },
|
||||
zoom: 5,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
var drawingManager = new google.maps.drawing.DrawingManager({
|
||||
drawingControl: true,
|
||||
drawingControlOptions: {
|
||||
position: google.maps.ControlPosition.TOP_CENTER,
|
||||
drawingModes: ['circle']
|
||||
},
|
||||
circleOptions: {
|
||||
fillColor: 'green',
|
||||
fillOpacity: 0.5,
|
||||
strokeWeight: 0.1,
|
||||
clickable: false,
|
||||
editable: false,
|
||||
zIndex: 1
|
||||
}
|
||||
});
|
||||
drawingManager.setMap(map);
|
||||
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// set SQL query to create the grid of hexagons
|
||||
const source = new carto.source.SQL(`
|
||||
SELECT * FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
|
||||
// define styles of layer.
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-fill: red;
|
||||
}
|
||||
`);
|
||||
|
||||
// set the CARTO layer using the source and style defines previously
|
||||
const layer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(layer);
|
||||
|
||||
// retrieve tiles from CARTO to the map
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
// get radius and center of drawn circle and change source of the CARTO layer
|
||||
google.maps.event.addListener(drawingManager, 'circlecomplete', function (circle) {
|
||||
let radius = circle.getRadius();
|
||||
let centerLat = circle.getCenter().lat();
|
||||
let centerLng = circle.getCenter().lng();
|
||||
circleCountPointsIntersect(radius, centerLat, centerLng)
|
||||
});
|
||||
|
||||
// function to change the source of the CARTO layer based on radius and
|
||||
// center of the circle
|
||||
function circleCountPointsIntersect(radius, lat,lng){
|
||||
source.setQuery(`
|
||||
SELECT cartodb_id, the_geom, the_geom_webmercator
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE ST_intersects(
|
||||
the_geom,
|
||||
ST_Buffer(
|
||||
ST_SetSRID(ST_Point(${lng},${lat}),4326)::geography,
|
||||
${radius})::geometry
|
||||
)
|
||||
`);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,125 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title> Filter data on map | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include Leaflet Draw plugin -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- map element -->
|
||||
<div id="map"></div>
|
||||
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Filter data based on drawn circle</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Filter data based on drawn circle.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
const map = L.map('map').setView([40, -80], 7);
|
||||
// disable scroll wheel zoom
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
// add basemaps to map
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// set SQL query to create the grid of hexagons
|
||||
const source = new carto.source.SQL(`
|
||||
SELECT * FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
|
||||
// define styles of layer.
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-fill: red;
|
||||
}
|
||||
`);
|
||||
|
||||
// set the CARTO layer using the source and style defines previously
|
||||
const layer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(layer);
|
||||
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
let drawControl = new L.Control.Draw({
|
||||
draw: {
|
||||
polygon: false,
|
||||
polyline: false,
|
||||
line: false,
|
||||
marker: false,
|
||||
rectangle: false,
|
||||
circle: {
|
||||
shapeOptions: {
|
||||
color: 'green',
|
||||
weight: 0.1,
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
circlemarker: false,
|
||||
},
|
||||
edit: false
|
||||
});
|
||||
|
||||
// initialise the draw controls
|
||||
map.addControl(drawControl);
|
||||
|
||||
// get radius and center of drawn circle and change source of the CARTO layer
|
||||
map.on(L.Draw.Event.CREATED, function (e) {
|
||||
let layer = e.layer;
|
||||
map.addLayer(layer);
|
||||
let radius = layer.getRadius();
|
||||
let centerLat = layer.getLatLng().lat;
|
||||
let centerLng = layer.getLatLng().lng;
|
||||
circleCountPointsIntersect(radius, centerLat, centerLng)
|
||||
});
|
||||
|
||||
// function to change the source of the CARTO layer based on radius and
|
||||
// center of the circle
|
||||
function circleCountPointsIntersect(radius, lat,lng){
|
||||
source.setQuery(`
|
||||
SELECT cartodb_id, the_geom, the_geom_webmercator
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE ST_intersects(
|
||||
the_geom,
|
||||
ST_Buffer(
|
||||
ST_SetSRID(ST_Point(${lng},${lat}),4326)::geography,
|
||||
${radius})::geometry
|
||||
)
|
||||
`);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,218 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Guide | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Guide</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Full reference guide example.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">Select a country</p>
|
||||
</section>
|
||||
<div id="controls">
|
||||
<h2 class="h2">European countries</h2>
|
||||
<select class="js-countries">
|
||||
<option value="">All</option>
|
||||
</select>
|
||||
<div id="info"></div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">Average population</h2>
|
||||
<p class="result open-sans">
|
||||
<span class="js-average-population">xxx</span>
|
||||
<small>inhabitants</small>
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// 1. Setting up a Google Maps Map
|
||||
// 1.1 Creating the Google Maps Map
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 50, lng: 15 },
|
||||
zoom: 4,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// 1.2 Hide countries borders
|
||||
map.set('styles', [{
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
// 2 Defining a carto.Client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// 3. Displaying countries and cities on the map
|
||||
// 3.1 Defining the layers
|
||||
// European Countries layer
|
||||
const europeanCountriesDataset = new carto.source.Dataset('ne_adm0_europe');
|
||||
const europeanCountriesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
polygon-fill: #826DBA;
|
||||
polygon-opacity: 0.5;
|
||||
::outline {
|
||||
line-width: 1;
|
||||
line-color: #FFFFFF;
|
||||
line-opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`);
|
||||
const europeanCountries = new carto.layer.Layer(europeanCountriesDataset, europeanCountriesStyle);
|
||||
|
||||
// Europe cities layer
|
||||
const populatedPlacesSource = new carto.source.SQL(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
|
||||
`);
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-fill-opacity: 0.9;
|
||||
marker-line-width: 0.5;
|
||||
marker-line-color: #FFFFFF;
|
||||
marker-line-opacity: 1;
|
||||
marker-type: ellipse;
|
||||
marker-allow-overlap: false;
|
||||
}
|
||||
`);
|
||||
const populatedPlaces = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
|
||||
featureOverColumns: ['name']
|
||||
});
|
||||
|
||||
// 3.2 Adding the layers to the client
|
||||
client.addLayers([europeanCountries, populatedPlaces]);
|
||||
|
||||
// 3.3. Adding the layers to the map
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
// 4. Setting up tooltips
|
||||
// 4.1 Showing the tooltip when user mouses over a city
|
||||
const infowindow = new google.maps.InfoWindow();
|
||||
populatedPlaces.on('featureOver', featureEvent => {
|
||||
infowindow.setPosition(featureEvent.latLng);
|
||||
if (!infowindow.map) {
|
||||
infowindow.setContent(featureEvent.data.name);
|
||||
infowindow.open(map);
|
||||
}
|
||||
});
|
||||
|
||||
// 4.2 Hiding the tooltip
|
||||
populatedPlaces.on('featureOut', featureEvent => {
|
||||
infowindow.close();
|
||||
});
|
||||
|
||||
// 5 Creating a formula widget
|
||||
// 5.1 Defining a formula dataview
|
||||
const averagePopulation = new carto.dataview.Formula(populatedPlacesSource, 'pop_max', {
|
||||
operation: carto.operation.AVG
|
||||
});
|
||||
|
||||
// 5.2 Listening to data changes on the dataview
|
||||
averagePopulation.on('dataChanged', data => {
|
||||
refreshAveragePopulationWidget(data.result);
|
||||
});
|
||||
|
||||
function refreshAveragePopulationWidget(avgPopulation) {
|
||||
const widgetDom = document.querySelector('.box.widget');
|
||||
const averagePopulationDom = widgetDom.querySelector('.js-average-population');
|
||||
averagePopulationDom.innerText = Math.floor(avgPopulation);
|
||||
}
|
||||
|
||||
// 5.3 Adding the dataview to the client
|
||||
client.addDataview(averagePopulation);
|
||||
|
||||
// 6 Creating a country selector widget
|
||||
// 6.1 Defining a category dataview
|
||||
const countriesDataview = new carto.dataview.Category(europeanCountriesDataset, 'admin', {
|
||||
limit: 100
|
||||
});
|
||||
|
||||
// 6.2 Listening to data changes on the dataview
|
||||
countriesDataview.on('dataChanged', data => {
|
||||
const countryNames = data.categories.map(category => category.name).sort();
|
||||
refreshCountriesWidget(countryNames);
|
||||
});
|
||||
|
||||
function refreshCountriesWidget(adminNames) {
|
||||
const asideElement = document.querySelector('aside.toolbox');
|
||||
const countriesDom = asideElement.querySelector('.js-countries');
|
||||
countriesDom.onchange = event => {
|
||||
const admin = event.target.value;
|
||||
highlightCountry(admin);
|
||||
filterPopulatedPlacesByCountry(admin);
|
||||
};
|
||||
|
||||
// Fill in the list of countries
|
||||
adminNames.forEach(admin => {
|
||||
const option = document.createElement('option');
|
||||
option.innerHTML = admin;
|
||||
option.value = admin;
|
||||
countriesDom.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
function highlightCountry(admin) {
|
||||
let cartoCSS = `
|
||||
#layer {
|
||||
polygon-fill: #826DBA;
|
||||
polygon-opacity: 0.5;
|
||||
::outline {
|
||||
line-color: #FFFFFF;
|
||||
line-width: 1;
|
||||
line-opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`;
|
||||
if (admin) {
|
||||
cartoCSS = `
|
||||
${cartoCSS}
|
||||
#layer[admin!='${admin}'] {
|
||||
polygon-fill: #e5e5e5;
|
||||
}
|
||||
`;
|
||||
}
|
||||
europeanCountriesStyle.setContent(cartoCSS);
|
||||
}
|
||||
|
||||
function filterPopulatedPlacesByCountry(admin) {
|
||||
const query = admin
|
||||
? `SELECT * FROM ne_10m_populated_places_simple WHERE adm0name='${admin}'`
|
||||
: 'SELECT * FROM ne_10m_populated_places_simple WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)';
|
||||
|
||||
populatedPlacesSource.setQuery(query);
|
||||
}
|
||||
|
||||
// 6.3 Adding the dataview to the client
|
||||
client.addDataview(countriesDataview);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Guide | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Guide</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Full reference guide example.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">Select a country</p>
|
||||
</section>
|
||||
<div id="controls">
|
||||
<h2 class="h2">European countries</h2>
|
||||
<select class="js-countries">
|
||||
<option value="">All</option>
|
||||
</select>
|
||||
<div id="info"></div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box widget">
|
||||
<h2 class="h2">Average population</h2>
|
||||
<p class="result open-sans"><span class="js-average-population">xxx</span> <small>inhabitants</small></p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// 1. Setting up the Leaflet Map
|
||||
// 1.1 Creating the Leaflet Map
|
||||
const map = L.map('map').setView([50, 15], 4);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
// 1.2 Adding basemap and labels layers
|
||||
// Adding Voyager Basemap
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
// Adding Voyager Labels
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18,
|
||||
zIndex: 10
|
||||
}).addTo(map);
|
||||
|
||||
// 2 Defining a carto.Client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
// 3. Displaying countries and cities on the map
|
||||
// 3.1 Defining the layers
|
||||
// European Countries layer
|
||||
const europeanCountriesDataset = new carto.source.Dataset('ne_adm0_europe');
|
||||
const europeanCountriesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
polygon-fill: #826DBA;
|
||||
polygon-opacity: 0.5;
|
||||
::outline {
|
||||
line-width: 1;
|
||||
line-color: #FFFFFF;
|
||||
line-opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`);
|
||||
const europeanCountries = new carto.layer.Layer(europeanCountriesDataset, europeanCountriesStyle);
|
||||
|
||||
// Europe cities layer
|
||||
const populatedPlacesSource = new carto.source.SQL(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
|
||||
`);
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-fill-opacity: 0.9;
|
||||
marker-line-width: 0.5;
|
||||
marker-line-color: #FFFFFF;
|
||||
marker-line-opacity: 1;
|
||||
marker-type: ellipse;
|
||||
marker-allow-overlap: false;
|
||||
}
|
||||
`);
|
||||
const populatedPlaces = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
|
||||
featureOverColumns: ['name']
|
||||
});
|
||||
|
||||
// 3.2 Adding the layers to the client
|
||||
client.addLayers([europeanCountries, populatedPlaces]);
|
||||
|
||||
// 3.3. Adding the layers to the map
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
// 4. Setting up tooltips
|
||||
// 4.1 Showing the tooltip when user mouses over a city
|
||||
const popup = L.popup({ closeButton: false });
|
||||
populatedPlaces.on('featureOver', featureEvent => {
|
||||
popup.setLatLng(featureEvent.latLng);
|
||||
if (!popup.isOpen()) {
|
||||
popup.setContent(featureEvent.data.name);
|
||||
popup.openOn(map);
|
||||
}
|
||||
});
|
||||
|
||||
// 4.2 Hiding the tooltip
|
||||
populatedPlaces.on('featureOut', featureEvent => {
|
||||
popup.removeFrom(map);
|
||||
});
|
||||
|
||||
// 5 Creating a formula widget
|
||||
// 5.1 Defining a formula dataview
|
||||
const averagePopulation = new carto.dataview.Formula(populatedPlacesSource, 'pop_max', {
|
||||
operation: carto.operation.AVG
|
||||
});
|
||||
|
||||
// 5.2 Listening to data changes on the dataview
|
||||
averagePopulation.on('dataChanged', data => {
|
||||
refreshAveragePopulationWidget(data.result);
|
||||
});
|
||||
|
||||
function refreshAveragePopulationWidget(avgPopulation) {
|
||||
const widgetDom = document.querySelector('.box.widget');
|
||||
const averagePopulationDom = widgetDom.querySelector('.js-average-population');
|
||||
averagePopulationDom.innerText = Math.floor(avgPopulation);
|
||||
}
|
||||
|
||||
// 5.3 Adding the dataview to the client
|
||||
client.addDataview(averagePopulation);
|
||||
|
||||
// 6 Creating a country selector widget
|
||||
// 6.1 Defining a category dataview
|
||||
const countriesDataview = new carto.dataview.Category(europeanCountriesDataset, 'admin', {
|
||||
limit: 100
|
||||
});
|
||||
|
||||
// 6.2 Listening to data changes on the dataview
|
||||
countriesDataview.on('dataChanged', data => {
|
||||
const countryNames = data.categories.map(category => category.name).sort();
|
||||
refreshCountriesWidget(countryNames);
|
||||
});
|
||||
|
||||
function refreshCountriesWidget(adminNames) {
|
||||
const asideElement = document.querySelector('aside.toolbox');
|
||||
const countriesDom = asideElement.querySelector('.js-countries');
|
||||
countriesDom.onchange = event => {
|
||||
const admin = event.target.value;
|
||||
highlightCountry(admin);
|
||||
filterPopulatedPlacesByCountry(admin);
|
||||
};
|
||||
|
||||
// Fill in the list of countries
|
||||
adminNames.forEach(admin => {
|
||||
const option = document.createElement('option');
|
||||
option.innerHTML = admin;
|
||||
option.value = admin;
|
||||
countriesDom.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
function highlightCountry(admin) {
|
||||
let cartoCSS = `
|
||||
#layer {
|
||||
polygon-fill: #826DBA;
|
||||
polygon-opacity: 0.5;
|
||||
::outline {
|
||||
line-width: 1;
|
||||
line-color: #FFFFFF;
|
||||
line-opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`;
|
||||
if (admin) {
|
||||
cartoCSS = `
|
||||
${cartoCSS}
|
||||
#layer[admin!='${admin}'] {
|
||||
polygon-fill: #e5e5e5;
|
||||
}
|
||||
`;
|
||||
}
|
||||
europeanCountriesStyle.setContent(cartoCSS);
|
||||
}
|
||||
|
||||
function filterPopulatedPlacesByCountry(admin) {
|
||||
const query = admin
|
||||
? `SELECT * FROM ne_10m_populated_places_simple WHERE adm0name='${admin}'`
|
||||
: 'SELECT * FROM ne_10m_populated_places_simple WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)';
|
||||
|
||||
populatedPlacesSource.setQuery(query);
|
||||
}
|
||||
|
||||
// 6.3 Adding the dataview to the client
|
||||
client.addDataview(countriesDataview);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hexagon aggregation | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Create an hexagonal grid</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Aggregate your points in hexagons.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
<!-- Set legend of the map -->
|
||||
<div class="box legend">
|
||||
<h2 class="h2">Number of points aggregated in hexagons</h2>
|
||||
<ul class="category open-sans">
|
||||
<li><div class="circle" style="background: #04817E "></div><p>1-2</p></li>
|
||||
<li><div class="circle" style="background: #39AB7E "></div><p>>2</p></li>
|
||||
<li><div class="circle" style="background: #8BD16D"></div><p>>9</p></li>
|
||||
<li><div class="circle" style="background: #EDEF5D"></div><p>>30</p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
// and disabling scroll wheel zoom
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 40, lng: -80 },
|
||||
zoom: 7,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'public'
|
||||
});
|
||||
|
||||
// set SQL query to create the grid of hexagons
|
||||
/*
|
||||
To create the grid of hexagons we must use a SQL query that generates that grid for a specific
|
||||
zoom level. We will use the zoom level 9 to create a grid of hexagons that will have a side size
|
||||
of 12 pixel units.
|
||||
|
||||
We use the CARTO function CDB_HexagonGrid(geometry, side measure) to create the hexagon grid
|
||||
where "geometry" is defined by the PostGIS function ST_Expand: "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)"
|
||||
and "side measure" is defined by "CDB_XYZ_Resolution(9) * 12)", where the function
|
||||
CDB_XYZ_Resolution(zoom level) returns the pixel resolution of tiles at a given zoom level.
|
||||
|
||||
The geometry defined in "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)" returns the geometry of
|
||||
the bounding box that is defined by mapnik's !bbox! token and that is expanded in all directions a
|
||||
distance of CDB_XYZ_Resolution(9) * 12 units
|
||||
*/
|
||||
const source = new carto.source.SQL(`
|
||||
-- Create hexagon grid
|
||||
WITH hgrid AS (
|
||||
SELECT CDB_HexagonGrid(
|
||||
ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12),
|
||||
CDB_XYZ_Resolution(9) * 12) as cell
|
||||
)
|
||||
-- select the data from the "virtual table" hgrid, which has been created
|
||||
-- using the "WITH" statement of PostgreSQL,
|
||||
-- that intesects with the dataset of points "stormevents_locations_2014"
|
||||
SELECT hgrid.cell as the_geom_webmercator,
|
||||
count(1) as agg_value,
|
||||
row_number() over () as cartodb_id
|
||||
FROM hgrid, (SELECT * FROM stormevents_locations_2014) i
|
||||
WHERE ST_Intersects(i.the_geom_webmercator, hgrid.cell)
|
||||
GROUP BY hgrid.cell
|
||||
`);
|
||||
|
||||
// define styles of layer. We will style the color of the geometry based on the value
|
||||
// of the column "agg_value" of the SQL query.
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
[agg_value > 0] {
|
||||
polygon-fill: #04817E;
|
||||
}
|
||||
[agg_value > 2] {
|
||||
polygon-fill: #39AB7E;
|
||||
}
|
||||
[agg_value > 9] {
|
||||
polygon-fill: #8BD16D;
|
||||
}
|
||||
[agg_value > 30] {
|
||||
polygon-fill: #EDEF5D;
|
||||
}
|
||||
}
|
||||
|
||||
#layer::outline {
|
||||
line-width: 1;
|
||||
line-color: #FFFFFF;
|
||||
line-opacity: 1;
|
||||
}
|
||||
`);
|
||||
|
||||
// set the CARTO layer using the source and style defines previously
|
||||
const layer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(layer);
|
||||
|
||||
// retrieve tiles from CARTO to the map
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hexagon aggregation | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Create an hexagonal grid</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Aggregate your points in hexagons.</p>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
<!-- Set legend of the map -->
|
||||
<div class="box legend">
|
||||
<h2 class="h2">Number of points aggregated in hexagons</h2>
|
||||
<ul class="category open-sans">
|
||||
<li><div class="circle" style="background: #04817E "></div><p>1-2</p></li>
|
||||
<li><div class="circle" style="background: #39AB7E "></div><p>>2</p></li>
|
||||
<li><div class="circle" style="background: #8BD16D"></div><p>>9</p></li>
|
||||
<li><div class="circle" style="background: #EDEF5D"></div><p>>30</p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
const map = L.map('map').setView([40, -80], 7);
|
||||
// disable scroll wheel zoom
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
// add basemaps to map
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'public'
|
||||
});
|
||||
|
||||
// set SQL query to create the grid of hexagons
|
||||
/*
|
||||
To create the grid of hexagons we must use a SQL query that generates that grid for a specific
|
||||
zoom level. We will use the zoom level 9 to create a grid of hexagons that will have a side size
|
||||
of 12 pixel units.
|
||||
|
||||
We use the CARTO function CDB_HexagonGrid(geometry, side measure) to create the hexagon grid
|
||||
where "geometry" is defined by the PostGIS function ST_Expand: "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)"
|
||||
and "side measure" is defined by "CDB_XYZ_Resolution(9) * 12)", where the function
|
||||
CDB_XYZ_Resolution(zoom level) returns the pixel resolution of tiles at a given zoom level.
|
||||
|
||||
The geometry defined in "ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12)" returns the geometry of
|
||||
the bounding box that is defined by mapnik's !bbox! token and that is expanded in all directions a
|
||||
distance of CDB_XYZ_Resolution(9) * 12 units
|
||||
*/
|
||||
const source = new carto.source.SQL(`
|
||||
-- Create hexagon grid
|
||||
WITH hgrid AS (
|
||||
SELECT CDB_HexagonGrid(
|
||||
ST_Expand(!bbox!, CDB_XYZ_Resolution(9) * 12),
|
||||
CDB_XYZ_Resolution(9) * 12) as cell
|
||||
)
|
||||
|
||||
-- select the data from the "virtual table" hgrid, which has been created
|
||||
-- using the "WITH" statement of PostgreSQL,
|
||||
-- that intesects with the dataset of points "stormevents_locations_2014"
|
||||
|
||||
SELECT hgrid.cell as the_geom_webmercator,
|
||||
count(1) as agg_value,
|
||||
row_number() over () as cartodb_id
|
||||
FROM hgrid, (SELECT * FROM stormevents_locations_2014) i
|
||||
WHERE ST_Intersects(i.the_geom_webmercator, hgrid.cell)
|
||||
GROUP BY hgrid.cell
|
||||
`);
|
||||
|
||||
// define styles of layer. We will style the color of the geometry based on the value
|
||||
// of the column "agg_value" of the SQL query.
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
[agg_value > 0] {
|
||||
polygon-fill: #04817E;
|
||||
}
|
||||
[agg_value > 2] {
|
||||
polygon-fill: #39AB7E;
|
||||
}
|
||||
[agg_value > 9] {
|
||||
polygon-fill: #8BD16D;
|
||||
}
|
||||
[agg_value > 30] {
|
||||
polygon-fill: #EDEF5D;
|
||||
}
|
||||
}
|
||||
|
||||
#layer::outline {
|
||||
line-width: 1;
|
||||
line-color: #FFFFFF;
|
||||
line-opacity: 1;
|
||||
}
|
||||
`);
|
||||
|
||||
// set the CARTO layer using the source and style defines previously
|
||||
const layer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(layer);
|
||||
|
||||
// retrieve tiles from CARTO to the map
|
||||
client.getLeafletLayer().addTo(map);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Legends | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Legends</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create dynamic legends.</p>
|
||||
<div class="separator"></div>
|
||||
<div id="controls">
|
||||
<ul>
|
||||
<li onclick="setAllCities()">
|
||||
<input type="radio" name="data" checked id="all">
|
||||
<label for="all">ALL cities</label>
|
||||
</li>
|
||||
<li onclick="setEuropeanCities()">
|
||||
<input type="radio" name="data" id="europe">
|
||||
<label for="europe">European cities</label>
|
||||
</li>
|
||||
<li onclick="setSpanishCities()">
|
||||
<input type="radio" name="data" id="spain">
|
||||
<label for="spain">Spanish cities</label>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="separator"></div>
|
||||
<ul>
|
||||
<li onchange="invertColors()">
|
||||
<input type="checkbox" name="data" id="invertColors">
|
||||
<label for="invertColors">Invert colors</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box legend">
|
||||
<h2 class="h2">World cities</h2>
|
||||
<ul class="category open-sans">
|
||||
<li id="capital"></li>
|
||||
<li id="normal"></li>
|
||||
</ul>
|
||||
<h2 class="h2">Inhabitants</h2>
|
||||
<ul id="legend-population">
|
||||
<li class="size open-sans">
|
||||
<div id="min"></div>
|
||||
<div id="max"></div>
|
||||
</li>
|
||||
<li class="avg open-sans"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 30, lng: 0 },
|
||||
zoom: 3,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
|
||||
marker-fill: ramp([adm0cap], (#EE4D5A, #68B69E), (0, 1), "=", category);
|
||||
marker-fill-opacity: 0.6;
|
||||
marker-allow-overlap: true;
|
||||
marker-line-width: 1;
|
||||
marker-line-color: #000;
|
||||
marker-line-opacity: 0.2;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
populatedPlacesLayer.on('metadataChanged', function (event) {
|
||||
event.styles.forEach(function (styleMetadata) {
|
||||
switch (styleMetadata.getProperty()) {
|
||||
case 'marker-width':
|
||||
renderLegendSize(styleMetadata);
|
||||
break;
|
||||
case 'marker-fill':
|
||||
renderLegendCapital(styleMetadata);
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function renderLegendSize(metadata) {
|
||||
document.getElementById('min').innerHTML = `
|
||||
<div class="circle circle-outline" style="width:8px; height:8px;"></div> <p>${metadata.getMin()}</p>
|
||||
`;
|
||||
|
||||
document.getElementById('max').innerHTML = `
|
||||
<div class="circle circle-outline" style="width:24px; height:24px;"></div> <p>${metadata.getMax()}</p>
|
||||
`;
|
||||
|
||||
document.querySelector('.legend .avg').innerHTML = `
|
||||
<p><b>Average: </b> ${metadata.getAverage().toFixed(2)}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderLegendCapital(metadata) {
|
||||
const categories = metadata.getCategories();
|
||||
|
||||
for (category of categories) {
|
||||
switch (category.name) {
|
||||
case 0:
|
||||
document.getElementById('normal').innerHTML = `
|
||||
<div class="circle" style="background:${category.value}"></div> Normal
|
||||
`;
|
||||
break;
|
||||
case 1:
|
||||
document.getElementById('capital').innerHTML = `
|
||||
<div class="circle" style="background:${category.value}"></div> Capital
|
||||
`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setAllCities() {
|
||||
populatedPlacesSource.setQuery('SELECT * FROM ne_10m_populated_places_simple');
|
||||
}
|
||||
|
||||
function setEuropeanCities() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
|
||||
`);
|
||||
}
|
||||
|
||||
function setSpanishCities() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name = \'Spain\'
|
||||
`);
|
||||
}
|
||||
|
||||
function invertColors() {
|
||||
const invert = document.getElementById('invertColors').checked;
|
||||
const colors = invert ? '(#68B69E, #EE4D5A)' : '(#EE4D5A, #68B69E)';
|
||||
const content = `
|
||||
#layer {
|
||||
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
|
||||
marker-fill: ramp([adm0cap], ${colors}, (0, 1), "=", category);
|
||||
marker-fill-opacity: 0.6;
|
||||
marker-allow-overlap: true;
|
||||
marker-line-width: 1;
|
||||
marker-line-color: #000;
|
||||
marker-line-opacity: 0.2;
|
||||
}
|
||||
`;
|
||||
populatedPlacesStyle.setContent(content);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Legends | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Legends</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create dynamic legends.</p>
|
||||
<div class="separator"></div>
|
||||
<div id="controls">
|
||||
<ul>
|
||||
<li onclick="setAllCities()">
|
||||
<input type="radio" name="data" checked id="all">
|
||||
<label for="all">ALL cities</label>
|
||||
</li>
|
||||
<li onclick="setEuropeanCities()">
|
||||
<input type="radio" name="data" id="europe">
|
||||
<label for="europe">European cities</label>
|
||||
</li>
|
||||
<li onclick="setSpanishCities()">
|
||||
<input type="radio" name="data" id="spain">
|
||||
<label for="spain">Spanish cities</label>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="separator"></div>
|
||||
<ul>
|
||||
<li onchange="invertColors()">
|
||||
<input type="checkbox" name="data" id="invertColors">
|
||||
<label for="invertColors">Invert colors</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
|
||||
<div class="box legend">
|
||||
<h2 class="h2">World cities</h2>
|
||||
<ul class="category open-sans">
|
||||
<li id="capital"></li>
|
||||
<li id="normal"></li>
|
||||
</ul>
|
||||
<h2 class="h2">Inhabitants</h2>
|
||||
<ul id="legend-population">
|
||||
<li class="size open-sans">
|
||||
<div id="min"></div>
|
||||
<div id="max"></div>
|
||||
</li>
|
||||
<li class="avg open-sans"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
|
||||
marker-fill: ramp([adm0cap], (#EE4D5A, #68B69E), (0, 1), "=", category);
|
||||
marker-fill-opacity: 0.6;
|
||||
marker-allow-overlap: true;
|
||||
marker-line-width: 1;
|
||||
marker-line-color: #000;
|
||||
marker-line-opacity: 0.2;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
populatedPlacesLayer.on('metadataChanged', function(event) {
|
||||
event.styles.forEach(function (styleMetadata) {
|
||||
switch(styleMetadata.getProperty()) {
|
||||
case 'marker-width':
|
||||
renderLegendSize(styleMetadata);
|
||||
break;
|
||||
case 'marker-fill':
|
||||
renderLegendCapital(styleMetadata);
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function renderLegendSize(metadata) {
|
||||
document.getElementById('min').innerHTML = `
|
||||
<div class="circle circle-outline" style="width:8px; height:8px;"></div> <p>${metadata.getMin()}</p>
|
||||
`;
|
||||
|
||||
document.getElementById('max').innerHTML = `
|
||||
<div class="circle circle-outline" style="width:24px; height:24px;"></div> <p>${metadata.getMax()}</p>
|
||||
`;
|
||||
|
||||
document.querySelector('.legend .avg').innerHTML = `
|
||||
<p><b>Average: </b> ${metadata.getAverage().toFixed(2)}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderLegendCapital(metadata) {
|
||||
const categories = metadata.getCategories();
|
||||
|
||||
for (category of categories) {
|
||||
switch (category.name) {
|
||||
case 0:
|
||||
document.getElementById('normal').innerHTML = `
|
||||
<div class="circle" style="background:${category.value}"></div> Normal
|
||||
`;
|
||||
break;
|
||||
case 1:
|
||||
document.getElementById('capital').innerHTML = `
|
||||
<div class="circle" style="background:${category.value}"></div> Capital
|
||||
`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setAllCities() {
|
||||
populatedPlacesSource.setQuery('SELECT * FROM ne_10m_populated_places_simple');
|
||||
}
|
||||
|
||||
function setEuropeanCities() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name IN (SELECT admin FROM ne_adm0_europe)
|
||||
`);
|
||||
}
|
||||
|
||||
function setSpanishCities() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name = \'Spain\'
|
||||
`);
|
||||
}
|
||||
|
||||
function invertColors() {
|
||||
const invert = document.getElementById('invertColors').checked;
|
||||
const colors = invert ? '(#68B69E, #EE4D5A)' : '(#EE4D5A, #68B69E)';
|
||||
const content = `
|
||||
#layer {
|
||||
marker-width: ramp([pop_max], range(2, 12), quantiles(5));
|
||||
marker-fill: ramp([adm0cap], ${colors}, (0, 1), "=", category);
|
||||
marker-fill-opacity: 0.6;
|
||||
marker-allow-overlap: true;
|
||||
marker-line-width: 1;
|
||||
marker-line-color: #000;
|
||||
marker-line-opacity: 0.2;
|
||||
}
|
||||
`;
|
||||
populatedPlacesStyle.setContent(content);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CARTO.js + Category Dataviews + Vega Pie Chart</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="https://libs.cartocdn.com/carto.js/v4.1.11/carto.min.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:600" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
|
||||
|
||||
<!-- Custom Style -->
|
||||
<link href="https://carto.com/developers/carto-js/examples/maps/public/style.css" rel="stylesheet">
|
||||
|
||||
<!-- Vega -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/vega@3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vega-lite@2"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vega-embed@3"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Pie Chart Example</h1>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Done with Vega Lite</p>
|
||||
<br>
|
||||
<div id="piechart"></div>
|
||||
<div style="margin-top: 12px;" id="legend"></div>
|
||||
</section>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const source = new carto.source.SQL('SELECT * FROM ne_10m_populated_places_simple');
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: ramp([adm0name], cartocolor(Vivid), category(10));
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const layer = new carto.layer.Layer(source, style);
|
||||
|
||||
client.addLayer(layer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
const categoryDataview = new carto.dataview.Category(source, 'adm0name', {
|
||||
limit: 12,
|
||||
operation: carto.operation.COUNT
|
||||
});
|
||||
|
||||
categoryDataview.on('dataChanged', data => {
|
||||
const categories = data.categories;
|
||||
drawPieChart(categories, '#piechart');
|
||||
});
|
||||
|
||||
categoryDataview.on('error', error => {
|
||||
alert(error.message);
|
||||
});
|
||||
|
||||
client.addDataview(categoryDataview);
|
||||
|
||||
const bboxFilter = new carto.filter.BoundingBoxLeaflet(map);
|
||||
|
||||
categoryDataview.addFilter(bboxFilter);
|
||||
|
||||
const legend = document.getElementById("legend");
|
||||
|
||||
function renderCategoryLegend(metadata){
|
||||
|
||||
metadata.styles.forEach(function (styleMetadata) {
|
||||
if (styleMetadata.getProperty() == 'marker-fill') {
|
||||
let metaCategories = styleMetadata.getCategories();
|
||||
|
||||
for (category of metaCategories){
|
||||
const li = document.createElement('li');
|
||||
li.style.color = `${category.value}`
|
||||
li.innerHTML = `<span style="color: black;">${category.name}</span>`;
|
||||
legend.append(li);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
layer.on('metadataChanged', renderCategoryLegend);
|
||||
|
||||
function drawPieChart(cats, id) {
|
||||
|
||||
const vegaSpecPie = {
|
||||
"$schema": "https://vega.github.io/schema/vega/v3.3.1.json",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"autosize": "none",
|
||||
"signals": [{
|
||||
"name": "startAngle",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"name": "endAngle",
|
||||
"value": 6.29
|
||||
},
|
||||
{
|
||||
"name": "padAngle",
|
||||
"value": 0.05
|
||||
},
|
||||
{
|
||||
"name": "innerRadius",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"name": "sort",
|
||||
"value": false
|
||||
},
|
||||
],
|
||||
"data": [{
|
||||
"name": "categories",
|
||||
"values": cats,
|
||||
"transform": [{
|
||||
"type": "pie",
|
||||
"field": "value",
|
||||
"startAngle": {
|
||||
"signal": "startAngle"
|
||||
},
|
||||
"endAngle": {
|
||||
"signal": "endAngle"
|
||||
},
|
||||
"sort": {
|
||||
"signal": "sort"
|
||||
}
|
||||
}]
|
||||
}],
|
||||
|
||||
"scales": [{
|
||||
"name": "vivid",
|
||||
"type": "ordinal",
|
||||
"domain": {
|
||||
"data": "categories",
|
||||
"field": "name"
|
||||
},
|
||||
"range": ['#E58606','#5D69B1','#52BCA3','#99C945','#CC61B0','#24796C','#DAA51B','#2F8AC4','#764E9F','#ED645A','#CC3A8E','#A5AA99']
|
||||
}],
|
||||
|
||||
"marks": [{
|
||||
"type": "arc",
|
||||
"from": {
|
||||
"data": "categories"
|
||||
},
|
||||
"encode": {
|
||||
"enter": {
|
||||
"fill": {
|
||||
"scale": "vivid",
|
||||
"field": "name"
|
||||
},
|
||||
"x": {
|
||||
"signal": "width / 2"
|
||||
},
|
||||
"y": {
|
||||
"signal": "height / 2"
|
||||
}
|
||||
},
|
||||
"update": {
|
||||
"startAngle": {
|
||||
"field": "startAngle"
|
||||
},
|
||||
"endAngle": {
|
||||
"field": "endAngle"
|
||||
},
|
||||
"padAngle": {
|
||||
"signal": "padAngle"
|
||||
},
|
||||
"innerRadius": {
|
||||
"signal": "innerRadius"
|
||||
},
|
||||
"outerRadius": {
|
||||
"signal": "width / 2"
|
||||
},
|
||||
"fillOpacity": {
|
||||
"value": 1
|
||||
}
|
||||
},
|
||||
"hover": {
|
||||
"fillOpacity": {
|
||||
"value": 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
vegaEmbed(id, vegaSpecPie, {
|
||||
actions: false
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Populated places | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Most/less populated places</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Filter the 20 most/less populated places in the world.</p>
|
||||
<div class="separator"></div>
|
||||
<div id="controls">
|
||||
<ul class="actions">
|
||||
<li onclick="setAll()">
|
||||
<input type="radio" name="style" value="01" id="all" checked="">
|
||||
<label for="all">ALL Places
|
||||
<label>
|
||||
</li>
|
||||
<li onclick="setMostPopulated(20)">
|
||||
<input type="radio" name="style" value="02" id="most">
|
||||
<label for="most">Most populated places</label>
|
||||
</li>
|
||||
<li onclick="setLessPopulated(20)">
|
||||
<input type="radio" name="style" value="03" id="less">
|
||||
<label for="less">Less populated places</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 30, lng: 0 },
|
||||
zoom: 3,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-fill: #EE4D5A;
|
||||
marker-width: 7;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
function setAll() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #EE4D5A;
|
||||
marker-width: 7;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
function setMostPopulated(limit) {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
ORDER BY pop_max DESC LIMIT ${limit}
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #68B69E;
|
||||
marker-width: 12;
|
||||
marker-line-color: #FFFFFF;
|
||||
text-name: [name];
|
||||
text-face-name: 'Open Sans Regular';
|
||||
text-size: 12;
|
||||
text-dy: -10;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
function setLessPopulated(limit) {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
ORDER BY pop_max ASC LIMIT ${limit}
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #F15743;
|
||||
marker-width: 12;
|
||||
marker-line-color: #FFFFFF;
|
||||
text-name: [name];
|
||||
text-face-name: 'Open Sans Regular';
|
||||
text-size: 12;
|
||||
text-dy: -10;
|
||||
}
|
||||
`);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Populated places | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Most/less populated places</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Filter the 20 most/less populated places in the world.</p>
|
||||
<div class="separator"></div>
|
||||
<div id="controls">
|
||||
<ul class="actions">
|
||||
<li onclick="setAll()">
|
||||
<input type="radio" name="style" value="01" id="all" checked="">
|
||||
<label for="all">ALL Places<label>
|
||||
</li>
|
||||
<li onclick="setMostPopulated(20)">
|
||||
<input type="radio" name="style" value="02" id="most">
|
||||
<label for="most">Most populated places</label>
|
||||
</li>
|
||||
<li onclick="setLessPopulated(20)">
|
||||
<input type="radio" name="style" value="03" id="less">
|
||||
<label for="less">Less populated places</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.SQL(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-fill: #EE4D5A;
|
||||
marker-width: 7;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle);
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
function setAll() {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #EE4D5A;
|
||||
marker-width: 7;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
function setMostPopulated(limit) {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
ORDER BY pop_max DESC LIMIT ${limit}
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #68B69E;
|
||||
marker-width: 12;
|
||||
marker-line-color: #FFFFFF;
|
||||
text-name: [name];
|
||||
text-face-name: 'Open Sans Regular';
|
||||
text-size: 12;
|
||||
text-dy: -10;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
function setLessPopulated(limit) {
|
||||
populatedPlacesSource.setQuery(`
|
||||
SELECT *
|
||||
FROM ne_10m_populated_places_simple
|
||||
ORDER BY pop_max ASC LIMIT ${limit}
|
||||
`);
|
||||
|
||||
populatedPlacesStyle.setContent(`
|
||||
#layer {
|
||||
marker-fill: #F15743;
|
||||
marker-width: 12;
|
||||
marker-line-color: #FFFFFF;
|
||||
text-name: [name];
|
||||
text-face-name: 'Open Sans Regular';
|
||||
text-size: 12;
|
||||
text-dy: -10;
|
||||
}
|
||||
`);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pop-ups | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Pop-Ups</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create pop-up information windows and interact with your map.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">Select your preferred kind of pop-ups</p>
|
||||
</section>
|
||||
|
||||
<div id="controls">
|
||||
<ul class="actions">
|
||||
<li onclick="setPopupsClick()">
|
||||
<input type="radio" name="style" value="01" id="popup">
|
||||
<label for="popup">Pop-ups on click</label>
|
||||
</li>
|
||||
<li onclick="setPopupsHover()">
|
||||
<input type="radio" name="style" value="01" id="hover">
|
||||
<label for="hover">Pop-ups on hover</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 30, lng: 0 },
|
||||
zoom: 3,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.Dataset('ne_10m_populated_places_simple');
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
|
||||
featureOverColumns: ['name', 'pop_max', 'pop_min']
|
||||
});
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
const infowindow = new google.maps.InfoWindow();
|
||||
|
||||
function openPopup(featureEvent) {
|
||||
let content = '<div class="widget">';
|
||||
|
||||
if (featureEvent.data.name) {
|
||||
content += `<h2 class="h2">${featureEvent.data.name}</h2>`;
|
||||
}
|
||||
|
||||
if (featureEvent.data.pop_max || featureEvent.data.pop_min) {
|
||||
content += `<ul>`;
|
||||
|
||||
if (featureEvent.data.pop_max) {
|
||||
content += `<li><h3>Max:</h3><p class="open-sans">${featureEvent.data.pop_max}</p></li>`;
|
||||
}
|
||||
|
||||
if (featureEvent.data.pop_min) {
|
||||
content += `<li><h3>Min:</h3><p class="open-sans">${featureEvent.data.pop_min}</p></li>`;
|
||||
}
|
||||
|
||||
content += `</ul>`;
|
||||
}
|
||||
|
||||
content += `</div>`;
|
||||
|
||||
infowindow.setContent(content);
|
||||
infowindow.setPosition(featureEvent.latLng);
|
||||
if (!infowindow.map) {
|
||||
infowindow.open(map);
|
||||
}
|
||||
}
|
||||
|
||||
function closePopup(featureEvent) {
|
||||
infowindow.close();
|
||||
}
|
||||
|
||||
function setPopupsClick() {
|
||||
populatedPlacesLayer.off('featureOver');
|
||||
populatedPlacesLayer.off('featureOut');
|
||||
populatedPlacesLayer.on('featureClicked', openPopup);
|
||||
}
|
||||
|
||||
function setPopupsHover() {
|
||||
populatedPlacesLayer.off('featureClicked');
|
||||
populatedPlacesLayer.on('featureOver', openPopup);
|
||||
populatedPlacesLayer.on('featureOut', closePopup);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pop-ups | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Pop-Ups</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create pop-up information windows and interact with your map.</p>
|
||||
<div class="separator"></div>
|
||||
<section class="usage">
|
||||
<header>USAGE</header>
|
||||
<p class="open-sans">Select your preferred kind of pop-ups</p>
|
||||
</section>
|
||||
|
||||
<div id="controls">
|
||||
<ul class="actions">
|
||||
<li onclick="setPopupsClick()">
|
||||
<input type="radio" name="style" value="01" id="popup">
|
||||
<label for="popup">Pop-ups on click</label>
|
||||
</li>
|
||||
<li onclick="setPopupsHover()">
|
||||
<input type="radio" name="style" value="01" id="hover">
|
||||
<label for="hover">Pop-ups on hover</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([30, 0], 3);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const populatedPlacesSource = new carto.source.Dataset(`
|
||||
ne_10m_populated_places_simple
|
||||
`);
|
||||
const populatedPlacesStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 7;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const populatedPlacesLayer = new carto.layer.Layer(populatedPlacesSource, populatedPlacesStyle, {
|
||||
featureOverColumns: ['name', 'pop_max', 'pop_min']
|
||||
});
|
||||
|
||||
client.addLayer(populatedPlacesLayer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
const popup = L.popup({ closeButton: false });
|
||||
|
||||
function openPopup(featureEvent) {
|
||||
let content = '<div class="widget">';
|
||||
|
||||
if (featureEvent.data.name) {
|
||||
content += `<h2 class="h2">${featureEvent.data.name}</h2>`;
|
||||
}
|
||||
|
||||
if (featureEvent.data.pop_max || featureEvent.data.pop_min) {
|
||||
content += `<ul>`;
|
||||
|
||||
if (featureEvent.data.pop_max) {
|
||||
content += `<li><h3>Max:</h3><p class="open-sans">${featureEvent.data.pop_max}</p></li>`;
|
||||
}
|
||||
|
||||
if (featureEvent.data.pop_min) {
|
||||
content += `<li><h3>Min:</h3><p class="open-sans">${featureEvent.data.pop_min}</p></li>`;
|
||||
}
|
||||
|
||||
content += `</ul>`;
|
||||
}
|
||||
|
||||
content += `</div>`;
|
||||
|
||||
popup.setContent(content);
|
||||
popup.setLatLng(featureEvent.latLng);
|
||||
if (!popup.isOpen()) {
|
||||
popup.openOn(map);
|
||||
}
|
||||
}
|
||||
|
||||
function closePopup(featureEvent) {
|
||||
popup.removeFrom(map);
|
||||
}
|
||||
|
||||
function setPopupsClick() {
|
||||
populatedPlacesLayer.off('featureOver');
|
||||
populatedPlacesLayer.off('featureOut');
|
||||
populatedPlacesLayer.on('featureClicked', openPopup);
|
||||
}
|
||||
|
||||
function setPopupsHover() {
|
||||
populatedPlacesLayer.off('featureClicked');
|
||||
populatedPlacesLayer.on('featureOver', openPopup);
|
||||
populatedPlacesLayer.on('featureOut', closePopup);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pop-ups with embed video | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Google Maps -->
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDpVNTQI60ossApFzZ3dwSMZ1LcxOTY-rI&v=3.35"></script>
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Pop-Ups with embed video</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create pop-up information windows with embed videos.</p>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
var map = new google.maps.Map(document.getElementById('map'), {
|
||||
center: { lat: 0, lng: 0 },
|
||||
zoom: 5,
|
||||
fullscreenControl: false,
|
||||
gestureHandling: 'cooperative'
|
||||
});
|
||||
// Hide the map labels and geometry strokes
|
||||
map.set('styles', [{
|
||||
elementType: 'labels',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}, {
|
||||
elementType: 'geometry.stroke',
|
||||
stylers: [{ visibility: 'off' }]
|
||||
}]);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const cartoSource = new carto.source.Dataset(`
|
||||
example_video
|
||||
`);
|
||||
const cartoStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 20;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const cartoLayer = new carto.layer.Layer(cartoSource, cartoStyle, {
|
||||
featureClickColumns: ['youtube_url']
|
||||
});
|
||||
|
||||
client.addLayer(cartoLayer);
|
||||
map.overlayMapTypes.push(client.getGoogleMapsMapType(map));
|
||||
|
||||
const infowindow = new google.maps.InfoWindow();
|
||||
|
||||
function openPopup(featureEvent) {
|
||||
let content = '<div class="widget">';
|
||||
|
||||
if (featureEvent.data.youtube_url) {
|
||||
content += `<iframe width="240" src= ${featureEvent.data.youtube_url} frameborder="0" allowfullscreen></iframe>`
|
||||
}
|
||||
|
||||
content += `</div>`;
|
||||
|
||||
infowindow.setContent(content);
|
||||
infowindow.setPosition(featureEvent.latLng);
|
||||
if (!infowindow.map) {
|
||||
infowindow.open(map);
|
||||
}
|
||||
}
|
||||
|
||||
function closePopup(featureEvent) {
|
||||
infowindow.close();
|
||||
}
|
||||
|
||||
|
||||
cartoLayer.on('featureClicked', openPopup);
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pop-ups with embed video | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Pop-Ups with embed video</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<section>
|
||||
<p class="description open-sans">Create pop-up information windows with embed videos.</p>
|
||||
|
||||
</section>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<script>
|
||||
const map = L.map('map').setView([0, 0], 5);
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const cartoSource = new carto.source.Dataset(`
|
||||
example_video
|
||||
`);
|
||||
const cartoStyle = new carto.style.CartoCSS(`
|
||||
#layer {
|
||||
marker-width: 20;
|
||||
marker-fill: #EE4D5A;
|
||||
marker-line-color: #FFFFFF;
|
||||
}
|
||||
`);
|
||||
const cartoLayer = new carto.layer.Layer(cartoSource, cartoStyle, {
|
||||
featureClickColumns: ['youtube_url']
|
||||
});
|
||||
|
||||
client.addLayer(cartoLayer);
|
||||
client.getLeafletLayer().addTo(map);
|
||||
|
||||
const popup = L.popup({ closeButton: false });
|
||||
|
||||
function openPopup(featureEvent) {
|
||||
let content = '<div class="widget">';
|
||||
|
||||
if (featureEvent.data.youtube_url) {
|
||||
content += `<iframe width="240" src= ${featureEvent.data.youtube_url} frameborder="0" allowfullscreen></iframe>`
|
||||
}
|
||||
|
||||
content += `</div>`;
|
||||
|
||||
popup.setContent(content);
|
||||
popup.setLatLng(featureEvent.latLng);
|
||||
|
||||
if (!popup.isOpen()) {
|
||||
popup.openOn(map);
|
||||
}
|
||||
}
|
||||
|
||||
function closePopUp(featureEvent) {
|
||||
// remove popup from map object
|
||||
popup.removeFrom(map)
|
||||
}
|
||||
|
||||
|
||||
cartoLayer.on('featureClicked', openPopup);
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Storytelling map using Storymap.js | CARTO</title>
|
||||
<meta name="viewport" content="initial-scale=1.0">
|
||||
<meta charset="utf-8">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
|
||||
<!-- Include Leaflet -->
|
||||
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
|
||||
<link href="https://unpkg.com/leaflet/dist/leaflet.css" rel="stylesheet">
|
||||
<!-- Include CARTO.js -->
|
||||
<script src="../../../dist/public/carto.js"></script>
|
||||
<!--jquery-->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
||||
<!--boostrap-->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<!--leaflet.ajax for asynchronously adding geojson data-->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>
|
||||
<!--story map plugin-->
|
||||
<script src="https://cdn.rawgit.com/jakobzhao/storymap/master/dist/storymap.2.3.js"></script>
|
||||
|
||||
<link href="../style.css" rel="stylesheet">
|
||||
<!--add required stylesheets-->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<!--animation-->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
|
||||
<!--Google Font-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Cairo" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/jakobzhao/storymap/master/dist/storymap.2.3.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div id="storymap" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-8 storymap-map"></div>
|
||||
<div class="col-sm-6 col-md-4 storymap-story">
|
||||
<section data-scene="scene1">
|
||||
<h1>Spain, France and Portugal</h1>
|
||||
</section>
|
||||
<section data-scene="scene2">
|
||||
<h1>Spain</h1>
|
||||
<p>
|
||||
<a href="https://en.wikipedia.org/wiki/Spain">Source Wikipedia</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Spain (Spanish: España [esˈpaɲa] (About this sound listen)), officially the Kingdom of Spain (Spanish: Reino de España),[a][b]
|
||||
is a sovereign state located on the Iberian Peninsula in southwestern Europe, with two large archipelagoes,
|
||||
the Balearic Islands in the Mediterranean Sea and the Canary Islands off the North African Atlantic
|
||||
coast, two cities, Ceuta and Melilla, in the North African mainland and several small islands in
|
||||
the Alboran Sea near the Moroccan coast. The country's mainland is bordered to the south and east
|
||||
by the Mediterranean Sea except for a small land boundary with Gibraltar; to the north and northeast
|
||||
by France, Andorra, and the Bay of Biscay; and to the west and northwest by Portugal and the Atlantic
|
||||
Ocean. It is the only European country to have a border with an African country (Morocco)[h] and
|
||||
its African territory accounts for nearly 5% of its population, mostly in the Canary Islands but
|
||||
also in Ceuta and Melilla.
|
||||
</p>
|
||||
</section>
|
||||
<section data-scene="scene3">
|
||||
<h1>France</h1>
|
||||
<p>
|
||||
<a href="https://en.wikipedia.org/wiki/France">Source Wikipedia</a>
|
||||
</p>
|
||||
<p>
|
||||
France (French IPA: [fʁɑ̃s]), officially the French Republic (French: République française [ʁepyblik fʁɑ̃sɛz]), is a country
|
||||
whose territory consists of metropolitan France in western Europe, as well as several overseas regions
|
||||
and territories.[XIII] The metropolitan area of France extends from the Mediterranean Sea to the
|
||||
English Channel and the North Sea, and from the Rhine to the Atlantic Ocean. The overseas territories
|
||||
include French Guiana in South America and several islands in the Atlantic, Pacific and Indian oceans.
|
||||
The country's 18 integral regions (5 of which are situated overseas) span a combined area of 643,801
|
||||
square kilometres (248,573 sq mi) which, as of October 2017, has a population of 67.15 million people.[10]
|
||||
France is a unitary semi-presidential republic with its capital in Paris, the country's largest city
|
||||
and main cultural and commercial centre. Other major urban centres include Marseille, Lyon, Lille,
|
||||
Nice, Toulouse and Bordeaux.
|
||||
</p>
|
||||
</section>
|
||||
<section data-scene="scene4">
|
||||
<h1>Portugal</h1>
|
||||
<p>
|
||||
<a href="https://en.wikipedia.org/wiki/Portugal">Source Wikipedia</a>
|
||||
</p>
|
||||
<p>
|
||||
Portugal (Portuguese: [puɾtuˈɣaɫ]), officially the Portuguese Republic (Portuguese: República Portuguesa [ʁɛ'puβlikɐ puɾtu'ɣezɐ]),[note
|
||||
1] is a sovereign state located on the Iberian Peninsula in southwestern Europe. It is the westernmost
|
||||
country of mainland Europe, being bordered to the west and south by the Atlantic Ocean and to the
|
||||
north and east by Spain. Its territory also includes the Atlantic archipelagos of the Azores and
|
||||
Madeira, both autonomous regions with their own regional governments. At 1.7 million km2, its Exclusive
|
||||
Economic Zone is the 3rd largest in the European Union and the 11th largest in the world.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<aside class="toolbox">
|
||||
<div class="box">
|
||||
<header>
|
||||
<h1>Storytelling map</h1>
|
||||
<button class="github-logo js-source-link"></button>
|
||||
</header>
|
||||
<div>
|
||||
<p class="description open-sans">Storytelling map using Storymap.js and CARTO.js.</p>
|
||||
</div>
|
||||
<footer class="js-footer"></footer>
|
||||
</div>
|
||||
</aside>
|
||||
<script>
|
||||
// set map with initial zoom and coodinates view
|
||||
const map = L.map('map').setView([40, 2], 4);
|
||||
// define scenes
|
||||
let scenes = {
|
||||
scene1: { lat: 30, lng: 0, zoom: 3, layers: ['basemap'], name: "1" },
|
||||
scene2: { lat: 40.40002626, lng: -3.68335169, zoom: 5, layers: ['basemap','cartoLayer'], name: "2" },
|
||||
scene3: { lat: 47.08372683, lng: 2.39999792, zoom: 5, layers: ['basemap','cartoLayer'], name: "3" },
|
||||
scene4: { lat: 38.52995953, lng: -8.90001001, zoom: 7, layers: ['basemap','cartoLayer'], name: "4" }
|
||||
};
|
||||
// disable scroll wheel zoom
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
|
||||
// add basemaps to map
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
// set CARTO client
|
||||
const client = new carto.Client({
|
||||
apiKey: 'default_public',
|
||||
username: 'cartojs-test'
|
||||
});
|
||||
|
||||
const source = new carto.source.SQL(`
|
||||
SELECT * FROM ne_10m_populated_places_simple
|
||||
WHERE adm0name IN ('Spain', 'Portugal', 'France')
|
||||
`);
|
||||
// define CartoCSS code to style data on map
|
||||
const style = new carto.style.CartoCSS(`
|
||||
#layer[adm0name = "Spain"]{
|
||||
marker-fill: #fbb4ae;
|
||||
marker-allow-overlap: true;
|
||||
}
|
||||
#layer[adm0name = "Portugal"]{
|
||||
marker-fill: #ccebc5;
|
||||
marker-allow-overlap: true;
|
||||
}
|
||||
#layer[adm0name = "France"]{
|
||||
marker-fill: #b3cde3;
|
||||
marker-allow-overlap: true;
|
||||
}
|
||||
|
||||
`);
|
||||
// create CARTO layer from source and style variables
|
||||
const Cartolayer = new carto.layer.Layer(source, style);
|
||||
|
||||
// add CARTO layer to the client
|
||||
client.addLayer(Cartolayer);
|
||||
|
||||
// define layers that will be used on the map
|
||||
var layers = {
|
||||
cartoLayer: {
|
||||
layer: client.getLeafletLayer()
|
||||
},
|
||||
basemap: {
|
||||
layer: L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png')
|
||||
}
|
||||
};
|
||||
|
||||
// initializaze storymap
|
||||
$('#storymap').storymap({
|
||||
scenes: scenes,
|
||||
layers: layers,
|
||||
baselayer: layers.basemap,
|
||||
legend: true,
|
||||
loader: true,
|
||||
flyto: false,
|
||||
scalebar: true,
|
||||
scrolldown: true,
|
||||
progressline: true,
|
||||
navwidget: true,
|
||||
createMap: function () {
|
||||
let map = L.map($(".storymap-map")[0], { zoomControl: false }).setView([30, 0], 3);
|
||||
// add basemap
|
||||
this.baselayer.layer.addTo(map);
|
||||
// add carto layer
|
||||
layers.cartoLayer.layer.addTo(map)
|
||||
return map;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user