📄 svgimporter.java
字号:
/**
*
*/
package com.esri.solutions.jitk.data.svg.importer;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.batik.svggen.SVGSyntax;
import org.apache.commons.codec.binary.Base64;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import com.esri.adf.web.data.GraphicElement;
import com.esri.adf.web.data.geometry.WebCircle;
import com.esri.adf.web.data.geometry.WebGeometry;
import com.esri.adf.web.data.geometry.WebPath;
import com.esri.adf.web.data.geometry.WebPoint;
import com.esri.adf.web.data.geometry.WebPolygon;
import com.esri.adf.web.data.geometry.WebPolyline;
import com.esri.adf.web.data.geometry.WebRing;
import com.esri.adf.web.data.geometry.WebSpatialReference;
import com.esri.adf.web.data.symbol.WebPictureMarkerSymbol;
import com.esri.adf.web.data.symbol.WebSimpleLineSymbol;
import com.esri.adf.web.data.symbol.WebSimpleMarkerSymbol;
import com.esri.adf.web.data.symbol.WebSimplePolygonSymbol;
import com.esri.adf.web.data.symbol.WebSymbol;
import com.esri.adf.web.data.symbol.WebTrueTypeMarkerSymbol;
import com.esri.solutions.jitk.data.svg.ColorEncoder;
import com.esri.solutions.jitk.data.svg.SVGIEException;
import com.esri.solutions.jitk.data.svg.SVGUtils;
import com.esri.solutions.jitk.web.data.geometry.WebArc;
public class SVGImporter extends DefaultHandler {
//private static final Logger _log = LogManager.getLogger(SVGReader.class);
private WebSpatialReference spatialReference = null;
private List<GraphicElement> points = new ArrayList<GraphicElement>();
private List<GraphicElement> labels = new ArrayList<GraphicElement>();
private List<GraphicElement> graphics = new ArrayList<GraphicElement>();
private List<GraphicElement> lines = new ArrayList<GraphicElement>();
private List<GraphicElement> polygons = new ArrayList<GraphicElement>();
private List<GraphicElement> arcs = new ArrayList<GraphicElement>();
private StringBuffer _characters = new StringBuffer();
private ArrayList<String> _svgSymbols;
private Hashtable<String,SVGPattern> _svgPatterns;
// Definitions
private boolean _readDefs = false;
// Geometries
private boolean _readG = false;
private Hashtable<String, String> _gAtts = null;
private GraphicElement _ge = null;
private LinkedList<GraphicElement> _gList = null;
private AffineTransform _tx = null;
// Metadata/CRS info
private boolean _readMetadata = false;
private String _crsName;
private String _crsCode;
private String _crsCodeSpace;
// Default stroke attributes
private String _defaultLineType;
private String _defaultLineColor;
private String _defaultLineWidth;
private String _defaultLineCapType;
private String _defaultLineJoinType;
private String _defaultLineColorOpacity;
// Default font attributes
private String _defaultFontFamily;
private String _defaultFontStyle;
private String _defaultFontSize;
private String _defaultFontWeight;
// Default fill attributes
private String _defaultFillColor;
private String _defaultFillColorOpacity;
// SVGPattern class is used while parsing <defs> section of svg document
// If more <pattern> parameters is needed expand it's parameters list and
// modify code appropriately
// For now only two parameters are read: id & fill color
private class SVGPattern {
private String id;
private String type;
private String fillColor;
private SVGPattern(String id) {
this.id = "";
this.type = "";
this.fillColor = "";
// Each pattern id must qualify to the following naming convention in order to be recognized as ADF fill type:
// id = "[pattern]_[bdiagonal | fdiagonal | cross | diagcross | horizontal | vertical | gray | lightgray | darkgray]_{unique modifier}..."
if(id != null && id.length() > 0) {
this.id = id;
String[] parts = id.split("_");
if(parts.length >= 2 && parts[0].equals(SVGSyntax.SVG_PATTERN_TAG) &&
(parts[1].equals(WebSimplePolygonSymbol.BDIAGONAL) || parts[1].equals(WebSimplePolygonSymbol.FDIAGONAL) ||
parts[1].equals(WebSimplePolygonSymbol.CROSS) || parts[1].equals(WebSimplePolygonSymbol.DIAGCROSS) ||
parts[1].equals(WebSimplePolygonSymbol.HORIZONTAL) || parts[1].equals(WebSimplePolygonSymbol.VERTICAL) ||
parts[1].equals(WebSimplePolygonSymbol.GRAY) || parts[1].equals(WebSimplePolygonSymbol.LIGHTGRAY) ||
parts[1].equals(WebSimplePolygonSymbol.DARKGRAY)))
this.type = parts[1];
}
}
private void setFillColor(String fillColor) {
this.fillColor = ColorEncoder.parseColor(fillColor);
}
private String getType() {
return this.type;
}
private String getFillColor() {
return this.fillColor;
}
public String getId() {
return this.id;
}
private boolean isValid() {
return !id.equals("") && !type.equals("") && !fillColor.equals("");
}
}
public SVGImporter() {}
public void read(InputStream iStream) throws SVGIEException {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(false);
SAXParser saxParser = factory.newSAXParser();
InputSource is = new InputSource(iStream);
is.setEncoding("UTF-8");
saxParser.parse(is, this);
}
catch (ParserConfigurationException e) { throw new SVGIEException(e.toString()); }
catch (SAXException e) { throw new SVGIEException(e.toString()); }
catch (IOException e) { throw new SVGIEException(e.toString()); }
}
public void read(String fileName) throws SVGIEException {
try {
File file = new File(fileName);
if(!file.exists())
throw new SVGIEException("'" + fileName + "' - doesn't exist.");
if(!file.isFile())
throw new SVGIEException("'" + fileName + "' - is not a file.");
else if(!file.canRead())
throw new SVGIEException("'" + fileName + "' - is not readable.");
else
read(file.toURI().toURL().openStream());
}
catch(MalformedURLException e) { throw new SVGIEException("'" + fileName + "' - is a malformed URL: " + e.toString()); }
catch(IOException e) { throw new SVGIEException("Can't read from '" + fileName + "': " + e.toString()); }
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startDocument()
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
spatialReference = null;
points = new ArrayList<GraphicElement>();
labels = new ArrayList<GraphicElement>();
graphics = new ArrayList<GraphicElement>();
lines = new ArrayList<GraphicElement>();
polygons = new ArrayList<GraphicElement>();
arcs = new ArrayList<GraphicElement>();
_characters = new StringBuffer();
// Definitions
_readDefs = false;
_svgPatterns = new Hashtable<String,SVGPattern>();
_svgSymbols = new ArrayList<String>();
// Geometries
_readG = false; _gAtts = null; _ge = null; _tx = null;
_gList = new LinkedList<GraphicElement>();
// Metadata/CRS info
_readMetadata = false; _crsName = ""; _crsCode = ""; _crsCodeSpace = "";
// Default stroke attributes
_defaultLineType = "";
_defaultLineColor = "";
_defaultLineWidth = "";
_defaultLineCapType = "";
_defaultLineJoinType = "";
_defaultLineColorOpacity = "";
// Default font attributes
_defaultFontFamily = "";
_defaultFontStyle = "";
_defaultFontSize = "";
_defaultFontWeight = "";
// Default fill attributes
_defaultFillColor = "";
_defaultFillColorOpacity = "";
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
super.startElement(uri, localName, qName, atts);
_characters = new StringBuffer();
// Parse transformation definition from <crs:CoordinateReferenceSystem> tag
if (_readMetadata && qName.equalsIgnoreCase("crs:CoordinateReferenceSystem"))
_tx = SVGParser.parseTransformList(atts.getValue("svg:transform"));
// Read <g> tag attributes and start reading its content
if (qName.equalsIgnoreCase(SVGSyntax.SVG_G_TAG)) {
if(atts.getLength() > 0) {
_gAtts = new Hashtable<String, String>();
for(int i=0; i < atts.getLength(); i++) {
_gAtts.put(atts.getQName(i), atts.getValue(i));
}
}
_readG = true;
}
// Read SVG document attributes
if(qName.equalsIgnoreCase(SVGSyntax.SVG_SVG_TAG)) {
// Read default line attributes
_defaultLineType = getAttributeValue(atts, SVGSyntax.SVG_STROKE_DASHARRAY_ATTRIBUTE, "none");
_defaultLineColor = getAttributeValue(atts, SVGSyntax.SVG_STROKE_ATTRIBUTE, "black");
_defaultLineWidth = getAttributeValue(atts, SVGSyntax.SVG_STROKE_WIDTH_ATTRIBUTE, "1");
_defaultLineCapType = getAttributeValue(atts, SVGSyntax.SVG_STROKE_LINECAP_ATTRIBUTE, "square");
_defaultLineJoinType = getAttributeValue(atts, SVGSyntax.SVG_STROKE_LINEJOIN_ATTRIBUTE, "miter");
_defaultLineColorOpacity = getAttributeValue(atts, SVGSyntax.SVG_STROKE_OPACITY_ATTRIBUTE, "1");
// Fill attributes
_defaultFillColor = getAttributeValue(atts, SVGSyntax.SVG_FILL_ATTRIBUTE, "black");
_defaultFillColorOpacity = getAttributeValue(atts, SVGSyntax.SVG_FILL_OPACITY_ATTRIBUTE, "1");
// Font attributes
_defaultFontFamily = getAttributeValue(atts, SVGSyntax.SVG_FONT_FAMILY_ATTRIBUTE, "Dialog");
_defaultFontStyle = getAttributeValue(atts, SVGSyntax.SVG_FONT_STYLE_ATTRIBUTE, "normal");
_defaultFontSize = getAttributeValue(atts, SVGSyntax.SVG_FONT_SIZE_ATTRIBUTE, "12");
_defaultFontWeight = getAttributeValue(atts, SVGSyntax.SVG_FONT_WEIGHT_ATTRIBUTE, "normal");
}
// Start reading Metadata section
if (qName.equalsIgnoreCase(SVGSyntax.SVG_METADATA_TAG))
_readMetadata = true;
// Start reading SVG document definitions
if (qName.equalsIgnoreCase(SVGSyntax.SVG_DEFS_TAG))
_readDefs = true;
if(_readDefs) readDefs(qName, atts);
if(_readG) readG(qName, atts);
}
private void readDefs(String qName, Attributes atts) {
// Read pattern
if(qName.equals(SVGSyntax.SVG_PATTERN_TAG)) {
SVGPattern pattern = new SVGPattern(getAttributeValue(atts, SVGSyntax.SVG_ID_ATTRIBUTE, ""));
pattern.setFillColor(ColorEncoder.parseColor(getAttributeValue(atts, SVGSyntax.SVG_STROKE_ATTRIBUTE, _defaultFillColor)));
if(pattern.isValid())
_svgPatterns.put(pattern.getId(), pattern);
}
// Read symbol
if(qName.equals(SVGSyntax.SVG_SYMBOL_TAG)) {
String sId = getAttributeValue(atts, SVGSyntax.SVG_ID_ATTRIBUTE, "");
if(sId != null && sId.length() > 0)
_svgSymbols.add(sId);
}
}
private void readG(String qName, Attributes atts) {
// Read text label
if(qName.equals(SVGSyntax.SVG_TEXT_TAG)) readText(atts);
// Read point marker symbol
if(qName.equals(SVGSyntax.SVG_USE_TAG)) readUse(atts);
// Read picture marker symbol
if(qName.equals(SVGSyntax.SVG_IMAGE_TAG)) readImage(atts);
// Read Polylines/Polygons/Arcs
if(qName.equals(SVGSyntax.SVG_PATH_TAG)) readPath(atts);
// Read Circle tag
if(qName.equals(SVGSyntax.SVG_CIRCLE_TAG)) readCircle(atts);
}
// This is a small helper method that is used for reading point geometry
// Text labels(svg <text> tag), marker symbols(svg <use> tag), graphics symbols(svg <image> tag)
// Method returns null if no geometry was read
private WebPoint readPointGeometry(Attributes atts) {
if(atts != null) {
double x = Double.NaN, y = Double.NaN;
if(atts.getIndex(SVGSyntax.SVG_X_ATTRIBUTE) != -1)
x = SVGUtils.toDouble(atts.getValue(SVGSyntax.SVG_X_ATTRIBUTE), Double.NaN);
if(atts.getIndex(SVGSyntax.SVG_Y_ATTRIBUTE) != -1)
y = SVGUtils.toDouble(atts.getValue(SVGSyntax.SVG_Y_ATTRIBUTE), Double.NaN);
if (x != Double.NaN && y != Double.NaN)
return new WebPoint(x, y);
}
return null;
}
private void newGraphicElement(WebGeometry geometry, WebSymbol symbol) {
GraphicElement ge = new GraphicElement();
ge.setGeometry(geometry);
ge.setSymbol(symbol);
_gList.add(ge);
}
private void readText(Attributes atts) {
WebPoint point = readPointGeometry(atts);
if(point != null) {
WebTrueTypeMarkerSymbol symbol = new WebTrueTypeMarkerSymbol();
symbol.setFontColor(ColorEncoder.parseColor(getAttributeValue(atts, SVGSyntax.SVG_FILL_ATTRIBUTE, _defaultLineColor)));
symbol.setTransparency(SVGUtils.toDouble(getAttributeValue(atts, SVGSyntax.SVG_STROKE_OPACITY_ATTRIBUTE, _defaultLineColorOpacity), 1));
symbol.setFontName(getAttributeValue(atts, SVGSyntax.SVG_FONT_FAMILY_ATTRIBUTE, _defaultFontFamily));
symbol.setFontStyle(getAttributeValue(atts, SVGSyntax.SVG_FONT_STYLE_ATTRIBUTE, _defaultFontStyle));
symbol.setFontSize(SVGUtils.toInt(getAttributeValue(atts, SVGSyntax.SVG_FONT_SIZE_ATTRIBUTE, _defaultFontSize), 12));
_ge = new GraphicElement();
_ge.setGeometry(point);
_ge.setSymbol(symbol);
}
}
private void readUse(Attributes atts) {
//<use xlink:href="#symbol_0" x="-151.21718377088305" y="24.66791550811567" width="8" height="8"/>
WebPoint point = readPointGeometry(atts);
if(point != null) {
// Each marker xlink:href attribute must qualify to the following naming convention in order to be recognized as ADF WebSimpleMarkerSymbol:
// xlink:href = "#[symbol]_[0 | 1 | 2 | 3 | 4]", where number is a WebSimpleMarkerSymbol marker type
String[] href = getAttributeValue(atts, SVGSyntax.XLINK_HREF_QNAME, "").split("_");
if(href.length == 2 && href[0].equals("#symbol") && _svgSymbols.contains("symbol_" + href[1])) {
int mType = SVGUtils.toInt(href[1], 0);
if(mType == WebSimpleMarkerSymbol.CIRCLE || mType == WebSimpleMarkerSymbol.CROSS ||
mType == WebSimpleMarkerSymbol.SQUARE || mType == WebSimpleMarkerSymbol.STAR ||
mType == WebSimpleMarkerSymbol.TRIANGLE) {
WebSimpleMarkerSymbol symbol = new WebSimpleMarkerSymbol();
symbol.setMarkerType(mType);
symbol.setWidth(SVGUtils.toInt(getAttributeValue(atts, SVGSyntax.SVG_WIDTH_ATTRIBUTE, "10"), 10));
symbol.setColor(ColorEncoder.parseColor(getAttributeValue(atts, SVGSyntax.SVG_FILL_ATTRIBUTE, _defaultFillColor)));
symbol.setOutlineColor(ColorEncoder.parseColor(getAttributeValue(atts, SVGSyntax.SVG_STROKE_ATTRIBUTE, _defaultLineColor)));
symbol.setTransparency(SVGUtils.toDouble(getAttributeValue(atts, SVGSyntax.SVG_FILL_OPACITY_ATTRIBUTE, _defaultFillColorOpacity), SVGUtils.toDouble(_defaultFillColorOpacity, 1)));
symbol.setAntialiasing(true);
newGraphicElement(point, symbol);
}
}
}
}
private void readImage(Attributes atts) {
/* <image xlink:href="data:image/png;base64,..." x="-77.02625298329355" y="52.78486061551436" width="44" height="20" xlink:type="simple" xlink:actuate="onLoad" xlink:show="embed" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none"/>
*/
WebPoint point = readPointGeometry(atts);
if(point != null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -