Store rings so exerior is clockwise and interior is counter-clockwise
KML and WKT don't specify a winding order, so we write those out in CW/CCW order (for exterior/interior). GML references ISO 19107 that specifies CCW/CW, so we serialize in that winding order. Having hand generated all this GML data the first time around, I reserve the right to modify it for the tests.
This commit is contained in:
@@ -10,6 +10,12 @@ goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
/**
|
||||
* Create a polygon from an array of vertex arrays. Coordinates for the
|
||||
* exterior ring will be forced to clockwise order. Coordinates for any
|
||||
* interior rings will be forced to counter-clockwise order. In cases where
|
||||
* the opposite winding order occurs in the passed vertex arrays, they will
|
||||
* be modified in place.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {Array.<ol.geom.VertexArray>} coordinates Array of rings. First
|
||||
@@ -40,8 +46,21 @@ ol.geom.Polygon = function(coordinates, opt_shared) {
|
||||
* @type {Array.<ol.geom.LinearRing>}
|
||||
*/
|
||||
this.rings = new Array(numRings);
|
||||
var ringCoords;
|
||||
for (var i = 0; i < numRings; ++i) {
|
||||
this.rings[i] = new ol.geom.LinearRing(coordinates[i], vertices);
|
||||
ringCoords = coordinates[i];
|
||||
if (i === 0) {
|
||||
// force exterior ring to be clockwise
|
||||
if (!ol.geom.LinearRing.isClockwise(ringCoords)) {
|
||||
ringCoords.reverse();
|
||||
}
|
||||
} else {
|
||||
// force interior rings to be counter-clockwise
|
||||
if (ol.geom.LinearRing.isClockwise(ringCoords)) {
|
||||
ringCoords.reverse();
|
||||
}
|
||||
}
|
||||
this.rings[i] = new ol.geom.LinearRing(ringCoords, vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -755,6 +755,10 @@ ol.parser.KML = function(opt_options) {
|
||||
return node;
|
||||
},
|
||||
'Polygon': function(geometry) {
|
||||
/**
|
||||
* KML doesn't specify the winding order of coordinates in linear
|
||||
* rings. So we keep them as they are in the geometries.
|
||||
*/
|
||||
var node = this.createElementNS('Polygon');
|
||||
var coordinates = geometry.getCoordinates();
|
||||
this.writeNode('outerBoundaryIs', coordinates[0], null, node);
|
||||
|
||||
@@ -67,9 +67,17 @@ ol.parser.ogc.GML_v2 = function(opt_options) {
|
||||
'Polygon': function(geometry) {
|
||||
var node = this.createElementNS('gml:Polygon');
|
||||
var coordinates = geometry.getCoordinates();
|
||||
this.writeNode('outerBoundaryIs', coordinates[0], null, node);
|
||||
/**
|
||||
* Though there continues to be ambiguity around this, GML references
|
||||
* ISO 19107, which says polygons have counter-clockwise exterior rings
|
||||
* and clockwise interior rings. The ambiguity comes because the
|
||||
* the Simple Feature Access - SQL spec (ISO 19125-2) says that no
|
||||
* winding order is enforced. Anyway, we write out counter-clockwise
|
||||
* exterior and clockwise interior here but accept either when reading.
|
||||
*/
|
||||
this.writeNode('outerBoundaryIs', coordinates[0].reverse(), null, node);
|
||||
for (var i = 1; i < coordinates.length; ++i) {
|
||||
this.writeNode('innerBoundaryIs', coordinates[i], null, node);
|
||||
this.writeNode('innerBoundaryIs', coordinates[i].reverse(), null, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
@@ -298,18 +298,26 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
|
||||
var node = this.createElementNS('gml:PolygonPatch');
|
||||
node.setAttribute('interpolation', 'planar');
|
||||
var coordinates = geometry.getCoordinates();
|
||||
this.writeNode('exterior', coordinates[0], null, node);
|
||||
this.writeNode('exterior', coordinates[0].reverse(), null, node);
|
||||
for (var i = 1, len = coordinates.length; i < len; ++i) {
|
||||
this.writeNode('interior', coordinates[i], null, node);
|
||||
this.writeNode('interior', coordinates[i].reverse(), null, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
'Polygon': function(geometry) {
|
||||
var node = this.createElementNS('gml:Polygon');
|
||||
var coordinates = geometry.getCoordinates();
|
||||
this.writeNode('exterior', coordinates[0], null, node);
|
||||
/**
|
||||
* Though there continues to be ambiguity around this, GML references
|
||||
* ISO 19107, which says polygons have counter-clockwise exterior rings
|
||||
* and clockwise interior rings. The ambiguity comes because the
|
||||
* the Simple Feature Access - SQL spec (ISO 19125-2) says that no
|
||||
* winding order is enforced. Anyway, we write out counter-clockwise
|
||||
* exterior and clockwise interior here but accept either when reading.
|
||||
*/
|
||||
this.writeNode('exterior', coordinates[0].reverse(), null, node);
|
||||
for (var i = 1, len = coordinates.length; i < len; ++i) {
|
||||
this.writeNode('interior', coordinates[i], null, node);
|
||||
this.writeNode('interior', coordinates[i].reverse(), null, node);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user