SlideShare ist ein Scribd-Unternehmen logo
1 von 57
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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 RailsRORLAB
 
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 guideLuc 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 FunctionsAleksandar Bozinovski
 

Was ist angesagt? (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
 

Ähnlich wie Application devevelopment with open source libraries

Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron 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
 
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 ApplicationAndrew 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 TracerySarah Sexton
 
UX Design for Developers
UX Design for DevelopersUX Design for Developers
UX Design for DevelopersFrank Garofalo
 
Getting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot FrameworkGetting Started with Microsoft Bot Framework
Getting Started with Microsoft Bot FrameworkSarah 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 ArangoDBArangoDB 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 appsandrewsmatt
 
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 Gearsdion
 
Phoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるPhoenix + Reactで 社内システムを 密かに作ってる
Phoenix + Reactで 社内システムを 密かに作ってるTakahiro Kobaru
 

Ähnlich wie 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で 社内システムを 密かに作ってる
 

Mehr von Allan Laframboise

Esri open source projects on GitHub
Esri open source projects on GitHubEsri open source projects on GitHub
Esri open source projects on GitHubAllan 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 BikersAllan 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 CloudAllan Laframboise
 
Navteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POINavteq Developer Days - ArcGIS + POI
Navteq Developer Days - ArcGIS + POIAllan 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 geolocationAllan Laframboise
 
Gis & Social Media Integration
Gis & Social Media IntegrationGis & Social Media Integration
Gis & Social Media IntegrationAllan 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
 
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
 

Mehr von 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?
 

Kürzlich hochgeladen

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 

Kürzlich hochgeladen (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

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!