How to switch layers[] in esri leaflet dynamiclayer - javascript

I have a single MapService with multiple layers. I'd like to utilize layer group for changing layers with radio buttons, but want to use it with the layers[] array option rather that creating a single L.esri.dynamicMapLayer etc... for each layer.
Here is a sample snippet:
var msndfd = "https://nowcoast.noaa.gov/arcgis/rest/services/nowcoast/forecast_meteoceanhydro_sfc_ndfd_time/MapServer";
var minTemp = L.esri.dynamicMapLayer({
url: msndfd,
layers: [8],
opacity: .7
});
How do we switch layers based on that layers array # such as [4,8,12,16] while using the L.control.layers(baseMaps, overlayMaps)? So each of the overlayMaps would essentially be a layer# not another dynamicMapLayer variable such as minTemp in my example above.

the way Leaflet's layers control is currently written is to add/remove layers from the map in reaction to user interaction with the checkboxes and radio buttons.
if you'd like to organize things so that choosing a different radio ensures that L.esri.dynamicMapLayer.setLayers() is called instead, you'd have to customize the control to lay out its UI differently (referencing a single base layer and an array of sublayers to toggle) and ensure that the appropriate action occurs when a new radio is selected.
existing logic for laying out the list -
Control.Layers.js#L313-L322
existing logic for responding to user interaction -
Control.Layers.js#L382-L387
my gut reaction is that you'd probably be better off accepting how the control is already designed, but i'm sure you have your reasons.

Related

Cesium -- on click, change map point to standard marker with icon

I am attempting to mimic the the functionality one would see using the Waze LiveMap (https://www.waze.com/livemap) in Cesium. When a point is clicked, it is converted to a marker with an icon.
I've attempted a few different things with varying levels of success and I'm at my wits end. Does anyone have a good suggestion as to how I can proceed?
There are a couple different ways of doing this, some high-level and some lower-level. The high-level one is easiest so I'll start there. The Cesium Viewer fires an event called selectedEntityChanged when its own selection changes, and you can wire that up to toggle billboard show flags on and off.
Here's a demo. For this demo, I took the original map pins demo and added some lines of code: I turned off the show flags for all the billboards at the start, I added points to stand in for the now-hidden billboards, and I added the following block of code to toggle the billboard show flags when selected, like this:
var lastSelectedPin;
viewer.selectedEntityChanged.addEventListener(function(newEntity) {
if (lastSelectedPin && lastSelectedPin.billboard) {
lastSelectedPin.billboard.show = false;
}
lastSelectedPin = newEntity;
if (lastSelectedPin && lastSelectedPin.billboard) {
lastSelectedPin.billboard.show = true;
}
});
This uses Cesium Viewer's own selection system, but toggles the billboard show flag to appear when selected and disappear when de-selected.
Alternatively, you can dig into Cesium's lower levels for finer control, but there will be a longer learning curve. The Picking Demo shows off several types of picking operations, including scene.pick, scene.drillPick, and camera.pickEllipsoid, which offer various ways to detect what contents exist at a particular screen location. Often these functions are called in response to mouse movements or clicks, or touch/pointer events, to see what the user is interacting with.

Update map panes and legend dynamically on leaflet

I'm trying to use leaflet to make an interactive map (like a choropleth) using data from geojson files and I've a problem to update data and legend on the map, dynamically.
My code use a leaflet map with a mapbox-light baselayer, a dropdownlist and a legend. Two jsons files are loaded and I use two map panes to use them and set their z-index. Dropdownlist has two options and is used to change the selected geojsons to expand this example; the real case has 25 values to choose.
I use $(id_dropdownlist).change to make everything. If ddl change:
remove panes if these exists.
select geojsons files using ddl value (default url myjson files + ajax for this example).
add panes, load and color polygons.
When I make the first change in the ddl works fine: select geojsons files, load and color polygons. My problem appears from the second change onwards, after remove panes: geojsons are loaded successfully but these are not showed/colored on my map.
My amateur debugging detect than in the first change the div leaflet-pane element has the geojsons values, but from the second change onwards the same div leaflet-pane has not data.
Also, I want to update the legend at same time after load the geojsons, but I do not have any idea how to make that.
Here is a functional example in JSFiddle.
If someone could help me step by step, for learn it, I would be very grateful. If panes are not the way to do this, or another way to do this better, please tell me how.
When user changes the selection of your drop down list, you first try to clear your map by removing your previously created custom panes from the DOM.
There is a very high chance Leaflet does not expect such fiddling with its panes, even if they are custom. That is probably why when you create new custom panes with the same names, Leaflet does not reference them correctly, hence it does not display your new layers in those new panes.
For adding and removing your layers dynamically to / from the map, you should simply use Layer Groups instead. In particular, it provides you with a clearLayers method that does what you are trying to achieve.
Therefore, you just add your polygons and markers to that Layer Group (instead of directly to the map), so that you can easily clear them when the user selects a new value. The custom panes remain unaffected.
// Initialize the Layer Group.
// Add it to map so that its children will appear on map.
var layerGroup = L.layerGroup().addTo(map);
// On <select> "change" event:
layerGroup.clearLayers();
// When you have retrieved your data and are ready to convert it to layers:
L.geoJSON(data, {
style: { // Can be a function as usual.
pane: 'polygon'
},
pointToLayer: function(feature, latlng) {
return L.circleMarker(latlng, {
pane: 'POI'
});
}
}).addTo(layerGroup); // Add to layerGroup instead of directly to map.
Updated JSFiddle: https://jsfiddle.net/Ljetvd2x/4/
As for updating your legend, I am sure you should be able to find some resources on that topic, including here on SO. If you still need help, that should very probably be separated into a new post.

Transitioning between models on a ng-repeat

I'm building a directive (Angular 1.2) that will toggle between displaying two different lists - think of them as a list of "trending" items on the site and a list of items the user is "following". So we have a toggle that allows the user to choose which list is being displayed, with an ng-repeat below it showing the items.
There will be a good deal of overlap between these lists, and when the user toggles from one list to the other, I'd like items that are contained in both to transition from their places on the "outgoing" list to their places on the new one, rather than disappearing and reappearing.
My question isn't about how to achieve the actual animations (we're using ngAnimate), but about how I should structure the controller/data to. I'm thinking about my directive controller having a trendingList and a followingList (that contain the actual data items), and an activeList that points to whichever of the two are currently being displayed. So the ng-repeat is actually on activeList, and toggling is essentially:
$scope.toggleMode = function(){
if ($scope.mode == 'trending')
$scope.mode = following;
$scope.activeList = followingList;
else {/*the inverse...*/}
}
Is that the most reasonable approach? If so, how do I ensure that angular recognizes the equality of objects present in both lists?
Or is there an easier/cleaner way to do this?
From what I understand, angular isn't tracking the equality of objects in the list it is repeating. The animations are triggered when the DOM is manipulated, not when the data changes (though data changes will change the DOM). As to what you should do, I don't have experience with this problem so hopefully somebody can point you in the right direction!

setting focus to object on google map

How can I retrieve and object on google map without user interaction. Meaning the user do not click on the object.
I have 10 polygons and I want user to navigate to each of them, manipulate maybe the color.
without clicking on the polygon itself.
I do have a "next" button that when user click, it suppose to navigate to the next polygon setting it active and to be filled with desire color.
The polygons are store in an array with json format.
Im using Data Layer. I am not sure how to implement this. I can click on polygon itself and change the color, but I need to traverse them without clicking.
Thanks
making map:
function loadJson(url, style)
{
var jsonfile = $.getJSON(url).done(function (data){
map.data.addGeoJson(data);
map.data.setStyle(style);
});
}
change color
map.data.addListener('click', function(event) {
mapName.data.overrideStyle(event.feature, currentStyle);
});
WORKING PROTOTYPE
In a data-layer there is no way to access the shapes(e.g. polygons) that have been drawn, you only may access the features.
The problem: the features are not available as array(then it would be easy to iterate over the features or select a feature by index)
Possible solution:
store the polygon-features in an array when they will be added to the layer(could be done via a addfeature-callback)
calculate the bounds of the polygons:(See: How to get LatLngBounds of feature polygon geometry in google maps v3?)
to implement the "next"-feature:
use map.data.revertStyle() to reset the style of the previous selected feature
select the first feature in the array and apply the desired style and call map.fitBounds() based on the calculated bounds(step2)
put the first feature to the end of the array
arrayWithFeatures.push(arrayWithFeatures.shift());
Demo: http://jsfiddle.net/doktormolle/anmfe/

Setting different formatting for mouseover and select in OpenLayers?

I have a vector Layer in Open layers. http://www.geos.ed.ac.uk/~s0825955/cgi-bin/maps6.pl
When selected it uses the selected formatting intent and also brings up a popup. I want the selected formatting to be displayed when the mouse moves over the layer, and the popup to display only when the feature is clicked.
I have tried adding {hover: true} to the SelectFeature control but this makes the popups appear as you move the mouse over the map.
I have also tried adding a second feature control that the popup doesn't listen to but the style map doesn't recognize this either.
Is there any way I can have a different style for hovering that does not have the feature selected?
Only one SelectFeature control may be active at a time, unless the second one has the property highlightOnly = true. From the OpenLayers docs:
highlightOnly{Boolean} -
If true do not actually select features (that is place them in the layer’s selected features array), just highlight them.
Try adding a second SelectFeature control that just changes the style. It should look like this:
var hover_feature_control = new OpenLayers.Control.SelectFeature(
[your_layer],
{
hover: true,
highlightOnly: true,
renderIntent: "temporary"
}
);
The renderIntent property should match the name of the style you want on hover in the style map.
styleMap: new OpenLayers.StyleMap({
'default': default_marker_style,
'temporary': hover_marker_style
})
Make sure you remove {hover: true} from the control that manages popups!

Categories

Resources