3const char* image_coord_tracker = R
"JS(/* src/js/image_coord_tracker.js */
5function image_coord_tracker(){
7 const elems = document.querySelectorAll(".MOUSE");
9 elems.forEach(panel => {
12 // Plane listening to mouse events
13 const coordTracker = panel.querySelector(".MOUSE_TRACKER");
16 console.error("elem .MOUSE found without child .MOUSE_TRACKER");
20 // var precision = parseInt(coordTracker.getAttribute("data-precision")); // for rect
22 // TODO: direct attr in frame
24 var metadata = panel.querySelector("metadata.SHARED");
25 if (metadata.hasAttribute('EPSG')){
26 epsg = metadata.getAttribute('EPSG');
27 console.info('EPSG='+epsg);
31 const BBOX_KEY='data-bbox';
34 if (coordTracker.hasAttribute(BBOX_KEY)){
35 bbox = coordTracker.getAttribute(BBOX_KEY).split(',');
36 console.log("data-bbox: ", bbox);
39 console.log("No attribute [data-bbox], bbox=", bbox);
44 const m = new CoordHandler(bbox, coordTracker.getBoundingClientRect());
45 m.setPrecision(coordTracker.getAttribute("data-resolution"));
47 const selectionRect = panel.querySelector("rect.SELECTOR");
49 // Collective, to support cross-actions
50 const monitorMove = panel.querySelector('.MONITOR_MOVE');
51 const monitorDown = panel.querySelector('.MONITOR_DOWN');
52 const monitorUp = panel.querySelector('.MONITOR_UP');
53 // Optional (move also the box)
54 const monitorBox = panel.querySelector('.MONITOR_BOX');
58 coordTracker.addEventListener("mousemove", (ev) => {
59 m.readEvent(ev, m.curr);
60 m.update(m.curr, monitorMove);
61 // console.log(m.curr)
62 if (m.drag && selectionRect){
63 m.updateSpan(selectionRect);
66 if (m.curr.x > m.start.x){
67 monitorBox.setAttribute("style", "text-anchor:start");
70 monitorBox.setAttribute("style", "text-anchor:end");
73 if (m.curr.y > m.start.y){
74 monitorBox.setAttribute("transform", "translate(0,+20)"); // retrieve STYLE/ font size?
77 monitorBox.setAttribute("transform", "translate(0,-10)"); // retrieve STYLE/ font size?
87 coordTracker.addEventListener("mousedown", (ev) => {
89 m.readEvent(ev, m.start);
90 m.update(m.start, monitorDown);
91 // Restart drawing, so redraw both corners
94 m.update(m.curr, monitorDown);
98 monitorUp.textContent = '';
101 monitorBox.setAttribute("x", m.start.x);
102 monitorBox.setAttribute("y", m.start.y);
103 if (m.start.x > m.curr.x){
110 if (monitorUp){ // = panel.querySelector('.MONITOR_UP')){
112 coordTracker.addEventListener("mouseup", (ev) => {
113 m.readEvent(ev, m.curr);
114 m.update(m.curr, monitorUp); // needed?
116 console.info([m.start.x, m.start.y, m.curr.x, m.curr.y].join(','));
117 console.info("Array size: ", Math.abs(m.curr.x-m.start.x), ',', Math.abs(m.curr.y-m.start.y));
118 var bb = m.getGeoBBOX();
119 console.info(bb.join(','));
120 console.info("Geo size: ", bb[2]-bb[0], ',', bb[3]-bb[1]);
122 navigator.clipboard.writeText(bb).then(
124 console.info(bb + ' copied to clipboard')
127 console.warn('clipboard write failed')
140 this.left = parseFloat(bbox[0]);
141 this.top = parseFloat(bbox[3]);
142 this.width = parseFloat(bbox[2]) - this.left;
143 this.height = parseFloat(bbox[1]) - this.top;
152Coord2D.prototype.readEvent = function(ev){
153 this.cbox = ev.target.getBoundingClientRect();
154 this.x = ev.clientX - this.cbox.left;
155 this.y = ev.clientY - this.cbox.top;
159// function CoordHandler(coordTracker, bbox){ // , group?
160function CoordHandler(bboxGeo, bboxFrame){ // , group?
162 this.bboxFrame = bboxFrame; // coordTracker.getBoundingClientRect();
163 this.bboxGeo = new BBox(bboxGeo);
166 this.curr = new Coord2D()
167 this.start = new Coord2D()
168 // this.up = new Coord2D()
169 // this.group = group;
170 // this.resolution = 0;
173CoordHandler.prototype.readEvent = function(ev, coords){
174 this.bboxFrame = ev.target.getBoundingClientRect();
175 coords.x = ev.clientX - this.bboxFrame.left;
176 coords.y = ev.clientY - this.bboxFrame.top;
177 if (this.precisionFocus){
178 coords.x = this.precisionFocus*Math.round(coords.x/this.precisionFocus);
179 coords.y = this.precisionFocus*Math.round(coords.y/this.precisionFocus);
183CoordHandler.prototype.update = function(coord, elem){
184 // elem.textContent = this.getPosString(coord.x, coord.y);x
185 elem.textContent = this.getGeoPos(coord.x, coord.y);
188CoordHandler.prototype.updateSpan = function(elem){
189 var width = Math.abs(this.start.x - this.curr.x);
190 var height = Math.abs(this.start.y - this.curr.y);
192 if (this.precisionWidth){
193 width = this.precisionWidth*Math.round(width / this.precisionWidth);
194 height = this.precisionWidth*Math.round(height / this.precisionWidth);
197 if (width && height){
199 elem.setAttribute("x", Math.min(this.start.x, this.curr.x));
200 elem.setAttribute("y", Math.min(this.start.y, this.curr.y));
201 elem.setAttribute("width", width);
202 elem.setAttribute("height", height);
203 console.info("Size: ", width,',',height);
206 elem.setAttribute("x", 0);
207 elem.setAttribute("y", 0);
208 elem.setAttribute("width", 0);
209 elem.setAttribute("height", 0);
210 // console.info('skip update: ', this.start, ' ', this.curr, ' ', this.up)
211 // toggle invisible, or open up
213 //elem.textContent = this.getPosString(coord.x, coord.y);
216CoordHandler.prototype.setPrecision = function(precision){
217 if (typeof(precision) === 'number'){
218 this.precisionFocus = precision;
219 this.precisionWidth = precision;
221 else if (typeof(precision) === 'string'){
222 precision = precision.split(RegExp('[,:]'))
225 console.log("precision: ", precision, "px")
227 switch (precision.length) {
229 this.precisionFocus = parseInt(precision[0]);
230 this.precisionWidth = parseInt(precision[1]);
233 this.precisionFocus = parseInt(precision[0]);
234 this.precisionWidth = this.precisionFocus
237 this.precisionFocus = parseInt(precision[1]);
238 this.precisionWidth = precision;
242CoordHandler.prototype.getRelativeX = function(x){
243 //return (x - this.bboxFrame.left)/this.bboxFrame.width;
244 return x/this.bboxFrame.width;
247CoordHandler.prototype.getRelativeY = function(y){
248 // return (y - this.bboxFrame.top)/this.bboxFrame.height;
249 return y/this.bboxFrame.height;
252CoordHandler.prototype.getLongitude = function(xRel){
253 return this.bboxGeo.left + xRel*this.bboxGeo.width;
256CoordHandler.prototype.getLatitude = function(yRel){
257 return this.bboxGeo.top + (1.0-yRel)*this.bboxGeo.height;
261CoordHandler.prototype.getGeoPos = function(x,y){
262 return [ Math.round(this.getLongitude(this.getRelativeX(x))),
263 Math.round(this.getLatitude(this.getRelativeY(y))) ]
266CoordHandler.prototype.getGeoBBOX = function(){
267 var x0 = Math.min(this.start.x, this.curr.x)
268 var x = Math.max(this.start.x, this.curr.x)
269 var y0 = Math.min(this.start.y, this.curr.y)
270 var y = Math.max(this.start.y, this.curr.y)
272 return [].concat(this.getGeoPos(x0, y0 ),
273 this.getGeoPos(x, y ))
276CoordHandler.prototype.getPosString = function(x,y){
278 var xRel = this.getRelativeX(x);
279 var yRel = this.getRelativeY(y);
280 x = Math.round(this.getLongitude(xRel));
281 y = Math.round(this.getLatitude(yRel));
284 // a.push(this.drag);