Last active
April 24, 2019 22:58
-
-
Save jsanch/82e127086ad2b30b69af7c6d5d048e3c to your computer and use it in GitHub Desktop.
Cadastro Mineiro - SATEC | CARTO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title> 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