GeoToolsでシェープファイル表示

 GeoToolsは、JavaのGISToolkit。
 こいつを使って、シェープファイルを表示してみる。

 ■準備
 GeoToolsからライブラリのダウンロードしてクラスパスを設定。
 ■ソースコード
 とりあえず、次のようなコードを書いてみた。
 なお、サンプルデータは、ESRI Japanのシェープファイルサンプル(全国市区町村界データ)を使用。
 

package test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.map.DefaultMapContext;
import org.geotools.map.MapContext;
import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Fill;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.SLD;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.Symbolizer;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.FeatureType;
import org.opengis.filter.FilterFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Polygon;

public class GeoTest1 {
	private final static StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null);
	private final static FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
	
	public GeoTest1(){
		JFrame f=new JFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().setLayout(new BorderLayout());
		f.setSize(640,480);
		f.setTitle("GeoTool Test");
		final ShapePanel sp=new ShapePanel();
		f.getContentPane().add(sp,BorderLayout.CENTER);
		final URL url=this.getClass().getResource("japan_ver62.shp");
		Runnable run=new Runnable(){
			@Override
			public void run() {
				try{
					final ShapeFileTest st=new ShapeFileTest(url);
					Runnable r=new Runnable(){
						public void run(){
							try{
								sp.map=st.map;
								sp.area=st.map.getLayerBounds();
								sp.renderer=st.renderer;
								sp.repaint();
							}catch(Exception e){}
						}
					};
					SwingUtilities.invokeLater(r);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		};
		new Thread(run).start();
		f.setVisible(true);
	}
	
	public static void main(String[] arg){
		GeoTest1 doit=new GeoTest1();
	}
	
	private class ShapePanel extends JComponent{

		private static final long serialVersionUID = 1L;
		private GTRenderer renderer;
		private MapContext map;
		private Envelope area;
		
		public ShapePanel(){
			super();
			super.setBackground(Color.WHITE);
		}

		@Override
		protected void paintComponent(Graphics arg0) {
			super.paintComponent(arg0);
			if(renderer!=null){
				double mapWidth=area.getWidth();
				double mapHeight=area.getHeight();
				double scaleX=getWidth()/area.getWidth();
				double scaleY=getHeight()/area.getHeight();
				double scale=1.0;
				if(scaleX<scaleY){
					scale=scaleX;
				}else{
					scale=scaleY;
				}
				double deltaX=Math.abs((getWidth()/scale)-mapWidth);
				double deltaY=Math.abs((getHeight()/scale)-mapHeight);
				Coordinate ll=new Coordinate(area.getMinX()-(deltaX/2.0),
						area.getMinY()-(deltaY/2.0));
				Coordinate ur=new Coordinate(area.getMaxX()+(deltaX/2.0),
						area.getMaxY()+(deltaY/2.0));
				area=new Envelope(ll,ur);
				RenderingHints rh=new RenderingHints(
						RenderingHints.KEY_ALPHA_INTERPOLATION,
						RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
				rh.add(new RenderingHints(
						RenderingHints.KEY_ANTIALIASING,
						RenderingHints.VALUE_ANTIALIAS_ON));
				rh.add(new RenderingHints(
						RenderingHints.KEY_TEXT_ANTIALIASING,
						RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
				renderer.setJava2DHints(rh);
				renderer.setContext(map);
				renderer.paint((Graphics2D)arg0,getBounds(),area);
			}
		}
		
	}
	
	private class ShapeFileTest{
		private GTRenderer renderer;
		private MapContext map;
		
		ShapeFileTest(URL url) throws MalformedURLException,IOException{
			ShapefileDataStore shapefile = new ShapefileDataStore(url);
			FeatureSource<SimpleFeatureType,SimpleFeature> featureSource 
				= shapefile.getFeatureSource();
			FeatureType schema = featureSource.getSchema();
			CoordinateReferenceSystem crs
				= schema.getGeometryDescriptor().getCoordinateReferenceSystem();
			map=new DefaultMapContext(crs);
			Style style=createStyle(new File(url.getFile()), schema);
			map.addLayer(featureSource, style);
			renderer=new StreamingRenderer();
		}
		
		private Style createStyle(File file, FeatureType schema) {
			File sld = toSLDFile(file);
			if (sld.exists())return createFromSLD(sld);
			Class<?> type = schema.getGeometryDescriptor().getType().getBinding();
			if(type.isAssignableFrom(Polygon.class)||
					type.isAssignableFrom(MultiPolygon.class)) {
				return createPolygonStyle();
			}else if (type.isAssignableFrom(LineString.class)||
					type.isAssignableFrom(MultiLineString.class)) {
				return createLineStyle();
			}else {
				return createPointStyle();
			}
		}
		
		public File toSLDFile(File file)  {
			String filename = file.getAbsolutePath();
			if (filename.endsWith(".shp")
					||filename.endsWith(".dbf")|| filename.endsWith(".shx")) {
				filename = filename.substring(0, filename.length() - 4);
				filename += ".sld";
			}else if(filename.endsWith(".SLD")
					|| filename.endsWith(".SLD")|| filename.endsWith(".SLD")) {
				filename = filename.substring(0, filename.length() - 4);
				filename += ".SLD";
			}
			return new File(filename);
		}
	    
		private Style createFromSLD(File sld) {
			SLDParser stylereader;
			try {
				stylereader = new SLDParser(styleFactory, sld.toURI().toURL());
				Style[] style = stylereader.readXML();
				return style[0];
			} catch (Exception e) {
				JOptionPane.showMessageDialog(null, e.getMessage());
				System.exit(0);
			}
			return null;
		}

		@SuppressWarnings("deprecation")
		private Style createPointStyle() {
			Style style;
			PointSymbolizer symbolizer = styleFactory.createPointSymbolizer();
			symbolizer.getGraphic().setSize(filterFactory.literal(1));
			Rule rule = styleFactory.createRule();
			rule.setSymbolizers(new Symbolizer[] { symbolizer });
			FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();
			fts.setRules(new Rule[] { rule });
			style = styleFactory.createStyle();
			style.addFeatureTypeStyle(fts);
			return style;
		}

		@SuppressWarnings("deprecation")
		private Style createLineStyle() {
			Style style;
			LineSymbolizer symbolizer = styleFactory.createLineSymbolizer();
			SLD.setLineColour(symbolizer, Color.BLUE);
			symbolizer.getStroke().setWidth(filterFactory.literal(1));
			symbolizer.getStroke().setColor(filterFactory.literal(Color.BLUE));
			Rule rule = styleFactory.createRule();
			rule.setSymbolizers(new Symbolizer[] { symbolizer });
			FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();
			fts.setRules(new Rule[] { rule });
			style = styleFactory.createStyle();
			style.addFeatureTypeStyle(fts);
			return style;
		}
	    
		@SuppressWarnings("deprecation")
		private Style createPolygonStyle(){
			Style style;
			PolygonSymbolizer symbolizer = styleFactory.createPolygonSymbolizer();
			Fill fill = styleFactory.createFill(
					filterFactory.literal("#FFAA00"),
					filterFactory.literal(0.5)
			);
			symbolizer.setFill(fill);
			Rule rule = styleFactory.createRule();        
			rule.setSymbolizers(new Symbolizer[] { symbolizer });
			FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();
			fts.setRules(new Rule[] { rule });
			style = styleFactory.createStyle();
			style.addFeatureTypeStyle(fts);
			return style;
		}
	}
	
}

 ■結果
 なんか、Deprecatedが多いが、とりあえず、表示できた。