Rendering Maps in GeoScript Jared Erickson CUGOS September 2012 Friday, September 21, 2012
Jun 29, 2015
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