how to initiate Marzipano viewer http://www.marzipano.net/ - virtual-reality

Since Marzipano documentation is bad for newbies i have no idea how to initialize a pano
I decided to get only the pano viewer and keep away of integrating the Marzipano tool!
so far i have now a generated 360 panoramic zip file through the Marzipano tool and would like to render it on my website
how could that be done ?
http://www.marzipano.net/

this is how you create a viewer.
opts = { controls: { mouseViewMode: "drag" } }
const viewer = new Marzipano.Viewer(document.getElementById(domID), opts);
let defaultCubeGeometry = [{ tileSize: 256, size: 256, fallbackOnly: true }, { tileSize: 1024, size: 1024 }];
let cubeGeometry = new Marzipano.CubeGeometry(defaultCubeGeometry);
let limiter = return new Marzipano.util.compose(
Marzipano.RectilinearView.limit.resolution(resolution),
Marzipano.RectilinearView.limit.vfov(vfov.min, vfov.max),
Marzipano.RectilinearView.limit.hfov(vfov.min, vfov.max),
Marzipano.RectilinearView.limit.pitch(pitch.min, pitch.max)
);
let initialView = { yaw:0, pitch:0, roll:0 };
let view = new Marzipano.RectilinearView(initialView, limiter);
let source = new Marzipano.ImageUrlSource.fromString(imageUrl);
let scene = viewer.createScene({ source, geometry, view });
scene.switchTo();
this should be the complete initialization of viewer

Related

Leaflet: How read pixel dBZ values from the added rain-viewer layer

I am requesting available weather past timestamps from Rain Viewer, below script tag clip:
...
init = function()
{
var apiRequest = new XMLHttpRequest();
apiRequest.open("GET", "https://tilecache.rainviewer.com/api/maps.json", true);
var o_that = this;
apiRequest.onload = function(e) {
...
And then request Leaflet layers with "dBz" data
radarLayers[ts] = new L.TileLayer( 'https://tilecache.rainviewer.com/v2/radar/' + ts + '/256/{z}/{x}/{y}/0/0_0.png' , {
tileSize: 256,
opacity: 0.001,
zIndex: ts
});
I my application I want to check tile pixels for dBz values.
How I can do it JavaScript code?

Getting the map bounds of a GeoJson region in leaflet prior to zooming

I'm using leaflet and I'm loading up the regions of my map dynamically from a database, based on the bounding box coordinates of the currently viewed map. As I zoom in, the detail of each new layer increases. The same regions will exist in every layer of the map, and the same region on a different zoom level will have the same id.
I am currently attempting to calculate the target map bounds and target zoom level, so that I can load up all the intersecting regions within the new map bounding box. I currently have the following code.
zoomToFeature(e) {
//e.g. map zoom for currently visible map is 3
const layer = e.target;
let padding = [5, 5];
let layerBounds = layer.getBounds();
//e.g layerBounds returns:
//ne = lat: -37.770025, lng: 145.02439
//sw = lat: -37.834451, lng: 144.900952
let targetZoom = this.map.getBoundsZoom(layerBounds, false, padding);
targetZoom = Math.min(this.map.getMaxZoom(), targetZoom);
//e.g.targetZoom for this feature is 12
let center = layer.getCenter()
//e.g. center for this layer is lat: -37.78808138412046, lng: 144.93164062500003
let targetPixelBounds = this.map.getPixelBounds(center, targetZoom);
//e.g. targetPixelBounds: max: Point{x: 946751, y: 643578} min:{x:946114,y:643078}
//this looks very wrong, and so causes everything below to fail I think.
//am I supposed to reset the origin? am I meant to project the center and targetZoom?
let sw = this.map.unproject(targetPixelBounds.getBottomLeft());
let ne = this.map.unproject(targetPixelBounds.getTopRight());
let targetMapBounds = new L.LatLngBounds(sw, ne);
this.map.flyTo(center,targetZoom);
this.loadMapData(targetMapBounds, targetZoom).subscribe(() => {
this.removeOldRegions(); // deletes existing geojson
this.loadRegions(); // adds retrieved data to new geojson layer
//find the same region but in the new zoom layer
let newLayer = this.getLayerById(layer.feature.properties.id);
this.highlightFeature(newLayer);
});
}
It is going wrong at the
let targetPixelBounds = this.map.getPixelBounds(center, targetZoom)
line.
Any idea how I can fix this?
Ok, I've cracked the case.
The unproject lines in the original code above take zoom level as an argument, which I didn't put in the original code.. So I've refactored the code, which I have posted below.
Basically once I have the map bounding box, I can perform the fly to, and execute code to retrieve the new geojson at the new zoom level. By the time the animation has completed, the new geojson layer is already loaded. (Written in TypeScript. Sorry non TypeScript people)
zoomToFeature(e) {
const layer = e.target;
let padding = [5, 5];
let layerBounds = layer.getBounds();
let targetMapBoundsZoom = this.getTargetMapBoundsZoom(layerBounds, { padding: padding });
this.map.flyToBounds(targetMapBoundsZoom.bounds);
this.loadMapData(targetMapBoundsZoom.bounds, targetMapBoundsZoom.zoom).subscribe(() => {
this.removeOldRegions();
this.loadRegions();
//find the same region but in the new zoom layer
let newLayer = this.getLayerById(layer.feature.properties.id);
this.highlightFeature(newLayer);
});
}
getTargetMapBoundsZoom(bounds, options) {
let newBoundsCenterZoom = this._getBoundsCenterZoom(bounds, options);
let targetMapBoundsPixels = this.map.getPixelBounds(newBoundsCenterZoom.center, newBoundsCenterZoom.zoom);
let targetSw = this.map.unproject(targetMapBoundsPixels.getBottomLeft(), newBoundsCenterZoom.zoom);
let targetNe = this.map.unproject(targetMapBoundsPixels.getTopRight(), newBoundsCenterZoom.zoom);
let targetMapBounds = new L.LatLngBounds(targetSw, targetNe);
return {
bounds: targetMapBounds,
zoom: newBoundsCenterZoom.zoom
}
}
loadMapData(bounds, zoom): Observable<any[]> {
const boundingBox = Util.GetMapBounds(bounds);
const regionTypeId = this.regionTypeIds[this._regionType];
return this.mapService.getGeoJsonData("AU",
regionTypeId,
zoom,
boundingBox.n,
boundingBox.s,
boundingBox.e,
boundingBox.w).pipe(map((response: any) => {
this.mapGeoJsonData = this.createFeatureCollection(response.data);
return this.mapGeoJsonData;
}));
}
//this is a copy of the original _getBoundsCenterZoom that is internal to leaflet, with minor modifications.
_getBoundsCenterZoom(bounds, options) {
options = options || {};
bounds = bounds.getBounds ? bounds.getBounds() : L.latLngBounds(bounds);
var paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]),
paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]),
zoom = this.map.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom;
if (zoom === Infinity) {
return {
center: bounds.getCenter(),
zoom: zoom
};
}
var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),
swPoint = this.map.project(bounds.getSouthWest(), zoom),
nePoint = this.map.project(bounds.getNorthEast(), zoom),
center = this.map.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
return {
center: center,
zoom: zoom
};
}
createFeatureCollection(data: any) {
let featureCollection = {
type: "FeatureCollection",
features: data.map(r => {
const geoJson = JSON.parse(r.geoJson);
if (geoJson.type === "GeometryCollection") {
geoJson.geometries = geoJson.geometries.filter(r => r.type === "Polygon" || r.type === "MultiPolygon");
}
let feature = {
type: "Feature",
id: r.id,
properties: { id: r.id },
geometry: geoJson
}
return feature;
})
};
return featureCollection;
}
The default behaviour for this is to read out the bounds and pass it to the map:
map.fitBounds(e.target.getBounds());
Then you function can look like:
zoomToFeature(e) {
let padding = [5, 5];
let layerBounds = e.target.getBounds();
let targetZoom = this.map.getBoundsZoom(layerBounds, false, padding);
targetZoom = Math.min(this.map.getMaxZoom(), targetZoom);
//e.g.targetZoom for this feature is 12
map.fitBounds(layerBounds , {padding: padding, maxZoom: targetZoom });
this.loadMapData(layerBounds , targetZoom).subscribe(() => {
this.removeOldRegions(); // deletes existing geojson
this.loadRegions(); // adds retrieved data to new geojson layer
//find the same region but in the new zoom layer
let newLayer = this.getLayerById(layer.feature.properties.id);
this.highlightFeature(newLayer);
});
}
this moves the map and zoom it to the layer.

How to send large Base64 data to NavController in Ionic 2/3?

I am trying to send Base64 data as string to another page using NavController using below code:
ConvertHTMLToPDF = () => {
let htmlGrid = document.getElementById('customContent');
const options = {background: "white", height: htmlGrid.clientHeight, width: htmlGrid.clientWidth};
html2canvas(htmlGrid, options).then((canvas) => {
let doc = new jsPDF("p", "mm", "a4");
let imgData = canvas.toDataURL("image/PNG");
//Add image Canvas to PDF
doc.addImage(imgData, 'PNG', 20, 20);
let pdfData = doc.output('datauri');
let obj = {PDFSrc: pdfData};
this.navCtrl.setRoot('SaveConsentLetterPage', obj);
});
};
This is perfectly working when the Base64 data is small in size like 3Kb or 4Kb. But, when the data is like 1.2Mb, the NavController can redirect to SaveConsentLetterPage. It crashes the application.
Why is that? Is there any limit to send data with setRoot to another page in Ionic 2/3?
Actually the problem was with below line:
let pdfData = doc.output('datauri');
This opens the data uri/pdfData in current window and as a result, preventing to go the next page.
But, below line returns only the data uri string and as a result, can easily pass the data to next page.
doc.output('datauristring');

leaftletjs-adding points dynamically and draw line string

I am trying to draw the path of a flight using leafletjs and geojson. I'll be getting the geometry from a stream.
this is what I have done so far:
let index = 0;
let geoJsonLayer;
let intervalFn = setInterval(function () {
let point = trackData.features[index++];
if(point) {
let coords = point.geometry.coordinates;
coords.pop();
coords.reverse();
geoFeature.geometry.coordinates.push(coords);
if(map.hasLayer(geoJsonLayer)) map.removeLayer(geoJsonLayer);
geoJsonLayer = L.geoJson(geoFeature, {
onEachFeature: (feature, layer) => {
const content = feature.properties.title;
layer.bindPopup(content);
}
});
geoJsonLayer.addTo(map);
// console.log(coords);
} else {
clearInterval(intervalFn);
}
}, 100);
setInterval is to simulate the part whereby I get the geometry from a stream.
now when a user clicks on the path I need to show some properties of the path, and I am trying to use the onEachFeature for that, but its not working correctly.
I suspect its because I am removing the layers (I did this to improve the performance)
Is there any other better ways to do what I am trying to achieve ?
You should probably try addLatLng()
Adds a given point to the polyline.
Your geoFeature sounds to be a single Feature, so your geoJsonLayer will contain a single layer (polyline):
let myPolyline;
geoJsonLayer.eachLayer(function (layer) {
myPolyline = layer; // Will be done only once actually.
});
// When you receive a new point…
myPolyline.addLatLng([lat, lng]);
With this you should not have to remove your layers every time.
The popup should therefore stay open, if it is shown.
Demo: https://jsfiddle.net/3v7hd2vx/265/ (click on the button to add new points)

Trying to make use of Jcrop and serverside image resizing with scala Scrimage lib

I'm trying to combine jcrop and scrimage but I'm having trouble in understanding
the documentation of scrimage.
The user uploads an image. When the upload is done the user is able choose a fixed
area to crop with Jcrop:
upload.js
$(function () {
$('#fileupload').fileupload({
dataType: 'json',
progress: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$("#progress").find(".progress-bar").css(
"width",
progress + "%"
);
},
done: function (e, data) {
$("#cropArea").empty();
var cropWidth = 210;
var cropHeight = 144;
if(data.result.status == 200) {
var myImage = $("<img></img>", {
src: data.result.link
}).appendTo('#cropArea');
var c = myImage.Jcrop({
allowResize: false,
allowSelect: false,
setSelect:[0,0,cropWidth,cropHeight],
onSelect: showCoords
});
}
}
});
});
Example:
When the user is satisfied the coordinates will be posted to the server and there is where the magic should happen.
Controller:
def uploadFile = Action(multipartFormDataAsBytes) { request =>
val result = request.body.files.map {
case FilePart(key, filename, contentType, bytes) => {
val coords = request.body.dataParts.get("coords")
val bais = new ByteArrayInputStream(bytes)
Image(bais).resize(magic stuff with coords)
Ok("works")
}
}
result(0)
}
If i read the docs for scrimage and resize:
Resizes the canvas to the given dimensions. This does not scale the
image but simply changes the dimensions of the canvas on which the
image is sitting. Specifying a larger size will pad the image with a
background color and specifying a smaller size will crop the image.
This is the operation most people want when they think of crop.
But when trying to implement resize with an inputstream Image(is).resize() I'm not sure I how should do this. Resize takes a scaleFactor, position and color... I guess I should
populate the position with the coords I get from jcrop??, and what do I do with the scaleFactor? Anybody got a good example of how to do this this?
Thank you for two great libs!
Subimage is what you want. That lets you specify coordinates rather than offsets.
So simply,
val image = // original
val resized = image.subimage(x,y,w,h) // you'll get these from jcrop somehow