Added Douglas-Peucker linestring simplification to OpenLayers.Geometry.LineString. Thanks chrismayer for this excellent patch. p=chrismayer, r=me (closes #2869)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@10969 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
86
examples/simplify-linestring.html
Normal file
86
examples/simplify-linestring.html
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Simplify LineString</title>
|
||||||
|
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
|
||||||
|
<link rel="stylesheet" href="style.css" type="text/css">
|
||||||
|
<style type="text/css">
|
||||||
|
#map, #map-simplify {
|
||||||
|
height: 400px;
|
||||||
|
width: 400px;
|
||||||
|
margin: 5px !important;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
#info {
|
||||||
|
width: 300px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 id="title">Simplify a LineString</h1>
|
||||||
|
<div id="tags">
|
||||||
|
Douglas-Peucker, Douglas, Peucker, Peuker, tolerance
|
||||||
|
</div>
|
||||||
|
<p id="shortdesc">
|
||||||
|
Shows the usage of the utility method "simplifyLineString" that
|
||||||
|
implements the Douglas-Peucker algorithm to remove "insignificant"
|
||||||
|
vertices from LineString geometries.
|
||||||
|
</p>
|
||||||
|
<div id="control-simplify">
|
||||||
|
<input name="tolerance" id="tolerance" type="number" min="0" max="1" step="0.02" value="0.1">
|
||||||
|
<input type="button" id="simplify" value="Simplify LineString">
|
||||||
|
<input type="button" id="animation" value="Start animation">
|
||||||
|
</div>
|
||||||
|
<div id="map" class="smallmap">
|
||||||
|
</div>
|
||||||
|
<div id="map-simplify" class="smallmap">
|
||||||
|
</div>
|
||||||
|
<div id="info">
|
||||||
|
</div>
|
||||||
|
<div id="docs" style="clear: both;">
|
||||||
|
<p>
|
||||||
|
The method OpenLayers.Util.simplifyLineString can be used to
|
||||||
|
simplify linestring geometries. Simplification sometimes is
|
||||||
|
useful to enhance the perfomance of vector rendering or to
|
||||||
|
reduce complexity of geometries. This might be especially handy
|
||||||
|
when viewing geometries a small scales.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
OpenLayers.Util.simplifyLineString is a recursive implementation
|
||||||
|
of the famous Douglas-Peucker algorithm. It
|
||||||
|
is controlled by a tolerance factor that defines the threshold
|
||||||
|
for vertices to be considered "insignificant" for the general
|
||||||
|
structure of the geometry.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The LineString on the left map can be simplified according to
|
||||||
|
the tolerance value one enters in the form-field above the maps.
|
||||||
|
Use a value between 0 and 1 for best results. If you navigate
|
||||||
|
the left map, the right map will show the same location to make
|
||||||
|
it easier to spot the differeces between the LineStrings.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The LineString
|
||||||
|
represents a part of the coastline of
|
||||||
|
<a href="http://www.openstreetmap.org/?lat=54.7309684753418&lon=83.1809234619141&zoom=11">this
|
||||||
|
place in Russia</a> — found via <a href="http://ryba4.com/python/ramer-douglas-peucker">an
|
||||||
|
example implementation of the algorithm in python</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For a detailled explanation of the algorithm see
|
||||||
|
<a href="http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm">the
|
||||||
|
Wikipedia article</a> or the original publication: David Douglas
|
||||||
|
& Thomas Peucker, "Algorithms for the reduction of the
|
||||||
|
number of points required to represent a digitized line or its
|
||||||
|
caricature", The Canadian Cartographer 10(2), 112-122 (1973)
|
||||||
|
(<a href="http://dx.doi.org/10.3138/FM57-6770-U75U-7727">DOI:
|
||||||
|
10.3138/FM57-6770-U75U-7727</a>).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="../lib/OpenLayers.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="simplify-linestring.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
599
examples/simplify-linestring.js
Normal file
599
examples/simplify-linestring.js
Normal file
@@ -0,0 +1,599 @@
|
|||||||
|
// global variables
|
||||||
|
var map, map2;
|
||||||
|
|
||||||
|
// wrap the instanciation code in an anonymous function that gets executed
|
||||||
|
// immedeately
|
||||||
|
(function(){
|
||||||
|
// style the vectorlayer
|
||||||
|
var styleMap = new OpenLayers.StyleMap({
|
||||||
|
'default': new OpenLayers.Style({
|
||||||
|
strokeColor: "#333333",
|
||||||
|
strokeWidth: 1.2,
|
||||||
|
strokeOpacity: 1
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// the vectorlayer
|
||||||
|
var vectorlayer = new OpenLayers.Layer.Vector('Vectorlayer', {
|
||||||
|
isBaseLayer: true,
|
||||||
|
styleMap: styleMap
|
||||||
|
});
|
||||||
|
|
||||||
|
var original = OpenLayers.Geometry.fromWKT("LINESTRING(" +
|
||||||
|
"6.247872 11.316756," +
|
||||||
|
"6.338566 11.316756," +
|
||||||
|
"6.633323 11.205644," +
|
||||||
|
"6.724018 11.205644," +
|
||||||
|
"6.792039 11.205644," +
|
||||||
|
"7.154817 11.372311," +
|
||||||
|
"7.313532 11.400089," +
|
||||||
|
"7.381553 11.344533," +
|
||||||
|
"7.336206 11.288978," +
|
||||||
|
"7.200164 11.288978," +
|
||||||
|
"7.154817 11.261200," +
|
||||||
|
"7.132143 11.233422," +
|
||||||
|
"7.154817 11.150089," +
|
||||||
|
"7.268185 11.177867," +
|
||||||
|
"7.313532 11.122311," +
|
||||||
|
"7.404227 11.150089," +
|
||||||
|
"7.472248 11.094533," +
|
||||||
|
"7.767005 10.900089," +
|
||||||
|
"7.758951 10.864989," +
|
||||||
|
"7.752684 10.837656," +
|
||||||
|
"7.426900 10.927867," +
|
||||||
|
"6.519955 10.927867," +
|
||||||
|
"6.429261 10.900089," +
|
||||||
|
"6.315893 10.955644," +
|
||||||
|
"6.270545 10.955644," +
|
||||||
|
"6.247872 10.927867," +
|
||||||
|
"6.111830 11.011200," +
|
||||||
|
"6.066483 11.066756," +
|
||||||
|
"5.862420 11.038978," +
|
||||||
|
"5.817073 10.955644," +
|
||||||
|
"5.771726 10.900089," +
|
||||||
|
"5.862420 10.761200," +
|
||||||
|
"5.975788 10.733422," +
|
||||||
|
"6.157177 10.566756," +
|
||||||
|
"6.247872 10.511200," +
|
||||||
|
"6.293219 10.427867," +
|
||||||
|
"6.315893 10.233422," +
|
||||||
|
"6.315893 10.177867," +
|
||||||
|
"6.542629 9.844533," +
|
||||||
|
"6.587976 9.761200," +
|
||||||
|
"6.610650 9.288978," +
|
||||||
|
"6.542629 9.066756," +
|
||||||
|
"6.565303 8.900089," +
|
||||||
|
"6.519955 8.816756," +
|
||||||
|
"6.542629 8.761200," +
|
||||||
|
"6.565303 8.733422," +
|
||||||
|
"6.429261 8.427867," +
|
||||||
|
"6.474608 8.316756," +
|
||||||
|
"6.724018 8.288978," +
|
||||||
|
"6.882733 8.538978," +
|
||||||
|
"6.973428 8.594533," +
|
||||||
|
"6.996101 8.622311," +
|
||||||
|
"7.200164 8.650089," +
|
||||||
|
"7.290859 8.650089," +
|
||||||
|
"7.426900 8.483422," +
|
||||||
|
"7.404227 8.455644," +
|
||||||
|
"7.245511 8.511200," +
|
||||||
|
"6.996101 8.427867," +
|
||||||
|
"7.041449 8.372311," +
|
||||||
|
"7.154817 8.455644," +
|
||||||
|
"7.200164 8.455644," +
|
||||||
|
"7.245511 8.455644," +
|
||||||
|
"7.381553 8.316756," +
|
||||||
|
"7.381553 8.261200," +
|
||||||
|
"7.404227 8.233422," +
|
||||||
|
"7.494921 8.205644," +
|
||||||
|
"7.767005 8.288978," +
|
||||||
|
"7.948394 8.233422," +
|
||||||
|
"8.016415 8.261200," +
|
||||||
|
"8.197804 8.094533," +
|
||||||
|
"8.084435 7.816756," +
|
||||||
|
"8.152456 7.733422," +
|
||||||
|
"8.175130 7.650089," +
|
||||||
|
"8.175130 7.511200," +
|
||||||
|
"8.311172 7.427867," +
|
||||||
|
"8.311172 7.372311," +
|
||||||
|
"8.651276 7.372311," +
|
||||||
|
"8.923360 7.316756," +
|
||||||
|
"8.900686 7.261200," +
|
||||||
|
"8.809991 7.261200," +
|
||||||
|
"8.472735 7.171122," +
|
||||||
|
"8.333845 7.038978," +
|
||||||
|
"8.282022 6.981100," +
|
||||||
|
"8.254778 6.848911," +
|
||||||
|
"8.265824 6.816756," +
|
||||||
|
"8.239206 6.711211," +
|
||||||
|
"8.219743 6.612067," +
|
||||||
|
"8.130227 6.433044," +
|
||||||
|
"8.084435 6.316756," +
|
||||||
|
"8.107109 6.288978," +
|
||||||
|
"7.948394 6.177867," +
|
||||||
|
"7.925720 5.983422," +
|
||||||
|
"7.857699 5.816756," +
|
||||||
|
"7.835026 5.788978," +
|
||||||
|
"7.857699 5.511200," +
|
||||||
|
"7.812352 5.400089," +
|
||||||
|
"7.812352 5.344533," +
|
||||||
|
"7.812352 5.177867," +
|
||||||
|
"8.084435 4.733422," +
|
||||||
|
"8.107109 4.622311," +
|
||||||
|
"7.857699 4.344533," +
|
||||||
|
"7.630963 4.261200," +
|
||||||
|
"7.540268 4.177867," +
|
||||||
|
"7.494921 4.150089," +
|
||||||
|
"7.449574 4.150089," +
|
||||||
|
"7.404227 4.150089," +
|
||||||
|
"7.336206 4.094533," +
|
||||||
|
"7.313532 4.066756," +
|
||||||
|
"7.041449 4.011200," +
|
||||||
|
"6.905407 3.955644," +
|
||||||
|
"6.950754 3.900089," +
|
||||||
|
"7.200164 3.927867," +
|
||||||
|
"7.630963 3.872311," +
|
||||||
|
"7.721657 3.872311," +
|
||||||
|
"7.948394 3.788978," +
|
||||||
|
"7.993741 3.705644," +
|
||||||
|
"7.971067 3.677867," +
|
||||||
|
"7.925720 3.622311," +
|
||||||
|
"8.175130 3.705644," +
|
||||||
|
"8.401866 3.650089," +
|
||||||
|
"8.492561 3.650089," +
|
||||||
|
"8.605929 3.538978," +
|
||||||
|
"8.651276 3.566756," +
|
||||||
|
"8.855339 3.372311," +
|
||||||
|
"8.900686 3.316756," +
|
||||||
|
"8.900686 3.150089," +
|
||||||
|
"8.787318 2.900089," +
|
||||||
|
"8.787318 2.844533," +
|
||||||
|
"8.946033 2.816756," +
|
||||||
|
"8.991380 2.788978," +
|
||||||
|
"9.014054 2.705644," +
|
||||||
|
"8.886928 2.524989," +
|
||||||
|
"8.832665 2.538978," +
|
||||||
|
"8.809991 2.455644," +
|
||||||
|
"8.923360 2.538978," +
|
||||||
|
"9.014054 2.400089," +
|
||||||
|
"9.308811 2.288978," +
|
||||||
|
"9.399506 2.261200," +
|
||||||
|
"9.512874 2.122311," +
|
||||||
|
"9.535548 1.983422," +
|
||||||
|
"9.512874 1.955644," +
|
||||||
|
"9.467527 1.816756," +
|
||||||
|
"9.036728 1.816756," +
|
||||||
|
"8.991380 1.927867," +
|
||||||
|
"8.946033 1.955644," +
|
||||||
|
"8.900686 1.983422," +
|
||||||
|
"8.946033 2.122311," +
|
||||||
|
"8.968707 2.150089," +
|
||||||
|
"9.195443 1.927867," +
|
||||||
|
"9.354158 1.955644," +
|
||||||
|
"9.376832 2.038978," +
|
||||||
|
"9.376832 2.094533," +
|
||||||
|
"9.240790 2.205644," +
|
||||||
|
"9.195443 2.205644," +
|
||||||
|
"9.263464 2.150089," +
|
||||||
|
"9.240790 2.122311," +
|
||||||
|
"9.195443 2.122311," +
|
||||||
|
"9.104749 2.122311," +
|
||||||
|
"8.900686 2.316756," +
|
||||||
|
"8.787318 2.344533," +
|
||||||
|
"8.696623 2.372311," +
|
||||||
|
"8.651276 2.427867," +
|
||||||
|
"8.719297 2.455644," +
|
||||||
|
"8.787318 2.650089," +
|
||||||
|
"8.832665 2.705644," +
|
||||||
|
"8.605929 2.677867," +
|
||||||
|
"8.537908 2.788978," +
|
||||||
|
"8.333845 2.788978," +
|
||||||
|
"7.925720 2.316756," +
|
||||||
|
"7.925720 2.261200," +
|
||||||
|
"7.903046 2.233422," +
|
||||||
|
"7.857699 2.233422," +
|
||||||
|
"7.857699 2.177867," +
|
||||||
|
"7.789678 1.983422," +
|
||||||
|
"7.812352 1.788978," +
|
||||||
|
"7.948394 1.538978," +
|
||||||
|
"7.971067 1.511200," +
|
||||||
|
"8.129783 1.511200," +
|
||||||
|
"8.243151 1.594533," +
|
||||||
|
"8.333845 1.594533," +
|
||||||
|
"8.424540 1.622311," +
|
||||||
|
"8.515234 1.566756," +
|
||||||
|
"8.673950 1.400089," +
|
||||||
|
"8.771174 1.291756," +
|
||||||
|
"8.828938 1.119878," +
|
||||||
|
"8.762504 0.972544," +
|
||||||
|
"9.238614 0.759633," +
|
||||||
|
"9.492323 0.627022," +
|
||||||
|
"9.820891 0.644711," +
|
||||||
|
"10.376567 0.800622," +
|
||||||
|
"10.651961 1.085978," +
|
||||||
|
"10.762173 1.132022," +
|
||||||
|
"10.943045 1.095989," +
|
||||||
|
"11.256739 0.999878," +
|
||||||
|
"11.576074 0.761611," +
|
||||||
|
"11.768247 0.425211," +
|
||||||
|
"11.960165 0.074778," +
|
||||||
|
"11.953907 0.000000," +
|
||||||
|
"11.629411 0.258767," +
|
||||||
|
"11.229920 0.582278," +
|
||||||
|
"11.001633 0.564300," +
|
||||||
|
"10.868476 0.447478," +
|
||||||
|
"10.633849 0.541833," +
|
||||||
|
"10.513370 0.672133," +
|
||||||
|
"11.188700 0.820078," +
|
||||||
|
"11.194014 0.859656," +
|
||||||
|
"11.118212 0.905822," +
|
||||||
|
"10.874860 0.930311," +
|
||||||
|
"10.427319 0.716522," +
|
||||||
|
"10.023620 0.374211," +
|
||||||
|
"9.434614 0.360144," +
|
||||||
|
"8.455131 0.859544," +
|
||||||
|
"8.180481 0.920500," +
|
||||||
|
"7.902529 1.115078," +
|
||||||
|
"7.823108 1.269800," +
|
||||||
|
"7.830482 1.403778," +
|
||||||
|
"7.791937 1.496744," +
|
||||||
|
"7.767005 1.538978," +
|
||||||
|
"7.676310 1.622311," +
|
||||||
|
"7.653637 1.650089," +
|
||||||
|
"7.585616 1.955644," +
|
||||||
|
"7.562942 1.983422," +
|
||||||
|
"7.562942 2.233422," +
|
||||||
|
"7.608289 2.400089," +
|
||||||
|
"7.630963 2.427867," +
|
||||||
|
"7.608289 2.538978," +
|
||||||
|
"7.585616 2.566756," +
|
||||||
|
"7.653637 2.705644," +
|
||||||
|
"7.630963 2.816756," +
|
||||||
|
"7.336206 3.011200," +
|
||||||
|
"7.290859 3.011200," +
|
||||||
|
"7.245511 3.011200," +
|
||||||
|
"7.041449 2.955644," +
|
||||||
|
"6.928081 2.816756," +
|
||||||
|
"6.928081 2.733422," +
|
||||||
|
"6.905407 2.622311," +
|
||||||
|
"6.860060 2.677867," +
|
||||||
|
"6.814712 2.677867," +
|
||||||
|
"6.678671 2.677867," +
|
||||||
|
"6.678671 2.733422," +
|
||||||
|
"6.769365 2.733422," +
|
||||||
|
"6.814712 2.733422," +
|
||||||
|
"6.792039 2.788978," +
|
||||||
|
"6.293219 3.066756," +
|
||||||
|
"6.225198 3.122311," +
|
||||||
|
"6.202525 3.233422," +
|
||||||
|
"6.134504 3.344533," +
|
||||||
|
"5.907767 3.261200," +
|
||||||
|
"5.862420 3.288978," +
|
||||||
|
"6.043809 3.427867," +
|
||||||
|
"6.021136 3.483422," +
|
||||||
|
"5.975788 3.483422," +
|
||||||
|
"5.930441 3.511200," +
|
||||||
|
"5.953115 3.566756," +
|
||||||
|
"5.975788 3.594533," +
|
||||||
|
"5.749052 3.788978," +
|
||||||
|
"5.703705 3.788978," +
|
||||||
|
"5.635684 3.788978," +
|
||||||
|
"5.703705 3.844533," +
|
||||||
|
"5.703705 4.011200," +
|
||||||
|
"5.499642 4.011200," +
|
||||||
|
"5.862420 4.372311," +
|
||||||
|
"5.975788 4.427867," +
|
||||||
|
"6.021136 4.427867," +
|
||||||
|
"6.089156 4.538978," +
|
||||||
|
"6.111830 4.566756," +
|
||||||
|
"6.089156 4.650089," +
|
||||||
|
"5.998462 4.650089," +
|
||||||
|
"5.817073 4.788978," +
|
||||||
|
"5.771726 4.816756," +
|
||||||
|
"5.681031 4.816756," +
|
||||||
|
"5.749052 4.927867," +
|
||||||
|
"5.749052 5.038978," +
|
||||||
|
"5.839747 5.177867," +
|
||||||
|
"5.998462 5.233422," +
|
||||||
|
"6.225198 5.233422," +
|
||||||
|
"6.270545 5.233422," +
|
||||||
|
"6.383914 5.288978," +
|
||||||
|
"6.406587 5.372311," +
|
||||||
|
"6.429261 5.400089," +
|
||||||
|
"6.587976 5.483422," +
|
||||||
|
"6.670626 5.490000," +
|
||||||
|
"6.700845 5.564100," +
|
||||||
|
"6.860060 5.927867," +
|
||||||
|
"6.860060 6.038978," +
|
||||||
|
"6.950754 6.205644," +
|
||||||
|
"6.973428 6.316756," +
|
||||||
|
"7.041449 6.344533," +
|
||||||
|
"7.064122 6.455644," +
|
||||||
|
"7.116072 6.541989," +
|
||||||
|
"7.114313 6.603667," +
|
||||||
|
"7.025305 6.741422," +
|
||||||
|
"6.736924 6.701367," +
|
||||||
|
"6.641658 6.741467," +
|
||||||
|
"6.500574 6.761389," +
|
||||||
|
"6.435410 6.733422," +
|
||||||
|
"6.224291 6.728556," +
|
||||||
|
"6.191759 6.738989," +
|
||||||
|
"6.099124 6.755000," +
|
||||||
|
"6.041805 6.749733," +
|
||||||
|
"6.001672 6.742967," +
|
||||||
|
"5.905382 6.718300," +
|
||||||
|
"5.817073 6.677867," +
|
||||||
|
"5.611713 6.686622," +
|
||||||
|
"5.401366 6.864333," +
|
||||||
|
"5.386274 6.927867," +
|
||||||
|
"5.356608 6.981811," +
|
||||||
|
"5.404095 7.111822," +
|
||||||
|
"5.561958 7.216133," +
|
||||||
|
"5.660643 7.244722," +
|
||||||
|
"5.366149 7.489478," +
|
||||||
|
"5.340927 7.511200," +
|
||||||
|
"5.114998 7.592867," +
|
||||||
|
"4.870667 7.692033," +
|
||||||
|
"4.746560 7.781856," +
|
||||||
|
"4.708060 7.760867," +
|
||||||
|
"4.692225 7.802500," +
|
||||||
|
"4.607090 7.849044," +
|
||||||
|
"4.481324 7.879711," +
|
||||||
|
"4.340031 8.093378," +
|
||||||
|
"4.181171 8.158044," +
|
||||||
|
"4.116415 8.200800," +
|
||||||
|
"4.081135 8.195278," +
|
||||||
|
"4.090912 8.272500," +
|
||||||
|
"4.032232 8.378311," +
|
||||||
|
"3.779566 8.791278," +
|
||||||
|
"3.769654 8.849022," +
|
||||||
|
"3.598177 8.955178," +
|
||||||
|
"3.576828 9.059633," +
|
||||||
|
"3.527037 9.066756," +
|
||||||
|
"3.498069 9.082022," +
|
||||||
|
"3.541865 9.174211," +
|
||||||
|
"3.542409 9.234411," +
|
||||||
|
"3.576275 9.262711," +
|
||||||
|
"3.582279 9.287744," +
|
||||||
|
"3.390995 9.316756," +
|
||||||
|
"3.209606 9.344533," +
|
||||||
|
"3.100836 9.367511," +
|
||||||
|
"2.957466 9.370756," +
|
||||||
|
"2.870844 9.366222," +
|
||||||
|
"2.777211 9.285222," +
|
||||||
|
"2.744851 9.285900," +
|
||||||
|
"2.775397 9.294867," +
|
||||||
|
"2.832661 9.341156," +
|
||||||
|
"2.868114 9.373300," +
|
||||||
|
"2.869502 9.400089," +
|
||||||
|
"2.794434 9.420178," +
|
||||||
|
"2.714423 9.440078," +
|
||||||
|
"2.641124 9.441944," +
|
||||||
|
"2.572096 9.428378," +
|
||||||
|
"2.548379 9.418600," +
|
||||||
|
"2.573130 9.388211," +
|
||||||
|
"2.563126 9.333567," +
|
||||||
|
"2.535855 9.320067," +
|
||||||
|
"2.517670 9.282778," +
|
||||||
|
"2.479488 9.260278," +
|
||||||
|
"2.483125 9.239067," +
|
||||||
|
"2.464034 9.224278," +
|
||||||
|
"2.468586 9.180556," +
|
||||||
|
"2.443129 9.168989," +
|
||||||
|
"2.439084 9.147456," +
|
||||||
|
"2.448389 9.129344," +
|
||||||
|
"2.444897 9.109600," +
|
||||||
|
"2.450720 9.097256," +
|
||||||
|
"2.444897 9.080389," +
|
||||||
|
"2.447808 9.045822," +
|
||||||
|
"2.424536 9.024011," +
|
||||||
|
"2.415811 9.000133," +
|
||||||
|
"2.442457 8.957422," +
|
||||||
|
"2.429887 8.946567," +
|
||||||
|
"2.455028 8.894556," +
|
||||||
|
"2.435936 8.879078," +
|
||||||
|
"2.413136 8.853411," +
|
||||||
|
"2.410805 8.836944," +
|
||||||
|
"2.412202 8.822133," +
|
||||||
|
"2.387533 8.789544," +
|
||||||
|
"2.386608 8.776044," +
|
||||||
|
"2.398706 8.757278," +
|
||||||
|
"2.373103 8.739511," +
|
||||||
|
"2.387070 8.769467," +
|
||||||
|
"2.375434 8.784611," +
|
||||||
|
"2.358674 8.785922," +
|
||||||
|
"2.337270 8.793167," +
|
||||||
|
"2.365195 8.790533," +
|
||||||
|
"2.399169 8.821478," +
|
||||||
|
"2.396376 8.837933," +
|
||||||
|
"2.408946 8.879078," +
|
||||||
|
"2.432218 8.894878," +
|
||||||
|
"2.414995 8.963022," +
|
||||||
|
"2.390961 8.983722," +
|
||||||
|
"2.340091 8.969389," +
|
||||||
|
"2.332091 8.946244," +
|
||||||
|
"2.340091 8.927722," +
|
||||||
|
"2.332091 8.912289," +
|
||||||
|
"2.316093 8.904067," +
|
||||||
|
"2.311730 8.874744," +
|
||||||
|
"2.288975 8.861244," +
|
||||||
|
"2.247727 8.856233," +
|
||||||
|
"2.233180 8.861889," +
|
||||||
|
"2.209436 8.859233," +
|
||||||
|
"2.231003 8.871144," +
|
||||||
|
"2.265911 8.873200," +
|
||||||
|
"2.277548 8.869600," +
|
||||||
|
"2.290635 8.873711," +
|
||||||
|
"2.299360 8.904578," +
|
||||||
|
"2.268088 8.909622," +
|
||||||
|
"2.247727 8.925256," +
|
||||||
|
"2.225734 8.920756," +
|
||||||
|
"2.208747 8.909622," +
|
||||||
|
"2.203768 8.921811," +
|
||||||
|
"2.214352 8.931822," +
|
||||||
|
"2.197138 8.933811," +
|
||||||
|
"2.148725 8.907478," +
|
||||||
|
"2.134577 8.904844," +
|
||||||
|
"2.113354 8.917222," +
|
||||||
|
"2.095107 8.918800," +
|
||||||
|
"2.079961 8.912944," +
|
||||||
|
"2.060761 8.913356," +
|
||||||
|
"2.034577 8.902656," +
|
||||||
|
"1.983589 8.895400," +
|
||||||
|
"2.033997 8.913356," +
|
||||||
|
"2.062502 8.918700," +
|
||||||
|
"2.092758 8.929811," +
|
||||||
|
"2.148090 8.928756," +
|
||||||
|
"2.168397 8.937878," +
|
||||||
|
"2.146421 8.965533," +
|
||||||
|
"2.182173 8.943933," +
|
||||||
|
"2.201537 8.951311," +
|
||||||
|
"2.239138 8.938400," +
|
||||||
|
"2.267063 8.944989," +
|
||||||
|
"2.284939 8.925767," +
|
||||||
|
"2.306887 8.926022," +
|
||||||
|
"2.311086 8.936356," +
|
||||||
|
"2.296312 8.952489," +
|
||||||
|
"2.317254 8.981122," +
|
||||||
|
"2.334939 9.003844," +
|
||||||
|
"2.374500 9.014044," +
|
||||||
|
"2.386136 9.034778," +
|
||||||
|
"2.401962 9.044656," +
|
||||||
|
"2.418723 9.044889," +
|
||||||
|
"2.426287 9.054878," +
|
||||||
|
"2.411739 9.063522," +
|
||||||
|
"2.426867 9.099311," +
|
||||||
|
"2.398362 9.125233," +
|
||||||
|
"2.373339 9.121944," +
|
||||||
|
"2.403595 9.134289," +
|
||||||
|
"2.417680 9.165778," +
|
||||||
|
"2.425860 9.192778," +
|
||||||
|
"2.423783 9.231400," +
|
||||||
|
"2.400330 9.237022," +
|
||||||
|
"2.419494 9.243567," +
|
||||||
|
"2.429815 9.246711," +
|
||||||
|
"2.449495 9.245489," +
|
||||||
|
"2.457676 9.289856," +
|
||||||
|
"2.481311 9.298211," +
|
||||||
|
"2.488585 9.334211," +
|
||||||
|
"2.520255 9.353822," +
|
||||||
|
"2.520400 9.369944," +
|
||||||
|
"2.494960 9.432511," +
|
||||||
|
"2.463671 9.469200," +
|
||||||
|
"2.406950 9.500578," +
|
||||||
|
"2.240907 9.536433," +
|
||||||
|
"2.129969 9.569467," +
|
||||||
|
"2.031530 9.607422," +
|
||||||
|
"1.932328 9.658044," +
|
||||||
|
"1.835167 9.695656," +
|
||||||
|
"1.746196 9.760744," +
|
||||||
|
"1.667446 9.789667," +
|
||||||
|
"1.575400 9.797622," +
|
||||||
|
"1.562104 9.828722," +
|
||||||
|
"1.531422 9.846800," +
|
||||||
|
"1.415859 9.888744," +
|
||||||
|
"1.315206 9.942167," +
|
||||||
|
"1.175573 10.083667," +
|
||||||
|
"1.147394 10.090267," +
|
||||||
|
"1.118064 10.086567," +
|
||||||
|
"0.990883 9.998400," +
|
||||||
|
"0.778930 9.990856," +
|
||||||
|
"0.592924 10.033144," +
|
||||||
|
"0.507490 10.125422," +
|
||||||
|
"0.419562 10.320811," +
|
||||||
|
"0.375403 10.344533," +
|
||||||
|
"0.276464 10.431189," +
|
||||||
|
"0.220170 10.534911," +
|
||||||
|
"0.181271 10.571000," +
|
||||||
|
"0.153745 10.620156," +
|
||||||
|
"0.114973 10.653889," +
|
||||||
|
"0.103274 10.707756," +
|
||||||
|
"0.097914 10.761511," +
|
||||||
|
"0.076256 10.811522," +
|
||||||
|
"0.061935 10.867833," +
|
||||||
|
"0.000000 10.960167)"
|
||||||
|
);
|
||||||
|
vectorlayer.addFeatures([new OpenLayers.Feature.Vector(original)]);
|
||||||
|
var maxExtent = vectorlayer.getDataExtent();
|
||||||
|
// instanciate the map
|
||||||
|
map = new OpenLayers.Map("map", {
|
||||||
|
fractionalZoom: true,
|
||||||
|
maxExtent: maxExtent,
|
||||||
|
layers: [vectorlayer]
|
||||||
|
});
|
||||||
|
map.zoomToMaxExtent();
|
||||||
|
map.events.register('moveend', map, function(){
|
||||||
|
map2.setCenter(map.getCenter(), map.getZoom());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var vectorlayer2 = new OpenLayers.Layer.Vector('Vectorlayer simplified', {
|
||||||
|
isBaseLayer: true,
|
||||||
|
styleMap: styleMap
|
||||||
|
});
|
||||||
|
|
||||||
|
map2 = new OpenLayers.Map("map-simplify", {
|
||||||
|
fractionalZoom: true,
|
||||||
|
maxExtent: maxExtent,
|
||||||
|
controls: [],
|
||||||
|
layers: [vectorlayer2]
|
||||||
|
});
|
||||||
|
map2.zoomToExtent(maxExtent);
|
||||||
|
|
||||||
|
// Control behaviour
|
||||||
|
var lastValue = 0.1;
|
||||||
|
var simplify = function() {
|
||||||
|
var min = 0;
|
||||||
|
var max = 1;
|
||||||
|
var givenVal= parseFloat(document.getElementById('tolerance').value);
|
||||||
|
var useVal = lastValue;
|
||||||
|
if (!isNaN(givenVal)) {
|
||||||
|
if (givenVal >= min && givenVal <= max) {
|
||||||
|
useVal = givenVal;
|
||||||
|
} else {
|
||||||
|
useVal = (givenVal < min) ? min : max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById('tolerance').value = useVal;
|
||||||
|
vectorlayer2.removeFeatures(vectorlayer2.features);
|
||||||
|
var newLineString = original.simplify(useVal);
|
||||||
|
vectorlayer2.addFeatures([new OpenLayers.Feature.Vector(newLineString)]);
|
||||||
|
var originalVerticesCnt = original.getVertices().length;
|
||||||
|
var simplifiedVerticesCnt = newLineString.getVertices().length;
|
||||||
|
var infotxt = '<ul><li>Original LineString: <strong>';
|
||||||
|
infotxt += originalVerticesCnt + ' vertices</strong></li>';
|
||||||
|
infotxt += ' <li>Simplified geometry: <strong>' + simplifiedVerticesCnt + ' vertices</strong></li>';
|
||||||
|
infotxt += ' <li>Decreased by <strong>' + (((originalVerticesCnt-simplifiedVerticesCnt)/originalVerticesCnt)*100).toFixed(2) + ' per cent</strong></li></ul>';
|
||||||
|
document.getElementById('info').innerHTML = infotxt;
|
||||||
|
lastValue = useVal;
|
||||||
|
};
|
||||||
|
document.getElementById('tolerance').value = lastValue;
|
||||||
|
document.getElementById('simplify').onclick = simplify;
|
||||||
|
simplify();
|
||||||
|
|
||||||
|
var animationInterval;
|
||||||
|
var animationHandler = function(){
|
||||||
|
if (this.value === 'Start animation') {
|
||||||
|
document.getElementById('simplify').disabled = true;
|
||||||
|
document.getElementById('animation').value = "Stop animation";
|
||||||
|
animationInterval = window.setInterval(function(){
|
||||||
|
var tolerance = parseFloat(document.getElementById('tolerance').value);
|
||||||
|
if (tolerance < 1) {
|
||||||
|
tolerance+=0.02;
|
||||||
|
} else {
|
||||||
|
tolerance = 0.02;
|
||||||
|
}
|
||||||
|
document.getElementById('tolerance').value = tolerance.toFixed(2);
|
||||||
|
simplify();
|
||||||
|
}, 500);
|
||||||
|
simplify();
|
||||||
|
} else {
|
||||||
|
if (animationInterval) {
|
||||||
|
window.clearInterval(animationInterval);
|
||||||
|
}
|
||||||
|
document.getElementById('simplify').disabled = false;
|
||||||
|
document.getElementById('animation').value = "Start animation";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.getElementById('animation').onclick = animationHandler;
|
||||||
|
})();
|
||||||
@@ -547,6 +547,98 @@ OpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {
|
|||||||
}
|
}
|
||||||
return best;
|
return best;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIMethod: simplify
|
||||||
|
* This function will return a simplified LineString.
|
||||||
|
* Simplification is based on the Douglas-Peucker algorithm.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* tolerance - {number} threshhold for simplification in map units
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {OpenLayers.Geometry.LineString} the simplified LineString
|
||||||
|
*/
|
||||||
|
simplify: function(tolerance){
|
||||||
|
if (this && this !== null) {
|
||||||
|
var points = this.getVertices();
|
||||||
|
if (points.length < 3) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compareNumbers = function(a, b){
|
||||||
|
return (a-b);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private function doing the Douglas-Peucker reduction
|
||||||
|
*/
|
||||||
|
var douglasPeuckerReduction = function(points, firstPoint, lastPoint, tolerance){
|
||||||
|
var maxDistance = 0;
|
||||||
|
var indexFarthest = 0;
|
||||||
|
|
||||||
|
for (var index = firstPoint; index < lastPoint; index++) {
|
||||||
|
distance = perpendicularDistance(points[firstPoint], points[lastPoint], points[index]);
|
||||||
|
if (distance > maxDistance) {
|
||||||
|
maxDistance = distance;
|
||||||
|
indexFarthest = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDistance > tolerance && indexFarthest != firstPoint) {
|
||||||
|
//Add the largest point that exceeds the tolerance
|
||||||
|
pointIndexsToKeep.push(indexFarthest);
|
||||||
|
douglasPeuckerReduction(points, firstPoint, indexFarthest, tolerance);
|
||||||
|
douglasPeuckerReduction(points, indexFarthest, lastPoint, tolerance);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private function calculating the perpendicular distance
|
||||||
|
* TODO: check whether OpenLayers.Geometry.LineString::distanceTo() is faster or slower
|
||||||
|
*/
|
||||||
|
var perpendicularDistance = function(point1, point2, point){
|
||||||
|
//Area = |(1/2)(x1y2 + x2y3 + x3y1 - x2y1 - x3y2 - x1y3)| *Area of triangle
|
||||||
|
//Base = v((x1-x2)²+(x1-x2)²) *Base of Triangle*
|
||||||
|
//Area = .5*Base*H *Solve for height
|
||||||
|
//Height = Area/.5/Base
|
||||||
|
|
||||||
|
var area = Math.abs(0.5 * (point1.x * point2.y + point2.x * point.y + point.x * point1.y - point2.x * point1.y - point.x * point2.y - point1.x * point.y));
|
||||||
|
var bottom = Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));
|
||||||
|
var height = area / bottom * 2;
|
||||||
|
|
||||||
|
return height;
|
||||||
|
};
|
||||||
|
|
||||||
|
var firstPoint = 0;
|
||||||
|
var lastPoint = points.length - 1;
|
||||||
|
var pointIndexsToKeep = [];
|
||||||
|
|
||||||
|
//Add the first and last index to the keepers
|
||||||
|
pointIndexsToKeep.push(firstPoint);
|
||||||
|
pointIndexsToKeep.push(lastPoint);
|
||||||
|
|
||||||
|
//The first and the last point cannot be the same
|
||||||
|
while (points[firstPoint].equals(points[lastPoint])) {
|
||||||
|
lastPoint--;
|
||||||
|
//Addition: the first point not equal to first point in the LineString is kept as well
|
||||||
|
pointIndexsToKeep.push(lastPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
douglasPeuckerReduction(points, firstPoint, lastPoint, tolerance);
|
||||||
|
var returnPoints = [];
|
||||||
|
pointIndexsToKeep.sort(compareNumbers);
|
||||||
|
for (var index = 0; index < pointIndexsToKeep.length; index++) {
|
||||||
|
returnPoints.push(points[pointIndexsToKeep[index]]);
|
||||||
|
}
|
||||||
|
return new OpenLayers.Geometry.LineString(returnPoints);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
CLASS_NAME: "OpenLayers.Geometry.LineString"
|
CLASS_NAME: "OpenLayers.Geometry.LineString"
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -374,7 +374,67 @@
|
|||||||
t.eq(Math.round(got), Math.round(cases[i].exp), "[case " + i + "] length calculated");
|
t.eq(Math.round(got), Math.round(cases[i].exp), "[case " + i + "] length calculated");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_LineString_simplify(t){
|
||||||
|
t.plan(8);
|
||||||
|
var ls1 = new OpenLayers.Geometry.LineString([
|
||||||
|
new OpenLayers.Geometry.Point(0,0),
|
||||||
|
new OpenLayers.Geometry.Point(1,2.1),
|
||||||
|
new OpenLayers.Geometry.Point(1.8,3.8),
|
||||||
|
new OpenLayers.Geometry.Point(2,4),
|
||||||
|
new OpenLayers.Geometry.Point(3,4),
|
||||||
|
new OpenLayers.Geometry.Point(4,4.5),
|
||||||
|
new OpenLayers.Geometry.Point(5,5)
|
||||||
|
|
||||||
|
]);
|
||||||
|
var ls2 = new OpenLayers.Geometry.LineString([
|
||||||
|
new OpenLayers.Geometry.Point(0,0),
|
||||||
|
new OpenLayers.Geometry.Point(1,2.1),
|
||||||
|
new OpenLayers.Geometry.Point(1.8,3.8),
|
||||||
|
new OpenLayers.Geometry.Point(2,4),
|
||||||
|
new OpenLayers.Geometry.Point(3,4),
|
||||||
|
new OpenLayers.Geometry.Point(4,4.5),
|
||||||
|
new OpenLayers.Geometry.Point(5,5),
|
||||||
|
new OpenLayers.Geometry.Point(0,0)
|
||||||
|
|
||||||
|
]);
|
||||||
|
var ls3 = new OpenLayers.Geometry.LineString([
|
||||||
|
new OpenLayers.Geometry.Point(0,0),
|
||||||
|
new OpenLayers.Geometry.Point(1,1)
|
||||||
|
]);
|
||||||
|
var ls5 = new OpenLayers.Geometry.LineString([
|
||||||
|
new OpenLayers.Geometry.Point(0,0),
|
||||||
|
new OpenLayers.Geometry.Point(1,1),
|
||||||
|
new OpenLayers.Geometry.Point(2,2),
|
||||||
|
new OpenLayers.Geometry.Point(3,3),
|
||||||
|
new OpenLayers.Geometry.Point(4,4),
|
||||||
|
new OpenLayers.Geometry.Point(5,5)
|
||||||
|
|
||||||
|
]);
|
||||||
|
var ls6 = new OpenLayers.Geometry.LineString([
|
||||||
|
new OpenLayers.Geometry.Point(0,0),
|
||||||
|
new OpenLayers.Geometry.Point(1,1),
|
||||||
|
new OpenLayers.Geometry.Point(1,1),
|
||||||
|
new OpenLayers.Geometry.Point(3,2)
|
||||||
|
]);
|
||||||
|
|
||||||
|
t.ok(ls1 instanceof OpenLayers.Geometry.LineString, 'LineString is instance of OpenLayers.Geometry.LineString');
|
||||||
|
var simplified1 = ls1.simplify(0.5);
|
||||||
|
t.ok(simplified1 instanceof OpenLayers.Geometry.LineString, 'Simplified LineString is instance of OpenLayers.Geometry.LineString');
|
||||||
|
t.ok(simplified1.getVertices().length <= ls1.getVertices().length, 'Simplified LineString has less or equal number of vertices');
|
||||||
|
// The simplified version is derived from PostGIS function ST_SIMPLIFY()
|
||||||
|
t.ok(simplified1.toString() === 'LINESTRING(0 0,1.8 3.8,5 5)', 'LineString 1 was simplified correctly');
|
||||||
|
var simplified2 = ls2.simplify(0.5);
|
||||||
|
// The simplified version is derived from PostGIS function ST_SIMPLIFY()
|
||||||
|
t.ok(simplified2.toString() === 'LINESTRING(0 0,1.8 3.8,5 5,0 0)', 'LineString 2 was simplified correctly');
|
||||||
|
var simplified3 = ls3.simplify(0.5);
|
||||||
|
t.ok(simplified3.toString() === ls3.toString(), 'LineString with 2 vertices is left untouched');
|
||||||
|
var simplified5 = ls5.simplify(0.0);
|
||||||
|
t.ok(simplified5.toString() === 'LINESTRING(0 0,5 5)', 'A tolerance of 0 returns the optimized version needless vertices');
|
||||||
|
var simplified6 = ls6.simplify(0.0);
|
||||||
|
t.ok(simplified6.toString() === 'LINESTRING(0 0,1 1,3 2)', 'A tolerance of 0 returns the optimized version without doubled vertices');
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
Reference in New Issue
Block a user