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

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?

Related

MapQuest/Leaflet - How to trace routes between marquers with gps coordinates?

I have managed to integrate mapquest within my leaflet maps which was initially showing markers on the map. Below is an example with markers showing photographs taking during a trip in Namibia.
https://www.paulgodard.com/map?c=2108_DesolationValley&p=travel&m=images
Terms
Blog
Routes between marquers with gps coordinates
1 post / 0 new
Quick reply
Thu, 08/19/2021 - 06:10
#1
Paul Godard
Routes between marquers with gps coordinates
I have managed to integrate mapquest within my leaflet maps which was initially showing markers on the map. Below is an example with markers showing photographs taking during a trip in Namibia.
https://www.paulgodard.com/map?c=2108_DesolationValley&p=travel&m=images
I already have an array of locations and I would like to display the routes in between each marker. What is the best way to do this?
window.mapData = #json($mapData);
window.onload = function() {
L.mapquest.key = 'mykey';
var map = L.mapquest.map('mapOSM', {
center: [0,0],
layers: L.mapquest.tileLayer('map'),
zoom: 10
});
map.addControl(L.mapquest.control());
var mainIcon = L.Icon.extend({ options: {
iconSize: [24,24],
iconAnchor: [12,24], // half of x | full y
popupAnchor: [0,-12] // x = 0 | - half y
}});
var oms = new OverlappingMarkerSpiderfier(map);
var bounds = new L.LatLngBounds();
for (var i = 0; i < window.mapData.length; i ++) {
var datum = window.mapData[i];
var loc = new L.LatLng(datum.lat, datum.lon);
bounds.extend(loc);
var mapIconURL = '/public/assets/icons/' + datum.icon;
mapIconURL = mapIconURL.replace(/\s+/g,'');
var marker = new L.Marker(loc, { icon: new mainIcon({iconUrl: mapIconURL}) });
marker.desc = datum.popup; //JSON.parse(datum.popup);
//if ($i=0) { alert(datum.popup); }
map.addLayer(marker);
oms.addMarker(marker);
}
if (window.mapData.length > 0) {
map.fitBounds(bounds);
} else {
map.center(window.mapData[0].lat,window.mapData[0].lon);
map.zoom(1);
}
var popup = new L.Popup({closeButton: false, offset: new L.Point(0.5, -24)});
oms.addListener('click', function(marker) {
popup.setContent(marker.desc);
popup.setLatLng(marker.getLatLng());
map.openPopup(popup);
});
oms.addListener('spiderfy', function(markers) { map.closePopup(); });
oms.addListener('unspiderfy', function(markers) { });
}
You can start with the Leaflet Routing Plugin here: https://developer.mapquest.com/documentation/leaflet-plugins/routing/
Routing in Namibia might get iffy though.

Get FeatureId of target in popup on vector layer in Leaflet

The below code works ok, I get lots of interesting data in getFeatureId.
How do I get my hands on that in the popup ?
var map = L.map('map').setView([53.505, -7.09], 7);
L.tileLayer('https://{s}.etc.etc/{z}/{x}/{y}.png', {
attribution: 'osm..'
}).addTo(map);
var VectorTileOptions = {
rendererFactory: L.canvas.tile,
attribution: '',
interactive: true,
getFeatureId:function(feat){
return feat.properties.routes
}
};
var TilesPbfLayer = L.vectorGrid.protobuf(tileurl, VectorTileOptions).addTo(map);
var popup = L.popup();
map.on('popupopen', function(e) {
popup.setContent("how do i get the feature Id ? ")
});
TilesPbfLayer.bindPopup(popup)
I can get a click event on the tile layer, and its got a layer with my stuff in
TilesPbfLayer.on('click', function(e) {
if (e.layer)
popup.setContent(e.layer.properties.routes)
})

Changing overlay layers when switching base layer

I have built a leaflet map with two base layers, and each of these base layers will have their own unique points of interest. The points of interest are being stored as geojson that I loop over to create multiple overlays for different categories. So when viewing the default base layer you would see layers for Show All, Cat1, Cat2 etc.
I need a way to be able to attach overlay layers to a base layer, or remove all overlay layers and then load the relevant ones when the base layer changes.
I tried using the following, which worked to switch categories, with the baselayerchange event, but the overlay layers were still displaying when I switched base layers.
layerControl._layers.forEach(function(layer){
if(layer.overlay){
map.removeLayer(layer.layer)
}
});
I've been searching for a couple of days now for an answer to this without any luck, any help is greatly appreciated.
EDIT
Posting additional code for context. This is not the entirety of the code, there are some plugins that I'm not including code for and have excluded definitions for a several variables, but this should provide better insight into how things are working.
//Initialize the map
var map = new L.Map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: crs1848,
attributionControl: false,
layers: [pano1848]
});
//add controls to the map
var layerControl = L.control.layers(null, null, {position: 'bottomleft'}).addTo(map);
//building category layers from geojson
var types = ['African Americans', 'Art Architecture Culture', 'Education Religion Reform', 'Everyday Life', 'Immigrants', 'Science Inventions', 'Transportation Industry Commerce'];
types.forEach(function(type){
var catType = type.replace(/\s/g,"");
var catPoints = L.geoJson(mapData, {
filter: function(feature, layer){
var cat = feature.properties['category'];
return cat.indexOf(catType) >= 0;
},
onEachFeature: function (feature, layer) {
layer.bindTooltip(feature.properties.name);
(function(layer, properties){
//Create Numeric markers
var numericMarker = L.ExtraMarkers.icon({
icon: 'fa-number',
markerColor: 'yellow',
number: feature.properties['id']
});
layer.setIcon(numericMarker);
layer.on('click', function() {
$.ajax({
url:feature.properties['url'],
dataType:'html',
success: function(result){
$('#detailContainer').html(result);
$('#overlay').fadeIn(300);
}
});
});
})(layer, feature.properties);
}
});
layerControl.addOverlay(catPoints, catType);
});
//Base Layer Change Event
map.on('baselayerchange', function(base){
var layerName;
layerControl._layers.forEach(function(layer){
if(layer.overlay){
map.removeLayer(layer.layer)
}
});
if(base._url.indexOf('1848') >= 0){
map.options.crs = crs1848;
map.fitBounds([
crs1848.unproject(L.point(mapExtent1848[2], mapExtent1848[3])),
crs1848.unproject(L.point(mapExtent1848[0], mapExtent1848[1]))
]);
var southWest = map.unproject([0, 8192], map.getMaxZoom());
var northEast = map.unproject([90112, 0], map.getMaxZoom());
map.setMaxBounds(new L.LatLngBounds(southWest, northEast));
map.addLayer(allPoints);
layerName = '1848 Panorama';
}
else if(base._url.indexOf('2018') >= 0){
map.options.crs = crs2018;
map.fitBounds([
crs2018.unproject(L.point(mapExtent2018[2], mapExtent2018[3])),
crs2018.unproject(L.point(mapExtent2018[0], mapExtent2018[1]))
]);
var southWest = map.unproject([0, 8192], map.getMaxZoom());
var northEast = map.unproject([49152, 0], map.getMaxZoom());
map.setMaxBounds(new L.LatLngBounds(southWest, northEast));
layerName = '2018 Panorama'
}
miniMap.changeLayer(minimapLayers[layerName]);
//map.setView(map.getCenter(), map.getZoom());
});
You may create global variable call "overlays", and remove it like an example below.
Here is the similar example to illustrate your problem jsFiddle
var overlays = {
'Name 1': catPoints,
'Name 2': catType
};
L.control.layers(null, overlays).addTo(map);
// Whenever you want to remove all overlays:
for (var name in overlays) {
map.removeLayer(overlays[name]);
}

Leaflet Clustering with multiple layers (use MarkerCluster.LayerSupport?)

Alright, so I've tried and failed a number of times and dug through SE hoping to figure out my problems.
I've been basing a lot of my work off this SE post: link.
I have been unable to make this work, mainly because of two errors, but the first one being an obvious hurdle to overcome first:
Error 1:
Uncaught SyntaxError: Unexpected token <
Error 2:
Uncaught TypeError: L.markerClusterGroup.layerSupport is not a function
So, I would like clustering to work with any layer that is turned on via the L.control.layers() function.
Here is my page, as it sits now: TN Alcohol Map
And the code, sans headers/misc:
// initialize the map
var map = L.map('map').setView([36.17, -86.78], 7);
// load a tile layer/base map
L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png',
{
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
maxZoom: 18,
minZoom: 7
}).addTo(map);
//attributes for basemap credit (lower right hand corner annotation)
var streetsAttr = 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap';
var aerialAttr = 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community';
var artsyfartsyAttr = 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap';
//crete variables for the base map layer switcher
var streets = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png', {id: 'MapID', attribution: streetsAttr}),
aerial = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {id: 'MapID', attribution: aerialAttr}),
artsyfartsy = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', {id: 'MapID', attribution: artsyfartsyAttr});
//create baseMaps variable to store basemap layer switcher
var baseMaps = {
"Streets": streets,
"Aerial": aerial,
"ArtsyFartsy": artsyfartsy
};
// BEER icon & load beer geojson
var beerIcon = L.icon({
iconUrl: 'glass.png',
iconSize: [24, 48]
});
var beerMarker = L.geoJson(false, {
pointToLayer: function(feature, latlng) {
var marker = L.marker(latlng, {
icon: beerIcon
});
//popup shows NAME, ADDRESS, URL and opens the URL in a new window/tab
marker.bindPopup("<strong>" + feature.properties.NAME + "</strong><br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + "<br/>" + "<a target = _blank href=" +
feature.properties.URL + ">" + feature.properties.URLDISPLAY + "</a>");
return marker;
}
}).addTo(map);
$.getJSON("breweries.geojson", function(data) {
beerMarker.addData(data);
});
// WINE icon & load wine geojson
var wineIcon = L.icon({
iconUrl: 'wine.png',
iconSize: [48, 48]
});
var wineMarker = L.geoJson(false, {
pointToLayer: function(feature, latlng) {
var marker = L.marker(latlng, {
icon: wineIcon
});
//popup shows NAME, ADDRESS, URL and opens the URL in a new window/tab
marker.bindPopup("<strong>" + feature.properties.NAME + "</strong><br/>" + feature.properties.STREETNUM + " " + feature.properties.STREET + ", " + feature.properties.CITY + "<br/>" + "<a target = _blank href=" +
feature.properties.URL + ">" + feature.properties.URLDISPLAY + "</a>");
return marker;
}
}).addTo(map);
$.getJSON("wine.geojson", function(data) {
wineMarker.addData(data);
});
//Define overlay maps (non-base layer maps)
var overlayMaps = {
"Breweries": beerMarker,
"Wineries": wineMarker
};
//Creates a Marker Cluster Group
var mcg = L.markerClusterGroup.layerSupport().addTo(map);
//Checking in the 'sub groups'
mcg.checkIn([
beerMarker,
wineMarker
]);
//baseMaps layer switcher
L.control.layers(baseMaps, overlayMaps).addTo(map);
As said by nathansnider in the question comment, the content of your leaflet.markercluster.layersupport-src file is not the JavaScript code of the markerCluster.LayerSupport plugin, but the GitHub HTML page that displays the code of that file, i.e. surrounded by plenty HTML code.
You should simply replace the content of your file by the content of the raw file here: https://raw.githubusercontent.com/ghybs/Leaflet.MarkerCluster.LayerSupport/master/leaflet.markercluster.layersupport-src.js
Demo: http://plnkr.co/edit/Jd8skZ1U0bWxgl2orJV6?p=preview
Side note:
If you just need the Layers Control to work with Leaflet.markercluster, there is another plugin that does just that and which is much simpler: Leaflet.FeatureGroup.SubGroup (230 lines of code v.s. 600 lines for Leaflet.MarkerCluster.LayerSupport as of today).
In your case you would use it this way:
// Create a normal Marker Cluster Group.
var mcg = L.markerClusterGroup().addTo(map);
// Create SubGroups.
var beerMarkerSub = L.featureGroup.subGroup(mcg).addTo(map);
var wineMarkerSub = L.featureGroup.subGroup(mcg).addTo(map);
// For Layers Control.
var overlayMaps = {
"Breweries": beerMarkerSub,
"Wineries": wineMarkerSub
};
// That is it! No need to check-in.
Code specific for your application, since you load GeoJSON data by AJAX:
var beerMarker = L.geoJson(null, beerOptions); // DO NOT add to map.
var wineMarker = L.geoJson(null, wineOptions); // Same story.
$.getJSON("breweries.geojson", function(data) {
beerMarker.addData(data); // GeoJSON conversion.
// Then transfer all features into the corresponding sub-group.
beerMarker.eachLayer(function (layer) {
layer.addTo(beerMarkerSub);
});
});
$.getJSON("wine.geojson", function(data) {
wineMarker.addData(data); // GeoJSON conversion.
// Then transfer all features into the corresponding sub-group.
wineMarker.eachLayer(function (layer) {
layer.addTo(wineMarkerSub);
});
});
Demo: http://plnkr.co/edit/x8vTLjE53TPiLd52BQ1d?p=preview
Disclosure: I am the author of these plugins.

create web map layers from multiple mbtiles on multiple servers

I'm using this http://blog.carte-libre.fr/index.php?post/2012/02/12/Serve-all-MBTtile-features-with-PHP-script to create a web map with mbtiles hosted on my server.
I want to create selectable layers using several mbtiles (mb1, mb2, mb3) which are stored on different servers (serv1, serv2, serv3).
The script is
wax.tilejson(
'mbtiles-server.php?db=mb1.mbtiles',
function(tilejson) {
var omq = new L.TileLayer(
'http://otile2.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {
maxZoom: 14,
attribution: 'OpenStreetMap - MapQuest',
opacity: 0.4,
});//modify to call mb2 from serv3
var power = new L.TileLayer(
"mbtiles-server.php?db=mb1.mbtiles&z={z}&x={x}&y={y}", {
maxZoom: 14,
attribution: 'OpenStreetMap - CL 2012-02-05',
});
var map = new L.Map('map', {
center: new L.LatLng(46, 0),
zoom: 6,
layers: [omq, power]
});
map.addControl( new L.Control.Layers( { "OpenMapQuest": omq }, { "Power": power }));
wax.leaf.interaction(map, tilejson);
document.getElementById("legend").innerHTML = tilejson.legend;
});
Assuming there is a php script file in each mbtiles folder, how can I modify the script to be able to call mb2 from serv3 so that i have 2 layers from 2 mbtiles hosted on 2 servers?
any advice would be welcomed!
An update...
The issue was trying to load several mbtiles while having respective popup interactions for each layer (each mbtile included interaction, created in TileMill).
I opted to load the mbtiles to the map using:
var base1 = L.tileLayer("http://ms1.mysite.com/folder1/mbtiles-server.php?db=base1layer.mbtiles&z={z}&x={x}&y={y}.png"
var base2 = L.tileLayer("http://ms2.mysite.com/folder2/mbtiles-server.php?db=base2layer.mbtiles&z={z}&x={x}&y={y}.png"
Then added interaction from a separate geojson file.
var onEachFeature_Polygon = function (feature, layer) {
//polygon geojson file contains center points
var centerLat = feature.properties.y;
var centerLon = feature.properties.x;
var centLatLon = new L.LatLng(centerLat, centerLon); //this is used to place the popup in the "mouseover" function
layer.setStyle(tooltip_default_style);
if (feature.properties && feature.properties.Name) {//fields Name, Population, RI10K
var list = "<b>" + feature.properties.Name + "</b>" + "<br>" + "<i>" + "Population: " + feature.properties.Population + "</i>" + "<br>" + "<i>" + "Income 10,000+: " + feature.properties.RI10K + "</i>" + "<br>";//end of tooltip list
layer.bindPopup(list);
}
layer.on("mouseover", function (e) {
layer.setStyle(tooltip_hover_style);
layer.openPopup(centLatLon);
});
layer.on("mouseout", function (e) { layer.setStyle(tooltip_default_style) });
}
//this is the onEachFeature function called when the statsJSON layer is added to the map
var statsinteractive = new L.GeoJSON(statsgeo, { onEachFeature: onEachFeature_Polygon });
statsinteractive.addTo(map);
Would still like to understand or be directed to a clearly outlined method to 'call' interaction from an mbtile file.
In the meantime, I hope this is helpful for someone with a similar issue.