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; } } }