/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2008, Open Source Geospatial Foundation (OSGeo)
*
* This library 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;
* version 2.1 of the License.
*
* 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.
*/
package org.geotools.xacml.geoxacml.attr;
import java.util.List;
import java.util.Map;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
/**
*
* Class for supporting GML2 encoding and GML2 Parsing
*
* @author Christian Mueller
*
*/
public class GML2Support extends GMLSupport {
public final static GMLSupport Singleton = new GML2Support();
public final static String GML_POINT = "http://www.opengis.net/gml#Point";
public final static String GML_BOX = "http://www.opengis.net/gml#Box";
public final static String GML_LINESTRING = "http://www.opengis.net/gml#LineString";
public final static String GML_LINEARRING = "http://www.opengis.net/gml#LinearRing";
public final static String GML_POLYGON = "http://www.opengis.net/gml#Polygon";
public final static String GML_MULTIPOINT = "http://www.opengis.net/gml#MultiPoint";
public final static String GML_MULTILINESTRING = "http://www.opengis.net/gml#MultiLineString";
public final static String GML_MULTIPOLYGON = "http://www.opengis.net/gml#MultiPolygon";
GeometryAttribute buildFromGML(Node gmlNode) throws Exception {
NamedNodeMap attrMap = gmlNode.getAttributes();
Node n = attrMap.getNamedItem("gid");
String gid = n == null ? null : n.getTextContent();
n = attrMap.getNamedItem("srsName");
String srsName = n == null ? null : n.getTextContent();
if ("Box".equals(gmlNode.getLocalName())) {
Polygon p = parseBox(gmlNode);
GeometryAttribute attr = new GeometryAttribute(p, srsName, gid, GMLVersion.Version2,
GML_BOX);
return attr;
}
if ("Point".equals(gmlNode.getLocalName())) {
Point p = parsePoint(gmlNode);
GeometryAttribute attr = new GeometryAttribute(p, srsName, gid, GMLVersion.Version2,
GML_POINT);
return attr;
}
if ("LineString".equals(gmlNode.getLocalName())) {
LineString ls = parseLineString(gmlNode);
GeometryAttribute attr = new GeometryAttribute(ls, srsName, gid, GMLVersion.Version2,
GML_LINESTRING);
return attr;
}
if ("LinearRing".equals(gmlNode.getLocalName())) {
LinearRing lr = parseLinearRing(gmlNode);
GeometryAttribute attr = new GeometryAttribute(lr, srsName, gid, GMLVersion.Version2,
GML_LINEARRING);
return attr;
}
if ("Polygon".equals(gmlNode.getLocalName())) {
Polygon poly = parsePolygon(gmlNode);
GeometryAttribute attr = new GeometryAttribute(poly, srsName, gid, GMLVersion.Version2,
GML_POLYGON);
return attr;
}
if ("MultiPoint".equals(gmlNode.getLocalName())) {
MultiPoint mp = parseMultiPoint(gmlNode);
GeometryAttribute attr = new GeometryAttribute(mp, srsName, gid, GMLVersion.Version2,
GML_MULTIPOINT);
return attr;
}
if ("MultiLineString".equals(gmlNode.getLocalName())) {
MultiLineString mls = parseMultiLineString(gmlNode);
GeometryAttribute attr = new GeometryAttribute(mls, srsName, gid, GMLVersion.Version2,
GML_MULTILINESTRING);
return attr;
}
if ("MultiPolygon".equals(gmlNode.getLocalName())) {
MultiPolygon mp = parseMultiPolygon(gmlNode);
GeometryAttribute attr = new GeometryAttribute(mp, srsName, gid, GMLVersion.Version2,
GML_MULTIPOLYGON);
return attr;
}
return null;
}
void encodeASGML(GeometryAttribute attr, StringBuffer buff) {
Map<String, String> abstractGeometryAttributeMap = abstractGeometryAttribueMap(attr);
abstractGeometryAttributeMap.put("xmlns:" + GMLNS_PREFIX, GMLNS);
if (GML_POINT.equals(attr.getGmlType()))
encodePoint((Point) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_BOX.equals(attr.getGmlType()))
encodeBox((Polygon) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_LINESTRING.equals(attr.getGmlType()))
encodeLineString((LineString) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_LINEARRING.equals(attr.getGmlType()))
encodeLinearRing((LinearRing) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_POLYGON.equals(attr.getGmlType()))
encodePolygon((Polygon) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_MULTIPOINT.equals(attr.getGmlType()))
encodeMultiPoint((MultiPoint) attr.getGeometry(), buff, abstractGeometryAttributeMap);
if (GML_MULTILINESTRING.equals(attr.getGmlType()))
encodeMultiLineString((MultiLineString) attr.getGeometry(), buff,
abstractGeometryAttributeMap);
if (GML_MULTIPOLYGON.equals(attr.getGmlType()))
encodeMultiPolygon((MultiPolygon) attr.getGeometry(), buff,
abstractGeometryAttributeMap);
}
protected void encodeCoordinates(CoordinateSequence coordinates, StringBuffer buf) {
encodeStartTag("coordinates", buf, null);
for (int i = 0; i < coordinates.size(); i++) {
Coordinate c = coordinates.getCoordinate(i);
buf.append(c.x);
boolean y = (coordinates.getDimension() > 1) && !new Double(c.y).isNaN();
if (y)
buf.append("," + c.y);
boolean z = y && (coordinates.getDimension() > 2) && !new Double(c.z).isNaN();
if (z)
buf.append("," + c.z);
if (i < (coordinates.size() - 1))
buf.append(" ");
}
encodeEndTag("coordinates", buf);
;
}
public Polygon parseBox(Node node) throws GMLException {
List<Node> coordinates = getChildren(node, "coord");
if (!coordinates.isEmpty() && (coordinates.size() == 2)) {
Node n1 = (Node) coordinates.get(0);
Node n2 = (Node) coordinates.get(1);
Coordinate c1 = parseCoordGML2(n1);
Coordinate c2 = parseCoordGML2(n2);
return toGeometry(new Envelope(c1.x, c2.x, c1.y, c2.y));
}
if (!coordinates.isEmpty()) {
throw new GMLException("Envelope can have only two coordinates");
}
Node coords = getChild(node, "coordinates");
if (coords != null) {
CoordinateSequence cs = parseCoordinatesGML2(coords);
if (cs.size() != 2) {
throw new GMLException("Envelope can have only two coordinates");
}
return toGeometry(new Envelope(cs.getX(0), cs.getX(1), cs.getY(0), cs.getY(1)));
}
throw new GMLException("Could not find coordinates for envelope");
}
public LineString parseLineString(Node node) throws GMLException {
LineString ls = parseLineStringGML2(node);
if (ls == null)
throw new GMLException("Could not find \"coord\" or \"coordinates\" for LineString");
return ls;
}
public Polygon parsePolygon(Node node) throws GMLException {
Node outer = getChild(node, "outerBoundaryIs");
Node lr = getChild(outer, "LinearRing");
LinearRing extRing = parseLinearRing(lr);
List<Node> innerList = getChildren(node, "innerBoundaryIs");
LinearRing[] innerRings = new LinearRing[innerList.size()];
for (int i = 0; i < innerRings.length; i++) {
lr = getChild(innerList.get(i), "LinearRing");
innerRings[i] = parseLinearRing(lr);
}
return gf.createPolygon(extRing, innerRings);
}
public LinearRing parseLinearRing(Node node) throws GMLException {
LinearRing lr = parseLinearRingGML2(node);
if (lr == null)
throw new GMLException("Could not find \"coord\" or \"coordinates\" for LinearRing");
return lr;
}
public void encodeBox(Polygon poly, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("Box", buff, abstractGeometryAttributeMap);
Envelope env = poly.getEnvelopeInternal();
Coordinate[] array = new Coordinate[] { new Coordinate(env.getMinX(), env.getMinY()),
new Coordinate(env.getMaxX(), env.getMaxY()) };
CoordinateSequence sequence = csFactory.create(array);
encodeCoordinates(sequence, buff);
encodeEndTag("Box", buff);
}
public void encodeLineString(LineString ls, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("LineString", buff, abstractGeometryAttributeMap);
encodeCoordinates(ls.getCoordinateSequence(), buff);
encodeEndTag("LineString", buff);
}
public void encodeLinearRing(LinearRing lr, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("LinearRing", buff, abstractGeometryAttributeMap);
encodeCoordinates(lr.getCoordinateSequence(), buff);
encodeEndTag("LinearRing", buff);
}
public Point parsePoint(Node node) throws GMLException {
Point p = parsePointGML2(node);
if (p == null)
throw new GMLException("Could not find a \"coordinate\" odr \"coord\" for Point");
return p;
}
public MultiPoint parseMultiPoint(Node node) throws GMLException {
List<Node> pointMemberList = getChildren(node, "pointMember");
Point[] array = new Point[pointMemberList.size()];
for (int i = 0; i < pointMemberList.size(); i++) {
Node pointNode = getChild(pointMemberList.get(i), "Point");
array[i] = parsePoint(pointNode);
}
return gf.createMultiPoint(array);
}
public MultiLineString parseMultiLineString(Node node) throws GMLException {
List<Node> lsMemberList = getChildren(node, "lineStringMember");
LineString[] array = new LineString[lsMemberList.size()];
for (int i = 0; i < lsMemberList.size(); i++) {
Node lsNode = getChild(lsMemberList.get(i), "LineString");
array[i] = parseLineString(lsNode);
}
return gf.createMultiLineString(array);
}
public MultiPolygon parseMultiPolygon(Node node) throws GMLException {
List<Node> polygonMemberList = getChildren(node, "polygonMember");
Polygon[] array = new Polygon[polygonMemberList.size()];
for (int i = 0; i < polygonMemberList.size(); i++) {
Node polygonNode = getChild(polygonMemberList.get(i), "Polygon");
array[i] = parsePolygon(polygonNode);
}
return gf.createMultiPolygon(array);
}
public void encodePoint(Point p, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("Point", buff, abstractGeometryAttributeMap);
CoordinateSequence sequence = csFactory.create(p.getCoordinates());
encodeCoordinates(sequence, buff);
encodeEndTag("Point", buff);
}
public void encodePolygon(Polygon poly, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("Polygon", buff, abstractGeometryAttributeMap);
encodeStartTag("outerBoundaryIs", buff, null);
encodeStartTag("LinearRing", buff, null);
encodeCoordinates(poly.getExteriorRing().getCoordinateSequence(), buff);
encodeEndTag("LinearRing", buff);
encodeEndTag("outerBoundaryIs", buff);
int countInner = poly.getNumInteriorRing();
for (int i = 0; i < countInner; i++) {
encodeStartTag("innerBoundaryIs", buff, null);
encodeStartTag("LinearRing", buff, null);
encodeCoordinates(poly.getInteriorRingN(i).getCoordinateSequence(), buff);
encodeEndTag("LinearRing", buff);
encodeEndTag("innerBoundaryIs", buff);
}
encodeEndTag("Polygon", buff);
}
public void encodeMultiPoint(MultiPoint mp, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("MultiPoint", buff, abstractGeometryAttributeMap);
for (int i = 0; i < mp.getNumGeometries(); i++) {
encodeStartTag("pointMember", buff, null);
Point p = (Point) mp.getGeometryN(i);
encodePoint(p, buff, null);
encodeEndTag("pointMember", buff);
}
encodeEndTag("MultiPoint", buff);
}
public void encodeMultiLineString(MultiLineString mls, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("MultiLineString", buff, abstractGeometryAttributeMap);
for (int i = 0; i < mls.getNumGeometries(); i++) {
encodeStartTag("lineStringMember", buff, null);
LineString ls = (LineString) mls.getGeometryN(i);
encodeLineString(ls, buff, null);
encodeEndTag("lineStringMember", buff);
}
encodeEndTag("MultiLineString", buff);
}
public void encodeMultiPolygon(MultiPolygon mp, StringBuffer buff,
Map<String, String> abstractGeometryAttributeMap) {
encodeStartTag("MultiPolygon", buff, abstractGeometryAttributeMap);
for (int i = 0; i < mp.getNumGeometries(); i++) {
encodeStartTag("polygonMember", buff, null);
Polygon p = (Polygon) mp.getGeometryN(i);
encodePolygon(p, buff, null);
encodeEndTag("polygonMember", buff);
}
encodeEndTag("MultiPolygon", buff);
}
}