Jason Davies
Line Simplification
In cartography, line simplification algorithms are often used to render high-resolution geographic features at an appropriate output resolution.
They can be applied to both polylines and polygons.
Visvalingam’s Algorithm: Avoiding Intersections
Many geometry algorithms require polygons to be simple, i.e. without self-intersections.
The following map of the Norwegian coastline demonstrates occasional intersections generated by Visvalingam’s algorithm, highlighted in red.
Data: N2000 Kartdata (scale: 1:2,000,000).
Intersections can be avoided using a simple modification.
Visvalingam’s algorithm gives each point in a line an importance weighting, so that least important points are removed first.
The importance is commonly derived from the area of the triangle formed by each point and its immediate neighbours.
In the following example, the triangle areas have been replaced with ranks for simplicity, starting with 0 for the smallest area.
On the left, the unmodified Visvalingam algorithm results in an intersection when point 0 is removed.
On the right, the modified algorithm has promoted this point to the next-largest effective area, hence two points have rank 0, and the intersection is avoided when they are both removed at once.
Unmodified Visvalingam
Modified Visvalingam
Explanation
We begin by assuming that there are no intersections between any segments.
Each time we remove a point from the heap, we ensure that the assumption still holds.
It’s somewhat easier to explain via the pseudocode below, with modifications to the standard Visvalingam algorithm highlighted:
// points is a doubly linked list
simplify(points)
heap = minHeap(compareArea)
maxArea = 0
intersecting = []
for (point in points)
point.area = area(point)
heap.add(point)
while (point = heap.pop())
if (point.area < maxArea) point.area = maxArea
else maxArea = point.area
// Check that the new segment doesn’t intersect with
// any existing segments, except for the point’s
// immediate neighbours.
if (intersect(heap, point.previous, point.next))
intersecting.push(point)
continue
// Reattempt to process points that previously would
// have caused intersections when removed.
while (i = intersecting.pop()) heap.push(i)
remove(point) // remove from doubly linked list
update(point.previous, heap)
update(point.next, heap)
update(point, heap)
point.area = area(point)
heap.update(point)
Performance
Checking for intersections between the new segment and virtually all existing segments quickly becomes impractical for non-trivial numbers of segments.
The number of intersection tests can be reduced drastically using a spatial index, e.g. an R*-tree is used in the current implementation (RBush) with excellent results.
Future Work
The current implementation is 2D-only, but I’d like to add support for spherical arc intersections.
This could potentially end up as part of TopoJSON so that problematic self-intersecting polygons are avoided when drawn with D3.
Further Reading
- Mike Bostock has written a nice illustrated explanation of how Visvalingam’s algorithm works.
- Quadratic Koch Island Simplification: a stress test for topology preservation.
- The Douglas–Peucker algorithm: sufficiency conditions for non-self-intersections
- MapShaper.org: A Map Generalization Web Service
22 July 2014
The thrillingness was slightly shorn of its vibrations by the return of her mother, who had a great deal to say about the felicitous manner in which she had opened the bazaar. She had brought back with her a small plush monkey climbing a string, and a realistic representation of a spider¡¯s web, with a woolly spider sitting in the middle of it. The rim of the web was fitted with hooks, so that you could hang it up anywhere. She selected the base of the pink clock as the most suitable site. "Why, he's going to Japan," said Mrs. Bassett. With the first streak of dawn the boys were on deck, where they were joined by Doctor Bronson. The sun was just rising when the steamer dropped her anchor, and, consequently, their first day in the new country was begun very early. There was an abundance of sights for the young eyes, and no lack of subjects for conversation. XV VENUS AND MARS "Well, neither shall I." CHAPTER XLVII. FLOWN. To search out the secret of things, and putting away two trunkfuls of clothes (it doesn't seem believable 28 ¡°Jeff!¡± Dick knelt and lifted the man¡¯s head. The White explained carefully that it was not a contract, that it was nothing at all, in fact. Webster's Primary, but I aint to be menshuned in the saim "Go ahead, there, and divide them rations, as I ordered you, and be quick about it, for we must hurry off." "Thought you'd be interested to hear. I remember as how you used to be unaccountable friendly wud them Jurys, considering the difference in your position." HoMEºÚëÒÂÁåÔ°®ÀòÃÛ
ENTER NUMBET 0016khchain.com.cn
www.iotdms.com.cn
www.iwfc.org.cn
h-wain.com.cn
wbbdtu.com.cn
www.voleye.net.cn
rfbboo.com.cn
uf8news.com.cn
www.noeixr.com.cn
www.qzqosy.com.cn