Draw multi-part geometries

Polygons still need holes.
This commit is contained in:
Tim Schaub
2013-03-06 19:01:16 -07:00
parent 100c8a1cf4
commit 7c4c3c547c
+59 -22
View File
@@ -10,6 +10,9 @@ goog.require('ol.canvas');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.LineString'); goog.require('ol.geom.LineString');
goog.require('ol.geom.MultiLineString');
goog.require('ol.geom.MultiPoint');
goog.require('ol.geom.MultiPolygon');
goog.require('ol.geom.Point'); goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon'); goog.require('ol.geom.Polygon');
goog.require('ol.style.IconLiteral'); goog.require('ol.style.IconLiteral');
@@ -95,17 +98,23 @@ ol.renderer.canvas.Renderer.prototype.renderFeaturesByGeometryType =
var deferred = false; var deferred = false;
switch (type) { switch (type) {
case ol.geom.GeometryType.POINT: case ol.geom.GeometryType.POINT:
goog.asserts.assert(symbolizer instanceof ol.style.PointLiteral); case ol.geom.GeometryType.MULTIPOINT:
goog.asserts.assert(symbolizer instanceof ol.style.PointLiteral,
'Expected point symbolizer: ' + symbolizer);
deferred = this.renderPointFeatures_( deferred = this.renderPointFeatures_(
features, /** @type {ol.style.PointLiteral} */ (symbolizer)); features, /** @type {ol.style.PointLiteral} */ (symbolizer));
break; break;
case ol.geom.GeometryType.LINESTRING: case ol.geom.GeometryType.LINESTRING:
goog.asserts.assert(symbolizer instanceof ol.style.LineLiteral); case ol.geom.GeometryType.MULTILINESTRING:
goog.asserts.assert(symbolizer instanceof ol.style.LineLiteral,
'Expected line symbolizer: ' + symbolizer);
this.renderLineStringFeatures_( this.renderLineStringFeatures_(
features, /** @type {ol.style.LineLiteral} */ (symbolizer)); features, /** @type {ol.style.LineLiteral} */ (symbolizer));
break; break;
case ol.geom.GeometryType.POLYGON: case ol.geom.GeometryType.POLYGON:
goog.asserts.assert(symbolizer instanceof ol.style.PolygonLiteral); case ol.geom.GeometryType.MULTIPOLYGON:
goog.asserts.assert(symbolizer instanceof ol.style.PolygonLiteral,
'Expected polygon symbolizer: ' + symbolizer);
this.renderPolygonFeatures_( this.renderPolygonFeatures_(
features, /** @type {ol.style.PolygonLiteral} */ (symbolizer)); features, /** @type {ol.style.PolygonLiteral} */ (symbolizer));
break; break;
@@ -125,25 +134,35 @@ ol.renderer.canvas.Renderer.prototype.renderLineStringFeatures_ =
function(features, symbolizer) { function(features, symbolizer) {
var context = this.context_, var context = this.context_,
i, ii, line, dim, j, jj, x, y; i, ii, geometry, components, j, jj, line, dim, k, kk, x, y;
context.globalAlpha = symbolizer.opacity; context.globalAlpha = symbolizer.opacity;
context.strokeStyle = symbolizer.strokeStyle; context.strokeStyle = symbolizer.strokeStyle;
context.lineWidth = symbolizer.strokeWidth * this.inverseScale_; context.lineWidth = symbolizer.strokeWidth * this.inverseScale_;
context.beginPath(); context.beginPath();
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
line = /** @type {ol.geom.LineString} */ features[i].getGeometry(); geometry = features[i].getGeometry();
if (geometry instanceof ol.geom.LineString) {
components = [geometry];
} else {
goog.asserts.assert(geometry instanceof ol.geom.MultiLineString,
'Expected MultiLineString');
components = geometry.components;
}
for (j = 0, jj = components.length; j < jj; ++j) {
line = components[j];
dim = line.dimension; dim = line.dimension;
for (j = 0, jj = line.getCount(); j < jj; ++j) { for (k = 0, kk = line.getCount(); k < kk; ++k) {
x = line.get(j, 0); x = line.get(k, 0);
y = line.get(j, 1); y = line.get(k, 1);
if (j === 0) { if (k === 0) {
context.moveTo(x, y); context.moveTo(x, y);
} else { } else {
context.lineTo(x, y); context.lineTo(x, y);
} }
} }
} }
}
context.stroke(); context.stroke();
}; };
@@ -159,7 +178,7 @@ ol.renderer.canvas.Renderer.prototype.renderPointFeatures_ =
function(features, symbolizer) { function(features, symbolizer) {
var context = this.context_, var context = this.context_,
content, alpha, i, ii, point, vec; content, alpha, i, ii, geometry, components, j, jj, point, vec;
if (symbolizer instanceof ol.style.ShapeLiteral) { if (symbolizer instanceof ol.style.ShapeLiteral) {
content = ol.renderer.canvas.Renderer.renderShape(symbolizer); content = ol.renderer.canvas.Renderer.renderShape(symbolizer);
@@ -182,11 +201,21 @@ ol.renderer.canvas.Renderer.prototype.renderPointFeatures_ =
context.setTransform(1, 0, 0, 1, -midWidth, -midHeight); context.setTransform(1, 0, 0, 1, -midWidth, -midHeight);
context.globalAlpha = alpha; context.globalAlpha = alpha;
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
point = /** @type {ol.geom.Point} */ features[i].getGeometry(); geometry = features[i].getGeometry();
if (geometry instanceof ol.geom.Point) {
components = [geometry];
} else {
goog.asserts.assert(geometry instanceof ol.geom.MultiPoint,
'Expected MultiPoint');
components = geometry.components;
}
for (j = 0, jj = components.length; j < jj; ++j) {
point = components[j];
vec = goog.vec.Mat4.multVec3( vec = goog.vec.Mat4.multVec3(
this.transform_, [point.get(0), point.get(1), 0], []); this.transform_, [point.get(0), point.get(1), 0], []);
context.drawImage(content, vec[0], vec[1], content.width, content.height); context.drawImage(content, vec[0], vec[1], content.width, content.height);
} }
}
context.restore(); context.restore();
return false; return false;
@@ -204,7 +233,8 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
var context = this.context_, var context = this.context_,
strokeStyle = symbolizer.strokeStyle, strokeStyle = symbolizer.strokeStyle,
fillStyle = symbolizer.fillStyle, fillStyle = symbolizer.fillStyle,
i, ii, poly, rings, numRings, ring, dim, j, jj, x, y; i, ii, geometry, components, j, jj, poly,
rings, numRings, ring, dim, k, kk, x, y;
context.globalAlpha = symbolizer.opacity; context.globalAlpha = symbolizer.opacity;
if (strokeStyle) { if (strokeStyle) {
@@ -224,20 +254,26 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
*/ */
context.beginPath(); context.beginPath();
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
poly = /** @type {ol.geom.Polygon} */ features[i].getGeometry(); geometry = features[i].getGeometry();
if (geometry instanceof ol.geom.Polygon) {
components = [geometry];
} else {
goog.asserts.assert(geometry instanceof ol.geom.MultiPolygon,
'Expected MultiPolygon');
components = geometry.components;
}
for (j = 0, jj = components.length; j < jj; ++j) {
poly = components[j];
dim = poly.dimension; dim = poly.dimension;
rings = poly.rings; rings = poly.rings;
numRings = rings.length; numRings = rings.length;
if (numRings > 1) { if (numRings > 0) {
// scenario 4 // TODO: scenario 4
// TODO: use sketch canvas to render outer and punch holes for inner rings
throw new Error('Rendering holes not implemented');
} else {
ring = rings[0]; ring = rings[0];
for (j = 0, jj = ring.getCount(); j < jj; ++j) { for (k = 0, kk = ring.getCount(); k < kk; ++k) {
x = ring.get(j, 0); x = ring.get(k, 0);
y = ring.get(j, 1); y = ring.get(k, 1);
if (j === 0) { if (k === 0) {
context.moveTo(x, y); context.moveTo(x, y);
} else { } else {
context.lineTo(x, y); context.lineTo(x, y);
@@ -253,6 +289,7 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
} }
} }
} }
}
if (!(fillStyle && strokeStyle)) { if (!(fillStyle && strokeStyle)) {
if (fillStyle) { if (fillStyle) {
// scenario 2 - fill all at once // scenario 2 - fill all at once