SlideShare a Scribd company logo
GeoScript Spatial Capabilities for Scripting Languages Justin Deolivera, Tim Schaub, and Jared Erickson
Introduction What is GeoScript? Overview of languages Motivation GeoTools hard, scripting easy Development turnaround GeoScript Modules/API Overview Geometry Projection Data Access Styling
Scripting Platform for JVM Languages Similar API  Respect languages differences
Groovy Groovy  Dynamic language Easy for Java programmers to learn  Closures, DSLs REPL, GUI Console Compiles to Java Byte Code Full access to Java libraries http://geoscript.org/groovy https://github.com/jericks/geoscript-groovy
JavaScript Not just for the browser any more! Common JS module loading with Rhino. One language for client & server code. Docs: http://geoscript.org/js/ Source: https://github.com/tschaub/geoscript-js/
Python Jython  Java implementation of Python  Jython 2.5 = CPython 2.5 Full access to Java libraries http://geoscript.org/py https://github.com/jdeolive/geoscript-py
Scala Combine functional and object-oriented programming Statically typed REPL Compiles to Java bytecode Full access to Java libraries http://geoscript.org/scala/ https://github.com/dwins/geoscript.scala/ Scala
On the shoulders of giants...
GeoScript Modules
Geometry Easy to use constructors I/O WKT/WKB JSON GML Plotting Transforms
Geometry >>>  from geoscript import geom >>>  geom.Point(30, 10) POINT(30 10)
Geometry >>>  import geoscript.geom.* >>>  line = new LineString([[111.0, -47], [123.0, -48], [110.0, -47]]) LINESTRING (111 -47, 123 -48, 110 -47)
Geometry js>  var poly = geom.Point([10, 30]).    >      buffer(5) js>  poly <Polygon [[[15, 30], [14.90...> js>  poly.area 78.03612880645133
Geometry - I/O >>>  from geoscript import geom >>>  point = geom.Point(30, 10) >>>  geom.writeKML(point) <kml:Point xmlns:kml=&quot;http://earth.google.com/kml/2.1&quot;>   <kml:coordinates>0.0,0.0</kml:coordinates> </kml:Point>
Geometry - I/O >>>  import geoscript.geom.Point >>>  import geoscript.geom.io.Gml2Writer >>>  p = new Point(111, -47) >>>  gml = new Gml2Writer() >>>  gml.write(p) <gml:Point>   <gml:coordinates>111.0,-47.0</gml:coordinates> </gml:Point>
Geometry - I/O js>  var geom = require(&quot;geoscript/geom&quot;); js>  var point = geom.Point([1, 2]) js>  point.json {&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[1,2]}
Geometry - Visualization >>>  from geoscript.render import plot >>> from geoscript import geom >>> poly = geom.Polygon([(35,10), (10,20), (15,40), (45,45), (35,10)], [(20,30), (35,35), (30,20), (20,30)]) >>>  plot(poly)
Geometry - Visualization js>  var geom = require(&quot;geoscript/geom&quot;) js>  require(&quot;geoscript/viewer&quot;).bind()   js>  var poly1 = geom.Point([0, 0]).buffer(1) js>  var poly2 = poly1.transform({dx: 0.5, dy: 0.5}) js>  poly1.difference(poly2) <Polygon [[[0.9095298326166407, -0.409529...>
Projection Parse/encode WKT Full GeoTools EPSG database Re-projection
Projection js>  var proj = require(&quot;geoscript/proj&quot;); js>  var p = proj.Projection(&quot;epsg:4326&quot;); js>  p.wkt GEOGCS[&quot;WGS 84&quot;,     DATUM[&quot;World Geodetic System 1984&quot;,     ...
Projection >>> from geoscript import geom >>> from geoscript.proj import Projection >>> p = Projection('epsg:4326') >>>  p.transform((-111, 45.7), 'epsg:26912') (500000.0, 5060716.313515949) >>> g = geom.Point(0, 0).buffer(4) >>> g = reduce(lambda x,y:x.union(y),[geom.transform(g,dx=x,dy=y)        for x,y in [(3,0),(0,3),(-3,0),(0,-3)]]) >>>  p.transform(g, 'epsg:26912') >>>  p.transform(g, 'epsg:3005') Reprojection WGS 84 UTM Albers
Data Access Read and Write Layers Query Layers using CQL I/O  GeoJSON GML
Data Access - Workspace js>  var ws = require(&quot;geoscript/workspace&quot;);         js>  var dir = ws.Directory(&quot;data&quot;);    js>  dir            <Directory [&quot;states&quot;]> js>  var states = dir.get(&quot;states&quot;); js>  states <Layer name: states, count: 49>
Data Access - Workspace >>  from geoscript.workspace import PostGIS >>  pg = PostGIS('spearfish') >>  pg.layers() ['archsites', 'bugsites', ..., 'streams'] >>  l = pg['archsites']
Data Access - Workspace >>>  import geoscript.workspace.H2 >>>  import geoscript.geom.Point >>>  import geoscript.feature.Feature >>>  h2 = new H2(&quot;name&quot;, &quot;path&quot;) >>>  layer = h2.create(&quot;points&quot;, [      new Field(&quot;geom&quot;,&quot;Point&quot;),      new Field(&quot;name&quot;,&quot;String&quot;) ]) >>>  layer.add([new Point[1,1],&quot;one&quot;])
Data Access - Layers >>>  from geoscript.layer import Shapefile >>>  states = Shapefile('states.shp') >>>  states = states.reproject('epsg:3005')
Data Access - Layer Info >>>  import geoscript.layer.Shapefile >>>  shp = new Shapefile(&quot;states.shp&quot;) >>>  shp.count 49 >>>  shp.bounds (-124.73142200000001, 24.955967,-66.969849, 49.371735, EPSG:4326) >>>  shp.schema.fields.each {    fld -> println fld} the_geom: MultiPolygon(EPSG:4326) STATE_NAME: String STATE_FIPS: String SUB_REGION: String STATE_ABBR: String
Data Access - Layers js>  var ws = require(&quot;geoscript/workspace&quot;);        js>  var dir = ws.Directory(&quot;data&quot;);    js>  var states = dir.get(&quot;states&quot;); js>  states.query(&quot;STATE_ABBR like 'M%'&quot;).forEach(    >      function(feature) {    >          print(feature.get(&quot;STATE_NAME&quot;));    >      }    >  ) Maryland Missouri Mississippi ...
Styling and Rendering Taming SLD Symbolizers Scale dependence Thematics
Styling - Stroke >>>  from geoscript.style import Stroke >>>  Stroke('#000000', width=2) >>>  Stroke('black', width=2, dash=[5,5]) >>>  Stroke((0,0,0),width=2).hatch('vertline')
Styling - Fill >>>  import geoscript.style.Fill >>>  new Fill(&quot;gray&quot;) >>>  new Fill(&quot;gray&quot;, 0.5)) >>>  new Fill(&quot;gray&quot;).hatch(&quot;backslash&quot;) >>>  new Stroke(&quot;red&quot;,2) + new Fill(&quot;gray&quot;).hatch(&quot;times&quot;)
Styling - Shape and Icon js>  var style = require(&quot;geoscript/style&quot;); js>  style.Shape({name: &quot;star&quot;, fill: &quot;yellow&quot;}) <Shape name: 'star', size: 6> js>  style.Icon(&quot;rainy.svg&quot;) <Icon url: 'rainy.svg'>
Styling - Labels >>>  from geoscript.style import Label,Stroke,Fill,Shape >>>  font = 'bold 16px Arial' >>>   Shape() +  Label('name',font)       .point(displace=(20,0)) >>>   Stroke() +  Label('name',font)       .linear(offset=10) >>>   Fill() +  Label('name',font).halo('white',2)
Styling - Scale >>>  new Shape('#004d96', 5).range(3000)  + new Icon('school20.png').range(1500, 3000) + new Icon('school40.png').range(-1, 1500)
Styling - Theming >>> from geoscript.style Stroke, Fill, Label >>> style = Stroke() + Label('STATE_ABBR', 14, 'Serif') >>> style += Fill('#4DFF4D', 0.7)        .where('PERSONS < 2000000') >>> style += Fill('#FF4D4D', 0.7)       .where('PERSONS BETWEEN 2000000 AND 4000000') >>> style += Fill('#4D4DFF', 0.7)       .where('PERSONS > 4000000')
Demos
Voronoi Diagram Example import geoscript.layer.* import geoscript.feature.* import geoscript.geom.* def shp = new Shapefile('states.shp') def schema = new Schema('states_voronoi',           [['the_geom','MultiPolygon','EPSG:4326']]) def diagramLayer = shp.workspace.create(schema) def geoms = shp.features.collect{f->      f.geom.centroid } def geomCol = new GeometryCollection(geoms) def voronoiGeom = geomCol.voronoiDiagram diagramLayer.add(schema.feature([voronoiGeom]))
Gradient  Example var Directory = require(&quot;geoscript/workspace&quot;).Directory; var {Fill, gradient} = require(&quot;geoscript/style&quot;); var Map = require(&quot;geoscript/map&quot;).Map; var states = Directory(&quot;data&quot;).get(&quot;states&quot;); states.style = gradient({      expression: &quot;PERSONS / LAND_KM&quot;,       values: [0, 200],       styles: [Fill(&quot;#000066&quot;), Fill(&quot;red&quot;)],      classes: 10,       method: &quot;exponential&quot; }).and(      Fill(&quot;red&quot;).where(&quot;PERSONS / LAND_KM > 200&quot;) ); var map = Map([states]); map.render({path: &quot;states.png&quot;});
Shapefile to PostGIS from geoscript.workspace import Directory, PostGIS shps = Directory('shapefiles') shps.layers() archsites = shps['archsites'] archsites.proj.id pg = PostGIS('demo') pg.layers() for layer in shps:    reprojected = shps[layer].reproject('epsg:4326')    pg.add(reprojected, name=layer) pg.layers() archsites = pg['archsites'] archsites.proj.id
Road Map Raster Rendering WPS/GeoServer Map Printing
Resources Web Site      http://geoscript.org Google Group      http://groups.google.com/group/geoscript Blog      http://geoscriptblog.blogspot.com GitHub      https://github.com/jdeolive/geoscript-py      https://github.com/tschaub/geoscript-js      https://github.com/dwins/geoscript.scala      https://github.com/jericks/geoscript-groovy     
Thank you!
Centroids import geoscript.layer.* import geoscript.feature.* import geoscript.geom.* Shapefile shp = new Shapefile('states.shp') Schema schema = shp.schema.changeGeometryType('Point', 'states_centroids') Layer centroidLayer = shp.workspace.create(schema)   Cursor cursor = shp.cursor while(cursor.hasNext()) {     Feature f = cursor.next()     Map attributes = [:]     f.attributes.each{k,v ->        if (v instanceof Geometry) {            attributes[k] = v.centroid        }        else {           attributes[k] = v        }     }     Feature feature = schema.feature(attributes, f.id)     centroidLayer.add(feature) } cursor.close()  
Shapefiles to PostGIS import geoscript.workspace.* import geoscript.layer.* def dir = new Directory(&quot;/Users/jericks/Downloads/wash&quot;) println(&quot;Shapefiles: ${dir.layers}&quot;) def postgis = new PostGIS('postgres','localhost','5432','public','postgres', 'postgres') println(&quot;PostGIS Layers: ${postgis.layers}&quot;) dir.layers.each{name->      def layer = dir.get(name)      println(&quot;Adding ${layer.name}...&quot;)      postgis.add(layer) }
USGS Earth Quakes Read RSS Feed to a Shapefile
import geoscript.geom.* import geoscript.feature.* import geoscript.layer.Layer import geoscript.workspace.Directory Schema s = new Schema('earthquakes'[['the_geom', 'Point', 'EPSG:4326'], ['title','String'], ['date', 'java.util.Date'], ['elevation', 'Double']]) Directory dir = new Directory('.') Layer layer = dir.create(s) def url = &quot;http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml&quot; def rss = new XmlParser().parse(url) int c = 0 String dateFormat = &quot;yyyy-MM-dd'T'HH:mm:ss'Z'&quot; rss.entry.each{e ->      def title = e.title.text()      def date = Date.parse(dateFormat, e.updated.text())      def coordinate = e.&quot;georss:point&quot;.text().split(&quot; &quot;)      double x = coordinate[1] as Double      double y = coordinate[0] as Double      def point = new Point(x,y)      def elev = e.&quot;georss:elev&quot;.text() as Double      Feature f = s.feature(['title':title,'date':date,        'elevation': elev, 'the_geom': point],&quot;earthquake_${c}&quot;)      layer.add(f)      c++ }
Web Applications @GrabResolver(name=&quot;graffiti&quot;, root=&quot;http://simple-dm.googlecode.com/svn/repository&quot;) @Grab(&quot;com.goodercode:graffiti:1.0-SNAPSHOT&quot;) import graffiti.* import geoscript.geom.Geometry @Get(&quot;/buffer&quot;) def buffer() {      Geometry.fromWKT(params.geom).buffer(params.distance as double).wkt } @Get(&quot;/centroid&quot;) def centroid() {      Geometry.fromWKT(params.geom).centroid.wkt } @Get(&quot;/convexHull&quot;) def convexHull() {      Geometry.fromWKT(params.geom).convexHull.wkt } Graffiti.root 'graffiti' Graffiti.serve this Graffiti.start()      Graffiti Micro Web Framework
Geometry Web Services 
Geometry Web Services Open Layers function centroid() {     var features = vectorLayer.features;     if (features.length == 0) {        alert(&quot;Please add some features!&quot;);     } else {        OpenLayers.loadURL('centroid', {              geom: wktFormat.write(features)           },            this,            function(request) {              var wkt = request.responseText;              var features = wktFormat.read(wkt);              if (features) vectorLayer.addFeatures(features);           },            function() {              alert(&quot;Error calculating centroids!&quot;);           }        );     } }
WMS Server import com.sun.grizzly.http.embed.GrizzlyWebServer import com.sun.grizzly.http.servlet.ServletAdapter import groovy.servlet.GroovySerlvet @Grab(group='com.sun.grizzly',module='grizzly-servlet-webserver',  version='1.9.10') def start() {      def server = new GrizzlyWebServer(8080, &quot;web&quot;)      def servlet = new ServletAdapter()      servlet.contextPath = &quot;/geoscript&quot;      servlet.servletInstance = new GroovyServlet()      server.addGrizzlyAdapter(servlet, [&quot;/geoscript&quot;] as String[])      server.start() } start()
WMS Server... import geoscript.map.Map import geoscript.style.* import geoscript.layer.Shapefile import geoscript.geom.Bounds def file = new File(&quot;states.shp&quot;) def shp = new Shapefile(file) shp.style = new Fill(&quot;steelblue&quot;) + new Stroke(&quot;wheat&quot;, 0.1) def map = new Map(      width: 256,       height: 256,       layers: [shp],      proj: shp.proj,      fixAspectRatio: false ) def bbox = request.getParameter(&quot;BBOX&quot;).split(&quot;,&quot;) def bounds = new Bounds(bbox[0] as double, bbox[1] as double, bbox[2] as double, bbox[3] as double) map.bounds = bounds response.contentType = &quot;image/png&quot; map.render(response.outputStream) map.close()
Geometry Command line  echo &quot;POINT (1 1)&quot; | geoscript-groovy geom_buffer.groovy -d 10 | geoscript-groovy geom_envelope.groovy def cli = new CliBuilder(usage: 'geoscript-groovy geom_buffer.groovy -d') cli.d(longOpt: 'distance', 'buffer distance', args:1) cli.h(longOpt: 'help', 'Show usage information and quit') def opt = cli.parse(args) if(!opt) return if (opt.h || !opt.d) cli.usage() else println geoscript.geom.Geometry.fromWKT(System.in.text).buffer(opt.d as double).wkt def cli = new CliBuilder(usage: 'geoscript-groovy geom_envelope.groovy') cli.h(longOpt: 'help', 'Show usage information and quit') def opt = cli.parse(args) if(!opt) return if (opt.h) cli.usage() else println geoscript.geom.Geometry.fromWKT(System.in.text).bounds.geometry.wkt geom_buffer.groovy geom_envelope.groovy

More Related Content

PPT
Scripting GeoServer with GeoScript
PPT
The State of GeoServer
PDF
Scripting GeoServer
PDF
Rendering Maps in GeoScript
PDF
Utilizing Powerful Extensions for Analytics and Operations
PDF
3 u-mpb2u2na
PPTX
Angular mix chrisnoring
PDF
Practical Testing of Ruby Core
Scripting GeoServer with GeoScript
The State of GeoServer
Scripting GeoServer
Rendering Maps in GeoScript
Utilizing Powerful Extensions for Analytics and Operations
3 u-mpb2u2na
Angular mix chrisnoring
Practical Testing of Ruby Core

What's hot (19)

PDF
Taking Apache Camel For A Ride
PDF
Letswift19-clean-architecture
PDF
RubyKaigi2015 making robots-with-mruby
PDF
Map kit light
PDF
The Ring programming language version 1.5.3 book - Part 40 of 184
PDF
Minimizing Decision Fatigue to Improve Team Productivity
PDF
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
PDF
RxSwift to Combine
PDF
RxSwift to Combine
PDF
Compose Async with RxJS
PPTX
Build Lightweight Web Module
PDF
High Performance tDiary
PDF
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
PDF
Relaxing With CouchDB
PDF
Protocol-Oriented Networking
PDF
Wprowadzenie do technologi Big Data i Apache Hadoop
PDF
JavaScript 2016 for C# Developers
PDF
OneRing @ OSCamp 2010
PDF
HDTR images with Photoshop Javascript Scripting
Taking Apache Camel For A Ride
Letswift19-clean-architecture
RubyKaigi2015 making robots-with-mruby
Map kit light
The Ring programming language version 1.5.3 book - Part 40 of 184
Minimizing Decision Fatigue to Improve Team Productivity
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
RxSwift to Combine
RxSwift to Combine
Compose Async with RxJS
Build Lightweight Web Module
High Performance tDiary
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Relaxing With CouchDB
Protocol-Oriented Networking
Wprowadzenie do technologi Big Data i Apache Hadoop
JavaScript 2016 for C# Developers
OneRing @ OSCamp 2010
HDTR images with Photoshop Javascript Scripting
Ad

Similar to GeoScript - Spatial Capabilities for Scripting Languages (20)

PPT
Html and i_phone_mobile-2
PPT
Python And GIS - Beyond Modelbuilder And Pythonwin
PPT
Google maps
PPT
Google maps
ODP
Intro To PostGIS
PPTX
Yahoo Query Language: Select * from Internet
PPTX
Beholding the giant pyramid of application development; why Ajax applications...
PPTX
Designing and developing mobile web applications with Mockup, Sencha Touch an...
KEY
Google MAP API
ODP
Use of django at jolt online v3
PDF
JavaOne 2009 - 2d Vector Graphics in the browser with Canvas and SVG
PDF
PART 4: GEOGRAPHIC SCRIPTING
PPT
Gooogle Web Toolkit
PPT
PPT
Building Complex GUI Apps The Right Way. With Ample SDK - SWDC2010
PPT
Introduction To Groovy 2005
PPTX
XML-Free Programming
PPTX
How data rules the world: Telemetry in Battlefield Heroes
PPTX
Groovy
ODP
Introduction To PostGIS
Html and i_phone_mobile-2
Python And GIS - Beyond Modelbuilder And Pythonwin
Google maps
Google maps
Intro To PostGIS
Yahoo Query Language: Select * from Internet
Beholding the giant pyramid of application development; why Ajax applications...
Designing and developing mobile web applications with Mockup, Sencha Touch an...
Google MAP API
Use of django at jolt online v3
JavaOne 2009 - 2d Vector Graphics in the browser with Canvas and SVG
PART 4: GEOGRAPHIC SCRIPTING
Gooogle Web Toolkit
Building Complex GUI Apps The Right Way. With Ample SDK - SWDC2010
Introduction To Groovy 2005
XML-Free Programming
How data rules the world: Telemetry in Battlefield Heroes
Groovy
Introduction To PostGIS
Ad

Recently uploaded (20)

PDF
Approach and Philosophy of On baking technology
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Machine learning based COVID-19 study performance prediction
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Cloud computing and distributed systems.
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPT
Teaching material agriculture food technology
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Spectral efficient network and resource selection model in 5G networks
Approach and Philosophy of On baking technology
Programs and apps: productivity, graphics, security and other tools
sap open course for s4hana steps from ECC to s4
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Digital-Transformation-Roadmap-for-Companies.pptx
MYSQL Presentation for SQL database connectivity
Network Security Unit 5.pdf for BCA BBA.
Encapsulation_ Review paper, used for researhc scholars
Diabetes mellitus diagnosis method based random forest with bat algorithm
Machine learning based COVID-19 study performance prediction
MIND Revenue Release Quarter 2 2025 Press Release
Cloud computing and distributed systems.
Review of recent advances in non-invasive hemoglobin estimation
Chapter 3 Spatial Domain Image Processing.pdf
Teaching material agriculture food technology
The AUB Centre for AI in Media Proposal.docx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Spectral efficient network and resource selection model in 5G networks

GeoScript - Spatial Capabilities for Scripting Languages

  • 1. GeoScript Spatial Capabilities for Scripting Languages Justin Deolivera, Tim Schaub, and Jared Erickson
  • 2. Introduction What is GeoScript? Overview of languages Motivation GeoTools hard, scripting easy Development turnaround GeoScript Modules/API Overview Geometry Projection Data Access Styling
  • 3. Scripting Platform for JVM Languages Similar API  Respect languages differences
  • 4. Groovy Groovy  Dynamic language Easy for Java programmers to learn  Closures, DSLs REPL, GUI Console Compiles to Java Byte Code Full access to Java libraries http://geoscript.org/groovy https://github.com/jericks/geoscript-groovy
  • 5. JavaScript Not just for the browser any more! Common JS module loading with Rhino. One language for client & server code. Docs: http://geoscript.org/js/ Source: https://github.com/tschaub/geoscript-js/
  • 6. Python Jython  Java implementation of Python  Jython 2.5 = CPython 2.5 Full access to Java libraries http://geoscript.org/py https://github.com/jdeolive/geoscript-py
  • 7. Scala Combine functional and object-oriented programming Statically typed REPL Compiles to Java bytecode Full access to Java libraries http://geoscript.org/scala/ https://github.com/dwins/geoscript.scala/ Scala
  • 8. On the shoulders of giants...
  • 10. Geometry Easy to use constructors I/O WKT/WKB JSON GML Plotting Transforms
  • 11. Geometry >>> from geoscript import geom >>> geom.Point(30, 10) POINT(30 10)
  • 12. Geometry >>>  import geoscript.geom.* >>> line = new LineString([[111.0, -47], [123.0, -48], [110.0, -47]]) LINESTRING (111 -47, 123 -48, 110 -47)
  • 13. Geometry js> var poly = geom.Point([10, 30]).   >     buffer(5) js> poly <Polygon [[[15, 30], [14.90...> js> poly.area 78.03612880645133
  • 14. Geometry - I/O >>>  from geoscript import geom >>>  point = geom.Point(30, 10) >>>  geom.writeKML(point) <kml:Point xmlns:kml=&quot;http://earth.google.com/kml/2.1&quot;>   <kml:coordinates>0.0,0.0</kml:coordinates> </kml:Point>
  • 15. Geometry - I/O >>> import geoscript.geom.Point >>> import geoscript.geom.io.Gml2Writer >>> p = new Point(111, -47) >>> gml = new Gml2Writer() >>> gml.write(p) <gml:Point>   <gml:coordinates>111.0,-47.0</gml:coordinates> </gml:Point>
  • 16. Geometry - I/O js> var geom = require(&quot;geoscript/geom&quot;); js> var point = geom.Point([1, 2]) js> point.json {&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[1,2]}
  • 17. Geometry - Visualization >>>  from geoscript.render import plot >>> from geoscript import geom >>> poly = geom.Polygon([(35,10), (10,20), (15,40), (45,45), (35,10)], [(20,30), (35,35), (30,20), (20,30)]) >>>  plot(poly)
  • 18. Geometry - Visualization js> var geom = require(&quot;geoscript/geom&quot;) js> require(&quot;geoscript/viewer&quot;).bind()   js> var poly1 = geom.Point([0, 0]).buffer(1) js> var poly2 = poly1.transform({dx: 0.5, dy: 0.5}) js> poly1.difference(poly2) <Polygon [[[0.9095298326166407, -0.409529...>
  • 19. Projection Parse/encode WKT Full GeoTools EPSG database Re-projection
  • 20. Projection js> var proj = require(&quot;geoscript/proj&quot;); js> var p = proj.Projection(&quot;epsg:4326&quot;); js> p.wkt GEOGCS[&quot;WGS 84&quot;,    DATUM[&quot;World Geodetic System 1984&quot;,    ...
  • 21. Projection >>> from geoscript import geom >>> from geoscript.proj import Projection >>> p = Projection('epsg:4326') >>>  p.transform((-111, 45.7), 'epsg:26912') (500000.0, 5060716.313515949) >>> g = geom.Point(0, 0).buffer(4) >>> g = reduce(lambda x,y:x.union(y),[geom.transform(g,dx=x,dy=y)        for x,y in [(3,0),(0,3),(-3,0),(0,-3)]]) >>>  p.transform(g, 'epsg:26912') >>>  p.transform(g, 'epsg:3005') Reprojection WGS 84 UTM Albers
  • 22. Data Access Read and Write Layers Query Layers using CQL I/O  GeoJSON GML
  • 23. Data Access - Workspace js> var ws = require(&quot;geoscript/workspace&quot;);        js> var dir = ws.Directory(&quot;data&quot;);    js> dir           <Directory [&quot;states&quot;]> js> var states = dir.get(&quot;states&quot;); js> states <Layer name: states, count: 49>
  • 24. Data Access - Workspace >>  from geoscript.workspace import PostGIS >>  pg = PostGIS('spearfish') >>  pg.layers() ['archsites', 'bugsites', ..., 'streams'] >> l = pg['archsites']
  • 25. Data Access - Workspace >>> import geoscript.workspace.H2 >>> import geoscript.geom.Point >>> import geoscript.feature.Feature >>> h2 = new H2(&quot;name&quot;, &quot;path&quot;) >>> layer = h2.create(&quot;points&quot;, [     new Field(&quot;geom&quot;,&quot;Point&quot;),     new Field(&quot;name&quot;,&quot;String&quot;) ]) >>> layer.add([new Point[1,1],&quot;one&quot;])
  • 26. Data Access - Layers >>> from geoscript.layer import Shapefile >>> states = Shapefile('states.shp') >>> states = states.reproject('epsg:3005')
  • 27. Data Access - Layer Info >>> import geoscript.layer.Shapefile >>> shp = new Shapefile(&quot;states.shp&quot;) >>> shp.count 49 >>> shp.bounds (-124.73142200000001, 24.955967,-66.969849, 49.371735, EPSG:4326) >>> shp.schema.fields.each {   fld -> println fld} the_geom: MultiPolygon(EPSG:4326) STATE_NAME: String STATE_FIPS: String SUB_REGION: String STATE_ABBR: String
  • 28. Data Access - Layers js>  var ws = require(&quot;geoscript/workspace&quot;);        js>  var dir = ws.Directory(&quot;data&quot;);    js>  var states = dir.get(&quot;states&quot;); js> states.query(&quot;STATE_ABBR like 'M%'&quot;).forEach(   >     function(feature) {   >         print(feature.get(&quot;STATE_NAME&quot;));   >     }   > ) Maryland Missouri Mississippi ...
  • 29. Styling and Rendering Taming SLD Symbolizers Scale dependence Thematics
  • 30. Styling - Stroke >>>  from geoscript.style import Stroke >>>  Stroke('#000000', width=2) >>>  Stroke('black', width=2, dash=[5,5]) >>>  Stroke((0,0,0),width=2).hatch('vertline')
  • 31. Styling - Fill >>> import geoscript.style.Fill >>>  new Fill(&quot;gray&quot;) >>>  new Fill(&quot;gray&quot;, 0.5)) >>>  new Fill(&quot;gray&quot;).hatch(&quot;backslash&quot;) >>>  new Stroke(&quot;red&quot;,2) + new Fill(&quot;gray&quot;).hatch(&quot;times&quot;)
  • 32. Styling - Shape and Icon js> var style = require(&quot;geoscript/style&quot;); js> style.Shape({name: &quot;star&quot;, fill: &quot;yellow&quot;}) <Shape name: 'star', size: 6> js> style.Icon(&quot;rainy.svg&quot;) <Icon url: 'rainy.svg'>
  • 33. Styling - Labels >>>  from geoscript.style import Label,Stroke,Fill,Shape >>>  font = 'bold 16px Arial' >>> Shape() + Label('name',font)       .point(displace=(20,0)) >>> Stroke() + Label('name',font)       .linear(offset=10) >>>   Fill() + Label('name',font).halo('white',2)
  • 34. Styling - Scale >>> new Shape('#004d96', 5).range(3000)  + new Icon('school20.png').range(1500, 3000) + new Icon('school40.png').range(-1, 1500)
  • 35. Styling - Theming >>> from geoscript.style Stroke, Fill, Label >>> style = Stroke() + Label('STATE_ABBR', 14, 'Serif') >>> style += Fill('#4DFF4D', 0.7)       .where('PERSONS < 2000000') >>> style += Fill('#FF4D4D', 0.7)       .where('PERSONS BETWEEN 2000000 AND 4000000') >>> style += Fill('#4D4DFF', 0.7)       .where('PERSONS > 4000000')
  • 36. Demos
  • 37. Voronoi Diagram Example import geoscript.layer.* import geoscript.feature.* import geoscript.geom.* def shp = new Shapefile('states.shp') def schema = new Schema('states_voronoi',           [['the_geom','MultiPolygon','EPSG:4326']]) def diagramLayer = shp.workspace.create(schema) def geoms = shp.features.collect{f->      f.geom.centroid } def geomCol = new GeometryCollection(geoms) def voronoiGeom = geomCol.voronoiDiagram diagramLayer.add(schema.feature([voronoiGeom]))
  • 38. Gradient  Example var Directory = require(&quot;geoscript/workspace&quot;).Directory; var {Fill, gradient} = require(&quot;geoscript/style&quot;); var Map = require(&quot;geoscript/map&quot;).Map; var states = Directory(&quot;data&quot;).get(&quot;states&quot;); states.style = gradient({     expression: &quot;PERSONS / LAND_KM&quot;,      values: [0, 200],      styles: [Fill(&quot;#000066&quot;), Fill(&quot;red&quot;)],     classes: 10,      method: &quot;exponential&quot; }).and(     Fill(&quot;red&quot;).where(&quot;PERSONS / LAND_KM > 200&quot;) ); var map = Map([states]); map.render({path: &quot;states.png&quot;});
  • 39. Shapefile to PostGIS from geoscript.workspace import Directory, PostGIS shps = Directory('shapefiles') shps.layers() archsites = shps['archsites'] archsites.proj.id pg = PostGIS('demo') pg.layers() for layer in shps:   reprojected = shps[layer].reproject('epsg:4326')   pg.add(reprojected, name=layer) pg.layers() archsites = pg['archsites'] archsites.proj.id
  • 40. Road Map Raster Rendering WPS/GeoServer Map Printing
  • 41. Resources Web Site     http://geoscript.org Google Group     http://groups.google.com/group/geoscript Blog     http://geoscriptblog.blogspot.com GitHub      https://github.com/jdeolive/geoscript-py      https://github.com/tschaub/geoscript-js      https://github.com/dwins/geoscript.scala      https://github.com/jericks/geoscript-groovy     
  • 43. Centroids import geoscript.layer.* import geoscript.feature.* import geoscript.geom.* Shapefile shp = new Shapefile('states.shp') Schema schema = shp.schema.changeGeometryType('Point', 'states_centroids') Layer centroidLayer = shp.workspace.create(schema)   Cursor cursor = shp.cursor while(cursor.hasNext()) {     Feature f = cursor.next()     Map attributes = [:]     f.attributes.each{k,v ->        if (v instanceof Geometry) {            attributes[k] = v.centroid        }        else {           attributes[k] = v        }     }     Feature feature = schema.feature(attributes, f.id)     centroidLayer.add(feature) } cursor.close()  
  • 44. Shapefiles to PostGIS import geoscript.workspace.* import geoscript.layer.* def dir = new Directory(&quot;/Users/jericks/Downloads/wash&quot;) println(&quot;Shapefiles: ${dir.layers}&quot;) def postgis = new PostGIS('postgres','localhost','5432','public','postgres', 'postgres') println(&quot;PostGIS Layers: ${postgis.layers}&quot;) dir.layers.each{name->     def layer = dir.get(name)     println(&quot;Adding ${layer.name}...&quot;)     postgis.add(layer) }
  • 45. USGS Earth Quakes Read RSS Feed to a Shapefile
  • 46. import geoscript.geom.* import geoscript.feature.* import geoscript.layer.Layer import geoscript.workspace.Directory Schema s = new Schema('earthquakes'[['the_geom', 'Point', 'EPSG:4326'], ['title','String'], ['date', 'java.util.Date'], ['elevation', 'Double']]) Directory dir = new Directory('.') Layer layer = dir.create(s) def url = &quot;http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml&quot; def rss = new XmlParser().parse(url) int c = 0 String dateFormat = &quot;yyyy-MM-dd'T'HH:mm:ss'Z'&quot; rss.entry.each{e ->     def title = e.title.text()     def date = Date.parse(dateFormat, e.updated.text())     def coordinate = e.&quot;georss:point&quot;.text().split(&quot; &quot;)     double x = coordinate[1] as Double     double y = coordinate[0] as Double     def point = new Point(x,y)     def elev = e.&quot;georss:elev&quot;.text() as Double     Feature f = s.feature(['title':title,'date':date,       'elevation': elev, 'the_geom': point],&quot;earthquake_${c}&quot;)     layer.add(f)     c++ }
  • 47. Web Applications @GrabResolver(name=&quot;graffiti&quot;, root=&quot;http://simple-dm.googlecode.com/svn/repository&quot;) @Grab(&quot;com.goodercode:graffiti:1.0-SNAPSHOT&quot;) import graffiti.* import geoscript.geom.Geometry @Get(&quot;/buffer&quot;) def buffer() {     Geometry.fromWKT(params.geom).buffer(params.distance as double).wkt } @Get(&quot;/centroid&quot;) def centroid() {     Geometry.fromWKT(params.geom).centroid.wkt } @Get(&quot;/convexHull&quot;) def convexHull() {     Geometry.fromWKT(params.geom).convexHull.wkt } Graffiti.root 'graffiti' Graffiti.serve this Graffiti.start()      Graffiti Micro Web Framework
  • 49. Geometry Web Services Open Layers function centroid() {     var features = vectorLayer.features;     if (features.length == 0) {       alert(&quot;Please add some features!&quot;);     } else {       OpenLayers.loadURL('centroid', {             geom: wktFormat.write(features)           },            this,            function(request) {             var wkt = request.responseText;             var features = wktFormat.read(wkt);             if (features) vectorLayer.addFeatures(features);           },            function() {             alert(&quot;Error calculating centroids!&quot;);           }       );     } }
  • 50. WMS Server import com.sun.grizzly.http.embed.GrizzlyWebServer import com.sun.grizzly.http.servlet.ServletAdapter import groovy.servlet.GroovySerlvet @Grab(group='com.sun.grizzly',module='grizzly-servlet-webserver',  version='1.9.10') def start() {     def server = new GrizzlyWebServer(8080, &quot;web&quot;)     def servlet = new ServletAdapter()     servlet.contextPath = &quot;/geoscript&quot;     servlet.servletInstance = new GroovyServlet()     server.addGrizzlyAdapter(servlet, [&quot;/geoscript&quot;] as String[])     server.start() } start()
  • 51. WMS Server... import geoscript.map.Map import geoscript.style.* import geoscript.layer.Shapefile import geoscript.geom.Bounds def file = new File(&quot;states.shp&quot;) def shp = new Shapefile(file) shp.style = new Fill(&quot;steelblue&quot;) + new Stroke(&quot;wheat&quot;, 0.1) def map = new Map(     width: 256,      height: 256,      layers: [shp],     proj: shp.proj,     fixAspectRatio: false ) def bbox = request.getParameter(&quot;BBOX&quot;).split(&quot;,&quot;) def bounds = new Bounds(bbox[0] as double, bbox[1] as double, bbox[2] as double, bbox[3] as double) map.bounds = bounds response.contentType = &quot;image/png&quot; map.render(response.outputStream) map.close()
  • 52. Geometry Command line  echo &quot;POINT (1 1)&quot; | geoscript-groovy geom_buffer.groovy -d 10 | geoscript-groovy geom_envelope.groovy def cli = new CliBuilder(usage: 'geoscript-groovy geom_buffer.groovy -d') cli.d(longOpt: 'distance', 'buffer distance', args:1) cli.h(longOpt: 'help', 'Show usage information and quit') def opt = cli.parse(args) if(!opt) return if (opt.h || !opt.d) cli.usage() else println geoscript.geom.Geometry.fromWKT(System.in.text).buffer(opt.d as double).wkt def cli = new CliBuilder(usage: 'geoscript-groovy geom_envelope.groovy') cli.h(longOpt: 'help', 'Show usage information and quit') def opt = cli.parse(args) if(!opt) return if (opt.h) cli.usage() else println geoscript.geom.Geometry.fromWKT(System.in.text).bounds.geometry.wkt geom_buffer.groovy geom_envelope.groovy