1 / 45

GeoScript

GeoScript. Spatial Capabilities for Scripting Languages Justin Deolivera and Jared Erickson. Scripting Platform for JVM Languages. Similar API  Respect languages differences     Python GeoScript should be Pythonic Make easy things easy, Make hard things possible. Groovy. Groovy 

zanta
Télécharger la présentation

GeoScript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. GeoScript Spatial Capabilities for Scripting Languages Justin Deolivera and Jared Erickson

  2. Scripting Platform for JVM Languages Similar API  Respect languages differences     Python GeoScript should be Pythonic Make easy things easy, Make hard things possible

  3. 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

  4. JavaScript

  5. 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

  6. Scala • 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/

  7. On the shoulders of giants...

  8. On the shoulders of giants... • Java Topology Suite (JTS) • Geometry API and Algorithms • GeoTools • DataStores • Features  • Coverages/Rasters  • Referencing • Renderering • Java Tribe Base libraries • GeoServer • uDig • Geomajas

  9. GeoScript Modules

  10. GeoScript Modules • Geometry • Projection • Feature • Layer • Workspace • Style • Renderer

  11. Geometry • Convenient constructors • I/O • WKT/WKB • JSON • GML • Plotting • Transforms

  12. Geometry Constructors >>> from geoscript import geom >>> geom.Point(30, 10) POINT(30 10) >>> geom.LineString((30,10), (10,20), (20,40), (40,40), (30,10)) LINESTRING (30 10, 10 20, 20 40, 40 40, 30 10) >>> geom.Polygon([(35,10), (10,20), (15,40), (45,45), (35,10)], [(20,30), (35,35), (30,20), (20,30)]) POLYGON ((35 10, 10 20, ... 30 20, 20 30)) >>> geom.MultiLineString([(10,10), (20,20), (10,40)],  [(40,40), (30,30), (40,20), (30,10)]) MULTILINESTRING ((10 10, 20 20, ... 40 20, 30 10))

  13. Geometry Input/Output >>> from geoscript import geom >>> point = geom.Point(30, 10) >>> geom.writeGML(point) <gml:Point xmlns:gml="http://www.opengis.net/gml">  <gml:coord>   <gml:X>30.0</gml:X>   <gml:Y>10.0</gml:Y>  </gml:coord> </gml:Point> >>> geom.readJSON('{"type":"Point","coordinates":[30,10]}') POINT(30 10) >>> geom.writeWKB(point) array('b', [0, 0, 0, 0, 1, 64, 62, ... 64, 36, 0, 0, 0, 0, 0, 0])

  14. Geometry Plotting >>> 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)

  15. Geometry Transforms >>> from geoscript.geom import Point, transform >>> from geoscript.render import draw >>> c = geom.Point(0, 0).buffer(10) >>> d = transform(c, dx=5) # translate >>> draw([c,d]) >>> e,f = transform(c, shx=0.5), transform(c, shx=-0.5) # shear >>> g = transform(c, sx=0.7) # scale >>> draw([e,f,g])

  16. Projection • Parse/encode WKT • Full GeoTools EPSG database • Re-projection

  17. Projection Constructors >>> from geoscript.proj import Projection >>> Projection('EPSG:4326') GEOGCS["WGS 84",    DATUM["World Geodetic System 1984",      SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],      AUTHORITY["EPSG","6326"]],    PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],    UNIT["degree", 0.017453292519943295],    AXIS["Geodetic longitude", EAST],    AXIS["Geodetic latitude", NORTH],    AUTHORITY["EPSG","4326"]] >>> p = Projection('GEOGCS[..."Degree",0.017453292519943295]]')  >>> p.id 'EPSG:4326'

  18. Projection Reprojection >>> from geoscript import geom, render >>> 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)]]) >>> render.draw(g) >>> render.draw(p.transform(g, 'epsg:26912')) >>>render.draw(p.transform(g, 'epsg:3005')) Albers WGS 84 UTM

  19. Data Access • Read and Write Layers • Query Layers using CQL • I/O  • GeoJSON • GML

  20. Data Access Workspaces >>> from geoscript.workspace import PostGIS >>> from geoscript import geom >>> pg = PostGIS('spearfish') >>> pg.layers()['archsites', 'bugsites', 'railroads', 'restricted', 'roads', 'streams'] >>> l = pg['bugsites'] >>> l.schema bugsites [cat: long, str1: str, the_geom: Point] >>> l = Layer('foo') >>> l.add([geom.Point(0,0)])  >>> l = pg.add(l)  >>> l = pg.create('bar', [('geom',geom.Point),('name',str)])

  21. Data Access Layers >>> from geoscript.layer import Shapefile >>> shp = Shapefile('states.shp') >>> shp.count()49 >>> shp.count('CARPOOL/PERSONS > 0.06') 26 >>> shp.bounds() (-124.731422, 24.955967, -66.969849, 49.371735, EPSG:4326) >>> shp.bounds("STATE_NAME = 'Colorado'") (-109.055199, 36.988972, -102.036758, 41.00341, EPSG:4326) >>> for f in shp.features(): ...print '%s has %f people' % (f['STATE_NAME'],f['PERSONS']) >>> for f in shp.features('CARPOOL/PERSONS > 0.06'): ...   print '%s likes to carpool' % f['STATE_NAME']

  22. Data Access Features >>> from geoscript.feature import Schema, Feature >>> from geoscript.geom import * >>> schema = Schema('shapes', [('geom',Polygon), ('name',str)])  >>> square = Feature([LineString((0,0),(1,1)).bounds().toPolygon(),       'square'], 0, schema) >>> square.id0 >>> square['name'] 'square' >>> square.geom POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))>>> square.geom = LineString((0,0),(2,1)).bounds().toPolygon() >>> square['name'] = 'rectangle' >>> circle = Feature({'geom':Point(0,0).buffer(1),'name':'circle'})

  23. Data Access Input/Output >>> from geoscript.feature import * >>> from geoscript.geom import Polygon >>> triangle = Feature({'geom':Polygon([(0,0),(1,1),(2,0),(0,0)])}) >>> writeGML(triangle) <gsf:feature fid="fid--272f9bd3_1322c34ca2d_-8000" xmlns:gml="http://www.opengis.net/gml" xmlns:gsf="http://geoscript.org/feature">  <gsf:geom>   <gml:Polygon>...</gml:Polygon>  </gsf:geom> </gsf:feature> >>> writeGML(triangle, version=3.2) ... >>> writeJSON(triangle) {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[0.0,0.0],[1,1],[2,0.0],[0.0,0.0]]]},"properties":{},"id":"fid--272f9bd3_1322c34ca2d_-8000"} >>> f = readJSON('{"type":"Feature", "geometry":{"type":"Point", "coordinates":[1.0, 2.0]}}') feature.fid--709b2d80_1322c512876_-8000 {geometry: POINT (1 2)}

  24. Styling and Rendering • Taming SLD • Symbolizers • Scale dependence • Thematics

  25. Styling Stroke >>> from geoscript.style import Stroke >>>from geoscript.render import draw >>> from geoscript.geom import * >>> line = LineString((0,0), (1,1)) >>> draw(line, Stroke('#000000', width=2))# normal >>> draw(line, Stroke('black', width=2, dash=[5,5]))# dash >>> draw(line, Stroke((0,0,0), width=2).hatch('vertline'))# hatch

  26. Styling Fill >>> from geoscript.style import Fill, Stroke >>> from geoscript.render import draw >>> from geoscript.geom import * >>> poly = Point(0,0).buffer(1) >>> draw(poly, Fill('gray')) # normal >>> draw(poly, Fill('gray', opacity=0.5)) # transparent >>> draw(poly, Fill('gray').hatch('backslash')) # hatch>>> draw(poly, Stroke('red',2) + Fill().hatch('times'))

  27. Styling Shape >>> from geoscript.style import Shape >>> from geoscript.render import draw >>> from geoscript.geom import * >>> mpoint = MultiPoint((0,0), (0,1), (1,1), (1,0), (0.5,0.5)) >>> draw(mpoint, Shape('black', 10)) >>> draw(mpoint, Shape('yellow', 20, 'star')) >>> draw(mpoint, Shape('red', 20, 'x'))

  28. Styling Icon >>> from geoscript.style import Icon >>> from geoscript.render import draw >>> from geoscript.geom import * >>> mpoint = MultiPoint((0,0), (0,1), (1,1), (1,0), (0.5,0.5)) >>> draw(mpoint, Icon('hospital.png')) >>> draw(mpoint, Icon('rainy.svg'))

  29. Styling Labels >>> from geoscript.style import Label, Stroke, Fill, Shape >>> from geoscript.feature import Feature >>> from geoscript.render import draw >>> from geoscript.geom import * >>> font = 'bold 16px Arial' >>>f = Feature({'geom': Point(0,0), 'name': 'foo'}) >>>draw(f,Shape() + Label('name', font).point(displace=(20,0))) >>> f = Feature({'geom': LineString((0,0), (1,1)), 'name': 'bar'}) >>>draw(f, Stroke() + Label('name', font).linear(offset=10)) >>> f = Feature({'geom': Point(0,0).buffer(1), 'name': 'baz'}) >>>draw(f, Fill() + Label('name', font).halo('white', 2))

  30. Styling Scale >>> from geoscript.style Shape, Icon, Label >>> from geoscript.render import draw >>> from geoscript.feature import Feature >>> from geoscript.geom import * >>> school = Feature({'loc': Point(0,0), 'name': 'J.L. Crowe'}) >>> style = Shape('#004d96', 5).range(min=3000)  >>>style += Icon('school20.png').range(max=3000, min=1500) >>>style += Icon('school40.png').range(max=1500) >>> bounds = Bounds(-100, -100, 100, 100, 'epsg:404000') >>> draw(school, style, bounds) >>> draw(school, style, bounds.scale(0.5)) >>> draw(school, style, bounds.scale(0.1))

  31. Styling Theming >>> from geoscript.style Stroke, Fill, Label >>> from geoscript.render import draw >>> from geoscript.layer import Shapefile >>> states = Shapefile('states.shp') >>> style = Stroke() + Label('STATE_ABBR', '14 "Times New Roman"') >>> 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') >>> draw(states, style)

  32. 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()

  33. Voronoi Diagram import geoscript.layer.* import geoscript.feature.* import geoscript.geom.* Shapefile shp = new Shapefile('states.shp') Schema schema = new Schema('states_voronoi',           [['the_geom','MultiPolygon','EPSG:4326']]) Layer diagramLayer = shp.workspace.create(schema) List geoms = shp.features.collect{f->     f.geom.centroid } GeometryCollection geomCol = new GeometryCollection(geoms) Geometry voronoiGeom = geomCol.voronoiDiagram diagramLayer.add(schema.feature([voronoiGeom]))

  34. Shapefiles to PostGIS import geoscript.workspace.* import geoscript.layer.* def dir = new Directory("/Users/jericks/Downloads/wash") println("Shapefiles: ${dir.layers}") def postgis = new PostGIS('postgres','localhost','5432','public','postgres', 'postgres') println("PostGIS Layers: ${postgis.layers}") dir.layers.each{name->     def layer = dir.get(name)     println("Adding ${layer.name}...")     postgis.add(layer) }

  35. USGS Earth Quakes Read RSS Feed to a Shapefile

  36. 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 = "http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml" def rss = new XmlParser().parse(url) int c = 0 String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" rss.entry.each{e ->     def title = e.title.text()     def date = Date.parse(dateFormat, e.updated.text())     def coordinate = e."georss:point".text().split(" ")     double x = coordinate[1] as Double     double y = coordinate[0] as Double     def point = new Point(x,y)     def elev = e."georss:elev".text() as Double     Feature f = s.feature(['title':title,'date':date,       'elevation': elev, 'the_geom': point],"earthquake_${c}")     layer.add(f)     c++ }

  37. Web Applications Graffiti Micro Web Framework @GrabResolver(name="graffiti", root="http://simple-dm.googlecode.com/svn/repository") @Grab("com.goodercode:graffiti:1.0-SNAPSHOT") import graffiti.* import geoscript.geom.Geometry @Get("/buffer") def buffer() {     Geometry.fromWKT(params.geom).buffer(params.distance as double).wkt } @Get("/centroid") def centroid() {     Geometry.fromWKT(params.geom).centroid.wkt } @Get("/convexHull") def convexHull() {     Geometry.fromWKT(params.geom).convexHull.wkt } Graffiti.root 'graffiti' Graffiti.serve this Graffiti.start()

  38. Geometry Web Services 

  39. Geometry Web ServicesOpen Layers function centroid() {    var features = vectorLayer.features;    if (features.length == 0) {       alert("Please add some features!");    } 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("Error calculating centroids!");          }       );    } }

  40. 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, "web")     def servlet = new ServletAdapter()     servlet.contextPath = "/geoscript"     servlet.servletInstance = new GroovyServlet()     server.addGrizzlyAdapter(servlet, ["/geoscript"] as String[])     server.start() } start()

  41. WMS Server... import geoscript.map.Map import geoscript.style.* import geoscript.layer.Shapefile import geoscript.geom.Bounds def file = new File("states.shp") def shp = new Shapefile(file) shp.style = new Fill("steelblue") + new Stroke("wheat", 0.1) def map = new Map(     width: 256,      height: 256,      layers: [shp],     proj: shp.proj,     fixAspectRatio: false ) def bbox = request.getParameter("BBOX").split(",") 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 = "image/png" map.render(response.outputStream) map.close()

  42. Geometry Command line  geom_buffer.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 echo "POINT (1 1)" | geoscript-groovy geom_buffer.groovy -d 10 | geoscript-groovy geom_envelope.groovy geom_envelope.groovy 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

  43. Road Map • Rendering Module • Raster Module • WPS/GeoServer plugin(s) • Map Printing

  44. 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

  45. Thank you!

More Related