rendering maps in geoscript
DESCRIPTION
Rendering Maps in GeoScriptTRANSCRIPT
Rendering Maps in GeoScript
Jared Erickson
CUGOS September 2012
Friday, September 21, 2012
What is GeoScript?
• Geospatial Scripting on the JVM
• One API Four Languages
• Python
• JavaScript
• Scala
• Groovy
• Built on the shoulders of giants (GeoTools, JTS)
Friday, September 21, 2012
Java Tribe
Friday, September 21, 2012
GeoScript Modules
Friday, September 21, 2012
Styling
• geoscript.style module
• Symbolizer and Composite
• Symbolizer
• where: Filter
• range: min and max scale
• zindex: drawing order
• Composite: Two or more Symbolizers
Friday, September 21, 2012
Rendering
• geoscript.render module
• Draw and Plot shortcuts
• draw/plot to image, gui, or file
• Map for complicate rendering
• Image, PDF, SVG, GUI outputs
Friday, September 21, 2012
Stroke• Symbolizer for Linear geometries
• color, width, opacity, dash, cap, join, hatch, shape
1 import geoscript.layer.Shapefile2 import geoscript.style.Stroke3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Stroke("#999999",0.1)7 draw(shp)
Friday, September 21, 2012
Fill
• Symbolizer for Polygon geometries
• color, opacity,hatch,icon
1 import geoscript.layer.Shapefile2 import geoscript.style.Fill3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Fill("wheat",0.5)7 draw(shp, out: "fill.png")
Friday, September 21, 2012
Shape
• Symbolizer for Point geometries
• type, color, size, opacity, rotation, stroke1 import geoscript.layer.Shapefile2 import geoscript.style.Shape3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states_centroids.shp")6 shp.style = new Shape("#008080", 8, "circle", 0.55)7 draw(shp, out: "shape.png")
Friday, September 21, 2012
Icon
• Symbolizer using external files
• url, format (svg, png, gif, jpeg), size1 import geoscript.layer.Shapefile2 import geoscript.style.Icon3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states_centroids.shp")6 shp.style = new Icon("library.svg", "image/svg", 12)7 draw(shp, out: "icon.png")
Friday, September 21, 2012
Composite• Two or more Symbolizers
• Used to create complicated styles
1 import geoscript.layer.Shapefile2 import geoscript.style.*3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Fill("wheat",0.5) + new Stroke("black",0.2)7 draw(shp, out: "composite.png")
Friday, September 21, 2012
Where• Apply Symbolizers to some features
• Uses CQL or Common Query Language 1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import static geoscript.render.Draw.* 4 5 shp = new Shapefile("states.shp") 6 shp.style = new Stroke("black",0.1) + new Label(property: "STATE_ABBR", font: new Font(size: 14, family: "Serif")) 7 shp.style += new Fill("#4DFF4D", 0.7).where("PERSONS < 2000000") 8 shp.style += new Fill("#FF4D4D", 0.7).where("PERSONS BETWEEN 2000000 AND 4000000") 9 shp.style += new Fill("#4D4DFF", 0.7).where("PERSONS > 4000000")10 draw(shp, out: "where.png")
Friday, September 21, 2012
Z-index
• Order Symbolizers
1 import geoscript.layer.Shapefile2 import geoscript.style.Stroke3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Stroke("black",2.0).zindex(0) + new Stroke("white", 0.1).zindex(1)7 draw(shp, out: "zindex.png")
Friday, September 21, 2012
Scale• Scale dependent styles
1 import geoscript.geom.Bounds2 import geoscript.layer.Shapefile3 import geoscript.style.*4 import static geoscript.render.Draw.*5 6 shp = new Shapefile("states.shp")7 shp.style = (new Fill("wheat",0.5) + new Stroke("black",0.2)) + new Label("STATE_ABBR").font(size:24).range(max: 16000000)8 draw(shp, out: "scale1.png")9 draw(shp, out: "scale2.png", bounds: new Bounds(-105, 35, -95, 45))
Friday, September 21, 2012
Transform• Dynamically transform values
• String/Date formatting 1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import static geoscript.render.Draw.* 4 5 shp = new Shapefile("states.shp") 6 shp.style = (new Fill("#E6E6E6") + new Stroke("#4C4C4C",0.5)) + 7 (new Shape("#66CCff", 6, "circle").stroke("#004080") + new Transform("centroid(the_geom)")).zindex(1) + 8 (new Label("STATE_ABBR").font(new Font("normal", "bold", 10, "serif")).fill(new Fill("#004080"))) 9 10 draw(shp, out: "function.png")
Friday, September 21, 2012
Expressions• geoscript.filter module
• Most style properties are Expressions
• Expression, Property, Function, Color
1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import geoscript.filter.Function 4 import static geoscript.render.Draw.* 5 6 shp = new Shapefile("states.shp") 7 shp.style = (new Fill("#E6E6E6") + new Stroke("#4C4C4C",0.5)) + 8 (new Label(new Function("strToLowerCase(STATE_ABBR)")).font(new Font("normal", "bold", 20, "serif")).fill(new Fill("#004080"))) 9 10 draw(shp, out: "expression.png")
Friday, September 21, 2012
Gradient 1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import geoscript.filter.Expression 4 import static geoscript.render.Draw.* 5 6 shp = new Shapefile("states.shp") 7 shp.style = new Gradient( 8 new Expression("PERSONS / LAND_KM"), 9 [0,200],10 [new Fill("#000066") + new Stroke("black",0.1),11 new Fill("red") + new Stroke("black", 0.1)],12 10,13 "exponential")14 15 draw(shp, out: "gradient.png")
Friday, September 21, 2012
Another Gradient
1 import geoscript.layer.Shapefile2 import geoscript.style.*3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Gradient(shp, "WORKERS", "Quantile", 5, "Greens")7 draw(shp, out: "gradient2.png")
• Color brewer: geoscript.filter.Color
• getPaletteNames(String type = “all”)
• getPaletteColors(String name, int count = -1)
Friday, September 21, 2012
Unique Values
• Symbolizer for unique values
• colors can be palette name, closure, or list1 import geoscript.layer.Shapefile2 import geoscript.style.UniqueValues3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new UniqueValues(shp, "STATE_ABBR", "Greens")7 draw(shp, out: "uniquevalues.png")
Friday, September 21, 2012
SLD• The standard way of styling GIS data
• Kind of verbose
• geoscript.style.io module can read and write SLD
1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import geoscript.style.io.* 4 import static geoscript.render.Draw.* 5 6 def style = new Fill("#E6E6E6") + new Stroke("#4C4C4C",0.5) 7 new SLDWriter().write(style, new File("states.sld")) 8 9 shp = new Shapefile("states.shp")10 shp.style = new SLDReader().read(new File("states.sld"))11 draw(shp, out: "sld.png")
Friday, September 21, 2012
1 <?xml version="1.0" encoding="UTF-8"?> 2 <sld:UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"> 3 <sld:Name>Default Styler</sld:Name> 4 <sld:Title/> 5 <sld:FeatureTypeStyle> 6 <sld:Name>name</sld:Name> 7 <sld:Rule> 8 <sld:PolygonSymbolizer> 9 <sld:Fill>10 <sld:CssParameter name="fill">#E6E6E6</sld:CssParameter>11 </sld:Fill>12 </sld:PolygonSymbolizer>13 <sld:LineSymbolizer>14 <sld:Stroke>15 <sld:CssParameter name="stroke">#4C4C4C</sld:CssParameter>16 <sld:CssParameter name="stroke-width">0.5</sld:CssParameter>17 </sld:Stroke>18 </sld:LineSymbolizer>19 </sld:Rule>20 </sld:FeatureTypeStyle>21 </sld:UserStyle>
1 def style = new Fill("#E6E6E6") + new Stroke("#4C4C4C",0.5)
SLD
vs
Friday, September 21, 2012
CSS• CSS for maps!
• Read only 1 import geoscript.layer.Shapefile 2 import geoscript.style.* 3 import geoscript.style.io.* 4 import static geoscript.render.Draw.* 5 6 shp = new Shapefile("states.shp") 7 shp.style = new CSSReader().read(""" 8 states { 9 fill: "#FFEBC3";10 stroke: "#342D36";11 }12 """) 13 draw(shp, out: "css.png")
Friday, September 21, 2012
Map• geoscript.render.Map
• Good for complicated maps with many layers
Friday, September 21, 2012
Map 1 import geoscript.layer.Shapefile 2 import geoscript.layer.io.CsvReader 3 import geoscript.style.* 4 import geoscript.render.Map 5 6 def dir = "/Users/jericks/Projects/NaturalEarth/SmallScale" 7 8 def ocean = new Shapefile("${dir}/110m_Physical/110m_ocean.shp") 9 ocean.style = new Fill("#66CCFF")10 11 def countries = new Shapefile("${dir}/110m_Cultural/110m_admin_0_countries.shp")12 countries.style = new Stroke("#666666",0.5) + new Fill("#E6E6E6")13 14 def graticlues = new Shapefile("${dir}/110m_physical/110m_graticules_all/110m_graticules_30.shp")15 graticlues.style = new Stroke("#CCCCCC",0.1)16 17 def bbox = new Shapefile("${dir}/110m_physical/110m_graticules_all/110m_wgs84_bounding_box.shp")18 bbox.style = new Stroke("#4C4C4C",0.8)19 20 def pplaces = new Shapefile("${dir}/110m_cultural/110m_populated_places.shp")21 pplaces.style = new Shape("#CCCCCC",3,"circle",0.55).stroke("#B3B3B3")22
Friday, September 21, 2012
23 def earthquakes = new CsvReader("Lon","Lat").read(24 new URL("http://earthquake.usgs.gov/earthquakes/catalogs/eqs7day-M2.5.txt").text25 )26 earthquakes.style = (new Shape("#FF6666", 4, "circle").stroke("#8000000",0.1)).where("Magnitude < 3")27 earthquakes.style += (new Shape("#FF6666", 6, "circle").stroke("#8000000",0.1)).where("Magnitude BETWEEN 3 AND 6")28 earthquakes.style += (new Shape("#FF6666", 10, "circle").stroke("#8000000",0.1)).where("Magnitude > 6")29 30 def map = new Map(layers: [ocean,countries,graticlues,bbox,pplaces,earthquakes])31 map.render(new File("map.png"))
Map...
Friday, September 21, 2012
PDF1 import geoscript.layer.Shapefile2 import geoscript.style.*3 import geoscript.render.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Fill("wheat",0.5) + new Stroke("black",0.2)7 Map map = new Map(layers:[shp])8 Pdf pdf = new Pdf()9 pdf.render(map, new FileOutputStream(new File("map.pdf")))
Friday, September 21, 2012
SVG1 import geoscript.layer.Shapefile2 import geoscript.style.*3 import static geoscript.render.Draw.*4 5 shp = new Shapefile("states.shp")6 shp.style = new Fill("wheat",0.5) + new Stroke("black",0.2)7 draw(shp, out: "map.svg", format: "svg")
Friday, September 21, 2012
Uses
• Quickly view results of analysis
• Preview & Create SLD
• Creating map series
• Simple WMS/TMS/WMST services
• UTF-8, MBTiless
Friday, September 21, 2012
Thank you!
Friday, September 21, 2012