").addClass("track-info").appendTo(t);
$("").html((this.info.zmin||"Zmin")+': ').appendTo(tr);
$(" | ").html((this.info.zmax||"Zmax")+': ').appendTo(tr);
$(" | ").html((this.info.distance||"Distance")+': ').appendTo(tr);
$(" | ").html((this.info.time||"Time")+': ').appendTo(tr);
tr = $("").addClass("point-info").appendTo(t);
$("").html((this.info.altitude||"Altitude")+': ').appendTo(tr);
$(" | ").html((this.info.distance||"Distance")+': ').appendTo(tr);
$(" | ").html((this.info.time||"Time")+': ').appendTo(tr);
// Array of data
this.tab_ = [];
// Show feature
if (options.feature)
{ this.setGeometry (options.feature);
}
};
ol.inherits(ol.control.Profil, ol.control.Control);
/** Custom infos list
* @api stable
*/
ol.control.Profil.prototype.info =
{ "zmin": "Zmin",
"zmax": "Zmax",
"ytitle": "Altitude (m)",
"xtitle": "Distance (km)",
"time": "Time",
"altitude": "Altitude",
"distance": "Distance"
};
/** Show popup info
* @param {string} info to display as a popup
* @api stable
*/
ol.control.Profil.prototype.popup = function(info)
{ this.popup_.html(info);
}
/** Mouse move over canvas
*/
ol.control.Profil.prototype.onMove = function(e)
{ if (!this.tab_.length) return;
var pos = $(this.canvas_).offset();
var dx = e.pageX -pos.left;
var dy = e.pageY -pos.top;
var ratio = this.ratio;
if (dx>this.margin_.left/ratio && dx<(this.canvas_.width-this.margin_.right)/ratio
&& dy>this.margin_.top/ratio && dy<(this.canvas_.height-this.margin_.bottom)/ratio)
{ this.bar_.css("left", dx+"px").show();
var d = (dx*ratio-this.margin_.left)/this.scale_[0];
var p0 = this.tab_[0];
for (var i=1, p; p=this.tab_[i]; i++)
{ if (p[0]>=d)
{ if (d < (p[0]+p0[0])/2) p = p0;
break;
}
}
if (p) this.cursor_.css({
left:dx+"px",
top:(this.canvas_.height-this.margin_.bottom+p[1]*this.scale_[1]+this.dy_)/ratio+"px"
}).show();
else this.cursor_.hide();
this.bar_.parent().addClass("over");
$(".point-info .z", this.element).text(p[1]+"m");
$(".point-info .dist", this.element).text((p[0]/1000).toFixed(1)+"km");
$(".point-info .time", this.element).text(p[2]);
if (dx>this.canvas_.width/ratio/2) this.popup_.addClass('ol-left');
else this.popup_.removeClass('ol-left');
this.dispatchEvent({ type:'over', click:e.type=="click", coord: p[3], time: p[2], distance: p[0] });
}
else
{ if (this.bar_.parent().hasClass("over"))
{ this.bar_.hide();
this.cursor_.hide();
this.bar_.parent().removeClass("over");
this.dispatchEvent({ type:'out' });
}
}
}
/** Show panel
* @api stable
*/
ol.control.Profil.prototype.show = function()
{ $(this.element).removeClass("ol-collapsed");
this.dispatchEvent({ type:'show', show: true });
}
/** Hide panel
* @api stable
*/
ol.control.Profil.prototype.hide = function()
{ $(this.element).addClass("ol-collapsed");
this.dispatchEvent({ type:'show', show: false });
}
/** Toggle panel
* @api stable
*/
ol.control.Profil.prototype.toggle = function()
{ var b = $(this.element).toggleClass("ol-collapsed").hasClass("ol-collapsed");
this.dispatchEvent({ type:'show', show: !b });
}
/** Is panel visible
*/
ol.control.Profil.prototype.isShown = function()
{ return (!$(this.element).hasClass("ol-collapsed"));
}
/**
* Set the geometry to draw the profil.
* @param {ol.Feature|ol.geom} f the feature.
* @param {Object=} options
* - projection {ol.ProjectionLike} feature projection, default projection of the map
* - zunit {m|km} default m
* - unit {m|km} default km
* - zmin {Number|undefined} default 0
* - zmax {Number|undefined} default max Z of the feature
* - graduation {Number|undefined} z graduation default 100
* - amplitude {integer|undefined} amplitude of the altitude, default zmax-zmin
* @api stable
*/
ol.control.Profil.prototype.setGeometry = function(g, options)
{ if (!options) options = {};
if (g instanceof ol.Feature) g = g.getGeometry();
var canvas = this.canvas_;
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0, w, h);
// No Z
if (!/Z/.test(g.getLayout())) return;
// No time
if(/M/.test(g.getLayout())) $(".time", this.element).parent().show();
else $(".time", this.element).parent().hide();
// Coords
var c = g.getCoordinates();
switch (g.getType())
{ case "LineString": break;
case "MultiLineString": c = c[0]; break;
default: return;
}
// Distance beetween 2 coords
var wgs84Sphere = new ol.Sphere(6378137);
var proj = options.projection || this.getMap().getView().getProjection();
function dist2d(p1,p2)
{ return wgs84Sphere.haversineDistance(
ol.proj.transform(p1, proj, 'EPSG:4326'),
ol.proj.transform(p2, proj, 'EPSG:4326'));
}
function getTime(t0, t1)
{ if (!t0 || !t1) return "-"
var dt = (t1-t0) / 60; // mn
var ti = Math.trunc(dt/60);
var mn = Math.trunc(dt-ti*60);
return ti+"h"+(mn<10?"0":"")+mn+"mn";
}
// Margin
ctx.setTransform(1, 0, 0, 1, this.margin_.left, h-this.margin_.bottom);
var ratio = this.ratio;
w -= this.margin_.right + this.margin_.left;
h -= this.margin_.top + this.margin_.bottom;
// Draw axes
ctx.strokeStyle = "#000";
ctx.lineWidth = 0.5*ratio;
ctx.beginPath();
ctx.moveTo(0,0); ctx.lineTo(0,-h);
ctx.moveTo(0,0); ctx.lineTo(w, 0);
ctx.stroke();
//
var zmin=Infinity, zmax=-Infinity;
var d, z, ti, t = this.tab_ = [];
for (var i=0, p; p=c[i]; i++)
{ z = p[2];
if (zzmax) zmax=z;
if (i==0) d = 0;
else d += dist2d(c[i-1], p);
ti = getTime(c[0][3],p[3]);
t.push ([d, z, ti, p]);
}
// Info
$(".track-info .zmin", this.element).text(zmin.toFixed(2)+"m");
$(".track-info .zmax", this.element).text(zmax.toFixed(2)+"m");
if (d>1000)
{ $(".track-info .dist", this.element).text((d/1000).toFixed(1)+"km");
}
else
{ $(".track-info .dist", this.element).text((d).toFixed(1)+"m");
}
$(".track-info .time", this.element).text(ti);
// Set graduation
var grad = options.graduation || 100;
while (true)
{ zmax = Math.ceil(zmax/grad)*grad;
zmin = Math.floor(zmin/grad)*grad;
var nbgrad = (zmax-zmin)/grad;
if (h/nbgrad < 15*ratio)
{ grad *= 2;
}
else break;
}
// Set amplitude
if (typeof(options.zmin)=='number' && zmin > options.zmin) zmin = options.zmin;
if (typeof(options.zmax)=='number' && zmax < options.zmax) zmax = options.zmax;
var amplitude = options.amplitude;
if (amplitude)
{ zmax = Math.max (zmin + amplitude, zmax);
}
// Scales lines
var scx = w/d;
var scy = -h/(zmax-zmin);
var dy = this.dy_ = -zmin*scy;
this.scale_ = [scx,scy];
// Draw
ctx.font = (10*ratio)+"px arial";
ctx.textAlign = "right";
ctx.textBaseline = "middle";
ctx.fillStyle="#000";
// Scale Z
ctx.beginPath();
for (var i=zmin; i<=zmax; i+=grad)
{ if (options.zunit!="km") ctx.fillText(i, -4*ratio, i*scy+dy);
else ctx.fillText((i/1000).toFixed(1), -4*ratio, i*scy+dy);
ctx.moveTo (-2*ratio, i*scy+dy);
if (i!=0) ctx.lineTo (d*scx, i*scy+dy);
else ctx.lineTo (0, i*scy+dy);
}
// Scale X
ctx.textAlign = "center";
ctx.textBaseline = "top";
ctx.setLineDash([ratio,3*ratio]);
var unit = options.unit ||"km";
var step;
if (d>1000)
{ step = Math.round(d/1000)*100;
if (step > 1000) step = Math.ceil(step/1000)*1000;
}
else
{ unit = "m";
if (d>100) step = Math.round(d/100)*10;
else if (d>10) step = Math.round(d/10);
else if (d>1) step = Math.round(d)/10;
else step = d;
}
for (var i=0; i<=d; i+=step)
{ var txt = (unit=="m") ? i : (i/1000);
//if (i+step>d) txt += " "+ (options.zunits || "km");
ctx.fillText(Math.round(txt*10)/10, i*scx, 4*ratio);
ctx.moveTo (i*scx, 2*ratio); ctx.lineTo (i*scx, 0);
}
ctx.font = (12*ratio)+"px arial";
ctx.fillText(this.info.xtitle.replace("(km)","("+unit+")"), w/2, 18*ratio);
ctx.save();
ctx.rotate(-Math.PI/2);
ctx.fillText(this.info.ytitle, h/2, -this.margin_.left);
ctx.restore();
ctx.stroke();
//
ctx.strokeStyle = "#369";
ctx.lineWidth = 1;
ctx.setLineDash([]);
ctx.beginPath();
for (var i=0, p; p=t[i]; i++)
{ if (i==0) ctx.moveTo(p[0]*scx,p[1]*scy+dy);
else ctx.lineTo(p[0]*scx,p[1]*scy+dy);
}
ctx.stroke();
};
/** Get profil image
* @param {string|undefined} type image format or 'canvas' to get the canvas image, default image/png.
* @param {Number|undefined} encoderOptions between 0 and 1 indicating image quality image/jpeg or image/webp, default 0.92.
* @return {string} requested data uri
* @api stable
*/
ol.control.Profil.prototype.getImage = function(type, encoderOptions)
{ if (type==="canvas") return this.canvas_;
return this.canvas_.toDataURL(type, encoderOptions);
}
/* Copyright (c) 2017 Jean-Marc VIGLINO,
released under the CeCILL-B license (French BSD license)
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/
/**
* Search features.
*
* @constructor
* @extends {ol.control.Control}
* @fires select
* @param {Object=} Control options.
* - className {string} control class name
* - target {Element | string | undefined} Specify a target if you want the control to be rendered outside of the map's viewport.
* - placeholder {string | undefined} placeholder, default "Search..."
* - typing {number | undefined} a delay on each typing to start searching (ms), default 300.
* - source {ol.source.Vector} source to search in
* - minLength {integer | undefined} minimum length to start searching, default 1
* - maxItems {integer | undefined} maximum number of items to display in the autocomplete list, default 10
*
* - property {string | function | undefined} a property to display in the index or a function that takes a feature and return the name to display in the index, default 'name'.
* - getSearchString {function | undefined} a function that take a feature and return a text to be used as search string, default property is used as seach string
*/
ol.control.SearchFeature = function(options)
{ var self = this;
if (!options) options = {};
var element;
if (options.target)
{ element = $("").addClass((options.className||"")+ "ol-searchfeature");
}
else
{ element = $(" ").addClass((options.className||"") + 'ol-searchfeature ol-unselectable ol-control ol-collapsed');
this.button = $(" | |