|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
|
* full list of contributors). Published under the Clear BSD license. |
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|
* full text of the license. */ |
|
|
|
/** |
|
* @requires OpenLayers/Format/XML.js |
|
* @requires OpenLayers/Geometry/Polygon.js |
|
* @requires OpenLayers/Geometry/Point.js |
|
* @requires OpenLayers/Geometry/MultiPolygon.js |
|
* @requires OpenLayers/Geometry/LinearRing.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Format.ArcXML |
|
* Read/Wite ArcXML. Create a new instance with the <OpenLayers.Format.ArcXML> |
|
* constructor. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Format> |
|
*/ |
|
OpenLayers.Format.ArcXML = OpenLayers.Class(OpenLayers.Format.XML, { |
|
|
|
/** |
|
* Property: fontStyleKeys |
|
* {Array} List of keys used in font styling. |
|
*/ |
|
fontStyleKeys: [ |
|
'antialiasing', 'blockout', 'font', 'fontcolor','fontsize', 'fontstyle', |
|
'glowing', 'interval', 'outline', 'printmode', 'shadow', 'transparency' |
|
], |
|
|
|
/** |
|
* Property: request |
|
* A get_image request destined for an ArcIMS server. |
|
*/ |
|
request: null, |
|
|
|
/** |
|
* Property: response |
|
* A parsed response from an ArcIMS server. |
|
*/ |
|
response: null, |
|
|
|
/** |
|
* Constructor: OpenLayers.Format.ArcXML |
|
* Create a new parser/writer for ArcXML. Create an instance of this class |
|
* to begin authoring a request to an ArcIMS service. This is used |
|
* primarily by the ArcIMS layer, but could be used to do other wild |
|
* stuff, like geocoding. |
|
* |
|
* Parameters: |
|
* options - {Object} An optional object whose properties will be set on |
|
* this instance. |
|
*/ |
|
initialize: function(options) { |
|
this.request = new OpenLayers.Format.ArcXML.Request(); |
|
this.response = new OpenLayers.Format.ArcXML.Response(); |
|
|
|
if (options) { |
|
if (options.requesttype == "feature") { |
|
this.request.get_image = null; |
|
|
|
var qry = this.request.get_feature.query; |
|
this.addCoordSys(qry.featurecoordsys, options.featureCoordSys); |
|
this.addCoordSys(qry.filtercoordsys, options.filterCoordSys); |
|
|
|
if (options.polygon) { |
|
qry.isspatial = true; |
|
qry.spatialfilter.polygon = options.polygon; |
|
} else if (options.envelope) { |
|
qry.isspatial = true; |
|
qry.spatialfilter.envelope = {minx:0, miny:0, maxx:0, maxy:0}; |
|
this.parseEnvelope(qry.spatialfilter.envelope, options.envelope); |
|
} |
|
} else if (options.requesttype == "image") { |
|
this.request.get_feature = null; |
|
|
|
var props = this.request.get_image.properties; |
|
this.parseEnvelope(props.envelope, options.envelope); |
|
|
|
this.addLayers(props.layerlist, options.layers); |
|
this.addImageSize(props.imagesize, options.tileSize); |
|
this.addCoordSys(props.featurecoordsys, options.featureCoordSys); |
|
this.addCoordSys(props.filtercoordsys, options.filterCoordSys); |
|
} else { |
|
// if an arcxml object is being created with no request type, it is |
|
// probably going to consume a response, so do not throw an error if |
|
// the requesttype is not defined |
|
this.request = null; |
|
} |
|
} |
|
|
|
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); |
|
}, |
|
|
|
/** |
|
* Method: parseEnvelope |
|
* Parse an array of coordinates into an ArcXML envelope structure. |
|
* |
|
* Parameters: |
|
* env - {Object} An envelope object that will contain the parsed coordinates. |
|
* arr - {Array(double)} An array of coordinates in the order: [ minx, miny, maxx, maxy ] |
|
*/ |
|
parseEnvelope: function(env, arr) { |
|
if (arr && arr.length == 4) { |
|
env.minx = arr[0]; |
|
env.miny = arr[1]; |
|
env.maxx = arr[2]; |
|
env.maxy = arr[3]; |
|
} |
|
}, |
|
|
|
/** |
|
* Method: addLayers |
|
* Add a collection of layers to another collection of layers. Each layer in the list is tuple of |
|
* { id, visible }. These layer collections represent the |
|
* /ARCXML/REQUEST/get_image/PROPERTIES/LAYERLIST/LAYERDEF items in ArcXML |
|
* |
|
* TODO: Add support for dynamic layer rendering. |
|
* |
|
* Parameters: |
|
* ll - {Array({id,visible})} A list of layer definitions. |
|
* lyrs - {Array({id,visible})} A list of layer definitions. |
|
*/ |
|
addLayers: function(ll, lyrs) { |
|
for(var lind = 0, len=lyrs.length; lind < len; lind++) { |
|
ll.push(lyrs[lind]); |
|
} |
|
}, |
|
|
|
/** |
|
* Method: addImageSize |
|
* Set the size of the requested image. |
|
* |
|
* Parameters: |
|
* imsize - {Object} An ArcXML imagesize object. |
|
* olsize - {OpenLayers.Size} The image size to set. |
|
*/ |
|
addImageSize: function(imsize, olsize) { |
|
if (olsize !== null) { |
|
imsize.width = olsize.w; |
|
imsize.height = olsize.h; |
|
imsize.printwidth = olsize.w; |
|
imsize.printheight = olsize.h; |
|
} |
|
}, |
|
|
|
/** |
|
* Method: addCoordSys |
|
* Add the coordinate system information to an object. The object may be |
|
* |
|
* Parameters: |
|
* featOrFilt - {Object} A featurecoordsys or filtercoordsys ArcXML structure. |
|
* fsys - {String} or {OpenLayers.Projection} or {filtercoordsys} or |
|
* {featurecoordsys} A projection representation. If it's a {String}, |
|
* the value is assumed to be the SRID. If it's a {OpenLayers.Projection} |
|
* AND Proj4js is available, the projection number and name are extracted |
|
* from there. If it's a filter or feature ArcXML structure, it is copied. |
|
*/ |
|
addCoordSys: function(featOrFilt, fsys) { |
|
if (typeof fsys == "string") { |
|
featOrFilt.id = parseInt(fsys); |
|
featOrFilt.string = fsys; |
|
} |
|
// is this a proj4js instance? |
|
else if (typeof fsys == "object" && fsys.proj !== null){ |
|
featOrFilt.id = fsys.proj.srsProjNumber; |
|
featOrFilt.string = fsys.proj.srsCode; |
|
} else { |
|
featOrFilt = fsys; |
|
} |
|
}, |
|
|
|
/** |
|
* APIMethod: iserror |
|
* Check to see if the response from the server was an error. |
|
* |
|
* Parameters: |
|
* data - {String} or {DOMElement} data to read/parse. If nothing is supplied, |
|
* the current response is examined. |
|
* |
|
* Returns: |
|
* {Boolean} true if the response was an error. |
|
*/ |
|
iserror: function(data) { |
|
var ret = null; |
|
|
|
if (!data) { |
|
ret = (this.response.error !== ''); |
|
} else { |
|
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); |
|
var errorNodes = data.documentElement.getElementsByTagName("ERROR"); |
|
ret = (errorNodes !== null && errorNodes.length > 0); |
|
} |
|
|
|
return ret; |
|
}, |
|
|
|
/** |
|
* APIMethod: read |
|
* Read data from a string, and return an response. |
|
* |
|
* Parameters: |
|
* data - {String} or {DOMElement} data to read/parse. |
|
* |
|
* Returns: |
|
* {OpenLayers.Format.ArcXML.Response} An ArcXML response. Note that this response |
|
* data may change in the future. |
|
*/ |
|
read: function(data) { |
|
if(typeof data == "string") { |
|
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); |
|
} |
|
|
|
var arcNode = null; |
|
if (data && data.documentElement) { |
|
if(data.documentElement.nodeName == "ARCXML") { |
|
arcNode = data.documentElement; |
|
} else { |
|
arcNode = data.documentElement.getElementsByTagName("ARCXML")[0]; |
|
} |
|
} |
|
|
|
// in Safari, arcNode will be there but will have a child named |
|
// parsererror |
|
if (!arcNode || arcNode.firstChild.nodeName === 'parsererror') { |
|
var error, source; |
|
try { |
|
error = data.firstChild.nodeValue; |
|
source = data.firstChild.childNodes[1].firstChild.nodeValue; |
|
} catch (err) { |
|
// pass |
|
} |
|
throw { |
|
message: "Error parsing the ArcXML request", |
|
error: error, |
|
source: source |
|
}; |
|
} |
|
|
|
var response = this.parseResponse(arcNode); |
|
return response; |
|
}, |
|
|
|
/** |
|
* APIMethod: write |
|
* Generate an ArcXml document string for sending to an ArcIMS server. |
|
* |
|
* Returns: |
|
* {String} A string representing the ArcXML document request. |
|
*/ |
|
write: function(request) { |
|
if (!request) { |
|
request = this.request; |
|
} |
|
var root = this.createElementNS("", "ARCXML"); |
|
root.setAttribute("version","1.1"); |
|
|
|
var reqElem = this.createElementNS("", "REQUEST"); |
|
|
|
if (request.get_image != null) { |
|
var getElem = this.createElementNS("", "GET_IMAGE"); |
|
reqElem.appendChild(getElem); |
|
|
|
var propElem = this.createElementNS("", "PROPERTIES"); |
|
getElem.appendChild(propElem); |
|
|
|
var props = request.get_image.properties; |
|
if (props.featurecoordsys != null) { |
|
var feat = this.createElementNS("", "FEATURECOORDSYS"); |
|
propElem.appendChild(feat); |
|
|
|
if (props.featurecoordsys.id === 0) { |
|
feat.setAttribute("string", props.featurecoordsys['string']); |
|
} |
|
else { |
|
feat.setAttribute("id", props.featurecoordsys.id); |
|
} |
|
} |
|
|
|
if (props.filtercoordsys != null) { |
|
var filt = this.createElementNS("", "FILTERCOORDSYS"); |
|
propElem.appendChild(filt); |
|
|
|
if (props.filtercoordsys.id === 0) { |
|
filt.setAttribute("string", props.filtercoordsys.string); |
|
} |
|
else { |
|
filt.setAttribute("id", props.filtercoordsys.id); |
|
} |
|
} |
|
|
|
if (props.envelope != null) { |
|
var env = this.createElementNS("", "ENVELOPE"); |
|
propElem.appendChild(env); |
|
|
|
env.setAttribute("minx", props.envelope.minx); |
|
env.setAttribute("miny", props.envelope.miny); |
|
env.setAttribute("maxx", props.envelope.maxx); |
|
env.setAttribute("maxy", props.envelope.maxy); |
|
} |
|
|
|
var imagesz = this.createElementNS("", "IMAGESIZE"); |
|
propElem.appendChild(imagesz); |
|
|
|
imagesz.setAttribute("height", props.imagesize.height); |
|
imagesz.setAttribute("width", props.imagesize.width); |
|
|
|
if (props.imagesize.height != props.imagesize.printheight || |
|
props.imagesize.width != props.imagesize.printwidth) { |
|
imagesz.setAttribute("printheight", props.imagesize.printheight); |
|
imagesz.setArrtibute("printwidth", props.imagesize.printwidth); |
|
} |
|
|
|
if (props.background != null) { |
|
var backgrnd = this.createElementNS("", "BACKGROUND"); |
|
propElem.appendChild(backgrnd); |
|
|
|
backgrnd.setAttribute("color", |
|
props.background.color.r + "," + |
|
props.background.color.g + "," + |
|
props.background.color.b); |
|
|
|
if (props.background.transcolor !== null) { |
|
backgrnd.setAttribute("transcolor", |
|
props.background.transcolor.r + "," + |
|
props.background.transcolor.g + "," + |
|
props.background.transcolor.b); |
|
} |
|
} |
|
|
|
if (props.layerlist != null && props.layerlist.length > 0) { |
|
var layerlst = this.createElementNS("", "LAYERLIST"); |
|
propElem.appendChild(layerlst); |
|
|
|
for (var ld = 0; ld < props.layerlist.length; ld++) { |
|
var ldef = this.createElementNS("", "LAYERDEF"); |
|
layerlst.appendChild(ldef); |
|
|
|
ldef.setAttribute("id", props.layerlist[ld].id); |
|
ldef.setAttribute("visible", props.layerlist[ld].visible); |
|
|
|
if (typeof props.layerlist[ld].query == "object") { |
|
var query = props.layerlist[ld].query; |
|
|
|
if (query.where.length < 0) { |
|
continue; |
|
} |
|
|
|
var queryElem = null; |
|
if (typeof query.spatialfilter == "boolean" && query.spatialfilter) { |
|
// handle spatial filter madness |
|
queryElem = this.createElementNS("", "SPATIALQUERY"); |
|
} |
|
else { |
|
queryElem = this.createElementNS("", "QUERY"); |
|
} |
|
|
|
queryElem.setAttribute("where", query.where); |
|
|
|
if (typeof query.accuracy == "number" && query.accuracy > 0) { |
  |