Skip to content

Instantly share code, notes, and snippets.

@jsanch
Last active April 24, 2019 22:58
Show Gist options
  • Save jsanch/82e127086ad2b30b69af7c6d5d048e3c to your computer and use it in GitHub Desktop.
Save jsanch/82e127086ad2b30b69af7c6d5d048e3c to your computer and use it in GitHub Desktop.
Cadastro Mineiro - SATEC | CARTO
<!DOCTYPE html>
<html>
<head>
<title> Cadastro Mineiro - SATEC | 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@1.3.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.3.1/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="https://libs.cartocdn.com/carto.js/v4.1.11/carto.min.js"></script>
<link href="https://carto.com/developers/carto-js/examples/maps/public/style.css" rel="stylesheet">
<!-- Include Airship -->
<link rel="stylesheet" href="https://libs.cartocdn.com/airship-style/v1.0.3/airship.css">
<!-- <link rel="stylesheet" href="https://libs.cartocdn.com/airship-icons/v1.0.3/icons.css"> -->
<script src="https://libs.cartocdn.com/airship-components/v1.0.3/airship.js"></script>
<!-- axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body class="as-app-body as-app">
<nav role="tablist" class="as-toolbar-tabs as-tabs">
<button onclick="showMap(event)" role="tab" class="as-tabs__item as-tabs__item--active">MAP</button>
<button onclick="showLeft(event)" role="tab" class="as-tabs__item">LEFT</button>
<button onclick="showRight(event)" role="tab" class="as-tabs__item">RIGHT</button>
</nav>
<div class="as-content">
<main class="as-main">
<div class="as-map-area">
<div id="map"></div>
</div>
<footer class="as-map-footer" style="min-height:100px;">
<section class="as-box as-box--xlarge as-box--scroll" style="min-width: 200px;">
<h1 class="as-title">Definir área de interesse</h1>
<section class="usage">
<header>Filtrar dados com base no polígono desenhado</header>
<ul class="description open-sans" id="rPoint"></ul>
</section>
</section>
</footer>
</main>
<aside class="as-sidebar as-sidebar--right as-bg--support-02">
<div id="coords"></div>
<as-category-widget
class="as-p--16"
heading="Tipo "
description="tipo de cadastro mineiro (click para filtrar)"></as-category-widget>
</aside>
</div>
<script>
// set map with initial zoom and coodinates view
const map = L.map('map').setView([-12.9, 15.51], 6);
// 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: 'eb4e759b57d6555e9c7880b6e39b9db8bcc5ae6e',
username: 'satec-partner'
});
// set SQL query
const source1 = new carto.source.SQL(`select cartodb_id,tipo,
the_geom_webmercator,
the_geom,
n_titulo,
empresa
from cadastro_mineiro_1
where gis_ok = 'SIM'
`);
// define styles of layer.
const style1 = new carto.style.CartoCSS(`
#layer {
polygon-fill: ramp([tipo], (#66C5CC, #F6CF71, #404bed, #B3B3B3), ("AM", "TP", "TE"), "=");
polygon-opacity: 0.4;
}
#layer::outline {
line-width: 1;
line-color: ramp([tipo], (#00f5d8, #ad831f, #404bed, #B3B3B3), ("AM", "TP", "TE"), "=");
line-opacity: 1;
}
`);
// set the CARTO layer using the source and style defines previously
const layer1 = new carto.layer.Layer(source1, style1, {
featureOverColumns: ['n_titulo','tipo','empresa']
});
const polydrawn = false;
// popoup
const popup = L.popup({ closeButton: false });
layer1.off('featureOver');
layer1.off('featureOut');
layer1.on('featureClicked', openPopup);
function openPopup(featureEvent) {
let content = '<div class="widget">';
if (featureEvent.data.n_titulo) {
content += `<li> <b>titulo</b>: ${featureEvent.data.n_titulo}</li>`;
}
if (featureEvent.data.tipo || featureEvent.data.empresa) {
if (featureEvent.data.tipo) {
content += `<li><b>tipo</b>: ${featureEvent.data.tipo} </li>`;
}
if (featureEvent.data.empresa) {
content += `<li><b>empresa</b>: ${featureEvent.data.empresa} </li>`;
}
}
content += `</div>`;
popup.setContent(content);
popup.setLatLng(featureEvent.latLng);
if (!popup.isOpen()) {
popup.openOn(map);
}
}
function closePopup(featureEvent) {
popup.removeFrom(map);
}
// add CARTO layer to the client
client.addLayer(layer1);
// WIDGET
const categoryWidget = document.querySelector('as-category-widget');
categoryWidget.showClearButton = true;
categoryWidget.showHeader = true;
categoryWidget.visibleCategories = 8;
// DATAVIEW
const categoryDataview = new carto.dataview.Category(source1, 'tipo', {
limit: 8,
operation: carto.operation.COUNT,
operationColumn: 'tipo'
});
// FILTER according to widget selection
const currentSelection = new carto.filter.Category('tipo', {});
source1.addFilter(currentSelection);
// FILTER datavie by custom bounding box
// const bboxFilter = new carto.filter.BoundingBoxLeaflet(map);
// categoryDataview.addFilter(bboxFilter);
//categoryDataview.addFilter(bboxFilter);
categoryWidget.addEventListener('categoriesSelected', (event) => {
if (event.detail.length){
currentSelection.setFilters({ in: event.detail });
}
else {
currentSelection.resetFilters();
}
});
categoryDataview.on('dataChanged', data => {
console.log('Updating category widget');
colorDict = {
"AM": "#66C5CC",
"TP": "#F6CF71",
"TE": "#404bed"
};
data.categories.forEach((item, index, arr)=>
{
arr[index]["color"] = colorDict[item.name.trim()];
});
categoryWidget.categories = data.categories;
});
categoryDataview.on('error', error => {
// alert(error.message);
});
client.addDataview(categoryDataview);
client.getLeafletLayer().addTo(map);
// DRAWING TOOL
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
let drawControl = new L.Control.Draw({
draw: {
polygon: {
shapeOptions: {
stroke: true,
color: '#3388ff',
weight: 4,
opacity: 0.5,
fill: true,
fillColor: null, //same as color by default
fillOpacity: 0.2,
showArea: true,
clickable: true
},
metric: true
},
polyline: false,
line: false,
marker: false,
rectangle: false,
circle: false,
circlemarker: false,
},
edit: {
featureGroup: drawnItems
}
});
// initialise the draw controls
map.addControl(drawControl);
// Clear the previous layers from the feature group
map.on('draw:drawstart', () => {
drawnItems.clearLayers();
clearChart();
});
// Reset the source when clearing features
map.on('draw:deletestop ', () =>{
source1.setQuery(`select cartodb_id,tipo,
the_geom_webmercator,
the_geom,
n_titulo,
empresa
from cadastro_mineiro_1
where gis_ok = 'SIM'
`);
clearChart();
});
// Resert the chart if there's one and categories change
categoryDataview.on('dataChanged', data => {
if (drawnItems.getLayers().length > 0){
generateChart(data);
}
});
var deb = '';
// 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;
coords = layer.toGeoJSON()['geometry']["coordinates"]
dms = coords[0].map(function(a){return ddToDms(a[0],a[1])})
firstN = dms.slice(0,-1);
layer.bindTooltip(firstN.join('<br>'))
layer.addTo(drawnItems);
map.addLayer(layer);
// get drawn rectangle data
polySelect(JSON.stringify(layer.toGeoJSON().geometry));
el = document.getElementById('coords');
el.innerHTML = firstN.join('<br>');
});
// get radius and center of drawn circle and change source of the CARTO layer
map.on(L.Draw.Event.EDITED, function (e) {
let layer = e.layer;
coords = layer.toGeoJSON()['geometry']["coordinates"]
dms = coords[0].map(function(a){return ddToDms(a[0],a[1])})
firstN = dms.slice(0,-1);
layer.bindTooltip(firstN.join('<br>'))
layer.addTo(drawnItems);
map.addLayer(layer);
// get drawn rectangle data
polySelect(JSON.stringify(layer.toGeoJSON().geometry));
});
function polySelect(poly){
let polyDrawn = true;
source1.setQuery(`select cartodb_id,tipo, the_geom_webmercator, the_geom, n_titulo, empresa
from cadastro_mineiro_1
where gis_ok = 'SIM' and
ST_intersects(
the_geom,
St_SetSRID(
St_GeomFromGeoJSON('${poly}'),
4326)
)`);
};
/* create an axios client to the SQL API */
var SQL_CLIENT = axios.create({
method: 'get',
url: 'https://satec-partner.carto.com/api/v2/sql?',
params: { api_key: 'eb4e759b57d6555e9c7880b6e39b9db8bcc5ae6e'}
});
function clearChart(){
console.log('Clearing the chart');
// remove current chart rows
const list = document.getElementById('rPoint');
if(list.childNodes.length > 0){
list.removeChild(list.childNodes[0]);
}
}
// chart is only generated when rectangle is drawn
function generateChart(data){
console.log('Populate the chart');
let qry = source1.getQuery();
if (data && data.categories.length < 3){
const catlist = data.categories.map( c => { return `'${c.name}'` }).join(',');
qry = `SELECT * FROM ( ${qry} ) s WHERE tipo in (${catlist})`;
}
// remove current chart rows
const list = document.getElementById('rPoint');
clearChart;
// check for widget filters
// if filter exists get values from filter items & add where clause to request below using them
const filtercheck = source1.getFilters();
SQL_CLIENT.request({
params: {
q: `WITH q AS (
${qry}
)
SELECT n_titulo,tipo,empresa
FROM q`
},
})
.then(function (response) {
if (response && response.data && response.data.rows) {
const rows = response.data.rows;
let results = ""
let header_attributes = [];
let results_table = "<table class=\"as-table as-table--stripped\">";
results_table += "<tr>";
rows.forEach(function (row) {
for (var field in row) {
if (header_attributes.includes(field)) {
} else {
header_attributes.push(field);
results_table += "<th>" + field + "</th>";
}
}
});
results_table += "</tr>";
rows.forEach(function (row) {
header_attributes.forEach(function (attrib) {
if (row.hasOwnProperty(attrib)) {
results_table += "<td>" + row[attrib] + "</td>";
} else {
results_table += "<td>nodata</td>";
}
});
results_table += "</tr>";
});
results_table += "</table>";
document.getElementById('rPoint').innerHTML = results_table;
} else {
alert('Check the console, something happened');
}
})
.catch(function (error) {
console.log(error);
});
};
function ddToDms(lat, lng) {
var lat = lat;
var lng = lng;
var latResult, lngResult, dmsResult;
lat = parseFloat(lat);
lng = parseFloat(lng);
latResult = (lat >= 0)? 'N' : 'S';
// Call to getDms(lat) function for the coordinates of Latitude in DMS.
// The result is stored in latResult variable.
latResult += getDms(lat);
lngResult = (lng >= 0)? 'E' : 'W';
// Call to getDms(lng) function for the coordinates of Longitude in DMS.
// The result is stored in lngResult variable.
lngResult += getDms(lng);
// Joining both variables and separate them with a space.
dmsResult = latResult + ' ' + lngResult;
// Return the resultant string
return dmsResult;
}
function getDms(val) {
var valDeg, valMin, valSec, result;
val = Math.abs(val);
valDeg = Math.floor(val);
result = valDeg + "º";
valMin = Math.floor((val - valDeg) * 60);
result += valMin + "'";
valSec = Math.round((val - valDeg - valMin / 60) * 3600 * 1000) / 1000;
result += valSec + '"';
return result;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment