Leaflet with two switchable maps - maps

I have two types of map tiles, and I want to be able to switch between them using layers with a custom html control. Both will have the same tilesize and the other options that I have set. The only difference is that one is located in normal map folder and the other in gridmap folder.
This is the code that I use to display one map:
var map = L.map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
zoomControl: false,
crs: L.CRS.MySimple
}).setView([0, 0], 2);
L.tileLayer('normalmap/{z}/{x}/{y}.jpg', {
minZoom: mapMinZoom,
maxZoom: mapMaxZoom,
tileSize: 268,
noWrap: true,
tms: false,
continuousWorld: true
}).addTo(map);
I tried to follow the leaflet example: http://leafletjs.com/examples/layers-control.html
But no luck.
Can someone explain to me how to add 2 maps with a custom control?

Keep a reference to both your tile layers and add/remove them as appropiate:
var map = L.map(...);
var tilelayer1 = L.tileLayer('map1/{z}/{x}/{y}.jpg', { ... });
var tilelayer2 = L.tileLayer('map2/{z}/{x}/{y}.jpg', { ... });
tilelayer1.addTo(map);
document.getElementById('switch-layers').addEventHandler('click', function(ev){
if (map.hasLayer(tilelayer1)) {
map.addLayer(tilelayer2);
map.removeLayer(tilelayer1);
} else {
map.addLayer(tilelayer1);
map.removeLayer(tilelayer2);
}
})
Keep in mind that you can create layers and not add them to the map right away.

Related

Is there any event listener to check if the wms layer has loaded or not in google maps?

In a react web application, I am overlaying wms tiles on google maps using map's property overlayMapTypes.
if (map && activeLayer) {
let layer = new window.google.maps.ImageMapType({
getTileUrl: activeLayer.type === "wms" ? getTileUrl : getWMTSUrl,
tileSize: new window.google.maps.Size(256, 256),
minZoom: 0,
maxZoom: 24,
opacity: 1.0,
isPng: true,
});
map.overlayMapTypes.setAt(0, layer);
}
Some layers take time to load. So, I want to show a spinner or a message while the layer is
being loaded. Is there an event to get the status of it to check if it is still loading or loading is completed?
There is an event listener tilesloaded, but this is for the google maps base tiles, not for the overlayed map tiles.
useEffect(() => {
if (map) {
map.addListener("tilesloaded", () => {
console.log("Tiles Loaded");
});
}
}, [map]);
tilesloaded event listener is available for ImageMapType as well
let layer = new window.google.maps.ImageMapType({
getTileUrl: activeLayer.type === "wms" ? getTileUrl : getWMTSUrl,
tileSize: new window.google.maps.Size(256, 256),
minZoom: 0,
maxZoom: 24,
opacity: 1.0,
isPng: true,
});
map.overlayMapTypes.setAt(0, layer);
layer.addListener("tilesloaded", () => {
console.log("Overlay tiles loaded");
});

How to get lat lang of top left and bottom right of map when zoomed

I am trying to get top left and right bottom of the Map which i am displaying. And i am trying to get this particular data in zoom event, but somehow this.map is becoming undefined and breaking the application
this.map.on('zoomend', function (layer) {
console.log("zoom",layer.target._zoom)
console.log("getbounds", this.map.getBounds());
});
Below i am providing the componentDidMount, here only i am defining zoom event, which working fine if i simply console.
componentDidMount() {
/* We are loading the map here whether or not load has loaded */
this.map = L.map('map', {
center: [50, 10],
zoom: 3,
minZoom: 2,
maxZoom: 11,
zoomControl: false,
attributionControl: false,
scrollwheel: false,
legends: true,
infoControl: false,
});
console.log("getbounds", this.map.getBounds()); //WORKING BUT JUST ONCE, when this component mounts.
this.map.on('zoomend', function (layer,a) {
console.log("zoom",layer.target._zoom)
console.log("zoom",layer)
console.log("a",a)
console.log("getbounds", this.map.getBounds()); // NOT WORKING, this.map GETS UNDEFINED which is obvious also.
});
/* Giving zoom control a different place in UI */
L.control.zoom({ position: 'topright' }).addTo(this.map);
L.control.scale({ position: "topright" }).addTo(this.map);
/* Selecting and showing styles for the map */
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
}).addTo(this.map);
}
Just change this part of your code bro
this.map.on('zoomend', (layer,a) => {
console.log("zoom",layer.target._zoom)
console.log("zoom",layer)
console.log("a",a)
console.log("getbounds", this.map.getBounds()); // NOT WORKING, this.map GETS UNDEFINED which is obvious also.
});
The reason why your code did not work is you were using simple function as a callback which need to bind to use this.
Solution: Use arrow function

LeafletJS not loading all tiles until moving map

I am trying to load a simple leaflet map in my Ionic 2 app. Unfortunately not all tiles are loaded currectly until a moving the map.
this.map = new L.Map('mainmap', {
zoomControl: false,
center: new L.LatLng(40.731253, -73.996139),
zoom: 12,
minZoom: 4,
maxZoom: 19,
layers: [this.mapService.baseMaps.OpenStreetMap],
attributionControl: false
});
There are a couple of solutions for this problem:
1- Add "./node_modules/leaflet/dist/leaflet.css" in the styles array in `angular.json'.
2- Invalidate size when a map is ready:
onMapReady(map: L.Map) {
setTimeout(() => {
map.invalidateSize();
}, 0);
}
Add this to your template:
<div style="height: 300px;"
leaflet
(leafletMapReady)="onMapReady($event)">
</div>
And this will bind onMapReady method which you have in your component.
3- Install Leaflet typings for Typescript:
npm install --save-dev #types/leaflet
Vanilla JavaScript:
1- Validate the size of map:
onMapReady(map: L.Map) {
setTimeout(() => {
map.invalidateSize();
}, 0);
}
2- Add leaflet stylesheet leaflet/dist/leaflet.css in the <head> of your document.
this work for me fine :
this.map = L.map('map');
const self = this;
this.map.on("load",function() { setTimeout(() => {
self.map.invalidateSize();
}, 1); });
this.map.setView([36.3573539, 59.487427], 13);
Just put the creation of the map into the Ionic ionViewDidEnter lifecycle method. Much cleaner than any setTimeout hack ;)
import { Map, tileLayer } from 'leaflet';
...
ionViewDidEnter(): void {
this.map = new Map('map', {
center: [48.1351, 11.5819],
zoom: 3
});
const tiles = tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
minZoom: 3,
attribution: '© OSM'
});
tiles.addTo(this.map);
}

3D map visualization in Angular Google Maps

Preamble
I'm using Angular Google Maps to indicate the location of different buildings across a campus. My initilization goes as follows:
$scope.map = {
control: {},
center:
{
latitude: $scope.Item.Latitude,
longitude: $scope.Item.Longitude
},
zoom: 16,
options: {
streetViewControl: true,
maxZoom: 20,
minZoom: 8,
mapTypeId: google.maps.MapTypeId.HYBRID
},
showTraffic: true,
showBicycling: true,
events: {
blacklist: ['drag', 'dragend', 'dragstart', 'center_changed']
}
};
That works flawlessly for the following visualization:
However, I just noticed that there is 3D data available for the region, and I would like to have it renderized as such:
Question
Is it possible, via Angular Google Maps, to configure my initialization in such a way as to show the map as indicated?
Bonus Question
...would it be possible to programatically have the 'camera' spin around the marker (or the center)?
This is the Map link for the reference images:
https://www.google.com/maps/#40.9570608,-76.8816097,179a,20y,180h,41.69t/data=!3m1!1e3
The best you can get with the Google Maps Javascript API is the 45° imagery.
Not like the 3D map visualization, 45° imagery only has:
1) the 45° tile...
2) 4 angels (0, 90, 180, 270)
3) only has SATELLITE mode. (Road names and other maps elements isn't shown even the maps is in HYBRID)
4) it is not available everywhere over the globe. (for example, 40.9570608,-76.8816097)
Look at this example for more information.
http://jsfiddle.net/u1qcf892/

openlayers inside qooxdoo JS framework

i´m using the openlayers drawing example inside my mobile JS (qooxdoo) app and all works fine except that the drawing cursor is above the viewport
so I can draw but I don´t see the cursor and I can only see the drawing after I scroll down.
I have used this qooxdoo example as a base. I have also added all the css rules from the openlayers example to my qooxdoo styles.
Seems like a css position issue, but I can´t seem to find it.
Any help would be appreciated.
/**
* Loads JavaScript library which is needed for the map.
*/
_loadMapLibrary: function() {
var self = this;
var req = new qx.bom.request.Script();
var options = {
singleTile: true,
ratio: 1,
isBaseLayer: true,
wrapDateLine: true,
getURL: function() {
var center = self._map.getCenter().transform("EPSG:3857", "EPSG:4326"),
size = self._map.getSize();
return [
this.url, "&center=", center.lat, ",", center.lon, "&zoom=", self._map.getZoom(), "&size=", size.w, "x", size.h].join("");
}
};
req.onload = function() {
var vector = new OpenLayers.Layer.Vector('Vector Layer', {
styleMap: new OpenLayers.StyleMap({
temporary: OpenLayers.Util.applyDefaults({
pointRadius: 16
}, OpenLayers.Feature.Vector.style.temporary)
})
});
// OpenLayers' EditingToolbar internally creates a Navigation control, we
// want a TouchNavigation control here so we create our own editing toolbar
var toolbar = new OpenLayers.Control.Panel({
displayClass: 'olControlEditingToolbar'
});
toolbar.addControls([
// this control is just there to be able to deactivate the drawing
// tools
new OpenLayers.Control({
displayClass: 'olControlNavigation'
}), new OpenLayers.Control.ModifyFeature(vector, {
vertexRenderIntent: 'temporary',
displayClass: 'olControlModifyFeature'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Point, {
displayClass: 'olControlDrawFeaturePoint'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Path, {
displayClass: 'olControlDrawFeaturePath'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Polygon, {
displayClass: 'olControlDrawFeaturePolygon'
})]);
var osm = new OpenLayers.Layer.OSM();
osm.wrapDateLine = false;
map = new OpenLayers.Map({
div: 'googleMap',
projection: 'EPSG:900913',
numZoomLevels: 18,
controls: [
new OpenLayers.Control.TouchNavigation({
dragPanOptions: {
enableKinetic: true
}
}), new OpenLayers.Control.Zoom(), toolbar],
layers: [osm, vector],
center: new OpenLayers.LonLat(0, 0),
zoom: 1,
theme: null
});
// activate the first control to render the "navigation icon"
// as active
toolbar.controls[0].activate();
}
req.open("GET", this._mapUri);
req.send();
},
Please check the z-Index of the cursor's class. The best way is to modify the z-Index through Chrome's debugger console or Firebug.
Is there any live example of your application available?

Resources