SlideShare uma empresa Scribd logo
1 de 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?

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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 (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)Davide Cerbo
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming Enguest9bcef2f
 
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
 

Semelhante a 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 (English)
Non Conventional Android Programming (English)Non Conventional Android Programming (English)
Non Conventional Android Programming (English)
 
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
 
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
 

Último

Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 

Último (20)

Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 

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