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 18): spring break
        
        
            
no class the week after (March 25)
        
        
            
class online after that (April 1)
        
        
        
        
        
            
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'
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
        
        
        
        
            
1. find the form's action attribute
        
        
        
        
          
make your own form in HTML with the same action
        
        
        
        
            
2. for each form input, find the name attribute
        
        
        
        
            
add a form input with the same name
        
        
        
            this is a pretty good walkthrough
            source
         
        
        
            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