SlideShare a Scribd company logo
1 of 39
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 CouchDBleinweber
 
Letswift19-clean-architecture
Letswift19-clean-architectureLetswift19-clean-architecture
Letswift19-clean-architectureJung 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 WhenChris 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 184Mahmoud 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
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2Jeado 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 PythonwinChad 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 ProductivityDerek 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 courseSages
 
Interactive Session on Sparkling Water
Interactive Session on Sparkling WaterInteractive Session on Sparkling Water
Interactive Session on Sparkling WaterSri 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 fileMitul 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# DevelopersRick Beerendonk
 
Tugas praktikukm pemrograman c++
Tugas praktikukm  pemrograman c++Tugas praktikukm  pemrograman c++
Tugas praktikukm pemrograman c++Dendi Riadi
 

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 2005Tugdual 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 v3Jaime 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 EngineAndy McKay
 
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, 2009Core Software Group
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesJohn Brunswick
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewDan 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 CakePHPMariano 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, CSVTatu Saloranta
 
Introduction to Apache Pig
Introduction to Apache PigIntroduction to Apache Pig
Introduction to Apache PigJason Shao
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming Enguest9bcef2f
 
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 PostGISmleslie
 
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

Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfFIDO Alliance
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...CzechDreamin
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FIDO Alliance
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty SecureFemke de Vroome
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCzechDreamin
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfFIDO Alliance
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Patrick Viafore
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfFIDO Alliance
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfFIDO Alliance
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?Mark Billinghurst
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutesconfluent
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...CzechDreamin
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyUXDXConf
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoUXDXConf
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoTAnalytics
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessUXDXConf
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIES VE
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge
 

Recently uploaded (20)

Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, Ocado
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 

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