v3.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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/GML/Base.js
  7. */
  8. /**
  9. * Class: OpenLayers.Format.GML.v3
  10. * Parses GML version 3.
  11. *
  12. * Inherits from:
  13. * - <OpenLayers.Format.GML.Base>
  14. */
  15. OpenLayers.Format.GML.v3 = OpenLayers.Class(OpenLayers.Format.GML.Base, {
  16. /**
  17. * Property: schemaLocation
  18. * {String} Schema location for a particular minor version. The writers
  19. * conform with the Simple Features Profile for GML.
  20. */
  21. schemaLocation: "http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd",
  22. /**
  23. * Property: curve
  24. * {Boolean} Write gml:Curve instead of gml:LineString elements. This also
  25. * affects the elements in multi-part geometries. Default is false.
  26. * To write gml:Curve elements instead of gml:LineString, set curve
  27. * to true in the options to the contstructor (cannot be changed after
  28. * instantiation).
  29. */
  30. curve: false,
  31. /**
  32. * Property: multiCurve
  33. * {Boolean} Write gml:MultiCurve instead of gml:MultiLineString. Since
  34. * the latter is deprecated in GML 3, the default is true. To write
  35. * gml:MultiLineString instead of gml:MultiCurve, set multiCurve to
  36. * false in the options to the constructor (cannot be changed after
  37. * instantiation).
  38. */
  39. multiCurve: true,
  40. /**
  41. * Property: surface
  42. * {Boolean} Write gml:Surface instead of gml:Polygon elements. This also
  43. * affects the elements in multi-part geometries. Default is false.
  44. * To write gml:Surface elements instead of gml:Polygon, set surface
  45. * to true in the options to the contstructor (cannot be changed after
  46. * instantiation).
  47. */
  48. surface: false,
  49. /**
  50. * Property: multiSurface
  51. * {Boolean} Write gml:multiSurface instead of gml:MultiPolygon. Since
  52. * the latter is deprecated in GML 3, the default is true. To write
  53. * gml:MultiPolygon instead of gml:multiSurface, set multiSurface to
  54. * false in the options to the constructor (cannot be changed after
  55. * instantiation).
  56. */
  57. multiSurface: true,
  58. /**
  59. * Constructor: OpenLayers.Format.GML.v3
  60. * Create a parser for GML v3.
  61. *
  62. * Parameters:
  63. * options - {Object} An optional object whose properties will be set on
  64. * this instance.
  65. *
  66. * Valid options properties:
  67. * featureType - {String} Local (without prefix) feature typeName (required).
  68. * featureNS - {String} Feature namespace (required).
  69. * geometryName - {String} Geometry element name.
  70. */
  71. initialize: function(options) {
  72. OpenLayers.Format.GML.Base.prototype.initialize.apply(this, [options]);
  73. },
  74. /**
  75. * Property: readers
  76. * Contains public functions, grouped by namespace prefix, that will
  77. * be applied when a namespaced node is found matching the function
  78. * name. The function will be applied in the scope of this parser
  79. * with two arguments: the node being read and a context object passed
  80. * from the parent.
  81. */
  82. readers: {
  83. "gml": OpenLayers.Util.applyDefaults({
  84. "_inherit": function(node, obj, container) {
  85. // SRSReferenceGroup attributes
  86. var dim = parseInt(node.getAttribute("srsDimension"), 10) ||
  87. (container && container.srsDimension);
  88. if (dim) {
  89. obj.srsDimension = dim;
  90. }
  91. },
  92. "featureMembers": function(node, obj) {
  93. this.readChildNodes(node, obj);
  94. },
  95. "Curve": function(node, container) {
  96. var obj = {points: []};
  97. this.readers.gml._inherit.apply(this, [node, obj, container]);
  98. this.readChildNodes(node, obj);
  99. if(!container.components) {
  100. container.components = [];
  101. }
  102. container.components.push(
  103. new OpenLayers.Geometry.LineString(obj.points)
  104. );
  105. },
  106. "segments": function(node, obj) {
  107. this.readChildNodes(node, obj);
  108. },
  109. "LineStringSegment": function(node, container) {
  110. var obj = {};
  111. this.readChildNodes(node, obj);
  112. if(obj.points) {
  113. Array.prototype.push.apply(container.points, obj.points);
  114. }
  115. },
  116. "pos": function(node, obj) {
  117. var str = this.getChildValue(node).replace(
  118. this.regExes.trimSpace, ""
  119. );
  120. var coords = str.split(this.regExes.splitSpace);
  121. var point;
  122. if(this.xy) {
  123. point = new OpenLayers.Geometry.Point(
  124. coords[0], coords[1], coords[2]
  125. );
  126. } else {
  127. point = new OpenLayers.Geometry.Point(
  128. coords[1], coords[0], coords[2]
  129. );
  130. }
  131. obj.points = [point];
  132. },
  133. "posList": function(node, obj) {
  134. var str = this.getChildValue(node).replace(
  135. this.regExes.trimSpace, ""
  136. );
  137. var coords = str.split(this.regExes.splitSpace);
  138. // The "dimension" attribute is from the GML 3.0.1 spec.
  139. var dim = obj.srsDimension ||
  140. parseInt(node.getAttribute("srsDimension") || node.getAttribute("dimension"), 10) || 2;
  141. var j, x, y, z;
  142. var numPoints = coords.length / dim;
  143. var points = new Array(numPoints);
  144. for(var i=0, len=coords.length; i<len; i += dim) {
  145. x = coords[i];
  146. y = coords[i+1];
  147. z = (dim == 2) ? undefined : coords[i+2];
  148. if (this.xy) {
  149. points[i/dim] = new OpenLayers.Geometry.Point(x, y, z);
  150. } else {
  151. points[i/dim] = new OpenLayers.Geometry.Point(y, x, z);
  152. }
  153. }
  154. obj.points = points;
  155. },
  156. "Surface": function(node, obj) {
  157. this.readChildNodes(node, obj);
  158. },
  159. "patches": function(node, obj) {
  160. this.readChildNodes(node, obj);
  161. },
  162. "PolygonPatch": function(node, obj) {
  163. this.readers.gml.Polygon.apply(this, [node, obj]);
  164. },
  165. "exterior": function(node, container) {
  166. var obj = {};
  167. this.readChildNodes(node, obj);
  168. container.outer = obj.components[0];
  169. },
  170. "interior": function(node, container) {
  171. var obj = {};
  172. this.readChildNodes(node, obj);
  173. container.inner.push(obj.components[0]);
  174. },
  175. "MultiCurve": function(node, container) {
  176. var obj = {components: []};
  177. this.readers.gml._inherit.apply(this, [node, obj, container]);
  178. this.readChildNodes(node, obj);
  179. if(obj.components.length > 0) {
  180. container.components = [
  181. new OpenLayers.Geometry.MultiLineString(obj.components)
  182. ];
  183. }
  184. },
  185. "curveMember": function(node, obj) {
  186. this.readChildNodes(node, obj);
  187. },
  188. "MultiSurface": function(node, container) {
  189. var obj = {components: []};
  190. this.readers.gml._inherit.apply(this, [node, obj, container]);
  191. this.readChildNodes(node, obj);
  192. if(obj.components.length > 0) {
  193. container.components = [
  194. new OpenLayers.Geometry.MultiPolygon(obj.components)
  195. ];
  196. }
  197. },
  198. "surfaceMember": function(node, obj) {
  199. this.readChildNodes(node, obj);
  200. },
  201. "surfaceMembers": function(node, obj) {
  202. this.readChildNodes(node, obj);
  203. },
  204. "pointMembers": function(node, obj) {
  205. this.readChildNodes(node, obj);
  206. },
  207. "lineStringMembers": function(node, obj) {
  208. this.readChildNodes(node, obj);
  209. },
  210. "polygonMembers": function(node, obj) {
  211. this.readChildNodes(node, obj);
  212. },
  213. "geometryMembers": function(node, obj) {
  214. this.readChildNodes(node, obj);
  215. },
  216. "Envelope": function(node, container) {
  217. var obj = {points: new Array(2)};
  218. this.readChildNodes(node, obj);
  219. if(!container.components) {
  220. container.components = [];
  221. }
  222. var min = obj.points[0];
  223. var max = obj.points[1];
  224. container.components.push(
  225. new OpenLayers.Bounds(min.x, min.y, max.x, max.y)
  226. );
  227. },
  228. "lowerCorner": function(node, container) {
  229. var obj = {};
  230. this.readers.gml.pos.apply(this, [node, obj]);
  231. container.points[0] = obj.points[0];
  232. },
  233. "upperCorner": function(node, container) {
  234. var obj = {};
  235. this.readers.gml.pos.apply(this, [node, obj]);
  236. container.points[1] = obj.points[0];
  237. }
  238. }, OpenLayers.Format.GML.Base.prototype.readers["gml"]),
  239. "feature": OpenLayers.Format.GML.Base.prototype.readers["feature"],
  240. "wfs": OpenLayers.Format.GML.Base.prototype.readers["wfs"]
  241. },
  242. /**
  243. * Method: write
  244. *
  245. * Parameters:
  246. * features - {Array(<OpenLayers.Feature.Vector>) | OpenLayers.Feature.Vector}
  247. * An array of features or a single feature.
  248. *
  249. * Returns:
  250. * {String} Given an array of features, a doc with a gml:featureMembers
  251. * element will be returned. Given a single feature, a doc with a
  252. * gml:featureMember element will be returned.
  253. */
  254. write: function(features) {
  255. var name;
  256. if(OpenLayers.Util.isArray(features)) {
  257. name = "featureMembers";
  258. } else {
  259. name = "featureMember";
  260. }
  261. var root = this.writeNode("gml:" + name, features);
  262. this.setAttributeNS(
  263. root, this.namespaces["xsi"],
  264. "xsi:schemaLocation", this.schemaLocation
  265. );
  266. return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
  267. },
  268. /**
  269. * Property: writers
  270. * As a compliment to the readers property, this structure contains public
  271. * writing functions grouped by namespace alias and named like the
  272. * node names they produce.
  273. */
  274. writers: {
  275. "gml": OpenLayers.Util.applyDefaults({
  276. "featureMembers": function(features) {
  277. var node = this.createElementNSPlus("gml:featureMembers");
  278. for(var i=0, len=features.length; i<len; ++i) {
  279. this.writeNode("feature:_typeName", features[i], node);
  280. }
  281. return node;
  282. },
  283. "Point": function(geometry) {
  284. var node = this.createElementNSPlus("gml:Point");
  285. this.writeNode("pos", geometry, node);
  286. return node;
  287. },
  288. "pos": function(point) {
  289. // only 2d for simple features profile
  290. var pos = (this.xy) ?
  291. (point.x + " " + point.y) : (point.y + " " + point.x);
  292. return this.createElementNSPlus("gml:pos", {
  293. value: pos
  294. });
  295. },
  296. "LineString": function(geometry) {
  297. var node = this.createElementNSPlus("gml:LineString");
  298. this.writeNode("posList", geometry.components, node);
  299. return node;
  300. },
  301. "Curve": function(geometry) {
  302. var node = this.createElementNSPlus("gml:Curve");
  303. this.writeNode("segments", geometry, node);
  304. return node;
  305. },
  306. "segments": function(geometry) {
  307. var node = this.createElementNSPlus("gml:segments");
  308. this.writeNode("LineStringSegment", geometry, node);
  309. return node;
  310. },
  311. "LineStringSegment": function(geometry) {
  312. var node = this.createElementNSPlus("gml:LineStringSegment");
  313. this.writeNode("posList", geometry.components, node);
  314. return node;
  315. },
  316. "posList": function(points) {
  317. // only 2d for simple features profile
  318. var len = points.length;
  319. var parts = new Array(len);
  320. var point;
  321. for(var i=0; i<len; ++i) {
  322. point = points[i];
  323. if(this.xy) {
  324. parts[i] = point.x + " " + point.y;
  325. } else {
  326. parts[i] = point.y + " " + point.x;
  327. }
  328. }
  329. return this.createElementNSPlus("gml:posList", {
  330. value: parts.join(" ")
  331. });
  332. },
  333. "Surface": function(geometry) {
  334. var node = this.createElementNSPlus("gml:Surface");
  335. this.writeNode("patches", geometry, node);
  336. return node;
  337. },
  338. "patches": function(geometry) {
  339. var node = this.createElementNSPlus("gml:patches");
  340. this.writeNode("PolygonPatch", geometry, node);
  341. return node;
  342. },
  343. "PolygonPatch": function(geometry) {
  344. var node = this.createElementNSPlus("gml:PolygonPatch", {
  345. attributes: {interpolation: "planar"}
  346. });
  347. this.writeNode("exterior", geometry.components[0], node);
  348. for(var i=1, len=geometry.components.length; i<len; ++i) {
  349. this.writeNode(
  350. "interior", geometry.components[i], node
  351. );
  352. }
  353. return node;
  354. },
  355. "Polygon": function(geometry) {
  356. var node = this.createElementNSPlus("gml:Polygon");
  357. this.writeNode("exterior", geometry.components[0], node);
  358. for(var i=1, len=geometry.components.length; i<len; ++i) {
  359. this.writeNode(
  360. "interior", geometry.components[i], node
  361. );
  362. }
  363. return node;
  364. },
  365. "exterior": function(ring) {
  366. var node = this.createElementNSPlus("gml:exterior");
  367. this.writeNode("LinearRing", ring, node);
  368. return node;
  369. },
  370. "interior": function(ring) {
  371. var node = this.createElementNSPlus("gml:interior");
  372. this.writeNode("LinearRing", ring, node);
  373. return node;
  374. },
  375. "LinearRing": function(ring) {
  376. var node = this.createElementNSPlus("gml:LinearRing");
  377. this.writeNode("posList", ring.components, node);
  378. return node;
  379. },
  380. "MultiCurve": function(geometry) {
  381. var node = this.createElementNSPlus("gml:MultiCurve");
  382. var components = geometry.components || [geometry];
  383. for(var i=0, len=components.length; i<len; ++i) {
  384. this.writeNode("curveMember", components[i], node);
  385. }
  386. return node;
  387. },
  388. "curveMember": function(geometry) {
  389. var node = this.createElementNSPlus("gml:curveMember");
  390. if(this.curve) {
  391. this.writeNode("Curve", geometry, node);
  392. } else {
  393. this.writeNode("LineString", geometry, node);
  394. }
  395. return node;
  396. },
  397. "MultiSurface": function(geometry) {
  398. var node = this.createElementNSPlus("gml:MultiSurface");
  399. var components = geometry.components || [geometry];
  400. for(var i=0, len=components.length; i<len; ++i) {
  401. this.writeNode("surfaceMember", components[i], node);
  402. }
  403. return node;
  404. },
  405. "surfaceMember": function(polygon) {
  406. var node = this.createElementNSPlus("gml:surfaceMember");
  407. if(this.surface) {
  408. this.writeNode("Surface", polygon, node);
  409. } else {
  410. this.writeNode("Polygon", polygon, node);
  411. }
  412. return node;
  413. },
  414. "Envelope": function(bounds) {
  415. var node = this.createElementNSPlus("gml:Envelope");
  416. this.writeNode("lowerCorner", bounds, node);
  417. this.writeNode("upperCorner", bounds, node);
  418. // srsName attribute is required for gml:Envelope
  419. if(this.srsName) {
  420. node.setAttribute("srsName", this.srsName);
  421. }
  422. return node;
  423. },
  424. "lowerCorner": function(bounds) {
  425. // only 2d for simple features profile
  426. var pos = (this.xy) ?
  427. (bounds.left + " " + bounds.bottom) :
  428. (bounds.bottom + " " + bounds.left);
  429. return this.createElementNSPlus("gml:lowerCorner", {
  430. value: pos
  431. });
  432. },
  433. "upperCorner": function(bounds) {
  434. // only 2d for simple features profile
  435. var pos = (this.xy) ?
  436. (bounds.right + " " + bounds.top) :
  437. (bounds.top + " " + bounds.right);
  438. return this.createElementNSPlus("gml:upperCorner", {
  439. value: pos
  440. });
  441. }
  442. }, OpenLayers.Format.GML.Base.prototype.writers["gml"]),
  443. "feature": OpenLayers.Format.GML.Base.prototype.writers["feature"],
  444. "wfs": OpenLayers.Format.GML.Base.prototype.writers["wfs"]
  445. },
  446. /**
  447. * Method: setGeometryTypes
  448. * Sets the <geometryTypes> mapping.
  449. */
  450. setGeometryTypes: function() {
  451. this.geometryTypes = {
  452. "OpenLayers.Geometry.Point": "Point",
  453. "OpenLayers.Geometry.MultiPoint": "MultiPoint",
  454. "OpenLayers.Geometry.LineString": (this.curve === true) ? "Curve": "LineString",
  455. "OpenLayers.Geometry.MultiLineString": (this.multiCurve === false) ? "MultiLineString" : "MultiCurve",
  456. "OpenLayers.Geometry.Polygon": (this.surface === true) ? "Surface" : "Polygon",
  457. "OpenLayers.Geometry.MultiPolygon": (this.multiSurface === false) ? "MultiPolygon" : "MultiSurface",
  458. "OpenLayers.Geometry.Collection": "GeometryCollection"
  459. };
  460. },
  461. CLASS_NAME: "OpenLayers.Format.GML.v3"
  462. });