docs: Update measure example.
Handle polygons with holes.
MODIFY
examples/measure/main.js
examples/measure/main.js
@@ -161,7 +161,14 @@ if (initialGeoJSON) {
if (query.x === undefined || query.y === undefined) {
const range = {};
layer.annotations().forEach(a => {
- a.coordinates().forEach(pt => {
+ let ptlist = a.coordinates();
+ if (ptlist.outer) {
+ ptlist = [ptlist.outer.slice()].concat((ptlist.inner || []).map((l) => l.slice()));
+ } else {
+ ptlist = [ptlist.slice()];
+ }
+ ptlist.forEach((pts) => {
+ pts.forEach(pt => {
if (range.left === undefined || pt.x < range.left) {
range.left = pt.x;
}
@@ -176,6 +183,7 @@ if (initialGeoJSON) {
}
});
});
+ });
map.bounds(range);
map.zoom(map.zoom() - 0.25);
}
@@ -356,7 +364,13 @@ function handleModeChange(evt) {
function annotationLength(annotation) {
let dist = 0;
const gcs = annotation.layer().map().ingcs();
- let pts = annotation.coordinates(gcs);
+ let ptlist = annotation.coordinates(gcs);
+ if (ptlist.outer) {
+ ptlist = [ptlist.outer.slice()].concat((ptlist.inner || []).map((l) => l.slice()));
+ } else {
+ ptlist = [ptlist.slice()];
+ }
+ ptlist.forEach((pts) => {
if (pts.length < 2) {
return;
}
@@ -370,6 +384,7 @@ function annotationLength(annotation) {
dist += partial.distance;
}
}
+ });
return dist;
}
@@ -382,20 +397,34 @@ function annotationLength(annotation) {
*/
function annotationArea(annotation) {
let area = 0,
- pts = annotation.coordinates('EPSG:4326');
- if (pts.length < 3 || ['polygon', 'rectangle'].indexOf(annotation.type()) < 0) {
+ ptlist = annotation.coordinates('EPSG:4326');
+ if (ptlist.outer) {
+ ptlist = [ptlist.outer];
+ } else {
+ ptlist = [ptlist];
+ }
+ if (ptlist[0].length < 3 || ['polygon', 'rectangle'].indexOf(annotation.type()) < 0) {
return;
}
// By using an equal-area projection centered at one of the vertices, the
// area calculation can be done with a simple formula. For polygons with
// long edges, this won't be accurate, however.
- const gcs = `+proj=laea +lat_0=${pts[0].y} +lon_0=${pts[0].x} +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs`;
- pts = annotation.coordinates(gcs).slice();
+ const gcs = `+proj=laea +lat_0=${ptlist[0][0].y} +lon_0=${ptlist[0][0].x} +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs`;
+ ptlist = annotation.coordinates(gcs);
+ if (ptlist.outer) {
+ ptlist = [ptlist.outer.slice()].concat((ptlist.inner || []).map((l) => l.slice()));
+ } else {
+ ptlist = [ptlist.slice()];
+ }
+ ptlist.forEach((pts, idx) => {
+ let looparea = 0;
pts.push(pts[0]);
for (let i = 0; i < pts.length - 1; i += 1) {
- area += (pts[i + 1].y - pts[i].y) * (pts[i + 1].x + pts[i].x) / 2;
+ looparea += (pts[i + 1].y - pts[i].y) * (pts[i + 1].x + pts[i].x) / 2;
}
- return Math.abs(area);
+ area += Math.abs(looparea) * (idx ? -1 : 1);
+ });
+ return area;
}
/**
@@ -416,16 +445,16 @@ function modifyAnnotation(annotation) {
area = annotationArea(annotation);
var result = s_labelRecord();
if (result) {
- dist = geo.gui.scaleWidget.formatUnit(dist, query.distunit || 'decmiles');
if (dist) {
+ dist = geo.gui.scaleWidget.formatUnit(dist, query.distunit || 'decmiles');
result.text += ' - ' + dist;
}
- area = geo.gui.scaleWidget.formatUnit(area, query.areaunit || 'decmiles', geo.gui.scaleWidget.areaUnitsTable);
if (area) {
+ area = geo.gui.scaleWidget.formatUnit(area, query.areaunit || 'decmiles', geo.gui.scaleWidget.areaUnitsTable);
result.text += ' - ' + area;
}
}
- if (result.text !== annotation._lastResultText) {
+ if (result && result.text !== annotation._lastResultText) {
map.scheduleAnimationFrame(handleAnnotationChange);
annotation._lastResultText = result.text;
}
@@ -441,8 +470,14 @@ function modifyAnnotation(annotation) {
* @param {object[]} labels The labels data array to extend.
*/
function labelVertices(annotation, annotationIndex, labels) {
- const gcs = annotation.layer().map().gcs(),
- pts = annotation.coordinates(gcs).slice();
+ const gcs = annotation.layer().map().gcs();
+ let ptlist = annotation.coordinates(gcs);
+ if (ptlist.outer) {
+ ptlist = [ptlist.outer.slice()].concat((ptlist.inner || []).map((l) => l.slice()));
+ } else {
+ ptlist = [ptlist.slice()];
+ }
+ ptlist.forEach((pts) => {
for (let i = 1; i < pts.length; i += 1) {
if (pts[i].x === pts[i - 1].x && pts[i].y === pts[i - 1].y) {
pts.splice(i, 1);
@@ -485,6 +520,7 @@ function labelVertices(annotation, annotationIndex, labels) {
});
}
});
+ });
}
/**

docs: Update measure example.

Handle polygons with holes.