メタデータの埋め込み仕様に従ってメタデータが埋め込まれたSVG Mapデータを生成するソフトウェアを、Shape to SVG Map Converterをもとにして作成しました。
メタデータのネームスペース宣言が適切ではないなどいくつかの問題点がありますが、このソフトウェアで変換したデータを、テキストエディタの正規表現による置換機能やXSLT等を用いて所望の描画スタイルを設定できると思います。
We publish the software which generates a SVG Map data where metadata was embedded according to the embedding specifications for the metadata based on Shape to SVG Map Converter.
It has some problems, such as a namespace declaration sentence of the metadata which cannot be said to be suitable. However, the data which this software generated is useful in order to carry out a rendition style set using XSLT, replacement functions of a text editor, etc.
// =============================================================================
// Meta-embedded SVG Map exporter program
//
// Copyright (C) 2008 by Satoru Takagi All rights reserved.
// http://www.svg-map.com/
//
// Usage: java Shape2SvgMapMeta shapefile.shp
//
// This program uses geoTools2.3.0
// =============================================================================
//
// This software is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =============================================================================
import java.io.*;
import java.io.IOException;
import java.net.URL;
import org.geotools.data.*;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.*;
import com.vividsolutions.jts.geom.*;
public class Shape2SvgMapMeta {
double boundHeight = 400.0; // SVG Height
double projCenter;
String fillColor = "green";
String strokeColor = "black";
double strokeWidth = 0.01;
// CRS:84 (WGS84 Long-Lat) This URI(URN) is ambiguous...
String CRS = "http://purl.org/crs/84";
double[] affineParam = new double[6];
FeatureType readFT;
String metaString;
public static void main(String[] args) {
Shape2SvgMapMeta s2sm = new Shape2SvgMapMeta();
try {
// Prepare an output SVG Map file
FileOutputStream osFile = new FileOutputStream( args[0] + ".svg" );
Writer fos = new BufferedWriter(new OutputStreamWriter( osFile , "UTF-8" ));
// Shape file
URL shapeURL = (new File(args[0])).toURL();
s2sm.parse( shapeURL , fos );
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void parse( URL shapeURL , Writer out ) throws Exception {
double maxX, minX, maxY, minY;
// Initialize shape file reader
ShapefileDataStore readStore = new ShapefileDataStore(shapeURL);
FeatureSource source = readStore.getFeatureSource();
readFT = source.getSchema();
// get envelope
Envelope env = source.getBounds();
maxX = env.getMaxX();
minX = env.getMinX();
maxY = env.getMaxY();
minY = env.getMinY();
// Make affine parameters for CRS metadata of SVG Map
// Equirectangular Projection (Standard parallel = Center of map)
//
// SVG_X = a * GEO_X + c * GEO_Y + e
// SVG_Y = b * GEO_X + d * GEO_Y + f
affineParam[1] = 0.0; // b
affineParam[2] = 0.0; // c
affineParam[3] = - boundHeight / ( maxY - minY ); // d
projCenter = ( maxY + minY ) / 2.0;
affineParam[0] = - affineParam[3] * Math.cos( projCenter * Math.PI / 180.0 ); // a
affineParam[4] = -affineParam[0] * minX; // e
affineParam[5] = -affineParam[3] * maxY; // f
// Make a SVG ViewBox
double origX , origY , cWidth , cHeight;
cWidth = Math.abs( ( maxX - minX ) * affineParam[0] );
cHeight = Math.abs( ( maxY - minY ) * affineParam[3] );
origX = affineParam[0] * minX + affineParam[4];
origY = affineParam[3] * maxY + affineParam[5];
// get FeatureCollection
FeatureCollection fsShape = source.getFeatures();
// Start SVG Map output
// SVG header etc.
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
out.write("<svg xmlns=\"http://www.w3.org/2000/svg\" ");
out.write("xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
out.write("xmlns:lm=\"http://www.svg-map.org/svgmap/localmetadata/\" ");
out.write("viewBox=\"" + origX + " " + origY + " " + cWidth + " " + cHeight + "\" >\n");
// metadata for SVG Map
out.write("<metadata>\n");
// CRS metadata
out.write(" <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" ");
out.write("xmlns:crs=\"http://opengis.org/xmldtds/transformations.dtd\" xmlns:svg=\"http://www.w3.org/2000/svg\">\n");
out.write(" <rdf:Description>\n");
out.write(" <crs:CoordinateReferenceSystem rdf:resource=\"" + CRS + "\" ");
out.write("svg:transform=\"matrix(" + affineParam[0] + "," + affineParam[1] + "," + affineParam[2]
+ "," + affineParam[3] + "," + affineParam[4] + "," + affineParam[5] +")\" />\n");
out.write(" </rdf:Description>\n");
out.write(" </rdf:RDF>\n");
out.write("</metadata>\n");
// Icon for Point
out.write("<defs>\n");
out.write(" <g id=\"p0\" >\n");
out.write("<circle cx=\"0.0\" cy=\"0.0\" r=\"" + (cWidth / 300) + "\" stroke=\"none\" />\n");
out.write(" </g>\n");
out.write("</defs>\n");
// Main data body
FeatureIterator reader = fsShape.features();
Feature oneFeature;
Geometry oneGeom;
Coordinate[] coord;
while (reader.hasNext()) {
oneFeature = reader.next();
metaString = getMetaString( oneFeature );
isChild = false;
oneGeom = oneFeature.getDefaultGeometry();
parseGeometry(oneGeom , out );
}
reader.close();
out.write("</svg>\n");
}
boolean isChild;
private void parseGeometry(Geometry geom , Writer out ) throws Exception {
Coordinate[] coord;
Coordinate oneCrd = new Coordinate();
if (geom instanceof Polygon ){
out.write("<path ");
if ( ! isChild ){ out.write(metaString);}
out.write("fill=\"" + fillColor + "\" fill-rule=\"evenodd\" d=\"M");
coord = (((Polygon)geom).getExteriorRing()).getCoordinates();
for ( int i = 0 ; i < coord.length ; i++ ){
if ( i!= 0 ){
out.write( "L" );
}
oneCrd = transform2D(coord[i] );
out.write( oneCrd.x + "," + oneCrd.y + " " );
}
out.write ("Z ");
for ( int j = 0 ; j < ((Polygon)geom).getNumInteriorRing() ; j++ ){
coord = (((Polygon)geom).getInteriorRingN(j)).getCoordinates();
for ( int i = 0 ; i < coord.length ; i++ ){
if ( i!= 0 ){
out.write( "L" );
} else {
out.write( "M" );
}
oneCrd = transform2D(coord[i] );
out.write( oneCrd.x + "," + oneCrd.y + " " );
}
out.write ("Z ");
}
out.write ("\"/>\n");
} else if (geom instanceof LineString ){
out.write("<polyline ");
if ( ! isChild ){ out.write(metaString);}
out.write("fill=\"none\" stroke-width=\"" + strokeWidth + "\" stroke=\"" + strokeColor + "\" points=\"");
coord = ((LineString)geom).getCoordinates();
for ( int i = 0 ; i < coord.length ; i++ ){
oneCrd = transform2D(coord[i] );
out.write( oneCrd.x + "," + oneCrd.y + " " );
}
out.write ("\"/>\n");
} else if (geom instanceof Point ){
oneCrd = transform2D(((Point)geom).getCoordinate() );
out.write("<use ");
if ( ! isChild ){ out.write(metaString);}
out.write("xlink:href=\"#p0\" fill=\"" + fillColor + "\"");
out.write(" x=\"" + oneCrd.x + "\"" + " y=\"" + oneCrd.y + "\"/>\n");
} else if (geom instanceof GeometryCollection ){
// out.write("<g ");
// if ( ! isChild ){ out.write(metaString);}
// out.write(">\n");
// isChild = true;
for ( int j = 0 ; j < ((GeometryCollection)geom).getNumGeometries() ; j++){
Geometry childGeom = ((GeometryCollection)geom).getGeometryN(j);
parseGeometry(childGeom , out);
}
// out.write("</g>\n");
} else if (geom instanceof Geometry ){
out.write("<!-- Type: Other Geometry...." + geom + "-->\n");
} else if (geom instanceof Object){
out.write("<!-- Type: Other Object...." + geom + "-->\n");
}
}
private Coordinate transform2D( Coordinate inCrd ){
Coordinate outCrd = new Coordinate(
affineParam[0] * inCrd.x + affineParam[2] * inCrd.y + affineParam[4] ,
affineParam[1] * inCrd.x + affineParam[3] * inCrd.y + affineParam[5] );
return (outCrd);
}
private String getMetaString( Feature oneFeature ){
StringBuffer metaString = new StringBuffer();
for ( int i = 0 ; i < readFT.getAttributeCount() ; i++){
if (oneFeature.getAttribute(i) instanceof Geometry == false ){
metaString.append("lm:");
metaString.append( readFT.getAttributeType(i).getName());
metaString.append("=\"");
metaString.append( oneFeature.getAttribute(i));
metaString.append( "\" ");
}
}
return ( metaString.toString() );
}
}