2011年12月12日月曜日

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.feature.*
import org.geotools.feature.simple.*
import org.geotools.filter.*
import org.geotools.map.*
import org.geotools.renderer.lite.*
import org.geotools.styling.*
import org.geotools.geometry.jts.*
import com.vividsolutions.jts.geom.*
import org.geotools.data.*
import org.opengis.feature.type.*

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

// フィルタを作成
filter = ff.createCompareFilter(FilterType.COMPARE_EQUALS)
filter.addLeftValue(ff.createAttributeExpression("NAME"))
filter.addRightValue(ff.createLiteralExpression("JAPAN"))
fs = fs.getFeatures(filter)

// ポリゴンの線の色1
stroke1 = sf.createStroke(
  ff.literal(new Color(0x59, 0x58, 0x55)),
  ff.literal(1)
)

// ポリゴンの塗りつぶし色1
fill1 = sf.createFill(
  ff.literal(new Color(0xD2, 0xDB, 0xD5))
)
sym1 = sf.createPolygonSymbolizer(stroke1, fill1, null)

// フィルタに一致する場合のルールを作成
rule1 = sf.createRule()
rule1.symbolizers().add(sym1)

fts = sf.createFeatureTypeStyle([rule1] as Rule[])
style1 = sf.createStyle()
style1.featureTypeStyles().add(fts)

// レイヤーとして追加
map.addLayer(new FeatureLayer(fs, style1))


// ------------------------------------------
// ポイント用のレイヤーを作成
// ポイント用のタイプを作成
pointtype = DataUtilities.createType(
  "Location", 
  "the_geom:Point," + 
  "name:String"
)
sfb = new SimpleFeatureBuilder(pointtype)

// 東京を示すポイントを作成
// 経度
longitude = 139.6917064d
// 緯度
latitude = 35.6894875d
gf = JTSFactoryFinder.getGeometryFactory(null)
point = gf.createPoint(new Coordinate(longitude, latitude))
sfb.add(point)
sfb.add("tokyo")

col = FeatureCollections.newCollection()
feature1 = sfb.buildFeature(null)
col.add(feature1)

// マーカーの線
stroke2 = sf.createStroke(
  ff.literal(new Color(0xC8, 0x46, 0x63)),
  ff.literal(3)
)
// マーカーの塗りつぶし色
fill2 = sf.createFill(ff.literal(new Color(0xff, 0xC8, 0x61)))

// マーカーの形
mark = sf.getCircleMark()
mark.setFill(fill2)
mark.setStroke(stroke2)

graphic = sf.createDefaultGraphic()
graphic.graphicalSymbols().clear()
graphic.graphicalSymbols().add(mark)
graphic.setSize(ff.literal(10))

GeometryDescriptor geomDesc = fs.getSchema().getGeometryDescriptor()
geometryAttributeName = geomDesc.getLocalName()
sym2 = sf.createPointSymbolizer(graphic, geometryAttributeName)

rule2 = sf.createRule()
rule2.symbolizers().add(sym2)
fts2 = sf.createFeatureTypeStyle([rule2] as Rule[])
style2 = sf.createStyle()
style2.featureTypeStyles().add(fts2)
// レイヤーとして追加
map.addLayer(new FeatureLayer(col, style2))

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

width = 400
// 表示範囲を設定
bounds = new ReferencedEnvelope(longitude-1, longitude+1, latitude-1, latitude+1, 
  map.getViewport().getBounds().getCoordinateReferenceSystem()
)
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("around_tokyo.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/

0 件のコメント:

コメントを投稿