Welcome to Advanced GIS, Lecture 8
This is a web page that can be viewed as slides.
→ to move forward
← to go back
Advanced GIS
Class 8
Please fill out this form while we settle in
no class next week (March 17): spring break
functions?
function sayHi(name) {
console.log('hi ' + name);
}
three steps:
- create a button
- listen for a click on the button
- change the layer's SQL
1. create a button
<button class="juvenile-button">
just show Juvenile habitat
</button>
2. listen for a click on the button
juvenileButton.addEventListener('click', function (e) {
...
});
3. change the layer's SQL
juvenileButton.addEventListener('click', function (e) {
source.setQuery("SELECT * FROM hms_efh_2009tiger_shark WHERE life_stage = 'Juvenile'");
});
events
most of the time, code happens sequentially
(you get the idea)
events give the user a way to interrupt the program
you can use this pattern with any other kind of input
- Add the HTML for the input to the page
- Listen for the input to change
- Update your data layer's SQL
you could make a button for each type of feature
SELECT *
FROM hms_efh_2009tiger_shark
WHERE life_stage = 'Adult'
and
SELECT *
FROM hms_efh_2009tiger_shark
WHERE life_stage = 'Neonate'
but that's kinda what dropdowns are for
1. create a dropdown
<select class="type-picker">
<option value="all">Show all life stages</option>
<option value="Adult">Adult</option>
<option value="Juvenile">Juvenile</option>
<option value="Neonate">Neonate</option>
</select>
2. listen for a change to the dropdown
layerPicker.addEventListener('change', function (e) {
...
});
with a dropdown, you want to vary the SQL by the option selected
SELECT *
FROM hms_efh_2009tiger_shark
WHERE life_stage = 'Adult'
SELECT *
FROM hms_efh_2009tiger_shark
WHERE life_stage = 'Neonate'
var lifeStage = e.target.value;
var lifeStage = e.target.value;
var sql = "SELECT * FROM hms_efh_2009tiger_shark WHERE life_stage = " + lifeStage;
var lifeStage = e.target.value;
var sql = "SELECT * FROM hms_efh_2009tiger_shark WHERE life_stage = '" + lifeStage + "'";
the event listeners we just looked at are standard browser events
there are also map-specific events
listening for leaflet events
map.on('moveend', function () {
console.log('done moving');
});
popups
1. when creating the layer, tell Carto which fields are allowed in the popup
source
like when you tell Carto which fields are in the popup
make an HTML string that goes into the popup
source
this can be basically any HTML you can imagine, including video, images, and audio
source
start simple and add to it
source
the process is very similar for putting data in a sidebar (or elsewhere on a page)
source
gathering data
I'd suggest starting with Google Forms
easiest case, with the least code
source
you have to manually enter the latitude and longitude
source
but we can customize this a bit if we copy the way Google Forms are submitted
hmm but you still have to enter the latitude and longitude somehow
source
using an event listener to set the latitude and longitude
source
hiding the latitude and longitude
source
same thing, with a redirect
source
when customizing a Google Form this way, you gain control over how it looks and adding a map input
but you also lose some features:
but you also lose some features:
- validation of inputs (making sure an input's not empty, for example)
but you also lose some features:
- validation of inputs (making sure an input's not empty, for example)
- fancy radio buttons and dropdowns
you will need to make these yourself (similarly to making the map input)
once your form is working, create a Google Sheet for the responses
and sync that sheet up with a Carto dataset
as long as there are fields called Latitude
and Longitude
, this will be fine
filter features to the area around a clicked point
source
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
ST_Transform(the_geom, 2263),
ST_Buffer(
ST_Transform(CDB_LatLng(40.732, -73.986), 2263),
10000
)
)
SELECT *
FROM nypd_motor_vehicle_collisions
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
smaller geometry,
larger geometry
)
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
the_geom,
larger geometry
)
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
ST_Transform(the_geom, 2263),
larger geometry
)
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
ST_Transform(the_geom, 2263),
ST_Buffer(
input point,
10000
)
)
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
ST_Transform(the_geom, 2263),
ST_Buffer(
CDB_LatLng(40.732, -73.986),
10000
)
)
SELECT *
FROM nypd_motor_vehicle_collisions
WHERE ST_Within(
ST_Transform(the_geom, 2263),
ST_Buffer(
ST_Transform(CDB_LatLng(40.732, -73.986), 2263),
10000
)
)
you can look at relationships between layers, too
SELECT collisions.*
FROM collisions
JOIN ny_boroughs ON
ST_Within(
collisions.the_geom,
ny_boroughs.the_geom
)
WHERE ny_boroughs.boroname = 'Bronx'
leaflet plugins