[RFC] moving to ES6 classes / ol7

This commit is contained in:
viglino 2022-09-09 15:48:07 +02:00
parent cb915d7f7d
commit b4f553abc3
30 changed files with 2559 additions and 2543 deletions

View File

@ -4,34 +4,36 @@
* - source: the window source (undefined if first window)
*/
if (!window.WSynchro) {
var WSynchro = { windows: [] };
var WSynchro = { windows: [] };
alert ('noSynch')
}
/** Open a new window to synchronize
* @param {url|undefined} url to open, default current window url
* @param {specs|undefined|null} specs (as for window.open), undefined to open in a new window, null to open in a new tab, default new window
*/
WSynchro.open = function (href, specs)
{ var w = window.open (href || window.location.href, "_blank", typeof(specs)=="undefined"? "location=1,menubar=1,toolbar=1,scrollbars=1" : specs);
if (!w.WSynchro) w.WSynchro = { windows: [ window ], source:window };
else
{ w.WSynchro.windows = [ window ];
w.WSynchro.source = window;
}
this.windows.push(w);
WSynchro.open = function (href, specs) {
var w = window.open (href || window.location.href, "_blank", typeof(specs)=="undefined"? "location=1,menubar=1,toolbar=1,scrollbars=1" : specs);
if (!w.WSynchro) {
w.WSynchro = { windows: [ window ], source:window };
} else {
w.WSynchro.windows = [ window ];
w.WSynchro.source = window;
}
this.windows.push(w);
}
/** Trigger function
* @param {synchronize}
* @param {function} synchronize function
*/
WSynchro.on = function (e, syncFn)
{ if (!this.syncFn_) this.syncFn_ = [];
if (e==='synchronize') this.syncFn_.push(syncFn);
WSynchro.on = function (e, syncFn) {
if (!this.syncFn_) this.syncFn_ = [];
if (e==='synchronize') this.syncFn_.push(syncFn);
}
/** Synchronize windows
* @param {Object|undefined} if undefined stop synchro (when the window is synchronize)
*/
WSynchro.synchronize = function(params)
{ this.synchronize_ (params);
WSynchro.synchronize = function(params) {
this.synchronize_ (params);
}
/** Synchronize windows:
* @param {Array} array of arguments to use with fn
@ -39,30 +41,31 @@ WSynchro.synchronize = function(params)
* @private
*/
WSynchro.synchronize_ = function(args, sync) {
var i;
// Stop condition
if (!sync)
{ if (this.synchronizing) sync = this.sync;
else this.sync = sync = (new Date()).getTime();
this.synchronizing = false;
}
else
{ // Don't synchronize twice
if (sync == this.sync) return;
this.sync = sync;
this.synchronizing = true;
try
{ if (WSynchro.syncFn_)
{ args.type = "synchronize";
for (i=0; i<WSynchro.syncFn_.length; i++)
{ WSynchro.syncFn_[i].apply (null, [args]);
}
}
} catch(e) { /* */ }
}
if (args) for (i=0; i<this.windows.length; i++)
{ try
{ this.windows[i].WSynchro.synchronize_(args, sync);
} catch(e) { /* */ }
}
var i;
// Stop condition
if (!sync) {
if (this.synchronizing) sync = this.sync;
else this.sync = sync = (new Date()).getTime();
this.synchronizing = false;
} else {
// Don't synchronize twice
if (sync == this.sync) return;
this.sync = sync;
this.synchronizing = true;
try {
if (WSynchro.syncFn_) {
args.type = "synchronize";
for (i=0; i<WSynchro.syncFn_.length; i++) {
WSynchro.syncFn_[i].apply (null, [args]);
}
}
} catch(e) { /* */ }
}
if (args) {
for (i=0; i<this.windows.length; i++){
try {
this.windows[i].WSynchro.synchronize_(args, sync);
} catch(e) { /* */ }
}
}
}

2151
dist/ol-ext.js vendored

File diff suppressed because it is too large Load Diff

2
dist/ol-ext.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -67,7 +67,7 @@ button i {
transform: translateX(-50%);
margin: 0;
border-radius: 0 0 2em 2em;
background: #1f6b75;
background: #333;
color: #fff;
padding: .2em 1.5em;
}

View File

@ -21,8 +21,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -1,82 +1,82 @@
<!DOCTYPE html>
<html>
<!--
Copyright (c) 2018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
Copyright (c) 2018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
<head>
<title>ol-ext: Clustering map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="A cluster layer for OpenLayers (ol) that animates clusters on zoom change." />
<meta name="keywords" content="ol3,cluster,charts,animation,layer,selectio,animate,animated clusters,openlayers" />
<title>ol-ext: Clustering map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="A cluster layer for OpenLayers (ol) that animates clusters on zoom change." />
<meta name="keywords" content="ol3,cluster,charts,animation,layer,selectio,animate,animated clusters,openlayers" />
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
<!-- ol-ext -->
<link rel="stylesheet" href="../../dist/ol-ext.css" />
<script type="text/javascript" src="../../dist/ol-ext.js"></script>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://unpkg.com/elm-pep"></script>
<!-- ol-ext maki and fontawesome defintions used in fontsymbol -->
<link rel="stylesheet" href="../css/fontmaki.css" />
<script type="text/javascript" src="../../dist/extra/FontMakiDef.js"></script>
<!-- ol-ext maki and fontawesome defintions used in fontsymbol -->
<link rel="stylesheet" href="../css/fontmaki.css" />
<script type="text/javascript" src="../../dist/extra/FontMakiDef.js"></script>
<link rel="stylesheet" href="../style.css" />
<style>
.infos > i {
float: left;
font-size: 3em;
margin: -.2em 0 -.2em -.2em;
}
[class^="maki-"]:before, [class*=" maki-"]:before {
width: initial;
}
</style>
<link rel="stylesheet" href="../style.css" />
<style>
.infos > i {
float: left;
font-size: 3em;
margin: -.2em 0 -.2em -.2em;
}
[class^="maki-"]:before, [class*=" maki-"]:before {
width: initial;
}
</style>
</head>
<body >
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>
<a href="../../index.html">
<h1>ol-ext: Clustering map</h1>
</a>
<p class="info">
This example show the use of the <i>ol.style.Chart</i> to display the cluster content.
</p>
<a href="../../index.html">
<h1>ol-ext: Clustering map</h1>
</a>
<p class="info">
This example show the use of the <i>ol.style.Chart</i> to display the cluster content.
</p>
<!-- DIV pour la carte -->
<div id="map" style="width:600px; height:400px;"></div>
<!-- DIV pour la carte -->
<div id="map" style="width:600px; height:400px;"></div>
<div class="options">
<h2>
Cluster options:
</h2>
<input id="animatecluster" type="checkbox" checked="checked" onchange="clusterLayer.set('animationDuration',(this.checked ? 700:0));" />
<label for="animatecluster">animate cluster</label>
<br />
Number of features:
<br/>
<input type="number" value="2000" onchange="addFeatures(this.value);" />
<h2>Select options:</h2>
<input id="animatesel" type="checkbox" checked="checked" onchange="selectCluster.animate = this.checked" />
<label for="animatesel">animate selection</label>
</div>
<div class="infos">
<!-- preload icon -->
<i class="fa maki-bus" title="building"></i>
<i class="fa maki-town_hall" title="building"></i>
<i class="fa maki-theatre" title="building"></i>
<i class="fa maki-industrial" title="building"></i>
</div>
<div class="options">
<h2>
Cluster options:
</h2>
<input id="animatecluster" type="checkbox" checked="checked" onchange="clusterLayer.set('animationDuration',(this.checked ? 700:0));" />
<label for="animatecluster">animate cluster</label>
<br />
Number of features:
<br/>
<input type="number" value="2000" onchange="addFeatures(this.value);" />
<h2>Select options:</h2>
<input id="animatesel" type="checkbox" checked="checked" onchange="selectCluster.animate = this.checked" />
<label for="animatesel">animate selection</label>
</div>
<div class="infos">
<!-- preload icon -->
<i class="fa maki-bus" title="building"></i>
<i class="fa maki-town_hall" title="building"></i>
<i class="fa maki-theatre" title="building"></i>
<i class="fa maki-industrial" title="building"></i>
</div>
<script type="text/javascript">
<script type="text/javascript">
// Layers
var layers = [ new ol.layer.Tile({
source: new ol.source.OSM()
@ -237,7 +237,7 @@
}
testFontLoaded ();
</script>
</script>
</body>
</html>

View File

@ -140,8 +140,8 @@
// Force thumbnail to non optional
vectorSource.querySubject = function () {
return "?subject rdfs:label ?label. "
+ "?subject dbpedia-owl:thumbnail ?thumbnail."
+ "OPTIONAL {?subject dbpedia-owl:abstract ?abstract} . "
+ "?subject dbo:thumbnail ?thumbnail."
+ "OPTIONAL {?subject dbo:abstract ?abstract} . "
+ "OPTIONAL {?subject rdf:type ?type}";
}

View File

@ -15,8 +15,8 @@
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
@ -85,7 +85,6 @@
zoom: 13,
center: [260841, 6250141]
}),
interactions: ol.interaction.defaults(),
layers: [ new ol.layer.Tile({ name:"OSM", source: new ol.source.OSM() })]
});

View File

@ -15,8 +15,8 @@
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
@ -88,7 +88,6 @@
zoom: 19,
center: [-245406, 5986536]// [-245575, 5986863], //[-244777, 5989809]
}),
interactions: ol.interaction.defaults(),
layers: [ layer ]
});

View File

@ -1,213 +1,213 @@
<!DOCTYPE html>
<html>
<head>
<!----------------------------------------------------------
Copyright (c) 2015-018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
------------------------------------------------------------>
<title>ol-ext: Pirates</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--
Copyright (c) 2015-018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
<title>ol-ext: Pirates</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="Add an old map effect on a canvas renderer with a parchment texture and compass." />
<meta name="keywords" content="ol3, control, canvas, pirate, compass, effect" />
<meta name="description" content="Add an old map effect on a canvas renderer with a parchment texture and compass." />
<meta name="keywords" content="ol3, control, canvas, pirate, compass, effect" />
<link rel="stylesheet" href="../style.css" />
<link rel="stylesheet" href="../style.css" />
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
<link rel="stylesheet" href="../../dist/ol-ext.css" />
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
<link rel="stylesheet" href="../../dist/ol-ext.css" />
<script type="text/javascript" src="../../dist/ol-ext.js"></script>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://unpkg.com/elm-pep"></script>
<style>
#map
{ position: fixed;
top:5em;
left: 0;
right: 0;
bottom: 0;
width:100%;
background:transparent;
}
.options
{ position:fixed;
top:6em;
right:1em;
margin:0;
width:200px;
z-index:10;
}
.options input[type="number"]
{ width: 5em;
}
<style>
#map {
position: fixed;
top:5em;
left: 0;
right: 0;
bottom: 0;
width:100%;
background:transparent;
}
.options {
position:fixed;
top:6em;
right:1em;
margin:0;
width:200px;
z-index:10;
}
.options input[type="number"] {
width: 5em;
}
.ol-compassctrl
{ top: 50%;
left: 5%;
width: 100px;
height: 100px;
-webkit-transform: translate(0,-50%);
transform: translate(0,-50%);
}
.ol-compassctrl.right
{ top: auto;
left: auto;
bottom: 5%;
right: 5%;
width: 150px;
height: 150px;
-webkit-transform: none;
transform: none;
}
.ol-compassctrl {
top: 50%;
left: 5%;
width: 100px;
height: 100px;
-webkit-transform: translate(0,-50%);
transform: translate(0,-50%);
}
.ol-compassctrl.right {
top: auto;
left: auto;
bottom: 5%;
right: 5%;
width: 150px;
height: 150px;
-webkit-transform: none;
transform: none;
}
</style>
</style>
</head>
<body >
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>
<a href="../../index.html">
<h1>ol-ext: Pirates!</h1>
</a>
<a href="../../index.html">
<h1>ol-ext: Pirates!</h1>
</a>
<!-- Map div -->
<div id="map" ></div>
<!-- Map div -->
<div id="map" ></div>
<div class="options">
This example show how to combine a <a href="../filter/map.filter.colorize.html">color filter</a>,
with a <a href="../filter/map.filter.texture.html">parchment texture filter</a>,
a <a href="../canvas/map.control.compass.html">compass control</a>
and a <a href="../canvas/map.control.graticule.html">graticule control</a>
to create an old map effect.
<h2>Options</h2>
<ul>
<li>
Hue:
<select onchange="color.setColor(this.value);">
<option value="#963">default</option>
<option value="#369">blue</option>
<option value="#936">red</option>
<option value="#396">green</option>
</select>
</li>
<li>
Saturation:
<input id="sat" type="number" value="0.6" onchange="color.setValue(this.value)" max="1" min="0" step="0.1" />
</li>
<li>
Opacity:
<input id="opacity" type="number" value="0.7" onchange="tex.setFilter({opacity:Number(this.value)})" max="1" min="0" step="0.1" />
</li>
<li>
<input id="rot" type="checkbox" onchange="tex.set('rotateWithView',$(this).prop('checked'));" /><label for="rot"> rotateWithView</label>
<small><i>May cause animation lags on mobile or slow devices</i></small>
</li>
</ul>
</div>
<div class="options">
This example show how to combine a <a href="../filter/map.filter.colorize.html">color filter</a>,
with a <a href="../filter/map.filter.texture.html">parchment texture filter</a>,
a <a href="../canvas/map.control.compass.html">compass control</a>
and a <a href="../canvas/map.control.graticule.html">graticule control</a>
to create an old map effect.
<h2>Options</h2>
<ul>
<li>
Hue:
<select onchange="color.setColor(this.value);">
<option value="#963">default</option>
<option value="#369">blue</option>
<option value="#936">red</option>
<option value="#396">green</option>
</select>
</li>
<li>
Saturation:
<input id="sat" type="number" value="0.6" onchange="color.setValue(this.value)" max="1" min="0" step="0.1" />
</li>
<li>
Opacity:
<input id="opacity" type="number" value="0.7" onchange="tex.setFilter({opacity:Number(this.value)})" max="1" min="0" step="0.1" />
</li>
<li>
<input id="rot" type="checkbox" onchange="tex.set('rotateWithView',$(this).prop('checked'));" /><label for="rot"> rotateWithView</label>
<small><i>May cause animation lags on mobile or slow devices</i></small>
</li>
</ul>
</div>
<script type="text/javascript">
if (/MSIE|Trident/.test(navigator.userAgent))
{ alert ("Oops, it seems you use IE!\nsome feature may not work correctly, try to use another navigator!")
$('#sat').val(0.2);
$('#opacity').val(0.3);
}
<script type="text/javascript">
if (/MSIE|Trident/.test(navigator.userAgent)){
alert ("Oops, it seems you use IE!\nsome feature may not work correctly, try to use another navigator!")
$('#sat').val(0.2);
$('#opacity').val(0.3);
}
var osm = new ol.layer.Tile({ source: new ol.source.OSM()});
// The map
var map = new ol.Map
({ target: 'map',
view: new ol.View
({ zoom: 14,
center: [-302537, 6001071]
}),
layers: [osm]
});
map.getView().fit ([-375917, 5976764, -229158, 6025378], map.getSize());
var osm = new ol.layer.Tile({ source: new ol.source.OSM()});
// The map
var map = new ol.Map ({
target: 'map',
view: new ol.View ({
zoom: 14,
center: [-302537, 6001071]
}),
layers: [osm]
});
map.getView().fit ([-375917, 5976764, -229158, 6025378], map.getSize());
// Color filter
var color = new ol.filter.Colorize(
{ operation: 'color',
color: "rgba(153,102,51,"+$("#sat").val()+")",
/*
red: 153,
green: 102,
blue: 51,
*/
value: Number($("#sat").val())
});
osm.addFilter(color);
// Color filter
var color = new ol.filter.Colorize({
operation: 'color',
color: "rgba(153,102,51,"+$("#sat").val()+")",
/*
red: 153,
green: 102,
blue: 51,
*/
value: Number($("#sat").val())
});
osm.addFilter(color);
// Texture filter
var tex = new ol.filter.Texture(
{ src: "../data/oldmap.jpg",
opacity: Number($("#opacity").val()),
rotateWithView: $("#rot").prop('checked'),
scale: 3
});
osm.addFilter(tex);
// Texture filter
var tex = new ol.filter.Texture({
src: "../data/oldmap.jpg",
opacity: Number($("#opacity").val()),
rotateWithView: $("#rot").prop('checked'),
scale: 3
});
osm.addFilter(tex);
// Compass
map.addControl(new ol.control.Compass(
{ src: "../data/piratecontrol.png",
style: new ol.style.Stroke ({ color: "#963", width: 1 })
}));
map.addControl(new ol.control.Compass(
{ className: 'right',
src: "../data/piratecontrol.png",
style: new ol.style.Stroke ({ color: "#963", width: 1 })
}));
// Graticule
map.addControl(new ol.control.Graticule(
{ step: 0.2,
stepCoord: 2,
projection: 'EPSG:4326',
//step: 1000, stepCoord: 5, projection: 'EPSG:2154',
margin:35,
stroke: true,
style: new ol.style.Style(
{ stroke: new ol.style.Stroke({ color:"rgba(102, 51, 0, 0.8)", width:1 }),
fill: new ol.style.Fill({ color: "rgba(255,255,255,0.3)" }),
text: new ol.style.Text(
{ stroke: new ol.style.Stroke({ color: "rgba(255,255,255,0.5)", width: 2 }),
fill: new ol.style.Fill({ color: "rgba(102, 51, 0, 1)" }),
})
}),
formatCoord:function(c){ return c.toFixed(1)+"°"
}
}));
map.addControl(new ol.control.Graticule(
{ step: 5000,
projection: 'EPSG:3857',
margin: 30,
stroke: false,
style: new ol.style.Style(
{ stroke: new ol.style.Stroke({ color: "rgba(102, 51, 0, 0.8)", width: 1 }),
fill: new ol.style.Fill({ color: "rgba(255,255,255,0.3)" }),
})
}));
// Compass
map.addControl(new ol.control.Compass({
src: "../data/piratecontrol.png",
style: new ol.style.Stroke ({ color: "#963", width: 1 })
}));
map.addControl(new ol.control.Compass({
className: 'right',
src: "../data/piratecontrol.png",
style: new ol.style.Stroke ({ color: "#963", width: 1 })
}));
// Graticule
map.addControl(new ol.control.Graticule({
step: 0.2,
stepCoord: 2,
projection: 'EPSG:4326',
//step: 1000, stepCoord: 5, projection: 'EPSG:2154',
margin:35,
stroke: true,
style: new ol.style.Style({
stroke: new ol.style.Stroke({ color:"rgba(102, 51, 0, 0.8)", width:1 }),
fill: new ol.style.Fill({ color: "rgba(255,255,255,0.3)" }),
text: new ol.style.Text({
stroke: new ol.style.Stroke({ color: "rgba(255,255,255,0.5)", width: 2 }),
fill: new ol.style.Fill({ color: "rgba(102, 51, 0, 1)" }),
})
}),
formatCoord: function(c) {
return c.toFixed(1)+"°"
}
})
);
map.addControl(new ol.control.Graticule({
step: 5000,
projection: 'EPSG:3857',
margin: 30,
stroke: false,
style: new ol.style.Style({
stroke: new ol.style.Stroke({ color: "rgba(102, 51, 0, 0.8)", width: 1 }),
fill: new ol.style.Fill({ color: "rgba(255,255,255,0.3)" }),
})
}));
// Clip
var clip = new ol.filter.Clip(
{ operation:'enhance',
coords: [[0.023, 0.957], [0, 0.463], [0.007, 0.42], [0.004, 0.397], [0.029, 0.383], [0.013, 0.383], [0.046, 0.367], [0.011, 0.371], [0.004, 0.349], [0.006, 0.297], [0.012, 0.265], [0.007, 0.246], [0.016, 0.191], [0.031, 0.191], [0.019, 0.171], [0.012, 0.1], [0.046, 0.001], [0.071, 0.012], [0.1, 0], [0.186, 0.01], [0.228, 0.008], [0.239, 0.022], [0.25, 0.009], [0.304, 0.002], [0.311, 0.027], [0.313, 0.007], [0.322, 0.064], [0.311, 0.101], [0.329, 0.055], [0.321, 0.018], [0.334, 0.01], [0.496, 0.009], [0.53, 0.019], [0.553, 0.01], [0.615, 0.014], [0.683, 0.03], [0.697, 0.019], [0.728, 0.027], [0.732, 0.066], [0.735, 0.012], [0.752, 0.006], [0.795, 0.014], [0.85, 0.007], [0.929, 0.013], [1, 0.204], [0.994, 0.324], [0.999, 0.393], [0.988, 0.464], [0.947, 0.46], [0.977, 0.47], [0.978, 0.479], [0.99, 0.489], [0.994, 0.572], [0.992, 0.669], [0.982, 0.673], [0.994, 0.689], [1, 0.716], [0.999, 0.81], [0.987, 0.816], [0.996, 0.83], [0.99, 0.894], [0.944, 1], [0.848, 0.993], [0.841, 0.97], [0.837, 0.993], [0.798, 0.981], [0.697, 0.98], [0.653, 0.986], [0.606, 0.981], [0.598, 0.968], [0.598, 0.941], [0.592, 0.982], [0.558, 0.988], [0.507, 0.983], [0.485, 0.988], [0.418, 0.978], [0.4, 0.969], [0.393, 0.98], [0.338, 0.984], [0.304, 0.977], [0.251, 0.984], [0.238, 0.979], [0.252, 0.915], [0.239, 0.969], [0.233, 0.953], [0.23, 0.984], [0.155, 0.971], [0.147, 0.957], [0.142, 0.974], [0.095, 0.976], [0.066, 0.98], [0.023, 0.957]],
units: '%',
extent: [0,0,1,1]
});
osm.addFilter(clip);
</script>
// Clip
var clip = new ol.filter.Clip({
operation:'enhance',
coords: [[0.023, 0.957], [0, 0.463], [0.007, 0.42], [0.004, 0.397], [0.029, 0.383], [0.013, 0.383], [0.046, 0.367], [0.011, 0.371], [0.004, 0.349], [0.006, 0.297], [0.012, 0.265], [0.007, 0.246], [0.016, 0.191], [0.031, 0.191], [0.019, 0.171], [0.012, 0.1], [0.046, 0.001], [0.071, 0.012], [0.1, 0], [0.186, 0.01], [0.228, 0.008], [0.239, 0.022], [0.25, 0.009], [0.304, 0.002], [0.311, 0.027], [0.313, 0.007], [0.322, 0.064], [0.311, 0.101], [0.329, 0.055], [0.321, 0.018], [0.334, 0.01], [0.496, 0.009], [0.53, 0.019], [0.553, 0.01], [0.615, 0.014], [0.683, 0.03], [0.697, 0.019], [0.728, 0.027], [0.732, 0.066], [0.735, 0.012], [0.752, 0.006], [0.795, 0.014], [0.85, 0.007], [0.929, 0.013], [1, 0.204], [0.994, 0.324], [0.999, 0.393], [0.988, 0.464], [0.947, 0.46], [0.977, 0.47], [0.978, 0.479], [0.99, 0.489], [0.994, 0.572], [0.992, 0.669], [0.982, 0.673], [0.994, 0.689], [1, 0.716], [0.999, 0.81], [0.987, 0.816], [0.996, 0.83], [0.99, 0.894], [0.944, 1], [0.848, 0.993], [0.841, 0.97], [0.837, 0.993], [0.798, 0.981], [0.697, 0.98], [0.653, 0.986], [0.606, 0.981], [0.598, 0.968], [0.598, 0.941], [0.592, 0.982], [0.558, 0.988], [0.507, 0.983], [0.485, 0.988], [0.418, 0.978], [0.4, 0.969], [0.393, 0.98], [0.338, 0.984], [0.304, 0.977], [0.251, 0.984], [0.238, 0.979], [0.252, 0.915], [0.239, 0.969], [0.233, 0.953], [0.23, 0.984], [0.155, 0.971], [0.147, 0.957], [0.142, 0.974], [0.095, 0.976], [0.066, 0.98], [0.023, 0.957]],
units: '%',
extent: [0,0,1,1]
});
osm.addFilter(clip);
</script>
</body>
</html>

View File

@ -12,9 +12,9 @@
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- ol3 to show the map -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- filesaver-js -->

View File

@ -13,8 +13,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- ol3 to show the map -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- filesaver-js -->

View File

@ -15,8 +15,8 @@
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -67,7 +67,7 @@
}),
layers: [
new ol.layer.Geoportail({ layer: 'ORTHOIMAGERY.ORTHOPHOTOS', visible: false }),
new ol.layer.Geoportail({ layer: 'GEOGRAPHICALGRIDSYSTEMS.MAPS', gppKey: 'h1osiyvfm7c4wu976jv6gpum' }),
new ol.layer.Geoportail({ layer: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2' }),
new ol.layer.Tile({ title: 'OSM', source: new ol.source.OSM(), visible: false })
]
});

View File

@ -10,8 +10,8 @@
<link rel="stylesheet" href="../style.css" />
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -20,8 +20,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -15,8 +15,8 @@
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -18,8 +18,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -12,8 +12,8 @@
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.15.1/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/v6.15.1/build/ol.js"></script>
<link rel="stylesheet" href="https://openlayers.org/en/latest/legacy/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/legacy/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->

View File

@ -139,12 +139,16 @@ a.title {
text-decoration: none;
}
h1 {
background: #1f6b75 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAACE1BMVEX///8A//8AgICA//8AVVVAQID///8rVVVJtttgv98nTmJ2xNgkW1ttyNsmWWZmzNZYxM4gWGgeU2JmzNNr0N1Rwc0eU2VXxdEhV2JqytQeVmMhVmNoydUfVGUgVGQfVGQfVmVqy9hqy9dWw9AfVWRpydVry9YhVmMgVGNUw9BrytchVWRexdGw294gVWQgVmUhVWPd4N6HoaZsy9cfVmQgVGRrytZsy9cgVWQgVWMgVWRsy9YfVWNsy9YgVWVty9YgVWVry9UgVWRsy9Zsy9UfVWRsy9YgVWVty9YgVWRty9Vsy9aM09sgVWRTws/AzM0gVWRtzNYgVWRuy9Zsy9cgVWRGcHxty9bb5ORbxdEgVWRty9bn6OZTws9mydRfxtLX3Nva5eRix9NFcXxOd4JPeINQeIMiVmVUws9Vws9Vw9BXw9BYxNBaxNBbxNBcxdJexdElWWgmWmhjyNRlx9IqXGtoipNpytVqytVryNNrytZsjZUuX210k5t1y9R2zNR3y9V4lp57zth9zdaAnKOGoaeK0NiNpquV09mesrag1tuitbmj1tuj19uktrqr2d2svcCu2d2xwMO63N+7x8nA3uDC3uDFz9DK4eHL4eLN4eIyYnDX5OM5Z3Tb397e4uDf4uHf5uXi5ePi5+Xj5+Xk5+Xm5+Xm6OY6aHXQ19fT4+NfhI1Ww89gx9Nhx9Nsy9ZWw9Dpj2abAAAAWnRSTlMAAQICAwQEBgcIDQ0ODhQZGiAiIyYpKywvNTs+QklPUlNUWWJjaGt0dnd+hIWFh4mNjZCSm6CpsbW2t7nDzNDT1dje5efr7PHy9PT29/j4+Pn5+vr8/f39/f6DPtKwAAABTklEQVR4Xr3QVWPbMBSAUTVFZmZmhhSXMjNvkhwqMzMzMzPDeD+xASvObKePPa+ffHVl8PlsnE0+qPpBuQjVJjno6pZpSKXYl7/bZyFaQxhf98hHDKEppwdWIW1frFnrxSOWHFfWesSEWC6R/P4zOFrix3TzDFLlXRTR8c0fEEJ1/itpo7SVO9Jdr1DVxZ0USyjZsEY5vZfiiAC0UoTGOrm9PZLuRl8X+Dq1HQtoFbJZbv61i+Poblh/97TC7n0neCcK0ETNUrz1/xPHf+DNAW9Ac6t8O8WH3Vp98f5lCaYKAOFZMLyHL4Y0fe319idMNgMMp+zWVSybUed/+/h7I4wRAG1W6XDy4XmjR9HnzvDRZXUAYDFOhC1S/Hh+fIXxen+eO+AKqbs+wAo30zDTDvDxKoJN88sjUzDFAvBzEUGFsnADoIvAJzoh2BZ8sner+Ke/vwECuQAAAABJRU5ErkJggg==) no-repeat scroll .3em center;
background: #333 url(https://openlayers.org/theme/img/logo-dark.svg) no-repeat scroll .3em center;
color: #fff;
font-size: 1.5em;
padding: .5em 0 .5em 2.1em;
margin: 0;
background-size: 1.5em;
text-decoration: none!important;
}
a:hover h1 {
color: #0af;
}
h2 {
color: #337ab7;

View File

@ -4,8 +4,9 @@
<title>ol-ext</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1" />
<link rel="icon" type="image/png" href="https://openlayers.org/assets/theme/img/logo70.png" />
<link rel="icon" type="image/svg+xml" href="https://openlayers.org/theme/img/logo-light.svg" media="(prefers-color-scheme: light)">
<link rel="icon" type="image/svg+xml" href="https://openlayers.org/theme/img/logo-dark.svg" media="(prefers-color-scheme: dark)">
<meta name="description" content="Cool extensions to use with Openlayers (ol)." />
<meta name="keywords" content="ol,extension,canvas,3D,animation,layer,selection,control,openlayers,popup" />
@ -56,8 +57,8 @@
width:100%;
position: fixed;
z-index: 1;
background-color: #1f6b75;
color: white;
background-color: #333;
color: #fff;
height: 4em;
overflow: hidden;
}
@ -369,7 +370,7 @@
<header role="navigation" class="navbar navbar-fixed-top">
<div class="container">
<h1><img src="https://upload.wikimedia.org/wikipedia/commons/6/67/OpenLayers_logo.svg">&nbsp;ol-ext<span>:
<h1><img src="https://openlayers.org/theme/img/logo-dark.svg">&nbsp;ol-ext<span>:
Extensions for OpenLayers (ol)</span>
</h1>
<p>

View File

@ -6,7 +6,6 @@ import {unByKey as ol_Observable_unByKey} from 'ol/Observable'
import ol_control_Control from 'ol/control/Control'
import ol_layer_Layer from 'ol/layer/Layer'
import ol_ext_element from '../util/element'
import ol_ext_inherits from '../util/ext'
/** Add a progress bar to a map.
* Use the layers option listen to tileload event and show the layer loading progress.
@ -17,86 +16,86 @@ import ol_ext_inherits from '../util/ext'
* @param {String} [options.label] waiting label
* @param {ol_layer_Layer|Array<ol_layer_Layer>} [options.layers] tile layers with tileload events
*/
var ol_control_ProgressBar = function(options) {
options = options || {};
var ol_control_ProgressBar = class olcontrolProgressBar extends ol_control_Control {
constructor(options) {
options = options || {}
var element = ol_ext_element.create('DIV', {
className: ((options.className || '') + ' ol-progress-bar ol-unselectable ol-control').trim()
});
this._waiting = ol_ext_element.create('DIV', {
html: options.label || '',
className: 'ol-waiting',
parent: element
});
this._bar = ol_ext_element.create('DIV', {
className: 'ol-bar',
parent: element
});
var element = ol_ext_element.create('DIV', {
className: ((options.className || '') + ' ol-progress-bar ol-unselectable ol-control').trim()
})
super({
element: element,
target: options.target
})
ol_control_Control.call(this, {
element: element,
target: options.target
});
this._waiting = ol_ext_element.create('DIV', {
html: options.label || '',
className: 'ol-waiting',
parent: element
})
this._bar = ol_ext_element.create('DIV', {
className: 'ol-bar',
parent: element
})
this._layerlistener = [];
this.setLayers(options.layers);
};
ol_ext_inherits(ol_control_ProgressBar, ol_control_Control);
/** Set the control visibility
* @param {Number} [n] progress percentage, a number beetween 0,1, default hide progress bar
*/
ol_control_ProgressBar.prototype.setPercent = function (n) {
this._bar.style.width = ((Number(n) || 0) * 100)+'%';
if (n===undefined) {
ol_ext_element.hide(this.element);
} else {
ol_ext_element.show(this.element);
this._layerlistener = []
this.setLayers(options.layers)
}
};
/** Set waiting text
* @param {string} label
*/
ol_control_ProgressBar.prototype.setLabel = function (label) {
this._waiting.innerHTML = label;
};
/** Use a list of tile layer to shown tile load
* @param {ol_layer_Layer|Array<ol_layer_Layer>} layers a layer or a list of layer
*/
ol_control_ProgressBar.prototype.setLayers = function (layers) {
// reset
this._layerlistener.forEach(function (l) {
ol_Observable_unByKey(l);
});
this._layerlistener = [];
this.setPercent();
var loading=0, loaded=0;
if (layers instanceof ol_layer_Layer) layers = [layers];
if (!layers || !layers.forEach) return;
var tout;
// Listeners
layers.forEach(function(layer) {
if (layer instanceof ol_layer_Layer) {
this._layerlistener.push(layer.getSource().on('tileloadstart', function () {
loading++;
this.setPercent(loaded/loading);
clearTimeout(tout);
}.bind(this)));
this._layerlistener.push(layer.getSource().on(['tileloadend', 'tileloaderror'], function () {
loaded++;
if (loaded === loading) {
loading = loaded = 0;
this.setPercent(1);
tout = setTimeout(this.setPercent.bind(this), 300);
} else {
this.setPercent(loaded/loading);
}
}.bind(this)));
/** Set the control visibility
* @param {Number} [n] progress percentage, a number beetween 0,1, default hide progress bar
*/
setPercent(n) {
this._bar.style.width = ((Number(n) || 0) * 100) + '%'
if (n === undefined) {
ol_ext_element.hide(this.element)
} else {
ol_ext_element.show(this.element)
}
}.bind(this));
}
/** Set waiting text
* @param {string} label
*/
setLabel(label) {
this._waiting.innerHTML = label
}
/** Use a list of tile layer to shown tile load
* @param {ol_layer_Layer|Array<ol_layer_Layer>} layers a layer or a list of layer
*/
setLayers(layers) {
// reset
this._layerlistener.forEach(function (l) {
ol_Observable_unByKey(l)
})
this._layerlistener = []
this.setPercent()
var loading = 0, loaded = 0
if (layers instanceof ol_layer_Layer)
layers = [layers]
if (!layers || !layers.forEach)
return
var tout
// Listeners
layers.forEach(function (layer) {
if (layer instanceof ol_layer_Layer) {
this._layerlistener.push(layer.getSource().on('tileloadstart', function () {
loading++
this.setPercent(loaded / loading)
clearTimeout(tout)
}.bind(this)))
this._layerlistener.push(layer.getSource().on(['tileloadend', 'tileloaderror'], function () {
loaded++
if (loaded === loading) {
loading = loaded = 0
this.setPercent(1)
tout = setTimeout(this.setPercent.bind(this), 300)
} else {
this.setPercent(loaded / loading)
}
}.bind(this)))
}
}.bind(this))
}
}
export default ol_control_ProgressBar

View File

@ -2,7 +2,6 @@ import ol_format_GeoJSONX from './GeoJSONX'
import ol_format_Polyline from 'ol/format/Polyline'
import ol_geom_Point from 'ol/geom/Point'
import ol_geom_LineString from 'ol/geom/LineString'
import ol_ext_inherits from '../util/ext'
/** Feature format for reading and writing data in the GeoJSONP format,
* using Polyline Algorithm to encode geometry.
@ -13,68 +12,67 @@ import ol_ext_inherits from '../util/ext'
* @param {ol.ProjectionLike} options.dataProjection Projection of the data we are reading. If not provided `EPSG:4326`
* @param {ol.ProjectionLike} options.featureProjection Projection of the feature geometries created by the format reader. If not provided, features will be returned in the dataProjection.
*/
var ol_format_GeoJSONP = function(options) {
options = options || {};
ol_format_GeoJSONX.call (this, options);
this._lineFormat = new ol_format_Polyline({ factor: Math.pow(10, options.decimals || 6) });
};
ol_ext_inherits(ol_format_GeoJSONP, ol_format_GeoJSONX);
var ol_format_GeoJSONP = class olformatGeoJSONP extends ol_format_GeoJSONX {
constructor(options) {
options = options || {}
super(options)
/** Encode coordinates
* @param {ol.coordinate|Array<ol.coordinate>} v
* @return {string|Array<string>}
* @api
*/
ol_format_GeoJSONP.prototype.encodeCoordinates = function(v) {
var g;
if (typeof(v[0]) === 'number') {
g = new ol_geom_Point(v);
return this._lineFormat.writeGeometry(g);
} else if (v.length && v[0]) {
var tab = (typeof(v[0][0]) === 'number');
if (tab) {
g = new ol_geom_LineString(v);
return this._lineFormat.writeGeometry(g);
} else {
var r = [];
for (var i=0; i<v.length; i++) {
r[i] = this.encodeCoordinates(v[i]);
}
return r;
}
} else {
return this.encodeCoordinates([0,0]);
this._lineFormat = new ol_format_Polyline({ factor: Math.pow(10, options.decimals || 6) })
}
};
/** Decode coordinates
* @param {string|Array<string>}
* @return {ol.coordinate|Array<ol.coordinate>} v
* @api
*/
ol_format_GeoJSONP.prototype.decodeCoordinates = function(v) {
var i, g;
if (typeof(v) === 'string') {
g = this._lineFormat.readGeometry(v);
return g.getCoordinates()[0];
} else if (v.length) {
var tab = (typeof(v[0]) === 'string');
var r = [];
if (tab) {
for (i=0; i<v.length; i++) {
g = this._lineFormat.readGeometry(v[i]);
r[i] = g.getCoordinates();
/** Encode coordinates
* @param {ol.coordinate|Array<ol.coordinate>} v
* @return {string|Array<string>}
* @api
*/
encodeCoordinates(v) {
var g
if (typeof (v[0]) === 'number') {
g = new ol_geom_Point(v)
return this._lineFormat.writeGeometry(g)
} else if (v.length && v[0]) {
var tab = (typeof (v[0][0]) === 'number')
if (tab) {
g = new ol_geom_LineString(v)
return this._lineFormat.writeGeometry(g)
} else {
var r = []
for (var i = 0; i < v.length; i++) {
r[i] = this.encodeCoordinates(v[i])
}
return r
}
} else {
for (i=0; i<v.length; i++) {
r[i] = this.decodeCoordinates(v[i]);
}
return this.encodeCoordinates([0, 0])
}
return r;
} else {
return null;
}
};
/** Decode coordinates
* @param {string|Array<string>}
* @return {ol.coordinate|Array<ol.coordinate>} v
* @api
*/
decodeCoordinates(v) {
var i, g
if (typeof (v) === 'string') {
g = this._lineFormat.readGeometry(v)
return g.getCoordinates()[0]
} else if (v.length) {
var tab = (typeof (v[0]) === 'string')
var r = []
if (tab) {
for (i = 0; i < v.length; i++) {
g = this._lineFormat.readGeometry(v[i])
r[i] = g.getCoordinates()
}
} else {
for (i = 0; i < v.length; i++) {
r[i] = this.decodeCoordinates(v[i])
}
}
return r
} else {
return null
}
}
}
export default ol_format_GeoJSONP

View File

@ -3,7 +3,6 @@
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/
import ol_ext_inherits from '../util/ext'
import {unByKey as ol_Observable_unByKey} from 'ol/Observable'
import ol_interaction_Interaction from 'ol/interaction/Interaction'
import ol_Map from 'ol/Map'
@ -15,107 +14,103 @@ import ol_Overlay from 'ol/Overlay'
* @param {*} options
* @param {Array<ol.Map>} options maps An array of maps to synchronize with the map of the interaction
*/
var ol_interaction_Synchronize = function(options) {
if (!options) options={};
var self = this;
var ol_interaction_Synchronize = class olinteractionSynchronize extends ol_interaction_Interaction {
constructor(options) {
options = options || {}
super({
handleEvent: function (e) {
if (e.type == "pointermove") { this.handleMove_(e)}
return true
}
})
ol_interaction_Interaction.call(this, {
handleEvent: function(e) {
if (e.type=="pointermove") { self.handleMove_(e); }
return true;
}
});
this.maps = options.maps || [];
if (options.active === false) this.setActive(false);
};
ol_ext_inherits(ol_interaction_Synchronize, ol_interaction_Interaction);
/**
* Remove the interaction from its current map, if any, and attach it to a new
* map, if any. Pass `null` to just remove the interaction from the current map.
* @param {ol_Map} map Map.
* @api stable
*/
ol_interaction_Synchronize.prototype.setMap = function(map) {
if (this._listener) {
ol_Observable_unByKey(this._listener.center);
ol_Observable_unByKey(this._listener.rotation);
ol_Observable_unByKey(this._listener.resolution);
this.getMap().getTargetElement().removeEventListener('mouseout', this._listener.mouseout);
this.maps = options.maps || []
if (options.active === false) this.setActive(false)
}
this._listener = null;
ol_interaction_Interaction.prototype.setMap.call (this, map);
if (map) {
this._listener = {};
this._listener.center = this.getMap().getView().on('change:center', this.syncMaps.bind(this));
this._listener.rotation = this.getMap().getView().on('change:rotation', this.syncMaps.bind(this));
this._listener.resolution = this.getMap().getView().on('change:resolution', this.syncMaps.bind(this));
this._listener.mouseout = this.handleMouseOut_.bind(this);
if (this.getMap().getTargetElement()) {
this.getMap().getTargetElement().addEventListener('mouseout', this._listener.mouseout);
/**
* Remove the interaction from its current map, if any, and attach it to a new
* map, if any. Pass `null` to just remove the interaction from the current map.
* @param {ol_Map} map Map.
* @api stable
*/
setMap(map) {
if (this._listener) {
ol_Observable_unByKey(this._listener.center)
ol_Observable_unByKey(this._listener.rotation)
ol_Observable_unByKey(this._listener.resolution)
this.getMap().getTargetElement().removeEventListener('mouseout', this._listener.mouseout)
}
this.syncMaps();
}
};
this._listener = null
super.setMap(map)
/** Auto activate/deactivate controls in the bar
* @param {boolean} b activate/deactivate
*/
ol_interaction_Synchronize.prototype.setActive = function (b) {
ol_interaction_Interaction.prototype.setActive.call(this, b);
this.syncMaps();
};
/** Synchronize the maps
*/
ol_interaction_Synchronize.prototype.syncMaps = function() {
if (!this.getActive()) return;
var map = this.getMap();
if (map) {
if (map.get('lockView')) return;
for (var i=0; i<this.maps.length; i++) {
this.maps[i].set('lockView', true);
// sync
if (this.maps[i].getView().getRotation() != map.getView().getRotation()) {
this.maps[i].getView().setRotation(map.getView().getRotation());
if (map) {
this._listener = {}
this._listener.center = this.getMap().getView().on('change:center', this.syncMaps.bind(this))
this._listener.rotation = this.getMap().getView().on('change:rotation', this.syncMaps.bind(this))
this._listener.resolution = this.getMap().getView().on('change:resolution', this.syncMaps.bind(this))
this._listener.mouseout = this.handleMouseOut_.bind(this)
if (this.getMap().getTargetElement()) {
this.getMap().getTargetElement().addEventListener('mouseout', this._listener.mouseout)
}
if (this.maps[i].getView().getCenter() != map.getView().getCenter()) {
this.maps[i].getView().setCenter(map.getView().getCenter());
}
if (this.maps[i].getView().getResolution() != map.getView().getResolution()) {
this.maps[i].getView().setResolution(map.getView().getResolution());
}
this.maps[i].set('lockView', false);
this.syncMaps()
}
}
};
/** Cursor move > tells other maps to show the cursor
* @param {ol.event} e "move" event
*/
ol_interaction_Synchronize.prototype.handleMove_ = function(e) {
for (var i=0; i<this.maps.length; i++) {
this.maps[i].showTarget(e.coordinate);
/** Auto activate/deactivate controls in the bar
* @param {boolean} b activate/deactivate
*/
setActive(b) {
super.setActive(b)
this.syncMaps()
}
this.getMap().showTarget();
};
/** Cursor out of map > tells other maps to hide the cursor
* @param {event} e "mouseOut" event
*/
ol_interaction_Synchronize.prototype.handleMouseOut_ = function(/*e*/) {
for (var i=0; i<this.maps.length; i++) {
if (this.maps[i]._targetOverlay) this.maps[i]._targetOverlay.setPosition(undefined);
/** Synchronize the maps
*/
syncMaps() {
if (!this.getActive())
return
var map = this.getMap()
if (map) {
if (map.get('lockView'))
return
for (var i = 0; i < this.maps.length; i++) {
this.maps[i].set('lockView', true)
// sync
if (this.maps[i].getView().getRotation() != map.getView().getRotation()) {
this.maps[i].getView().setRotation(map.getView().getRotation())
}
if (this.maps[i].getView().getCenter() != map.getView().getCenter()) {
this.maps[i].getView().setCenter(map.getView().getCenter())
}
if (this.maps[i].getView().getResolution() != map.getView().getResolution()) {
this.maps[i].getView().setResolution(map.getView().getResolution())
}
this.maps[i].set('lockView', false)
}
}
}
};
/** Cursor move > tells other maps to show the cursor
* @param {ol.event} e "move" event
*/
handleMove_(e) {
for (var i = 0; i < this.maps.length; i++) {
this.maps[i].showTarget(e.coordinate)
}
this.getMap().showTarget()
}
/** Cursor out of map > tells other maps to hide the cursor
* @param {event} e "mouseOut" event
*/
handleMouseOut_( /*e*/) {
for (var i = 0; i < this.maps.length; i++) {
if (this.maps[i]._targetOverlay)
this.maps[i]._targetOverlay.setPosition(undefined)
}
}
}
/** Show a target overlay at coord
* @param {ol.coordinate} coord
*/
* @param {ol.coordinate} coord
*/
ol_Map.prototype.showTarget = function(coord) {
if (!this._targetOverlay) {
var elt = document.createElement("div");
@ -131,7 +126,7 @@ ol_Map.prototype.showTarget = function(coord) {
};
/** Hide the target overlay
*/
*/
ol_Map.prototype.hideTarget = function() {
this.removeOverlay(this._targetOverlay);
this._targetOverlay = undefined;

View File

@ -31,375 +31,372 @@ ol_layer_Vector.prototype.setRender3D = function (r) {
* @param {number} param.defaultHeight default height if none is return by a propertie
* @param {function|string|Number} param.height a height function (returns height giving a feature) or a popertie name for the height or a fixed value
*/
var ol_render3D = function (options) {
options = options || {};
var ol_render3D = class olrender3D extends ol_Object {
constructor(options) {
options = options || {}
options.maxResolution = options.maxResolution || 100
options.defaultHeight = options.defaultHeight || 0;
ol_Object.call (this, options);
options.maxResolution = options.maxResolution || 100
options.defaultHeight = options.defaultHeight || 0
super(options)
this.setStyle(options.style);
this.set('ghost', options.ghost);
this.setActive(options.active || options.active!==false);
this.setStyle(options.style)
this.set('ghost', options.ghost)
this.setActive(options.active || options.active !== false)
this.height_ = options.height = this.getHfn (options.height);
if (options.layer) this.setLayer(options.layer);
}
ol_ext_inherits(ol_render3D, ol_Object);
/**
* Set style associated with the renderer
* @param {ol.style.Style} s
*/
ol_render3D.prototype.setStyle = function(s) {
if (s instanceof ol_style_Style) this._style = s;
else this._style = new ol_style_Style ();
if (!this._style.getStroke()) {
this._style.setStroke(new ol_style_Stroke({
width: 1,
color: 'red'
}));
this.height_ = options.height = this.getHfn(options.height)
if (options.layer)
this.setLayer(options.layer)
}
if (!this._style.getFill()) {
this._style.setFill( new ol_style_Fill({ color: 'rgba(0,0,255,0.5)'}) );
}
// Get the geometry
if (s && s.getGeometry()) {
var geom = s.getGeometry();
if (typeof(geom)==='function') {
this.set('geometry', geom);
} else {
this.set('geometry', function() { return geom; });
/**
* Set style associated with the renderer
* @param {ol.style.Style} s
*/
setStyle(s) {
if (s instanceof ol_style_Style)
this._style = s
else
this._style = new ol_style_Style()
if (!this._style.getStroke()) {
this._style.setStroke(new ol_style_Stroke({
width: 1,
color: 'red'
}))
}
} else {
this.set('geometry', function(f) { return f.getGeometry(); });
}
};
/**
* Get style associated with the renderer
* @return {ol.style.Style}
*/
ol_render3D.prototype.getStyle = function() {
return this._style;
};
/** Set active
* @param {function|boolean} active
*/
ol_render3D.prototype.setActive = function(active) {
if (typeof(active)==='function') {
this._active = active;
}
else {
this._active = function() { return active; };
}
if (this.layer_) this.layer_.changed();
};
/** Get active
* @return {boolean}
*/
ol_render3D.prototype.getActive = function() {
return this._active();
};
/** Calculate 3D at potcompose
* @private
*/
ol_render3D.prototype.onPostcompose_ = function(e) {
if (!this.getActive()) return;
var res = e.frameState.viewState.resolution;
if (res > this.get('maxResolution')) return;
this.res_ = res*400;
if (this.animate_) {
var elapsed = e.frameState.time - this.animate_;
if (elapsed < this.animateDuration_) {
this.elapsedRatio_ = this.easing_(elapsed / this.animateDuration_);
// tell OL3 to continue postcompose animation
e.frameState.animate = true;
if (!this._style.getFill()) {
this._style.setFill(new ol_style_Fill({ color: 'rgba(0,0,255,0.5)' }))
}
// Get the geometry
if (s && s.getGeometry()) {
var geom = s.getGeometry()
if (typeof (geom) === 'function') {
this.set('geometry', geom)
} else {
this.set('geometry', function () { return geom })
}
} else {
this.animate_ = false;
this.height_ = this.toHeight_
this.set('geometry', function (f) { return f.getGeometry() })
}
}
var ratio = e.frameState.pixelRatio;
var ctx = e.context;
var m = this.matrix_ = e.frameState.coordinateToPixelTransform;
// Old version (matrix)
if (!m) {
m = e.frameState.coordinateToPixelMatrix,
m[2] = m[4];
m[3] = m[5];
m[4] = m[12];
m[5] = m[13];
/**
* Get style associated with the renderer
* @return {ol.style.Style}
*/
getStyle() {
return this._style
}
this.center_ = [ ctx.canvas.width/2/ratio, ctx.canvas.height/ratio ];
/** Set active
* @param {function|boolean} active
*/
setActive(active) {
if (typeof (active) === 'function') {
this._active = active
}
else {
this._active = function () { return active }
}
if (this.layer_)
this.layer_.changed()
}
/** Get active
* @return {boolean}
*/
getActive() {
return this._active()
}
/** Calculate 3D at potcompose
* @private
*/
onPostcompose_(e) {
if (!this.getActive())
return
var res = e.frameState.viewState.resolution
if (res > this.get('maxResolution'))
return
this.res_ = res * 400
var f = this.layer_.getSource().getFeaturesInExtent(e.frameState.extent);
ctx.save();
ctx.scale(ratio,ratio);
var s = this.getStyle();
ctx.lineWidth = s.getStroke().getWidth();
ctx.strokeStyle = ol_color_asString(s.getStroke().getColor());
ctx.fillStyle = ol_color_asString(s.getFill().getColor());
var builds = [];
for (var i=0; i<f.length; i++) {
if (this.animate_) {
var elapsed = e.frameState.time - this.animate_
if (elapsed < this.animateDuration_) {
this.elapsedRatio_ = this.easing_(elapsed / this.animateDuration_)
// tell OL3 to continue postcompose animation
e.frameState.animate = true
} else {
this.animate_ = false
this.height_ = this.toHeight_
}
}
var ratio = e.frameState.pixelRatio
var ctx = e.context
var m = this.matrix_ = e.frameState.coordinateToPixelTransform
// Old version (matrix)
if (!m) {
m = e.frameState.coordinateToPixelMatrix,
m[2] = m[4]
m[3] = m[5]
m[4] = m[12]
m[5] = m[13]
}
this.center_ = [ctx.canvas.width / 2 / ratio, ctx.canvas.height / ratio]
var f = this.layer_.getSource().getFeaturesInExtent(e.frameState.extent)
ctx.save()
ctx.scale(ratio, ratio)
var s = this.getStyle()
ctx.lineWidth = s.getStroke().getWidth()
ctx.strokeStyle = ol_color_asString(s.getStroke().getColor())
ctx.fillStyle = ol_color_asString(s.getFill().getColor())
var builds = []
for (var i = 0; i < f.length; i++) {
var h = this.getFeatureHeight(f[i])
if (h) builds.push (this.getFeature3D_ (f[i], h));
if (h)
builds.push(this.getFeature3D_(f[i], h))
}
if (this.get('ghost')) this.drawGhost3D_ (ctx, builds);
else this.drawFeature3D_ (ctx, builds);
ctx.restore();
};
/** Set layer to render 3D
*/
ol_render3D.prototype.setLayer = function(l) {
if (this._listener) {
this._listener.forEach( function(l) {
ol_Observable_unByKey(l);
});
if (this.get('ghost'))
this.drawGhost3D_(ctx, builds)
else
this.drawFeature3D_(ctx, builds)
ctx.restore()
}
this.layer_ = l;
this._listener = l.on (['postcompose', 'postrender'], this.onPostcompose_.bind(this));
}
/** Create a function that return height of a feature
* @param {function|string|number} h a height function or a popertie name or a fixed value
* @return {function} function(f) return height of the feature f
*/
ol_render3D.prototype.getHfn= function(h) {
switch (typeof(h)) {
case 'function': return h;
case 'string': {
var dh = this.get('defaultHeight');
return (function(f) {
return (Number(f.get(h)) || dh);
});
/** Set layer to render 3D
*/
setLayer(l) {
if (this._listener) {
this._listener.forEach(function (l) {
ol_Observable_unByKey(l)
})
}
this.layer_ = l
this._listener = l.on(['postcompose', 'postrender'], this.onPostcompose_.bind(this))
}
/** Create a function that return height of a feature
* @param {function|string|number} h a height function or a popertie name or a fixed value
* @return {function} function(f) return height of the feature f
*/
getHfn(h) {
switch (typeof (h)) {
case 'function': return h
case 'string': {
var dh = this.get('defaultHeight')
return (function (f) {
return (Number(f.get(h)) || dh)
})
}
case 'number': return (function(/*f*/) { return h; });
default: return (function(/*f*/) { return 10; });
case 'number': return (function ( /*f*/) { return h })
default: return (function ( /*f*/) { return 10 })
}
}
}
/** Animate rendering
* @param {olx.render3D.animateOptions}
* @param {string|function|number} param.height an attribute name or a function returning height of a feature or a fixed value
* @param {number} param.duration the duration of the animatioin ms, default 1000
* @param {ol.easing} param.easing an ol easing function
* @api
*/
ol_render3D.prototype.animate = function(options) {
options = options || {};
this.toHeight_ = this.getHfn(options.height);
this.animate_ = new Date().getTime();
this.animateDuration_ = options.duration ||1000;
this.easing_ = options.easing || ol_easing_easeOut;
// Force redraw
this.layer_.changed();
}
/** Check if animation is on
* @return {bool}
*/
ol_render3D.prototype.animating = function() {
if (this.animate_ && new Date().getTime() - this.animate_ > this.animateDuration_) {
this.animate_ = false;
/** Animate rendering
* @param {olx.render3D.animateOptions}
* @param {string|function|number} param.height an attribute name or a function returning height of a feature or a fixed value
* @param {number} param.duration the duration of the animatioin ms, default 1000
* @param {ol.easing} param.easing an ol easing function
* @api
*/
animate(options) {
options = options || {}
this.toHeight_ = this.getHfn(options.height)
this.animate_ = new Date().getTime()
this.animateDuration_ = options.duration || 1000
this.easing_ = options.easing || ol_easing_easeOut
// Force redraw
this.layer_.changed()
}
return !!this.animate_;
}
/** Get feature height
* @param {ol.Feature} f
*/
ol_render3D.prototype.getFeatureHeight = function (f) {
if (this.animate_) {
var h1 = this.height_(f);
var h2 = this.toHeight_(f);
return (h1*(1-this.elapsedRatio_)+this.elapsedRatio_*h2);
/** Check if animation is on
* @return {bool}
*/
animating() {
if (this.animate_ && new Date().getTime() - this.animate_ > this.animateDuration_) {
this.animate_ = false
}
return !!this.animate_
}
else return this.height_(f);
};
/** Get elevation line
* @private
*/
ol_render3D.prototype.hvector_ = function (pt, h) {
var p0 = [
pt[0]*this.matrix_[0] + pt[1]*this.matrix_[1] + this.matrix_[4],
pt[0]*this.matrix_[2] + pt[1]*this.matrix_[3] + this.matrix_[5]
];
return {
p0: p0,
p1: [
p0[0] + h/this.res_ * (p0[0]-this.center_[0]),
p0[1] + h/this.res_ * (p0[1]-this.center_[1])
/** Get feature height
* @param {ol.Feature} f
*/
getFeatureHeight(f) {
if (this.animate_) {
var h1 = this.height_(f)
var h2 = this.toHeight_(f)
return (h1 * (1 - this.elapsedRatio_) + this.elapsedRatio_ * h2)
}
else
return this.height_(f)
}
/** Get elevation line
* @private
*/
hvector_(pt, h) {
var p0 = [
pt[0] * this.matrix_[0] + pt[1] * this.matrix_[1] + this.matrix_[4],
pt[0] * this.matrix_[2] + pt[1] * this.matrix_[3] + this.matrix_[5]
]
};
};
/** Get drawing
* @private
*/
ol_render3D.prototype.getFeature3D_ = function (f, h) {
var geom = this.get('geometry')(f);
var c = geom.getCoordinates();
switch (geom.getType()) {
case "Polygon":
c = [c];
// fallthrough
case "MultiPolygon":
var build = [];
for (var i=0; i<c.length; i++) {
for (var j=0; j<c[i].length; j++) {
var b = [];
for (var k=0; k<c[i][j].length; k++) {
b.push( this.hvector_(c[i][j][k], h) );
return {
p0: p0,
p1: [
p0[0] + h / this.res_ * (p0[0] - this.center_[0]),
p0[1] + h / this.res_ * (p0[1] - this.center_[1])
]
}
}
/** Get drawing
* @private
*/
getFeature3D_(f, h) {
var geom = this.get('geometry')(f)
var c = geom.getCoordinates()
switch (geom.getType()) {
case "Polygon":
c = [c]
// fallthrough
case "MultiPolygon":
var build = []
for (var i = 0; i < c.length; i++) {
for (var j = 0; j < c[i].length; j++) {
var b = []
for (var k = 0; k < c[i][j].length; k++) {
b.push(this.hvector_(c[i][j][k], h))
}
build.push(b)
}
build.push(b);
}
return { type: "MultiPolygon", feature: f, geom: build, height: h }
case "Point":
return { type: "Point", feature: f, geom: this.hvector_(c, h), height: h }
default: return {}
}
}
/** Draw a feature
* @param {CanvasRenderingContext2D} ctx
* @param {ol.Feature} build
* @private
*/
drawFeature3D_(ctx, build) {
var i, j, b, k
// Construct
for (i = 0; i < build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j = 0; j < build[i].geom.length; j++) {
b = build[i].geom[j]
for (k = 0; k < b.length; k++) {
ctx.beginPath()
ctx.moveTo(b[k].p0[0], b[k].p0[1])
ctx.lineTo(b[k].p1[0], b[k].p1[1])
ctx.stroke()
}
}
break
}
case "Point": {
var g = build[i].geom
ctx.beginPath()
ctx.moveTo(g.p0[0], g.p0[1])
ctx.lineTo(g.p1[0], g.p1[1])
ctx.stroke()
break
}
default: break
}
return { type:"MultiPolygon", feature: f, geom: build, height: h };
case "Point":
return { type:"Point", feature: f, geom: this.hvector_(c,h), height: h };
default: return {};
}
// Roof
for (i = 0; i < build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
ctx.beginPath()
for (j = 0; j < build[i].geom.length; j++) {
b = build[i].geom[j]
if (j == 0) {
ctx.moveTo(b[0].p1[0], b[0].p1[1])
for (k = 1; k < b.length; k++) {
ctx.lineTo(b[k].p1[0], b[k].p1[1])
}
} else {
ctx.moveTo(b[0].p1[0], b[0].p1[1])
for (k = b.length - 2; k >= 0; k--) {
ctx.lineTo(b[k].p1[0], b[k].p1[1])
}
}
ctx.closePath()
}
ctx.fill("evenodd")
ctx.stroke()
break
}
case "Point": {
b = build[i]
var t = b.feature.get('label')
if (t) {
var p = b.geom.p1
var f = ctx.fillStyle
ctx.fillStyle = ctx.strokeStyle
ctx.textAlign = 'center'
ctx.textBaseline = 'bottom'
ctx.fillText(t, p[0], p[1])
var m = ctx.measureText(t)
var h = Number(ctx.font.match(/\d+(\.\d+)?/g).join([]))
ctx.fillStyle = "rgba(255,255,255,0.5)"
ctx.fillRect(p[0] - m.width / 2 - 5, p[1] - h - 5, m.width + 10, h + 10)
ctx.strokeRect(p[0] - m.width / 2 - 5, p[1] - h - 5, m.width + 10, h + 10)
ctx.fillStyle = f
//console.log(build[i].feature.getProperties())
}
break
}
default: break
}
}
}
/**
* @private
*/
drawGhost3D_(ctx, build) {
var i, j, b, k
// Construct
for (i = 0; i < build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j = 0; j < build[i].geom.length; j++) {
b = build[i].geom[j]
for (k = 0; k < b.length - 1; k++) {
ctx.beginPath()
ctx.moveTo(b[k].p0[0], b[k].p0[1])
ctx.lineTo(b[k].p1[0], b[k].p1[1])
ctx.lineTo(b[k + 1].p1[0], b[k + 1].p1[1])
ctx.lineTo(b[k + 1].p0[0], b[k + 1].p0[1])
ctx.lineTo(b[k].p0[0], b[k].p0[1])
var m = [(b[k].p0[0] + b[k + 1].p0[0]) / 2, (b[k].p0[1] + b[k + 1].p0[1]) / 2]
var h = [b[k].p0[1] - b[k + 1].p0[1], -b[k].p0[0] + b[k + 1].p0[0]]
var c = ol_coordinate_getIntersectionPoint(
[m, [m[0] + h[0], m[1] + h[1]]],
[b[k].p1, b[k + 1].p1]
)
var gradient = ctx.createLinearGradient(
m[0], m[1],
c[0], c[1]
)
gradient.addColorStop(0, 'rgba(255,255,255,.2)')
gradient.addColorStop(1, 'rgba(255,255,255,0)')
ctx.fillStyle = gradient
ctx.fill()
}
}
break
}
case "Point": {
var g = build[i].geom
ctx.beginPath()
ctx.moveTo(g.p0[0], g.p0[1])
ctx.lineTo(g.p1[0], g.p1[1])
ctx.stroke()
break
}
default: break
}
}
}
}
/** Draw a feature
* @param {CanvasRenderingContext2D} ctx
* @param {ol.Feature} build
* @private
*/
ol_render3D.prototype.drawFeature3D_ = function(ctx, build) {
var i,j, b, k;
// Construct
for (i=0; i<build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j=0; j<build[i].geom.length; j++) {
b = build[i].geom[j];
for (k=0; k < b.length; k++) {
ctx.beginPath();
ctx.moveTo(b[k].p0[0], b[k].p0[1]);
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
ctx.stroke();
}
}
break;
}
case "Point": {
var g = build[i].geom;
ctx.beginPath();
ctx.moveTo(g.p0[0], g.p0[1]);
ctx.lineTo(g.p1[0], g.p1[1]);
ctx.stroke();
break;
}
default: break;
}
}
// Roof
for (i=0; i<build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
ctx.beginPath();
for (j=0; j<build[i].geom.length; j++) {
b = build[i].geom[j];
if (j==0) {
ctx.moveTo(b[0].p1[0], b[0].p1[1]);
for (k=1; k < b.length; k++) {
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
}
} else {
ctx.moveTo(b[0].p1[0], b[0].p1[1]);
for (k=b.length-2; k>=0; k--) {
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
}
}
ctx.closePath();
}
ctx.fill("evenodd");
ctx.stroke();
break;
}
case "Point": {
b = build[i];
var t = b.feature.get('label');
if (t) {
var p = b.geom.p1;
var f = ctx.fillStyle;
ctx.fillStyle = ctx.strokeStyle;
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText ( t, p[0], p[1] );
var m = ctx.measureText(t);
var h = Number (ctx.font.match(/\d+(\.\d+)?/g).join([]));
ctx.fillStyle = "rgba(255,255,255,0.5)";
ctx.fillRect (p[0]-m.width/2 -5, p[1]-h -5, m.width +10, h +10)
ctx.strokeRect (p[0]-m.width/2 -5, p[1]-h -5, m.width +10, h +10)
ctx.fillStyle = f;
//console.log(build[i].feature.getProperties())
}
break;
}
default: break;
}
}
};
/**
* @private
*/
ol_render3D.prototype.drawGhost3D_ = function(ctx, build) {
var i,j, b, k;
// Construct
for (i=0; i<build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j=0; j<build[i].geom.length; j++) {
b = build[i].geom[j];
for (k=0; k < b.length-1; k++) {
ctx.beginPath();
ctx.moveTo(b[k].p0[0], b[k].p0[1]);
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
ctx.lineTo(b[k+1].p1[0], b[k+1].p1[1]);
ctx.lineTo(b[k+1].p0[0], b[k+1].p0[1]);
ctx.lineTo(b[k].p0[0], b[k].p0[1]);
var m = [(b[k].p0[0] + b[k+1].p0[0]) /2, (b[k].p0[1] + b[k+1].p0[1]) /2];
var h = [b[k].p0[1] - b[k+1].p0[1], - b[k].p0[0] + b[k+1].p0[0]];
var c = ol_coordinate_getIntersectionPoint(
[m, [m[0] + h[0], m[1]+ h[1]]],
[b[k].p1, b[k+1].p1]
);
var gradient = ctx.createLinearGradient(
m[0], m[1],
c[0], c[1]
);
gradient.addColorStop(0, 'rgba(255,255,255,.2)');
gradient.addColorStop(1, 'rgba(255,255,255,0)');
ctx.fillStyle = gradient;
ctx.fill();
}
}
break;
}
case "Point": {
var g = build[i].geom;
ctx.beginPath();
ctx.moveTo(g.p0[0], g.p0[1]);
ctx.lineTo(g.p1[0], g.p1[1]);
ctx.stroke();
break;
}
default: break;
}
}
};
export default ol_render3D

View File

@ -6,7 +6,6 @@ import ol_source_Vector from 'ol/source/Vector'
import {tile as ol_loadingstrategy_tile} from 'ol/loadingstrategy'
import {createXYZ as ol_tilegrid_createXYZ} from 'ol/tilegrid'
import ol_format_GeoJSON from 'ol/format/GeoJSON'
import {ol_ext_inherits} from '../util/ext'
import ol_ext_Ajax from '../util/Ajax'
/** A vector source to load WFS at a tile zoom level
@ -24,122 +23,122 @@ import ol_ext_Ajax from '../util/Ajax'
* @param {number} options.featureLimit maximum features in the source before refresh, default Infinity
* @param {boolean} [options.pagination] experimental enable pagination, default no pagination
*/
var ol_source_TileWFS = function (options) {
options = options || {};
if (!options.featureLimit) options.featureLimit = Infinity;
var ol_source_TileWFS = class olsourceTileWFS extends ol_source_Vector {
constructor(options) {
options = options || {}
if (!options.featureLimit) options.featureLimit = Infinity
// Tile loading strategy
var zoom = options.tileZoom || 14;
var sourceOpt = {
strategy: ol_loadingstrategy_tile(ol_tilegrid_createXYZ({ minZoom: zoom, maxZoom: zoom, tileSize:512 }))
};
// Loading params
var format = new ol_format_GeoJSON();
var url = options.url
+ '?service=WFS'
+ '&request=GetFeature'
+ '&version=' + (options.version || '1.1.0')
+ '&typename=' + (options.typeName || '')
+ '&outputFormat=application/json';
if (options.maxFeatures) {
url += '&maxFeatures=' + options.maxFeatures + '&count=' + options.maxFeatures;
}
var loader = { loading: 0, loaded: 0 };
// Loading fn
sourceOpt.loader = function(extent, resolution, projection) {
if (loader.loading === loader.loaded) {
loader.loading = loader.loaded = 0;
if (this.getFeatures().length > options.maxFeatures) {
this.clear();
this.refresh();
}
// Tile loading strategy
var zoom = options.tileZoom || 14
var sourceOpt = {
strategy: ol_loadingstrategy_tile(ol_tilegrid_createXYZ({ minZoom: zoom, maxZoom: zoom, tileSize: 512 }))
}
loader.loading++;
this.dispatchEvent({
type: 'tileloadstart',
loading: loader.loading,
loaded: loader.loaded
});
this._loadTile(url, extent, projection, format, loader);
}
ol_source_Vector.call(this, sourceOpt);
// Loading params
var format = new ol_format_GeoJSON()
var url = options.url
+ '?service=WFS'
+ '&request=GetFeature'
+ '&version=' + (options.version || '1.1.0')
+ '&typename=' + (options.typeName || '')
+ '&outputFormat=application/json'
if (options.maxFeatures) {
url += '&maxFeatures=' + options.maxFeatures + '&count=' + options.maxFeatures
}
this.set('pagination', options.pagination);
};
ol_ext_inherits(ol_source_TileWFS, ol_source_Vector);
var loader = { loading: 0, loaded: 0 }
/**
*
*/
ol_source_TileWFS.prototype._loadTile = function(url, extent, projection, format, loader) {
var req = url
+ '&srsname=' + projection.getCode()
+ '&bbox=' + extent.join(',') + ',' + projection.getCode();
if (this.get('pagination') && !/&startIndex/.test(url)) {
req += '&startIndex=0';
}
ol_ext_Ajax.get({
url: req,
success: function(response) {
loader.loaded++;
if (response.error) {
this.dispatchEvent({
type: 'tileloaderror',
error: response,
loading: loader.loading,
loaded: loader.loaded
});
} else {
// Load features
var features = format.readFeatures(response, {
featureProjection: projection
});
if (features.length > 0) {
this.addFeatures(features);
}
// Next page?
let pos = response.numberReturned || 0;
if (/&startIndex/.test(url)) {
pos += parseInt(url.replace(/.*&startIndex=(\d*).*/, '$1'));
url = url.replace(/&startIndex=(\d*)/, '');
}
// Still something to load ?
if (pos < response.totalFeatures) {
if (!this.get('pagination')) {
this.dispatchEvent({ type: 'overload', total: response.totalFeatures, returned: response.numberReturned });
this.dispatchEvent({
type: 'tileloadend',
loading: loader.loading,
loaded: loader.loaded
});
} else {
url += '&startIndex='+pos;
loader.loaded--;
this._loadTile(url, extent, projection, format, loader);
}
} else {
this.dispatchEvent({
type: 'tileloadend',
loading: loader.loading,
loaded: loader.loaded
});
// Loading fn
sourceOpt.loader = function (extent, resolution, projection) {
if (loader.loading === loader.loaded) {
loader.loading = loader.loaded = 0
if (this.getFeatures().length > options.maxFeatures) {
this.clear()
this.refresh()
}
}
}.bind(this),
error: function(e) {
loader.loaded++;
loader.loading++
this.dispatchEvent({
type: 'tileloaderror',
error: e,
loading: loader.loading,
type: 'tileloadstart',
loading: loader.loading,
loaded: loader.loaded
});
}.bind(this)
})
};
})
this._loadTile(url, extent, projection, format, loader)
}
super(sourceOpt)
this.set('pagination', options.pagination)
}
/**
*
*/
_loadTile(url, extent, projection, format, loader) {
var req = url
+ '&srsname=' + projection.getCode()
+ '&bbox=' + extent.join(',') + ',' + projection.getCode()
if (this.get('pagination') && !/&startIndex/.test(url)) {
req += '&startIndex=0'
}
ol_ext_Ajax.get({
url: req,
success: function (response) {
loader.loaded++
if (response.error) {
this.dispatchEvent({
type: 'tileloaderror',
error: response,
loading: loader.loading,
loaded: loader.loaded
})
} else {
// Load features
var features = format.readFeatures(response, {
featureProjection: projection
})
if (features.length > 0) {
this.addFeatures(features)
}
// Next page?
let pos = response.numberReturned || 0
if (/&startIndex/.test(url)) {
pos += parseInt(url.replace(/.*&startIndex=(\d*).*/, '$1'))
url = url.replace(/&startIndex=(\d*)/, '')
}
// Still something to load ?
if (pos < response.totalFeatures) {
if (!this.get('pagination')) {
this.dispatchEvent({ type: 'overload', total: response.totalFeatures, returned: response.numberReturned })
this.dispatchEvent({
type: 'tileloadend',
loading: loader.loading,
loaded: loader.loaded
})
} else {
url += '&startIndex=' + pos
loader.loaded--
this._loadTile(url, extent, projection, format, loader)
}
} else {
this.dispatchEvent({
type: 'tileloadend',
loading: loader.loading,
loaded: loader.loaded
})
}
}
}.bind(this),
error: function (e) {
loader.loaded++
this.dispatchEvent({
type: 'tileloaderror',
error: e,
loading: loader.loading,
loaded: loader.loaded
})
}.bind(this)
})
}
}
export default ol_source_TileWFS

View File

@ -1,6 +1,6 @@
import ol_source_Vector from 'ol/source/Vector'
(function () {
;(function () {
var clear = ol_source_Vector.prototype.clear;
/** Overwrite ol/source/Vector clear to fire clearstart / clearend event

View File

@ -19,317 +19,312 @@ import {asString as ol_color_asString} from 'ol/color'
* @param {function|string|Number} options.height a height function (returns height giving a feature) or a popertie name for the height or a fixed value
* @param {Array<number>} options.center center of the view, default [.5,1]
*/
var ol_layer_Vector3D = function (options) {
options = options || {};
var ol_layer_Vector3D = class ollayerVector3D extends ol_layer_Image {
constructor(options) {
options = options || {}
this._source = options.source;
this.height_ = this.getHfn (options.height);
var canvas = document.createElement('canvas')
super({
source: new ol_source_ImageCanvas({
canvasFunction: function (extent, resolution, pixelRatio, size /*, projection*/) {
canvas.width = size[0]
canvas.height = size[1]
return canvas
}
}),
center: options.center || [.5, 1],
defaultHeight: options.defaultHeight || 0,
maxResolution: options.maxResolution || Infinity
})
var canvas = document.createElement('canvas');
ol_layer_Image.call (this, {
source: new ol_source_ImageCanvas({
canvasFunction: function(extent, resolution, pixelRatio, size /*, projection*/ ) {
canvas.width = size[0];
canvas.height = size[1];
return canvas;
this._source = options.source
this.height_ = this.getHfn(options.height)
this.setStyle(options.style)
this.on(['postcompose', 'postrender'], this.onPostcompose_.bind(this))
}
/**
* Set the height function for the layer
* @param {function|string|Number} height a height function (returns height giving a feature) or a popertie name or a fixed value
*/
setHeight(height) {
this.height_ = this.getHfn(height)
this.changed()
}
/**
* Set style associated with the layer
* @param {ol.style.Style} s
*/
setStyle(s) {
if (s instanceof ol_style_Style)
this._style = s
else
this._style = new ol_style_Style()
if (!this._style.getStroke()) {
this._style.setStroke(new ol_style_Stroke({
width: 1,
color: 'red'
}))
}
if (!this._style.getFill()) {
this._style.setFill(new ol_style_Fill({ color: 'rgba(0,0,255,0.5)' }))
}
if (!this._style.getText()) {
this._style.setText(new ol_style_Fill({
color: 'red'
})
)
}
// Get the geometry
if (s && s.getGeometry()) {
var geom = s.getGeometry()
if (typeof (geom) === 'function') {
this.set('geometry', geom)
} else {
this.set('geometry', function () { return geom })
}
}),
center: options.center || [.5,1],
defaultHeight: options.defaultHeight || 0,
maxResolution: options.maxResolution || Infinity
});
this.setStyle(options.style);
this.on (['postcompose', 'postrender'], this.onPostcompose_.bind(this));
}
ol_ext_inherits(ol_layer_Vector3D, ol_layer_Image);
/**
* Set the height function for the layer
* @param {function|string|Number} height a height function (returns height giving a feature) or a popertie name or a fixed value
*/
ol_layer_Vector3D.prototype.setHeight = function(height) {
this.height_ = this.getHfn (height);
this.changed();
};
/**
* Set style associated with the layer
* @param {ol.style.Style} s
*/
ol_layer_Vector3D.prototype.setStyle = function(s) {
if (s instanceof ol_style_Style) this._style = s;
else this._style = new ol_style_Style();
if (!this._style.getStroke()) {
this._style.setStroke(new ol_style_Stroke({
width: 1,
color: 'red'
}));
}
if (!this._style.getFill()) {
this._style.setFill( new ol_style_Fill({ color: 'rgba(0,0,255,0.5)'}) );
}
if (!this._style.getText()) {
this._style.setText( new ol_style_Fill({
color: 'red'})
);
}
// Get the geometry
if (s && s.getGeometry()) {
var geom = s.getGeometry();
if (typeof(geom)==='function') {
this.set('geometry', geom);
} else {
this.set('geometry', function() { return geom; });
}
} else {
this.set('geometry', function(f) { return f.getGeometry(); });
}
};
/**
* Get style associated with the layer
* @return {ol.style.Style}
*/
ol_layer_Vector3D.prototype.getStyle = function() {
return this._style;
};
/** Calculate 3D at potcompose
* @private
*/
ol_layer_Vector3D.prototype.onPostcompose_ = function(e) {
var res = e.frameState.viewState.resolution;
if (res > this.get('maxResolution')) return;
this.res_ = res*400;
if (this.animate_) {
var elapsed = e.frameState.time - this.animate_;
if (elapsed < this.animateDuration_) {
this.elapsedRatio_ = this.easing_(elapsed / this.animateDuration_);
// tell OL3 to continue postcompose animation
e.frameState.animate = true;
} else {
this.animate_ = false;
this.height_ = this.toHeight_
this.set('geometry', function (f) { return f.getGeometry() })
}
}
var ratio = e.frameState.pixelRatio;
var ctx = e.context;
var m = this.matrix_ = e.frameState.coordinateToPixelTransform;
// Old version (matrix)
if (!m) {
m = e.frameState.coordinateToPixelMatrix,
m[2] = m[4];
m[3] = m[5];
m[4] = m[12];
m[5] = m[13];
/**
* Get style associated with the layer
* @return {ol.style.Style}
*/
getStyle() {
return this._style
}
this.center_ = [
ctx.canvas.width*this.get('center')[0]/ratio,
ctx.canvas.height*this.get('center')[1]/ratio
];
/** Calculate 3D at potcompose
* @private
*/
onPostcompose_(e) {
var res = e.frameState.viewState.resolution
if (res > this.get('maxResolution'))
return
this.res_ = res * 400
var f = this._source.getFeaturesInExtent(e.frameState.extent);
ctx.save();
ctx.scale(ratio,ratio);
var s = this.getStyle();
ctx.lineWidth = s.getStroke().getWidth();
ctx.lineCap = s.getStroke().getLineCap();
ctx.strokeStyle = ol_color_asString(s.getStroke().getColor());
ctx.fillStyle = ol_color_asString(s.getFill().getColor());
var builds = [];
for (var i=0; i<f.length; i++) {
builds.push (this.getFeature3D_ (f[i], this._getFeatureHeight(f[i])));
}
this.drawFeature3D_ (ctx, builds);
ctx.restore();
};
/** Create a function that return height of a feature
* @param {function|string|number} h a height function or a popertie name or a fixed value
* @return {function} function(f) return height of the feature f
* @private
*/
ol_layer_Vector3D.prototype.getHfn= function(h) {
switch (typeof(h)) {
case 'function': return h;
case 'string': {
var dh = this.get('defaultHeight');
return (function(f) {
return (Number(f.get(h)) || dh);
});
if (this.animate_) {
var elapsed = e.frameState.time - this.animate_
if (elapsed < this.animateDuration_) {
this.elapsedRatio_ = this.easing_(elapsed / this.animateDuration_)
// tell OL3 to continue postcompose animation
e.frameState.animate = true
} else {
this.animate_ = false
this.height_ = this.toHeight_
}
case 'number': return (function(/*f*/) { return h; });
default: return (function(/*f*/) { return 10; });
}
};
}
/** Animate rendering
* @param {*} options
* @param {string|function|number} options.height an attribute name or a function returning height of a feature or a fixed value
* @param {number} options.duration the duration of the animatioin ms, default 1000
* @param {ol.easing} options.easing an ol easing function
* @api
*/
ol_layer_Vector3D.prototype.animate = function(options) {
options = options || {};
this.toHeight_ = this.getHfn(options.height);
this.animate_ = new Date().getTime();
this.animateDuration_ = options.duration ||1000;
this.easing_ = options.easing || ol_easing_easeOut;
// Force redraw
this.changed();
};
/** Check if animation is on
* @return {bool}
*/
ol_layer_Vector3D.prototype.animating = function() {
if (this.animate_ && new Date().getTime() - this.animate_ > this.animateDuration_) {
this.animate_ = false;
}
return !!this.animate_;
}
/** Get height for a feature
* @param {ol.Feature} f
* @return {number}
* @private
*/
ol_layer_Vector3D.prototype._getFeatureHeight = function (f) {
if (this.animate_) {
var h1 = this.height_(f);
var h2 = this.toHeight_(f);
return (h1*(1-this.elapsedRatio_)+this.elapsedRatio_*h2);
}
else return this.height_(f);
};
/** Get hvector for a point
* @private
*/
ol_layer_Vector3D.prototype.hvector_ = function (pt, h) {
var p0 = [
pt[0]*this.matrix_[0] + pt[1]*this.matrix_[1] + this.matrix_[4],
pt[0]*this.matrix_[2] + pt[1]*this.matrix_[3] + this.matrix_[5]
];
return {
p0: p0,
p1: [
p0[0] + h/this.res_ * (p0[0]-this.center_[0]),
p0[1] + h/this.res_ * (p0[1]-this.center_[1])
var ratio = e.frameState.pixelRatio
var ctx = e.context
var m = this.matrix_ = e.frameState.coordinateToPixelTransform
// Old version (matrix)
if (!m) {
m = e.frameState.coordinateToPixelMatrix,
m[2] = m[4]
m[3] = m[5]
m[4] = m[12]
m[5] = m[13]
}
this.center_ = [
ctx.canvas.width * this.get('center')[0] / ratio,
ctx.canvas.height * this.get('center')[1] / ratio
]
};
};
/** Get a vector 3D for a feature
* @private
*/
ol_layer_Vector3D.prototype.getFeature3D_ = function (f, h) {
var geom = this.get('geometry')(f);
var c = geom.getCoordinates();
switch (geom.getType()) {
case "Polygon":
c = [c];
// fallthrough
case "MultiPolygon":
var build = [];
for (var i=0; i<c.length; i++) {
for (var j=0; j<c[i].length; j++) {
var b = [];
for (var k=0; k<c[i][j].length; k++) {
b.push( this.hvector_(c[i][j][k], h) );
}
build.push(b);
}
}
return { type:"MultiPolygon", feature: f, geom: build };
case "Point":
return { type:"Point", feature: f, geom: this.hvector_(c,h) };
default: return {};
var f = this._source.getFeaturesInExtent(e.frameState.extent)
ctx.save()
ctx.scale(ratio, ratio)
var s = this.getStyle()
ctx.lineWidth = s.getStroke().getWidth()
ctx.lineCap = s.getStroke().getLineCap()
ctx.strokeStyle = ol_color_asString(s.getStroke().getColor())
ctx.fillStyle = ol_color_asString(s.getFill().getColor())
var builds = []
for (var i = 0; i < f.length; i++) {
builds.push(this.getFeature3D_(f[i], this._getFeatureHeight(f[i])))
}
this.drawFeature3D_(ctx, builds)
ctx.restore()
}
};
/** Draw 3D feature
* @private
*/
ol_layer_Vector3D.prototype.drawFeature3D_ = function(ctx, build) {
var i,j, b, k;
// Construct
for (i=0; i<build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j=0; j<build[i].geom.length; j++) {
b = build[i].geom[j];
for (k=0; k < b.length; k++) {
ctx.beginPath();
ctx.moveTo(b[k].p0[0], b[k].p0[1]);
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
ctx.stroke();
}
}
break;
/** Create a function that return height of a feature
* @param {function|string|number} h a height function or a popertie name or a fixed value
* @return {function} function(f) return height of the feature f
* @private
*/
getHfn(h) {
switch (typeof (h)) {
case 'function': return h
case 'string': {
var dh = this.get('defaultHeight')
return (function (f) {
return (Number(f.get(h)) || dh)
})
}
case "Point": {
var g = build[i].geom;
ctx.beginPath();
ctx.moveTo(g.p0[0], g.p0[1]);
ctx.lineTo(g.p1[0], g.p1[1]);
ctx.stroke();
break;
}
default: break;
case 'number': return (function ( /*f*/) { return h })
default: return (function ( /*f*/) { return 10 })
}
}
// Roof
for (i=0; i<build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
ctx.beginPath();
for (j=0; j<build[i].geom.length; j++) {
b = build[i].geom[j];
if (j==0) {
ctx.moveTo(b[0].p1[0], b[0].p1[1]);
for (k=1; k < b.length; k++) {
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
}
} else {
ctx.moveTo(b[0].p1[0], b[0].p1[1]);
for (k=b.length-2; k>=0; k--) {
ctx.lineTo(b[k].p1[0], b[k].p1[1]);
}
}
ctx.closePath();
}
ctx.fill("evenodd");
ctx.stroke();
break;
}
case "Point": {
b = build[i];
var t = b.feature.get('label');
if (t) {
var p = b.geom.p1;
var m = ctx.measureText(t);
var h = Number (ctx.font.match(/\d+(\.\d+)?/g).join([]));
ctx.fillRect (p[0]-m.width/2 -5, p[1]-h -5, m.width +10, h +10)
ctx.strokeRect (p[0]-m.width/2 -5, p[1]-h -5, m.width +10, h +10)
ctx.save()
ctx.fillStyle = ol_color_asString(this._style.getText().getFill().getColor());
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText ( t, p[0], p[1] );
ctx.restore();
}
break;
}
default: break;
/** Animate rendering
* @param {*} options
* @param {string|function|number} options.height an attribute name or a function returning height of a feature or a fixed value
* @param {number} options.duration the duration of the animatioin ms, default 1000
* @param {ol.easing} options.easing an ol easing function
* @api
*/
animate(options) {
options = options || {}
this.toHeight_ = this.getHfn(options.height)
this.animate_ = new Date().getTime()
this.animateDuration_ = options.duration || 1000
this.easing_ = options.easing || ol_easing_easeOut
// Force redraw
this.changed()
}
/** Check if animation is on
* @return {bool}
*/
animating() {
if (this.animate_ && new Date().getTime() - this.animate_ > this.animateDuration_) {
this.animate_ = false
}
return !!this.animate_
}
/** Get height for a feature
* @param {ol.Feature} f
* @return {number}
* @private
*/
_getFeatureHeight(f) {
if (this.animate_) {
var h1 = this.height_(f)
var h2 = this.toHeight_(f)
return (h1 * (1 - this.elapsedRatio_) + this.elapsedRatio_ * h2)
}
else
return this.height_(f)
}
/** Get hvector for a point
* @private
*/
hvector_(pt, h) {
var p0 = [
pt[0] * this.matrix_[0] + pt[1] * this.matrix_[1] + this.matrix_[4],
pt[0] * this.matrix_[2] + pt[1] * this.matrix_[3] + this.matrix_[5]
]
return {
p0: p0,
p1: [
p0[0] + h / this.res_ * (p0[0] - this.center_[0]),
p0[1] + h / this.res_ * (p0[1] - this.center_[1])
]
}
}
};
/** Get a vector 3D for a feature
* @private
*/
getFeature3D_(f, h) {
var geom = this.get('geometry')(f)
var c = geom.getCoordinates()
switch (geom.getType()) {
case "Polygon":
c = [c]
// fallthrough
case "MultiPolygon":
var build = []
for (var i = 0; i < c.length; i++) {
for (var j = 0; j < c[i].length; j++) {
var b = []
for (var k = 0; k < c[i][j].length; k++) {
b.push(this.hvector_(c[i][j][k], h))
}
build.push(b)
}
}
return { type: "MultiPolygon", feature: f, geom: build }
case "Point":
return { type: "Point", feature: f, geom: this.hvector_(c, h) }
default: return {}
}
}
/** Draw 3D feature
* @private
*/
drawFeature3D_(ctx, build) {
var i, j, b, k
// Construct
for (i = 0; i < build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
for (j = 0; j < build[i].geom.length; j++) {
b = build[i].geom[j]
for (k = 0; k < b.length; k++) {
ctx.beginPath()
ctx.moveTo(b[k].p0[0], b[k].p0[1])
ctx.lineTo(b[k].p1[0], b[k].p1[1])
ctx.stroke()
}
}
break
}
case "Point": {
var g = build[i].geom
ctx.beginPath()
ctx.moveTo(g.p0[0], g.p0[1])
ctx.lineTo(g.p1[0], g.p1[1])
ctx.stroke()
break
}
default: break
}
}
// Roof
for (i = 0; i < build.length; i++) {
switch (build[i].type) {
case "MultiPolygon": {
ctx.beginPath()
for (j = 0; j < build[i].geom.length; j++) {
b = build[i].geom[j]
if (j == 0) {
ctx.moveTo(b[0].p1[0], b[0].p1[1])
for (k = 1; k < b.length; k++) {
ctx.lineTo(b[k].p1[0], b[k].p1[1])
}
} else {
ctx.moveTo(b[0].p1[0], b[0].p1[1])
for (k = b.length - 2; k >= 0; k--) {
ctx.lineTo(b[k].p1[0], b[k].p1[1])
}
}
ctx.closePath()
}
ctx.fill("evenodd")
ctx.stroke()
break
}
case "Point": {
b = build[i]
var t = b.feature.get('label')
if (t) {
var p = b.geom.p1
var m = ctx.measureText(t)
var h = Number(ctx.font.match(/\d+(\.\d+)?/g).join([]))
ctx.fillRect(p[0] - m.width / 2 - 5, p[1] - h - 5, m.width + 10, h + 10)
ctx.strokeRect(p[0] - m.width / 2 - 5, p[1] - h - 5, m.width + 10, h + 10)
ctx.save()
ctx.fillStyle = ol_color_asString(this._style.getText().getFill().getColor())
ctx.textAlign = 'center'
ctx.textBaseline = 'bottom'
ctx.fillText(t, p[0], p[1])
ctx.restore()
}
break
}
default: break
}
}
}
}
export default ol_layer_Vector3D

View File

@ -1,6 +1,5 @@
import ol_Object from 'ol/Object';
import ol_ext_element from '../element'
import ol_ext_inherits from '../ext';
/** A list element synchronize with a Collection.
* Element in the list can be reordered interactively and the associated Collection is kept up to date.
@ -14,156 +13,152 @@ import ol_ext_inherits from '../ext';
* @param {Collection} [options.collection] the collection to display in the list
* @param {function} [options.getTitle] a function that takes a collection item and returns an Element or a string
*/
var ol_ext_input_Collection = function(options) {
ol_Object.call(this);
this.element = ol_ext_element.create('UL', {
className: ('ol-collection-list '+(options.className||'')).trim(),
parent: options.target
})
this._title = (typeof(options.getTitle) === 'function' ? options.getTitle : function(elt) { return elt.title });
this.setCollection(options.collection);
};
ol_ext_inherits(ol_ext_input_Collection, ol_Object);
/** Remove current collection (listeners)
* /!\ remove collection when input list is removed from the DOM
*/
ol_ext_input_Collection.prototype.removeCollection = function() {
if (this.collection) {
this.collection.un('change:length', this._update);
this.collection = null;
var ol_ext_input_Collection = class olextinputCollection extends ol_Object {
constructor(options) {
super();
this.element = ol_ext_element.create('UL', {
className: ('ol-collection-list ' + (options.className || '')).trim(),
parent: options.target
});
this._title = (typeof (options.getTitle) === 'function' ? options.getTitle : function (elt) { return elt.title; });
this.setCollection(options.collection);
}
}
/** Set the collection
* @param {ol_Collection} collection
*/
ol_ext_input_Collection.prototype.setCollection = function(collection) {
this.removeCollection();
this.collection = collection;
this.refresh();
if (this.collection) {
this._update = function() {
if (!this._reorder) {
this.refresh();
var pos = this.getSelectPosition();
if (pos < 0) {
this.dispatchEvent({ type: 'item:select', position: -1, item: null });
} else {
this.dispatchEvent({ type: 'item:order', position: pos, item: this._currentItem });
}
}
}.bind(this);
this.collection.on('change:length', this._update);
}
}
/** Select an item
* @param {*} item
*/
ol_ext_input_Collection.prototype.select = function(item) {
if (item === this._currentItem) return;
var pos = -1;
this._listElt.forEach(function (l, i) {
if (l.item !== item) {
l.li.classList.remove('ol-select');
} else {
l.li.classList.add('ol-select');
pos = i;
/** Remove current collection (listeners)
* /!\ remove collection when input list is removed from the DOM
*/
removeCollection() {
if (this.collection) {
this.collection.un('change:length', this._update);
this.collection = null;
}
})
this._currentItem = (pos >= 0 ? item : null);
this.dispatchEvent({ type: 'item:select', position: pos, item: this._currentItem });
};
/** Select an item at
* @param {number} n
*/
ol_ext_input_Collection.prototype.selectAt = function(n) {
this.select(this.collection.item(n));
};
/** Get current selection
* @returns {*}
*/
ol_ext_input_Collection.prototype.getSelect = function() {
return this._currentItem;
};
/** Get current selection
* @returns {number}
*/
ol_ext_input_Collection.prototype.getSelectPosition = function() {
if (!this.collection) return -1;
return this.collection.getArray().indexOf(this._currentItem);
};
/** Redraw the list
*/
ol_ext_input_Collection.prototype.refresh = function() {
this.element.innerHTML = '';
this._listElt = [];
if (!this.collection) return;
this.collection.forEach((item, pos) => {
var li = ol_ext_element.create('LI', {
html: this._title(item),
className: this._currentItem === item ? 'ol-select' : '',
'data-position': pos,
on: {
click: function() {
this.select(item);
}.bind(this),
dblclick: function() {
this.dispatchEvent({ type: 'item:dblclick', position: pos, item: item });
}.bind(this),
},
parent: this.element
});
this._listElt.push({ li: li, item: item });
var order = ol_ext_element.create('DIV', {
className: 'ol-noscroll ol-order',
parent: li
});
var current = pos;
var move = function(e) {
// Get target
var target = e.pointerType==='touch' ? document.elementFromPoint(e.clientX, e.clientY) : e.target;
while (target && target.parentNode !== this.element) {
target = target.parentNode;
}
if (target && target !== li) {
var over = parseInt(target.getAttribute('data-position'));
if (target.getAttribute('data-position') < current) {
target.insertAdjacentElement('beforebegin', li);
current = over;
} else {
target.insertAdjacentElement('afterend', li);
current = over+1;
}
/** Set the collection
* @param {ol_Collection} collection
*/
setCollection(collection) {
this.removeCollection();
this.collection = collection;
this.refresh();
if (this.collection) {
this._update = function () {
if (!this._reorder) {
this.refresh();
var pos = this.getSelectPosition();
if (pos < 0) {
this.dispatchEvent({ type: 'item:select', position: -1, item: null });
} else {
this.dispatchEvent({ type: 'item:order', position: pos, item: this._currentItem });
}
}
}.bind(this);
this.collection.on('change:length', this._update);
}
}
/** Select an item
* @param {*} item
*/
select(item) {
if (item === this._currentItem)
return;
var pos = -1;
this._listElt.forEach(function (l, i) {
if (l.item !== item) {
l.li.classList.remove('ol-select');
} else {
l.li.classList.add('ol-select');
pos = i;
}
}.bind(this);
var stop = function() {
document.removeEventListener('pointermove', move);
document.removeEventListener('pointerup', stop);
document.removeEventListener('pointercancel', stop);
if (current !== pos) {
this._reorder = true;
this.collection.removeAt(pos);
this.collection.insertAt(current>pos ? current-1 : current, item);
this._reorder = false;
this.dispatchEvent({ type: 'item:order', position: current>pos ? current-1 : current, oldPosition: pos, item: item })
this.refresh();
}
}.bind(this);
order.addEventListener('pointerdown', function() {
this.select(item)
document.addEventListener('pointermove', move);
document.addEventListener('pointerup', stop)
document.addEventListener('pointercancel', stop)
}.bind(this));
});
});
this._currentItem = (pos >= 0 ? item : null);
this.dispatchEvent({ type: 'item:select', position: pos, item: this._currentItem });
}
/** Select an item at
* @param {number} n
*/
selectAt(n) {
this.select(this.collection.item(n));
}
/** Get current selection
* @returns {*}
*/
getSelect() {
return this._currentItem;
}
/** Get current selection
* @returns {number}
*/
getSelectPosition() {
if (!this.collection)
return -1;
return this.collection.getArray().indexOf(this._currentItem);
}
/** Redraw the list
*/
refresh() {
this.element.innerHTML = '';
this._listElt = [];
if (!this.collection)
return;
this.collection.forEach((item, pos) => {
var li = ol_ext_element.create('LI', {
html: this._title(item),
className: this._currentItem === item ? 'ol-select' : '',
'data-position': pos,
on: {
click: function () {
this.select(item);
}.bind(this),
dblclick: function () {
this.dispatchEvent({ type: 'item:dblclick', position: pos, item: item });
}.bind(this),
},
parent: this.element
});
this._listElt.push({ li: li, item: item });
var order = ol_ext_element.create('DIV', {
className: 'ol-noscroll ol-order',
parent: li
});
var current = pos;
var move = function (e) {
// Get target
var target = e.pointerType === 'touch' ? document.elementFromPoint(e.clientX, e.clientY) : e.target;
while (target && target.parentNode !== this.element) {
target = target.parentNode;
}
if (target && target !== li) {
var over = parseInt(target.getAttribute('data-position'));
if (target.getAttribute('data-position') < current) {
target.insertAdjacentElement('beforebegin', li);
current = over;
} else {
target.insertAdjacentElement('afterend', li);
current = over + 1;
}
}
}.bind(this);
var stop = function () {
document.removeEventListener('pointermove', move);
document.removeEventListener('pointerup', stop);
document.removeEventListener('pointercancel', stop);
if (current !== pos) {
this._reorder = true;
this.collection.removeAt(pos);
this.collection.insertAt(current > pos ? current - 1 : current, item);
this._reorder = false;
this.dispatchEvent({ type: 'item:order', position: current > pos ? current - 1 : current, oldPosition: pos, item: item });
this.refresh();
}
}.bind(this);
order.addEventListener('pointerdown', function () {
this.select(item);
document.addEventListener('pointermove', move);
document.addEventListener('pointerup', stop);
document.addEventListener('pointercancel', stop);
}.bind(this));
});
}
}
export default ol_ext_input_Collection

View File

@ -4,37 +4,39 @@
* - source: the window source (undefined if first window)
*/
if (!window.WSynchro) {
var WSynchro = { windows: [] };
var WSynchro = { windows: [] };
alert ('noSynch')
}
/** Open a new window to synchronize
* @param {url|undefined} url to open, default current window url
* @param {specs|undefined|null} specs (as for window.open), undefined to open in a new window, null to open in a new tab, default new window
*/
WSynchro.open = function (href, specs)
{ var w = window.open (href || window.location.href, "_blank", typeof(specs)=="undefined"? "location=1,menubar=1,toolbar=1,scrollbars=1" : specs);
if (!w.WSynchro) w.WSynchro = { windows: [ window ], source:window };
else
{ w.WSynchro.windows = [ window ];
w.WSynchro.source = window;
}
this.windows.push(w);
WSynchro.open = function (href, specs) {
var w = window.open (href || window.location.href, "_blank", typeof(specs)=="undefined"? "location=1,menubar=1,toolbar=1,scrollbars=1" : specs);
if (!w.WSynchro) {
w.WSynchro = { windows: [ window ], source:window };
} else {
w.WSynchro.windows = [ window ];
w.WSynchro.source = window;
}
this.windows.push(w);
}
/** Trigger function
* @param {synchronize}
* @param {function} synchronize function
*/
WSynchro.on = function (e, syncFn)
{ if (!this.syncFn_) this.syncFn_ = [];
if (e==='synchronize') this.syncFn_.push(syncFn);
WSynchro.on = function (e, syncFn) {
if (!this.syncFn_) this.syncFn_ = [];
if (e==='synchronize') this.syncFn_.push(syncFn);
}
/** Synchronize windows
* @param {Object|undefined} if undefined stop synchro (when the window is synchronize)
*/
WSynchro.synchronize = function(params)
{ this.synchronize_ (params);
WSynchro.synchronize = function(params) {
this.synchronize_ (params);
}
/** Synchronize windows:
@ -43,30 +45,31 @@ WSynchro.synchronize = function(params)
* @private
*/
WSynchro.synchronize_ = function(args, sync) {
var i;
// Stop condition
if (!sync)
{ if (this.synchronizing) sync = this.sync;
else this.sync = sync = (new Date()).getTime();
this.synchronizing = false;
}
else
{ // Don't synchronize twice
if (sync == this.sync) return;
this.sync = sync;
this.synchronizing = true;
try
{ if (WSynchro.syncFn_)
{ args.type = "synchronize";
for (i=0; i<WSynchro.syncFn_.length; i++)
{ WSynchro.syncFn_[i].apply (null, [args]);
}
}
} catch(e) { /* */ }
}
if (args) for (i=0; i<this.windows.length; i++)
{ try
{ this.windows[i].WSynchro.synchronize_(args, sync);
} catch(e) { /* */ }
}
var i;
// Stop condition
if (!sync) {
if (this.synchronizing) sync = this.sync;
else this.sync = sync = (new Date()).getTime();
this.synchronizing = false;
} else {
// Don't synchronize twice
if (sync == this.sync) return;
this.sync = sync;
this.synchronizing = true;
try {
if (WSynchro.syncFn_) {
args.type = "synchronize";
for (i=0; i<WSynchro.syncFn_.length; i++) {
WSynchro.syncFn_[i].apply (null, [args]);
}
}
} catch(e) { /* */ }
}
if (args) {
for (i=0; i<this.windows.length; i++){
try {
this.windows[i].WSynchro.synchronize_(args, sync);
} catch(e) { /* */ }
}
}
}