ArcXML.js 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/Format/XML.js
  7. * @requires OpenLayers/Geometry/Polygon.js
  8. * @requires OpenLayers/Geometry/Point.js
  9. * @requires OpenLayers/Geometry/MultiPolygon.js
  10. * @requires OpenLayers/Geometry/LinearRing.js
  11. */
  12. /**
  13. * Class: OpenLayers.Format.ArcXML
  14. * Read/Write ArcXML. Create a new instance with the <OpenLayers.Format.ArcXML>
  15. * constructor.
  16. *
  17. * Inherits from:
  18. * - <OpenLayers.Format.XML>
  19. */
  20. OpenLayers.Format.ArcXML = OpenLayers.Class(OpenLayers.Format.XML, {
  21. /**
  22. * Property: fontStyleKeys
  23. * {Array} List of keys used in font styling.
  24. */
  25. fontStyleKeys: [
  26. 'antialiasing', 'blockout', 'font', 'fontcolor','fontsize', 'fontstyle',
  27. 'glowing', 'interval', 'outline', 'printmode', 'shadow', 'transparency'
  28. ],
  29. /**
  30. * Property: request
  31. * A get_image request destined for an ArcIMS server.
  32. */
  33. request: null,
  34. /**
  35. * Property: response
  36. * A parsed response from an ArcIMS server.
  37. */
  38. response: null,
  39. /**
  40. * Constructor: OpenLayers.Format.ArcXML
  41. * Create a new parser/writer for ArcXML. Create an instance of this class
  42. * to begin authoring a request to an ArcIMS service. This is used
  43. * primarily by the ArcIMS layer, but could be used to do other wild
  44. * stuff, like geocoding.
  45. *
  46. * Parameters:
  47. * options - {Object} An optional object whose properties will be set on
  48. * this instance.
  49. */
  50. initialize: function(options) {
  51. this.request = new OpenLayers.Format.ArcXML.Request();
  52. this.response = new OpenLayers.Format.ArcXML.Response();
  53. if (options) {
  54. if (options.requesttype == "feature") {
  55. this.request.get_image = null;
  56. var qry = this.request.get_feature.query;
  57. this.addCoordSys(qry.featurecoordsys, options.featureCoordSys);
  58. this.addCoordSys(qry.filtercoordsys, options.filterCoordSys);
  59. if (options.polygon) {
  60. qry.isspatial = true;
  61. qry.spatialfilter.polygon = options.polygon;
  62. } else if (options.envelope) {
  63. qry.isspatial = true;
  64. qry.spatialfilter.envelope = {minx:0, miny:0, maxx:0, maxy:0};
  65. this.parseEnvelope(qry.spatialfilter.envelope, options.envelope);
  66. }
  67. } else if (options.requesttype == "image") {
  68. this.request.get_feature = null;
  69. var props = this.request.get_image.properties;
  70. this.parseEnvelope(props.envelope, options.envelope);
  71. this.addLayers(props.layerlist, options.layers);
  72. this.addImageSize(props.imagesize, options.tileSize);
  73. this.addCoordSys(props.featurecoordsys, options.featureCoordSys);
  74. this.addCoordSys(props.filtercoordsys, options.filterCoordSys);
  75. } else {
  76. // if an arcxml object is being created with no request type, it is
  77. // probably going to consume a response, so do not throw an error if
  78. // the requesttype is not defined
  79. this.request = null;
  80. }
  81. }
  82. OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
  83. },
  84. /**
  85. * Method: parseEnvelope
  86. * Parse an array of coordinates into an ArcXML envelope structure.
  87. *
  88. * Parameters:
  89. * env - {Object} An envelope object that will contain the parsed coordinates.
  90. * arr - {Array(double)} An array of coordinates in the order: [ minx, miny, maxx, maxy ]
  91. */
  92. parseEnvelope: function(env, arr) {
  93. if (arr && arr.length == 4) {
  94. env.minx = arr[0];
  95. env.miny = arr[1];
  96. env.maxx = arr[2];
  97. env.maxy = arr[3];
  98. }
  99. },
  100. /**
  101. * Method: addLayers
  102. * Add a collection of layers to another collection of layers. Each layer in the list is tuple of
  103. * { id, visible }. These layer collections represent the
  104. * /ARCXML/REQUEST/get_image/PROPERTIES/LAYERLIST/LAYERDEF items in ArcXML
  105. *
  106. * TODO: Add support for dynamic layer rendering.
  107. *
  108. * Parameters:
  109. * ll - {Array({id,visible})} A list of layer definitions.
  110. * lyrs - {Array({id,visible})} A list of layer definitions.
  111. */
  112. addLayers: function(ll, lyrs) {
  113. for(var lind = 0, len=lyrs.length; lind < len; lind++) {
  114. ll.push(lyrs[lind]);
  115. }
  116. },
  117. /**
  118. * Method: addImageSize
  119. * Set the size of the requested image.
  120. *
  121. * Parameters:
  122. * imsize - {Object} An ArcXML imagesize object.
  123. * olsize - {<OpenLayers.Size>} The image size to set.
  124. */
  125. addImageSize: function(imsize, olsize) {
  126. if (olsize !== null) {
  127. imsize.width = olsize.w;
  128. imsize.height = olsize.h;
  129. imsize.printwidth = olsize.w;
  130. imsize.printheight = olsize.h;
  131. }
  132. },
  133. /**
  134. * Method: addCoordSys
  135. * Add the coordinate system information to an object. The object may be
  136. *
  137. * Parameters:
  138. * featOrFilt - {Object} A featurecoordsys or filtercoordsys ArcXML structure.
  139. * fsys - {String} or {<OpenLayers.Projection>} or {filtercoordsys} or
  140. * {featurecoordsys} A projection representation. If it's a {String},
  141. * the value is assumed to be the SRID. If it's a {OpenLayers.Projection}
  142. * AND Proj4js is available, the projection number and name are extracted
  143. * from there. If it's a filter or feature ArcXML structure, it is copied.
  144. */
  145. addCoordSys: function(featOrFilt, fsys) {
  146. if (typeof fsys == "string") {
  147. featOrFilt.id = parseInt(fsys);
  148. featOrFilt.string = fsys;
  149. }
  150. // is this a proj4js instance?
  151. else if (typeof fsys == "object" && fsys.proj !== null){
  152. featOrFilt.id = fsys.proj.srsProjNumber;
  153. featOrFilt.string = fsys.proj.srsCode;
  154. } else {
  155. featOrFilt = fsys;
  156. }
  157. },
  158. /**
  159. * APIMethod: iserror
  160. * Check to see if the response from the server was an error.
  161. *
  162. * Parameters:
  163. * data - {String} or {DOMElement} data to read/parse. If nothing is supplied,
  164. * the current response is examined.
  165. *
  166. * Returns:
  167. * {Boolean} true if the response was an error.
  168. */
  169. iserror: function(data) {
  170. var ret = null;
  171. if (!data) {
  172. ret = (this.response.error !== '');
  173. } else {
  174. data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
  175. var errorNodes = data.documentElement.getElementsByTagName("ERROR");
  176. ret = (errorNodes !== null && errorNodes.length > 0);
  177. }
  178. return ret;
  179. },
  180. /**
  181. * APIMethod: read
  182. * Read data from a string, and return an response.
  183. *
  184. * Parameters:
  185. * data - {String} or {DOMElement} data to read/parse.
  186. *
  187. * Returns:
  188. * {<OpenLayers.Format.ArcXML.Response>} An ArcXML response. Note that this response
  189. * data may change in the future.
  190. */
  191. read: function(data) {
  192. if(typeof data == "string") {
  193. data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
  194. }
  195. var arcNode = null;
  196. if (data && data.documentElement) {
  197. if(data.documentElement.nodeName == "ARCXML") {
  198. arcNode = data.documentElement;
  199. } else {
  200. arcNode = data.documentElement.getElementsByTagName("ARCXML")[0];
  201. }
  202. }
  203. // in Safari, arcNode will be there but will have a child named
  204. // parsererror
  205. if (!arcNode || arcNode.firstChild.nodeName === 'parsererror') {
  206. var error, source;
  207. try {
  208. error = data.firstChild.nodeValue;
  209. source = data.firstChild.childNodes[1].firstChild.nodeValue;
  210. } catch (err) {
  211. // pass
  212. }
  213. throw {
  214. message: "Error parsing the ArcXML request",
  215. error: error,
  216. source: source
  217. };
  218. }
  219. var response = this.parseResponse(arcNode);
  220. return response;
  221. },
  222. /**
  223. * APIMethod: write
  224. * Generate an ArcXml document string for sending to an ArcIMS server.
  225. *
  226. * Returns:
  227. * {String} A string representing the ArcXML document request.
  228. */
  229. write: function(request) {
  230. if (!request) {
  231. request = this.request;
  232. }
  233. var root = this.createElementNS("", "ARCXML");
  234. root.setAttribute("version","1.1");
  235. var reqElem = this.createElementNS("", "REQUEST");
  236. if (request.get_image != null) {
  237. var getElem = this.createElementNS("", "GET_IMAGE");
  238. reqElem.appendChild(getElem);
  239. var propElem = this.createElementNS("", "PROPERTIES");
  240. getElem.appendChild(propElem);
  241. var props = request.get_image.properties;
  242. if (props.featurecoordsys != null) {
  243. var feat = this.createElementNS("", "FEATURECOORDSYS");
  244. propElem.appendChild(feat);
  245. if (props.featurecoordsys.id === 0) {
  246. feat.setAttribute("string", props.featurecoordsys['string']);
  247. }
  248. else {
  249. feat.setAttribute("id", props.featurecoordsys.id);
  250. }
  251. }
  252. if (props.filtercoordsys != null) {
  253. var filt = this.createElementNS("", "FILTERCOORDSYS");
  254. propElem.appendChild(filt);
  255. if (props.filtercoordsys.id === 0) {
  256. filt.setAttribute("string", props.filtercoordsys.string);
  257. }
  258. else {
  259. filt.setAttribute("id", props.filtercoordsys.id);
  260. }
  261. }
  262. if (props.envelope != null) {
  263. var env = this.createElementNS("", "ENVELOPE");
  264. propElem.appendChild(env);
  265. env.setAttribute("minx", props.envelope.minx);
  266. env.setAttribute("miny", props.envelope.miny);
  267. env.setAttribute("maxx", props.envelope.maxx);
  268. env.setAttribute("maxy", props.envelope.maxy);
  269. }
  270. var imagesz = this.createElementNS("", "IMAGESIZE");
  271. propElem.appendChild(imagesz);
  272. imagesz.setAttribute("height", props.imagesize.height);
  273. imagesz.setAttribute("width", props.imagesize.width);
  274. if (props.imagesize.height != props.imagesize.printheight ||
  275. props.imagesize.width != props.imagesize.printwidth) {
  276. imagesz.setAttribute("printheight", props.imagesize.printheight);
  277. imagesz.setArrtibute("printwidth", props.imagesize.printwidth);
  278. }
  279. if (props.background != null) {
  280. var backgrnd = this.createElementNS("", "BACKGROUND");
  281. propElem.appendChild(backgrnd);
  282. backgrnd.setAttribute("color",
  283. props.background.color.r + "," +
  284. props.background.color.g + "," +
  285. props.background.color.b);
  286. if (props.background.transcolor !== null) {
  287. backgrnd.setAttribute("transcolor",
  288. props.background.transcolor.r + "," +
  289. props.background.transcolor.g + "," +
  290. props.background.transcolor.b);
  291. }
  292. }
  293. if (props.layerlist != null && props.layerlist.length > 0) {
  294. var layerlst = this.createElementNS("", "LAYERLIST");
  295. propElem.appendChild(layerlst);
  296. for (var ld = 0; ld < props.layerlist.length; ld++) {
  297. var ldef = this.createElementNS("", "LAYERDEF");
  298. layerlst.appendChild(ldef);
  299. ldef.setAttribute("id", props.layerlist[ld].id);
  300. ldef.setAttribute("visible", props.layerlist[ld].visible);
  301. if (typeof props.layerlist[ld].query == "object") {
  302. var query = props.layerlist[ld].query;
  303. if (query.where.length < 0) {
  304. continue;
  305. }
  306. var queryElem = null;
  307. if (typeof query.spatialfilter == "boolean" && query.spatialfilter) {
  308. // handle spatial filter madness
  309. queryElem = this.createElementNS("", "SPATIALQUERY");
  310. }
  311. else {
  312. queryElem = this.createElementNS("", "QUERY");
  313. }
  314. queryElem.setAttribute("where", query.where);
  315. if (typeof query.accuracy == "number" && query.accuracy > 0) {
  316. queryElem.setAttribute("accuracy", query.accuracy);
  317. }
  318. if (typeof query.featurelimit == "number" && query.featurelimit < 2000) {
  319. queryElem.setAttribute("featurelimit", query.featurelimit);
  320. }
  321. if (typeof query.subfields == "string" && query.subfields != "#ALL#") {
  322. queryElem.setAttribute("subfields", query.subfields);
  323. }
  324. if (typeof query.joinexpression == "string" && query.joinexpression.length > 0) {
  325. queryElem.setAttribute("joinexpression", query.joinexpression);
  326. }
  327. if (typeof query.jointables == "string" && query.jointables.length > 0) {
  328. queryElem.setAttribute("jointables", query.jointables);
  329. }
  330. ldef.appendChild(queryElem);
  331. }
  332. if (typeof props.layerlist[ld].renderer == "object") {
  333. this.addRenderer(ldef, props.layerlist[ld].renderer);
  334. }
  335. }
  336. }
  337. } else if (request.get_feature != null) {
  338. var getElem = this.createElementNS("", "GET_FEATURES");
  339. getElem.setAttribute("outputmode", "newxml");
  340. getElem.setAttribute("checkesc", "true");
  341. if (request.get_feature.geometry) {
  342. getElem.setAttribute("geometry", request.get_feature.geometry);
  343. }
  344. else {
  345. getElem.setAttribute("geometry", "false");
  346. }
  347. if (request.get_feature.compact) {
  348. getElem.setAttribute("compact", request.get_feature.compact);
  349. }
  350. if (request.get_feature.featurelimit == "number") {
  351. getElem.setAttribute("featurelimit", request.get_feature.featurelimit);
  352. }
  353. getElem.setAttribute("globalenvelope", "true");
  354. reqElem.appendChild(getElem);
  355. if (request.get_feature.layer != null && request.get_feature.layer.length > 0) {
  356. var lyrElem = this.createElementNS("", "LAYER");
  357. lyrElem.setAttribute("id", request.get_feature.layer);
  358. getElem.appendChild(lyrElem);
  359. }
  360. var fquery = request.get_feature.query;
  361. if (fquery != null) {
  362. var qElem = null;
  363. if (fquery.isspatial) {
  364. qElem = this.createElementNS("", "SPATIALQUERY");
  365. } else {
  366. qElem = this.createElementNS("", "QUERY");
  367. }
  368. getElem.appendChild(qElem);
  369. if (typeof fquery.accuracy == "number") {
  370. qElem.setAttribute("accuracy", fquery.accuracy);
  371. }
  372. //qElem.setAttribute("featurelimit", "5");
  373. if (fquery.featurecoordsys != null) {
  374. var fcsElem1 = this.createElementNS("", "FEATURECOORDSYS");
  375. if (fquery.featurecoordsys.id == 0) {
  376. fcsElem1.setAttribute("string", fquery.featurecoordsys.string);
  377. } else {
  378. fcsElem1.setAttribute("id", fquery.featurecoordsys.id);
  379. }
  380. qElem.appendChild(fcsElem1);
  381. }
  382. if (fquery.filtercoordsys != null) {
  383. var fcsElem2 = this.createElementNS("", "FILTERCOORDSYS");
  384. if (fquery.filtercoordsys.id === 0) {
  385. fcsElem2.setAttribute("string", fquery.filtercoordsys.string);
  386. } else {
  387. fcsElem2.setAttribute("id", fquery.filtercoordsys.id);
  388. }
  389. qElem.appendChild(fcsElem2);
  390. }
  391. if (fquery.buffer > 0) {
  392. var bufElem = this.createElementNS("", "BUFFER");
  393. bufElem.setAttribute("distance", fquery.buffer);
  394. qElem.appendChild(bufElem);
  395. }
  396. if (fquery.isspatial) {
  397. var spfElem = this.createElementNS("", "SPATIALFILTER");
  398. spfElem.setAttribute("relation", fquery.spatialfilter.relation);
  399. qElem.appendChild(spfElem);
  400. if (fquery.spatialfilter.envelope) {
  401. var envElem = this.createElementNS("", "ENVELOPE");
  402. envElem.setAttribute("minx", fquery.spatialfilter.envelope.minx);
  403. envElem.setAttribute("miny", fquery.spatialfilter.envelope.miny);
  404. envElem.setAttribute("maxx", fquery.spatialfilter.envelope.maxx);
  405. envElem.setAttribute("maxy", fquery.spatialfilter.envelope.maxy);
  406. spfElem.appendChild(envElem);
  407. } else if(typeof fquery.spatialfilter.polygon == "object") {
  408. spfElem.appendChild(this.writePolygonGeometry(fquery.spatialfilter.polygon));
  409. }
  410. }
  411. if (fquery.where != null && fquery.where.length > 0) {
  412. qElem.setAttribute("where", fquery.where);
  413. }
  414. }
  415. }
  416. root.appendChild(reqElem);
  417. return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
  418. },
  419. addGroupRenderer: function(ldef, toprenderer) {
  420. var topRelem = this.createElementNS("", "GROUPRENDERER");
  421. ldef.appendChild(topRelem);
  422. for (var rind = 0; rind < toprenderer.length; rind++) {
  423. var renderer = toprenderer[rind];
  424. this.addRenderer(topRelem, renderer);
  425. }
  426. },
  427. addRenderer: function(topRelem, renderer) {
  428. if (OpenLayers.Util.isArray(renderer)) {
  429. this.addGroupRenderer(topRelem, renderer);
  430. } else {
  431. var renderElem = this.createElementNS("", renderer.type.toUpperCase() + "RENDERER");
  432. topRelem.appendChild(renderElem);
  433. if (renderElem.tagName == "VALUEMAPRENDERER") {
  434. this.addValueMapRenderer(renderElem, renderer);
  435. } else if (renderElem.tagName == "VALUEMAPLABELRENDERER") {
  436. this.addValueMapLabelRenderer(renderElem, renderer);
  437. } else if (renderElem.tagName == "SIMPLELABELRENDERER") {
  438. this.addSimpleLabelRenderer(renderElem, renderer);
  439. } else if (renderElem.tagName == "SCALEDEPENDENTRENDERER") {
  440. this.addScaleDependentRenderer(renderElem, renderer);
  441. }
  442. }
  443. },
  444. addScaleDependentRenderer: function(renderElem, renderer) {
  445. if (typeof renderer.lower == "string" || typeof renderer.lower == "number") {
  446. renderElem.setAttribute("lower", renderer.lower);
  447. }
  448. if (typeof renderer.upper == "string" || typeof renderer.upper == "number") {
  449. renderElem.setAttribute("upper", renderer.upper);
  450. }
  451. this.addRenderer(renderElem, renderer.renderer);
  452. },
  453. addValueMapLabelRenderer: function(renderElem, renderer) {
  454. renderElem.setAttribute("lookupfield", renderer.lookupfield);
  455. renderElem.setAttribute("labelfield", renderer.labelfield);
  456. if (typeof renderer.exacts == "object") {
  457. for (var ext=0, extlen=renderer.exacts.length; ext<extlen; ext++) {
  458. var exact = renderer.exacts[ext];
  459. var eelem = this.createElementNS("", "EXACT");
  460. if (typeof exact.value == "string") {
  461. eelem.setAttribute("value", exact.value);
  462. }
  463. if (typeof exact.label == "string") {
  464. eelem.setAttribute("label", exact.label);
  465. }
  466. if (typeof exact.method == "string") {
  467. eelem.setAttribute("method", exact.method);
  468. }
  469. renderElem.appendChild(eelem);
  470. if (typeof exact.symbol == "object") {
  471. var selem = null;
  472. if (exact.symbol.type == "text") {
  473. selem = this.createElementNS("", "TEXTSYMBOL");
  474. }
  475. if (selem != null) {
  476. var keys = this.fontStyleKeys;
  477. for (var i = 0, len = keys.length; i < len; i++) {
  478. var key = keys[i];
  479. if (exact.symbol[key]) {
  480. selem.setAttribute(key, exact.symbol[key]);
  481. }
  482. }
  483. eelem.appendChild(selem);
  484. }
  485. }
  486. } // for each exact
  487. }
  488. },
  489. addValueMapRenderer: function(renderElem, renderer) {
  490. renderElem.setAttribute("lookupfield", renderer.lookupfield);
  491. if (typeof renderer.ranges == "object") {
  492. for(var rng=0, rnglen=renderer.ranges.length; rng<rnglen; rng++) {
  493. var range = renderer.ranges[rng];
  494. var relem = this.createElementNS("", "RANGE");
  495. relem.setAttribute("lower", range.lower);
  496. relem.setAttribute("upper", range.upper);
  497. renderElem.appendChild(relem);
  498. if (typeof range.symbol == "object") {
  499. var selem = null;
  500. if (range.symbol.type == "simplepolygon") {
  501. selem = this.createElementNS("", "SIMPLEPOLYGONSYMBOL");
  502. }
  503. if (selem != null) {
  504. if (typeof range.symbol.boundarycolor == "string") {
  505. selem.setAttribute("boundarycolor", range.symbol.boundarycolor);
  506. }
  507. if (typeof range.symbol.fillcolor == "string") {
  508. selem.setAttribute("fillcolor", range.symbol.fillcolor);
  509. }
  510. if (typeof range.symbol.filltransparency == "number") {
  511. selem.setAttribute("filltransparency", range.symbol.filltransparency);
  512. }
  513. relem.appendChild(selem);
  514. }
  515. }
  516. } // for each range
  517. } else if (typeof renderer.exacts == "object") {
  518. for (var ext=0, extlen=renderer.exacts.length; ext<extlen; ext++) {
  519. var exact = renderer.exacts[ext];
  520. var eelem = this.createElementNS("", "EXACT");
  521. if (typeof exact.value == "string") {
  522. eelem.setAttribute("value", exact.value);
  523. }
  524. if (typeof exact.label == "string") {
  525. eelem.setAttribute("label", exact.label);
  526. }
  527. if (typeof exact.method == "string") {
  528. eelem.setAttribute("method", exact.method);
  529. }
  530. renderElem.appendChild(eelem);
  531. if (typeof exact.symbol == "object") {
  532. var selem = null;
  533. if (exact.symbol.type == "simplemarker") {
  534. selem = this.createElementNS("", "SIMPLEMARKERSYMBOL");
  535. }
  536. if (selem != null) {
  537. if (typeof exact.symbol.antialiasing == "string") {
  538. selem.setAttribute("antialiasing", exact.symbol.antialiasing);
  539. }
  540. if (typeof exact.symbol.color == "string") {
  541. selem.setAttribute("color", exact.symbol.color);
  542. }
  543. if (typeof exact.symbol.outline == "string") {
  544. selem.setAttribute("outline", exact.symbol.outline);
  545. }
  546. if (typeof exact.symbol.overlap == "string") {
  547. selem.setAttribute("overlap", exact.symbol.overlap);
  548. }
  549. if (typeof exact.symbol.shadow == "string") {
  550. selem.setAttribute("shadow", exact.symbol.shadow);
  551. }
  552. if (typeof exact.symbol.transparency == "number") {
  553. selem.setAttribute("transparency", exact.symbol.transparency);
  554. }
  555. //if (typeof exact.symbol.type == "string")
  556. // selem.setAttribute("type", exact.symbol.type);
  557. if (typeof exact.symbol.usecentroid == "string") {
  558. selem.setAttribute("usecentroid", exact.symbol.usecentroid);
  559. }
  560. if (typeof exact.symbol.width == "number") {
  561. selem.setAttribute("width", exact.symbol.width);
  562. }
  563. eelem.appendChild(selem);
  564. }
  565. }
  566. } // for each exact
  567. }
  568. },
  569. addSimpleLabelRenderer: function(renderElem, renderer) {
  570. renderElem.setAttribute("field", renderer.field);
  571. var keys = ['featureweight', 'howmanylabels', 'labelbufferratio',
  572. 'labelpriorities', 'labelweight', 'linelabelposition',
  573. 'rotationalangles'];
  574. for (var i=0, len=keys.length; i<len; i++) {
  575. var key = keys[i];
  576. if (renderer[key]) {
  577. renderElem.setAttribute(key, renderer[key]);
  578. }
  579. }
  580. if (renderer.symbol.type == "text") {
  581. var symbol = renderer.symbol;
  582. var selem = this.createElementNS("", "TEXTSYMBOL");
  583. renderElem.appendChild(selem);
  584. var keys = this.fontStyleKeys;
  585. for (var i=0, len=keys.length; i<len; i++) {
  586. var key = keys[i];
  587. if (symbol[key]) {
  588. selem.setAttribute(key, renderer[key]);
  589. }
  590. }
  591. }
  592. },
  593. writePolygonGeometry: function(polygon) {
  594. if (!(polygon instanceof OpenLayers.Geometry.Polygon)) {
  595. throw {
  596. message:'Cannot write polygon geometry to ArcXML with an ' +
  597. polygon.CLASS_NAME + ' object.',
  598. geometry: polygon
  599. };
  600. }
  601. var polyElem = this.createElementNS("", "POLYGON");
  602. for (var ln=0, lnlen=polygon.components.length; ln<lnlen; ln++) {
  603. var ring = polygon.components[ln];
  604. var ringElem = this.createElementNS("", "RING");
  605. for (var rn=0, rnlen=ring.components.length; rn<rnlen; rn++) {
  606. var point = ring.components[rn];
  607. var pointElem = this.createElementNS("", "POINT");
  608. pointElem.setAttribute("x", point.x);
  609. pointElem.setAttribute("y", point.y);
  610. ringElem.appendChild(pointElem);
  611. }
  612. polyElem.appendChild(ringElem);
  613. }
  614. return polyElem;
  615. },
  616. /**
  617. * Method: parseResponse
  618. * Take an ArcXML response, and parse in into this object's internal properties.
  619. *
  620. * Parameters:
  621. * data - {String} or {DOMElement} The ArcXML response, as either a string or the
  622. * top level DOMElement of the response.
  623. */
  624. parseResponse: function(data) {
  625. if(typeof data == "string") {
  626. var newData = new OpenLayers.Format.XML();
  627. data = newData.read(data);
  628. }
  629. var response = new OpenLayers.Format.ArcXML.Response();
  630. var errorNode = data.getElementsByTagName("ERROR");
  631. if (errorNode != null && errorNode.length > 0) {
  632. response.error = this.getChildValue(errorNode, "Unknown error.");
  633. } else {
  634. var responseNode = data.getElementsByTagName("RESPONSE");
  635. if (responseNode == null || responseNode.length == 0) {
  636. response.error = "No RESPONSE tag found in ArcXML response.";
  637. return response;
  638. }
  639. var rtype = responseNode[0].firstChild.nodeName;
  640. if (rtype == "#text") {
  641. rtype = responseNode[0].firstChild.nextSibling.nodeName;
  642. }
  643. if (rtype == "IMAGE") {
  644. var envelopeNode = data.getElementsByTagName("ENVELOPE");
  645. var outputNode = data.getElementsByTagName("OUTPUT");
  646. if (envelopeNode == null || envelopeNode.length == 0) {
  647. response.error = "No ENVELOPE tag found in ArcXML response.";
  648. } else if (outputNode == null || outputNode.length == 0) {
  649. response.error = "No OUTPUT tag found in ArcXML response.";
  650. } else {
  651. var envAttr = this.parseAttributes(envelopeNode[0]);
  652. var outputAttr = this.parseAttributes(outputNode[0]);
  653. if (typeof outputAttr.type == "string") {
  654. response.image = {
  655. envelope: envAttr,
  656. output: {
  657. type: outputAttr.type,
  658. data: this.getChildValue(outputNode[0])
  659. }
  660. };
  661. } else {
  662. response.image = { envelope: envAttr, output: outputAttr };
  663. }
  664. }
  665. } else if (rtype == "FEATURES") {
  666. var features = responseNode[0].getElementsByTagName("FEATURES");
  667. // get the feature count
  668. var featureCount = features[0].getElementsByTagName("FEATURECOUNT");
  669. response.features.featurecount = featureCount[0].getAttribute("count");
  670. if (response.features.featurecount > 0) {
  671. // get the feature envelope
  672. var envelope = features[0].getElementsByTagName("ENVELOPE");
  673. response.features.envelope = this.parseAttributes(envelope[0], typeof(0));
  674. // get the field values per feature
  675. var featureList = features[0].getElementsByTagName("FEATURE");
  676. for (var fn = 0; fn < featureList.length; fn++) {
  677. var feature = new OpenLayers.Feature.Vector();
  678. var fields = featureList[fn].getElementsByTagName("FIELD");
  679. for (var fdn = 0; fdn < fields.length; fdn++) {
  680. var fieldName = fields[fdn].getAttribute("name");
  681. var fieldValue = fields[fdn].getAttribute("value");
  682. feature.attributes[ fieldName ] = fieldValue;
  683. }
  684. var geom = featureList[fn].getElementsByTagName("POLYGON");
  685. if (geom.length > 0) {
  686. // if there is a polygon, create an openlayers polygon, and assign
  687. // it to the .geometry property of the feature
  688. var ring = geom[0].getElementsByTagName("RING");
  689. var polys = [];
  690. for (var rn = 0; rn < ring.length; rn++) {
  691. var linearRings = [];
  692. linearRings.push(this.parsePointGeometry(ring[rn]));
  693. var holes = ring[rn].getElementsByTagName("HOLE");
  694. for (var hn = 0; hn < holes.length; hn++) {
  695. linearRings.push(this.parsePointGeometry(holes[hn]));
  696. }
  697. holes = null;
  698. polys.push(new OpenLayers.Geometry.Polygon(linearRings));
  699. linearRings = null;
  700. }
  701. ring = null;
  702. if (polys.length == 1) {
  703. feature.geometry = polys[0];
  704. } else
  705. {
  706. feature.geometry = new OpenLayers.Geometry.MultiPolygon(polys);
  707. }
  708. }
  709. response.features.feature.push(feature);
  710. }
  711. }
  712. } else {
  713. response.error = "Unidentified response type.";
  714. }
  715. }
  716. return response;
  717. },
  718. /**
  719. * Method: parseAttributes
  720. *
  721. * Parameters:
  722. * node - {<DOMElement>} An element to parse attributes from.
  723. *
  724. * Returns:
  725. * {Object} An attributes object, with properties set to attribute values.
  726. */
  727. parseAttributes: function(node,type) {
  728. var attributes = {};
  729. for(var attr = 0; attr < node.attributes.length; attr++) {
  730. if (type == "number") {
  731. attributes[node.attributes[attr].nodeName] = parseFloat(node.attributes[attr].nodeValue);
  732. } else {
  733. attributes[node.attributes[attr].nodeName] = node.attributes[attr].nodeValue;
  734. }
  735. }
  736. return attributes;
  737. },
  738. /**
  739. * Method: parsePointGeometry
  740. *
  741. * Parameters:
  742. * node - {<DOMElement>} An element to parse <COORDS> or <POINT> arcxml data from.
  743. *
  744. * Returns:
  745. * {<OpenLayers.Geometry.LinearRing>} A linear ring represented by the node's points.
  746. */
  747. parsePointGeometry: function(node) {
  748. var ringPoints = [];
  749. var coords = node.getElementsByTagName("COORDS");
  750. if (coords.length > 0) {
  751. // if coords is present, it's the only coords item
  752. var coordArr = this.getChildValue(coords[0]);
  753. coordArr = coordArr.split(/;/);
  754. for (var cn = 0; cn < coordArr.length; cn++) {
  755. var coordItems = coordArr[cn].split(/ /);
  756. ringPoints.push(new OpenLayers.Geometry.Point(coordItems[0], coordItems[1]));
  757. }
  758. coords = null;
  759. } else {
  760. var point = node.getElementsByTagName("POINT");
  761. if (point.length > 0) {
  762. for (var pn = 0; pn < point.length; pn++) {
  763. ringPoints.push(
  764. new OpenLayers.Geometry.Point(
  765. parseFloat(point[pn].getAttribute("x")),
  766. parseFloat(point[pn].getAttribute("y"))
  767. )
  768. );
  769. }
  770. }
  771. point = null;
  772. }
  773. return new OpenLayers.Geometry.LinearRing(ringPoints);
  774. },
  775. CLASS_NAME: "OpenLayers.Format.ArcXML"
  776. });
  777. OpenLayers.Format.ArcXML.Request = OpenLayers.Class({
  778. initialize: function(params) {
  779. var defaults = {
  780. get_image: {
  781. properties: {
  782. background: null,
  783. /*{
  784. color: { r:255, g:255, b:255 },
  785. transcolor: null
  786. },*/
  787. draw: true,
  788. envelope: {
  789. minx: 0,
  790. miny: 0,
  791. maxx: 0,
  792. maxy: 0
  793. },
  794. featurecoordsys: {
  795. id:0,
  796. string:"",
  797. datumtransformid:0,
  798. datumtransformstring:""
  799. },
  800. filtercoordsys:{
  801. id:0,
  802. string:"",
  803. datumtransformid:0,
  804. datumtransformstring:""
  805. },
  806. imagesize:{
  807. height:0,
  808. width:0,
  809. dpi:96,
  810. printheight:0,
  811. printwidth:0,
  812. scalesymbols:false
  813. },
  814. layerlist:[],
  815. /* no support for legends */
  816. output:{
  817. baseurl:"",
  818. legendbaseurl:"",
  819. legendname:"",
  820. legendpath:"",
  821. legendurl:"",
  822. name:"",
  823. path:"",
  824. type:"jpg",
  825. url:""
  826. }
  827. }
  828. },
  829. get_feature: {
  830. layer: "",
  831. query: {
  832. isspatial: false,
  833. featurecoordsys: {
  834. id:0,
  835. string:"",
  836. datumtransformid:0,
  837. datumtransformstring:""
  838. },
  839. filtercoordsys: {
  840. id:0,
  841. string:"",
  842. datumtransformid:0,
  843. datumtransformstring:""
  844. },
  845. buffer:0,
  846. where:"",
  847. spatialfilter: {
  848. relation: "envelope_intersection",
  849. envelope: null
  850. }
  851. }
  852. },
  853. environment: {
  854. separators: {
  855. cs:" ",
  856. ts:";"
  857. }
  858. },
  859. layer: [],
  860. workspaces: []
  861. };
  862. return OpenLayers.Util.extend(this, defaults);
  863. },
  864. CLASS_NAME: "OpenLayers.Format.ArcXML.Request"
  865. });
  866. OpenLayers.Format.ArcXML.Response = OpenLayers.Class({
  867. initialize: function(params) {
  868. var defaults = {
  869. image: {
  870. envelope:null,
  871. output:''
  872. },
  873. features: {
  874. featurecount: 0,
  875. envelope: null,
  876. feature: []
  877. },
  878. error:''
  879. };
  880. return OpenLayers.Util.extend(this, defaults);
  881. },
  882. CLASS_NAME: "OpenLayers.Format.ArcXML.Response"
  883. });