GeoServer is a solid and mature implementation of a variety of OGC services including Web Feature Service, Web Map Service, Web Coverage Service, and Web Processing Service. Add to this a KML engine, integrated security framework, powerful styling language with SLD and this rich feature set makes GeoServer very appealing to the user. However it has always been somewhat lacking when it comes to the developer. Developing with GeoServer has a steep learning curve and requires expert knowledge to do simple tasks like writing new output formats, implementing new WPS processes, and adding custom filter functions. GeoScript to the rescue!
GeoScript adds spatial capabilities to popular languages such as Python, JavaScript, Scala, and Groovy. Scripting languages are the perfect tool for developers who want to do simple coding tasks quickly in a lightweight development environment. GeoScript builds on top of the very powerful GeoTools library to provide an interface to its capabilities though concise and easy to use API's. Recent extensions to GeoServer now allow developers to write components and plug-ins in the scripting language of their choice, using GeoScript as the engine for spatial functionality.
This presentation is geared toward developers who are interested in developing with GeoServer but not necessarily ready to get their hands dirty with low level Java. The talk will detail the various scripting hooks available and provide examples, complete with code, of how to write some simple plug-ins. Check out this presentation and you'll be developing with GeoServer in no time.
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("geoscript/workspace").PostGIS; var pg = PostGIS("geoscript"); pg.get("states").features.forEach(function(f) { print(f.get("STATE_NAME")); });
17. Script Hooks - Transactions Intercept WFS transactions with a wfs.js script in your data directory. exports.beforeCommit = function(details, request) { LOGGER.info("beforeCommit"); var records = details["PreInsert"] || []; 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()
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)