SlideShare a Scribd company logo
Scripting GeoServer with GeoScript Justin Deoliveira and Tim Schaub
GeoScript? ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
GeoScript
GeoScript
GeoScript ... import org.geotools.data.DataStore; import org.geotools.data.postgis.PostgisNGDataStoreFactory; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.jdbc.JDBCDataStoreFactory; import org.opengis.feature.Feature; ... Map<String,Serializable> params = new HashMap<String, Serializable>(); params.put(JDBCDataStoreFactory.HOST.key, &quot;localhost&quot;); params.put(JDBCDataStoreFactory.PORT.key, 5432); params.put(JDBCDataStoreFactory.DATABASE.key, &quot;geoscript&quot;); params.put(JDBCDataStoreFactory.DBTYPE.key, &quot;postgis&quot;); params.put(JDBCDataStoreFactory.USER.key, &quot;jdeolive&quot;); PostgisNGDataStoreFactory factory = new PostgisNGDataStoreFactory(); DataStore pg = factory.createDataStore(params);  FeatureCollection features = pg.getFeatureSource(&quot;states&quot;).getFeatures(); FeatureIterator it = features.features(); try {    while(it.hasNext()) {       Feature f = it.next();       System.out.println(f.getProperty(&quot;STATE_NAME&quot;).getValue());    } } finally {    it.close(); } Java
GeoScript from geoscript.workspace import PostGIS pg = PostGIS('geoscript') for f in pg['states'].features():    print f['STATE_NAME'] Python JavaScript var PostGIS = require(&quot;geoscript/workspace&quot;).PostGIS; var pg = PostGIS(&quot;geoscript&quot;); pg.get(&quot;states&quot;).features.forEach(function(f) {      print(f.get(&quot;STATE_NAME&quot;)); });
GeoServer
GeoServer
Script Hooks - Data Formats ,[object Object],[object Object],[object Object]
Script Hooks - Data Formats from geoserver import datastore from geoscript.layer import readJSON class GeoJSON(object):    @datastore('GeoJSON', 'GeoJSON', file=('GeoJSON file', str))    def __init__(self, file):      self.json = readJSON(file)    def layers(self):      return [self.json.name]    def get(self, layer):      return self.json GeoJSON DataStore
Script Hooks - Data Formats from geoserver import datastore from geoscript.layer import readJSON class GeoJSON(object):    @datastore('GeoJSON', 'GeoJSON', file=('GeoJSON file', str))    def __init__(self, file):      self.json = readJSON(file)    def layers(self):      return [self.json.name]    def get(self, layer):      return self.json GeoJSON DataStore
Script Hooks - Output Formats ,[object Object],[object Object],[object Object]
Script Hooks - Output Formats from geoserver.format import vector_format @vector_format('property', 'text/plain') def write(data, out):   for f in data.features:     values = [str(val) for val in f.values()]     out.write('%s=%s' % (f.id, '|'.join(values)) Property File Format states.1=MULTIPOLYGON (((37.51 -88.07, ... 37.51 -88.07)))|Illinois states.2=MULTIPOLYGON (((38.97 -77.00, ... 38.97 -77.01)))|District of Columbia states.3=MULTIPOLYGON (((38.56 -75.71, ... 38.56 -75.71)))|Delaware states.4=MULTIPOLYGON (((38.48 -79.23, ... 38.48 -79.23)))|West Virginia    .    .    . .../wfs?request=GetFeature&typename=topp:states&outputformat=property
Script Hooks - Process ,[object Object],[object Object],[object Object]
Script Hooks - Process var Process = require(&quot;geoscript/process&quot;).Process; exports.process = new Process({      title: &quot;JavaScript Buffer Process&quot;,      description: &quot;Process that buffers a geometry.&quot;,      inputs: {          geom: {              type: &quot;Geometry&quot;,              title: &quot;Input Geometry&quot;          },          distance: {              type: &quot;Double&quot;,              title: &quot;Buffer Distance&quot;          }      },      outputs: {          result: {              type: &quot;Geometry&quot;,              title: &quot;Result&quot;          }      },      run: function(inputs) {          return {result: inputs.geom.buffer(inputs.distance)};      } }); JavaScript
Script Hooks - Filter Functions ,[object Object],[object Object],[object Object],from geosever.filter import function from geoscript.geom import Polygon @function def areaGreaterThan(feature, area):    return feature.geom.area > area Area Function
Script Hooks - Transactions Intercept WFS transactions with a wfs.js script in your data directory. exports.beforeCommit = function(details, request) {      LOGGER.info(&quot;beforeCommit&quot;);      var records = details[&quot;PreInsert&quot;] || [];           records.forEach(function(record) {          var feature = record.feature;          feature.geometry = feature.geometry.simplify(10);      }); }; JavaScript
Script Hooks - Web/HTTP ,[object Object],[object Object],[object Object],def app(environ, start_response):     start_response('200 OK', [('Content-type','text/plain')])     return 'Hello world!' Hello World App
Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
Data Summary App Demo
Fusion Tables DataStore class GFT(object):    @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))     def __init__(self, user, passwd):      token = ClientLogin().authorize(user, passwd)      self.ft = ftclient.ClientLoginFTClient(token)    def layers(self):      return [tbl.name for tbl in self.tables()]           def get(self, layer):      try:        return Layer(filter(lambda t: t.name == layer, self.tables())[0])      except IndexError:        raise Exception('No table named %s' % layer)    def tables(self):      tables = self.ft.query(SQL().showTables())      return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
Fusion Tables DataStore class GFT(object):    @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))     def __init__(self, user, passwd):      token = ClientLogin().authorize(user, passwd)      self.ft = ftclient.ClientLoginFTClient(token)    def layers(self):      return [tbl.name for tbl in self.tables()]           def get(self, layer):      try:        return Layer(filter(lambda t: t.name == layer, self.tables())[0])      except IndexError:        raise Exception('No table named %s' % layer)    def tables(self):      tables = self.ft.query(SQL().showTables())      return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
Fusion Tables DataStore class GFT(object):    @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))     def __init__(self, user, passwd):      token = ClientLogin().authorize(user, passwd)      self.ft = ftclient.ClientLoginFTClient(token)    def layers(self):      return [tbl.name for tbl in self.tables()]           def get(self, layer):      try:        return Layer(filter(lambda t: t.name == layer, self.tables())[0])      except IndexError:        raise Exception('No table named %s' % layer)    def tables(self):      tables = self.ft.query(SQL().showTables())      return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
Fusion Tables DataStore class GFT(object):    @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))     def __init__(self, user, passwd):      token = ClientLogin().authorize(user, passwd)      self.ft = ftclient.ClientLoginFTClient(token)    def layers(self):      return [tbl.name for tbl in self.tables()]           def get(self, layer):      try:        return Layer(filter(lambda t: t.name == layer, self.tables())[0])      except IndexError:        raise Exception('No table named %s' % layer)    def tables(self):      tables = self.ft.query(SQL().showTables())      return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]]) for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]])          for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]])          for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
Fusion Tables DataStore class Layer(object):     ...     def features(self):       rows = self.tbl.gft.ft.query(SQL().select(self.tbl.id))       rows = rows.split('')[1:-1]       for row in rows:         vals = csv.reader([row]).next()         atts = []         for i in range(0, len(vals)):           val = vals[i]           fld = self.schema.get(i)           if issubclass(fld.typ, Geometry):             val = readKML(val)           atts.append(val)          yield Feature(atts, schema=self.schema)
Fusion Tables DataStore Demo
H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
H2 Output Format Demo
Scripted WPS and  WFS Transaction Hooks Demo
Thanks! http://geoscript.org http://geoserver.org Questions?

More Related Content

What's hot

Relaxing With CouchDB
Relaxing With CouchDBRelaxing With CouchDB
Relaxing With CouchDB
leinweber
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
Jung Kim
 
InterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and WhenInterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and When
Chris Bailey
 
The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184
Mahmoud Samir Fayed
 
HTTP APIs as first class procedures in your language: cutting out SDK complex...
HTTP APIs as first class procedures in your language: cutting out SDK complex...HTTP APIs as first class procedures in your language: cutting out SDK complex...
HTTP APIs as first class procedures in your language: cutting out SDK complex...
ProgrammableWeb
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing
Swakriti Rathore
 
Railwaynew
RailwaynewRailwaynew
Railwaynew
Arsh Vishwakarma
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
Jeado Ko
 
Python And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And PythonwinPython And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And Pythonwin
Chad Cooper
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team Productivity
Derek Lee Boire
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Sages
 
Interactive Session on Sparkling Water
Interactive Session on Sparkling WaterInteractive Session on Sparkling Water
Interactive Session on Sparkling Water
Sri Ambati
 
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...MongoDB
 
Cs pritical file
Cs pritical fileCs pritical file
Cs pritical file
Mitul Patel
 
c++ program for Railway reservation
c++ program for Railway reservationc++ program for Railway reservation
c++ program for Railway reservationSwarup Kumar Boro
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
Rick Beerendonk
 
Tugas praktikukm pemrograman c++
Tugas praktikukm  pemrograman c++Tugas praktikukm  pemrograman c++
Tugas praktikukm pemrograman c++Dendi Riadi
 
Go react codelab
Go react codelabGo react codelab
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
Hiroshi SHIBATA
 

What's hot (20)

Relaxing With CouchDB
Relaxing With CouchDBRelaxing With CouchDB
Relaxing With CouchDB
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architecture
 
InterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and WhenInterConnect: Java, Node.js and Swift - Which, Why and When
InterConnect: Java, Node.js and Swift - Which, Why and When
 
The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184The Ring programming language version 1.5.3 book - Part 40 of 184
The Ring programming language version 1.5.3 book - Part 40 of 184
 
HTTP APIs as first class procedures in your language: cutting out SDK complex...
HTTP APIs as first class procedures in your language: cutting out SDK complex...HTTP APIs as first class procedures in your language: cutting out SDK complex...
HTTP APIs as first class procedures in your language: cutting out SDK complex...
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing
 
ql.io at NodePDX
ql.io at NodePDXql.io at NodePDX
ql.io at NodePDX
 
Railwaynew
RailwaynewRailwaynew
Railwaynew
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
Python And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And PythonwinPython And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And Pythonwin
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team Productivity
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
 
Interactive Session on Sparkling Water
Interactive Session on Sparkling WaterInteractive Session on Sparkling Water
Interactive Session on Sparkling Water
 
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...
MongoDB Analytics: Learn Aggregation by Example - Exploratory Analytics and V...
 
Cs pritical file
Cs pritical fileCs pritical file
Cs pritical file
 
c++ program for Railway reservation
c++ program for Railway reservationc++ program for Railway reservation
c++ program for Railway reservation
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
 
Tugas praktikukm pemrograman c++
Tugas praktikukm  pemrograman c++Tugas praktikukm  pemrograman c++
Tugas praktikukm pemrograman c++
 
Go react codelab
Go react codelabGo react codelab
Go react codelab
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 

Similar to Scripting GeoServer with GeoScript

Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
Tugdual Grall
 
Use of django at jolt online v3
Use of django at jolt online v3Use of django at jolt online v3
Use of django at jolt online v3
Jaime Buelta
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL Suraj Bang
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
Andy McKay
 
What's New in ZF 1.10
What's New in ZF 1.10What's New in ZF 1.10
What's New in ZF 1.10
Ralph Schindler
 
Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009
Core Software Group
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
Guillaume Laforge
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
John Quaglia
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
John Brunswick
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overview
Dan Morrill
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
Mariano Iglesias
 
JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼
Sukjoon Kim
 
Jackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSVJackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSV
Tatu Saloranta
 
Introduction to Apache Pig
Introduction to Apache PigIntroduction to Apache Pig
Introduction to Apache Pig
Jason Shao
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
guest9bcef2f
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)
Davide Cerbo
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Rafael Soto
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGIS
mleslie
 
Html and i_phone_mobile-2
Html and i_phone_mobile-2Html and i_phone_mobile-2
Html and i_phone_mobile-2tonvanbart
 

Similar to Scripting GeoServer with GeoScript (20)

Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Use of django at jolt online v3
Use of django at jolt online v3Use of django at jolt online v3
Use of django at jolt online v3
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
What's New in ZF 1.10
What's New in ZF 1.10What's New in ZF 1.10
What's New in ZF 1.10
 
Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009Plone For Developers - World Plone Day, 2009
Plone For Developers - World Plone Day, 2009
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overview
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼JavaScript on Rails 튜토리얼
JavaScript on Rails 튜토리얼
 
Jackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSVJackson beyond JSON: XML, CSV
Jackson beyond JSON: XML, CSV
 
Introduction to Apache Pig
Introduction to Apache PigIntroduction to Apache Pig
Introduction to Apache Pig
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
 
Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)
 
Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011Demoiselle Spatial Latinoware 2011
Demoiselle Spatial Latinoware 2011
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGIS
 
Html and i_phone_mobile-2
Html and i_phone_mobile-2Html and i_phone_mobile-2
Html and i_phone_mobile-2
 

Recently uploaded

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
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
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
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
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
 
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
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
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
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
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
 
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
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 

Recently uploaded (20)

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
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
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
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
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
 
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
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
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
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
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
 
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...
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 

Scripting GeoServer with GeoScript

  • 1. Scripting GeoServer with GeoScript Justin Deoliveira and Tim Schaub
  • 2.
  • 5. GeoScript ... import org.geotools.data.DataStore; import org.geotools.data.postgis.PostgisNGDataStoreFactory; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.jdbc.JDBCDataStoreFactory; import org.opengis.feature.Feature; ... Map<String,Serializable> params = new HashMap<String, Serializable>(); params.put(JDBCDataStoreFactory.HOST.key, &quot;localhost&quot;); params.put(JDBCDataStoreFactory.PORT.key, 5432); params.put(JDBCDataStoreFactory.DATABASE.key, &quot;geoscript&quot;); params.put(JDBCDataStoreFactory.DBTYPE.key, &quot;postgis&quot;); params.put(JDBCDataStoreFactory.USER.key, &quot;jdeolive&quot;); PostgisNGDataStoreFactory factory = new PostgisNGDataStoreFactory(); DataStore pg = factory.createDataStore(params);  FeatureCollection features = pg.getFeatureSource(&quot;states&quot;).getFeatures(); FeatureIterator it = features.features(); try {   while(it.hasNext()) {       Feature f = it.next();       System.out.println(f.getProperty(&quot;STATE_NAME&quot;).getValue());   } } finally {   it.close(); } Java
  • 6. GeoScript from geoscript.workspace import PostGIS pg = PostGIS('geoscript') for f in pg['states'].features():   print f['STATE_NAME'] Python JavaScript var PostGIS = require(&quot;geoscript/workspace&quot;).PostGIS; var pg = PostGIS(&quot;geoscript&quot;); pg.get(&quot;states&quot;).features.forEach(function(f) {     print(f.get(&quot;STATE_NAME&quot;)); });
  • 9.
  • 10. Script Hooks - Data Formats from geoserver import datastore from geoscript.layer import readJSON class GeoJSON(object):   @datastore('GeoJSON', 'GeoJSON', file=('GeoJSON file', str))   def __init__(self, file):     self.json = readJSON(file)   def layers(self):     return [self.json.name]   def get(self, layer):     return self.json GeoJSON DataStore
  • 11. Script Hooks - Data Formats from geoserver import datastore from geoscript.layer import readJSON class GeoJSON(object):   @datastore('GeoJSON', 'GeoJSON', file=('GeoJSON file', str))   def __init__(self, file):     self.json = readJSON(file)   def layers(self):     return [self.json.name]   def get(self, layer):     return self.json GeoJSON DataStore
  • 12.
  • 13. Script Hooks - Output Formats from geoserver.format import vector_format @vector_format('property', 'text/plain') def write(data, out):   for f in data.features:     values = [str(val) for val in f.values()]     out.write('%s=%s' % (f.id, '|'.join(values)) Property File Format states.1=MULTIPOLYGON (((37.51 -88.07, ... 37.51 -88.07)))|Illinois states.2=MULTIPOLYGON (((38.97 -77.00, ... 38.97 -77.01)))|District of Columbia states.3=MULTIPOLYGON (((38.56 -75.71, ... 38.56 -75.71)))|Delaware states.4=MULTIPOLYGON (((38.48 -79.23, ... 38.48 -79.23)))|West Virginia   .   .   . .../wfs?request=GetFeature&typename=topp:states&outputformat=property
  • 14.
  • 15. Script Hooks - Process var Process = require(&quot;geoscript/process&quot;).Process; exports.process = new Process({     title: &quot;JavaScript Buffer Process&quot;,     description: &quot;Process that buffers a geometry.&quot;,     inputs: {         geom: {             type: &quot;Geometry&quot;,             title: &quot;Input Geometry&quot;         },         distance: {             type: &quot;Double&quot;,             title: &quot;Buffer Distance&quot;         }     },     outputs: {         result: {             type: &quot;Geometry&quot;,             title: &quot;Result&quot;         }     },     run: function(inputs) {         return {result: inputs.geom.buffer(inputs.distance)};     } }); JavaScript
  • 16.
  • 17. Script Hooks - Transactions Intercept WFS transactions with a wfs.js script in your data directory. exports.beforeCommit = function(details, request) {     LOGGER.info(&quot;beforeCommit&quot;);     var records = details[&quot;PreInsert&quot;] || [];          records.forEach(function(record) {         var feature = record.feature;         feature.geometry = feature.geometry.simplify(10);     }); }; JavaScript
  • 18.
  • 19. Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
  • 20. Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
  • 21. Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
  • 22. Data Summary App from geoserver.catalog import Layer from StringIO import StringIO def app(env, start_response):   kvp = dict([tuple(kv.split('=')) for kv in env['QUERY_STRING'].split('&')])   layer = kvp['layer']   l = Layer(layer, store=None)   buf = StringIO()   buf.write('Layer: %s' % l.name)   data = l.data   buf.write(' Format: %s' % data.format)   buf.write(' Feature count: %d' % data.count())   buf.write(' CRS/Projection: %s' % data.proj.wkt)   b = data.bounds()   buf.write(' Bounds: (%f,%f,%f,%f)' % (b.west, b.south, b.east, b.north))   buf.write(' Fields:')   buf.write(''.join(['   %s' % repr(fld) for fld in data.schema.fields]))   buf.write('')   start_response('200 OK', [('Content-type','text/plain')])   return buf.getvalue()
  • 24. Fusion Tables DataStore class GFT(object):   @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))    def __init__(self, user, passwd):     token = ClientLogin().authorize(user, passwd)     self.ft = ftclient.ClientLoginFTClient(token)   def layers(self):     return [tbl.name for tbl in self.tables()]          def get(self, layer):     try:       return Layer(filter(lambda t: t.name == layer, self.tables())[0])     except IndexError:       raise Exception('No table named %s' % layer)   def tables(self):     tables = self.ft.query(SQL().showTables())     return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
  • 25. Fusion Tables DataStore class GFT(object):   @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))    def __init__(self, user, passwd):     token = ClientLogin().authorize(user, passwd)     self.ft = ftclient.ClientLoginFTClient(token)   def layers(self):     return [tbl.name for tbl in self.tables()]          def get(self, layer):     try:       return Layer(filter(lambda t: t.name == layer, self.tables())[0])     except IndexError:       raise Exception('No table named %s' % layer)   def tables(self):     tables = self.ft.query(SQL().showTables())     return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
  • 26. Fusion Tables DataStore class GFT(object):   @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))    def __init__(self, user, passwd):     token = ClientLogin().authorize(user, passwd)     self.ft = ftclient.ClientLoginFTClient(token)   def layers(self):     return [tbl.name for tbl in self.tables()]          def get(self, layer):     try:       return Layer(filter(lambda t: t.name == layer, self.tables())[0])     except IndexError:       raise Exception('No table named %s' % layer)   def tables(self):     tables = self.ft.query(SQL().showTables())     return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
  • 27. Fusion Tables DataStore class GFT(object):   @datastore('GFT', 'Google Fusion Tables',                user=('User email', str), passwd=('Password', str))    def __init__(self, user, passwd):     token = ClientLogin().authorize(user, passwd)     self.ft = ftclient.ClientLoginFTClient(token)   def layers(self):     return [tbl.name for tbl in self.tables()]          def get(self, layer):     try:       return Layer(filter(lambda t: t.name == layer, self.tables())[0])     except IndexError:       raise Exception('No table named %s' % layer)   def tables(self):     tables = self.ft.query(SQL().showTables())     return [Table(self,*row.split(',')) for row in tables.split('')[1:-1]]
  • 28. Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]]) for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
  • 29. Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]])          for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
  • 30. Fusion Tables DataStore __types = {'string':str, 'number': float, 'location':Geometry} class Layer(object):     def __init__(self, tbl):       self.tbl = tbl       self.name = tbl.name       self.workspace = tbl.gft       self.proj = Projection('epsg:4326')       self.schema = Schema(tbl.name, [(col[0], __types[col[1]])          for col in tbl.schema()])     def bounds(self):       return reduce(lambda x,y: x.expand(y.bounds), self.features(), Bounds())     def features(self):       ...
  • 31. Fusion Tables DataStore class Layer(object):     ...     def features(self):       rows = self.tbl.gft.ft.query(SQL().select(self.tbl.id))       rows = rows.split('')[1:-1]       for row in rows:         vals = csv.reader([row]).next()         atts = []         for i in range(0, len(vals)):           val = vals[i]           fld = self.schema.get(i)           if issubclass(fld.typ, Geometry):             val = readKML(val)           atts.append(val)          yield Feature(atts, schema=self.schema)
  • 33. H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
  • 34. H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
  • 35. H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
  • 36. H2 Output Format @vector_format('h2', 'application/zip') def write(data, out):   dir = tempfile.mkdtemp()   # create the database and copy the features into it   db = H2(data.schema.name, dir=dir)   layer = db.create(schema=data.schema)   for f in data.features:     layer.add(f)   db.close()   # zip and ship   file = tempfile.mktemp()   zip = zipfile.ZipFile(file, 'w')   for root, dirs, files in os.walk(dir):     name = abspath(root)[len(abspath(dir)):]       for f in files:       zip.write(join(root,f), join(name,f), zipfile.ZIP_DEFLATED)   zip.close()   shutil.copyfileobj(open(file, 'r'), out)   # clean up   os.remove(file)   shutil.rmtree(dir)
  • 38. Scripted WPS and  WFS Transaction Hooks Demo