pan and zoom images for jQuery Mobile - jquery-mobile

I would appreciate any help concerning pan and zoom for a jquery mobile web app. I have an image of a building floorplan with an image map on top that I would like the user to be able to view from his mobile phone, zoom in and out and pan the area of interest into view.

This should do the trick. http://www.photoswipe.com/

I solved my problem with OpenLayers, image now pans and zooms http://dev.openlayers.org/releases/OpenLayers-2.11/examples/image-layer.html
have to figure out how to combine it with imagemapster now.. (http://www.outsharked.com/imagemapster/)

I have been working on the same problem where an office's floor map of desks should be shown in different colors based on desk's status (Empty, Allocated, Hot seated and etc).
Adding to to this if user clicks on desk, the details of allocated associates/employees should be shown.
The above requirements had been implemented using image mapster jquery plug-in.
And also zooming and panning should be provided.For zooming and panning I have found gzoom plug-in which best suits my requirement. But it is not working as expected when used with image mapster plug-in.
I appreciate your help regarding this.

I figured it out, got everything I needed from the OpenLayers examples
<script type="text/javascript">
var map;
function init(){
map = new OpenLayers.Map('map');
var options = {numZoomLevels: 3}
var floorplan = new OpenLayers.Layer.Image(
'Floorplan Map',
'../../temp_photos/sample-floor-plan.jpg',
new OpenLayers.Bounds(-180, -90, 180, 90),
new OpenLayers.Size(275, 190),
options
);
map.addLayer(floorplan);
//Create a Format object
var vector_format = new OpenLayers.Format.GeoJSON({});
//Create a Protocol object using the format object just created
var vector_protocol = new OpenLayers.Protocol.HTTP({
url: '../../controller?action=GET_FLOOR_FEATURES',
format: vector_format
});
//Create an array of strategy objects
var vector_strategies = [new OpenLayers.Strategy.Fixed()];
//Create a vector layer that contains a Format, Protocol, and Strategy class
var vector_layer = new OpenLayers.Layer.Vector('More Advanced Vector Layer',{
protocol: vector_protocol,
strategies: vector_strategies
});
map.addLayer(vector_layer);
//Create and add selectFeature control
var select_feature_control = new OpenLayers.Control.SelectFeature(
vector_layer,
{
multiple: false,
toggle: true,
toggleKey: 'ctrlKey',
multipleKey: 'shiftKey'
}
);
map.addControl(select_feature_control);
//Activate the control
select_feature_control.activate();
//Finally, let's add some events so we can do stuff when the user
// interacts with the features
function selected_feature(event){
//clear out the log's contents
document.getElementById('map_feature_log').innerHTML = '';
//Show the current selected feature (passed in from the event object)
var display_text = 'Clicked on: '
+ '<strong>' + event.feature.attributes.location + '</strong>'
+ ': ' + event.feature.attributes.description + '<hr />';
document.getElementById('map_feature_log').innerHTML = display_text;
//Show all the selected features
document.getElementById('map_feature_log').innerHTML += 'All selected features: ';
//Now, loop through the selected feature array
for(var i=0; i<vector_layer.selectedFeatures.length; i++){
document.getElementById('map_feature_log').innerHTML +=
vector_layer.selectedFeatures[i].attributes.location + ' | ';
}
}
function unselected_feature(event){
var display_text = event.feature.attributes.location + ' unselected!' + '<hr />';
document.getElementById('map_feature_log').innerHTML = display_text;
//Show all the selected features
document.getElementById('map_feature_log').innerHTML += 'All selected features: ';
//Now, loop through the selected feature array
for(var i=0; i<vector_layer.selectedFeatures.length; i++){
document.getElementById('map_feature_log').innerHTML +=
vector_layer.selectedFeatures[i].attributes.location + ' | ';
}
}
//Register the event
vector_layer.events.register('featureselected', this, selected_feature);
vector_layer.events.register('featureunselected', this, unselected_feature);
if(!map.getCenter()){
map.setCenter(new OpenLayers.LonLat(0, 0),1);
}
}
</script>
Markup:
Image Layer Example
<p id="shortdesc">
This is a floor plan for the first floor of the Science Building
</p>
<div id="map" class="smallmap"></div>
<div id="docs"><div id='map_feature_log'></div>
<p class="caption">
This test shows how to display an image of a floorplan as a
base layer and then draw vectors on top of that, on a new layerage
</p>
<p>
When vector is added popup appears with that vector's information
</p>
</div>
</body>
I get my features from the server:
package actions;
import control_layer.Action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* #author christina
*/
public class GetFloorFeatures implements Action {
private static final int MAX_INACTIVE_INTERVAL = 900; // 15 minutes
private String view;
#Override
public boolean execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
HttpSession session = req.getSession(true);
System.out.println("------------ In GetFloorFeatures");
session.setMaxInactiveInterval(MAX_INACTIVE_INTERVAL);
view = "pages/maps/displayFloorFeatures.jsp";
return true;
}
#Override
public String getView() {
return view;
}
#Override
public Object getModel() {
return null;
}
}
The data is hardcoded in the jsp file but it will eventually be generated by a database query:
<%#page contentType="application/json" pageEncoding="UTF-8"%>
<% response.setContentType("application/json");
//harcoded now, later will call database query to retrieve features for this floor
String floorFeatureVectors = "{\"type\": \"FeatureCollection\",\"features\": [{\"type\":\"Feature\", \"id\":\"OpenLayers.Feature.Vector_84\", \"properties\":{\"location\": \"Telecom Lab\",\"description\": \"Stand back, I'm going to try science!\"}, \"geometry\":{\"type\":\"Polygon\", \"coordinates\":[[[9, -52.342105263158], [9.4736842105263, -79.815789473684], [40.263157894737, -78.868421052632], [43.105263157895, -78.394736842105], [44.526315789474, -51.394736842105], [9, -52.342105263158]]]}, \"crs\":{\"type\":\"OGC\", \"properties\":{\"urn\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}},"
+ "{\"type\":\"Feature\", \"id\":\"OpenLayers.Feature.Vector_85\", \"properties\":{\"location\": \"MUSIC lab\",\"description\": \"Laboratory of Distributed Multimedia Information Systems and Applications \"}, \"geometry\":{\"type\":\"Polygon\", \"coordinates\":[[[-113.21052631579, 4.9736842105263], [-113.68421052632, -11.605263157895], [-76.263157894737, -13.026315789474], [-76.263157894737, -1.1842105263158], [-93.315789473684, -0.71052631578947], [-93.789473684211, 4.0263157894737], [-113.21052631579, 4.9736842105263]]]}, \"crs\":{\"type\":\"OGC\", \"properties\":{\"urn\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}},"
+ "{\"type\":\"Feature\", \"id\":\"OpenLayers.Feature.Vector_86\", \"properties\":{\"location\": \"Main Entrance Science Building\",\"description\": \"Caffeteria \"}, \"geometry\":{\"type\":\"Point\", \"coordinates\":[-8.0526315789474, 36.710526315789]}, \"crs\":{\"type\":\"OGC\", \"properties\":{\"urn\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}"
+ "]}";%><%=floorFeatureVectors%>

Related

How to save changes to firebase document if user closes window or tab

Context: I have a use case where in the components used is firebase realtime database in Polymer 2.x. I have a function that does transformations on certain user activity with the firebase realtime object. I used polymerfire webcomponent.
What I want is: on user closes tab or window, save the data into firebase realtime database and then close the window.
Result: I used on beforeunload of window in the script of the polymer element. But not able to fire a method inside polymer element that triggers storage of the data in realtime db.
What I am looking for:
1. A way to initiate the element public function from script of an element.
Or
2. a better way to implement on window/tab close save the data
Thanks.
Code:
<!DOCTYPE html>
<dom-module id="t-page">
<template is="dom-bind">
....
</template>
<script>
var myEvent = window.attachEvent || window.addEventListener;
var chkevent = window.attachEvent ? 'onbeforeunload' :
'beforeunload'; /// make IE7, IE8 compitable
myEvent(chkevent, async function (e) { // For >=IE7, Chrome, Firefox
var confirmationMessage = 'Are you sure to leave the page?'; // a space
(e || window.event).returnValue = confirmationMessage;
setTimeout(async () => {
document.getElementById('trello-page').onCloseWindow();
}, 2500);
return confirmationMessage;
});
/**
* #polymer
* #extends HTMLElement
*/
class TPage extends Polymer.Element {
static get is() {
return 't-page';
}
... some properties ....{ colUpdateArr{...}}
async onCloseWindow() {
for (var i = 0; i < this.colUpdateArr.length; i += 2) {
var toCol = this.colUpdateArr[i];
var fromCol = this.colUpdateArr[i + 1];
await this.$.query.ref.child(toCol.$key).child('tasks').set(toCol.tasks);
await this.$.query.ref.child(fromCol.$key).child('tasks').set(fromCol.tasks);
}
}
} //end Polymer.Element
window.customElements.define(TPage.is, TPage);
</script>
</dom-module>

Tile loading progress for vector sources utilizing tile loading strategy

I am loading features into Vector source utilizing the Tile strategy. I'd like implement kind of progress bar, similar to http://openlayers.org/en/master/examples/tile-load-events.html.
However, unlike VectorTile source, the Vector source doesn't trigger tile loading events which could be used for calculating desired ratio 100*(tilesLoaded/tilesToLoad).
So far I can retrieve the total count of tiles to load, but I am unable to count already loaded tiles. The most promising is a custom loader, but it is not clear to me how to modify it without touching the original OL source code.
var vectorSource = new ol.source.Vector({
loader: ol.featureloader.xhrX(url, format),
strategy: ol.loadingstrategy.tile(tileGrid)
});
// forked method, but the inner 'loadFeaturesXhr' method seems to be private and cannot be used
ol.featureloader.xhrX = function(url, format) {
/*
return ol.featureloader.loadFeaturesXhr(url, format,
function(features, dataProjection) {
this.addFeatures(features);
// when tile loading succeeds
tilesLoaded++;
},
function() {
// when tile loading fails
tilesLoaded++;
});
*/
// just returning the original loader
return ol.featureloader.xhr(url, format);
}
var url = function(extent, resolution) {
tilesToLoad++; // when a new tile is needed, this counter is incremented
var tileCoord = tileGrid.getTileCoordForCoordAndResolution(ol.extent.getCenter(extent), resolution);
return 'tiles/' +
tileCoord[0] + '/' +
tileCoord[1] + '/' +
(Math.pow(2, tileCoord[0]) + tileCoord[2]) + '.json';
}
var format = new ol.format.GeoJSON({
defaultDataProjection: 'EPSG:3857'
});
Any idea how to call loadFeaturesXhr() method from my source?
Instead of forking default OL3 loader I created a custom one. It was not as hard as expected. Now I can freely add counters to proper places (in the code below I actually update the progress component itself):
var vectorSource = new ol.source.Vector({
loader: function(extent, resolution, projection) {
var getUrl = function(extent, resolution) {
progress.addLoading();
...
};
var xhr = new XMLHttpRequest();
xhr.open('GET', getUrl(extent, resolution), true);
xhr.onload = function(event) {
...
progress.addLoaded();
}.bind(this);
xhr.onerror = function(event) {
progress.addLoaded();
}
xhr.send();
},
strategy: ol.loadingstrategy.tile(tileGrid)
});

Jstree, get_checked, pass value to div onselect event

i'm using an MVC c# asp.net 4.0 project with Jstree, but i have a small problem i have a jstree that's populated witha a JSON array.
My problem is I need to catch the value of the checkboxes in jstree when checked to a div in my view.
OK, i finally got this working this is the solution i hope it Help's someone :)
first you must bind:
.bind('check_node.jstree', function (e, data) {
$("#listSelectedActives").html(BuildList());
})
.bind('uncheck_node.jstree', function (e, data) {
$("#listSelectedActives").html(BuildList());
then the use this function:
function BuildList() {
var checked = $("#demoTree").jstree("get_checked", null, true);
var output = "";
$(checked).each(function (i, node) {
var id = $(node).attr("ID");
var text = $(node).attr("NodeText");
output += "<p>ID: " + id + " TEXT: " + text + "</p>";
})
return output;
}
If this is too confusing please let'me know :)

jQuery UI portlets - toggle portlets to save to a cookie (half way there!)

I'm a bit of a jQuery n00b so please excuse me if this seems like a stupid question. I am creating a site using the jQuery UI more specifically the sortable portlets. I have been able store whether or not a portlet is has been open or closed to a cookie. This is done using the following code. The slider ID is currently where the controls are stored to turn each portlet on and off.
var cookie = $.cookie("hidden");
var hidden = cookie ? cookie.split("|").getUnique() : [];
var cookieExpires = 7; // cookie expires in 7 days, or set this as a date object to specify a date
// Remember content that was hidden
$.each( hidden, function(){
var pid = this; //parseInt(this,10);
$('#' + pid).hide();
$("#slider div[name='" + pid + "']").addClass('add');
})
// Add Click functionality
$("#slider div").click(function(){
$(this).toggleClass('add');
var el = $("div#" + $(this).attr('name'));
el.toggle();
updateCookie(el);
});
$('a.toggle').click(function(){
$(this).parents(".portlet").hide();
// *** Below line just needs to select the correct 'id' and insert as selector i.e ('#slider div#block-1') and then update cookie! ***
$('#slider div').addClass('add');
});
// Update the Cookie
function updateCookie(el){
var indx = el.attr('id');
var tmp = hidden.getUnique();
if (el.is(':hidden')) {
// add index of widget to hidden list
tmp.push(indx);
} else {
// remove element id from the list
tmp.splice( tmp.indexOf(indx) , 1);
}
hidden = tmp.getUnique();
$.cookie("hidden", hidden.join('|'), { expires: cookieExpires } );
}
})
// Return a unique array.
Array.prototype.getUnique = function() {
var o = new Object();
var i, e;
for (i = 0; e = this[i]; i++) {o[e] = 1};
var a = new Array();
for (e in o) {a.push (e)};
return a;
}
What I would like to do is also add a [x] into the corner of each portlet to give the user another way of hiding it but I'm unable to currently get this to store within the Cookie using the code above.
Can anyone give me a pointer of how I would do this?
Thanks in advance!
Gareth
Have you tried adding another selector to the click function?
$("#slider div, #slider div > span.ui-icon-x").click(function(){
$(this).toggleClass('add');
var el = $("div#" + $(this).attr('name'));
el.toggle();
updateCookie(el);
});

Is there any way to display image in client browser without uploading it to server?

I am writing a simple "Book" create page in ASP.NET MVC. User can create book by filling title,year etc.. and selecting a cover image. When user press "Create" button Form sends image and data to Controller action called "Create" then I save image to disk and data to database.
But I want to display image when user select image by file dialog.To do this As far as I know I must upload image to server then display in client browser.But if a user cancels the "Create" operation after uploading image, the image will remain in the server's disk.So How can I deal with these temp images or Is there any way to display image in client browser without upload to server?
Due to security reasons, you will not be able to display the images to the users without uploading them to the server. Displaying images from file system is considered a security risk.
EDIT: To remove the unused images, you can create a thread to run a cleanup routine to which will delete them from the upload directory regularly.
Yes, using Silverlight, for example:
In Page.xaml:
<StackPanel x:Name="LayoutRoot" Background="White">
<Button x:Name="btn1" Content="Select image file">
<Image x:Name="img1">
</StackPanel>
and in Page.xaml.cs:
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
btn1.Click += new RoutedEventHandler(btn1_Click);
}
void btn1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
Stream s = ofd.File.OpenRead();
BitmapImage bi = new BitmapImage();
bi.SetSource(s);
img1.Source = bi;
s.Close();
}
}
}
Read more here.
Yes, you can using javascript
Javascript:
function showThumbnail(files){
for(var i=0;i<files.length;i++){
var file = files[i]
var imageType = /image.*/
if(!file.type.match(imageType)){
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
thumbnail.appendChild(image)
var reader = new FileReader()
reader.onload = (function(aImg){
return function(e){
aImg.src = e.target.result;
};
}(image))
var ret = reader.readAsDataURL(file);
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
image.onload= function(){
ctx.drawImage(image,100,100)
}
}
}
var fileInput = document.getElementById("upload-image");
fileInput.addEventListener("change",function(e){
var files = this.files
showThumbnail(files)
},false)
HTML:
<input type="file" id="upload-image" multiple="multiple"></input>
<div id="thumbnail"></div>
You just need the input field and The div to display the thumbnail image, and on change for the input field will call showThumbnail function which will append img inside the "thumbnail" div.
You can do it with Simple javascript...
assign the selected image path.. to image tag prefixing the file://, n it works the way you want it to be

Resources