SlideShare uma empresa Scribd logo
1 de 224
INTRODUCTION TO WEB
PROGRAMMING FOR GIS
APPLICATIONS
WHO THIS COURSE IS FOR
• Anyone who is interested in a more conceptual understanding of how web
applications work.
• HTML, CSS, Bootstrap, JavaScript, JQuery, PHP, SQL and how they all work together.
• Web development is very different than programming an application for a single computer,
so even if you are an experienced programmer there can be a steep learning curve when
moving to the web.
• In particular, we will be talking about geospatial applications.
• Leaflet, OpenLayers, PostGIS, geoJSON, geospatial data storage, retrieval, analysis, and
display.
• There are some aspects of geospatial web applications that differ from standard database
applications, which we will identify and explore.
WHO THIS COURSE IS FOR
• Two main groups of people
• GIS specialists, analysts, and/or developers interested in deploying internet based
applications.
• Publish content onto the web for external consumption.
• Escape the costs of commercial licenses for internal users of GIS.
• Develop spatial tools that are free from dependencies on ESRI update cycles.
• Web programmers interested in expanding their skillset into geospatial applications.
• Geospatial data
• Web maps
• Spatial Analysis
• Server-side tools
MY BACKGROUND
• I’ve been programming computers since the early 80s. There was very little canned software at
the time so you almost had to program to get much use out of a computer.
• I remember cassette tape drives, 8” floppies, and the first PC with a 10MB hard drive and
wondering how you would ever fill that much space.
• I remember monochrome monitors with only a single font and dot matrix printers with only a
single font, and word processing software that you had to use in-text tags to make bold print or
indent a paragraph so you wouldn’t really know what the document looked like until you printed
it.
• I remember when Apple McIntosh came out and blew everybody away with a mouse and What-
You-See-Is-What-You-Get graphical display so you could actually see on the screen what your
documents would look like and you could control the computer without typing commands.
MY BACKGROUND
• I sold my first software, a flash card program, in 1984 as a senior in high school to PC Disk
magazine.
• I developed database applications for video store rentals for several years between high school
and college.
• In 1990 I changed course and started a degree in Wildlife Biology. Soon after I learned about
GIS and realized I had found my calling.
• I began programming in ArcInfo with AML, then ArcView with Avenue. In 2000, as I was starting
a PhD program, ESRI introduced ArcGIS 8.0 and I quickly realized I would need to learn to
program in Visual Basic and ArcObjects as well.
• When ESRI introduced ArcGIS 9.0 I had to learn Python to speed up the development process
and create more portable extensions.
MY BACKGROUND
• When maps first started being served over the internet I immediately saw the
advantages but I did not have the resources to set up an ArcServer instance on a
server and learn to program against it.
• I took some classes on ESRI’s JavaScript API but struggled to use it for anything
productive for two main reasons.
• They skipped over the basics of web application programming.
• Without a server installation I had no way to practice what I learned.
MY BACKGROUND
• In 2014 I saw some talks at a GIS conference on open-source GIS programming and the light went on.
• With an open source approach I could develop web applications on my own for free without spending tens of
thousands of dollars on ESRI software.
• The only cost would be my time and even though I had three decades of experience programming database
applications and two decades of experience developing GIS applications in a large number of languages and
environments, the web development world sounded like a foreign language.
• What did all the jargon mean? How did all the pieces work together? Which pieces did I really need to focus on?
• I began trying to learn it all, and spent extensive amounts of time reading books and taking on-line classes and
setting up software and developing applications both at work and for fun.
• This course is my attempt to share what I learned with others in my position, and help them ease through the
process. If you are a programmer or GIS analyst who is struggling with making the transition to the on-line world
then I hope this course can help you.
COURSE PHILOSOPHY
• Although this is a course on web application development you will not learn
much code.
• You will see some code in examples of course, but there are many courses
available to teach you the actual nuts and bolts of writing code.
• I believe that it is more important to understand things conceptually before
diving into the details. Web programming, in particular, has a lot of bits and
pieces that aren’t intuitively obvious, even to experienced desktop developers.
This course is intended to fill in those gaps.
COURSE GOALS - UNDERSTANDING
• Understand the basics of client-server architecture and how it differs from single-
user applications
• Understand the basics of client side technologies (HTML, CSS, JavaScript)
• Understand the basics of server-side technologies (PHP, SQL, Databases)
• Understand how to communicate between client and server (AJAX)
• Understand commonly available libraries and frameworks (JQuery, Boostrap)
• Understand the tools available for geospatial applications (Leaflet, Turf, PostGIS,
GeoJSON)
HOW IS PROGRAMMING FOR THE WEB DIFFERENT THAN
A SINGLE USER DESKTOP ENVIRONMENT?
• Client-Server Architecture
• Hundreds or thousands of clients accessing one server.
• Clients can be using different browsers, different operating systems, different screen
sizes, etc.
• Data is stored on the server and requested by the client.
• User interaction occurs on the client, data access is handled by the server, and data
processing can occur on either end.
• As a result you need to know how to program on the client side as well as the server
side.
• More importantly you need to know WHEN to handle things on the client and when to
handle things on the server and how to communicate between client and server.
CLIENT-SERVER ARCHITECTURE
• Servers process requests and return a result, then Clients do something with the results
• Just like a server in a restaurant
• You (the client) tell the server what you want (Request)
• The server delivers it to you (Result), and then you do something with it.
• This requires things to happen on both ends
• In order to process your request, the server informs the cook of your order and the cook prepares the
food from scratch and then the server delivers it to the client.
• This happens behind the scene. The details are unknown and unimportant to the client. This is server-
side processing.
• Once the food is delivered, the client has to cut the steak, put salad dressing on the salad, and spoon it
into his mouth. This is client-side processing.
• The server and the cook handle multiple clients simultaneously.
CLIENT-SERVER ARCHITECTURE
Client (HTML,
CSS, JavaScript)
Database (PostgreSQL,
SQLServer, Oracle,
MySQL)
Web Server (PHP,
ASP,.Net Java,
Node)
Request
(AJAX)
Result
(AJAX)
Request (SQL)
Data
MAJOR COMPONENTS
• Client
• HTML, CSS, JavaScript (Work together)
• Server
• PHP, Java, ASP.NET, Ruby, Python, Node (Choose one)
• Database
• SQL (MySQL, PostgreSQL, SQLite, SQLServer, Oracle, DB2)
• No SQL (Mongo, Couch, IndexDB)
MINOR COMPONENTS
• Communication
• GET, POST, ECHO, AJAX, JSON
• Libraries, API’s, and Frameworks
• Client - JQuery, Dojo, Bootstrap,
• Server – Cake, CodeIgnitor, Laravel
• Mapping Components
• Google Maps, Leaflet, OpenLayers, ESRI Javascript API, Turf.js, PostGIS
CLIENT SIDE
• In terms of the Web, client means browser.
• Netscape, Chrome, Firefox, Safari, Internet Explorer, Edge, Opera, “Webkit”
• All browsers understand HTML, CSS, JavaScript
• Minor differences in how they are implemented and supported, especially IE.
• HTML – HyperText Markup Language
• CSS – Cascading Style Sheets
• JavaScript – Programming Language
CLIENT SIDE
• In terms of the Web, client means browser.
• All browsers understand HTML, CSS, Javascript
• HTML – HyperText Markup Language
• Provides structure and content
• Original web technology
• CSS – Cascading Style Sheets
• JavaScript – Programming Language
CLIENT SIDE
• In terms of the Web, client means browser.
• All browsers understand HTML, CSS, Javascript
• HTML – HyperText Markup Language
• CSS – Cascading Style Sheets
• Makes things pretty
• Colors, borders, positioning, etc.
• JavaScript – Programming Language
CLIENT SIDE
• In terms of the Web, client means browser.
• All browsers understand HTML, CSS, Javascript
• HTML – HyperText Markup Language
• CSS – Cascading Style Sheets
• JavaScript – Programming Language
• Makes things happen.
• Respond to user input, calculations, animations.
• NOT Java
HTML DOCUMENT STRUCTURE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
………….
</body>
</html>
HTML
• Tag based
• Headings
• Paragraph
• Lists
• Opening and closing tags
• <h1>GIS</h1>
• <p>Lorem ipsum</p>
• <ul> ( <ol> )
<li> item 1</li>
<li> item 2 </li>
• </ul> ( </ol> )
HTML
• Links
• Images
• Div
• Span
• Breaks
• Style
• <a href=“http://www.google.com”>Go to
Google</a>
• <img src=“images/picture.jpg” width=“200px”>
• <div class=“text-bold” id=“div1”>……</div>
• <p>Lorem Ipsum<span class=“super-
script”>2</span> Lorem Ipsum </p>
• <br><hr>
• <b>Bold</b><i>Italics</i><small>Small
text</small>
HTML TABLES
<table>
<tr>
<td>A</td><td>B</td><td>C</td>
</tr>
<tr>
<td>1</td><td>2</td><td>3</td>
</tr>
</table>
A B C
1 2 3
HTML FORMS
<form action=“process.php” method=“post”>
<input type=“text” name=“firstName” value=“Bob” ><br><br>
<input type=“date” name=“birthday”><br><br>
<select name=“registered”>
<option value=“true”>Yes</option>
<option value=“false”>No</option>
</select><br><br>
<input type=“checkbox” name=“active” value=“active” checked>
Active?<br><br>
<hr>
<input type=“radio” name=“gender” value=“male” checked> Male<br><br>
<input type=“radio” name=“gender” value=“female” > Female<br><br>
<hr>
<input type=“submit name=“submit” value=“Submit Button”>
</form>
CSS
• Cascading Style Sheets
• Introduced in the mid 90’s
• Standardized in the mid 00’s
• Separation of content from
presentation
• CSS is composed of RULES that act
on SELECTORS
p {
font-size: 20pt;
color:red;
background-color:black;
}
.text-bold {
font-weight:bold;
}
#first-row {
padding-left:30px;
}
CSS – SELECTORS & RULES
• Tags
• Classes - .
• ID - #
• Pseudo Classes
• :visited
• :hover
p {
font-size: 20pt;
color:red;
background-color:black;
}
.text-bold {
font-weight:bold;
}
#first-row {
padding-left:30px;
}
a {
color:yellow;
}
a:visited {
color:orange;
}
a:hover {
background-color:black;
}
CSS – WHERE IT LIVES
• Inline
• Internal
• External
• <h1 style=“color:#000;background-color:#FFF”>Title</h1>
• <style>
• h2 {
• color:#FFF
• background-color:#000;
• }
• </style
• <link rel=“stylesheet” type=“txt/css”
href=“master_style.css”>
CSS - PRECEDENCE
• Specificity takes precedence over
generality.
• id>class>tag
• inline>internal>external
<div class=“default-text”>
<p> These are a few of my favorite
things
<ul id=“favorite-things-list”>
<li>Pizza</li>
<li>Beer</li>
</ul>
</p>
</div>
CSS - PRECEDENCE
• Specificity takes precedence over
generality.
• id>class>tag
• inline>internal>external
<div class=“default-text”>
<p> These are a few of my favorite things
<ul id=“favorite-things-list”>
<li>Pizza</li>
<li>Beer</li>
</ul>
</p>
</div>
CSS - PRECEDENCE
<div class=“default-text”>
<p> These are a few of my favorite
things
<ul id=“favorite-things-list”>
<li>Pizza</li>
<li>Beer</li>
</ul>
</p>
</div>
p {
color: red;
}
.default-text {
color:black;
}
#favorite-things-list
{
color:darkblue;
}
CSS - PRECEDENCE
<div>
<p class=“default-text”> These are a few of my
favorite things
<ul id=“favorite-things-list”
style=“color:black”>
<li>Pizza</li>
<li>Beer</li>
</ul>
</p>
</div>
External CSS
p {
color: red;
}
.default-text {
color:black;
}
#favorite-things-list {
color:darkblue;
}
Internal CSS
p {
color: black
}
.default-text {
color:blue;
}
#favorite-things-list {
color:red;
}
CSS – PSEUDO-SELECTORS
• Links
• a:link {color:blue}
• a:visited {color:purple}
• a:active {color:black}
• Hover
a:hover {
background-color:blue;
color:white;
}
• Focus
• input:focus {background-
color:yellow)
• Children
• li:firstchild {font-weight:bold}
• ul .multi-list>li {color:red}
• ul .multilist>li>ul>li {color:blue}
• ul .multilist>li>ul>li>ul>li
{color:green}
COLORS ON THE WEB
• Constants
• red
• azure
• saddlebrown
• RGB
• #000 Black
• #800 Pink
• #F00 Red
• RGB (Continued)
• #F0F ?????
• #FFF ?????
• RGB 24 bit
• #FF0000 Red
• #FF0088 Magenta
• #6AD029 ????????
CSS – PRIMARY USES
• Style
• Font
• Color
• Size
• Borders
• Formatting
• Indents
• Margin
• Alignment
• Spacing
• Layout
• Relative
• Absolute
• Float
• Animation
• Hover and focus pseudo:selectors
• Turn content on and off, change its
position, or change styles on the fly
(with Javascript)
BEYOND CSS
• LESS and SASS
• Use variables in CSS
• Use conditional statements
• Compile to CSS
DOCUMENT OBJECT MODEL (DOM)
• The DOM is an object oriented depiction of the HTML and CSS in a web page.
• Every time a page is loaded its HTML and CSS are translated into a DOM.
• The DOM is actually what the browser uses to display the page.
WHAT IS AN OBJECT?
• Objects are a way of describing the world into language a computer can
understand.
• An object is a data structure that has both properties and methods.
• Properties are data and can be a single value, an array, or another object.
• In computer lingo these are analogous to variables.
• Methods are actions that an object can perform.
• In computer lingo these are analogous to a function.
• Objects can inherit the properties and methods of its parent object and overwrite
them or add to them.
WHAT IS AN OBJECT?
• Animal Object
• Properties
• Skin Type
• Movement Type
• Color
• Temperament
• Methods
• Make a noise
• Move
• Eat
INHERITING FROM AN OBJECT
• Reptile Object – Inherit from animal
• Properties
• Skin Type: Scales
• Movement Type: crawl
• Color
• Temperament
• Methods
• Make a noise {}
• Move {crawl}
• Eat{}
• Grow Scales{}
• Mammal Object – Inherit from animal
• Properties
• Skin Type:Hair
• Movement Type:[walk, hop, fly,]
• Color
• Temperament
• Methods
• Make a noise{}
• Move {if Rabbit then hop, if bat then fly, else
walk}
• Eat{}
• Grow Hair{}
• Produce Milk{}
INHERITING FROM AN OBJECT
• Mouse Object – Inherit from Mammal
• Properties
• Skin Type:Hair
• Movement Type:Walk
• Color
• Temperament: Nervous
• Methods
• Make a noise {squeak}
• Move {walk}
• Eat {search for cheese}
• Grow Hair {}
• Produce Milk {}
• Scare Ladies {}
• Avoid cats {}
• Dog Object – Inherit from Mammal
• Properties
• Skin Type:Hair
• Movement Type:Walk
• Color
• Temperament: Friendly
• Methods
• Make a noise {bark}
• Move {walk}
• Eat {beg for treats}
• Grow Hair {}
• Produce Milk {}
• Catch Frisbee {}
• Chase cats {}
ABSTRACTION AND INSTANTIATION
• To instantiate an object means to create an individual object from the object blueprint.
• In computer lingo, the blueprint is known as a “class”
• An “Abstract” class is one that can have its properties and methods inherited but can not be instantiated.
• If I say “get me an animal” you will say “what kind?”.
• Defining an animal is useful as a blueprint that other things can inherit from but cannot be an actual thing.
• Mammals inherit properties of animals and modify or add new ones. Reptiles do the same but in a different manner
• Dogs and mice also inherit properties of mammals and add new ones, but you can go to the store and actually buy a
dog or a mouse.
• In computer lingo each individual dog is an instance of the dog class which inherits some properties from the mammal
abstract class which inherits some properties from the animal class.
• Some properties can not actually be set until the object is instantiated. We know that dogs have a color and
temperament property but we won’t know what color or what temperament until we have an actual instance of the dog
class.
• This object hierarchy is an intuitive way to describe the world and translate it into language that a computer can
understand.
OBJECTS IN COMPUTERS
• The concept of objects and object hierarchies is very common in computer software.
• If I right click on a graphic object in PowerPoint I can see and change its color, transparency, size, etc.
• Those properties are different if it’s a line or a polygon or an image.
• In GIS terms we can think of a feature as an instantiation of a feature class and the coordinates
and attributes as its properties.
• The feature class can inherit different properties depending on whether it is a point, line, or polygon.
• When we display a layer on a map we can also set its display properties
• Size
• Color
• Transparency, etc.
DOCUMENT OBJECT MODEL (DOM)
• The DOM is an object oriented depiction of the HTML and CSS in a web page.
• Every time a page is loaded its HTML and CSS are translated into a DOM.
• The DOM is actually what the browser uses to display the page.
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p>Lorem Ipsum</p>
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
IMPORTANT PROPERTIES OF HTML ELEMENTS
• childElementCount
• children[5]
• innerHTML
• innerText
• id
• eventhandlers (onclick
etc.)
• parentElement
• style
• style.color=“red”
• style.display=“none”
• tagname
EVENTS
• Event Driven Programming
• When Apple introduced the McIntosh in 1984 it introduced an entirely new paradigm into computer programming.
• Prior to this, computer code was written and processed in a top down manner
• First line of code was executed, then the second, etc.
• The McIntosh allowed the user to interact with the computer via the mouse.
• Click, double click, drag, drop, right click, scroll up, scroll down, etc. I.E. events.
• Event handlers are snippets of code that are executed in response to an event.
• Events also can occur when the mouse hovers over an object, when a window is resized, before and/or after a page is
loaded, when the text in an input box is changed, etc.
• Modern programming is largely object oriented and event driven.
• Programmers need to understand the events that occur in the environment that they are programming in and write
event handlers for those events.
• They also need to understand the object model behind their environment so that they can manipulate those objects in
response to events.
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p> Lorem Ipsum
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
JAVASCRIPT
• Also began in the mid 90’s as Netscape’s scripting technology
• Microsoft used JScript and VBScript
• Adobe used ActionScript in Flash
• Standardized in the mid-00’s as the dominant client-side scripting language in
browsers
• Allows manipulation of the DOM.
• Also available for server-side scripting in NODE.js
• Open Source – This is good. It is not subject to the whims of a single company.
• Object Oriented – EVERYTHING in JavaScript is an object. Even functions.
• Event Driven – Much of the JavaScript code that you write will be event handlers.
HOW DO WE ACCESS THE DOM?
• Every browser makes the DOM accessible through the document object
• The document object is available to all JavaScript code
• document.head or document.body to reference the head or body.
• Children of the body are an array of HTML elements
• document.body.children[2] to reference the third child element of the body.
• document.body.children[2].children[1] to reference the second child of the third child
of the body.
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p> Lorem Ipsum
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
ACESSING THE DOM
• var colorlist = document.body.children[1].children[0]
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p> Lorem Ipsum
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
ACESSING THE DOM
• colorlist = document.body.children[1].children[0]
• animallist = document.body.children[1].children[1]
• firstanimallist =
document.body.children[1].children[1].children[0]
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p> Lorem Ipsum
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
JAVASCRIPT
<script>
console.log(“Hello World!”);
console.log(document);
console.log(document.body.children[0].children[0].innerHTML)
</script>
DOCUMENT OBJECT MODEL (DOM)
<html>
<head>
<title> My Page</title>
</head>
<body>
<div id=“col1”>
<p>Lorem Ipsum</p>
</div>
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
</div>
</body>
</html>
html
body
head
title div: col1
p
div: col2
ul:
animallist
ul: colorlist
li li li li
JAVASCRIPT
<script>
console.log(“Hello World!”);
console.log(document);
console.log(document.body.children[0].children[0].innerHTML)
</script>
IMPORTANT PROPERTIES OF HTML ELEMENTS
• childElementCount
• children[5]
• innerHTML
• innerText
• id
• eventhandlers (onclick
etc.)
• parentElement
• style
• style.color=“red”
• style.display=“none”
• tagname
JAVASCRIPT
• Since most of the JavaScript we write will be event handlers lets write one.
<script>
document.body.addEventListener(“click”, function(e){
console.log(“Clicked in the body”);
console.log(e);
alert(“Clicked in the bodynX: ”+e.clientX+”nY: “+e.clientY);
alert(e);
});
</script>
EVENT HANDLER
<div id=“col2”>
<ul id=“colorlist”>
<li>Red</li>
<li>Green</li>
</ul>
<ul id=“animallist”>
<li>dog</li>
<li>cat</li>
</ul>
<button id=“switch-
list”>Switch</button>
</div>
#colorlist {
display:block;
}
#animallist {
display:none;
}
#switch-list {
color:red;
background-color:black;
}
#switch-list:hover {
color:black;
background-color:red;
}
#switch-list:click {
if #colorlist is displayed
hide #colorlist
show #animallist
else
hide #animallist
show #colorlist
}
JAVASCRIPT CONDITIONAL STATEMENTS
If (condition) {
…….. Code
} elseif (condition) {
……... Code
} else {
……... Code
}
• Condition
• Always evaluate to true or false
• document.title == “My Page”
• document.body.childElements > 4
• e.shiftKey
• document.title != “My Page”
EVENT HANDLER
document.body.children[1].children[2].addEventListener('click', function(e){ // #switch-list:click
if (document.body.children[1].children[0].style.display != "none") { // If #colorlist is
displayed
document.body.children[1].children[0].style.display = "none"; // Hide #colorlist
document.body.children[1].children[1].style.display = "block"; // Show
#animallist
} else { // Else
document.body.children[1].children[1].style.display = "none"; // Hide #animallist
document.body.children[1].children[0].style.display = "block"; // Show #colorlist
}
});
ACESSING THE DOM
• var colorlist = document.body.children[1].children[0];
• var animallist = document.body.children[1].children[1];
• var firstanimallist = animallist.children[0];
• var firstanimallist = document.body.children[1].children[1].children[0];
EVENT HANDLER
document.body.children[1].children[2].addEventListener('click', function(e){ // #switch-list:click
if (document.body.children[1].children[0].style.display!="none") { // If #colorlist is
displayed
document.body.children[1].children[0].style.display="none"; // Hide #colorlist
document.body.children[1].children[1].style.display="block"; // Show #animallist
} else { // Else
document.body.children[1].children[1].style.display="none"; // Hide #animallist
document.body.children[1].children[0].style.display="block"; // Show #colorlist
}
});
EVENT HANDLER
var btnSwitch = document.body.children[1].children[2];
var colorlist = document.body.children[1].children[0];
var animallist = document.body.children[1].children[1];
btnSwitch.addEventListener('click', function(e){// #switch-list:click
if (colorlist.style.display!="none") { // If #colorlist is displayed
colorlist.style.display="none"; // Hide #colorlist
animallist.style.display="block"; // Show #animallist
} else { // Else
animallist.style.display="none"; // Hide #animallist
colorlist.style.display="block"; // Show #colorlist
}
});
EVENT HANDLER
var btnSwitch = document.getElementById(‘switch-button’);
var colorlist = document.getElementById(‘colorlist’);
var animallist = document.getElementById(‘animallist’);
btnSwitch.addEventListener('click', function(e){// #switch-list:click
if (colorlist.style.display!="none") { // If #colorlist is displayed
colorlist.style.display="none"; // Hide #colorlist
animallist.style.display="block"; // Show #animallist
} else { // Else
animallist.style.display="none"; // Hide #animallist
colorlist.style.display="block"; // Show #colorlist
}
});
DOM MANIPULATION – EXAMPLE 2
<div id="col2">
<ul id="colorlist">
<li>Red</li>
<li>Green</li>
</ul>
<ul id="animallist">
<li>dog</li>
<li>cat</li>
</ul>
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
var btnChange = document.getElementById('change-color');
btnChange.addEventListener('click', function(e){
var col1=document.getElementById('col1');
switch (col1.style.color) {
case "red":
col1.style.color="orange";
break;
case "green":
col1.style.color="blue";
break;
case "blue":
col1.style.color="purple";
break;
case "black":
col1.style.color="red";
break;
default:
col1.style.color="red";
break;
}
});
SWITCH STATEMENT
switch (col1.style.color) {
case "red":
col1.style.color=“green";
break;
case "green":
col1.style.color="blue";
break;
case "blue":
col1.style.color=“black";
break;
case "black":
col1.style.color=“purple";
break;
default:
col1.style.color="red";
break;
}
If (col1.style.color==”red”){
col1.style.color=" green ";
} else if (col1.style.color==” green”){
col1.style.color=“blue";
} else if (col1.style.color==” blue”){
col1.style.color=“black";
} else if (col1.style.color==” black”){
col1.style.color=“purple";
} else {
col1.style.color="red";
}
DOM MANIPULATION – EXAMPLE 2
<div id="col2">
<ul id="colorlist">
<li>Red</li>
<li>Green</li>
</ul>
<ul id="animallist">
<li>dog</li>
<li>cat</li>
</ul>
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
var btnChange = document.getElementById('change-color');
btnChange.addEventListener('click', function(e){
var col1=document.getElementById('col1');
switch (col1.style.color) {
case "red":
col1.style.color=“green";
break;
case "green":
col1.style.color="blue";
break;
case "blue":
col1.style.color=“black";
break;
case "black":
col1.style.color=“purple";
break;
default:
col1.style.color="red";
break;
));
CALCULATIONS AND VALIDATION
……
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
<input id="value1" type="text" value="5">
<input id="value2" type="text" value=“6">
<button id="multiply">Multiply</button>
var
btnMultiply=document.getElementById("multiply");
var
inputValue1=document.getElementById("value1");
var
inputValue2=document.getElementById("value2");
btnMultiply.addEventListener('click', function(e) {
var val1=inputValue1.value;
var val2=inputValue2.value;
alert(val1+" X "+val2+" = "+(val1*val2))
});
CALCULATIONS AND VALIDATION
……
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
<input id="value1" type="text" value="5">
<input id="value2" type="text" value=“6">
<button id="multiply">Multiply</button>
var btnMultiply=document.getElementById("multiply");
var inputValue1=document.getElementById("value1");
var inputValue2=document.getElementById("value2");
btnMultiply.addEventListener('click', function(e) {
var val1=inputValue1.value;
var val2=inputValue2.value;
if (isNaN(val1) || isNaN(val2)) {
alert("At least one of the values is not a number");
} else {
alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2));
}
});
CALCULATIONS AND VALIDATION
……
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
<input id="value1" type="text" value="5">
<input id="value2" type="text" value=“6">
<button id="multiply">Multiply</button>
…..
btnMultiply.addEventListener('click', function(e) {
var val1=inputValue1.value;
var val2=inputValue2.value;
if (isNaN(val1) || isNaN(val2)) {
alert("At least one of the values is not a number");
} else {
alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2));
}
});
inputValue1.addEventListener('keyup', function(e) {
if (isNaN(inputValue1.value)) {
alert("Please enter a number.");
}
});
THE PROBLEM WITH ALERTS
• Many people find alerts annoying.
• The first time a user visits your site and
sees an alert everything is fine
• But the SECOND time they have the
option of preventing anymore dialogs by
clicking the box.
• Because of this, alerts are not a reliable
method for getting a message to the
user.
SO HOW DO WE COMMUNICATE TO THE USER?
• Use a third party library such as Impromptu.
• Simulate alerts through HTML, CSS, JavaScript
• <div> that’s normally hidden with a button to remove it.
• Jquery
• Bootstrap
• DOM manipulation
• Add or modify text, change colors, border, etc.
CALCULATIONS AND VALIDATION
……
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
<input id="value1" type="text" value="5">
<input id="value2" type="text" value=“6">
<button id="multiply">Multiply</button>
…..
btnMultiply.addEventListener('click', function(e) {
var val1=inputValue1.value;
var val2=inputValue2.value;
if (isNaN(val1) || isNaN(val2)) {
alert("At least one of the values is not a number");
} else {
alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2));
}
});
inputValue1.addEventListener('keyup', function(e) {
if (isNaN(inputValue1.value)) {
inputValue1.style.border="2px solid red";
} else {
inputValue1.style.border="";
}
});
PASSING FUNCTIONS AS PARAMETERS
inputValue1.addEventListener('keyup', function(e) {
if (isNaN(inputValue1.value)) {
inputValue1.style.border="2px solid red";
} else {
inputValue1.style.border=""; }
});
inputValue2.addEventListener('keyup', function(e) {
if (isNaN(inputValue2.value)) {
inputValue2.style.border="2px solid red";
} else {
inputValue2.style.border="";
}
});
function validateNumber() {
if (isNaN(this.value)) {
this.style.border="2px solid red";
} else {
this.style.border="";
}
inputValue1.addEventListener(‘keyup', validateNumber)
inputValue2.addEventListener(‘keyup', validateNumber)
CALCULATIONS AND VALIDATION
……
<button id="switch-button">Switch</button>
<button id="change-color">Change
Color</button>
</div>
<input id="value1" type="text" value="5">
<input id="value2" type="text" value=“6">
<button id="multiply">Multiply</button>
<hr>
<p id="result"></p>
…..
var result=document.getElementById(‘result’)
btnMultiply.addEventListener('click', function(e) {
var val1=inputValue1.value;
var val2=inputValue2.value;
if (isNaN(val1) || isNaN(val2)) {
result.innerHTML="One or both of the input values is invalid";
result.style.color="red";
} else {
result.innerHTML=val1+" X "+val2+" = " + val1*val2;
result.style.color="green";
}
});
……
LOOPS IN JAVASCRIPT
• While Loop
var i=0;
while (i<9){
alert(i);
i++; // i=i+1
}
• For Loop
for (var i=0;i<myArray.length;i++){
alert(myArray[i]);
}
ARRAY’S IN JAVASCRIPT
• Arrays are indexed numerically using the [ ]
notation.
• Arrays can hold any type of objects
• Arrrays can hold different types of objects in the
same array.
• An empty array is created using
• var myArray=[ ];
• You can add items to an array at initiation using
• var myArray=[45, ‘dog’, [1,2,3], {color:red;size:10}]
• myArray[0] = 45;
• myArray[1] = ‘dog’;
• myArray[2] = [1,2,3];
• myArray[2][2]=3;
• myArray[3]={color:red;size:10};
• myArray[3].size = 10;
ARRAYS IN JAVASCRIPT (CONT’D)
• Arrays have a length property
holding the number of elements in
an array.
• myArray.length = 4;
• You can add an element to an array
in three ways.
• myArray[myArray.length]=‘Bob’;
• myArray.push(‘Bob’);
• myArray.push(‘Bob’, ‘Bill’,103);
• myArray.unshift(‘Bob’, ‘Bill’, 103)
• Deleting elements from an array
• From the top
• x=myArray.pop();
• From the bottom
• x=myArray.shift();
OBJECTS IN JAVASCRIPT
• Everything in JavaScript is an object
• Unlike many programming languages you
don’t have to define an object class.
• You can create your own objects on the fly
using the following notation
myDog = {
species:”dog”,
color:”blue”,
name:”Lola”,
age: 14,
legs: [‘front-left’, ‘front-right’, ‘rear-left’, ‘rear-
right’],
displayAge:function(){
alert(“Lola is 14 years old”);
}
}
• You reference an objects properties and/or
methods using the ‘dot’ notation.
• myDog.name = “Lola”;
• myDog.legs[2] = ‘rear-left’
• myDog.displayAge();
OBJECT LITERALS AND JSON
• Object Literal and Binary Objects
var myDog = {species:”dog”,
color:”blue”,
name:”Lola”,
age: 14,
legs: [‘front-left’, ‘front-right’,
‘rear-
left’, ‘rear-right’]
};
myDogJSON=JSON.stringify(myDog);
• JSON
var myDogJSON = ‘{"species":"dog",
"color":"blue",
"name":"Lola",
"age":14,
"legs":["front-left","front-right","rear-
left","rear-right"]
}’;
myDog = JSON.parse(myDogJSON);
FRAMEWORKS, LIBRARIES, API’S, PLUG-INS
• Bootstrap – CSS library for responsive web sites.
• Layout, formatting tables and forms, lists, menus, tooltips, etc.
• JQuery – Very popular for manipulating the DOM, event handlers, animations, AJAX, etc.
• JQuery Mobile – for mobile devices.
• Dojo – Similar functionality to JQuery, less popular but common in GIS applications.
• Leaflet.js – Mapping library
• Accessing different types of data
• Editing
• Measuring
• Routing
• Turf.js – JavaScript library for GIS operations.
• Impromptu – Deal with the alert box issue and make stylized popups with forms and pages.
MVC FRAMEWORKS
• Not a product, but a programming philosophy for organizing your code
• Model – View – Controller
• Model – Data access
• View – User Interface
• Controller – Connects user interface to data.
• Adaptations – MVA, MVP, HMVC, MVVM
• MVC Frameworks exist in many languages
• Django – Python
• Rails – Ruby
• ASP.NET MVC – Microsoft
• CodeIgnitor, Cake, Laravel – PHP
• Angular, Backbone, Ember - JavaScript
BOOTSTRAP
• CSS Library
• Cross Browser Compatibility
• Pre-defined classes
• Responsive Design
• Grid design
• 12 columns
• 4 screen size classes
• xs, small, medium, large
• Glyphicons – Fonts for standard web symbols.
• Javascript Library – tooltips, dialogs, etc.
• Makes your pages responsive, pretty, and standardized.
JQUERY - ”WRITE LESS, DO MORE”
• Cross Browser Compatibility
• Javascript Library for DOM manipulation
• Respond to Events
• Add and remove classes, attributes, and CSS
• Modify content
• Other Functionality
• AJAX – communicate with server from within Javascript
• Animations
• Validation
• JQuery UI – User interface – Tabs, Dialogs, Menu’s, etc.
JQUERY – STEP 1 SELECT A DOM ELEMENT OR GROUP OF DOM ELEMENTS
• Document
• Tags
• Classes
• ID
• $(document)
• $(“p”)
• $(“.link-buttons”)
• $(“#my-link”)
JQUERY – SELECTORS (ADVANCED)
• $(“#navBar a”)
• $(“img[alt]”)
• $(“#col2 p:first”)
• $(“tr:odd”)
• $(“a:not(#googleLink)”)
• $(“p:hidden”)
• Descendants (a tags within the navBar element)
• Attributes (image tags with the alt attribute set)
• Filters (first paragraph in the col2 element)
• Filters (odd table rows)
• Filters (Links except the one with an id of googleLink)
• Filters (hidden paragraphs)
JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED
• Run code automatically when the page is
loaded
• Add an event handler
• Hide or display an element
• Get the content
• Replace the content
• Add or Remove a class
$(document).ready(function(){})
$(“#myButton”).click(function(){
alert(“You clicked myButton”);
});
$(“.lights”).hide();
$(“.lights”).show();
var frstHTML = $(“p:first”).html();
$(“p:first”).html(“Replacing with this”);
$(“.lights”).addClass(“text-center”);
$(“.lights”).removeClass(“text-center”);
JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED
• Read the CSS
• Change the CSS
• Read an HTML attribute
• Change an HTML attribute
• Read an HTML form element
• Change an HTML form element
var size = $(“#header”).css(“font-size”);
$(“.main-points”). css(“font-weight”, “bold”);
var headerSrc = $(“#header_image”).attr(“src”);
$(“#header_image”).attr(“src”,“images/header2.jpg”);
var name = $(“#name”).val();
$(“#name”).val(“Joe Smith”);
JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED
• Loop through a set
$(“.numericField”).on(“keyup”,
function(){
});
$(“#myForm_submit”).click(function(){
$(“.numericField”).each(function(){
if (isNan($(this).val()) {
$(this).addClass(“has-error”);
} else {
$(this).removeClass(“has-
error”);
} // if NaN
}); // each numeric field
}); // click myForm_submit
GEOSPATIAL DATA ON THE WEB
• Binary Formats
• ESRI
• Coverages, Shapefile, Personal Geodatabase, File Geodatabase, Enterprise Geodatabase
• Open Source
• Shapefile, PostGIS., Spatiallite
• Text Based Formats
• XML based formats
• KML - Google
• GPX – GPS
• JSON based formats
• geoJSON
• topoJSON
XML
• GPX
<time>2016-10-17T10:08:03Z</time>
<wpt lat="20.38333" lon="-100">
<name>1</name>
<cmt>08:54 17-Oct-16</cmt>
</wpt>
<wpt lat="20.51667" lon="-100.81667">
<name>2</name>
<cmt>08:54 17-Oct-16</cmt>
</wpt>
<wpt lat="20.6" lon="-100.38333">
<name>3</name>
<cmt>08:54 17-Oct-16</cmt>
</wpt>
<wpt lat="21.3" lon="-100.51667">
<name>4</name>
<cmt>08:54 17-Oct-16</cmt>
</wpt>
• KML
</description>
<styleUrl>#IconStyle00</styleUrl>
<MultiGeometry>
<Point>
<altitudeMode>clampToGround</altitudeMode>
<coordinates> -
100.5166700003203,21.29999999980021,0</coordinates>
</Point>
</MultiGeometry>
</Placemark>
</Folder>
<Style id="IconStyle00">
<IconStyle>
<Icon><href>Layer0_Symbol_153b24f0_0.png</href></Icon>
<scale>0.250000</scale>
</IconStyle>
<LabelStyle>
<color>00000000</color>
<scale>0.000000</scale>
</LabelStyle>
<PolyStyle>
<color>ff000000</color>
<outline>0</outline>
</PolyStyle>
</Style>
</Document>
GEOJSON
• A specification for creating, identifying, and storing geospatial data in JavaScript Object Notation
• Mapping API’s
• Leaflet
• Google
• OpenLayers
• ESRI????
• Other software
• QGIS
• PostGIS
• Turf.js
• PHP
• Databases
GEOJSON - POINT
{“type”: “Point”,
“coordinates”:[-108.5, 33.7]
}
coordinates[0] = -108.5
coordinates[1] = 33.7
{“type”: “MultiPoint”,
“coordinates”:[[-108.5, 33.7], [-108.4,
33.5], [-108.6, 33.2]]
}
coordinates[1][0] = -108.4
coordinates[0][1] = ??????
coordinates[2,0] = ??????
coordinates[0,2] = ??????
GEOJSON - LINE
{“type”: “LineString”,
“coordinates”:[[-108.5, 33.7], [-108.4,
33.5], [-108.6, 33.2]]
}
{“type”: “MultiLineString”,
“coordinates”:[[[-108.5, 33.7], [-108.4,
33.5], [-108.6, 33.2]], [[-108.5, 33.7], [-
108.4, 33.5], [-108.6, 33.2]], [[-108.5,
33.7], [-108.4, 33.5], [-108.6, 33.2]]]
}
GEOJSON - POLYGON
{“type”: “Polygon”,
“coordinates”:[[[-108.5, 33.7], [-108.4,
33.5], [-108.6, 33.2], [-108.5, 33.7]], [[-
108.5, 33.7], [-108.4, 33.5], [-108.6,
33.2], [-108.5, 33.7]]]
}
{“type”: “MultiPolygon”,
“coordinates”:[[[[-108.5, 33.7], [-108.4,
33.5], [-108.6, 33.2], [-108.5, 33.7]], [[-
108.5, 33.7], [-108.4, 33.5], [-108.6,
33.2], [-108.5, 33.7]]],
[[[-108.5, 33.7], [-108.4, 33.5], [-108.6,
33.2], [-108.5, 33.7]]]]
}
GEOJSON – FEATURES AND FEATURECOLLECTIONS
{“type”:”feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-108.5, 33.7]
},
“properties”: {“species”:”Bald Eagle”,
“sex”:”male”,
“age”:7
}
}
{“type”:”featureCollection”,
“features”: [{“type”:”feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-108.5, 33.7]
},
“properties”: {“species”:”Bald Eagle”,
“sex”:”male”,
“age”:7
}
}, {“type”:”feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-109.1, 32.5]
},
“properties”: {“species”:”Golden Eagle”,
“sex”:”female”,
“age”:2
}
}]
}
GEOJSON
var county = { "type": "FeatureCollection",
"features": [ { "type": "Feature",
"properties": { "id": 1180,
"name": "San Juan del Rio",
"population": 118173.000000,
"country": "Mexico",
"state": "Queretaro",
"county": "San Juan del Rio“ },
"geometry": { "type": "MultiPoint",
"coordinates": [ [ -99.999, 20.3833 ] ] }
}]
}
MAPPING API’S FOR THE WEB
• Google Maps API
• Pro: Familiarity
• Pro: Perspective, Streetview
• Con: Proprietary
• Con: Limited to Google background maps
• Leaflet
• Pro: Open Source
• Pro: Small Footprint
• Pro: Newer codebase
• Pro: Easy to use
• Con: Limited in scope(but lots of plug-ins)
• Open Layers
• Pro: Open Source
• Pro: Many features
• Pro: Rotation, 3D
• Con: Large footprint
• Con: Learning curve
• ESRI Javascript API
• Con: Proprietary
• Pro: Many Features
• Pro: Integrates well with ESRI products if you
use them.
WHAT DO YOU GET WITH A MAPPING API?
• Map canvas
• Occupies a div on your web page
• Control size and placement of the map by setting the CSS of the div
• JavaScript library
• Add controls (zoom, select layers, scale bar, coordinates, edit tools, etc)
• Display data
• Manipulate data
• Analyze data using turf.js
WHAT CAN YOU DO WITH A MAPPING API ON THE
CLIENT SIDE
• Display a background map
• Streets
• Topography
• Aerial Photos
• Display your own GIS data
• Zoom, pan, search, select, view attributes, etc.
• Display your location
• Analyze (intersections, nearest features, distances, areas, buffers, etc.)
BUT…..
• You are only working with static data.
• You cannot change the data.
• You cannot add new data (at least not that anyone else can see).
• In order to make changes to the base data that others will be able to see, you
need…..
• A database server.
• You can’t secure your web page to prevent others from accessing it.
WHAT YOU NEED A DATABASE SERVER FOR
• Any changes that need to be persisted longer than the current session.
• Any changes that others will be to see when they open the web page.
• Security – If you want to password protect your web pages or implement any kind
of log-in system you will need some a database system.
EDITORS
• HTML, CSS, and JavaScript are just text files.
• You can write code in any program that will save a plain asci text file.
• There are many advantages to having an actual code editor and many are free.
• Colors
• Automatic indenting
• Code “hinting”
• Code completion
• Code collapsing
• Parenthesis highlighting
• Run time environment
• Debugging
• Plug-Ins
• Emmet
EDITORS
• Brackets
• Free
• All Platforms
• Supports all languages
• Supports Emmet
• Live Preview
• Sublime Text
• Notepad++
• Emacs
• Text Wrangler
• Komodo
• Atom
• Netbeans
LETS MAKE A MAP!
1. Make a directory
2. HTML
3. CSS
4. JavaScript
HTML
CSS
JAVASCRIPT
• Load Leaflet
• Load Jquery
• Initialize Map
JAVASCRIPT – ADD DATA
• Create a marker and add it to the map
• Add a popup to the marker
• Chaining
• Pop-ups can include HTML and be complex
JAVASCRIPT – HANDLE DOM EVENT
• HTML
• CSS
• JavaScript
$(“zoomToZocalo”).on(“click”, function(){
JAVASCRIPT – HANDLE MAP EVENT
• Choose an event to respond to
• Write an event handler
JAVASCRIPT – ADD EXTERNAL DATA
• Add Leaflet.ajax.js plug-in to map document
• Add the JavaScript code to read the ajax file and add it to the map.
• Add a pointToLayer option that creates the popup for each attraction
{
"type": "Feature",
"properties": {
"id": 3,
"name": "Chapultepec Park",
"image": "chapultepec.jpg",
"web": "https://en.wikipedia.org/wiki/Chapultepec"
},
"geometry": {
"type": "Point",
"coordinates": [ -99.18654, 19.41933 ]
}
}
JAVASCRIPT – ADD EXTERNAL DATA
• Add Leaflet.ajax.js plug-in to map document
• Add the JavaScript code to read the ajax file and add it to the map.
• Add a pointToLayer option that creates the popup for each attraction
JAVASCRIPT – BUILD HTML FROM GEOJSON
• Add buttons for each feature
• Add event handlers for each button
JAVASCRIPT - ANALYSIS
• Turf.js – Client side geospatial analysis
• HTML
• JavaScript
QGIS
• Open Source Desktop GIS
• Equivalent of ArcGIS Desktop in the ESRI suite
• Advantages
• Free
• Raster manipulation without Spatial Analyst
• Includes functionality only available in ArcEditor or ArcInfo
• Multi-user capable out of the box with PostGIS
• Wide range of data formats and easily converts between them
SUMMARY
• So far we have learned a little bit about
• The three primary technologies that drive the internet and how they interact.
• HTML
• CSS
• JavaScript
• Two very popular libraries that make web development easier
• Bootstrap (CSS)
• jQuery (JavaScript)
• Two open source libraries for geospatial applications
• Leaflet – Web mapping
• Turf – Geospatial Analysis
SUMMARY
• With the knowledge we have so far we can
• Create a web map with our own data
• Respond to user input
• Perform relatively complex spatial analysis
• The caveat is that the data is relatively static
• What we cannot do is develop an application where the clients can create or edit
data and send it back to the server so that it is accessible by other clients.
• For that we need a database server.
SERVER SIDE TECHNOLOGIES
• Database
• Allows for storage and retrieval of information
• Structured Query Language (SQL)
• Programming Language
• PHP
• Java
• Perl
• Ruby
• ASP.Net
• JavaScript via Node.js
DATABASES
• Most GIS people are brought up in the world of single user computers and think of
databases in terms of a program on their computer such as dBase, FoxPro or Microsoft
Access.
• These databases include both a database engine (storage and retrieval) and front end tools
(forms, reports, etc).
• In the multi-user or enterprise world a database is only the database engine.
• The front end can be written in any kind of language that has a driver for the database.
• Dedicated software: Visual Basic, C#, Python
• Internet Application: HTML, CSS, Javascript + Server side language to access the database.
• The biggest differences between a personal computer database and an enterprise
level multi-user database is that they are highly optimized for speed, security, and
handling many users simultaneously.
SQL
• Structured Query Language
• Implements CRUD
• Create
• Retrieve
• Update
• Delete
POPULAR ENTERPRISE DATABASES (RDBMS)
• Commercial
• Microsoft SQL Server
• Oracle
• IBM DB2
• Open Source
• MySQL
• PostgreSQL
• SQLite
• Advantages – Well established technology
POPULAR ENTERPRISE DATABASES (NO SQL)
• Commercial
• ???????
• Open Source
• MongoDB
• CouchDB
• PouchDB
• IndexDB – HTML5 spec in every browser.
• Advantages – Flexibility
• JSON Storage = ease of use with JavaScript
DATABASES AND GEOSPATIAL DATA
DATABASES AND GEOSPATIAL DATA
• How to handle coordinates????
• Table fields
• Store geoJSON objects in a text field.
• Utilize a spatial extension to a database
• Method for storing coordinates in a binary field
• Set of functions for dealing with spatial data
• ArcSDE
• SQL Server, Oracle, DB2, PostgreSQL
• PostGIS
• PostgreSQL
• Spatialite
• SQLite
TECHNOLOGY STACK USED IN THIS COURSE
• Database
• PostgreSQL
• PostGIS Extension
• Programming Language
• PHP
• Open source
• Widely available
• Well documented
SERVER OPTIONS
• Install on local machine
• Great for development but not great for a webserver.
• XAMPP includes Apache Web Server, MySQL, PHP, and Perl
• PostgreSQL and PostGIS
• Purchase a hosting plan
• Make sure that the plan includes the programming language and database you install on
your local machine.
• A2 Hosting includes PostgreSQL and PostGIS
• Move files back and forth using FTP.
• Control server using SSH (command line) or web application (phpPgAdmin)
• Purchase a dedicated server
WHAT DO I USE THE SERVER FOR?
• Number crunching and analysis
• You can do this locally using JavaScript.
• But the server is generally more powerful.
• Decision to process on the client or server depends on many factors.
• Retrieving data from the database
• AJAX call from JavaScript that returns text. (JSON, or HTML).
• Dynamic web pages
• .php extension instead of .html
• <?php …code…. ?>
• echo “string”; statement
COMMON FRUSTRATIONS
• The internet has grown organically as a bottom-up system
• At the time it was developed nobody really had any expectation of it growing into
what it has become
• There is a phenomenon known as “lock-in”, whereby a substandard technology
becomes established and popular to the point where it becomes almost
impossible for superior technology to replace it.
• QWERTY keyboard layout was designed to prevent manual typewriter keys from
jamming.
• Betamax vs VHS
• PC vs Mac
COMMON FRUSTRATIONS
• SQL has been around since the 70s. Long before the internet was even dreamed
of.
• PHP was developed in 1994 by Rasmus Lerdorf to help with his personal web
page.
• PHP originally stood for Personal Home Page
• Lerdorf didn’t intend for PHP to interact with databases.
• He said "I don’t know how to stop it, there was never any intent to write a
programming language. I have absolutely no idea how to write a programming
language, I just kept adding the next logical step on the way.“
• As of February 2014 PHP was the server-side language for 82% of web sites, up from
75% in 2010.
COMMON FRUSTRATIONS
• JavaScript wasn’t developed until 1995.
• While it was being developed nobody really knew what PHP was.
• Developed by Netscape while Navigator was the #1 browser in the world.
• Everyone knew Microsoft was also developing a scripting language called VBScript.
• This led to the “Browser Wars” of the late 1990s
• Over the years JavaScript and PHP became dominant.
• PHP added the ability to interact with databases.
• Both added object oriented functionality
• In 2005 AJAX was developed allowing JavaScript in the client to communicate directly with
PHP in the server.
TAKEAWAYS
• JavaScript, PHP, and SQL were never intended to work with each other and as a result they have
very different syntax.
• This is likely to remain the case due to “Lock-in” despite developments such as Node.JS and
ASP.NET
• “Suck it up, cupcake”. You have to learn 3 different ways to
• Concatenate strings
• Format numbers
• Deal with date and time
• Deal with objects and arrays
• Etc, etc, etc.
• Don’t get taken in by people selling you the latest and greatest technologies.
SQL - INTRODUCTION
• Structured Query Language
• Started with IBM in the early 70’s. First commercial version by Oracle in 1979.
• Client Server Architecture
• Request = SQL command
• Response – Recordset / # records / error.
• Declarative Programming – Say what you want to do
• Data Definition Language
• Data Manipulation Language
• Data Control Language
• Imperative Programming – Step by step algorithms
• Triggers
• Text-based
SQL - ARCGIS
• Select by Attributes • Definition Queries
SQL - ACCESS
• Design View • SQL View
• SELECT Vehicles.Year & " " &
[Vehicles.Make] & " " &
Vehicles.Model AS Vehicles,
Expenses.*
• FROM [Vehicles Extended] INNER
JOIN Expenses ON [Vehicles
Extended].ID = Expenses.Vehicle
• ORDER BY Vehicles.Year & " " &
[Vehicles.Make] & " " &
Vehicles.Model DESC ,
Expenses.[Service Date] DESC;
SQL - CREATE
• Create a new empty table
CREATE TABLE raptor_nests (
id int PRIMARY KEY DEFAULT nextval(‘raptor_nests_id’),
nest_id varchar(10) NOT NULL,
species varchar(50),
2016_status varchar(50),
current_status varchar(50),
date_found date,
last_date_inspected date,
project_id integer
)
SELECT AddGeometryColumn(‘public’, ‘raptor_nests’, ‘geom’, 4326, ‘POINT’, 2)
SQL - CREATE
• Create a new empty table
CREATE TABLE projects (
id int PRIMARY KEY DEFAULT nextval(‘project_id’),
project_id varchar(50) NOT NULL,
name varchar(255) NOT NULL,
start_date date NOT NULL,
status varchar(50),
)
SELECT AddGeometryColumn(‘public’, ‘projects’, ‘geom’, 4326, ‘LINESTRING’, 2)
SQL - INSERT
• Add data to an existing table
• INSERT INTO raptor_nests (nest_id, species, current_status, date_found, geom) VALUES
(‘RN_025’, ‘SWHA’, ‘ACTIVE’, ‘2015-11-05’, ST_GeomFromText(‘POINT(-106.435 39.423)’,
4326));
• INSERT INTO projects (project_id, name, start_date, geom) VALUES (‘USD 10-5’,
‘UNITED SANITARY DESIGN #10, Project 5’, ‘2016-04-12’,
ST_SetSRID(ST_GeomFromGeoJSON(‘{“type”:”LineString”, “coordinates”:[[-106.45245,
38.5642], [-106.65876, 38.80678],[-106.1952, 38.65335]]}’), 4326))
SQL - RETRIEVE
• SELECT – Single Table
• SELECT * FROM raptor_nests;
• SELECT nest_id, species, current_status, date_found, last_date_inspected FROM raptor_nests
• SELECT nest_id, species, date_found, last_date_inspected FROM raptor_nests WHERE current_status =
‘active’;
• SELECT nest_id, species, date_found, last_date_inspected FROM raptor_nests WHERE current_status =
‘active’ ORDER BY species, last_date_inspected DESC, nest_id;
• SELECT species, count(species), max(last_date_inspected) FROM raptor_nests GROUP BY species ORDER
BY species
• SELECT species, count(species) AS count, max(last_date_inspected) AS most_recent_inspection FROM
raptor_nests WHERE current_status <> 2016_status GROUP BY species ORDER BY species
• SELECT name, length_feet/5280 as length_miles, start_date FROM projects ORDER BY dist_miles
SQL - RETRIEVE
• SELECT - Multiple Tables
• SELECT p.start_date, p.name, r.nest_id, r.species, r.current_status FROM raptor_nests r JOIN projects p ON
p.id = r.project_id ORDER BY p.start_date, DESC, p.name, r.nest_id
• JOIN TYPES
• INNER
• LEFT
• RIGHT
• FULL
• SELECT – Spatial Queries with POSTGIS
• SELECT p.start_date, p.name, r.nest_id, r.species, r.current_status, ST_Distance(r.geom, p.geom) as
distance FROM raptor_nests r JOIN projects p ON ST_DWithin(r.geom, p.geom, 500)
SQL - UPDATE
• Modify existing data in an existing table
• UPDATE raptor_nests SET last_inspection_date=‘2016-07-18’,
current_status=‘FLEDGED’ WHERE id=13;
• UPDATE raptor_nests SET current_status=‘FLEDGED’ WHERE
upper(current_status)=‘FLEDGED’;
SQL - DELETE
• Delete data from an existing table
• DELETE FROM raptor_nests WHERE id=12;
• DELETE FROM raptor_nests WHERE (current_status=‘REMOVED’) AND ((current_date()-
last_inspection_date) > 730)
SQL - DELETE
• Delete data from an existing table
• DELETE FROM raptor_nests WHERE id=12;
• DELETE FROM raptor_nests WHERE (current_status=‘REMOVED’) AND ((current_date()-
last_inspection_date) > 730)
• Operator precedence
1. ()
2. *, /
3. +, -,
4. =, <, >
5. NOT
6. AND
7. IN, LIKE, OR
6-3*4/2 = ?????
(6-3)*4/2 = ????
(6-(3*4))/2 = ??????
0
6
-3
SO I HAVE A SQL STATEMENT…..
• How do you send it to the database and what do you do with the result…
• An enterprise database is not like a standalone program, they are designed to be
accessible in many ways.
• All you need is connection information
• Host – localhost, www.millermountain.com, 189.207.169.17
• Port – 5432
• Database Name – gis_test
• Username
• Password
SO I HAVE A SQL STATEMENT…..
• You can access it many ways.
• Command line – (psql)
• GUI – pgAdmin III
• Web Interface – phpPgAdmin
• Custom software – QGIS, ArcGIS, Excel, Access
• Custom web page – PHP, Java, ASP.NET, Ruby, Node.js
• Result
• Text
• Table
• Feature Class, Spreadsheet, Table
• Array of data or objects
OVERVIEW
1. User interacts with a web page or map on the client
A. Submit a form, enter a project id, select from a list, click on the map.
2. Web page sends data to the server(GET, POST, AJAX)
3. A php script on the server receives the data, processes it SQL statement, sends to the
database
4. The database returns a result that is processed by a php script and returns a string (AJAX,
ECHO)
A. Loop through and add HTML for a web page table
B. Loop through and return geoJSON to turn into features on a map
5. Web page does something with the result string
A. Inserts table into page.
B. Inserts features onto the map.
PHP - INTRO
• Two flavors of PHP
• Procedural
• Object Oriented
• Two ways to use PHP
• Dynamic web page
• HTML document with embedded PHP code
• AJAX
• Script on server receives data from Javascript and returns text to javascript
<?php
$heading = “Welcome to my web page”;
?>
……..
<h1><?php echo $heading; ?></h1>
<h1> Welcome to my web page </h1>
PHP - STRINGS
• All statements end with a semicolon;
• Variable names begin with $
• Do not need to be declared
• String concatenation
• $space=“ “;
• $myString1= “Micky”.$space.”Mouse”;
• $myString2=“Mickey$space Mouse”;
• $myString3=“Mickey{$space}Mouse”;
“Mickey”+$space+”Mouse”;
PHP - ARRAYS
• Indexed Arrays – indexed numerically
• $animalType = array(“CAT”, “DOG”, “CHICKEN”);
• $animalType = [“CAT”, “DOG”, “CHICKEN”];
• $animalType[] = “BEAR”
• $animalType[6] = “FERRET”
• Associative Arrays – indexed by keys
• $geomDimension = array(“POINT”=>0,
“LINE”=>1);
• $geomDimension = [“POINT”=>0, “LINE”=>1];
• $geomDimension[‘POLYGON’]=2;
• $animalType[0]=“CAT”;
• $animalType[1]=“DOG”;
• $animalType[2]=“CHICKEN;
• $animalType[3]=“BEAR”;
• $animalType[6]=“FERRET”;
• $geomDimension[“POINT”]=0;
• $geomDimension[“LINE”]=1;
• $geomDimension[“POLYGON”]=
2;
PHP – ARRAY FUNCTIONS
• sizeof() or count() – returns number of elements
• array_push(), array_pop(), array_shift(),
array_unshift()
• array_keys(), array_values()
• array_unique()
• sort(), asort(), ksort()
• rsort(), arsort(), krsort()
• json_encode()
• count($geomDimension) = 3
• array_push($animalType, “BIRD”)
COMMUNICATION WITH SERVER - GET
• Sending information TO server
• Parameters encoded in the URL
• Syntax = localhost/webmap101/php_test.php?lat=19.25831&long=-
99.34295&alt=2207
• lat = “19.25831”
• long=“-99.34295”
• alt=“2207”
• Limited to 2048 characters
• Visible to user = Insecure
• Can be bookmarked
COMMUNICATION WITH SERVER - POST
• Sending information TO server
• Parameters encoded in the HTTP request header
• Not visible to user = More secure
• No limit on size
• Cannot be bookmarked
• So how do you send data with POST?
• Form submit button.
• AJAX
COMMUNICATION WITH SERVER
• Reading GET and POST information
• Superglobal variables in PHP
• $_GET
• $_POST
• Associative arrays
COMMUNICATION WITH SERVER - GET
• Sending information TO server
• Parameters encoded in the URL
• Syntax = localhost/webmap101/php_test.php?lat=19.25831&long=-
99.34295&alt=2207
• lat = “19.25831”
• long=“-99.34295”
• alt=“2207”
• Limited to 2048 characters
• Visible to user = Insecure
• Can be bookmarked
COMMUNICATION WITH SERVER
• Reading GET and POST information
• Superglobal variables in PHP
• $_GET
• $_POST
• Associative array
• $_GET[‘lat’]
• $_GET[‘long’]
• $_GET[‘alt’]
PHP – CONDITIONAL STATEMENTS
if (condition) {
code……
} elseif {
code….
} else {
code…..
}
if (isset($_GET[‘lat’])) {
$lat=$_GET[‘lat’];
} else {
$lat= “N/A”;
}
switch ($geomType[i]) {
case “POINT”:
$size = “No Dimension<br>”;
break;
case “LINE”:
$size = “Length = “.lineLength($geom).”<br>”;
break
case “POLYGON”:
$size = “Area= “.area($geom).”<br>”;
break;
default:
echo “N/A”;
}
PHP - LOOPS
for ($i=0;$i<count($animalType);$i++) {
echo $animalType[$i].”<br>”;
}
$i=0;
$while ($i<count($animalType) {
echo $animalType[$i].”<br>”;
$i++;
}
PHP - LOOPS
foreach ($_GET as $key=>$val) {
echo “Key: {$key} Value: {$val}<br>”;
}
$sql = “UPDATE cords SET “;
foreach ($_POST as $key=>$val) {
$sql += “{$key} = ‘{$val}’, “;
}
$sql += “ WHERE id = 13”;
SECURITY NOTE – SQL INJECTION
• One of the most common forms of security threats is a SQL Injection attack.
• SQL statements end with a semi-colon.
• SQL Engine will process anything after a semicolon as a new statement.
• This allows someone with knowledge of SQL to “Insert” a SQL statement into a
text input box.
SOLUTION – USE PDO
• PHP Data Objects
• Use Prepared Statements rather than a single SQL query
• Prepared statements
• Only allow one SQL statement at a time
• Separate data from code by using placeholders
• Properly escape user input values
• “” removes any special meaning of the character following it
• VALUES (‘John’s house’) becomes VALUES (‘John’s house’)
SOLUTION – USE PDO
• Standard
$db = pg_connect("host=localhost port=5432 dbname=gis_test user=joe password=12345");
$result = pg_query($db, “SELECT nest_id, createdate, lastsurvey, recentstatus FROM
raptor_nests”);
echo “<table>”;
while ($row = pg_fetch_array($result)) {
echo “<tr>”;
foreach ($row as $field=>$value) {
echo “<td>{$value}</td>”;
}
echo “</tr>”;
}
echo “</table>”;
SOLUTION – USE PDO
• Prepared Statements
$db = new PDO(“pgsql:host=localhost;port=5432;dbname=millermo_testgis;user=joe;password=12345");
$sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies FROM
wildlife_raptor_nests WHERE lastsurvey> :ls AND recentstatus = :rs”);
$params = [“ls”=>”2016-07-06”, “rs”=>”Active”];
$sql->execute($params);
echo “<table>”;
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
echo “<tr>”;
foreach ($row as $field=>$value) {
echo “<td>{$value}</td>”;
}
echo “</tr>”;
}
echo “</table>”;
PHP - PROBLEMS
• Pages must be reloaded every time to see any changes
• No direct access to the DOM
• Very limited ability to get user input and respond to events
• Requires a server connection so off-line applications are out
of the question.
• Mapping libraries are all based on JavaScript.
AJAX
• Asynchronous JavaScript And XML*
• Microsoft (1999), Google (2004), AJAX coined (2005)
• XMLHttpRequest object standardized by W3C (2006)
• Allows the client to request information from the server asynchronously
• When the request is completed a JavaScript callback function is executed.
• The callback function can process the result and manipulate the DOM.
• JQuery includes a wrapper for the XMLHttpRequest object that makes it easy to
use.
AJAX – HTML AND JAVASCRIPT
(QUERY_NESTS_AJAX.HTML)
<input type="date" id="lastsurvey" value="2015-01-01"><br>
<select id="recentstatus">
<option value='ACTIVE NEST'>Active Nest</option>
<option value='INACTIVE NEST'>Inactive Nest</option>
<option value='FLEDGED NEST'>Fledged Nest</option>
</select><br>
<button id=“filterSubmit" >Submit</button>
<hr><div id=“resultTable></div>
<script>
$(“#filterSubmit”).click(function(){
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(),
recentstatus:$(“#recentstatus).val()}, success: function(response){
}});
});
</script>
AJAX – HTML AND JAVASCRIPT
(QUERY_NESTS_AJAX.HTML)
$.AJAX OPTIONS
• async
• beforeSend(xhr)
• complete(xhr, status)
• data
• error(xhr, status, error)
• success(result, status, xhr)
• type
• URL
• Boolean indicating whether the request is asynchronous.
• Function to run BEFORE the request is sent
• Function to run AFTER the request is complete
• Object containing properties that will become POST variables
• Function to run if an error occurs on the server
• Function to run if no error occurs
• The type of transfer protocol to use GET or POST
• The location of the script to run on the server
AJAX – HTML AND JAVASCRIPT
(QUERY_NESTS_AJAX.HTML)
<input type="date" id="lastsurvey" value="2015-01-01"><br>
<select id="recentstatus">
<option value='ACTIVE NEST'>Active Nest</option>
<option value='INACTIVE NEST'>Inactive Nest</option>
<option value='FLEDGED NEST'>Fledged Nest</option>
</select><br>
<button id=“filterSubmit" >Submit</button>
<hr><div id=“resultTable></div>
<script>
$(“#filterSubmit”).click(function(){
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(),
recentstatus:$(“#recentstatus).val()}, success: function(response){
$(“#resultTable”).html(response);
}});
});
</script>
AJAX – PHP (QUERY_NESTS_AJAX.PHP)
<?php
$ls = $_POST[‘lastsurvey’];
$rs = $_POST[‘recentstatus’];
$db = new PDO(pgsql:host=localhost;port=5432;dbname=gis_test;user=joe;password=12345");
$sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies,
ST_AsGeoJSON(ST_Transform(geom, 4326),5) as geom FROM wildlife_raptor_nests WHERE lastsurvey> :ls AND
recentstatus = :rs"”;
$sql->execute([“ls”=>$ls, “rs”=>$rs]);
echo “<table>”;
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
echo “<tr>”;
foreach ($row as $field=>$value) {
echo “<td>{$value}</td>”;
}
echo “</tr>”;
}
echo “</table>”;
?>
AJAX - RESPONSE
<table…..>
<th>……</th>
<tr>
<td>Rnest_034</td>
<td>2011-04-23</td>
<td>2015-07-14</td>
<td>ACTIVE NEST</td>
<td>Red-Tailed Hawk</td>
</tr>
<tr>
<td>Rnest_045</td>
<td>2012-05-17</td>
<td>2015-07-08</td>
<td>ACTIVE NEST</td>
<td>Red-Tailed Hawk</td>
</tr>
</table>
AJAX – HTML AND JAVASCRIPT
(QUERY_NESTS_AJAX.HTML)
<input type="date" id="lastsurvey" value="2015-01-01"><br>
<select id="recentstatus">
<option value='ACTIVE NEST'>Active Nest</option>
<option value='INACTIVE NEST'>Inactive Nest</option>
<option value='FLEDGED NEST'>Fledged Nest</option>
</select><br>
<button id=“filterSubmit" >Submit</button>
<hr><div id=“resultTable></div>
<script>
$(“#filterSubmit”).click(function(){
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(),
recentstatus:$(“#recentstatus).val()}, success: function(response){
$(“#resultTable”).html(response);
}});
});
</script>
AJAX – HTML AND JAVASCRIPT
(QUERY_NESTS_AJAX.HTML)
<input type="date" id="lastsurvey" value="2015-01-01"><br>
<select id="recentstatus">
<option value='ACTIVE NEST'>Active Nest</option>
<option value='INACTIVE NEST'>Inactive Nest</option>
<option value='FLEDGED NEST'>Fledged Nest</option>
</select><br>
<button id=“filterSubmit" >Submit</button>
<hr><div id=“resultTable></div>
<script>
$(“#filterSubmit”).click(function(){
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(),
recentstatus:$(“#recentstatus).val()}, success: function(response){
$(“#resultTable”).html(response);
}});
});
</script>
AJAX – PHP (QUERY_NESTS_AJAX.PHP)
<?php
$ls = $_POST[‘lastsurvey’];
$rs = $_POST[‘recentstatus’];
$db = new PDO(pgsql:host=localhost;port=5432;dbname=gis_test;user=joe;password=12345");
$sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies,
ST_AsGeoJSON(ST_Transform(geom, 4326),5) as geom FROM wildlife_raptor_nests WHERE lastsurvey> :ls AND
recentstatus = :rs"”;
$sql->execute([“ls”=>$ls, “rs”=>$rs]);
echo “<table>”;
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
echo “<tr>”;
foreach ($row as $field=>$value) {
echo “<td>{$value}</td>”;
}
echo “</tr>”;
}
echo “</table>”;
?>
$features=[];
array_push($features, $row);
echo json_encode($features);
$row[‘geom’]=json_decode($row[‘geom’]);
AJAX - RESPONSE
[
{
"nest_id":"RNest_291 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-10",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Swainsons Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.91081,40.1328]
}
},
{
"nest_id":"RNest_294 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-24",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Red-tail Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.80846,40.15926]
}
}
]
AJAX – HTML AND JAVASCRIPT
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()},
success: function(response){
var objResponse = JSON.parse(response);
var strResponse = “<table>”;
for (var i=0;i<objResponse.length;i++){
strResponse += "<tr>”’
strResponse += “<td>"+objResponse[i].nest_id+"</td>";
strResponse += "<td>"+objResponse[i].createdate+"</td>";
strResponse += "<td>"+objResponse[i].lastsurvey+"</td>";
strResponse += "<td>"+objResponse[i].recentstatus+"</td>";
strResponse += "<td>"+objResponse[i].recentspecies+"</td>";
strResponse += "<td>"+JSON.stringify(objResponse[i].geom)+"</td>;
strResponse += “</tr>";
}
strResponse += “</table>”;
$(“#resultTable”).html(strResponse);
}
AJAX - RESPONSE
[
{
"nest_id":"RNest_291 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-10",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Swainsons Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.91081,40.1328]
}
},
{
"nest_id":"RNest_294 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-24",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Red-tail Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.80846,40.15926]
}
}
]
AJAX - RESPONSE
[
{
"nest_id":"RNest_291 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-10",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Swainsons Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.91081,40.1328]
}
},
{
"nest_id":"RNest_294 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-24",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Red-tail Hawk ",
"geom":{
"type":"Point",
"coordinates":[-
104.80846,40.15926]
}
}
]
GEOJSON – FEATURES AND FEATURECOLLECTIONS
{“type”:”Feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-108.5, 33.7]
},
“properties”: {“species”:”Bald Eagle”,
“sex”:”male”,
“age”:7
}
}
{“type”:”FeatureCollection”,
“features”: [{“type”:”feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-108.5, 33.7]
},
“properties”: {“species”:”Bald Eagle”,
“sex”:”male”,
“age”:7
}
}, {“type”:”feature”,
“geometry”: {“type”: “Point”,
“coordinates”:[-109.1, 32.5]
},
“properties”: {“species”:”Golden Eagle”,
“sex”:”female”,
“age”:2
}
}]
}
AJAX – PHP (QUERY_NESTS_AJAX.PHP)
<?php
$features=[];
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$feature=[‘type’=>’Feature’];
$feature[‘geometry’]=$json_decode($row[‘geom’]);
unset($row[‘geom’]);
$feature[‘properties’]=$row;
array_push($features, $feature)
}
$featureCollection=[‘type’=>’FeatureCollection’, ‘Features’=>$features];
echo json_encode($featureCollection);
?>
GEOJSON
{
"type":“FeatureCollection",
"features":[{
"type":“Feature",
"geometry":{
"type":"Point",
"coordinates":[-104.91081,40.1328]
},
"properties":{
"nest_id":"RNest_291 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-10",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Swainsons Hawk “
}
},
{
"type":“Feature",
"geometry":{
"type":"Point",
"coordinates":[-
104.80846,40.15926]
},
"properties":{
“nest_id":"RNest_294 ",
"createdate":"2011-04-06",
"lastsurvey":"2015-08-24",
"recentstatus":"FLEDGED NEST ",
"recentspecies":"Red-tail Hawk “
}
}]
}
AJAX – HTML (QUERY_NESTS_AJAX.HTML)
<input type="date" id="lastsurvey" value="2015-01-01"><br>
<select id="recentstatus">
<option value='ACTIVE NEST'>Active Nest</option>
<option value='INACTIVE NEST'>Inactive Nest</option>
<option value='FLEDGED NEST'>Fledged Nest</option>
</select><br>
<button id=“filterSubmit" >Submit</button>
<hr><div id=“mapdiv” style=“width:800px;height:600px”></div>
AJAX – JAVASCRIPT (QUERY_NESTS_AJAX.HTML)
<script>
var mymap = L.map('mapdiv')
mymap.setView([19.4, -99.1], 11);
var backgroundLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');
mymap.addLayer(backgroundLayer);
$(“#filterSubmit”).click(function(){
$.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(),
recentstatus:$(“#recentstatus).val()}, success: function(response){
var queryLayer=L.geoJSON(JSON.parse(response)).addTo(mymap);
mymap.fitBounds(queryLayer.getBounds());
}});
});
</script>
POSTGIS
• Adding geospatial functionality to the PostgreSQL database
• Standards based – Simple Features for SQL from Open Geospatial Consortium
• Spatial functions – calculating distances, areas, conversion
• Relationship operators –crosses, contains, within, etc
• Spatial operators - intersection, union, difference, buffer, etc
• Conversion – GeoJSON, GML, KML
• Geography types – storing geometry based on spheroid
• Raster operations
• Spatial indexing – R-tree over GIST
SIMPLE FEATURES FOR SQL - GEOMETRY
SIMPLE FEATURES FOR SQL –SPATIAL REFERENCE
• Spatial Reference includes
• Coordinate system
• Geographic
• Projected.
• Zone
• Datum
• Single Integer, the SRID
• Examples
• Lat/Long WGS84 – 4326
• UTM Zone 13N NAD83 – 26913
• www.spatialreference.org
SFS - FUNCTIONS
• Conversion
• ST_AsText
• ST_PointFromText
• ST_LineFromText
• ST_PolygonFromText
• Description
• ST_SRID
• ST_IsEmpty
• ST_IsSimple
• ST_IsClosed
• ST_IsRing
• ST_IsValid
• ST_GeometryType
• Calculations
• ST_Distance
• ST_Length
• ST_Area
• Accessing
• ST_X
• ST_Y
• ST_StartPoint
• ST_EndPoint
• ST_PointN
• ST_ExteriorRing
• ST_InteriorRingN
• ST_GeometryN
SFS – SPATIAL ANALYSIS
• Relational Operators
• ST_Equals
• ST_Disjoint
• ST_Touches
• ST_Within
• ST_Contains
• ST_Intersects
• ST_Crosses
• ST_Overlaps
• ST_DWithin
• Spatial Operators
• ST_Intersection
• ST_Difference
• ST_Union
• ST_SymDifference
• ST_Buffer
• ST_ConvexHull
• ST_Transform
POSTGIS – BEYOND SFS
• Conversion
• GeoGSON – ST_AsGeoJSON, ST_GeomFromGeoJSON
• KML, GML, EWKT
• Geography Types
• Based on a spheroid.
• Only lat/long WGS84 coordinates
WHY GEOGRAPHY?
POSTGIS – BEYOND SFS
• Conversion
• GeoGSON – ST_AsgeoJSON, ST_GeomFromGeoJSON
• KML, GML
• Geography Types
• Based on a spheroid.
• Only lat/long WGS84 coordinates
• Limited functionality
• More accurate over large spatial areas.
• Raster
• Store rasters in the database
• Map algebra
• Reclass
• Resample
• Slope, aspect, hillshade
POSTGIS – SPATIAL INDEXING
• CREATE INDEX pipeline_geom_idx ON pipelines USING GIST (geom);
• Based on Bounding Boxes
• VACCUM ANALYZE pipelines;
• EXPLAIN ANALYZE sql;
POSTGIS – LOADING (AND EXPORTING) DATA
• Command Line
• shp2pgsql/pgsql2shp
• ogr2ogr
• raster2pgsql
• GDAL utilities
• GUI
• pgShapeLoader
• QGIS
• DB Manager
• Load Raster To PostGIS plug-in
• FME - Commercial
POSTGIS – EXAMPLES (SINGLE TABLE)
• Include the latitude and longitude of the point in the table
• SELECT nest_id, recentstatus, ST_Y(geom) as latitude, ST_X(geom) as longitude
• Given a lat and long, return all nests within 2 miles
• SELECT nest_id, recentstatus FROM raptor_nests WHERE ST_DWithin(ST_FromText(‘POINT(-
99.2314, 19.3451)’,4326), geom, 3218);
• Given a lat and long return the 5 closest nests buffered by one mile
• SELECT nest_id, recentstatus, ST_Distance(ST_FromText(‘POINT(-99.2314, 19.3451)’,4326),
geom) as distance, ST_Buffer(geom, 1609) as buffer FROM raptor_nests ORDER BY distance
LIMIT 5;
• Given a pipeline table sum up the length of pipelines by category.
• SELECT pipline_category, sum(ST_Length(geom)) as total FROM pipelines GROUP BY
pipeline_category ORDER BY total DESC
• SELECT pipline_category, sum(ST_Area(ST_Buffer(geom, 50))) as total……….
POSTGIS – EXAMPLES (MULTIPLE TABLES)
• Given a pipeline table and a raptor_nest table display pipelines with an active raptor nest within
1 mile.
• SELECT p.project_name, r.nest_id FROM pipeline p JOIN raptor_nests r ON ST_DWithin(p.geom, r.geom,
1609) WHERE r.recentstatus=‘ACTIVE’;
• Given an animal home range table and a vegetation table display the vegetation types found in
each animals home range
• SELECT h.animal_id, v.class FROM home_ranges h JOIN vegetation v ON ST_Intersects(h.geom, v.geom)
• Given an animal home range table and a vegetation table display the acres and percent of each
animals home range for every vegetation type.
• SELECT h.animal_id, v.class, ST_Area(ST_Intersection(h.geom, v.geom))/4045 as acres,
ST_Area(ST_Intersection(h.geom, v.geom))/ST_Area(g.geom) as percent FROM home_ranges h JOIN
vegetation v ON ST_Intersects(h.geom, v.geom)
• SELECT h.animal_id, v.class, sum(ST_Area(ST_Intersection(h.geom, v.geom))/4045) as acres,
sum(ST_Area(ST_Intersection(h.geom, v.geom))/ST_Area(h.geom)) as percent FROM home_ranges h JOIN
vegetation v ON ST_Intersects(h.geom, v.geom) GROUP BY h.animal, v.class
SERVER SIDE EXAMPLE
• Modify the Mexico City attraction application we started at the end of the client
side section to
• Store the attractions data in a PostGIS table
• Add the ability for end users to
• Add attractions
• Modify attractions
• Delete attractions
• Filter attractions by category
• Find the attractions closest to a point clicked on the map.
SERVER SIDE EXAMPLE - SETUP
1. Create a new database specific for this application
2. Add the data currently in the GeoJSON data file to the new PostGIS database
3. Add a category field to the attractions table
4. Populate category field for existing data
5. Modify the map to load the attractions via an AJAX call to the database rather
than from a file.
AJAX – PHP (LOAD_ATTRACTIONS.PHP)
<?php
$db = new PDO("pgsql:host=localhost;port=5432;dbname=webmap101;user=joe;password=12345");
$sql = $db->query("SELECT id, name, image, web, category, ST_AsGeoJSON(geom,5) as geom FROM
cdmx_attractions";
$features=[];
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$feature=[‘type’=>’Feature’];
$feature[‘geometry’]=$json_decode($row[‘geom’]);
unset($row[‘geom’]);
$feature[‘properties’]=$row;
array_push($features, $feature)
}
$featureCollection=[‘type’=>’FeatureCollection’, ‘Features’=>$features];
echo json_encode($featureCollection);
?>
AJAX – HTML AND JAVASCRIPT
var lyrAttractions;
$.ajax({url:'load_attractions.php', success: function(response){
if (lyrAttractions) {mymap.removeLayer(lyrAttractions)};
lyrAttractions=L.geoJSON(JSON.parse(response), {pointToLayer:function(feature,latlng){
……..
var strPopup = "<h4>"+feature.properties.name+"</h4><hr>";
strPopup += "<h5>Category: "+feature.properties.category+"</h5>";
strPopup += "<a href='"+feature.properties.web+"' target='blank'>";
strPopup += "<img src='img/"+feature.properties.image+"' width='200px'>";
strPopup += "</a>";
return L.marker(latlng).bindPopup(strPopup);
}}).addTo(mymap);
mymap.fitBounds(lyrAttractions.getBounds());
});
SERVER SIDE EXAMPLE – ADD NEW ATTRACTION
• HTML
• Modal dialog
• Data entry form
• Save and Cancel buttons.
• CSS
• Styling, positioning, and making visible the data entry form.
• Bootstrap classes for the buttons and form controls.
• JavaScript
• Event handlers to respond to map click
• Event handler to respond button clicks
• Save button will send an AJAX request to the server and process the result.
• Cancel Button will simply close the dialog.
SERVER SIDE EXAMPLE – ADD NEW ATTRACTION
• PHP
• Receive the ajax requests
• Process into SQL query
• Submit to database
• Process results
SERVER SIDE EXAMPLE – HTML
<div id="dlgAttraction" class="modal">
<div class="modal-content col-md-7 col-md-offset-4">
FORM INPUT CONTROLS………
<button id="btnSave" class="btn btn-success">Save</button>
<button id="btnCancel" class="btn btn-danger">Cancel</button>
</div>
</div>
SERVER SIDE EXAMPLE – CSS
.modal {
display: none;
z-index: 1000;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
}
.modal-content {
padding: 20px;
background-color:tan;
margin-top: 10%;
}
SERVER SIDE EXAMPLE – JAVASCRIPT
mymap.on('click', function(e){
$("#dlgAttraction").show();
$("#latitude").val(e.latlng.lat.toFixed(5));
$("#longitude").val(e.latlng.lng.toFixed(5));
$("#idDisplay").html("New");
});
$("#btnCancel").click(function(){
$("#dlgAttraction").hide();
});
$("#btnSave").click(function(){
$.ajax({url:'add_attraction.php',
type:'POST',
data:{name:$("#name").val(),
image:$("#image").val(),
web:$("#website").val(),
category:$("#category").val(),
latitude:$("#latitude").val(),
longitude:$("#longitude").val() },
success:function(response){
alert(response);
}}); });
SERVER SIDE EXAMPLE – PHP
if (isset($_POST['name'])) {
$name=$_POST['name'];
} else {
$name="NA";
}
………………..
$db = new PDO('pgsql:host=localhost;port=5432;dbname=webmap101;', 'joe', '12345');
$sql = $db->prepare("INSERT INTO cdmx_attractions (name, image, web, category, geom) VALUES (:nm, :im, :wb,
:ct, ST_SetSRID(ST_MakePoint(:lng, :lat), 4326))");
$params = ["nm"=>$name, "im"=>$image, "wb"=>$web, "ct"=>$category, "lng"=>$longitude,
"lat"=>$latitude];
if ($sql->execute($params)) {
echo "{$name} succesfully added";
} else {
echo var_dump($sql->errorInfo());
};
SERVER SIDE EXAMPLE
• Modify the Mexico City attraction application we started at the end of the client
side section to
• Store the attractions data in a PostGIS table
• Add the ability for end users to
• Add attractions
• Modify attractions
• Delete attractions
SERVER SIDE EXAMPLE – EDIT/DELETE ATTRACTION
• HTML
• CSS
• JavaScript
• Add button in popup to open edit dialog and populate form.
• Handle save edits and delete buttons in dialog.
SERVER SIDE EXAMPLE – EDIT/DELETE ATTRACTION
• PHP
• Receive the ajax requests
• Process into SQL query
• Submit to database
• Process results
• update_attraction.php
• delete_attraction.php
• find_attraction.php
SERVER SIDE EXAMPLE – HTML
<div id="dlgAttraction" class="modal">
<div class="modal-content col-md-7 col-md-offset-4">
FORM INPUT CONTROLS………
<button id="btnSave" class="btn btn-success">Save</button>
<button id="btnCancel" class="btn btn-danger">Cancel</button>
</div>
</div>
SERVER SIDE EXAMPLE – CSS
.modal {
display: none;
z-index: 1000;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
}
.modal-content {
padding: 20px;
background-color:tan;
margin-top: 10%;
}
SERVER SIDE EXAMPLE – JAVASCRIPT
mymap.on('click', function(e){
$("#dlgAttraction").show();
$("#latitude").val(e.latlng.lat.toFixed(5));
$("#longitude").val(e.latlng.lng.toFixed(5));
$("#idDisplay").html("New");
});
$("#btnCancel").click(function(){
$("#dlgAttraction").hide();
});
$("#btnSave").click(function(){
$.ajax({url:'add_attraction.php',
type:'POST',
data:{name:$("#name").val(),
image:$("#image").val(),
web:$("#website").val(),
category:$("#category").val(),
latitude:$("#latitude").val(),
longitude:$("#longitude").val() },
success:function(response){
alert(response);
}}); });
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx
6.1 GeospatialWeb101.pptx.pptx

Mais conteúdo relacionado

Semelhante a 6.1 GeospatialWeb101.pptx.pptx

Rich Internet Applications and Flex - 1
Rich Internet Applications and Flex - 1Rich Internet Applications and Flex - 1
Rich Internet Applications and Flex - 1Vijay Kalangi
 
Let’s learn how to use JavaScript responsibly and stay up-to-date.
Let’s learn how to use JavaScript responsibly and stay up-to-date. Let’s learn how to use JavaScript responsibly and stay up-to-date.
Let’s learn how to use JavaScript responsibly and stay up-to-date. Christian Heilmann
 
Web Development Technologies
Web Development TechnologiesWeb Development Technologies
Web Development TechnologiesVignesh Prajapati
 
Joomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiencesJoomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiencesAndy_Gaskell
 
The Characteristics of a Successful SPA
The Characteristics of a Successful SPAThe Characteristics of a Successful SPA
The Characteristics of a Successful SPAGil Fink
 
Week01 jan19 introductionto_php
Week01 jan19 introductionto_phpWeek01 jan19 introductionto_php
Week01 jan19 introductionto_phpJeanho Chu
 
Web APIs: The future of software
Web APIs: The future of softwareWeb APIs: The future of software
Web APIs: The future of softwareReuven Lerner
 
Building a REST API for Longevity
Building a REST API for LongevityBuilding a REST API for Longevity
Building a REST API for LongevityMuleSoft
 
Web tech weblamp_infosession_2012-13
Web tech weblamp_infosession_2012-13Web tech weblamp_infosession_2012-13
Web tech weblamp_infosession_2012-13Konrad Roeder
 
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxLATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxchitrachauhan21
 
eMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseeMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseScott Taylor
 
Joshua Harris resume
Joshua Harris resumeJoshua Harris resume
Joshua Harris resumeJosh Harris
 
Quo vadis, JavaScript? Devday.pl keynote
Quo vadis, JavaScript? Devday.pl keynoteQuo vadis, JavaScript? Devday.pl keynote
Quo vadis, JavaScript? Devday.pl keynoteChristian Heilmann
 
A guide to hiring a great developer to build your first app (redacted version)
A guide to hiring a great developer to build your first app (redacted version)A guide to hiring a great developer to build your first app (redacted version)
A guide to hiring a great developer to build your first app (redacted version)Oursky
 
Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011Nuxeo
 
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...How To Learn Programming For Beginners | How To Start Coding | Learn Programm...
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...Simplilearn
 
project web development
project web developmentproject web development
project web developmentlucky sharma
 
Introduction to web sites design
Introduction to  web sites designIntroduction to  web sites design
Introduction to web sites designMarwa Abdelgawad
 

Semelhante a 6.1 GeospatialWeb101.pptx.pptx (20)

Rich Internet Applications and Flex - 1
Rich Internet Applications and Flex - 1Rich Internet Applications and Flex - 1
Rich Internet Applications and Flex - 1
 
Let’s learn how to use JavaScript responsibly and stay up-to-date.
Let’s learn how to use JavaScript responsibly and stay up-to-date. Let’s learn how to use JavaScript responsibly and stay up-to-date.
Let’s learn how to use JavaScript responsibly and stay up-to-date.
 
Web Development Technologies
Web Development TechnologiesWeb Development Technologies
Web Development Technologies
 
Joomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiencesJoomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiences
 
The Characteristics of a Successful SPA
The Characteristics of a Successful SPAThe Characteristics of a Successful SPA
The Characteristics of a Successful SPA
 
Week01 jan19 introductionto_php
Week01 jan19 introductionto_phpWeek01 jan19 introductionto_php
Week01 jan19 introductionto_php
 
Web APIs: The future of software
Web APIs: The future of softwareWeb APIs: The future of software
Web APIs: The future of software
 
Building a REST API for Longevity
Building a REST API for LongevityBuilding a REST API for Longevity
Building a REST API for Longevity
 
Web tech weblamp_infosession_2012-13
Web tech weblamp_infosession_2012-13Web tech weblamp_infosession_2012-13
Web tech weblamp_infosession_2012-13
 
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxLATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
 
eMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseeMusic: WordPress in the Enterprise
eMusic: WordPress in the Enterprise
 
Joshua Harris resume
Joshua Harris resumeJoshua Harris resume
Joshua Harris resume
 
Quo vadis, JavaScript? Devday.pl keynote
Quo vadis, JavaScript? Devday.pl keynoteQuo vadis, JavaScript? Devday.pl keynote
Quo vadis, JavaScript? Devday.pl keynote
 
A guide to hiring a great developer to build your first app (redacted version)
A guide to hiring a great developer to build your first app (redacted version)A guide to hiring a great developer to build your first app (redacted version)
A guide to hiring a great developer to build your first app (redacted version)
 
Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011
 
Web dev#1
Web dev#1Web dev#1
Web dev#1
 
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...How To Learn Programming For Beginners | How To Start Coding | Learn Programm...
How To Learn Programming For Beginners | How To Start Coding | Learn Programm...
 
project web development
project web developmentproject web development
project web development
 
Jumpstart Your Web App
Jumpstart Your Web AppJumpstart Your Web App
Jumpstart Your Web App
 
Introduction to web sites design
Introduction to  web sites designIntroduction to  web sites design
Introduction to web sites design
 

Último

VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130
VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130
VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130Suhani Kapoor
 
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779Delhi Call girls
 
{Pooja: 9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...
{Pooja:  9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...{Pooja:  9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...
{Pooja: 9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...Pooja Nehwal
 
Week-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interactionWeek-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interactionfulawalesam
 
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Serviceranjana rawat
 
Schema on read is obsolete. Welcome metaprogramming..pdf
Schema on read is obsolete. Welcome metaprogramming..pdfSchema on read is obsolete. Welcome metaprogramming..pdf
Schema on read is obsolete. Welcome metaprogramming..pdfLars Albertsson
 
Invezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signalsInvezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signalsInvezz1
 
BabyOno dropshipping via API with DroFx.pptx
BabyOno dropshipping via API with DroFx.pptxBabyOno dropshipping via API with DroFx.pptx
BabyOno dropshipping via API with DroFx.pptxolyaivanovalion
 
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Callshivangimorya083
 
Call me @ 9892124323 Cheap Rate Call Girls in Vashi with Real Photo 100% Secure
Call me @ 9892124323  Cheap Rate Call Girls in Vashi with Real Photo 100% SecureCall me @ 9892124323  Cheap Rate Call Girls in Vashi with Real Photo 100% Secure
Call me @ 9892124323 Cheap Rate Call Girls in Vashi with Real Photo 100% SecurePooja Nehwal
 
Edukaciniai dropshipping via API with DroFx
Edukaciniai dropshipping via API with DroFxEdukaciniai dropshipping via API with DroFx
Edukaciniai dropshipping via API with DroFxolyaivanovalion
 
Generative AI on Enterprise Cloud with NiFi and Milvus
Generative AI on Enterprise Cloud with NiFi and MilvusGenerative AI on Enterprise Cloud with NiFi and Milvus
Generative AI on Enterprise Cloud with NiFi and MilvusTimothy Spann
 
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Callshivangimorya083
 
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girl
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girlCall Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girl
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girlkumarajju5765
 
Mature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptxMature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptxolyaivanovalion
 
CebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptxCebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptxolyaivanovalion
 
Zuja dropshipping via API with DroFx.pptx
Zuja dropshipping via API with DroFx.pptxZuja dropshipping via API with DroFx.pptx
Zuja dropshipping via API with DroFx.pptxolyaivanovalion
 
FESE Capital Markets Fact Sheet 2024 Q1.pdf
FESE Capital Markets Fact Sheet 2024 Q1.pdfFESE Capital Markets Fact Sheet 2024 Q1.pdf
FESE Capital Markets Fact Sheet 2024 Q1.pdfMarinCaroMartnezBerg
 

Último (20)

VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130
VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130
VIP Call Girls Service Miyapur Hyderabad Call +91-8250192130
 
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
Best VIP Call Girls Noida Sector 22 Call Me: 8448380779
 
{Pooja: 9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...
{Pooja:  9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...{Pooja:  9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...
{Pooja: 9892124323 } Call Girl in Mumbai | Jas Kaur Rate 4500 Free Hotel Del...
 
Week-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interactionWeek-01-2.ppt BBB human Computer interaction
Week-01-2.ppt BBB human Computer interaction
 
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service
(PARI) Call Girls Wanowrie ( 7001035870 ) HI-Fi Pune Escorts Service
 
Schema on read is obsolete. Welcome metaprogramming..pdf
Schema on read is obsolete. Welcome metaprogramming..pdfSchema on read is obsolete. Welcome metaprogramming..pdf
Schema on read is obsolete. Welcome metaprogramming..pdf
 
Invezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signalsInvezz.com - Grow your wealth with trading signals
Invezz.com - Grow your wealth with trading signals
 
BabyOno dropshipping via API with DroFx.pptx
BabyOno dropshipping via API with DroFx.pptxBabyOno dropshipping via API with DroFx.pptx
BabyOno dropshipping via API with DroFx.pptx
 
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Punjabi Bagh 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
 
Call me @ 9892124323 Cheap Rate Call Girls in Vashi with Real Photo 100% Secure
Call me @ 9892124323  Cheap Rate Call Girls in Vashi with Real Photo 100% SecureCall me @ 9892124323  Cheap Rate Call Girls in Vashi with Real Photo 100% Secure
Call me @ 9892124323 Cheap Rate Call Girls in Vashi with Real Photo 100% Secure
 
Sampling (random) method and Non random.ppt
Sampling (random) method and Non random.pptSampling (random) method and Non random.ppt
Sampling (random) method and Non random.ppt
 
Edukaciniai dropshipping via API with DroFx
Edukaciniai dropshipping via API with DroFxEdukaciniai dropshipping via API with DroFx
Edukaciniai dropshipping via API with DroFx
 
꧁❤ Aerocity Call Girls Service Aerocity Delhi ❤꧂ 9999965857 ☎️ Hard And Sexy ...
꧁❤ Aerocity Call Girls Service Aerocity Delhi ❤꧂ 9999965857 ☎️ Hard And Sexy ...꧁❤ Aerocity Call Girls Service Aerocity Delhi ❤꧂ 9999965857 ☎️ Hard And Sexy ...
꧁❤ Aerocity Call Girls Service Aerocity Delhi ❤꧂ 9999965857 ☎️ Hard And Sexy ...
 
Generative AI on Enterprise Cloud with NiFi and Milvus
Generative AI on Enterprise Cloud with NiFi and MilvusGenerative AI on Enterprise Cloud with NiFi and Milvus
Generative AI on Enterprise Cloud with NiFi and Milvus
 
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls CP 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
 
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girl
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girlCall Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girl
Call Girls 🫤 Dwarka ➡️ 9711199171 ➡️ Delhi 🫦 Two shot with one girl
 
Mature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptxMature dropshipping via API with DroFx.pptx
Mature dropshipping via API with DroFx.pptx
 
CebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptxCebaBaby dropshipping via API with DroFX.pptx
CebaBaby dropshipping via API with DroFX.pptx
 
Zuja dropshipping via API with DroFx.pptx
Zuja dropshipping via API with DroFx.pptxZuja dropshipping via API with DroFx.pptx
Zuja dropshipping via API with DroFx.pptx
 
FESE Capital Markets Fact Sheet 2024 Q1.pdf
FESE Capital Markets Fact Sheet 2024 Q1.pdfFESE Capital Markets Fact Sheet 2024 Q1.pdf
FESE Capital Markets Fact Sheet 2024 Q1.pdf
 

6.1 GeospatialWeb101.pptx.pptx

  • 1. INTRODUCTION TO WEB PROGRAMMING FOR GIS APPLICATIONS
  • 2. WHO THIS COURSE IS FOR • Anyone who is interested in a more conceptual understanding of how web applications work. • HTML, CSS, Bootstrap, JavaScript, JQuery, PHP, SQL and how they all work together. • Web development is very different than programming an application for a single computer, so even if you are an experienced programmer there can be a steep learning curve when moving to the web. • In particular, we will be talking about geospatial applications. • Leaflet, OpenLayers, PostGIS, geoJSON, geospatial data storage, retrieval, analysis, and display. • There are some aspects of geospatial web applications that differ from standard database applications, which we will identify and explore.
  • 3. WHO THIS COURSE IS FOR • Two main groups of people • GIS specialists, analysts, and/or developers interested in deploying internet based applications. • Publish content onto the web for external consumption. • Escape the costs of commercial licenses for internal users of GIS. • Develop spatial tools that are free from dependencies on ESRI update cycles. • Web programmers interested in expanding their skillset into geospatial applications. • Geospatial data • Web maps • Spatial Analysis • Server-side tools
  • 4. MY BACKGROUND • I’ve been programming computers since the early 80s. There was very little canned software at the time so you almost had to program to get much use out of a computer. • I remember cassette tape drives, 8” floppies, and the first PC with a 10MB hard drive and wondering how you would ever fill that much space. • I remember monochrome monitors with only a single font and dot matrix printers with only a single font, and word processing software that you had to use in-text tags to make bold print or indent a paragraph so you wouldn’t really know what the document looked like until you printed it. • I remember when Apple McIntosh came out and blew everybody away with a mouse and What- You-See-Is-What-You-Get graphical display so you could actually see on the screen what your documents would look like and you could control the computer without typing commands.
  • 5. MY BACKGROUND • I sold my first software, a flash card program, in 1984 as a senior in high school to PC Disk magazine. • I developed database applications for video store rentals for several years between high school and college. • In 1990 I changed course and started a degree in Wildlife Biology. Soon after I learned about GIS and realized I had found my calling. • I began programming in ArcInfo with AML, then ArcView with Avenue. In 2000, as I was starting a PhD program, ESRI introduced ArcGIS 8.0 and I quickly realized I would need to learn to program in Visual Basic and ArcObjects as well. • When ESRI introduced ArcGIS 9.0 I had to learn Python to speed up the development process and create more portable extensions.
  • 6. MY BACKGROUND • When maps first started being served over the internet I immediately saw the advantages but I did not have the resources to set up an ArcServer instance on a server and learn to program against it. • I took some classes on ESRI’s JavaScript API but struggled to use it for anything productive for two main reasons. • They skipped over the basics of web application programming. • Without a server installation I had no way to practice what I learned.
  • 7. MY BACKGROUND • In 2014 I saw some talks at a GIS conference on open-source GIS programming and the light went on. • With an open source approach I could develop web applications on my own for free without spending tens of thousands of dollars on ESRI software. • The only cost would be my time and even though I had three decades of experience programming database applications and two decades of experience developing GIS applications in a large number of languages and environments, the web development world sounded like a foreign language. • What did all the jargon mean? How did all the pieces work together? Which pieces did I really need to focus on? • I began trying to learn it all, and spent extensive amounts of time reading books and taking on-line classes and setting up software and developing applications both at work and for fun. • This course is my attempt to share what I learned with others in my position, and help them ease through the process. If you are a programmer or GIS analyst who is struggling with making the transition to the on-line world then I hope this course can help you.
  • 8. COURSE PHILOSOPHY • Although this is a course on web application development you will not learn much code. • You will see some code in examples of course, but there are many courses available to teach you the actual nuts and bolts of writing code. • I believe that it is more important to understand things conceptually before diving into the details. Web programming, in particular, has a lot of bits and pieces that aren’t intuitively obvious, even to experienced desktop developers. This course is intended to fill in those gaps.
  • 9. COURSE GOALS - UNDERSTANDING • Understand the basics of client-server architecture and how it differs from single- user applications • Understand the basics of client side technologies (HTML, CSS, JavaScript) • Understand the basics of server-side technologies (PHP, SQL, Databases) • Understand how to communicate between client and server (AJAX) • Understand commonly available libraries and frameworks (JQuery, Boostrap) • Understand the tools available for geospatial applications (Leaflet, Turf, PostGIS, GeoJSON)
  • 10. HOW IS PROGRAMMING FOR THE WEB DIFFERENT THAN A SINGLE USER DESKTOP ENVIRONMENT? • Client-Server Architecture • Hundreds or thousands of clients accessing one server. • Clients can be using different browsers, different operating systems, different screen sizes, etc. • Data is stored on the server and requested by the client. • User interaction occurs on the client, data access is handled by the server, and data processing can occur on either end. • As a result you need to know how to program on the client side as well as the server side. • More importantly you need to know WHEN to handle things on the client and when to handle things on the server and how to communicate between client and server.
  • 11. CLIENT-SERVER ARCHITECTURE • Servers process requests and return a result, then Clients do something with the results • Just like a server in a restaurant • You (the client) tell the server what you want (Request) • The server delivers it to you (Result), and then you do something with it. • This requires things to happen on both ends • In order to process your request, the server informs the cook of your order and the cook prepares the food from scratch and then the server delivers it to the client. • This happens behind the scene. The details are unknown and unimportant to the client. This is server- side processing. • Once the food is delivered, the client has to cut the steak, put salad dressing on the salad, and spoon it into his mouth. This is client-side processing. • The server and the cook handle multiple clients simultaneously.
  • 12. CLIENT-SERVER ARCHITECTURE Client (HTML, CSS, JavaScript) Database (PostgreSQL, SQLServer, Oracle, MySQL) Web Server (PHP, ASP,.Net Java, Node) Request (AJAX) Result (AJAX) Request (SQL) Data
  • 13. MAJOR COMPONENTS • Client • HTML, CSS, JavaScript (Work together) • Server • PHP, Java, ASP.NET, Ruby, Python, Node (Choose one) • Database • SQL (MySQL, PostgreSQL, SQLite, SQLServer, Oracle, DB2) • No SQL (Mongo, Couch, IndexDB)
  • 14. MINOR COMPONENTS • Communication • GET, POST, ECHO, AJAX, JSON • Libraries, API’s, and Frameworks • Client - JQuery, Dojo, Bootstrap, • Server – Cake, CodeIgnitor, Laravel • Mapping Components • Google Maps, Leaflet, OpenLayers, ESRI Javascript API, Turf.js, PostGIS
  • 15. CLIENT SIDE • In terms of the Web, client means browser. • Netscape, Chrome, Firefox, Safari, Internet Explorer, Edge, Opera, “Webkit” • All browsers understand HTML, CSS, JavaScript • Minor differences in how they are implemented and supported, especially IE. • HTML – HyperText Markup Language • CSS – Cascading Style Sheets • JavaScript – Programming Language
  • 16. CLIENT SIDE • In terms of the Web, client means browser. • All browsers understand HTML, CSS, Javascript • HTML – HyperText Markup Language • Provides structure and content • Original web technology • CSS – Cascading Style Sheets • JavaScript – Programming Language
  • 17. CLIENT SIDE • In terms of the Web, client means browser. • All browsers understand HTML, CSS, Javascript • HTML – HyperText Markup Language • CSS – Cascading Style Sheets • Makes things pretty • Colors, borders, positioning, etc. • JavaScript – Programming Language
  • 18. CLIENT SIDE • In terms of the Web, client means browser. • All browsers understand HTML, CSS, Javascript • HTML – HyperText Markup Language • CSS – Cascading Style Sheets • JavaScript – Programming Language • Makes things happen. • Respond to user input, calculations, animations. • NOT Java
  • 19. HTML DOCUMENT STRUCTURE <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> …………. </body> </html>
  • 20. HTML • Tag based • Headings • Paragraph • Lists • Opening and closing tags • <h1>GIS</h1> • <p>Lorem ipsum</p> • <ul> ( <ol> ) <li> item 1</li> <li> item 2 </li> • </ul> ( </ol> )
  • 21. HTML • Links • Images • Div • Span • Breaks • Style • <a href=“http://www.google.com”>Go to Google</a> • <img src=“images/picture.jpg” width=“200px”> • <div class=“text-bold” id=“div1”>……</div> • <p>Lorem Ipsum<span class=“super- script”>2</span> Lorem Ipsum </p> • <br><hr> • <b>Bold</b><i>Italics</i><small>Small text</small>
  • 23. HTML FORMS <form action=“process.php” method=“post”> <input type=“text” name=“firstName” value=“Bob” ><br><br> <input type=“date” name=“birthday”><br><br> <select name=“registered”> <option value=“true”>Yes</option> <option value=“false”>No</option> </select><br><br> <input type=“checkbox” name=“active” value=“active” checked> Active?<br><br> <hr> <input type=“radio” name=“gender” value=“male” checked> Male<br><br> <input type=“radio” name=“gender” value=“female” > Female<br><br> <hr> <input type=“submit name=“submit” value=“Submit Button”> </form>
  • 24. CSS • Cascading Style Sheets • Introduced in the mid 90’s • Standardized in the mid 00’s • Separation of content from presentation • CSS is composed of RULES that act on SELECTORS p { font-size: 20pt; color:red; background-color:black; } .text-bold { font-weight:bold; } #first-row { padding-left:30px; }
  • 25. CSS – SELECTORS & RULES • Tags • Classes - . • ID - # • Pseudo Classes • :visited • :hover p { font-size: 20pt; color:red; background-color:black; } .text-bold { font-weight:bold; } #first-row { padding-left:30px; } a { color:yellow; } a:visited { color:orange; } a:hover { background-color:black; }
  • 26. CSS – WHERE IT LIVES • Inline • Internal • External • <h1 style=“color:#000;background-color:#FFF”>Title</h1> • <style> • h2 { • color:#FFF • background-color:#000; • } • </style • <link rel=“stylesheet” type=“txt/css” href=“master_style.css”>
  • 27. CSS - PRECEDENCE • Specificity takes precedence over generality. • id>class>tag • inline>internal>external <div class=“default-text”> <p> These are a few of my favorite things <ul id=“favorite-things-list”> <li>Pizza</li> <li>Beer</li> </ul> </p> </div>
  • 28. CSS - PRECEDENCE • Specificity takes precedence over generality. • id>class>tag • inline>internal>external <div class=“default-text”> <p> These are a few of my favorite things <ul id=“favorite-things-list”> <li>Pizza</li> <li>Beer</li> </ul> </p> </div>
  • 29. CSS - PRECEDENCE <div class=“default-text”> <p> These are a few of my favorite things <ul id=“favorite-things-list”> <li>Pizza</li> <li>Beer</li> </ul> </p> </div> p { color: red; } .default-text { color:black; } #favorite-things-list { color:darkblue; }
  • 30. CSS - PRECEDENCE <div> <p class=“default-text”> These are a few of my favorite things <ul id=“favorite-things-list” style=“color:black”> <li>Pizza</li> <li>Beer</li> </ul> </p> </div> External CSS p { color: red; } .default-text { color:black; } #favorite-things-list { color:darkblue; } Internal CSS p { color: black } .default-text { color:blue; } #favorite-things-list { color:red; }
  • 31. CSS – PSEUDO-SELECTORS • Links • a:link {color:blue} • a:visited {color:purple} • a:active {color:black} • Hover a:hover { background-color:blue; color:white; } • Focus • input:focus {background- color:yellow) • Children • li:firstchild {font-weight:bold} • ul .multi-list>li {color:red} • ul .multilist>li>ul>li {color:blue} • ul .multilist>li>ul>li>ul>li {color:green}
  • 32. COLORS ON THE WEB • Constants • red • azure • saddlebrown • RGB • #000 Black • #800 Pink • #F00 Red • RGB (Continued) • #F0F ????? • #FFF ????? • RGB 24 bit • #FF0000 Red • #FF0088 Magenta • #6AD029 ????????
  • 33. CSS – PRIMARY USES • Style • Font • Color • Size • Borders • Formatting • Indents • Margin • Alignment • Spacing • Layout • Relative • Absolute • Float • Animation • Hover and focus pseudo:selectors • Turn content on and off, change its position, or change styles on the fly (with Javascript)
  • 34. BEYOND CSS • LESS and SASS • Use variables in CSS • Use conditional statements • Compile to CSS
  • 35. DOCUMENT OBJECT MODEL (DOM) • The DOM is an object oriented depiction of the HTML and CSS in a web page. • Every time a page is loaded its HTML and CSS are translated into a DOM. • The DOM is actually what the browser uses to display the page.
  • 36. WHAT IS AN OBJECT? • Objects are a way of describing the world into language a computer can understand. • An object is a data structure that has both properties and methods. • Properties are data and can be a single value, an array, or another object. • In computer lingo these are analogous to variables. • Methods are actions that an object can perform. • In computer lingo these are analogous to a function. • Objects can inherit the properties and methods of its parent object and overwrite them or add to them.
  • 37. WHAT IS AN OBJECT? • Animal Object • Properties • Skin Type • Movement Type • Color • Temperament • Methods • Make a noise • Move • Eat
  • 38. INHERITING FROM AN OBJECT • Reptile Object – Inherit from animal • Properties • Skin Type: Scales • Movement Type: crawl • Color • Temperament • Methods • Make a noise {} • Move {crawl} • Eat{} • Grow Scales{} • Mammal Object – Inherit from animal • Properties • Skin Type:Hair • Movement Type:[walk, hop, fly,] • Color • Temperament • Methods • Make a noise{} • Move {if Rabbit then hop, if bat then fly, else walk} • Eat{} • Grow Hair{} • Produce Milk{}
  • 39. INHERITING FROM AN OBJECT • Mouse Object – Inherit from Mammal • Properties • Skin Type:Hair • Movement Type:Walk • Color • Temperament: Nervous • Methods • Make a noise {squeak} • Move {walk} • Eat {search for cheese} • Grow Hair {} • Produce Milk {} • Scare Ladies {} • Avoid cats {} • Dog Object – Inherit from Mammal • Properties • Skin Type:Hair • Movement Type:Walk • Color • Temperament: Friendly • Methods • Make a noise {bark} • Move {walk} • Eat {beg for treats} • Grow Hair {} • Produce Milk {} • Catch Frisbee {} • Chase cats {}
  • 40. ABSTRACTION AND INSTANTIATION • To instantiate an object means to create an individual object from the object blueprint. • In computer lingo, the blueprint is known as a “class” • An “Abstract” class is one that can have its properties and methods inherited but can not be instantiated. • If I say “get me an animal” you will say “what kind?”. • Defining an animal is useful as a blueprint that other things can inherit from but cannot be an actual thing. • Mammals inherit properties of animals and modify or add new ones. Reptiles do the same but in a different manner • Dogs and mice also inherit properties of mammals and add new ones, but you can go to the store and actually buy a dog or a mouse. • In computer lingo each individual dog is an instance of the dog class which inherits some properties from the mammal abstract class which inherits some properties from the animal class. • Some properties can not actually be set until the object is instantiated. We know that dogs have a color and temperament property but we won’t know what color or what temperament until we have an actual instance of the dog class. • This object hierarchy is an intuitive way to describe the world and translate it into language that a computer can understand.
  • 41. OBJECTS IN COMPUTERS • The concept of objects and object hierarchies is very common in computer software. • If I right click on a graphic object in PowerPoint I can see and change its color, transparency, size, etc. • Those properties are different if it’s a line or a polygon or an image. • In GIS terms we can think of a feature as an instantiation of a feature class and the coordinates and attributes as its properties. • The feature class can inherit different properties depending on whether it is a point, line, or polygon. • When we display a layer on a map we can also set its display properties • Size • Color • Transparency, etc.
  • 42. DOCUMENT OBJECT MODEL (DOM) • The DOM is an object oriented depiction of the HTML and CSS in a web page. • Every time a page is loaded its HTML and CSS are translated into a DOM. • The DOM is actually what the browser uses to display the page.
  • 43. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p>Lorem Ipsum</p> </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 44. IMPORTANT PROPERTIES OF HTML ELEMENTS • childElementCount • children[5] • innerHTML • innerText • id • eventhandlers (onclick etc.) • parentElement • style • style.color=“red” • style.display=“none” • tagname
  • 45. EVENTS • Event Driven Programming • When Apple introduced the McIntosh in 1984 it introduced an entirely new paradigm into computer programming. • Prior to this, computer code was written and processed in a top down manner • First line of code was executed, then the second, etc. • The McIntosh allowed the user to interact with the computer via the mouse. • Click, double click, drag, drop, right click, scroll up, scroll down, etc. I.E. events. • Event handlers are snippets of code that are executed in response to an event. • Events also can occur when the mouse hovers over an object, when a window is resized, before and/or after a page is loaded, when the text in an input box is changed, etc. • Modern programming is largely object oriented and event driven. • Programmers need to understand the events that occur in the environment that they are programming in and write event handlers for those events. • They also need to understand the object model behind their environment so that they can manipulate those objects in response to events.
  • 46. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p> Lorem Ipsum </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 47. JAVASCRIPT • Also began in the mid 90’s as Netscape’s scripting technology • Microsoft used JScript and VBScript • Adobe used ActionScript in Flash • Standardized in the mid-00’s as the dominant client-side scripting language in browsers • Allows manipulation of the DOM. • Also available for server-side scripting in NODE.js • Open Source – This is good. It is not subject to the whims of a single company. • Object Oriented – EVERYTHING in JavaScript is an object. Even functions. • Event Driven – Much of the JavaScript code that you write will be event handlers.
  • 48. HOW DO WE ACCESS THE DOM? • Every browser makes the DOM accessible through the document object • The document object is available to all JavaScript code • document.head or document.body to reference the head or body. • Children of the body are an array of HTML elements • document.body.children[2] to reference the third child element of the body. • document.body.children[2].children[1] to reference the second child of the third child of the body.
  • 49. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p> Lorem Ipsum </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 50. ACESSING THE DOM • var colorlist = document.body.children[1].children[0]
  • 51. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p> Lorem Ipsum </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 52. ACESSING THE DOM • colorlist = document.body.children[1].children[0] • animallist = document.body.children[1].children[1] • firstanimallist = document.body.children[1].children[1].children[0]
  • 53. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p> Lorem Ipsum </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 55. DOCUMENT OBJECT MODEL (DOM) <html> <head> <title> My Page</title> </head> <body> <div id=“col1”> <p>Lorem Ipsum</p> </div> <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> </div> </body> </html> html body head title div: col1 p div: col2 ul: animallist ul: colorlist li li li li
  • 57. IMPORTANT PROPERTIES OF HTML ELEMENTS • childElementCount • children[5] • innerHTML • innerText • id • eventhandlers (onclick etc.) • parentElement • style • style.color=“red” • style.display=“none” • tagname
  • 58. JAVASCRIPT • Since most of the JavaScript we write will be event handlers lets write one. <script> document.body.addEventListener(“click”, function(e){ console.log(“Clicked in the body”); console.log(e); alert(“Clicked in the bodynX: ”+e.clientX+”nY: “+e.clientY); alert(e); }); </script>
  • 59. EVENT HANDLER <div id=“col2”> <ul id=“colorlist”> <li>Red</li> <li>Green</li> </ul> <ul id=“animallist”> <li>dog</li> <li>cat</li> </ul> <button id=“switch- list”>Switch</button> </div> #colorlist { display:block; } #animallist { display:none; } #switch-list { color:red; background-color:black; } #switch-list:hover { color:black; background-color:red; } #switch-list:click { if #colorlist is displayed hide #colorlist show #animallist else hide #animallist show #colorlist }
  • 60. JAVASCRIPT CONDITIONAL STATEMENTS If (condition) { …….. Code } elseif (condition) { ……... Code } else { ……... Code } • Condition • Always evaluate to true or false • document.title == “My Page” • document.body.childElements > 4 • e.shiftKey • document.title != “My Page”
  • 61. EVENT HANDLER document.body.children[1].children[2].addEventListener('click', function(e){ // #switch-list:click if (document.body.children[1].children[0].style.display != "none") { // If #colorlist is displayed document.body.children[1].children[0].style.display = "none"; // Hide #colorlist document.body.children[1].children[1].style.display = "block"; // Show #animallist } else { // Else document.body.children[1].children[1].style.display = "none"; // Hide #animallist document.body.children[1].children[0].style.display = "block"; // Show #colorlist } });
  • 62. ACESSING THE DOM • var colorlist = document.body.children[1].children[0]; • var animallist = document.body.children[1].children[1]; • var firstanimallist = animallist.children[0]; • var firstanimallist = document.body.children[1].children[1].children[0];
  • 63. EVENT HANDLER document.body.children[1].children[2].addEventListener('click', function(e){ // #switch-list:click if (document.body.children[1].children[0].style.display!="none") { // If #colorlist is displayed document.body.children[1].children[0].style.display="none"; // Hide #colorlist document.body.children[1].children[1].style.display="block"; // Show #animallist } else { // Else document.body.children[1].children[1].style.display="none"; // Hide #animallist document.body.children[1].children[0].style.display="block"; // Show #colorlist } });
  • 64. EVENT HANDLER var btnSwitch = document.body.children[1].children[2]; var colorlist = document.body.children[1].children[0]; var animallist = document.body.children[1].children[1]; btnSwitch.addEventListener('click', function(e){// #switch-list:click if (colorlist.style.display!="none") { // If #colorlist is displayed colorlist.style.display="none"; // Hide #colorlist animallist.style.display="block"; // Show #animallist } else { // Else animallist.style.display="none"; // Hide #animallist colorlist.style.display="block"; // Show #colorlist } });
  • 65. EVENT HANDLER var btnSwitch = document.getElementById(‘switch-button’); var colorlist = document.getElementById(‘colorlist’); var animallist = document.getElementById(‘animallist’); btnSwitch.addEventListener('click', function(e){// #switch-list:click if (colorlist.style.display!="none") { // If #colorlist is displayed colorlist.style.display="none"; // Hide #colorlist animallist.style.display="block"; // Show #animallist } else { // Else animallist.style.display="none"; // Hide #animallist colorlist.style.display="block"; // Show #colorlist } });
  • 66. DOM MANIPULATION – EXAMPLE 2 <div id="col2"> <ul id="colorlist"> <li>Red</li> <li>Green</li> </ul> <ul id="animallist"> <li>dog</li> <li>cat</li> </ul> <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> var btnChange = document.getElementById('change-color'); btnChange.addEventListener('click', function(e){ var col1=document.getElementById('col1'); switch (col1.style.color) { case "red": col1.style.color="orange"; break; case "green": col1.style.color="blue"; break; case "blue": col1.style.color="purple"; break; case "black": col1.style.color="red"; break; default: col1.style.color="red"; break; } });
  • 67. SWITCH STATEMENT switch (col1.style.color) { case "red": col1.style.color=“green"; break; case "green": col1.style.color="blue"; break; case "blue": col1.style.color=“black"; break; case "black": col1.style.color=“purple"; break; default: col1.style.color="red"; break; } If (col1.style.color==”red”){ col1.style.color=" green "; } else if (col1.style.color==” green”){ col1.style.color=“blue"; } else if (col1.style.color==” blue”){ col1.style.color=“black"; } else if (col1.style.color==” black”){ col1.style.color=“purple"; } else { col1.style.color="red"; }
  • 68. DOM MANIPULATION – EXAMPLE 2 <div id="col2"> <ul id="colorlist"> <li>Red</li> <li>Green</li> </ul> <ul id="animallist"> <li>dog</li> <li>cat</li> </ul> <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> var btnChange = document.getElementById('change-color'); btnChange.addEventListener('click', function(e){ var col1=document.getElementById('col1'); switch (col1.style.color) { case "red": col1.style.color=“green"; break; case "green": col1.style.color="blue"; break; case "blue": col1.style.color=“black"; break; case "black": col1.style.color=“purple"; break; default: col1.style.color="red"; break; ));
  • 69. CALCULATIONS AND VALIDATION …… <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> <input id="value1" type="text" value="5"> <input id="value2" type="text" value=“6"> <button id="multiply">Multiply</button> var btnMultiply=document.getElementById("multiply"); var inputValue1=document.getElementById("value1"); var inputValue2=document.getElementById("value2"); btnMultiply.addEventListener('click', function(e) { var val1=inputValue1.value; var val2=inputValue2.value; alert(val1+" X "+val2+" = "+(val1*val2)) });
  • 70. CALCULATIONS AND VALIDATION …… <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> <input id="value1" type="text" value="5"> <input id="value2" type="text" value=“6"> <button id="multiply">Multiply</button> var btnMultiply=document.getElementById("multiply"); var inputValue1=document.getElementById("value1"); var inputValue2=document.getElementById("value2"); btnMultiply.addEventListener('click', function(e) { var val1=inputValue1.value; var val2=inputValue2.value; if (isNaN(val1) || isNaN(val2)) { alert("At least one of the values is not a number"); } else { alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2)); } });
  • 71. CALCULATIONS AND VALIDATION …… <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> <input id="value1" type="text" value="5"> <input id="value2" type="text" value=“6"> <button id="multiply">Multiply</button> ….. btnMultiply.addEventListener('click', function(e) { var val1=inputValue1.value; var val2=inputValue2.value; if (isNaN(val1) || isNaN(val2)) { alert("At least one of the values is not a number"); } else { alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2)); } }); inputValue1.addEventListener('keyup', function(e) { if (isNaN(inputValue1.value)) { alert("Please enter a number."); } });
  • 72. THE PROBLEM WITH ALERTS • Many people find alerts annoying. • The first time a user visits your site and sees an alert everything is fine • But the SECOND time they have the option of preventing anymore dialogs by clicking the box. • Because of this, alerts are not a reliable method for getting a message to the user.
  • 73. SO HOW DO WE COMMUNICATE TO THE USER? • Use a third party library such as Impromptu. • Simulate alerts through HTML, CSS, JavaScript • <div> that’s normally hidden with a button to remove it. • Jquery • Bootstrap • DOM manipulation • Add or modify text, change colors, border, etc.
  • 74. CALCULATIONS AND VALIDATION …… <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> <input id="value1" type="text" value="5"> <input id="value2" type="text" value=“6"> <button id="multiply">Multiply</button> ….. btnMultiply.addEventListener('click', function(e) { var val1=inputValue1.value; var val2=inputValue2.value; if (isNaN(val1) || isNaN(val2)) { alert("At least one of the values is not a number"); } else { alert(val1+" X "+val2+" = "+(val1*val2).toFixed(2)); } }); inputValue1.addEventListener('keyup', function(e) { if (isNaN(inputValue1.value)) { inputValue1.style.border="2px solid red"; } else { inputValue1.style.border=""; } });
  • 75. PASSING FUNCTIONS AS PARAMETERS inputValue1.addEventListener('keyup', function(e) { if (isNaN(inputValue1.value)) { inputValue1.style.border="2px solid red"; } else { inputValue1.style.border=""; } }); inputValue2.addEventListener('keyup', function(e) { if (isNaN(inputValue2.value)) { inputValue2.style.border="2px solid red"; } else { inputValue2.style.border=""; } }); function validateNumber() { if (isNaN(this.value)) { this.style.border="2px solid red"; } else { this.style.border=""; } inputValue1.addEventListener(‘keyup', validateNumber) inputValue2.addEventListener(‘keyup', validateNumber)
  • 76. CALCULATIONS AND VALIDATION …… <button id="switch-button">Switch</button> <button id="change-color">Change Color</button> </div> <input id="value1" type="text" value="5"> <input id="value2" type="text" value=“6"> <button id="multiply">Multiply</button> <hr> <p id="result"></p> ….. var result=document.getElementById(‘result’) btnMultiply.addEventListener('click', function(e) { var val1=inputValue1.value; var val2=inputValue2.value; if (isNaN(val1) || isNaN(val2)) { result.innerHTML="One or both of the input values is invalid"; result.style.color="red"; } else { result.innerHTML=val1+" X "+val2+" = " + val1*val2; result.style.color="green"; } }); ……
  • 77. LOOPS IN JAVASCRIPT • While Loop var i=0; while (i<9){ alert(i); i++; // i=i+1 } • For Loop for (var i=0;i<myArray.length;i++){ alert(myArray[i]); }
  • 78. ARRAY’S IN JAVASCRIPT • Arrays are indexed numerically using the [ ] notation. • Arrays can hold any type of objects • Arrrays can hold different types of objects in the same array. • An empty array is created using • var myArray=[ ]; • You can add items to an array at initiation using • var myArray=[45, ‘dog’, [1,2,3], {color:red;size:10}] • myArray[0] = 45; • myArray[1] = ‘dog’; • myArray[2] = [1,2,3]; • myArray[2][2]=3; • myArray[3]={color:red;size:10}; • myArray[3].size = 10;
  • 79. ARRAYS IN JAVASCRIPT (CONT’D) • Arrays have a length property holding the number of elements in an array. • myArray.length = 4; • You can add an element to an array in three ways. • myArray[myArray.length]=‘Bob’; • myArray.push(‘Bob’); • myArray.push(‘Bob’, ‘Bill’,103); • myArray.unshift(‘Bob’, ‘Bill’, 103) • Deleting elements from an array • From the top • x=myArray.pop(); • From the bottom • x=myArray.shift();
  • 80. OBJECTS IN JAVASCRIPT • Everything in JavaScript is an object • Unlike many programming languages you don’t have to define an object class. • You can create your own objects on the fly using the following notation myDog = { species:”dog”, color:”blue”, name:”Lola”, age: 14, legs: [‘front-left’, ‘front-right’, ‘rear-left’, ‘rear- right’], displayAge:function(){ alert(“Lola is 14 years old”); } } • You reference an objects properties and/or methods using the ‘dot’ notation. • myDog.name = “Lola”; • myDog.legs[2] = ‘rear-left’ • myDog.displayAge();
  • 81. OBJECT LITERALS AND JSON • Object Literal and Binary Objects var myDog = {species:”dog”, color:”blue”, name:”Lola”, age: 14, legs: [‘front-left’, ‘front-right’, ‘rear- left’, ‘rear-right’] }; myDogJSON=JSON.stringify(myDog); • JSON var myDogJSON = ‘{"species":"dog", "color":"blue", "name":"Lola", "age":14, "legs":["front-left","front-right","rear- left","rear-right"] }’; myDog = JSON.parse(myDogJSON);
  • 82. FRAMEWORKS, LIBRARIES, API’S, PLUG-INS • Bootstrap – CSS library for responsive web sites. • Layout, formatting tables and forms, lists, menus, tooltips, etc. • JQuery – Very popular for manipulating the DOM, event handlers, animations, AJAX, etc. • JQuery Mobile – for mobile devices. • Dojo – Similar functionality to JQuery, less popular but common in GIS applications. • Leaflet.js – Mapping library • Accessing different types of data • Editing • Measuring • Routing • Turf.js – JavaScript library for GIS operations. • Impromptu – Deal with the alert box issue and make stylized popups with forms and pages.
  • 83. MVC FRAMEWORKS • Not a product, but a programming philosophy for organizing your code • Model – View – Controller • Model – Data access • View – User Interface • Controller – Connects user interface to data. • Adaptations – MVA, MVP, HMVC, MVVM • MVC Frameworks exist in many languages • Django – Python • Rails – Ruby • ASP.NET MVC – Microsoft • CodeIgnitor, Cake, Laravel – PHP • Angular, Backbone, Ember - JavaScript
  • 84. BOOTSTRAP • CSS Library • Cross Browser Compatibility • Pre-defined classes • Responsive Design • Grid design • 12 columns • 4 screen size classes • xs, small, medium, large • Glyphicons – Fonts for standard web symbols. • Javascript Library – tooltips, dialogs, etc. • Makes your pages responsive, pretty, and standardized.
  • 85. JQUERY - ”WRITE LESS, DO MORE” • Cross Browser Compatibility • Javascript Library for DOM manipulation • Respond to Events • Add and remove classes, attributes, and CSS • Modify content • Other Functionality • AJAX – communicate with server from within Javascript • Animations • Validation • JQuery UI – User interface – Tabs, Dialogs, Menu’s, etc.
  • 86. JQUERY – STEP 1 SELECT A DOM ELEMENT OR GROUP OF DOM ELEMENTS • Document • Tags • Classes • ID • $(document) • $(“p”) • $(“.link-buttons”) • $(“#my-link”)
  • 87. JQUERY – SELECTORS (ADVANCED) • $(“#navBar a”) • $(“img[alt]”) • $(“#col2 p:first”) • $(“tr:odd”) • $(“a:not(#googleLink)”) • $(“p:hidden”) • Descendants (a tags within the navBar element) • Attributes (image tags with the alt attribute set) • Filters (first paragraph in the col2 element) • Filters (odd table rows) • Filters (Links except the one with an id of googleLink) • Filters (hidden paragraphs)
  • 88. JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED • Run code automatically when the page is loaded • Add an event handler • Hide or display an element • Get the content • Replace the content • Add or Remove a class $(document).ready(function(){}) $(“#myButton”).click(function(){ alert(“You clicked myButton”); }); $(“.lights”).hide(); $(“.lights”).show(); var frstHTML = $(“p:first”).html(); $(“p:first”).html(“Replacing with this”); $(“.lights”).addClass(“text-center”); $(“.lights”).removeClass(“text-center”);
  • 89. JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED • Read the CSS • Change the CSS • Read an HTML attribute • Change an HTML attribute • Read an HTML form element • Change an HTML form element var size = $(“#header”).css(“font-size”); $(“.main-points”). css(“font-weight”, “bold”); var headerSrc = $(“#header_image”).attr(“src”); $(“#header_image”).attr(“src”,“images/header2.jpg”); var name = $(“#name”).val(); $(“#name”).val(“Joe Smith”);
  • 90. JQUERY – STEP 2 DO SOMETHING WITH THE ELEMENTS YOU SELECTED • Loop through a set $(“.numericField”).on(“keyup”, function(){ }); $(“#myForm_submit”).click(function(){ $(“.numericField”).each(function(){ if (isNan($(this).val()) { $(this).addClass(“has-error”); } else { $(this).removeClass(“has- error”); } // if NaN }); // each numeric field }); // click myForm_submit
  • 91. GEOSPATIAL DATA ON THE WEB • Binary Formats • ESRI • Coverages, Shapefile, Personal Geodatabase, File Geodatabase, Enterprise Geodatabase • Open Source • Shapefile, PostGIS., Spatiallite • Text Based Formats • XML based formats • KML - Google • GPX – GPS • JSON based formats • geoJSON • topoJSON
  • 92. XML • GPX <time>2016-10-17T10:08:03Z</time> <wpt lat="20.38333" lon="-100"> <name>1</name> <cmt>08:54 17-Oct-16</cmt> </wpt> <wpt lat="20.51667" lon="-100.81667"> <name>2</name> <cmt>08:54 17-Oct-16</cmt> </wpt> <wpt lat="20.6" lon="-100.38333"> <name>3</name> <cmt>08:54 17-Oct-16</cmt> </wpt> <wpt lat="21.3" lon="-100.51667"> <name>4</name> <cmt>08:54 17-Oct-16</cmt> </wpt> • KML </description> <styleUrl>#IconStyle00</styleUrl> <MultiGeometry> <Point> <altitudeMode>clampToGround</altitudeMode> <coordinates> - 100.5166700003203,21.29999999980021,0</coordinates> </Point> </MultiGeometry> </Placemark> </Folder> <Style id="IconStyle00"> <IconStyle> <Icon><href>Layer0_Symbol_153b24f0_0.png</href></Icon> <scale>0.250000</scale> </IconStyle> <LabelStyle> <color>00000000</color> <scale>0.000000</scale> </LabelStyle> <PolyStyle> <color>ff000000</color> <outline>0</outline> </PolyStyle> </Style> </Document>
  • 93. GEOJSON • A specification for creating, identifying, and storing geospatial data in JavaScript Object Notation • Mapping API’s • Leaflet • Google • OpenLayers • ESRI???? • Other software • QGIS • PostGIS • Turf.js • PHP • Databases
  • 94. GEOJSON - POINT {“type”: “Point”, “coordinates”:[-108.5, 33.7] } coordinates[0] = -108.5 coordinates[1] = 33.7 {“type”: “MultiPoint”, “coordinates”:[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2]] } coordinates[1][0] = -108.4 coordinates[0][1] = ?????? coordinates[2,0] = ?????? coordinates[0,2] = ??????
  • 95. GEOJSON - LINE {“type”: “LineString”, “coordinates”:[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2]] } {“type”: “MultiLineString”, “coordinates”:[[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2]], [[-108.5, 33.7], [- 108.4, 33.5], [-108.6, 33.2]], [[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2]]] }
  • 96. GEOJSON - POLYGON {“type”: “Polygon”, “coordinates”:[[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2], [-108.5, 33.7]], [[- 108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2], [-108.5, 33.7]]] } {“type”: “MultiPolygon”, “coordinates”:[[[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2], [-108.5, 33.7]], [[- 108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2], [-108.5, 33.7]]], [[[-108.5, 33.7], [-108.4, 33.5], [-108.6, 33.2], [-108.5, 33.7]]]] }
  • 97. GEOJSON – FEATURES AND FEATURECOLLECTIONS {“type”:”feature”, “geometry”: {“type”: “Point”, “coordinates”:[-108.5, 33.7] }, “properties”: {“species”:”Bald Eagle”, “sex”:”male”, “age”:7 } } {“type”:”featureCollection”, “features”: [{“type”:”feature”, “geometry”: {“type”: “Point”, “coordinates”:[-108.5, 33.7] }, “properties”: {“species”:”Bald Eagle”, “sex”:”male”, “age”:7 } }, {“type”:”feature”, “geometry”: {“type”: “Point”, “coordinates”:[-109.1, 32.5] }, “properties”: {“species”:”Golden Eagle”, “sex”:”female”, “age”:2 } }] }
  • 98. GEOJSON var county = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 1180, "name": "San Juan del Rio", "population": 118173.000000, "country": "Mexico", "state": "Queretaro", "county": "San Juan del Rio“ }, "geometry": { "type": "MultiPoint", "coordinates": [ [ -99.999, 20.3833 ] ] } }] }
  • 99. MAPPING API’S FOR THE WEB • Google Maps API • Pro: Familiarity • Pro: Perspective, Streetview • Con: Proprietary • Con: Limited to Google background maps • Leaflet • Pro: Open Source • Pro: Small Footprint • Pro: Newer codebase • Pro: Easy to use • Con: Limited in scope(but lots of plug-ins) • Open Layers • Pro: Open Source • Pro: Many features • Pro: Rotation, 3D • Con: Large footprint • Con: Learning curve • ESRI Javascript API • Con: Proprietary • Pro: Many Features • Pro: Integrates well with ESRI products if you use them.
  • 100. WHAT DO YOU GET WITH A MAPPING API? • Map canvas • Occupies a div on your web page • Control size and placement of the map by setting the CSS of the div • JavaScript library • Add controls (zoom, select layers, scale bar, coordinates, edit tools, etc) • Display data • Manipulate data • Analyze data using turf.js
  • 101. WHAT CAN YOU DO WITH A MAPPING API ON THE CLIENT SIDE • Display a background map • Streets • Topography • Aerial Photos • Display your own GIS data • Zoom, pan, search, select, view attributes, etc. • Display your location • Analyze (intersections, nearest features, distances, areas, buffers, etc.)
  • 102. BUT….. • You are only working with static data. • You cannot change the data. • You cannot add new data (at least not that anyone else can see). • In order to make changes to the base data that others will be able to see, you need….. • A database server. • You can’t secure your web page to prevent others from accessing it.
  • 103. WHAT YOU NEED A DATABASE SERVER FOR • Any changes that need to be persisted longer than the current session. • Any changes that others will be to see when they open the web page. • Security – If you want to password protect your web pages or implement any kind of log-in system you will need some a database system.
  • 104.
  • 105. EDITORS • HTML, CSS, and JavaScript are just text files. • You can write code in any program that will save a plain asci text file. • There are many advantages to having an actual code editor and many are free. • Colors • Automatic indenting • Code “hinting” • Code completion • Code collapsing • Parenthesis highlighting • Run time environment • Debugging • Plug-Ins • Emmet
  • 106. EDITORS • Brackets • Free • All Platforms • Supports all languages • Supports Emmet • Live Preview • Sublime Text • Notepad++ • Emacs • Text Wrangler • Komodo • Atom • Netbeans
  • 107. LETS MAKE A MAP! 1. Make a directory 2. HTML 3. CSS 4. JavaScript
  • 108. HTML
  • 109. CSS
  • 110. JAVASCRIPT • Load Leaflet • Load Jquery • Initialize Map
  • 111. JAVASCRIPT – ADD DATA • Create a marker and add it to the map • Add a popup to the marker • Chaining • Pop-ups can include HTML and be complex
  • 112. JAVASCRIPT – HANDLE DOM EVENT • HTML • CSS • JavaScript $(“zoomToZocalo”).on(“click”, function(){
  • 113. JAVASCRIPT – HANDLE MAP EVENT • Choose an event to respond to • Write an event handler
  • 114. JAVASCRIPT – ADD EXTERNAL DATA • Add Leaflet.ajax.js plug-in to map document • Add the JavaScript code to read the ajax file and add it to the map. • Add a pointToLayer option that creates the popup for each attraction
  • 115. { "type": "Feature", "properties": { "id": 3, "name": "Chapultepec Park", "image": "chapultepec.jpg", "web": "https://en.wikipedia.org/wiki/Chapultepec" }, "geometry": { "type": "Point", "coordinates": [ -99.18654, 19.41933 ] } }
  • 116. JAVASCRIPT – ADD EXTERNAL DATA • Add Leaflet.ajax.js plug-in to map document • Add the JavaScript code to read the ajax file and add it to the map. • Add a pointToLayer option that creates the popup for each attraction
  • 117. JAVASCRIPT – BUILD HTML FROM GEOJSON • Add buttons for each feature • Add event handlers for each button
  • 118. JAVASCRIPT - ANALYSIS • Turf.js – Client side geospatial analysis • HTML • JavaScript
  • 119. QGIS • Open Source Desktop GIS • Equivalent of ArcGIS Desktop in the ESRI suite • Advantages • Free • Raster manipulation without Spatial Analyst • Includes functionality only available in ArcEditor or ArcInfo • Multi-user capable out of the box with PostGIS • Wide range of data formats and easily converts between them
  • 120. SUMMARY • So far we have learned a little bit about • The three primary technologies that drive the internet and how they interact. • HTML • CSS • JavaScript • Two very popular libraries that make web development easier • Bootstrap (CSS) • jQuery (JavaScript) • Two open source libraries for geospatial applications • Leaflet – Web mapping • Turf – Geospatial Analysis
  • 121. SUMMARY • With the knowledge we have so far we can • Create a web map with our own data • Respond to user input • Perform relatively complex spatial analysis • The caveat is that the data is relatively static • What we cannot do is develop an application where the clients can create or edit data and send it back to the server so that it is accessible by other clients. • For that we need a database server.
  • 122. SERVER SIDE TECHNOLOGIES • Database • Allows for storage and retrieval of information • Structured Query Language (SQL) • Programming Language • PHP • Java • Perl • Ruby • ASP.Net • JavaScript via Node.js
  • 123. DATABASES • Most GIS people are brought up in the world of single user computers and think of databases in terms of a program on their computer such as dBase, FoxPro or Microsoft Access. • These databases include both a database engine (storage and retrieval) and front end tools (forms, reports, etc). • In the multi-user or enterprise world a database is only the database engine. • The front end can be written in any kind of language that has a driver for the database. • Dedicated software: Visual Basic, C#, Python • Internet Application: HTML, CSS, Javascript + Server side language to access the database. • The biggest differences between a personal computer database and an enterprise level multi-user database is that they are highly optimized for speed, security, and handling many users simultaneously.
  • 124. SQL • Structured Query Language • Implements CRUD • Create • Retrieve • Update • Delete
  • 125. POPULAR ENTERPRISE DATABASES (RDBMS) • Commercial • Microsoft SQL Server • Oracle • IBM DB2 • Open Source • MySQL • PostgreSQL • SQLite • Advantages – Well established technology
  • 126. POPULAR ENTERPRISE DATABASES (NO SQL) • Commercial • ??????? • Open Source • MongoDB • CouchDB • PouchDB • IndexDB – HTML5 spec in every browser. • Advantages – Flexibility • JSON Storage = ease of use with JavaScript
  • 128. DATABASES AND GEOSPATIAL DATA • How to handle coordinates???? • Table fields • Store geoJSON objects in a text field. • Utilize a spatial extension to a database • Method for storing coordinates in a binary field • Set of functions for dealing with spatial data • ArcSDE • SQL Server, Oracle, DB2, PostgreSQL • PostGIS • PostgreSQL • Spatialite • SQLite
  • 129. TECHNOLOGY STACK USED IN THIS COURSE • Database • PostgreSQL • PostGIS Extension • Programming Language • PHP • Open source • Widely available • Well documented
  • 130. SERVER OPTIONS • Install on local machine • Great for development but not great for a webserver. • XAMPP includes Apache Web Server, MySQL, PHP, and Perl • PostgreSQL and PostGIS • Purchase a hosting plan • Make sure that the plan includes the programming language and database you install on your local machine. • A2 Hosting includes PostgreSQL and PostGIS • Move files back and forth using FTP. • Control server using SSH (command line) or web application (phpPgAdmin) • Purchase a dedicated server
  • 131. WHAT DO I USE THE SERVER FOR? • Number crunching and analysis • You can do this locally using JavaScript. • But the server is generally more powerful. • Decision to process on the client or server depends on many factors. • Retrieving data from the database • AJAX call from JavaScript that returns text. (JSON, or HTML). • Dynamic web pages • .php extension instead of .html • <?php …code…. ?> • echo “string”; statement
  • 132. COMMON FRUSTRATIONS • The internet has grown organically as a bottom-up system • At the time it was developed nobody really had any expectation of it growing into what it has become • There is a phenomenon known as “lock-in”, whereby a substandard technology becomes established and popular to the point where it becomes almost impossible for superior technology to replace it. • QWERTY keyboard layout was designed to prevent manual typewriter keys from jamming. • Betamax vs VHS • PC vs Mac
  • 133. COMMON FRUSTRATIONS • SQL has been around since the 70s. Long before the internet was even dreamed of. • PHP was developed in 1994 by Rasmus Lerdorf to help with his personal web page. • PHP originally stood for Personal Home Page • Lerdorf didn’t intend for PHP to interact with databases. • He said "I don’t know how to stop it, there was never any intent to write a programming language. I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way.“ • As of February 2014 PHP was the server-side language for 82% of web sites, up from 75% in 2010.
  • 134. COMMON FRUSTRATIONS • JavaScript wasn’t developed until 1995. • While it was being developed nobody really knew what PHP was. • Developed by Netscape while Navigator was the #1 browser in the world. • Everyone knew Microsoft was also developing a scripting language called VBScript. • This led to the “Browser Wars” of the late 1990s • Over the years JavaScript and PHP became dominant. • PHP added the ability to interact with databases. • Both added object oriented functionality • In 2005 AJAX was developed allowing JavaScript in the client to communicate directly with PHP in the server.
  • 135. TAKEAWAYS • JavaScript, PHP, and SQL were never intended to work with each other and as a result they have very different syntax. • This is likely to remain the case due to “Lock-in” despite developments such as Node.JS and ASP.NET • “Suck it up, cupcake”. You have to learn 3 different ways to • Concatenate strings • Format numbers • Deal with date and time • Deal with objects and arrays • Etc, etc, etc. • Don’t get taken in by people selling you the latest and greatest technologies.
  • 136. SQL - INTRODUCTION • Structured Query Language • Started with IBM in the early 70’s. First commercial version by Oracle in 1979. • Client Server Architecture • Request = SQL command • Response – Recordset / # records / error. • Declarative Programming – Say what you want to do • Data Definition Language • Data Manipulation Language • Data Control Language • Imperative Programming – Step by step algorithms • Triggers • Text-based
  • 137. SQL - ARCGIS • Select by Attributes • Definition Queries
  • 138. SQL - ACCESS • Design View • SQL View • SELECT Vehicles.Year & " " & [Vehicles.Make] & " " & Vehicles.Model AS Vehicles, Expenses.* • FROM [Vehicles Extended] INNER JOIN Expenses ON [Vehicles Extended].ID = Expenses.Vehicle • ORDER BY Vehicles.Year & " " & [Vehicles.Make] & " " & Vehicles.Model DESC , Expenses.[Service Date] DESC;
  • 139. SQL - CREATE • Create a new empty table CREATE TABLE raptor_nests ( id int PRIMARY KEY DEFAULT nextval(‘raptor_nests_id’), nest_id varchar(10) NOT NULL, species varchar(50), 2016_status varchar(50), current_status varchar(50), date_found date, last_date_inspected date, project_id integer ) SELECT AddGeometryColumn(‘public’, ‘raptor_nests’, ‘geom’, 4326, ‘POINT’, 2)
  • 140. SQL - CREATE • Create a new empty table CREATE TABLE projects ( id int PRIMARY KEY DEFAULT nextval(‘project_id’), project_id varchar(50) NOT NULL, name varchar(255) NOT NULL, start_date date NOT NULL, status varchar(50), ) SELECT AddGeometryColumn(‘public’, ‘projects’, ‘geom’, 4326, ‘LINESTRING’, 2)
  • 141. SQL - INSERT • Add data to an existing table • INSERT INTO raptor_nests (nest_id, species, current_status, date_found, geom) VALUES (‘RN_025’, ‘SWHA’, ‘ACTIVE’, ‘2015-11-05’, ST_GeomFromText(‘POINT(-106.435 39.423)’, 4326)); • INSERT INTO projects (project_id, name, start_date, geom) VALUES (‘USD 10-5’, ‘UNITED SANITARY DESIGN #10, Project 5’, ‘2016-04-12’, ST_SetSRID(ST_GeomFromGeoJSON(‘{“type”:”LineString”, “coordinates”:[[-106.45245, 38.5642], [-106.65876, 38.80678],[-106.1952, 38.65335]]}’), 4326))
  • 142. SQL - RETRIEVE • SELECT – Single Table • SELECT * FROM raptor_nests; • SELECT nest_id, species, current_status, date_found, last_date_inspected FROM raptor_nests • SELECT nest_id, species, date_found, last_date_inspected FROM raptor_nests WHERE current_status = ‘active’; • SELECT nest_id, species, date_found, last_date_inspected FROM raptor_nests WHERE current_status = ‘active’ ORDER BY species, last_date_inspected DESC, nest_id; • SELECT species, count(species), max(last_date_inspected) FROM raptor_nests GROUP BY species ORDER BY species • SELECT species, count(species) AS count, max(last_date_inspected) AS most_recent_inspection FROM raptor_nests WHERE current_status <> 2016_status GROUP BY species ORDER BY species • SELECT name, length_feet/5280 as length_miles, start_date FROM projects ORDER BY dist_miles
  • 143. SQL - RETRIEVE • SELECT - Multiple Tables • SELECT p.start_date, p.name, r.nest_id, r.species, r.current_status FROM raptor_nests r JOIN projects p ON p.id = r.project_id ORDER BY p.start_date, DESC, p.name, r.nest_id • JOIN TYPES • INNER • LEFT • RIGHT • FULL • SELECT – Spatial Queries with POSTGIS • SELECT p.start_date, p.name, r.nest_id, r.species, r.current_status, ST_Distance(r.geom, p.geom) as distance FROM raptor_nests r JOIN projects p ON ST_DWithin(r.geom, p.geom, 500)
  • 144. SQL - UPDATE • Modify existing data in an existing table • UPDATE raptor_nests SET last_inspection_date=‘2016-07-18’, current_status=‘FLEDGED’ WHERE id=13; • UPDATE raptor_nests SET current_status=‘FLEDGED’ WHERE upper(current_status)=‘FLEDGED’;
  • 145. SQL - DELETE • Delete data from an existing table • DELETE FROM raptor_nests WHERE id=12; • DELETE FROM raptor_nests WHERE (current_status=‘REMOVED’) AND ((current_date()- last_inspection_date) > 730)
  • 146. SQL - DELETE • Delete data from an existing table • DELETE FROM raptor_nests WHERE id=12; • DELETE FROM raptor_nests WHERE (current_status=‘REMOVED’) AND ((current_date()- last_inspection_date) > 730) • Operator precedence 1. () 2. *, / 3. +, -, 4. =, <, > 5. NOT 6. AND 7. IN, LIKE, OR 6-3*4/2 = ????? (6-3)*4/2 = ???? (6-(3*4))/2 = ?????? 0 6 -3
  • 147. SO I HAVE A SQL STATEMENT….. • How do you send it to the database and what do you do with the result… • An enterprise database is not like a standalone program, they are designed to be accessible in many ways. • All you need is connection information • Host – localhost, www.millermountain.com, 189.207.169.17 • Port – 5432 • Database Name – gis_test • Username • Password
  • 148. SO I HAVE A SQL STATEMENT….. • You can access it many ways. • Command line – (psql) • GUI – pgAdmin III • Web Interface – phpPgAdmin • Custom software – QGIS, ArcGIS, Excel, Access • Custom web page – PHP, Java, ASP.NET, Ruby, Node.js • Result • Text • Table • Feature Class, Spreadsheet, Table • Array of data or objects
  • 149. OVERVIEW 1. User interacts with a web page or map on the client A. Submit a form, enter a project id, select from a list, click on the map. 2. Web page sends data to the server(GET, POST, AJAX) 3. A php script on the server receives the data, processes it SQL statement, sends to the database 4. The database returns a result that is processed by a php script and returns a string (AJAX, ECHO) A. Loop through and add HTML for a web page table B. Loop through and return geoJSON to turn into features on a map 5. Web page does something with the result string A. Inserts table into page. B. Inserts features onto the map.
  • 150. PHP - INTRO • Two flavors of PHP • Procedural • Object Oriented • Two ways to use PHP • Dynamic web page • HTML document with embedded PHP code • AJAX • Script on server receives data from Javascript and returns text to javascript <?php $heading = “Welcome to my web page”; ?> …….. <h1><?php echo $heading; ?></h1> <h1> Welcome to my web page </h1>
  • 151. PHP - STRINGS • All statements end with a semicolon; • Variable names begin with $ • Do not need to be declared • String concatenation • $space=“ “; • $myString1= “Micky”.$space.”Mouse”; • $myString2=“Mickey$space Mouse”; • $myString3=“Mickey{$space}Mouse”; “Mickey”+$space+”Mouse”;
  • 152. PHP - ARRAYS • Indexed Arrays – indexed numerically • $animalType = array(“CAT”, “DOG”, “CHICKEN”); • $animalType = [“CAT”, “DOG”, “CHICKEN”]; • $animalType[] = “BEAR” • $animalType[6] = “FERRET” • Associative Arrays – indexed by keys • $geomDimension = array(“POINT”=>0, “LINE”=>1); • $geomDimension = [“POINT”=>0, “LINE”=>1]; • $geomDimension[‘POLYGON’]=2; • $animalType[0]=“CAT”; • $animalType[1]=“DOG”; • $animalType[2]=“CHICKEN; • $animalType[3]=“BEAR”; • $animalType[6]=“FERRET”; • $geomDimension[“POINT”]=0; • $geomDimension[“LINE”]=1; • $geomDimension[“POLYGON”]= 2;
  • 153. PHP – ARRAY FUNCTIONS • sizeof() or count() – returns number of elements • array_push(), array_pop(), array_shift(), array_unshift() • array_keys(), array_values() • array_unique() • sort(), asort(), ksort() • rsort(), arsort(), krsort() • json_encode() • count($geomDimension) = 3 • array_push($animalType, “BIRD”)
  • 154. COMMUNICATION WITH SERVER - GET • Sending information TO server • Parameters encoded in the URL • Syntax = localhost/webmap101/php_test.php?lat=19.25831&long=- 99.34295&alt=2207 • lat = “19.25831” • long=“-99.34295” • alt=“2207” • Limited to 2048 characters • Visible to user = Insecure • Can be bookmarked
  • 155. COMMUNICATION WITH SERVER - POST • Sending information TO server • Parameters encoded in the HTTP request header • Not visible to user = More secure • No limit on size • Cannot be bookmarked • So how do you send data with POST? • Form submit button. • AJAX
  • 156. COMMUNICATION WITH SERVER • Reading GET and POST information • Superglobal variables in PHP • $_GET • $_POST • Associative arrays
  • 157. COMMUNICATION WITH SERVER - GET • Sending information TO server • Parameters encoded in the URL • Syntax = localhost/webmap101/php_test.php?lat=19.25831&long=- 99.34295&alt=2207 • lat = “19.25831” • long=“-99.34295” • alt=“2207” • Limited to 2048 characters • Visible to user = Insecure • Can be bookmarked
  • 158. COMMUNICATION WITH SERVER • Reading GET and POST information • Superglobal variables in PHP • $_GET • $_POST • Associative array • $_GET[‘lat’] • $_GET[‘long’] • $_GET[‘alt’]
  • 159. PHP – CONDITIONAL STATEMENTS if (condition) { code…… } elseif { code…. } else { code….. } if (isset($_GET[‘lat’])) { $lat=$_GET[‘lat’]; } else { $lat= “N/A”; } switch ($geomType[i]) { case “POINT”: $size = “No Dimension<br>”; break; case “LINE”: $size = “Length = “.lineLength($geom).”<br>”; break case “POLYGON”: $size = “Area= “.area($geom).”<br>”; break; default: echo “N/A”; }
  • 160. PHP - LOOPS for ($i=0;$i<count($animalType);$i++) { echo $animalType[$i].”<br>”; } $i=0; $while ($i<count($animalType) { echo $animalType[$i].”<br>”; $i++; }
  • 161. PHP - LOOPS foreach ($_GET as $key=>$val) { echo “Key: {$key} Value: {$val}<br>”; } $sql = “UPDATE cords SET “; foreach ($_POST as $key=>$val) { $sql += “{$key} = ‘{$val}’, “; } $sql += “ WHERE id = 13”;
  • 162. SECURITY NOTE – SQL INJECTION • One of the most common forms of security threats is a SQL Injection attack. • SQL statements end with a semi-colon. • SQL Engine will process anything after a semicolon as a new statement. • This allows someone with knowledge of SQL to “Insert” a SQL statement into a text input box.
  • 163. SOLUTION – USE PDO • PHP Data Objects • Use Prepared Statements rather than a single SQL query • Prepared statements • Only allow one SQL statement at a time • Separate data from code by using placeholders • Properly escape user input values • “” removes any special meaning of the character following it • VALUES (‘John’s house’) becomes VALUES (‘John’s house’)
  • 164. SOLUTION – USE PDO • Standard $db = pg_connect("host=localhost port=5432 dbname=gis_test user=joe password=12345"); $result = pg_query($db, “SELECT nest_id, createdate, lastsurvey, recentstatus FROM raptor_nests”); echo “<table>”; while ($row = pg_fetch_array($result)) { echo “<tr>”; foreach ($row as $field=>$value) { echo “<td>{$value}</td>”; } echo “</tr>”; } echo “</table>”;
  • 165. SOLUTION – USE PDO • Prepared Statements $db = new PDO(“pgsql:host=localhost;port=5432;dbname=millermo_testgis;user=joe;password=12345"); $sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies FROM wildlife_raptor_nests WHERE lastsurvey> :ls AND recentstatus = :rs”); $params = [“ls”=>”2016-07-06”, “rs”=>”Active”]; $sql->execute($params); echo “<table>”; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { echo “<tr>”; foreach ($row as $field=>$value) { echo “<td>{$value}</td>”; } echo “</tr>”; } echo “</table>”;
  • 166. PHP - PROBLEMS • Pages must be reloaded every time to see any changes • No direct access to the DOM • Very limited ability to get user input and respond to events • Requires a server connection so off-line applications are out of the question. • Mapping libraries are all based on JavaScript.
  • 167. AJAX • Asynchronous JavaScript And XML* • Microsoft (1999), Google (2004), AJAX coined (2005) • XMLHttpRequest object standardized by W3C (2006) • Allows the client to request information from the server asynchronously • When the request is completed a JavaScript callback function is executed. • The callback function can process the result and manipulate the DOM. • JQuery includes a wrapper for the XMLHttpRequest object that makes it easy to use.
  • 168. AJAX – HTML AND JAVASCRIPT (QUERY_NESTS_AJAX.HTML) <input type="date" id="lastsurvey" value="2015-01-01"><br> <select id="recentstatus"> <option value='ACTIVE NEST'>Active Nest</option> <option value='INACTIVE NEST'>Inactive Nest</option> <option value='FLEDGED NEST'>Fledged Nest</option> </select><br> <button id=“filterSubmit" >Submit</button> <hr><div id=“resultTable></div> <script> $(“#filterSubmit”).click(function(){ $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ }}); }); </script>
  • 169. AJAX – HTML AND JAVASCRIPT (QUERY_NESTS_AJAX.HTML)
  • 170. $.AJAX OPTIONS • async • beforeSend(xhr) • complete(xhr, status) • data • error(xhr, status, error) • success(result, status, xhr) • type • URL • Boolean indicating whether the request is asynchronous. • Function to run BEFORE the request is sent • Function to run AFTER the request is complete • Object containing properties that will become POST variables • Function to run if an error occurs on the server • Function to run if no error occurs • The type of transfer protocol to use GET or POST • The location of the script to run on the server
  • 171. AJAX – HTML AND JAVASCRIPT (QUERY_NESTS_AJAX.HTML) <input type="date" id="lastsurvey" value="2015-01-01"><br> <select id="recentstatus"> <option value='ACTIVE NEST'>Active Nest</option> <option value='INACTIVE NEST'>Inactive Nest</option> <option value='FLEDGED NEST'>Fledged Nest</option> </select><br> <button id=“filterSubmit" >Submit</button> <hr><div id=“resultTable></div> <script> $(“#filterSubmit”).click(function(){ $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ $(“#resultTable”).html(response); }}); }); </script>
  • 172. AJAX – PHP (QUERY_NESTS_AJAX.PHP) <?php $ls = $_POST[‘lastsurvey’]; $rs = $_POST[‘recentstatus’]; $db = new PDO(pgsql:host=localhost;port=5432;dbname=gis_test;user=joe;password=12345"); $sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies, ST_AsGeoJSON(ST_Transform(geom, 4326),5) as geom FROM wildlife_raptor_nests WHERE lastsurvey> :ls AND recentstatus = :rs"”; $sql->execute([“ls”=>$ls, “rs”=>$rs]); echo “<table>”; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { echo “<tr>”; foreach ($row as $field=>$value) { echo “<td>{$value}</td>”; } echo “</tr>”; } echo “</table>”; ?>
  • 173. AJAX - RESPONSE <table…..> <th>……</th> <tr> <td>Rnest_034</td> <td>2011-04-23</td> <td>2015-07-14</td> <td>ACTIVE NEST</td> <td>Red-Tailed Hawk</td> </tr> <tr> <td>Rnest_045</td> <td>2012-05-17</td> <td>2015-07-08</td> <td>ACTIVE NEST</td> <td>Red-Tailed Hawk</td> </tr> </table>
  • 174. AJAX – HTML AND JAVASCRIPT (QUERY_NESTS_AJAX.HTML) <input type="date" id="lastsurvey" value="2015-01-01"><br> <select id="recentstatus"> <option value='ACTIVE NEST'>Active Nest</option> <option value='INACTIVE NEST'>Inactive Nest</option> <option value='FLEDGED NEST'>Fledged Nest</option> </select><br> <button id=“filterSubmit" >Submit</button> <hr><div id=“resultTable></div> <script> $(“#filterSubmit”).click(function(){ $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ $(“#resultTable”).html(response); }}); }); </script>
  • 175. AJAX – HTML AND JAVASCRIPT (QUERY_NESTS_AJAX.HTML) <input type="date" id="lastsurvey" value="2015-01-01"><br> <select id="recentstatus"> <option value='ACTIVE NEST'>Active Nest</option> <option value='INACTIVE NEST'>Inactive Nest</option> <option value='FLEDGED NEST'>Fledged Nest</option> </select><br> <button id=“filterSubmit" >Submit</button> <hr><div id=“resultTable></div> <script> $(“#filterSubmit”).click(function(){ $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ $(“#resultTable”).html(response); }}); }); </script>
  • 176. AJAX – PHP (QUERY_NESTS_AJAX.PHP) <?php $ls = $_POST[‘lastsurvey’]; $rs = $_POST[‘recentstatus’]; $db = new PDO(pgsql:host=localhost;port=5432;dbname=gis_test;user=joe;password=12345"); $sql = $db->prepare(“SELECT nest_id, createdate, lastsurvey, recentstatus, recentspecies, ST_AsGeoJSON(ST_Transform(geom, 4326),5) as geom FROM wildlife_raptor_nests WHERE lastsurvey> :ls AND recentstatus = :rs"”; $sql->execute([“ls”=>$ls, “rs”=>$rs]); echo “<table>”; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { echo “<tr>”; foreach ($row as $field=>$value) { echo “<td>{$value}</td>”; } echo “</tr>”; } echo “</table>”; ?> $features=[]; array_push($features, $row); echo json_encode($features); $row[‘geom’]=json_decode($row[‘geom’]);
  • 177. AJAX - RESPONSE [ { "nest_id":"RNest_291 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-10", "recentstatus":"FLEDGED NEST ", "recentspecies":"Swainsons Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.91081,40.1328] } }, { "nest_id":"RNest_294 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-24", "recentstatus":"FLEDGED NEST ", "recentspecies":"Red-tail Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.80846,40.15926] } } ]
  • 178. AJAX – HTML AND JAVASCRIPT $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ var objResponse = JSON.parse(response); var strResponse = “<table>”; for (var i=0;i<objResponse.length;i++){ strResponse += "<tr>”’ strResponse += “<td>"+objResponse[i].nest_id+"</td>"; strResponse += "<td>"+objResponse[i].createdate+"</td>"; strResponse += "<td>"+objResponse[i].lastsurvey+"</td>"; strResponse += "<td>"+objResponse[i].recentstatus+"</td>"; strResponse += "<td>"+objResponse[i].recentspecies+"</td>"; strResponse += "<td>"+JSON.stringify(objResponse[i].geom)+"</td>; strResponse += “</tr>"; } strResponse += “</table>”; $(“#resultTable”).html(strResponse); }
  • 179. AJAX - RESPONSE [ { "nest_id":"RNest_291 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-10", "recentstatus":"FLEDGED NEST ", "recentspecies":"Swainsons Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.91081,40.1328] } }, { "nest_id":"RNest_294 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-24", "recentstatus":"FLEDGED NEST ", "recentspecies":"Red-tail Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.80846,40.15926] } } ]
  • 180. AJAX - RESPONSE [ { "nest_id":"RNest_291 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-10", "recentstatus":"FLEDGED NEST ", "recentspecies":"Swainsons Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.91081,40.1328] } }, { "nest_id":"RNest_294 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-24", "recentstatus":"FLEDGED NEST ", "recentspecies":"Red-tail Hawk ", "geom":{ "type":"Point", "coordinates":[- 104.80846,40.15926] } } ]
  • 181. GEOJSON – FEATURES AND FEATURECOLLECTIONS {“type”:”Feature”, “geometry”: {“type”: “Point”, “coordinates”:[-108.5, 33.7] }, “properties”: {“species”:”Bald Eagle”, “sex”:”male”, “age”:7 } } {“type”:”FeatureCollection”, “features”: [{“type”:”feature”, “geometry”: {“type”: “Point”, “coordinates”:[-108.5, 33.7] }, “properties”: {“species”:”Bald Eagle”, “sex”:”male”, “age”:7 } }, {“type”:”feature”, “geometry”: {“type”: “Point”, “coordinates”:[-109.1, 32.5] }, “properties”: {“species”:”Golden Eagle”, “sex”:”female”, “age”:2 } }] }
  • 182. AJAX – PHP (QUERY_NESTS_AJAX.PHP) <?php $features=[]; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { $feature=[‘type’=>’Feature’]; $feature[‘geometry’]=$json_decode($row[‘geom’]); unset($row[‘geom’]); $feature[‘properties’]=$row; array_push($features, $feature) } $featureCollection=[‘type’=>’FeatureCollection’, ‘Features’=>$features]; echo json_encode($featureCollection); ?>
  • 183. GEOJSON { "type":“FeatureCollection", "features":[{ "type":“Feature", "geometry":{ "type":"Point", "coordinates":[-104.91081,40.1328] }, "properties":{ "nest_id":"RNest_291 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-10", "recentstatus":"FLEDGED NEST ", "recentspecies":"Swainsons Hawk “ } }, { "type":“Feature", "geometry":{ "type":"Point", "coordinates":[- 104.80846,40.15926] }, "properties":{ “nest_id":"RNest_294 ", "createdate":"2011-04-06", "lastsurvey":"2015-08-24", "recentstatus":"FLEDGED NEST ", "recentspecies":"Red-tail Hawk “ } }] }
  • 184. AJAX – HTML (QUERY_NESTS_AJAX.HTML) <input type="date" id="lastsurvey" value="2015-01-01"><br> <select id="recentstatus"> <option value='ACTIVE NEST'>Active Nest</option> <option value='INACTIVE NEST'>Inactive Nest</option> <option value='FLEDGED NEST'>Fledged Nest</option> </select><br> <button id=“filterSubmit" >Submit</button> <hr><div id=“mapdiv” style=“width:800px;height:600px”></div>
  • 185. AJAX – JAVASCRIPT (QUERY_NESTS_AJAX.HTML) <script> var mymap = L.map('mapdiv') mymap.setView([19.4, -99.1], 11); var backgroundLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png'); mymap.addLayer(backgroundLayer); $(“#filterSubmit”).click(function(){ $.ajax({url:’query_nests_ajax.php’, type :‘POST’, data:{lastsurvey: $(“#lastsurvey).val(), recentstatus:$(“#recentstatus).val()}, success: function(response){ var queryLayer=L.geoJSON(JSON.parse(response)).addTo(mymap); mymap.fitBounds(queryLayer.getBounds()); }}); }); </script>
  • 186. POSTGIS • Adding geospatial functionality to the PostgreSQL database • Standards based – Simple Features for SQL from Open Geospatial Consortium • Spatial functions – calculating distances, areas, conversion • Relationship operators –crosses, contains, within, etc • Spatial operators - intersection, union, difference, buffer, etc • Conversion – GeoJSON, GML, KML • Geography types – storing geometry based on spheroid • Raster operations • Spatial indexing – R-tree over GIST
  • 187. SIMPLE FEATURES FOR SQL - GEOMETRY
  • 188. SIMPLE FEATURES FOR SQL –SPATIAL REFERENCE • Spatial Reference includes • Coordinate system • Geographic • Projected. • Zone • Datum • Single Integer, the SRID • Examples • Lat/Long WGS84 – 4326 • UTM Zone 13N NAD83 – 26913 • www.spatialreference.org
  • 189. SFS - FUNCTIONS • Conversion • ST_AsText • ST_PointFromText • ST_LineFromText • ST_PolygonFromText • Description • ST_SRID • ST_IsEmpty • ST_IsSimple • ST_IsClosed • ST_IsRing • ST_IsValid • ST_GeometryType • Calculations • ST_Distance • ST_Length • ST_Area • Accessing • ST_X • ST_Y • ST_StartPoint • ST_EndPoint • ST_PointN • ST_ExteriorRing • ST_InteriorRingN • ST_GeometryN
  • 190. SFS – SPATIAL ANALYSIS • Relational Operators • ST_Equals • ST_Disjoint • ST_Touches • ST_Within • ST_Contains • ST_Intersects • ST_Crosses • ST_Overlaps • ST_DWithin • Spatial Operators • ST_Intersection • ST_Difference • ST_Union • ST_SymDifference • ST_Buffer • ST_ConvexHull • ST_Transform
  • 191. POSTGIS – BEYOND SFS • Conversion • GeoGSON – ST_AsGeoJSON, ST_GeomFromGeoJSON • KML, GML, EWKT • Geography Types • Based on a spheroid. • Only lat/long WGS84 coordinates
  • 193. POSTGIS – BEYOND SFS • Conversion • GeoGSON – ST_AsgeoJSON, ST_GeomFromGeoJSON • KML, GML • Geography Types • Based on a spheroid. • Only lat/long WGS84 coordinates • Limited functionality • More accurate over large spatial areas. • Raster • Store rasters in the database • Map algebra • Reclass • Resample • Slope, aspect, hillshade
  • 194. POSTGIS – SPATIAL INDEXING • CREATE INDEX pipeline_geom_idx ON pipelines USING GIST (geom); • Based on Bounding Boxes • VACCUM ANALYZE pipelines; • EXPLAIN ANALYZE sql;
  • 195. POSTGIS – LOADING (AND EXPORTING) DATA • Command Line • shp2pgsql/pgsql2shp • ogr2ogr • raster2pgsql • GDAL utilities • GUI • pgShapeLoader • QGIS • DB Manager • Load Raster To PostGIS plug-in • FME - Commercial
  • 196. POSTGIS – EXAMPLES (SINGLE TABLE) • Include the latitude and longitude of the point in the table • SELECT nest_id, recentstatus, ST_Y(geom) as latitude, ST_X(geom) as longitude • Given a lat and long, return all nests within 2 miles • SELECT nest_id, recentstatus FROM raptor_nests WHERE ST_DWithin(ST_FromText(‘POINT(- 99.2314, 19.3451)’,4326), geom, 3218); • Given a lat and long return the 5 closest nests buffered by one mile • SELECT nest_id, recentstatus, ST_Distance(ST_FromText(‘POINT(-99.2314, 19.3451)’,4326), geom) as distance, ST_Buffer(geom, 1609) as buffer FROM raptor_nests ORDER BY distance LIMIT 5; • Given a pipeline table sum up the length of pipelines by category. • SELECT pipline_category, sum(ST_Length(geom)) as total FROM pipelines GROUP BY pipeline_category ORDER BY total DESC • SELECT pipline_category, sum(ST_Area(ST_Buffer(geom, 50))) as total……….
  • 197. POSTGIS – EXAMPLES (MULTIPLE TABLES) • Given a pipeline table and a raptor_nest table display pipelines with an active raptor nest within 1 mile. • SELECT p.project_name, r.nest_id FROM pipeline p JOIN raptor_nests r ON ST_DWithin(p.geom, r.geom, 1609) WHERE r.recentstatus=‘ACTIVE’; • Given an animal home range table and a vegetation table display the vegetation types found in each animals home range • SELECT h.animal_id, v.class FROM home_ranges h JOIN vegetation v ON ST_Intersects(h.geom, v.geom) • Given an animal home range table and a vegetation table display the acres and percent of each animals home range for every vegetation type. • SELECT h.animal_id, v.class, ST_Area(ST_Intersection(h.geom, v.geom))/4045 as acres, ST_Area(ST_Intersection(h.geom, v.geom))/ST_Area(g.geom) as percent FROM home_ranges h JOIN vegetation v ON ST_Intersects(h.geom, v.geom) • SELECT h.animal_id, v.class, sum(ST_Area(ST_Intersection(h.geom, v.geom))/4045) as acres, sum(ST_Area(ST_Intersection(h.geom, v.geom))/ST_Area(h.geom)) as percent FROM home_ranges h JOIN vegetation v ON ST_Intersects(h.geom, v.geom) GROUP BY h.animal, v.class
  • 198. SERVER SIDE EXAMPLE • Modify the Mexico City attraction application we started at the end of the client side section to • Store the attractions data in a PostGIS table • Add the ability for end users to • Add attractions • Modify attractions • Delete attractions • Filter attractions by category • Find the attractions closest to a point clicked on the map.
  • 199. SERVER SIDE EXAMPLE - SETUP 1. Create a new database specific for this application 2. Add the data currently in the GeoJSON data file to the new PostGIS database 3. Add a category field to the attractions table 4. Populate category field for existing data 5. Modify the map to load the attractions via an AJAX call to the database rather than from a file.
  • 200. AJAX – PHP (LOAD_ATTRACTIONS.PHP) <?php $db = new PDO("pgsql:host=localhost;port=5432;dbname=webmap101;user=joe;password=12345"); $sql = $db->query("SELECT id, name, image, web, category, ST_AsGeoJSON(geom,5) as geom FROM cdmx_attractions"; $features=[]; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { $feature=[‘type’=>’Feature’]; $feature[‘geometry’]=$json_decode($row[‘geom’]); unset($row[‘geom’]); $feature[‘properties’]=$row; array_push($features, $feature) } $featureCollection=[‘type’=>’FeatureCollection’, ‘Features’=>$features]; echo json_encode($featureCollection); ?>
  • 201. AJAX – HTML AND JAVASCRIPT var lyrAttractions; $.ajax({url:'load_attractions.php', success: function(response){ if (lyrAttractions) {mymap.removeLayer(lyrAttractions)}; lyrAttractions=L.geoJSON(JSON.parse(response), {pointToLayer:function(feature,latlng){ …….. var strPopup = "<h4>"+feature.properties.name+"</h4><hr>"; strPopup += "<h5>Category: "+feature.properties.category+"</h5>"; strPopup += "<a href='"+feature.properties.web+"' target='blank'>"; strPopup += "<img src='img/"+feature.properties.image+"' width='200px'>"; strPopup += "</a>"; return L.marker(latlng).bindPopup(strPopup); }}).addTo(mymap); mymap.fitBounds(lyrAttractions.getBounds()); });
  • 202. SERVER SIDE EXAMPLE – ADD NEW ATTRACTION • HTML • Modal dialog • Data entry form • Save and Cancel buttons. • CSS • Styling, positioning, and making visible the data entry form. • Bootstrap classes for the buttons and form controls. • JavaScript • Event handlers to respond to map click • Event handler to respond button clicks • Save button will send an AJAX request to the server and process the result. • Cancel Button will simply close the dialog.
  • 203. SERVER SIDE EXAMPLE – ADD NEW ATTRACTION • PHP • Receive the ajax requests • Process into SQL query • Submit to database • Process results
  • 204. SERVER SIDE EXAMPLE – HTML <div id="dlgAttraction" class="modal"> <div class="modal-content col-md-7 col-md-offset-4"> FORM INPUT CONTROLS……… <button id="btnSave" class="btn btn-success">Save</button> <button id="btnCancel" class="btn btn-danger">Cancel</button> </div> </div>
  • 205. SERVER SIDE EXAMPLE – CSS .modal { display: none; z-index: 1000; width: 100%; height: 100%; background-color: rgba(0,0,0,0.4); } .modal-content { padding: 20px; background-color:tan; margin-top: 10%; }
  • 206. SERVER SIDE EXAMPLE – JAVASCRIPT mymap.on('click', function(e){ $("#dlgAttraction").show(); $("#latitude").val(e.latlng.lat.toFixed(5)); $("#longitude").val(e.latlng.lng.toFixed(5)); $("#idDisplay").html("New"); }); $("#btnCancel").click(function(){ $("#dlgAttraction").hide(); }); $("#btnSave").click(function(){ $.ajax({url:'add_attraction.php', type:'POST', data:{name:$("#name").val(), image:$("#image").val(), web:$("#website").val(), category:$("#category").val(), latitude:$("#latitude").val(), longitude:$("#longitude").val() }, success:function(response){ alert(response); }}); });
  • 207. SERVER SIDE EXAMPLE – PHP if (isset($_POST['name'])) { $name=$_POST['name']; } else { $name="NA"; } ……………….. $db = new PDO('pgsql:host=localhost;port=5432;dbname=webmap101;', 'joe', '12345'); $sql = $db->prepare("INSERT INTO cdmx_attractions (name, image, web, category, geom) VALUES (:nm, :im, :wb, :ct, ST_SetSRID(ST_MakePoint(:lng, :lat), 4326))"); $params = ["nm"=>$name, "im"=>$image, "wb"=>$web, "ct"=>$category, "lng"=>$longitude, "lat"=>$latitude]; if ($sql->execute($params)) { echo "{$name} succesfully added"; } else { echo var_dump($sql->errorInfo()); };
  • 208. SERVER SIDE EXAMPLE • Modify the Mexico City attraction application we started at the end of the client side section to • Store the attractions data in a PostGIS table • Add the ability for end users to • Add attractions • Modify attractions • Delete attractions
  • 209. SERVER SIDE EXAMPLE – EDIT/DELETE ATTRACTION • HTML • CSS • JavaScript • Add button in popup to open edit dialog and populate form. • Handle save edits and delete buttons in dialog.
  • 210. SERVER SIDE EXAMPLE – EDIT/DELETE ATTRACTION • PHP • Receive the ajax requests • Process into SQL query • Submit to database • Process results • update_attraction.php • delete_attraction.php • find_attraction.php
  • 211. SERVER SIDE EXAMPLE – HTML <div id="dlgAttraction" class="modal"> <div class="modal-content col-md-7 col-md-offset-4"> FORM INPUT CONTROLS……… <button id="btnSave" class="btn btn-success">Save</button> <button id="btnCancel" class="btn btn-danger">Cancel</button> </div> </div>
  • 212. SERVER SIDE EXAMPLE – CSS .modal { display: none; z-index: 1000; width: 100%; height: 100%; background-color: rgba(0,0,0,0.4); } .modal-content { padding: 20px; background-color:tan; margin-top: 10%; }
  • 213. SERVER SIDE EXAMPLE – JAVASCRIPT mymap.on('click', function(e){ $("#dlgAttraction").show(); $("#latitude").val(e.latlng.lat.toFixed(5)); $("#longitude").val(e.latlng.lng.toFixed(5)); $("#idDisplay").html("New"); }); $("#btnCancel").click(function(){ $("#dlgAttraction").hide(); }); $("#btnSave").click(function(){ $.ajax({url:'add_attraction.php', type:'POST', data:{name:$("#name").val(), image:$("#image").val(), web:$("#website").val(), category:$("#category").val(), latitude:$("#latitude").val(), longitude:$("#longitude").val() }, success:function(response){ alert(response); }}); });