Add sentinel layer to leaflet map - reactjs

This is how i define my url for get wms image for sentinel:
Sentinel2:
"https://kade.si/cgi-bin/mapserv?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/jpeg&TRANSPARENT=true&LAYERS=Landsat-8&TILED=true&format=image%2Fvnd.jpeg-png&WIDTH=320&HEIGHT=320&CRS=EPSG%3A3857&STYLES=&MAP_RESOLUTION=112.5&BBOX={x}{y}{x}{y}",
I have problems with define how to get &BBOX={x}{y}{x}{y}
In this image i see that the request is successfull
[![enter image description here][1]][1]
But when i copu the request URL I see this message:
<ServiceExceptionReport xmlns="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.3.0" xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
<ServiceException>
msWMSLoadGetMapParams(): WMS server error. Wrong number of arguments for BBOX.
</ServiceException>
How to set the right Bbox parameteres..
i read that bbox
Bounding box for map extent. Value is minx,miny,maxx,maxy in units of the SRS.
Also this is working request url:
https://kade.si/cgi-bin/mapserv?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image/jpeg&TRANSPARENT=true&LAYERS=Landsat-8&TILED=true&format=image%2Fvnd.jpeg-png&WIDTH=320&HEIGHT=320&CRS=EPSG%3A3857&STYLES=&MAP_RESOLUTION=112.5&BBOX=2861802.338996999%2C5390950.730896911%2C2866694.30880725%2C5395842.700707162
Why bbox parameters are so long numbers:BBOX=2861802.338996999%2C5390950.730896911%2C2866694.30880725%2C5395842.700707162
Can you help me what to add in the bbox parameter so leaflet to get the right parameters and to view the layer...

Solution:
Javascript
// Declare map using EPSG3857 projection (default is also 3857, so just optionnal here) and set center
const center = [38, 20.472157];
const map = L.map('map', {
crs: L.CRS.EPSG3857
}).setView(center, 4);
// Define wmsOptions for wmsLayer
const wmsOptions = {
layers: 'Landsat-8',
transparent: true,
format: 'image/png'
}
// WMS Layer constructor
const wmsLayer = L.tileLayer.wms('https://kade.si/cgi-bin/mapserv', wmsOptions);
// add To the map
wmsLayer.addTo(map);
Don't forget to set a height to the div map :
Style CSS :
<style>
#map {
height: 500px;
}
</style>
HTML Element :
<div id="map"></div>
See example with your WMS here: jsfiddle example

Related

InvalidStateError: CanvasRenderingContext2D.createPattern: Passed-in canvas has height 0 (jsPDF, html2canvas, React)

I'm getting this error while I try to convert certain part of my page into a PDF (the page is like a group of charts and all of them are surrounded by a container called custom-view)
This is how my function looks like:
export function handleDownloadPdf() {
const element = document.getElementsByClassName("custom-view")[3];
html2canvas(element).then(canvas => {
const imgData = canvas.toDataURL("image/png");
const pdf = new jsPDF({
unit: "px",
format: [500, canvas.height],
});
pdf.addImage(imgData, "JPEG", 0, 0);
pdf.save("download.pdf");
});
}
I'm exporting this function from a component where all of my functions are to another component where the button to start the conversion exist. The reason why I put this: const element = document.getElementsByClassName("custom-view")[3]; as a index [3] is because I have other elements with custom-view class. The height of this custom-view container is dynamic, it gets changed based on the amount of charts there are in a custom view part.
The error I get is this one:
The browser I use is: Mozilla Firefox.

How to render images of unknown dimensions using next/image from Next.js?

This is my use case:
I'll be adding images to a blog post.
I can't set fixed dimensions to render those images, because each one may have unique proportions
For example: I might upload a square image of 400 x 400 or a rectangular image of 400 x 200
From: https://nextjs.org/docs/api-reference/next/image
To render the images, next/image demands you to define the dimensions, either by setting it directly on the <Image/> element, or by setting it on the parent. This is good, because it prevents any layout shift during the load phase of the images.
But since each image will have its own dimensions, I can use the same dimensions for every one.
This is the result I need.
How can I achieve that?
My current idea:
When I upload the image, I'll also have to save its dimensions. Before I started using next/image, I would simple save the image src. Now I'll have to save something like:
post: {
images: [
{
src: "https://.../image1.jpeg",
width: X, // SHOULD SAVE WIDTH
height: Y // AND HEIGHT
}
]
}
So I'll be able to render it like this:
const image = post.images[0];
return(
<Image
src={image.src}
width={image.width}
height={image.height}
/>
);
Is this how it should be done? Is there an easier solution to this?
The approach I've described in the question is exactly what I've ended up doing.
I've created this function to read the image dimensions before the upload:
type ImageDimensions = {
width: number,
height: number
}
export const getImageDimensions = (file: File) : Promise<ImageDimensions> => {
return new Promise((resolve,reject) => {
try {
const url = URL.createObjectURL(file);
const img = new Image;
img.onload = () => {
const { width, height } = img;
URL.revokeObjectURL(img.src);
if (width && height)
resolve({ width, height });
else
reject(new Error("Missing image dimensions"));
};
img.src=url;
}
catch(err) {
console.error(err);
reject(new Error("getImageDimensions error"));
}
});
};
So now every image is saved with at least the following properties:
image: {
src: string,
width: number,
height: number
}
And I'm rendering just like that:
<Image
src={image.src}
width={image.width}
height={image.height}
/>
It's working as intended.

Convert SVG to image in PNG

i am converting angular nvd3 chart to svg using html2canvas and canvg plugings but when i convert pie chart to png then i looks same as chart but when i convert line chart or area chart then its background goes to black and some circle drown on image.
My code is
var svgElements = $("#container").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function () {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function (index, el) {
$(this).css('font-size', getStyle(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
html2canvas($("#container"), {
onrendered: function (canvas) {
var a = document.createElement("a");
a.download = "Dashboard.png";
a.href = canvas.toDataURL("image/png");
a.click();
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm','a4');
var width = doc.internal.pageSize.width;
var height = doc.internal.pageSize.height;
doc.addImage(imgData, 'PNG', 0, 0, width, height);
doc.save('Dashboard.pdf');
}
});
$("#container").find('.screenShotTempCanvas').remove();
$("#container").find('.tempHide').show().removeClass('tempHide');
Help me guys.
Thanks In Advance
Your svg elements are being styled by the external stylesheet nv.d3.min.css .
canvg seems unable to access external style sheets, so you need to append it directly in your svg node.
To do so, if your style sheet is hosted on the same domain as your scripts, you can do something like :
var sheets = document.styleSheets;
var styleStr = '';
Array.prototype.forEach.call(sheets, function(sheet){
try{ // we need a try-catch block for external stylesheets that could be there...
styleStr += Array.prototype.reduce.call(sheet.cssRules, function(a, b){
return a + b.cssText; // just concatenate all our cssRules' text
}, "");
}
catch(e){console.log(e);}
});
// create our svg nodes that will hold all these rules
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
style.innerHTML = styleStr;
defs.appendChild(style);
// now append it in your svg node
thesvg[0].insertBefore(defs, thesvg[0].firstElementChild);
So now you can call the XMLSerializer, and canvg will be happy.
(note that this is not only a canvg limitation, the same applies for every way to draw an svg on a canvas).
Forked plunkr, where I copied the nv.d3.min.css's content to a same-origin style.css.
Very late to the conversation but I just wanted to add that the solution as described by Kaiido, put very simply, is to embed the styles into the SVG document directly.
In order to do this, you manipulate the DOM to make the SVG element look like this:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" version="1.1">
<defs>
<style>
.rectangleStyle{
width:200px;
height:100px;
stroke:black;
stroke-width: 6;
fill: green;
}
</style>
</defs>
<rect class="rectangleStyle"/>
</svg>

Scrollmagic duration

Is there a way to set the scrollmagic duration on a scene as long as the height of the scene? I want to use the class toggles functionality and certain scenes are heigher than the viewport height.
<section id="sec1">I'm 400px in height</section>
<section id="sec1">I'm 100% in height (1 viewport)</section>
<section id="sec1">I'm 2500px in height (2,2 viewports)</section>
Duration in px: {duration: 400}
Duration in vh: {duration: '100%'}
Duration in element height: ???
Thanks for helping!
Try using $("#sec1").height() in the duration option.
To make the duration the height of a scene, you would need to find the height of the item, and then apply that to the duration.
Seeing as all your scenes are sections, you could loop through all sections.
(function() {
let controller = new ScrollMagic.Controller();
// Run through all sections
let items = document.querySelectorAll("section");
items.forEach(function(element, index) {
let height = element.clientHeight; //height of current element
let scene = new ScrollMagic.Scene({
duration: height
//Other scene options go here
})
.on("leave enter", function() {
//Element instructions
})
.addTo(controller);
});
Note: Unless the goal is to give each section their own ID, I would change the ID to class on your sections as pages should only have an ID appear once on the page, while classes can be used multiple times.
An example of this in use.

Leaflet + Sencha NO touch + Sencha architect integration: mixed up tiles

I am trying to integrate Sencha 4.1 (ExtJS) with the Leaflet mapping library while using Sencha Architect.
When the page loads, the tiles are mixed up and appear offset. I need to drag the page up to be able to see the tiles.
The full project is available here: https://github.com/breizo/SenchaLeaflet.
Here is an excerpt of the custom component created (see full code here: https://github.com/breizo/SenchaLeaflet/blob/master/ux/LeafletMap.js).
constructor: function () {
this.callParent(arguments);
this.on({
resize: 'doResize',
scope: this
});
var ll = window.L;
if (!ll) {
this.setHtml('Leaflet library is required');
}
}
onRender: function() {
this.callParent(arguments);
var renderTo = arguments[0].dom.id;
debugger;
var me = this,
ll = window.L,
element = me.mapContainer,
mapOptions = me.getMapOptions(),
map,
tileLayer;
if (ll) {
// if no center property is given -> use default position
if (!mapOptions.hasOwnProperty('center') || !(mapOptions.center instanceof ll.LatLng)) {
mapOptions.center = new ll.LatLng(47.36865, 8.539183); // default: Zuerich
}
me.setTileLayer(new ll.TileLayer(me.getTileLayerUrl(), me.getTileLayerOptions()));
tileLayer = me.getTileLayer();
mapOptions.layers = [tileLayer];
me.setMap(new ll.Map(renderTo, mapOptions));
map = me.getMap();
// track map events
map.on('zoomend', me.onZoomEnd, me);
map.on('movestart', me.onMoveStart, me);
map.on('moveend', me.onMoveEnd, me);
me.fireEvent('maprender', me, map, tileLayer);
}
},
When debugging it appears that when onRender is called, the parent container of the map is not properly sized yet, in particular its height is only enough to contain the attrib text, about 16 pix. WHen the doResize is called, the container is properly sized, but it doesn't change the end result: the tiles are mixed up and offset.
I tried various changes to the container, but nothing worked...
1) Problem with mixed layers is caused by CSS. Your leaflet.css has wrong path in html, so it's not attached in the document. To fix mixing issue set correct path to css file, or attach it from CDN:
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.css" />
2) Wrong map offset is caused by extjs generated div:
<div class="x-llmap x-fit-item x-llmap-default" ...></div>
It pushes map container to the bottom and wrong offset calculations are made. You can also fix this using inline style or CSS:
.leaflet-map-pane {
top: 0;
}

Resources