Sunday, January 15, 2012

GeoToolsで指定した地点に星マークを描画する

GeoToolsで指定した地点に星マークを描画するには、以下のコードを実行します。
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import javax.imageio.*;
import org.geotools.data.*;
import org.geotools.data.shapefile.*;
import org.geotools.data.simple.*;
import org.opengis.filter.*;
import org.geotools.factory.*;
import org.geotools.feature.*;
import org.geotools.feature.simple.*;
import org.geotools.geometry.jts.*;
import org.geotools.map.*;
import org.geotools.renderer.lite.*;
import org.geotools.styling.*;
import org.opengis.feature.simple.*;
import org.opengis.feature.type.*;
import org.opengis.referencing.crs.*;
import com.vividsolutions.jts.geom.*;

public class Geotools9
{
  public static void main(String args[])
    throws Exception
  {
    URL url = new URL("file://C:/share/geotools/world.shp");
    ShapefileDataStore shapefile = new ShapefileDataStore(url);

    SimpleFeatureSource fs = shapefile.getFeatureSource();
    // 国の名前でフィルタリング
    FilterFactory ff = CommonFactoryFinder.getFilterFactory2(null);
    Filter filter = ff.equals(
      ff.property("NAME"),
      ff.literal("JAPAN")
    );
    SimpleFeatureCollection sfc = fs.getFeatures(filter);

    SimpleFeatureType schema = sfc.getSchema();
    CoordinateReferenceSystem crs = 
      schema.getGeometryDescriptor().getCoordinateReferenceSystem();
    MapLayer layers[] = {};
    DefaultMapContext map = new DefaultMapContext(layers, crs);

    //スタイルを作成
    StyleFactory sf = CommonFactoryFinder.getStyleFactory(null);
    // ポリゴンの線の色
    org.geotools.styling.Stroke stroke1 = sf.createStroke(
      ff.literal(new Color(0x59, 0x58, 0x55)),
      ff.literal(1)
    );
    // ポリゴンの塗りつぶし色
    org.geotools.styling.Fill fill1 = sf.createFill(
      ff.literal(new Color(0xD2, 0xDB, 0xD5))
    );
    PolygonSymbolizer sym1 = sf.createPolygonSymbolizer(stroke1, fill1, null);

    // フィルタに一致する場合のルールを作成
    Rule rule1 = sf.createRule();
    rule1.symbolizers().add(sym1);
    rule1.setFilter(filter);
    Rule rules[] = {rule1};
    FeatureTypeStyle fts = sf.createFeatureTypeStyle(rules);
    Style style1 = sf.createStyle();
    style1.featureTypeStyles().add(fts);

    map.addLayer(new FeatureLayer(sfc, style1));

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

    // 金沢を示すポイントを作成
    // 経度
    double longitude = 136.27166748046875d;
    // 緯度
    double latitude = 36.578041001498704d;
    GeometryFactory gf = JTSFactoryFinder.getGeometryFactory(null);
    com.vividsolutions.jts.geom.Point point = gf.createPoint(new Coordinate(longitude, latitude));
    sfb.add(point);
    sfb.add("kanazawa");

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

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

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

    Graphic graphic = sf.createDefaultGraphic();
    graphic.graphicalSymbols().clear();
    graphic.graphicalSymbols().add(mark);
    graphic.setSize(ff.literal(20));

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

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

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

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

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

    ImageIO.write(image, "jpeg", new File("kanazawa.jpg"));
  }
}

出力画像

動作環境
JDK7 Update1, geotools 2.7.4

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

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

No comments: