Merge pull request #878 from ahocevar/polygon-labels
Better label placement for polygons
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
goog.provide('ol.geom.Polygon');
|
goog.provide('ol.geom.Polygon');
|
||||||
|
|
||||||
goog.require('goog.asserts');
|
goog.require('goog.asserts');
|
||||||
|
goog.require('ol.extent');
|
||||||
goog.require('ol.geom.Geometry');
|
goog.require('ol.geom.Geometry');
|
||||||
goog.require('ol.geom.GeometryType');
|
goog.require('ol.geom.GeometryType');
|
||||||
goog.require('ol.geom.LinearRing');
|
goog.require('ol.geom.LinearRing');
|
||||||
@@ -35,6 +36,12 @@ ol.geom.Polygon = function(coordinates, opt_shared) {
|
|||||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.Coordinate}
|
||||||
|
*/
|
||||||
|
this.labelPoint_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {ol.geom.SharedVertices}
|
* @type {ol.geom.SharedVertices}
|
||||||
*/
|
*/
|
||||||
@@ -126,3 +133,49 @@ ol.geom.Polygon.prototype.containsCoordinate = function(coordinate) {
|
|||||||
}
|
}
|
||||||
return containsCoordinate;
|
return containsCoordinate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates a point that is guaranteed to lie in the interior of the polygon.
|
||||||
|
* Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.
|
||||||
|
* @return {ol.Coordinate} A point which is in the interior of the polygon.
|
||||||
|
*/
|
||||||
|
ol.geom.Polygon.prototype.getInteriorPoint = function() {
|
||||||
|
if (goog.isNull(this.labelPoint_)) {
|
||||||
|
var center = ol.extent.getCenter(this.getBounds()),
|
||||||
|
resultY = center[1],
|
||||||
|
vertices = this.rings[0].getCoordinates(),
|
||||||
|
intersections = [],
|
||||||
|
maxLength = 0,
|
||||||
|
i, vertex1, vertex2, x, segmentLength, resultX;
|
||||||
|
|
||||||
|
// Calculate intersections with the horizontal bounding box center line
|
||||||
|
for (i = vertices.length - 1; i >= 1; --i) {
|
||||||
|
vertex1 = vertices[i];
|
||||||
|
vertex2 = vertices[i - 1];
|
||||||
|
if ((vertex1[1] >= resultY && vertex2[1] <= resultY) ||
|
||||||
|
(vertex1[1] <= resultY && vertex2[1] >= resultY)) {
|
||||||
|
x = (resultY - vertex1[1]) / (vertex2[1] - vertex1[1]) *
|
||||||
|
(vertex2[0] - vertex1[0]) + vertex1[0];
|
||||||
|
intersections.push(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the longest segment of the horizontal bounding box center line that
|
||||||
|
// has its center point inside the polygon
|
||||||
|
intersections.sort();
|
||||||
|
for (i = intersections.length - 1; i >= 1; --i) {
|
||||||
|
segmentLength = Math.abs(intersections[i] - intersections[i - 1]);
|
||||||
|
if (segmentLength > maxLength) {
|
||||||
|
x = (intersections[i] + intersections[i - 1]) / 2;
|
||||||
|
if (this.containsCoordinate([x, resultY])) {
|
||||||
|
maxLength = segmentLength;
|
||||||
|
resultX = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.labelPoint_ = [resultX, resultY];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.labelPoint_;
|
||||||
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ goog.require('goog.events');
|
|||||||
goog.require('goog.events.EventType');
|
goog.require('goog.events.EventType');
|
||||||
goog.require('goog.vec.Mat4');
|
goog.require('goog.vec.Mat4');
|
||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.extent');
|
|
||||||
goog.require('ol.geom.AbstractCollection');
|
goog.require('ol.geom.AbstractCollection');
|
||||||
goog.require('ol.geom.Geometry');
|
goog.require('ol.geom.Geometry');
|
||||||
goog.require('ol.geom.GeometryType');
|
goog.require('ol.geom.GeometryType');
|
||||||
@@ -446,8 +445,7 @@ ol.renderer.canvas.VectorRenderer.getLabelVectors = function(geometry) {
|
|||||||
return [[geometry.get(0), geometry.get(1), 0]];
|
return [[geometry.get(0), geometry.get(1), 0]];
|
||||||
}
|
}
|
||||||
if (type == ol.geom.GeometryType.POLYGON) {
|
if (type == ol.geom.GeometryType.POLYGON) {
|
||||||
// TODO: better label placement
|
var coordinates = geometry.getInteriorPoint();
|
||||||
var coordinates = ol.extent.getCenter(geometry.getBounds());
|
|
||||||
return [[coordinates[0], coordinates[1], 0]];
|
return [[coordinates[0], coordinates[1], 0]];
|
||||||
}
|
}
|
||||||
throw new Error('Label rendering not implemented for geometry type: ' +
|
throw new Error('Label rendering not implemented for geometry type: ' +
|
||||||
|
|||||||
Reference in New Issue
Block a user