diff --git a/src/ol/format/kml.js b/src/ol/format/kml.js index eff0966db2..20f0f3509e 100644 --- a/src/ol/format/kml.js +++ b/src/ol/format/kml.js @@ -2475,10 +2475,16 @@ ol.format.KML.writePrimitiveGeometry_ = function(node, geometry, objectStack) { var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; context['layout'] = geometry.getLayout(); context['stride'] = geometry.getStride(); - ol.xml.pushSerializeAndPop(context, - ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_, - ol.format.KML.COORDINATES_NODE_FACTORY_, - [flatCoordinates], objectStack); + + // serialize properties (properties unknown to KML are not serialized) + var properties = geometry.getProperties(); + properties.coordinates = flatCoordinates; + + var parentNode = objectStack[objectStack.length - 1].node; + var orderedKeys = ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_[parentNode.namespaceURI]; + var values = ol.xml.makeSequence(properties, orderedKeys); + ol.xml.pushSerializeAndPop(context, ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_, + ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys); }; @@ -2639,7 +2645,6 @@ ol.format.KML.GEOMETRY_TYPE_TO_NODENAME_ = { 'GeometryCollection': 'MultiGeometry' }; - /** * @const * @type {Object.>} @@ -2815,6 +2820,17 @@ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS( }); +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_ = ol.xml.makeStructureNS( + ol.format.KML.NAMESPACE_URIS_, [ + 'extrude', 'tessellate', 'altitudeMode', 'coordinates' + ]); + + /** * @const * @type {Object.>} @@ -2822,6 +2838,9 @@ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS( */ ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS( ol.format.KML.NAMESPACE_URIS_, { + 'extrude': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode), + 'tessellate': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode), + 'altitudeMode': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode), 'coordinates': ol.xml.makeChildAppender( ol.format.KML.writeCoordinatesTextNode_) }); @@ -2933,16 +2952,6 @@ ol.format.KML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, ol.format.KML.COLOR_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('color'); -/** - * A factory for creating coordinates nodes. - * @const - * @type {function(*, Array.<*>, string=): (Node|undefined)} - * @private - */ -ol.format.KML.COORDINATES_NODE_FACTORY_ = - ol.xml.makeSimpleNodeFactory('coordinates'); - - /** * A factory for creating Data nodes. * @const diff --git a/test/spec/ol/format/kml.test.js b/test/spec/ol/format/kml.test.js index 02d20dbdaa..e929c80d54 100644 --- a/test/spec/ol/format/kml.test.js +++ b/test/spec/ol/format/kml.test.js @@ -192,6 +192,33 @@ describe('ol.format.KML', function() { expect(node).to.xmleql(ol.xml.parse(text)); }); + + it('can write properties', function() { + var lineString = new ol.geom.LineString([[1, 2], [3, 4]]); + lineString.set('extrude', false); + lineString.set('tessellate', true); + lineString.set('altitudeMode', 'clampToGround'); + lineString.set('unsupportedProperty', 'foo'); + var features = [new ol.Feature(lineString)]; + var node = format.writeFeaturesNode(features); + var text = + '' + + ' ' + + ' ' + + ' 0' + + ' 1' + + ' clampToGround' + + ' 1,2 3,4' + + ' ' + + ' ' + + ''; + expect(node).to.xmleql(ol.xml.parse(text)); + }); + it('can read Point geometries', function() { var text = '