Zoom to a country on a map when you click on a the country's name on a list - leaflet

I have a application that shows a highlighted list of countries on a map and their names in a side panel
I would like to make the following happen: When you click on the name of a country in the side panel. you zoom to the country on the map.
I am not sure how to make this happen and would appreciate it if someone point me to an example or suggest the best way to make this happen

Really depends upon your set-up and I'am assuming you are using geoJSON. In a project I worked on, I created a function that is ran once you click from a list that zooms to the corresponding geoJSON ... or you could attach the leaflet ID for each geoJSON layer to the corresponding elements of the list if the list populated from the geoJSON.
markers - collected geoJSON
layer.feature.properties.pin - the corresponding key that matches the listed record with the geoJSON (this needs to match your data)
pin - the corresponding element from the list (this needs to match your data)
The 1st setStyle - highlights the geoJSON
map.fitbounds - zooms to highlighted info
The 2nd setStyle - changes all of the other geoJSON layers back to the original style.
function selectedparcel(pin){
markers.eachLayer(function (layer){
if (layer.feature.properties.pin === pin){
layer.setStyle({
fillColor: '#2262CC',
fillOpacity: 1,
weight: 3
});
//this is where the zoom happens
map.fitBounds(layer.getBounds());
} else {
layer.setStyle({
color: '#ff7800',
weight: 1,
opacity: 1,
fillOpacity: 0
});
}
});
I hope this is what you were looking for. If you want to use the leaflet id method Bryan McBride has an example within his js code here:
https://github.com/bmcbride/building-damage-reporter

Related

Dragging/moving multiple geojsons on leaflet-geoman

I'd like to move/drag geojson features on map so that the distance to each other stays the same.
Choose geojsons by clicking them and then dragging them together. How should I make this?
Thanks!
I read about syncLayersOnDrag but can not get it to work.
If you set syncLayersOnDrag after adding the layer, it works
// data are coming from smaple-geojson.js
const geoLayer = L.geoJSON([bicycleRental, campus]).addTo(map)
map.fitBounds(geoLayer.getBounds())
map.pm.setGlobalOptions({
syncLayersOnDrag: true
});
https://jsfiddle.net/zba1ogjL/

how to hide/show layers in Mapbox

I want to be able to hide and show/layers in Mapbox like this example provided by Mapbox.... https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/
I have some vector data saved as a tile set in Mapbox, but I don't know where to find the URL is shown in the example below as 'mapbox://mapbox.2opop9hr'. Can anyone tell me how to find it for my own data?
// Wait until the map has finished loading.
map.on('load', () => {
// Add a custom vector tileset source. This tileset contains
// point features representing museums. Each feature contains
// three properties. For example:
// {
// alt_name: "Museo Arqueologico",
// name: "Museo Inka",
// tourism: "museum"
// }
map.addSource('museums', {
type: 'vector',
url: 'mapbox://mapbox.2opop9hr'
});
mapbox://mapbox.2opop9hr is a reference to a mapbox custom vector tileset. You can make one of your own by uploading data in Mapbox Studio: https://docs.mapbox.com/studio-manual/reference/tilesets/. Mapbox will then serve this tileset for your map to consume.
However, this isn't necessary to toggle map layers using the technique shown in the example. map.setLayoutProperty() can be used to show or hide any layer, including layers that came with the base style, or layers added after the fact using vector tiles or geojson sources.
If you are working with small/simple data, you may want to just add a geojson source and layer, and then use setLayoutProperty() to show and hide it as in the example.

Mapbox GL JS Set Paint property on specific Feature in Layer

I am using Mapbox Studio as basis for mapping and styling and then using HTML for additional map features.
One of the features is to change Icon opacity when hovering or mouse enter. I've checked other examples and all other refer to feature when you create it directly in HTML. I managed to change opacity but only for whole layer.
Can I use somehow e.features[0] command line to apply changes only to one feature rather than to whole layer?
I used this code which changer opacity for whole Layer 'Icon' (Layer contains 5 icons with text):
// Change the cursor to a default and change opacity when the it enters a feature in the 'Icons' layer.
map.on('mouseenter', 'Icons', function() {
map.getCanvas().style.cursor = 'default';
var feature = e.features[0];
map.setPaintProperty('Icons', 'icon-opacity', 0.5);
});
// Change it back to a pointer and reset opacity when it leaves.
map.on('mouseleave', 'Icons', function() {
map.getCanvas().style.cursor = '',
map.setPaintProperty('Icons', 'icon-opacity', 1);
});
Thank you!!!
There are a few ways which you could achieve this. One approach is to add each feature as separate layer, so that when you want to change the opacity of an icon added in a layer 'specific-icon-layer', you can pass 'specific-icon-layer' to the Map#on method. This is likely the most straightforward option if you have a relatively minimal number of markers.
Another approach is to add unique IDs to each icon feature, so that you can use a filter expression in conjunction with Map#setPaintProperty and Map#queryRenderedFeatures (or Map#querySourceFeatures). For example, suppose you add an 'id' property to each GeoJSON feature representing an icon in the source for the 'Icons' layer. Then, you could set up an event listener similar to this example, retrieve the 'id' of the returned feature, and use the 'id' (suppose here it is 'example-id') to update the paint property for the 'Icons' layer:
map.setPaintProperty(
'Icons',
'icon-opacity',
['match', ['get', 'id'], 'example-id', 0.5 , 1]
);
Here, we use match and get expressions to say "if the 'id' of a feature is 'example-id', paint its icon with opacity 0.5, otherwise use opacity 1."
Check the example at https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/
This approach makes use of setFeatureState and feature-state expressions
The problem with using map.setPaintProperty(layer, property, filter, matchValue, styleValue, fallbackStyleValue) every time is that it restyles every feature on the layer instead of only the feature being interacted with. This can cause poor performance when the layer has a high number of features.

Click-through markers and polylines in Leaflet

In Leaflet, is it possible to define a marker or polyline with {clickable:false}, so that a click is passed through to whatever lies beneath - be it the map or a clickable geometry object?
At the moment I solve this problem by making the marker/polyline clickable and passing the event onwards myself. But this leads to the mouse cursor always showing as the hand symbol. Ideally, the mouse cursor should look like the normal pointer or the hand, depending on whether what is beneath the marker/polyline is clickable.
This may not be the answer you are looking for, but you can use featureGroups to have all of your clickable polylines come to the front so that the actions are surfaced.
var lg_noclick = new L.FeatureGroup().addTo(map);
var lg_click = new L.FeatureGroup().addTo(map);
// Add lines
lg_click.bringToFront();
updated fiddle
Also if you can afford to know your lines before hand, correct ordering of when you add the lines it will work as well.
I know this is not ideal but it suited my situation just fine, so it might be good for you as well.
This hides the icon and brings it back after a second using mouseenter and mouseleave events:
$('.leaflet-marker-icon').mouseenter(function() {
$(this).hide();
});
$('.leaflet-marker-icon').mouseleave(function() {
$(this).delay(1000).show(0);
});

Virtual Earth (Bing) Pin "moves" when zoom level changes

Created a Virtual Earth (Bing) map to show a simple pin at a particular point. Everything works right now - the pin shows up, the title and description pop up on hover.
The map is initially fully zoomed into the pin, but the STRANGE problem is that when I zoom out it moves slightly lower on the map. So if I started with the pin pointing somewhere in Toronto, if I zoom out enough the pin ends up i the middle of Lake Ontario! If I pan the map, the pin correctly stays in its proper location. When I zoom back in, it moves slightly up until it's back to its original correct position!
I've looked around for a solution for a while, but I can't understand it at all. Please help!!
Thanks a lot!
import with javascript: http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2
$(window).ready(function(){
GetMap();
});
map = new VEMap('birdEye');
map.SetCredentials("hash key from Bing website");
map.LoadMap(new VELatLong(43.640144 ,-79.392593), 1 , VEMapStyle.BirdseyeHybrid, false, VEMapMode.Mode2D, true, null);
var pin = new VEShape(VEShapeType.Pushpin, new VELatLong(43.640144 ,-79.392593));
pin.SetTitle("Goes to Title of the Pushpin");
pin.SetDescription("Goes as Description.");
map.AddShape(pin);
I had the same problem. However, my code looks to be using the Microsoft.Maps AJAX methods.
I set locations of events on a bing map that I got from querying facebook's api for user_events and friend_events. An event was returned to me with the latitude and longitude.
I used those coordinates to place a custom styled pin for single pins and clustered pins.
When I zoomed out the potions would move and an un-realistic representation was provided about the location of the event.
ANSWER:
I found out you have to set the "anchor" property for the pushpin.
Here is what I found that works well.
var pushpinOption = {
icon : 'images/cluster_custom.png',
text : ''+ clusterInfo.dataIndices.length + '',
textOffset:offset,
anchor : new Microsoft.Maps.Point(8, 8)
};
Resources :
Example of using anchor pushpinoption
Note* Look at the "Load Module Clustering"
You will need to click the first link in the "Load modules section"
http://www.bingmapsportal.com/isdk/ajaxv7#LoadingDynamicModule2
documentat ion of pushpin option "anchor"
http://msdn.microsoft.com/en-us/library/gg427629.aspx
Not exactly the/an answer you're looking for but, I have the exact problem and found that the "move" happens on my pins that I have declared a scale transform for.
StoreEditPushPin pin = new StoreEditPushPin(Colors.Red);
pin.Location = new Location(43.640144 ,-79.392593);
ScaleTransform st = new ScaleTransform();
st.ScaleX = 0.55;
st.ScaleY = 0.55;
pin.RenderTransform = st;
PushPinLayer.AddChild(pin, d);
When you zoom out, the scale factor is applied to the pin and the location is shifted. I would take a look at your Pushpin class to see if the transform exists.
Try adding PositionOrigin to the pushpin, set it to "Center" or whatever.