package org.openscales.core.format
{
import flash.utils.getQualifiedClassName;
import flash.xml.XMLNode;
import org.openscales.core.Util;
import org.openscales.core.feature.Feature;
import org.openscales.core.geometry.Collection;
import org.openscales.core.geometry.LineString;
import org.openscales.core.geometry.LinearRing;
import org.openscales.core.geometry.MultiLineString;
import org.openscales.core.geometry.MultiPoint;
import org.openscales.core.geometry.MultiPolygon;
import org.openscales.core.geometry.Point;
import org.openscales.core.geometry.Polygon;
import org.openscales.proj4as.Proj4as;
import org.openscales.proj4as.ProjPoint;
import org.openscales.proj4as.ProjProjection;
import org.openscales.core.feature.Feature;
import org.openscales.core.feature.PointFeature;
import org.openscales.core.feature.MultiPointFeature;
import org.openscales.core.feature.LineStringFeature;
import org.openscales.core.feature.MultiLineStringFeature ;
import org.openscales.core.feature.PolygonFeature;
import org.openscales.core.feature.MultiPolygonFeature;
import org.openscales.core.Trace;
/**
* Read/Write GML. Supports the GML simple features profile.
*/
public class GMLFormat extends Format
{
protected var _featureNS:String = "http://openscales.org/OpenScales";
protected var _featureName:String = "featureMember";
protected var _featurePrefix:String = "OpenScales";
protected var _layerName:String = "features";
protected var _geometryName:String = "geometry";
protected var _collectionName:String = "FeatureCollection";
protected var _gmlns:String = "http://www.opengis.net/gml";
protected var _gmlprefix:String = "gml";
protected var _wfsns:String = "http://www.opengis.net/wfs";
protected var _wfsprefix:String = "wfs";
private var _extractAttributes:Boolean = true;
private var _dim:Number;
/**
* GMLFormat constructor
*
* @param extractAttributes
*
*/
public function GMLFormat(extractAttributes:Boolean = true) {
this.extractAttributes = extractAttributes;
}
/**
* Read data
*
* @param data data to read/parse.
*
* @return features.
*/
override public function read(data:Object):Object {
var dataXML:XML = null;
if (typeof data == "string") {
dataXML = new XML(data);
} else {
dataXML = XML(data);
}
var featureNodes:XMLList = dataXML..*::featureMember;
if (featureNodes.length() == 0) { return []; }
var dim:int;
var coordNodes:XMLList = featureNodes[0].*::posList;
if (coordNodes.length() == 0) {
coordNodes = featureNodes[0].*::pos;
}
if (coordNodes.length() > 0) {
dim = coordNodes[0]
[email protected]*::srsDimension;
}
this.dim = (dim == 3) ? 3 : 2;
var features:Array = [];
for (var i:int = 0; i Array = new Array();
var feature:Feature = null;
if (xmlNode..*::MultiPolygon.length() > 0) {
var multipolygon:XML = xmlNode..*::MultiPolygon[0];
geom = new MultiPolygon();
var polygons:XMLList = multipolygon..*::Polygon;
for (var i:int = 0; i 0) {
var multilinestring:XML = xmlNode..*::MultiLineString[0];
geom = new MultiLineString();
var lineStrings:XMLList = multilinestring..*::LineString;
for (i = 0; i 0) {
var multiPoint:XML = xmlNode..*::MultiPoint[0];
geom = new MultiPoint();
var points:XMLList = multiPoint..*::Point;
for (i = 0; i 0) {
var polygon2:XML = xmlNode..*::Polygon[0];
geom = this.parsePolygonNode(polygon2);
} else if (xmlNode..*::LineString.length() > 0) {
var lineString2:XML = xmlNode..*::LineString[0];
p = this.parseCoords(lineString2);
if (p) {
geom = new LineString(p);
}
} else if (xmlNode..*::Point.length() > 0) {
var point:XML = xmlNode..*::Point[0];
geom = new MultiPoint();
p = this.parseCoords(point);
if (p) {
geom.addComponent(p[0]);
}
}
if (geom) {
// Test more specific geom before because for is operator, a lineString is a multipoint for example (inheritance)
if (geom is MultiPolygon) {
feature = new MultiPolygonFeature(geom as MultiPolygon);
} else if (geom is Polygon) {
feature = new PolygonFeature(geom as Polygon);
} else if (geom is MultiLineString) {
feature = new MultiLineStringFeature(geom as MultiLineString);
} else if (geom is LineString) {
feature = new LineStringFeature(geom as LineString);
} else if (geom is MultiPoint) {
feature = new MultiPointFeature(geom as MultiPoint);
} else if (geom is Point) {
feature = new PointFeature(geom as Point);
} else {
Trace.warning("GMLFormat.parseFeature: unrecognized geometry);");
return null;
}
feature.name =
[email protected];
if (this.extractAttributes) {
feature.attributes = this.parseAttributes(xmlNode);
}
return feature;
} else {
return null;
}
}
/**
* Parse attributes
*
* @param node A XML feature node.
*
* @return An attributes object.
*/
public function parseAttributes(xmlNode:XML):Object {
var nodes:XMLList = xmlNode.children();
var attributes:Object = {};
for(var i:int = 0; i array size
var rings:Array = new Array(linearRings.length());
for (var i:int = 0; i array of coords
*/
public function parseCoords(xmlNode:XML):Array {
var x:Number, y:Number, left:Number, bottom:Number, right:Number, top:Number;
var points:Array = new Array();
if (xmlNode) {
var coordNodes:XMLList = xmlNode.*::posList;
if (coordNodes.length() == 0) {
coordNodes = xmlNode.*::pos;
}
if (coordNodes.length() == 0) {
coordNodes = xmlNode.*::coordinates;
}
var coordString:String = coordNodes[0].text();
var nums:Array = (coordString) ? coordString.split(/[, \n\t]+/) : [];
while (nums[0] == "")
nums.shift();
while (nums[nums.length-1] == "")
nums.pop();
for(var i:int = 0; i ");
for (var i:int=0; i ");
geomContainer.appendChild(geometryNode);
var featureNode:XML = new XML("");
var featureContainer:XML = new XML("");
featureContainer.appendChild(geomContainer);
for(var attr:String in feature.attributes) {
var attrText:XMLNode = new XMLNode(2, feature.attributes[attr]);
var nodename:String = attr;
if (attr.search(":") != -1) {
nodename = attr.split(":")[1];
}
var attrContainer:XML = new XML("");
attrContainer.appendChild(attrText);
featureContainer.appendChild(attrContainer);
}
featureNode.appendChild(featureContainer);
return featureNode;
}
/**
* create a GML Object
*
* @param geometry
*
* @return an XML
*/
public function buildGeometryNode(geometry:Object):XML {
var gml:XML;
if (getQualifiedClassName(geometry) == "org.openscales.core.geometry::MultiPolygon"
|| getQualifiedClassName(geometry) == "org.openscales.core.geometry::Polygon") {
gml = new XML("");
var polygonMember:XML = new XML("");
var polygon:XML = new XML("");
var outerRing:XML = new XML("");
var linearRing:XML = new XML("");
linearRing.appendChild(this.buildCoordinatesNode(g eometry.components[0]));
outerRing.appendChild(linearRing);
polygon.appendChild(outerRing);
polygonMember.appendChild(polygon);
gml.appendChild(polygonMember);
}
else if (getQualifiedClassName(geometry) == "org.openscales.core.geometry::MultiLineString"
|| getQualifiedClassName(geometry) == "org.openscales.core.geometry::LineString") {
gml = new XML("");
var lineStringMember:XML = new XML("");
var lineString:XML = new XML("");
lineString.appendChild(this.buildCoordinatesNode(g eometry));
lineStringMember.appendChild(lineString);
gml.appendChild(lineStringMember);
}
else if (getQualifiedClassName(geometry) == "org.openscales.core.geometry::MultiPoint") {
gml = new XML("");
var parts:Object = "";
parts = geometry.components;
for (var i:int = 0; i ");
var point:XML = new XML("");
point.appendChild(this.buildCoordinatesNode(parts[ i]));
pointMember.appendChild(point);
gml.appendChild(pointMember);
}
} else if (getQualifiedClassName(geometry) == "org.openscales.core.geometry::Point") {
parts = geometry;
gml = new XML("");
gml.appendChild(this.buildCoordinatesNode(parts));
}
return gml;
}
/**
* Builds the coordinates XmlNode
*
* @param geometry
*
* @return created xmlNode
*/
public function buildCoordinatesNode(geometry:Object):XML {
var coordinatesNode:XML = new XML("");
[email protected] = ".";
[email protected] = ",";
[email protected] = " ";
var points:Array = null;
if (geometry.components) {
if (geometry.components.length > 0) {
points = geometry.components;
}
}
var path:String = "";
if (points) {
for (var i:int = 0; i < points.length; i++) {
if (this.internalProj != null && this.externalProj != null)
(points[i] as Point).transform(this.internalProj, this.externalProj);
path += points[i].x + "," + points[i].y + " ";
}
} else {
if (this.internalProj != null && this.externalProj != null) {
var p:ProjPoint = new ProjPoint(geometry.x, geometry.y);
Proj4as.transform(internalProj, externalProj, p);
geometry.x = p.x;
geometry.y = p.y;
}
path += geometry.x + "," + geometry.y + " ";
}
coordinatesNode.appendChild(path);
return coordinatesNode;
}
//Getters and Setters
public function get extractAttributes():Boolean {
return this._extractAttributes;
}
public function set extractAttributes(value:Boolean):void {
this._extractAttributes = value;
}
public function get dim():Number {
return this._dim;
}
public function set dim(value:Number):void {
this._dim = value;
}
public function get internalProj():ProjProjection {
return this._internalProj;
}
public function set internalProj(value:ProjProjection):void {
this._internalProj = value;
}
public function get externalProj():ProjProjection {
return this._externalProj;
}
public function set externalProj(value:ProjProjection):void {
this._externalProj = value;
}
}
}