html2canvas artifacts and inconstancy when grabbing a screenshot of google map - javascript

Few things with html2canvas are not predictable:
Below is a screenshot of pdf map.
I am using html2canvas to take a screenshot of google map, and then putting it on pdf by using php.
sometimes html2canvas will display a grayish faded rectangular shape close to the center (in the image below the shape is to the right of DV-2 marker). Sometimes it is there, sometimes it it is not, inconsistent on all modern browsers.
Most of the times one or more markers will not have label displayed. In image below the blue marker to the right does not have marker.
On the map, before taking the screenshot, the gray shape is not there and all markers have label visible.
Any thoughts / suggestions why it is happening? Like I mentioned earlier, it is unpredictable, sometimes that shape does not show up and sometimes all marker labels are visible.
I notice that the markers without label are put on the map first (when I console.log()). It is happening in html2canvas not after. Below is the vue.js method which grabs the screenshot.
genAndSubmit() {
let xCrop = (this.dimensions.vw - this.dimensions.pw) / 2
this.form.processing = true;
html2canvas(document.querySelector("#mapWrapper"),
{
useCORS: true,
logging: true,
width: this.dimensions.pw,
x: xCrop,
// allowTaint: true,
// foreignObjectRendering: true,
// imageTimeout: 30000,
// scale: 2,
})
.then(canvas => {
this.form.image = canvas.toDataURL('image/png');
this.submit();
});
},

After trying different things here are my solutions:
Rectangular shape close to center - I increased the scale in html2canvas settings html2canvas(document.querySelector("#mapWrapper"),{scale: 1.001,})
Some Marker labels not visible - I increased the zIndex:9 for the marker.
Google Maps Info Window not showing content
Remove shadow from Info Window #mapWrapper .gm-style .gm-style-iw-c {box-shadow: none !important;}
Use V1.0.0 of html2canvas. In my tests, newer version did not display Info Window content.

I found that with the latest (1.4.1) I had to set overflow value so that it exporte properly.
.gm-style-iw.gm-style-iw-c {
overflow: visible;
}

Related

Problem of tiling with GeoWebCache: most tiles are missing

I set up a PostGIS database that I added in GeoServer via a parameterized SQL view. I used Leaflet to display this layer via wms.
It worked fine until I add GeoWebCache using the url "/geoserver/gwc/service/wms" instead of "/geoserver/wms". I can still see my polygons when I'm at the minimal zoom. But then when I zoom I see only a red polygon and a half of a green polygon and if I zoom again I see only the red polygon. You can see these 3 states on the images below:
I guess this is a problem of tiling: I get the minimal tiles and also some tiles around the red polygon for further zooms but for some reason it seems that the other tiles are not sent.
Here is the code I use to get my wms layer with leaflet:
geoJSONlayer = L.tileLayer.wms("/geoserver/gwc/service/wms", {
layers: 'cartowiki:choix',
format: 'image/png',
transparent: true,
viewparams: 'year:'+(annee+3000)
}).addTo(map);
geoJSONlayer.addTo(map);
Do you have an idea of the problem here ?
Thanks in advance,
The bounding box was the problem indeed. In Geoserver, I had to modify the properties of the layer in 2 places :
I clicked 'Compute from SRS bounds' and then 'Compute from native bounds' in the Bounding Boxes part of the Data section
I erased and created again the available gridsets in the Tile Caching section so that the grid subset bounds would update with the new Bounding Boxes
I hope it can help someone in the future!

BIng Map V8. All the Pins are falling 2cm below than positioned on first Load

BIng Map V8. All the Pins are falling 2cm below than positioned on first Load and when I refresh the page the pins are moving back to their actual location.
here is the sample of the code that I used in the implementation.
var pin = new Microsoft.Maps.Pushpin(addressLocation, {
icon: '/img/pin.png',
width: 29,
height: 40,
showPointer: true,
subTitle: _.template(CustomTemplate, _.extend({}, addressLocation))
});
this.locations.push(addressLocation);
this.pins.push(pin);
Are there any suggested fixes for this issue? Thanks in advance.
I suspect that if you zoom the map you will notice the pushpins drift to and from the location they are meant to represent. The issue is that your pushpin is a different size from the default pushpin, and as such the anchor point (part of your image anchored to the location point on the map) of your pushpin is using incorrect and causing this effect. Here is some documentation on how to address this in your app: https://msdn.microsoft.com/en-us/library/mt712695.aspx

Fill container with non-repeating map with Google Maps V3

I found a couple of people asking this question on here but the answers all had a map that didn't fill 100% of the screen so if you zoomed out it wouldn't repeat but you'd get gray bars above/below the map.
If you go to maps.google.com, no matter how far you zoom out, no matter how wide or tall your window, the map always fills the screens and never repeats. I can't figure out how to do this with the Google Maps JS API and I can't find anything on StackOverflow of this exact behavior.
For a visual, this is the default behavior (afaik) from Google Map's API:
Here is maps.google.com at the same screen size and zoomed out as far as they let you
If you make the window even wider Google Maps' site seems to resize the map to constantly stay 100% wide/tall so no gaps and repeats ever happen. How do I do this?
You may calculate the minZoom based on the size of the map.
The minZoom would be:
mapWidth<=256:0
mapWidth<=512:1
mapWidth<=1024:2
mapWidth<=2048:3
The formula:
Math.ceil(Math.log(map.getDiv().offsetWidth/256)/Math.log(2))
possible implementation(including re-centering the map)
google.maps.event.addDomListener(window,'resize',function(){
if(map.get('bounds_listener')){
google.maps.event.removeListener(map.get('bounds_listener'));
}
else{
map.set('_center',map.getCenter());
}
map.setOptions({
minZoom: Math.ceil(Math.log(map.getDiv().offsetWidth/256)/Math.log(2))
});
map.setCenter(map.get('_center'));
map.set('bounds_listener', google.maps.event.addListener(map, 'bounds_changed', function(){
this.set('_center',this.getCenter());
}));
});
//trigger resize to set initial value
google.maps.event.trigger(window,'resize');

leaflet rectangle disappears instantly

I'm just getting started creating a Leaflet webapp and I'm failing to draw a rectangle. When I load the page it shows for a split second, barely before the map even loads, and then it disappears (That's in Chrome, in Firefox it doesn't show at all). What am I missing here?
Below is my code:
<script>
var bounds = [[52.42, 4.78], [52.46, 4.88]];
var map = L.map('map', {
maxBounds: bounds,
minZoom: 14
}).setView([52.44, 4.83], 14);
var googleLayer = new L.Google('ROADMAP');
map.addLayer(googleLayer);
$(document).ready(function() {
L.rectangle(bounds, {color: "red", weight: 1}).addTo(map);
});
</script>
I tried drawing the rectangle at the $(document).ready() event but that didn't work.
The rectangle is hidden because the google layer gets drawn on top. Might be a bug, I would expect the layers to be in the z-order in which they get added. Quick fix (check for side effects) is to force the needed order using CSS styles such as these:
.leaflet-google-layer{
z-index: 0 !important;
}
.leaflet-map-pane{
z-index: 100;
}

Leafletjs Cursor when hovering over WMS Layer

I am using Leafletjs. Currently its pretty straight forward, I have a streets view from open maps.
var streets = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors'
});
I also have a WMS layer that is coming from a geoserver. It has the standard getFeatureInfo and everything shows up correctly.
L.tileLayer.wms("GEOSERVERURL", {
layers: 'layers',
format: 'image/png'
,transparent: true
}).addTo(map);
The wms layer is also clickable and I use getFeatureInfo to get the info for that layer. The issue is that the user doesn't know its clickable because the cursor never changes when they hover of the wms layer. My question is how do make the cursor change when hovering over the layer?
Has anyone implemented this feature before or have an idea to implement it? The only research I have stumbled across so far has using mouseover on the map and calling getFeatureInfo to tell if its over a layer. However, that seems like it would cause a lot of chatter just to identify cursor area.
EDIT: To clarify, I want the cursor to only change when its hovered over the wms layer that is populated. Although it technically gets applied to the whole map, it only has content on a part of it. Which kind of raises the question of 'Can I limit the wms layer to only the content area and then show a cursor?' Maybe a bounding area or something along those lines?
EDIT 2: Below is an example of what it looks like. The street map parts I want to keep the normal cursor but I want a pointer when hovering over the colored wms map parts.
Set an ID on the tileLayer's container and then use CSS to change the cursor:
Javascript:
var wms = L.tileLayer.wms("GEOSERVERURL", {
layers: 'layers',
format: 'image/png',
transparent: true
}).addTo(map);
wms.getContainer().setAttribute('id', 'wmsContainer');
Stylesheet:
#wmsContainer {
cursor: grab; /* or any other cursor: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor */
}
Note: you need to do this after the layer is added to the map. Before you add it to the map the getContainer method will return undefined.
Edit after question edit and comments:
Unfortunatly that's not possible. At least not as far as i know. Because L.TileLayer.WMS is a layer of images, there is absolutely no way of deducting which tiles have features on them and which are transparent.
What you could do as a workaround is work out the boundaries of your object, use that to create a transparent polygon without stroke and put that over your WMS layer. Polygons are interactive thus you get the cursorchange included, plus as an extra bonus, you can do other fancy stuff like show the outline or something like that on mouseover. I've created a little demo from the WMS example you supplied in the comments.
http://plnkr.co/edit/1HGn6IUzdrn1N5KGazXQ?p=preview
Note that i'm using a GeoJSON layer with one feature instead of a polygon, because it was easier to find the outline of the US in GeoJSON format. But in your case a four point polygon would do the trick just as wel.
Hope that helps, let me know if something isn't clear.

Categories

Resources