2011年11月30日水曜日

groovyとgeotoolsでポリゴンの色を指定する

groovyとgeotoolsでポリゴンの色を指定するには、以下のコードを実行します。
import java.awt.*
import java.awt.image.*
import javax.imageio.*
import org.geotools.data.shapefile.*
import org.geotools.factory.*
import org.geotools.filter.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*

url = new URL("file://C:/share/geotools/world.shp")
shapefile = new ShapefileDataStore(url)

fs = shapefile.getFeatureSource()
schema = fs.getSchema()
crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem()
map = new DefaultMapContext([] as MapLayer[], crs)

// スタイルを作成
ff = FilterFactoryFinder.createFilterFactory()
sf = CommonFactoryFinder.getStyleFactory()

// ポリゴンの線の色
stroke = sf.createStroke(
  ff.literal(new Color(47, 184, 27)),
  ff.literal(1)
)

// ポリゴンの塗りつぶし色
fill = sf.createFill(
  ff.literal(new Color(133, 255, 7))
)

sym = sf.createPolygonSymbolizer(stroke, fill, null)

rule = sf.createRule()
rule.symbolizers().add(sym)
fts = sf.createFeatureTypeStyle([rule] as Rule[])
style = sf.createStyle()
style.featureTypeStyles().add(fts)

map.addLayer(new FeatureLayer(fs, style))

// レンダリング
renderer = new StreamingRenderer()
renderer.setContext(map)

width = 400
bounds = map.getMaxBounds()
rect = new Rectangle(0, 0, width, 
  (int)(width * bounds.getHeight() / bounds.getWidth()))

image = new BufferedImage((int)rect.width, (int)rect.height, 
  BufferedImage.TYPE_INT_RGB)
gr = image.createGraphics()
gr.setPaint(Color.WHITE)
gr.fill(rect)
renderer.paint(gr, rect, bounds)

ImageIO.write(image, "jpeg", new File("polygon.jpg"))

出力画像

※世界地図のシェイプファイルは以下からダウンロード
World map for APRS
http://aprsworld.net/gisdata/world/

※.groovy/libからGROOVY_HOME/libにgeotools-2.7.3-bin.zipに
含まれるjarをコピーする

動作環境
groovy 1.8.2, JDK6 Update27, GeoTools 2.7.3

関連情報
・GeoToolsのウェブサイト
http://geotools.org/

2011年11月28日月曜日

groovyとgeotoolsで線の色と太さを指定する

groovyとgeotoolsで線の色と太さを指定するには、以下のコードを実行します。
import java.awt.*
import java.awt.image.*
import javax.imageio.*
import org.geotools.data.shapefile.*
import org.geotools.factory.*
import org.geotools.filter.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*

url = new URL("file://C:/share/geotools/world.shp")
shapefile = new ShapefileDataStore(url)

fs = shapefile.getFeatureSource()

// 国の名前でフィルタリング
ff = FilterFactoryFinder.createFilterFactory()
filter = ff.createCompareFilter(FilterType.COMPARE_EQUALS)
filter.addLeftValue(ff.createAttributeExpression("NAME"))
filter.addRightValue(ff.createLiteralExpression("JAPAN"))
fs = fs.getFeatures(filter)

schema = fs.getSchema()
crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem()
map = new DefaultMapContext([] as MapLayer[], crs)

// 線の色を水色にするスタイルを作成
sf = CommonFactoryFinder.getStyleFactory()
stroke = sf.createStroke(
  ff.literal(new Color(0x77, 0x99, 0xdd)),
  ff.literal(2)
)
sym = sf.createLineSymbolizer(stroke, null)

rule = sf.createRule()
rule.symbolizers().add(sym)
fts = sf.createFeatureTypeStyle([rule] as Rule[])
style = sf.createStyle()
style.featureTypeStyles().add(fts)

map.addLayer(new FeatureLayer(fs, style))

// レンダリング
renderer = new StreamingRenderer()
renderer.setContext(map)

width = 400
bounds = map.getMaxBounds()
rect = new Rectangle(0, 0, width, 
  (int)(width * bounds.getHeight() / bounds.getWidth()))

image = new BufferedImage((int)rect.width, (int)rect.height, 
  BufferedImage.TYPE_INT_RGB)
gr = image.createGraphics()
gr.setPaint(Color.WHITE)
gr.fill(rect)
renderer.paint(gr, rect, bounds)

ImageIO.write(image, "jpeg", new File("linecolor.jpg"))

出力画像

※世界地図のシェイプファイルは以下からダウンロード
World map for APRS
http://aprsworld.net/gisdata/world/

※.groovy/libからGROOVY_HOME/libにgeotools-2.7.3-bin.zipに
含まれるjarをコピーする

動作環境
groovy 1.8.2, JDK6 Update27, GeoTools 2.7.3

関連情報
・GeoToolsのウェブサイト
http://geotools.org/

2011年11月26日土曜日

groovyとgeotoolsで世界地図からOR条件で複数国をフィルタリングして描画する

groovyとgeotoolsで世界地図からOR条件で複数国をフィルタリングして描画するには、以下のコードを実行します。
import java.awt.*
import java.awt.image.*
import javax.imageio.*
import org.geotools.data.shapefile.*
import org.geotools.filter.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*

url = new URL("file://C:/share/geotools/world.shp")
shapefile = new ShapefileDataStore(url)

fs = shapefile.getFeatureSource()

countryNames = ["UNITED STATES", "CANADA"]
// OR条件で複数の国の名前でフィルタリング
ff = FilterFactoryFinder.createFilterFactory()
countries = []
for( name in countryNames ){
  filter = ff.createCompareFilter(FilterType.COMPARE_EQUALS)
  filter.addLeftValue(ff.createAttributeExpression("NAME"))
  filter.addRightValue(ff.createLiteralExpression(name))
  countries.add(filter)
}
orfilter = ff.or(countries)
fs = fs.getFeatures(orfilter)

schema = fs.getSchema()
crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem()
map = new DefaultMapContext([] as MapLayer[], crs)

// スタイルを作成
style = SLD.createSimpleStyle(schema)
map.addLayer(new FeatureLayer(fs, style))

// レンダリング
renderer = new StreamingRenderer()
renderer.setContext(map)

width = 400
bounds = map.getMaxBounds()
rect = new Rectangle(0, 0, width, 
  (int)(width * bounds.getHeight() / bounds.getWidth()))

image = new BufferedImage((int)rect.width, (int)rect.height, 
  BufferedImage.TYPE_INT_RGB)
gr = image.createGraphics()
gr.setPaint(Color.WHITE)
gr.fill(rect)
renderer.paint(gr, rect, bounds)

ImageIO.write(image, "jpeg", new File("us_and_canada.jpg"))

出力画像

※世界地図のシェイプファイルは以下からダウンロード
World map for APRS
http://aprsworld.net/gisdata/world/

※.groovy/libからGROOVY_HOME/libにgeotools-2.7.3-bin.zipに
含まれるjarをコピーする

動作環境
groovy 1.8.2, JDK6 Update27, GeoTools 2.7.3

関連情報
・GeoToolsのウェブサイト
http://geotools.org/

2011年11月24日木曜日

groovyとgeotoolsで世界地図から特定の国をフィルタリングして描画する

groovyとgeotoolsで世界地図から特定の国をフィルタリングして描画するには、以下のコードを実行します。
import java.awt.*
import java.awt.image.*
import javax.imageio.*
import org.geotools.data.shapefile.*
import org.geotools.filter.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*

url = new URL("file://C:/share/geotools/world.shp")
shapefile = new ShapefileDataStore(url)

fs = shapefile.getFeatureSource()

// 国の名前でフィルタリング
ff = FilterFactoryFinder.createFilterFactory()
filter = ff.createCompareFilter(FilterType.COMPARE_EQUALS)
filter.addLeftValue(ff.createAttributeExpression("NAME"))
filter.addRightValue(ff.createLiteralExpression("JAPAN"))
fs = fs.getFeatures(filter)

schema = fs.getSchema()
crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem()
map = new DefaultMapContext([] as MapLayer[], crs)

// スタイルを作成
style = SLD.createSimpleStyle(schema)
map.addLayer(new FeatureLayer(fs, style))

// レンダリング
renderer = new StreamingRenderer()
renderer.setContext(map)

width = 400
bounds = map.getMaxBounds()
rect = new Rectangle(0, 0, width, 
  (int)(width * bounds.getHeight() / bounds.getWidth()))

image = new BufferedImage((int)rect.width, (int)rect.height, 
  BufferedImage.TYPE_INT_RGB)
gr = image.createGraphics()
gr.setPaint(Color.WHITE)
gr.fill(rect)
renderer.paint(gr, rect, bounds)

ImageIO.write(image, "jpeg", new File("japan.jpg"))

出力画像

※世界地図のシェイプファイルは以下からダウンロード
World map for APRS
http://aprsworld.net/gisdata/world/

※.groovy/libからGROOVY_HOME/libにgeotools-2.7.3-bin.zipに
含まれるjarをコピーする

動作環境
groovy 1.8.2, JDK6 Update27, GeoTools 2.7.3

関連情報
・GeoToolsのウェブサイト
http://geotools.org/

2011年11月22日火曜日

groovyとjsoupでworldbank.orgから日本とUnited Statesの女性の人口割合を取得する

groovyとjsoupでworldbank.orgから日本とUnited Statesの女性の人口割合を取得するには、以下のコードを実行します。
@Grab(group='org.jsoup', module='jsoup', version='1.6.1')
import org.jsoup.*
import org.jsoup.select.*

// 日本とUnited Statesの女性の人口割合を取得
yearFrom = "2010"
yearTo = "2010"
countries = "jpn;usa"
base = "http://api.worldbank.org/countries/${countries}/indicators/SP.POP.TOTL.FE.ZS"
param = "?per_page=1000&date=${yearFrom}:${yearTo}"
doc = Jsoup.connect("${base}${param}").get()

for(elem in Selector.select("wb|data wb|data", doc)){
  // 国名
  country = elem.getElementsByTag("wb:country").eq(0).text()
  // 年
  year = elem.getElementsByTag("wb:date").eq(0).text()
  // 値
  value = elem.getElementsByTag("wb:value").eq(0).text()
  println("${country}:${year}:${value}")
}

動作環境
groovy 1.8.2, JDK6 Update27, jsoup 1.6.1

2011年11月20日日曜日

groovyとjsoupでworldbank.orgから日本の総人口に対する15歳~64歳の割合を取得する

groovyとjsoupでworldbank.orgから日本の総人口に対する15歳~64歳の割合を取得するには、以下のコードを実行します。
@Grab(group='org.jsoup', module='jsoup', version='1.6.1')
import org.jsoup.*
import org.jsoup.select.*

// 日本の15歳~64歳の人口割合を取得
yearFrom = "2006"
yearTo = "2010"
country = "jpn"
base = "http://api.worldbank.org/countries/${country}/indicators/SP.POP.1564.TO.ZS"
param = "?per_page=1000&date=${yearFrom}:${yearTo}"
doc = Jsoup.connect("${base}${param}").get()

for(elem in Selector.select("wb|data wb|data", doc)){
  // 国名
  country = elem.getElementsByTag("wb:country").eq(0).text()
  // 年
  year = elem.getElementsByTag("wb:date").eq(0).text()
  // 値
  value = elem.getElementsByTag("wb:value").eq(0).text()
  println("${country}:${year}:${value}")
}

動作環境
groovy 1.8.2, JDK6 Update27, jsoup 1.6.1

2011年11月18日金曜日

groovyでworldbank.orgから各地域・各国の人口増加率をJSON形式で取得する

groovyでworldbank.orgから各地域・各国の人口増加率をJSON形式で取得するには、以下のコードを実行します。
@Grab(group='org.jsoup', module='jsoup', version='1.6.1')
import groovy.json.*

// 各地域・各国の人口増加率を取得
yearFrom = "2010"
yearTo = "2010"
base = "http://api.worldbank.org/countries/all/indicators/SP.POP.GROW"
param = "?per_page=1000&date=${yearFrom}:${yearTo}&format=json"

result = "${base}${param}".toURL().text
slurper = new JsonSlurper()
json = slurper.parseText(result)

for(elem in json[1]){
  // 地域・国名
  country = elem.country.value
  // 年
  year = elem.date
  // 値
  value = elem.value
  println("${country}:${year}:${value}")
}

動作環境
groovy 1.8.2, JDK6 Update27, jsoup 1.6.1

2011年11月17日木曜日

groovyとsaxonでworldbank.orgから日本のCO2排出量をXQueryで取得する

groovyとsaxonでworldbank.orgから日本のCO2排出量をXQueryで取得するには、以下のコードを実行します。
@Grab(group='net.sf.saxon', module='saxon', version='8.7')
import net.sf.saxon.*
import net.sf.saxon.query.*
import org.xml.sax.*
import javax.xml.transform.sax.*
import javax.xml.transform.stream.*

// source url:CO2排出量(kt)
yearFrom = "2002"
yearTo = "2007"
countries = "jpn"
base = "http://api.worldbank.org/countries/${countries}/indicators/EN.ATM.CO2E.KT"
param = "?per_page=1000&date=${yearFrom}:${yearTo}"
sourceurl = "${base}${param}"

// XQuery
String query =
'''
declare namespace wb = "http://www.worldbank.org";
for $elem in //wb:data/wb:data
order by $elem/wb:date/text()
return 
<result> 
  <name>{$elem/wb:date/text()}</name>
  <value>{$elem/wb:value/text()}</value>
</result>
'''
println query

// XQueryを実行
conf = new Configuration()
sqc = new StaticQueryContext(conf)
dqc = new DynamicQueryContext(conf)
xq = sqc.compileQuery(query)
sqc =xq.getStaticContext()
di = sqc.buildDocument(new SAXSource(new InputSource(new URL(sourceurl).newInputStream())))
dqc.setContextNode(di)
xq.run(dqc, new StreamResult(System.out), new Properties())
動作環境
groovy1.8.2, JDK6 Update27, saxon 8.7

2011年11月16日水曜日

groovyとrabbitmqでパターンを指定して複数のキューにメッセージの送信を行う(topic exchange)

groovyとrabbitmqでパターンを指定して複数のキューにメッセージの送信を行う(topic exchangeを使用)には、以下のコードを実行します。
@Grab(group='com.rabbitmq', module='amqp-client', version='2.6.1')

import com.rabbitmq.client.*

factory = new ConnectionFactory()
factory.host = "localhost"
connection = factory.newConnection()
channel = connection.createChannel()
// topic exchangeを作成
exchangeName = "my_topic_exchange"
channel.exchangeDeclare(exchangeName, "topic")

// queueを作成&bind
queueName1 = "groovy_all_queue"
channel.queueDeclare(queueName1,
  true /*= durable */,
  false/*= exclusive*/,
  false /*= autoDelete*/,
  null /*= arguments */)
channel.queueBind(queueName1, exchangeName, "groovy.#")

queueName2 = "groovy_news_queue"
channel.queueDeclare(queueName2,
  true /*= durable */,
  false/*= exclusive*/,
  false /*= autoDelete*/,
  null /*= arguments */)
channel.queueBind(queueName2, exchangeName, "groovy.news.#")

// メッセージを送信
channel.basicPublish(exchangeName, "groovy.info", 
  MessageProperties.PERSISTENT_TEXT_PLAIN,
  "groovyの情報".getBytes("UTF-8"))
// メッセージを送信
channel.basicPublish(exchangeName, "groovy.news.release", 
  MessageProperties.PERSISTENT_TEXT_PLAIN,
  "new version is released!".getBytes("UTF-8"))
channel.close()
connection.close()
メッセージを受信するにはgroovyとrabbitmqでメッセージの送信・受信をおこなうの受信プログラムと同様にgroovy_all_queue, groovy_news_queueをコマンドライン引数に指定します。

動作環境
groovy 1.8.2, JDK6 Update26, rabbitmq 2.6.1

2011年11月15日火曜日

groovyとApache Commons Mathで相関係数を求める

groovyとApache Commons Mathで相関係数を求めるには、以下のコードを実行します。
@Grab(group='org.apache.commons', module='commons-math', version='2.2')
import org.apache.commons.math.stat.correlation.*

// 相関係数を求める
list1 = [100, 110, 120, 130, 150, 80, 110] as double[]
list2 = [102, 101, 100, 131, 155, 48, 100] as double[]
pc = new PearsonsCorrelation()
println "correlation coefficient:" + pc.correlation(list1, list2)

動作環境
groovy 1.8.2, JDK6 Update27, Apache Commons Math 2.2

groovyとgeotoolsで世界地図を描画する

groovyとgeotoolsで世界地図を描画するには、以下のコードを実行します。
import java.awt.*
import java.awt.image.*
import javax.imageio.*
import org.geotools.data.shapefile.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*

url = new URL("file://C:/share/geotools/world.shp")
shapefile = new ShapefileDataStore(url)

fs = shapefile.getFeatureSource()
schema = fs.getSchema()
crs = schema.getGeometryDescriptor().getCoordinateReferenceSystem()
map = new DefaultMapContext([] as MapLayer[], crs)

// スタイルを作成
style = SLD.createSimpleStyle(schema)
map.addLayer(new FeatureLayer(fs, style))

// レンダリング
renderer = new StreamingRenderer()
renderer.setContext(map)

width = 400
bounds = map.getMaxBounds()
rect = new Rectangle(0, 0, width, 
  (int)(width * bounds.getHeight() / bounds.getWidth()))

image = new BufferedImage((int)rect.width, (int)rect.height, 
  BufferedImage.TYPE_INT_RGB)
gr = image.createGraphics()
gr.setPaint(Color.WHITE)
gr.fill(rect)
renderer.paint(gr, rect, bounds)

ImageIO.write(image, "jpeg", new File("world.jpg"))
出力画像

※世界地図のシェイプファイルは以下からダウンロード
World map for APRS
http://aprsworld.net/gisdata/world/

※日本地図は国土地理院のウェブサイトからダウンロードできます。
ダウンロード・利用規約などは以下を参照。
http://www1.gsi.go.jp/geowww/globalmap-gsi/download/index.html

※.groovy/libからGROOVY_HOME/libにgeotools-2.7.3-bin.zipに
含まれるjarをコピーする

動作環境
groovy 1.8.2, JDK6 Update27, GeoTools 2.7.3

関連情報
・GeoToolsのウェブサイト
http://geotools.org/

2011年11月14日月曜日

gmongoでMapReduceを使用して配列フィールドの値をカウントする

gmongoでMapReduceを使用して配列フィールドの値をカウントするには、以下のコードを実行します。
@Grab(group='com.gmongo', module='gmongo', version='0.8')
import com.mongodb.*
import com.gmongo.*

mongo = new GMongo("localhost", 27017)
db = mongo.getDB("local")
db["articles"].drop()
// コレクションにオブジェクトを挿入する
col = db["articles"]
col.insert([url:"http://www.foo.com", tags:["groovy", "java"]])
col.insert([url:"http://www.bar.com", tags:["PHP"]])
col.insert([url:"http://www.baz.com", tags:["groovy"]])
// MapReduceでタグ毎の記事数を取得
println col.mapReduce(
  /* map */ """function(){
    for(var tl=0;tl<this.tags.length;tl++){
      emit(this.tags[tl], {count:1});
    }
  }""",
  /* reduce */ """function(key, values){
    var total = 0;
    for(var vi = 0;vi<values.length;vi++){
      total += values[vi].count;
    }
    return {count: total};
  }""",
  /* outputTarget */"mr_result",
  /* query */ new BasicDBObject()
)
// 結果を表示
db.mr_result.find().each {
  println it
}

動作環境
Groovy 1.8.0, JDK6 Update22, gmongo 0.8, MongoDB 2.0

関連情報
gmongoのウェブサイト
https://github.com/poiati/gmongo

groovyとMongoDBのまとめ