SlideShare a Scribd company logo
Application Development with
Open Source Libraries
Allan Laframboise
alaframboise.github.com
@AL_Laframboise
esri.github.com
Terraformer
Geodata JavaScript Library
Terraformer
§  Open
§  Key

source geometry and geodata library

features

§  Geometry

format conversions (GeoJSON)
§  Geometry operations
§  Coordinate system conversion
§  Store and access data
§  Node.js

and client-side JavaScript

github.com/Esri/Terraformer
Terraformer Modules
§  Terraformer
§  terraformer-arcgis-parser
§  terraformer-wkt-parser
§  terraformer-geostore
§  terraformer-geostore-rtree
§  terraformer-geostore-memory
§  terraformer-geostore-localstorage
Terraformer: Geometry and Features
terraformer.js

// create a typed primitive from GeoJSON!
var point = new Terraformer.Primitive({ "type": "Point",
"coordinates": [ 100, 1 ] });!
!
// create a Geometry from coordinates or GeoJSON !
var point = new Terraformer.Point( [ 10, 10 ] );!
var ls = new Terraformer.LineString([ [ 10, 10 ], [ 20, 20 ]]);!
var poly = new Terraformer.Polygon([!
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0]]]);!
var circle = new Terraformer.Circle([-122.6764, 45.5165], 1000);!
!
// creates a feature from a valid GeoJSON Object!
var feature = new Terraformer.Feature({"type": "Point",
"coordinates": [ 10, 10 ]}, "properties": {"prop0": "value0"});!
!
!
!
Terraformer: Geometric Operations
terraformer.js

// to Web Mercator and WGS84!
primitive.toMercator();!
primitive.toGeographic();!
!
var box = poly.bbox;!
var ev = polygon.envelope();!
!
multi.addPoint([ 10, 10 ]);!
multi.insertPoint([ 10, 10 ],1);!
multi.removePoint(1);!
multi.get(1);!
!
polygon1.within(polygon2);!
polygon1.intersects(line);!
polygon1.contains(point);!
circle.contains(point);!
!
!
!
!
Terraformer: WKT Conversion
terraformer-wkt-parser.js

// take a WKT representation and convert it into a primative !
<script>!
var primitive = Terraformer.WKT.parse('LINESTRING (30 10, 10 30, 40
40)');!
</script>!
!
// take a primitive and convert it into a WKT representation!
var polygon = Terraformer.WKT.convert(!
{!
"type": "Polygon",!
"coordinates": [!
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0],
[100.0, 0.0] ],!
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8],
[100.2, 0.2] ]!
]!
}!
);!
Terraformer: ArcGIS JSON to GeoJSON
terraformer-arcgis-parser.js

<script>!
// take ArcGIS JSON and convert to Primitive or GeoJSON!
!var primitive = Terraformer.ArcGIS.parse({!
x:"-122.6764",!
y:"45.5165",!
spatialReference: {!
wkid: 4326!
}!
});!
!
// take a Primitive or GeoJSON and convert it to ArcGIS JSON!
var point = Terraformer.ArcGIS.convert({!
"type": "Point",!
"coordinates": [45.5165, -122.6764]!
});!
</script>!
Terraformer: GeoStore
terraformer-geostore.js and terraformer-rtree.js

// In-memory geostore. Requires id property.!
var store = new Terraformer.GeoStore({!
store: new Terraformer.GeoStore.Memory(),!
index: new Terraformer.RTree()!
});!
!
store.add(geojson, function(err, resp){!
// callback!
});!
!
store.update(geojson, function(err, resp){!
// callback!
});!
!
store.contains(geojson, function(err, resp){!
// callback !
});!
!
Terraformer
Geoservices-js
ArcGIS REST Service API
Geoservices-js
§  Open

source Geoservices REST API

§  Communicate
§  Key

with ArcGIS REST services

features

§  Light-weight,

pure JavaScript
§  Browser and Node.js
§  Built on the Geoservices REST specification
github.com/Esri/geoservices-js
Geoservices-js: Getting Started
geoservices.js

// Browser!
<script src="browser/geoservices.js"></script>!
<script>!
var client = new Geoservices();!
</script>!
!
!
// Node.js!
var Geoservices = require('geoservices');!
var client = new Geoservices();!
Geoservices-js: FeatureService Info
geoservices.js

// Define parameters for a feature service!
var params = {!
catalog: 'http://server6.arcgisonline.com/arcgis/rest/services',!
service: 'Census',!
type: 'MapServer',!
layer: 3!
};!
!
// Make request to the service !
client.FeatureService( params , function (err, result) {!
if (err) {!
console.error("ERROR: " + err);!
} else {!
console.log("Got the FeatureService Metadata: ", result );!
}!
});!
Geoservices-js: FeatureService Query
geoservices.js

// Define query parameters!
var query_params = {!
f: 'json',!
returnGeometry: true,!
where: '1=1',!
outSR: '4326'!
};!
!
// Request features!
var fs = client.FeatureService( params , function(err, data){!
fs.query( query_params, function( err, result ){!
if (err) {!
console.error("ERROR: " + err);!
} else {!
console.log("Features: ", result );!
}!
});!
});!
Geoservices-js: Geocoding
geoservices.js

// Geosearch!
client.geocode({ text: "920 SW 3rd Ave, Portland, OR 97201" },
function (err, result) {!
if (!err) {!
!console.log(result.locations[0].feature.geometry.y + ", " !
!result.locations[0].feature.geometry.x);!
}!
});!
!
// Reverse-geocoding!
client.geocode.reverse({ location: "-122.67633,45.51673" }, !
function (err, result) {!
if (!err){!
console.log(result.address.Address + ", " + result.address.City);
!
}!
});!
Geoservices-js: Batch Geocoding
geoservices.js

// Simple authentication only!!
var client = new Geoservices();!
client.authentication.authenticate('username', 'password', { /*
optional options */ }, callback);!
!
// Batch geocoding!
var batch = new client.geocode.Batch();!
!
// add addresses to geocode!
batch.geocode("123 Fake Street");!
batch.geocode("456 Other Street");!
!
// run the batch!
batch.run(function (err, results) {!
console.dir(results);!
});!
geoservices-js
ArcGIS Services
Adaptors
Node.js REST Implementations
Koop/node-geoservices-adaptor
§  Open

source ArcGIS REST provider

§  Expose

“your” service as an ArcGIS service

§  Node.js

implementation

§  Can

consume “any” service

www.github.com/esri/Koop
www.github.com/esri/node-geoservices-adaptor
Koop: From the Client-side
§  Consumable
§  ArcGIS
§  Store

by different ArcGIS clients

map viewer

as ArcGIS Online “items”

§  Follows

the Geoservices REST specification

§  Examples:

rest-api

resources.arcgis.com/en/help/arcgis-
Koop: GitHub Provider Example
MVC
// routes/index.js!
module.exports {!
'get /github/:user/:repo/FeatureServer/:layer/:method': {!
controller: 'github',!
action: 'featureservice'!
},!
…!
// model/github.js!
var Geohub = require('geohub');!
module.exports = {!
find: function( user, repo, file, options, callback ){!
!var key = [ user, repo, file].join('/'),!
!type = 'Github’;!
…!
// controller/index.js!
module.exports = {!
getRepo: function(req, res){!
var _send = function( err, data ){!
…!
koop
node-geoservices-adaptor
Esri-Leaflet
ArcGIS Services Plug-in
Leaflet
§  Open
§  Pure

source mapping library

JavaScript – 31kb

§  Simple,
§  Many

easy to use, mobile friendly

plug-ins

www.leafletjs.com
Leaflet Functionality
What’s there?

What’s missing?

§  Draw

§  Basemaps

§  Add

pop-ups

§  Read
§  Add

map tiles
GeoJSON

graphics (layers)

§  Symbolize
§  Control
§  Add

features

layers

other controls

§  Plugins…

§  ArcGIS

support
§  Basemaps
§  Feature Services
§  Other Services
§  Widgets
§  Webmaps

§  Cloud

storage
Esri-Leaflet
ArcGIS Online Services Plug-in

§  Open

source plug-in for ArcGIS Online services

§  Extends

L.class and namespace = L.esri.xxx

§  Dependence

on Terraformer
Esri-Leaflet: Getting Started
Reference L.esri.xxx Library
<!DOCTYPE html>!
<html>!
<head>!
<title>Esri Leaflet</title>!
<link rel="stylesheet" href="/the/path/to/leaflet.css" />
!
!<style>!
html, body, #map { width: 100%; height: 100%; }!
</style>!
!<script src="/the/path/to/leaflet.js"></script>!
<script src="/the/path/to/esri-leaflet.min.js"></script>!
</head>!
<body>!
<div id="map"></div>!
<script>!
!var map = L.map('map');!
!
!L.esri.basemapLayer("Streets").addTo(map);!
!
!map.setView([38.97993, -104.9794], 12);!
!</script>!
</body>!
</html>!
Esri-Leaflet: ArcGIS Basemaps
L.esri.BasemapLayer = L.TileLayer.extend({…
// Load an ArcGIS basemap!
var map = L.map('map').setView([37.75,-122.45], 12);!
L.esri.basemapLayer("Topographic").addTo(map);!
!
// Supported basemap types!
//L.esri.basemapLayer("Streets").addTo(map);!
//L.esri.basemapLayer("Oceans").addTo(map);!
//L.esri.basemapLayer("NationalGeographic").addTo(map);!
//L.esri.basemapLayer("Gray").addTo(map);!
//L.esri.basemapLayer("GrayLabels").addTo(map);!
//L.esri.basemapLayer("Imagery").addTo(map);!
//L.esri.basemapLayer("ImageryLabels").addTo(map);!
!
!
!
!
Esri-Leaflet: ArcGIS FeatureServices
L.esri.FeatureLayer = L.GeoJSON.extend({…
// Access ArcGIS FeatureService!
var map = L.map('map').setView([45.52963623111275,
-122.67389774322508], 12);!
L.esri.basemapLayer("Topographic").addTo(map);!
!
var url = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/
arcgis/rest/services/stops/FeatureServer/0’!
!
L.esri.featureLayer(url);!
Esri-Leaflet: Symbols
// Create FeatureLayer and define styles!
L.esri.featureLayer(url, {!
style: function (feature) {!
return getStyle(feature);!
}).addTo(map);!
!
function getStyle(feature) {!
var c,o = 0.5;!
switch (feature.properties.BIKEMODE) {!
case "Low traffic through street":!
c = "#007D7D";!
break;!
case "Bike boulevard":!
c = "#00FF3C";!
break;!
! …!
}!
return {color: c, opacity: o};!
}!
Esri-Leaflet: Popups
// Create FeatureLayer and bind to popup!
L.esri.featureLayer(featureServiceUrl, {!
onEachFeature: createPopup!
}).addTo(map);!
!
// Define popup content - show all fields and values!
function createPopup(geojson,layer) {!
if (geojson.properties) {!
var popupText = "<div style='max-height:200px;'>";!
for (prop in geojson.properties) {!
var val = geojson.properties[prop];!
if (val) {!
popupText += "<b>" + prop + "</b>: " + val + "<br>";!
}!
}!
popupText += "</div>";!
layer.bindPopup(popupText);!
}!
}!
Esri-Leaflet: DynamicMapLayer
// ArcGIS Server Dynamic Map Service - Hurricane Tracks!
dynLayer = L.esri.dynamicMapLayer("http://
tmservices1.esri.com/arcgis/rest/services/LiveFeeds/
Hurricane_Recent/MapServer", { layers:[0,1] });!
!
// Identifying Dynamic Map Service Features!
map.on("click", function(e) {!
!dynLayer.identify(e.latlng, {!
!
!layerDefs: {!
0: "STORMNAME='ANDREA'",!
1: "STORMNAME='ANDREA'"!
}!
}, function(data) {!
!
!
!popupText = "<center><b>" +!
data.results[0].attributes.STORMNAME + "</b><br>" +!
data.results[0].attributes.STORMTYPE + "</center>”;!
!
!L.popup().setLatLng(e.latlng).setContent
!
!
!
!
!(popupText).openOn(map);!
!}!
!});!
});
!
Esri-Leaflet: ClusterFeatureLayer
esri-leaflet.js + clustered-feature-layer.js
// Reference cluster plug-in and esri feature layer!
<script src="lib/markercluster/leaflet.markercluster.js"></
script>!
!
<script src="lib/esri-leaflet/extras/clustered-featurelayer.js"></script>!
!
// Create and add a new feature cluster layer!
var fl = L.esri.clusteredFeatureLayer("http://
services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/
stops/FeatureServer/0", {!
!cluster: new L.MarkerClusterGroup(),!
!
!onEachMarker: function(geojson, marker) {!
marker.bindPopup("<h3>"+!
!
!
!geojson.properties.stop_name+"</h3><p>!
!
!
!Stop ID: "+geojson.properties.stop_id+"</p><p>”
!
!
!+geojson.properties.stop_desc+"</p>")!
}!
}).addTo(map);!
Esri-Leaflet: FeatureService Query
esri-leaflet.js + geoservices.js
// Access feature service directly and query (geoservices.js)!
var fs = new GeoServices.FeatureService({url:featureServiceUrl},
function (err, results) {!
!var queryOptions = document.getElementById("query");!
!var query = queryOptions.text;!
!var queryEnvelope = !
JSON.stringify(L.esri.Util.boundsToExtent(map.getBounds()));!
// Build query parameters !
!var params = {!
!f:"json”, where: query,!
!
!geometry: queryEnvelope, !
!
!spatialRel: "esriSpatialRelIntersects”,!
!returnGeometry:true, outSR: 4326, outFields:"*"!
};!
// Query the feature service!
fs.query(params, function (err, results) {!
!
!addFeaturesToMap(results); // Manual!
!}!
}!
Esri-Leaflet: Geocoding
esri-leaflet.js + geoservices.js
// Reference geoservices.js!
<script src="lib/geoservices/geoservices.js"></script>!
…!
var GeoServices = new Geoservices.Geoservices({});!
var options = {!
text:searchString,!
outFields: "Loc_name,Place_addr",!
bbox: mapBounds }!
!
// Add geocodes to map!
GeoServices.geocode(options, function (err,result) {!
!for (var i = 0; i < result.locations.length; i++) {!
var place = result.locations[i];!
var pt = new L.LatLng(place.feature.geometry.y,
place.feature.geometry.x);!
!
!var marker = L.marker(pt).bindPopup(place.name + "</
br>" + place.feature.attributes.Place_addr);!
layerPlaces.addLayer(marker);!
}!
}!
!
Other stuff
§  Retina

support (sort of…)

§  Layers
§  TiledMapLayers

§  Controls
§  esri-leaflet-geocoder
Esri-Leaflet: Holly Grail?
§  Widgets
§  Symbols
§  Renderers
§  Editing
§  Geometry

operations and types

§  Webmaps
§  Accessing
§  …

all ArcGIS Services
esri-leaflet
OAuth 2.0
Authenticating ArcGIS Apps
What is OAuth 2.0?
§  OAuth

2.0 is a framework for allowing apps to
securely access data on behalf of users

§  A more

secure alternative to asking for a user’s
password
Types of OAuth
§  Client-side
§  Best

for browser-based applications
§  No client_secret required, so it’s safe to use in
Javascript apps
§  Server-side
§  Requires client_secret,

so cannot be used from
a Javascript app without a proxy
Simple OAuth 2.0 Example
§  Use

the “implicit” grant type to generate an
access token directly in the browser

§  No

server-side code required

§  Browser

makes API calls directly to secure
services with the access token
Step 1: ArcGIS Developer Subscription
§  Sign

up for a subscription

§  Register
§  Enable

your apps

for OAuth
Registering your apps
Credentials

Redirect URLs
Step 2: Create a login page
https://www.arcgis.com/sharing/oauth2/authorize?
&client_id=YOUR_CLIENT_ID&response_type=token
&redirect_uri=REDIRECT_URI
var clientID = 's5R3ZF4K3GILBqsI';
var url = "https://www.arcgis.com/sharing/oauth2/authorize?client_id=";
var uri = encodeURIComponent(window.location.origin)+"%2Foauth
%2Fcallback.html”;

function startAGOOAuth() {
window.open(url + clientID
&redirect_uri=” + uri,
+"&response_type=token&expiration=20160
"oauth-window", "height=400,width=600");
}
The authorization page
Step 3: Acquire a token
On success, user is redirected back to your site with the
access token in the fragment
https://example.com/auth#token=ACCESS_TOKEN

On error, user is redirected back to your site with error
code
https://example.com/auth#error=access_denied
Using the Access Token
§  Parse

out the access token

§  Make API

requests using the token

var accessToken;!
!
window.oauthCallback = function(token) {!
accessToken = token;!
}!
!
// Access services with token!
L.esri.get("http://route.arcgis.com/arcgis/rest/services!
World/Route/NAServer/Route_World/solve", {!
token: accessToken,!
stops: s.lng+","+s.lat+"; "+e.lng+","+e.lat,!
outputLines: 'esriNAOutputLineTrueShape'!
}, function(response){!
!…!
esri-leaflet/directions
Licensing
ArcGIS Developer Subscriptions
Licensing
§ Free ArcGIS

Developer Subscription

§  Testing

and development
§  Public deployments (non-commercial)
§  50 credits
§  Paid ArcGIS

Developer or ArcGIS Organization

Subscription
§  Private

deployments
§  Commercial deployments (generates revenue)
alaframboise.github.io
Final Notes
§  Terraformer
§  Geoservices-js
§  Koop/node-geoservices-adaptor
§  Esri-Leaflet
§  OAuth
§  Licensing

Real value in Open Source libraries!
Application devevelopment with open source libraries

More Related Content

What's hot

Oracle ADF Mobile OGh (Oracle User Group Netherlands)
Oracle ADF Mobile OGh (Oracle User Group Netherlands)Oracle ADF Mobile OGh (Oracle User Group Netherlands)
Oracle ADF Mobile OGh (Oracle User Group Netherlands)
Luc Bors
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on Rails
RORLAB
 
Put a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going FastPut a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going FastOSCON Byrum
 
Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsColdFusionConference
 
ADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guideADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guide
Luc Bors
 
Building API in the cloud using Azure Functions
Building API in the cloud using Azure FunctionsBuilding API in the cloud using Azure Functions
Building API in the cloud using Azure Functions
Aleksandar Bozinovski
 

What's hot (6)

Oracle ADF Mobile OGh (Oracle User Group Netherlands)
Oracle ADF Mobile OGh (Oracle User Group Netherlands)Oracle ADF Mobile OGh (Oracle User Group Netherlands)
Oracle ADF Mobile OGh (Oracle User Group Netherlands)
 
Asset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on RailsAsset Pipeline in Ruby on Rails
Asset Pipeline in Ruby on Rails
 
Put a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going FastPut a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going Fast
 
Emberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applicationsEmberjs building-ambitious-web-applications
Emberjs building-ambitious-web-applications
 
ADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guideADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guide
 
Building API in the cloud using Azure Functions
Building API in the cloud using Azure FunctionsBuilding API in the cloud using Azure Functions
Building API in the cloud using Azure Functions
 

Similar to Application devevelopment with open source libraries

Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
Aaron Stannard
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Rafael Soto
 
OSCON july 2011
OSCON july 2011OSCON july 2011
OSCON july 2011chelm
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
Jared Erickson
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
Andrew Rota
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}.toster
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by expressShawn Meng
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Word Play in the Digital Age: Building Text Bots with Tracery
Word Play in the Digital Age: Building Text Bots with TraceryWord Play in the Digital Age: Building Text Bots with Tracery
Word Play in the Digital Age: Building Text Bots with Tracery
Sarah Sexton
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Geo servershell
Geo servershellGeo servershell
Geo servershell
Jared Erickson
 
UX Design for Developers
UX Design for DevelopersUX Design for Developers
UX Design for Developers
Frank Garofalo
 
Getting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot FrameworkGetting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot Framework
Sarah Sexton
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDB
ArangoDB Database
 
Velocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web appsVelocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web apps
andrewsmatt
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
dion
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
Takahiro Kobaru
 

Similar to Application devevelopment with open source libraries (20)

Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011
 
OSCON july 2011
OSCON july 2011OSCON july 2011
OSCON july 2011
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Word Play in the Digital Age: Building Text Bots with Tracery
Word Play in the Digital Age: Building Text Bots with TraceryWord Play in the Digital Age: Building Text Bots with Tracery
Word Play in the Digital Age: Building Text Bots with Tracery
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Geo servershell
Geo servershellGeo servershell
Geo servershell
 
UX Design for Developers
UX Design for DevelopersUX Design for Developers
UX Design for Developers
 
Getting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot FrameworkGetting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot Framework
 
NodeJS
NodeJSNodeJS
NodeJS
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDB
 
Velocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web appsVelocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web apps
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってる
 

More from Allan Laframboise

Esri Map App Builders
Esri Map App BuildersEsri Map App Builders
Esri Map App Builders
Allan Laframboise
 
Esri open source projects on GitHub
Esri open source projects on GitHubEsri open source projects on GitHub
Esri open source projects on GitHub
Allan Laframboise
 
Nutrition and Race Planning for Mountain Bikers
Nutrition and Race Planning for Mountain BikersNutrition and Race Planning for Mountain Bikers
Nutrition and Race Planning for Mountain Bikers
Allan Laframboise
 
UX Considerations for Touch Mapping Apps
UX Considerations for Touch Mapping AppsUX Considerations for Touch Mapping Apps
UX Considerations for Touch Mapping AppsAllan Laframboise
 
Building ArcGIS Mobile Solutions in the Cloud
Building ArcGIS Mobile Solutions in the CloudBuilding ArcGIS Mobile Solutions in the Cloud
Building ArcGIS Mobile Solutions in the Cloud
Allan Laframboise
 
Live on everest
Live on everestLive on everest
Live on everest
Allan Laframboise
 
Navteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POINavteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POI
Allan Laframboise
 
Geo services, social media and gis applications - Live on Everest
Geo services, social media and gis applications - Live on EverestGeo services, social media and gis applications - Live on Everest
Geo services, social media and gis applications - Live on EverestAllan Laframboise
 
Where are you with gis and geolocation
Where are you with gis and geolocationWhere are you with gis and geolocation
Where are you with gis and geolocation
Allan Laframboise
 
Gis & Social Media Integration
Gis & Social Media IntegrationGis & Social Media Integration
Gis & Social Media Integration
Allan Laframboise
 
Social #WebApps - Ideas for developing GIS applications that are socially a ”...
Social #WebApps - Ideas for developing GIS applications that are socially a ”...Social #WebApps - Ideas for developing GIS applications that are socially a ”...
Social #WebApps - Ideas for developing GIS applications that are socially a ”...
Allan Laframboise
 
What Is GIS?
What Is GIS?What Is GIS?
What Is GIS?
Allan Laframboise
 
GeoWeb Community Development: How Web 2.0 are you?
GeoWeb Community Development: How Web 2.0 are you?GeoWeb Community Development: How Web 2.0 are you?
GeoWeb Community Development: How Web 2.0 are you?
Allan Laframboise
 

More from Allan Laframboise (13)

Esri Map App Builders
Esri Map App BuildersEsri Map App Builders
Esri Map App Builders
 
Esri open source projects on GitHub
Esri open source projects on GitHubEsri open source projects on GitHub
Esri open source projects on GitHub
 
Nutrition and Race Planning for Mountain Bikers
Nutrition and Race Planning for Mountain BikersNutrition and Race Planning for Mountain Bikers
Nutrition and Race Planning for Mountain Bikers
 
UX Considerations for Touch Mapping Apps
UX Considerations for Touch Mapping AppsUX Considerations for Touch Mapping Apps
UX Considerations for Touch Mapping Apps
 
Building ArcGIS Mobile Solutions in the Cloud
Building ArcGIS Mobile Solutions in the CloudBuilding ArcGIS Mobile Solutions in the Cloud
Building ArcGIS Mobile Solutions in the Cloud
 
Live on everest
Live on everestLive on everest
Live on everest
 
Navteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POINavteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POI
 
Geo services, social media and gis applications - Live on Everest
Geo services, social media and gis applications - Live on EverestGeo services, social media and gis applications - Live on Everest
Geo services, social media and gis applications - Live on Everest
 
Where are you with gis and geolocation
Where are you with gis and geolocationWhere are you with gis and geolocation
Where are you with gis and geolocation
 
Gis & Social Media Integration
Gis & Social Media IntegrationGis & Social Media Integration
Gis & Social Media Integration
 
Social #WebApps - Ideas for developing GIS applications that are socially a ”...
Social #WebApps - Ideas for developing GIS applications that are socially a ”...Social #WebApps - Ideas for developing GIS applications that are socially a ”...
Social #WebApps - Ideas for developing GIS applications that are socially a ”...
 
What Is GIS?
What Is GIS?What Is GIS?
What Is GIS?
 
GeoWeb Community Development: How Web 2.0 are you?
GeoWeb Community Development: How Web 2.0 are you?GeoWeb Community Development: How Web 2.0 are you?
GeoWeb Community Development: How Web 2.0 are you?
 

Recently uploaded

Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Zilliz
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
Pixlogix Infotech
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 

Recently uploaded (20)

Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 

Application devevelopment with open source libraries

  • 1. Application Development with Open Source Libraries Allan Laframboise alaframboise.github.com @AL_Laframboise
  • 2.
  • 5. Terraformer §  Open §  Key source geometry and geodata library features §  Geometry format conversions (GeoJSON) §  Geometry operations §  Coordinate system conversion §  Store and access data §  Node.js and client-side JavaScript github.com/Esri/Terraformer
  • 6. Terraformer Modules §  Terraformer §  terraformer-arcgis-parser §  terraformer-wkt-parser §  terraformer-geostore §  terraformer-geostore-rtree §  terraformer-geostore-memory §  terraformer-geostore-localstorage
  • 7. Terraformer: Geometry and Features terraformer.js // create a typed primitive from GeoJSON! var point = new Terraformer.Primitive({ "type": "Point", "coordinates": [ 100, 1 ] });! ! // create a Geometry from coordinates or GeoJSON ! var point = new Terraformer.Point( [ 10, 10 ] );! var ls = new Terraformer.LineString([ [ 10, 10 ], [ 20, 20 ]]);! var poly = new Terraformer.Polygon([! [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0]]]);! var circle = new Terraformer.Circle([-122.6764, 45.5165], 1000);! ! // creates a feature from a valid GeoJSON Object! var feature = new Terraformer.Feature({"type": "Point", "coordinates": [ 10, 10 ]}, "properties": {"prop0": "value0"});! ! ! !
  • 8. Terraformer: Geometric Operations terraformer.js // to Web Mercator and WGS84! primitive.toMercator();! primitive.toGeographic();! ! var box = poly.bbox;! var ev = polygon.envelope();! ! multi.addPoint([ 10, 10 ]);! multi.insertPoint([ 10, 10 ],1);! multi.removePoint(1);! multi.get(1);! ! polygon1.within(polygon2);! polygon1.intersects(line);! polygon1.contains(point);! circle.contains(point);! ! ! ! !
  • 9. Terraformer: WKT Conversion terraformer-wkt-parser.js // take a WKT representation and convert it into a primative ! <script>! var primitive = Terraformer.WKT.parse('LINESTRING (30 10, 10 30, 40 40)');! </script>! ! // take a primitive and convert it into a WKT representation! var polygon = Terraformer.WKT.convert(! {! "type": "Polygon",! "coordinates": [! [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],! [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]! ]! }! );!
  • 10. Terraformer: ArcGIS JSON to GeoJSON terraformer-arcgis-parser.js <script>! // take ArcGIS JSON and convert to Primitive or GeoJSON! !var primitive = Terraformer.ArcGIS.parse({! x:"-122.6764",! y:"45.5165",! spatialReference: {! wkid: 4326! }! });! ! // take a Primitive or GeoJSON and convert it to ArcGIS JSON! var point = Terraformer.ArcGIS.convert({! "type": "Point",! "coordinates": [45.5165, -122.6764]! });! </script>!
  • 11. Terraformer: GeoStore terraformer-geostore.js and terraformer-rtree.js // In-memory geostore. Requires id property.! var store = new Terraformer.GeoStore({! store: new Terraformer.GeoStore.Memory(),! index: new Terraformer.RTree()! });! ! store.add(geojson, function(err, resp){! // callback! });! ! store.update(geojson, function(err, resp){! // callback! });! ! store.contains(geojson, function(err, resp){! // callback ! });! !
  • 14. Geoservices-js §  Open source Geoservices REST API §  Communicate §  Key with ArcGIS REST services features §  Light-weight, pure JavaScript §  Browser and Node.js §  Built on the Geoservices REST specification github.com/Esri/geoservices-js
  • 15. Geoservices-js: Getting Started geoservices.js // Browser! <script src="browser/geoservices.js"></script>! <script>! var client = new Geoservices();! </script>! ! ! // Node.js! var Geoservices = require('geoservices');! var client = new Geoservices();!
  • 16. Geoservices-js: FeatureService Info geoservices.js // Define parameters for a feature service! var params = {! catalog: 'http://server6.arcgisonline.com/arcgis/rest/services',! service: 'Census',! type: 'MapServer',! layer: 3! };! ! // Make request to the service ! client.FeatureService( params , function (err, result) {! if (err) {! console.error("ERROR: " + err);! } else {! console.log("Got the FeatureService Metadata: ", result );! }! });!
  • 17. Geoservices-js: FeatureService Query geoservices.js // Define query parameters! var query_params = {! f: 'json',! returnGeometry: true,! where: '1=1',! outSR: '4326'! };! ! // Request features! var fs = client.FeatureService( params , function(err, data){! fs.query( query_params, function( err, result ){! if (err) {! console.error("ERROR: " + err);! } else {! console.log("Features: ", result );! }! });! });!
  • 18. Geoservices-js: Geocoding geoservices.js // Geosearch! client.geocode({ text: "920 SW 3rd Ave, Portland, OR 97201" }, function (err, result) {! if (!err) {! !console.log(result.locations[0].feature.geometry.y + ", " ! !result.locations[0].feature.geometry.x);! }! });! ! // Reverse-geocoding! client.geocode.reverse({ location: "-122.67633,45.51673" }, ! function (err, result) {! if (!err){! console.log(result.address.Address + ", " + result.address.City); ! }! });!
  • 19. Geoservices-js: Batch Geocoding geoservices.js // Simple authentication only!! var client = new Geoservices();! client.authentication.authenticate('username', 'password', { /* optional options */ }, callback);! ! // Batch geocoding! var batch = new client.geocode.Batch();! ! // add addresses to geocode! batch.geocode("123 Fake Street");! batch.geocode("456 Other Street");! ! // run the batch! batch.run(function (err, results) {! console.dir(results);! });!
  • 22. Koop/node-geoservices-adaptor §  Open source ArcGIS REST provider §  Expose “your” service as an ArcGIS service §  Node.js implementation §  Can consume “any” service www.github.com/esri/Koop www.github.com/esri/node-geoservices-adaptor
  • 23. Koop: From the Client-side §  Consumable §  ArcGIS §  Store by different ArcGIS clients map viewer as ArcGIS Online “items” §  Follows the Geoservices REST specification §  Examples: rest-api resources.arcgis.com/en/help/arcgis-
  • 24. Koop: GitHub Provider Example MVC // routes/index.js! module.exports {! 'get /github/:user/:repo/FeatureServer/:layer/:method': {! controller: 'github',! action: 'featureservice'! },! …! // model/github.js! var Geohub = require('geohub');! module.exports = {! find: function( user, repo, file, options, callback ){! !var key = [ user, repo, file].join('/'),! !type = 'Github’;! …! // controller/index.js! module.exports = {! getRepo: function(req, res){! var _send = function( err, data ){! …!
  • 27. Leaflet §  Open §  Pure source mapping library JavaScript – 31kb §  Simple, §  Many easy to use, mobile friendly plug-ins www.leafletjs.com
  • 28. Leaflet Functionality What’s there? What’s missing? §  Draw §  Basemaps §  Add pop-ups §  Read §  Add map tiles GeoJSON graphics (layers) §  Symbolize §  Control §  Add features layers other controls §  Plugins… §  ArcGIS support §  Basemaps §  Feature Services §  Other Services §  Widgets §  Webmaps §  Cloud storage
  • 29. Esri-Leaflet ArcGIS Online Services Plug-in §  Open source plug-in for ArcGIS Online services §  Extends L.class and namespace = L.esri.xxx §  Dependence on Terraformer
  • 30. Esri-Leaflet: Getting Started Reference L.esri.xxx Library <!DOCTYPE html>! <html>! <head>! <title>Esri Leaflet</title>! <link rel="stylesheet" href="/the/path/to/leaflet.css" /> ! !<style>! html, body, #map { width: 100%; height: 100%; }! </style>! !<script src="/the/path/to/leaflet.js"></script>! <script src="/the/path/to/esri-leaflet.min.js"></script>! </head>! <body>! <div id="map"></div>! <script>! !var map = L.map('map');! ! !L.esri.basemapLayer("Streets").addTo(map);! ! !map.setView([38.97993, -104.9794], 12);! !</script>! </body>! </html>!
  • 31. Esri-Leaflet: ArcGIS Basemaps L.esri.BasemapLayer = L.TileLayer.extend({… // Load an ArcGIS basemap! var map = L.map('map').setView([37.75,-122.45], 12);! L.esri.basemapLayer("Topographic").addTo(map);! ! // Supported basemap types! //L.esri.basemapLayer("Streets").addTo(map);! //L.esri.basemapLayer("Oceans").addTo(map);! //L.esri.basemapLayer("NationalGeographic").addTo(map);! //L.esri.basemapLayer("Gray").addTo(map);! //L.esri.basemapLayer("GrayLabels").addTo(map);! //L.esri.basemapLayer("Imagery").addTo(map);! //L.esri.basemapLayer("ImageryLabels").addTo(map);! ! ! ! !
  • 32. Esri-Leaflet: ArcGIS FeatureServices L.esri.FeatureLayer = L.GeoJSON.extend({… // Access ArcGIS FeatureService! var map = L.map('map').setView([45.52963623111275, -122.67389774322508], 12);! L.esri.basemapLayer("Topographic").addTo(map);! ! var url = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/ arcgis/rest/services/stops/FeatureServer/0’! ! L.esri.featureLayer(url);!
  • 33. Esri-Leaflet: Symbols // Create FeatureLayer and define styles! L.esri.featureLayer(url, {! style: function (feature) {! return getStyle(feature);! }).addTo(map);! ! function getStyle(feature) {! var c,o = 0.5;! switch (feature.properties.BIKEMODE) {! case "Low traffic through street":! c = "#007D7D";! break;! case "Bike boulevard":! c = "#00FF3C";! break;! ! …! }! return {color: c, opacity: o};! }!
  • 34. Esri-Leaflet: Popups // Create FeatureLayer and bind to popup! L.esri.featureLayer(featureServiceUrl, {! onEachFeature: createPopup! }).addTo(map);! ! // Define popup content - show all fields and values! function createPopup(geojson,layer) {! if (geojson.properties) {! var popupText = "<div style='max-height:200px;'>";! for (prop in geojson.properties) {! var val = geojson.properties[prop];! if (val) {! popupText += "<b>" + prop + "</b>: " + val + "<br>";! }! }! popupText += "</div>";! layer.bindPopup(popupText);! }! }!
  • 35. Esri-Leaflet: DynamicMapLayer // ArcGIS Server Dynamic Map Service - Hurricane Tracks! dynLayer = L.esri.dynamicMapLayer("http:// tmservices1.esri.com/arcgis/rest/services/LiveFeeds/ Hurricane_Recent/MapServer", { layers:[0,1] });! ! // Identifying Dynamic Map Service Features! map.on("click", function(e) {! !dynLayer.identify(e.latlng, {! ! !layerDefs: {! 0: "STORMNAME='ANDREA'",! 1: "STORMNAME='ANDREA'"! }! }, function(data) {! ! ! !popupText = "<center><b>" +! data.results[0].attributes.STORMNAME + "</b><br>" +! data.results[0].attributes.STORMTYPE + "</center>”;! ! !L.popup().setLatLng(e.latlng).setContent ! ! ! ! !(popupText).openOn(map);! !}! !});! }); !
  • 36. Esri-Leaflet: ClusterFeatureLayer esri-leaflet.js + clustered-feature-layer.js // Reference cluster plug-in and esri feature layer! <script src="lib/markercluster/leaflet.markercluster.js"></ script>! ! <script src="lib/esri-leaflet/extras/clustered-featurelayer.js"></script>! ! // Create and add a new feature cluster layer! var fl = L.esri.clusteredFeatureLayer("http:// services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/ stops/FeatureServer/0", {! !cluster: new L.MarkerClusterGroup(),! ! !onEachMarker: function(geojson, marker) {! marker.bindPopup("<h3>"+! ! ! !geojson.properties.stop_name+"</h3><p>! ! ! !Stop ID: "+geojson.properties.stop_id+"</p><p>” ! ! !+geojson.properties.stop_desc+"</p>")! }! }).addTo(map);!
  • 37. Esri-Leaflet: FeatureService Query esri-leaflet.js + geoservices.js // Access feature service directly and query (geoservices.js)! var fs = new GeoServices.FeatureService({url:featureServiceUrl}, function (err, results) {! !var queryOptions = document.getElementById("query");! !var query = queryOptions.text;! !var queryEnvelope = ! JSON.stringify(L.esri.Util.boundsToExtent(map.getBounds()));! // Build query parameters ! !var params = {! !f:"json”, where: query,! ! !geometry: queryEnvelope, ! ! !spatialRel: "esriSpatialRelIntersects”,! !returnGeometry:true, outSR: 4326, outFields:"*"! };! // Query the feature service! fs.query(params, function (err, results) {! ! !addFeaturesToMap(results); // Manual! !}! }!
  • 38. Esri-Leaflet: Geocoding esri-leaflet.js + geoservices.js // Reference geoservices.js! <script src="lib/geoservices/geoservices.js"></script>! …! var GeoServices = new Geoservices.Geoservices({});! var options = {! text:searchString,! outFields: "Loc_name,Place_addr",! bbox: mapBounds }! ! // Add geocodes to map! GeoServices.geocode(options, function (err,result) {! !for (var i = 0; i < result.locations.length; i++) {! var place = result.locations[i];! var pt = new L.LatLng(place.feature.geometry.y, place.feature.geometry.x);! ! !var marker = L.marker(pt).bindPopup(place.name + "</ br>" + place.feature.attributes.Place_addr);! layerPlaces.addLayer(marker);! }! }! !
  • 39. Other stuff §  Retina support (sort of…) §  Layers §  TiledMapLayers §  Controls §  esri-leaflet-geocoder
  • 40. Esri-Leaflet: Holly Grail? §  Widgets §  Symbols §  Renderers §  Editing §  Geometry operations and types §  Webmaps §  Accessing §  … all ArcGIS Services
  • 43. What is OAuth 2.0? §  OAuth 2.0 is a framework for allowing apps to securely access data on behalf of users §  A more secure alternative to asking for a user’s password
  • 44. Types of OAuth §  Client-side §  Best for browser-based applications §  No client_secret required, so it’s safe to use in Javascript apps §  Server-side §  Requires client_secret, so cannot be used from a Javascript app without a proxy
  • 45. Simple OAuth 2.0 Example §  Use the “implicit” grant type to generate an access token directly in the browser §  No server-side code required §  Browser makes API calls directly to secure services with the access token
  • 46. Step 1: ArcGIS Developer Subscription §  Sign up for a subscription §  Register §  Enable your apps for OAuth
  • 48. Step 2: Create a login page https://www.arcgis.com/sharing/oauth2/authorize? &client_id=YOUR_CLIENT_ID&response_type=token &redirect_uri=REDIRECT_URI var clientID = 's5R3ZF4K3GILBqsI'; var url = "https://www.arcgis.com/sharing/oauth2/authorize?client_id="; var uri = encodeURIComponent(window.location.origin)+"%2Foauth %2Fcallback.html”; function startAGOOAuth() { window.open(url + clientID &redirect_uri=” + uri, +"&response_type=token&expiration=20160 "oauth-window", "height=400,width=600"); }
  • 50. Step 3: Acquire a token On success, user is redirected back to your site with the access token in the fragment https://example.com/auth#token=ACCESS_TOKEN On error, user is redirected back to your site with error code https://example.com/auth#error=access_denied
  • 51. Using the Access Token §  Parse out the access token §  Make API requests using the token var accessToken;! ! window.oauthCallback = function(token) {! accessToken = token;! }! ! // Access services with token! L.esri.get("http://route.arcgis.com/arcgis/rest/services! World/Route/NAServer/Route_World/solve", {! token: accessToken,! stops: s.lng+","+s.lat+"; "+e.lng+","+e.lat,! outputLines: 'esriNAOutputLineTrueShape'! }, function(response){! !…!
  • 54. Licensing § Free ArcGIS Developer Subscription §  Testing and development §  Public deployments (non-commercial) §  50 credits §  Paid ArcGIS Developer or ArcGIS Organization Subscription §  Private deployments §  Commercial deployments (generates revenue)
  • 56. Final Notes §  Terraformer §  Geoservices-js §  Koop/node-geoservices-adaptor §  Esri-Leaflet §  OAuth §  Licensing Real value in Open Source libraries!