TOC with Label layer in ArcGIS JavaScript - javascript

I am using ArcGIS JavaScript 3.7 API's and i am using agsjs.dijit.TOC control and it is working fine but when i added Label Layer in my map that time Label layer is coming fine but TOC is not working Properly.
While Pressing the checkbox to On-Off the Layer it is working fine but regarding the feature layer i added one Label layer that is not getting On-Off
Can anyone tell me how to Switch-Off or On the Label Layer.
Thanks in Advance.
I am Pasting some code..
Var load = function () {
require(["dojo/_base/Color", "esri/symbols/TextSymbol", "esri/renderers/SimpleRenderer", "esri/renderers/ScaleDependentRenderer"],
function (Color, TextSymbol, SimpleRenderer, ScaleDependentRenderer) {
var statesColor = new Color("#666");
var fieldLabel = new TextSymbol().setColor(statesColor);
fieldLabel.font.setSize("4pt");
fieldLabel.font.setFamily("arial");
statesLabelRenderer = new SimpleRenderer(fieldLabel);
return statesLabelRenderer;
});
}
var layers = [];
var layer = new esri.layers.FeatureLayer(url, {
mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
outFields: ["*"]
});
layers.push(layer);
layerInfo.push({ layer: layer, title: item["LookupDisplayDesc"], boxLabel: item["LookupDisplayDesc"], id: layer.id, checked: layer.visibleAtMapScale, slider: true });
if (item["LookupLongDesc"] != null && item["LookupLongDesc"] != "") {
var fieldNames = item["LookupLongDesc"].split(",");
var labelFields = "";
for (var i = 0 ; i < fieldNames.length ; i++) {
labelFields = labelFields + "${" + fieldNames[i].trim() + "},";
}
labelFields = labelFields.slice(0, -1).trim();
load();
var labelLayer = new esri.layers.LabelLayer();
labelLayer.addFeatureLayer(layer, statesLabelRenderer, labelFields);
layers.push(labelLayer);
}
}
map.addLayers(layers);
dojo.connect(map, 'onLayersAddResult', function (results) {
if (layerInfo.length > 0) {
var legendDijit = new esri.dijit.Legend({
map: map,
layerInfos: layerInfo
}, "legendDiv");
legendDijit.startup();
}
toc = new agsjs.dijit.TOC({
map: map,
layerInfos: layerInfo
}, 'LayerDiv');
toc.startup();
});

Not familiar with how TOC works, I build my layer logic manually. If you go the manual route you can just use show and hide like below or use setVisibleLayers like this.
A simple show and hide in your layer logic would be:
labelLayer.hide();
labelLayer.show();

Related

Counting markers in a layer in leaflet and add it to a div

I have a Leaflet map with markers and filters (checkboxes) and I would like to count the number of markers as the filters change.
I added this code which I found here Getting the count of markers in a layer in leaflet :
var counter = 0;
function onEachFeature(feature, layer) {
counter++;
console.log(counter)
}
L.geoJson(geojsonFeature, {
onEachFeature: onEachFeature
}).addTo(map);
The code works well but returns a NaN property. I would like to know if there is a way to reach the counter result as I would like to insert it in a div to my Leaflet Map?
Thanks a lot!
The first question is, do you have a geojson feature / geojson group or only markers?
If you have a GeoJSON group:
The simplest way would be to get all child layers of the geojson group, which is the marker count:
var group = L.geoJson(geojsonFeature, {
onEachFeature: onEachFeature
}).addTo(map);
var counter = group.getLayers().length;
If you have only markers on the map (not in a group):
You can loop through all layers of the map and check if the layer is existing on the map:
var counter = 0;
map.eachLayer((layer)=>{
if(layer instanceof L.Marker){
counter++;
}
});
Displaying the data as Control
L.MarkerCounterControl = L.Control.extend({
options: {
position: 'topright'
//control position - allowed: 'topleft', 'topright', 'bottomleft', 'bottomright'
},
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control fitall');
this.button = L.DomUtil.create('a', '', container);
this.button.style.width = 'auto';
this.button.style.padding = '2px 5px';
this.button.innerHTML = '0 Markers';
L.DomEvent.disableClickPropagation(this.button);
return container;
},
setCount(count) {
this.button.innerHTML = count+' Markers';
}
});
var control = new L.MarkerCounterControl().addTo(map)
control.setCount(10)
You can call after each layer change control.setCount(counter)
Demo: https://plnkr.co/edit/dyQKVQFDm5sBHzUK
I tried this. It does give me the correct number, but I am still tinkering with how to put it inside the L.control
var lg_cityMarkers = L.layerGroup([romaMarker, fidenaeMarker, antemnaeMarker, caeninaMarker, politoriumMarker]);
var totalCities = lg_cityMarkers.getLayers().length;
alert(totalCities);
You can see this live on this page: https://elcuentoderoma.com/rome/
Disclaimer: I am affiliated with this site.

Display a popup for each cluster marker with custom properties mapbox

I am displaying custom markers with an image icon and displaying the number of markers based on the zooming level. How do I add a popup window to each of these markers?
This is the code I used to plot all the markers.
map.on('load', function () {
// add a clustered GeoJSON source for a sample set of earthquakes
map.addSource('earthquakes', {
"type": "geojson",
"data": "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson",
"cluster": true,
"clusterRadius": 80
});
map.addLayer({
"id": "cluster",
"type": "symbol",
"source": "earthquakes",
"filter": ["!=", "cluster", true]
});
// objects for caching and keeping track of HTML marker objects (for performance)
var markers = {};
var markersOnScreen = {};
function updateMarkers(){
var newMarkers = {};
var features = map.querySourceFeatures( 'earthquakes' );
for ( var i = 0; i < features.length; i++ ) {
var coords = features[ i ].geometry.coordinates;
var props = features[ i ].properties;
if (!props.cluster) continue;
var id = props.cluster_id;
var marker = markers[id];
if (!marker) {
var el = new Image();
el.src = 'icon.png';
el.classList.add( 'mapMarker' );
el.dataset.type = props.type; // you can use custom data if you have assigned it in the GeoJSON data
marker = markers[id] = new mapboxgl.Marker({element: el}).setLngLat(coords);
}
newMarkers[id] = marker;
if (!markersOnScreen[id])
marker.addTo(map);
}
// for every marker we've added previously, remove those that are no longer visible
for (id in markersOnScreen) {
if (!newMarkers[id])
markersOnScreen[id].remove();
}
markersOnScreen = newMarkers;
}
// after the GeoJSON data is loaded, update markers on the screen and do so on every map move/moveend
map.on('data', function (e) {
if (e.sourceId !== 'earthquakes' || !e.isSourceLoaded) return;
map.on('move', updateMarkers);
map.on('moveend', updateMarkers);
updateMarkers();
});
});
I tried this but does not help.
map.on('click', 'states-layer', function (e) {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(e.features[0].properties.name)
.addTo(map);
});
// Change the cursor to a pointer when the mouse is over the states layer.
map.on('mouseenter', 'states-layer', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'states-layer', function () {
map.getCanvas().style.cursor = '';
});
Also tried marker.popup() function.
Any help is greatly appreciated.
Thanks,
Adheesh
Try not to create markers. Instead make a layer for single points in the map. You can add an icon to the layer so it looks like a marker. It works like this:
First you should add layer for points unclustered.
Example with an icon:
map.loadImage('https://imageURL', function(error, image) {
if (error) throw error;
map.addImage('IMAGE-NAME', image);
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "earthquakes",
filter: ["!", ["has", "point_count"]],
layout: {
"icon-image": 'IMAGE-NAME',
"icon-size":1,
}
});
Example without an icon:
map.addLayer({
id: "unclustered-point",
type: "circle",
source: "earthquakes",
filter: ["!", ["has", "point_count"]],
});
Then add a click event:
map.on('click', 'unclustered-point', function (e) {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(e.features[0].properties.description)
.addTo(map);
});
Remember to put your code inside of map.on("load"...) function
map.on('load', function()
{
//put your code here
}
I think for this to work you would have to not use yours markers code.

Setting multiple map point icons in JQM

I am trying to populate some map points on a canvas which have been read from a JSON file.
I can create one set of points fine but I want to add different icons depending on what kind of point it is. I have tried evaluating the JSON data the map will not load with more than on kind of icon.
My code is as follows:
$.each( data.markers, function(i, marker) {
$('#map_canvas').gmap('addMarker', {
'position': new google.maps.LatLng(marker.latitude, marker.longitude),
if (marker.company == "Capgemini") {
'icon':new google.maps.MarkerImage("capico.png"),
} else if (marker.company == "Accenture") {
'icon':new google.maps.MarkerImage("accico.png"),
}
'bounds': true
}).click(function() {
//$('#map_canvas').gmap('openInfoWindow', {
// 'content': marker.content
$.mobile.changePage("#details");
Not sure where im going wrong here.
Any help greatly appreciated
try this code
var customIcons = {
"Capgemini": {
icon: 'path_to_your_marker_pictures/capico.png',
},
"Accenture": {
icon: 'path_to_your_marker_pictures/accico.png',
}
};
var icon = customIcons[marker.company] || {};
var marker = new google.maps.Marker({
position: point,
icon: icon.icon,
});
Best,
Darko

How to auto-update a marker on a leaflet map, with meteor

For a school project we are having this idea of making a geospatial tag-game. You log in on our app, your location is shown on the map, and whenever you get close to another player, you tag that person. (Like children's tag but with meteor)
The issue we are having, we seem not able to auto-update our marker on the leaflet map. There's an marker showing it's just not updating.
We tried using Player.update in a time but it doesn't work.
Any suggestions?
The code
if (Meteor.isClient) {
var userLatitude;
var userLongitude;
var map;
Template.map.rendered = function () {
// Setup map
map = new L.map('map', {
dragging: false,
zoomControl: false,
scrollWheelZoom: false,
doubleClickZoom: false,
boxZoom: false,
touchZoom: false
});
map.setView([52.35873, 4.908228], 17);
//map.setView([51.9074877, 4.4550772], 17);
L.tileLayer('http://{s}.tile.cloudmade.com/9950b9eba41d491090533c541f170f3e/997#2x/256/{z}/{x}/{y}.png', {
maxZoom: 17
}).addTo(map);
// If user has location then place marker on map
if (userLatitude && userLongitude) {
var marker = L.marker([userLatitude, userLongitude]).addTo(map);
}
var playersList = players.find().fetch();
playersList.forEach(function(players) {
// Change position of all markers
var marker = L.marker([players.latitude, players.longitude], options={"id" : 666}).addTo(map);
});
};
// If the collection of players changes (location or amount of players)
Meteor.autorun(function() {
var playersList = players.find().fetch();
playersList.forEach(function(players) {
// Change position of all markers
var marker = L.marker([players.latitude, players.longitude]).addTo(map);
});
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
/*
Template.hello.events({
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
*/
/*
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
userLatitude = 52.35873;
userLongitude = 4.908228;
players.insert({
name: "Martijn",
latitude: userLatitude,
longitude: userLongitude
});
});
}
*/
You need to clear the existing markers, otherwise they remain on the map. The easiest / most efficient way to do this is to attach the markers to a LayerGroup when you're creating them. Then, when you want to update, clear all the markers, and then add them again.
Add layer group declaration at the top, so you have
var map, markers;
After initialising the map,
markers = new L.LayerGroup().addTo(map);
Change this line:
var marker = L.marker([userLatitude, userLongitude]).addTo(map);
to:
var marker = L.marker([userLatitude, userLongitude]).addTo(markers);
in your autorun, before the forEach,
markers.clearLayers();
then in your foreach,
var marker = L.marker([players.latitude, players.longitude]).addTo(markers);

Google Maps Zoom and Description dialog not working right

Well I'm having a couple problems getting google maps to work using the v3 API.
Look here: [Removed by Poster]
Both maps are, in fact, working but the zoom level seems like it is random. The zoom is set to 12 when the map is initialized. Also, if you click on the marker, the description box is missing corners and is unable to be closed. Here is the javascript functions I am using to activate these maps:
var mapHash = [];
var bound = new google.maps.LatLngBounds();
finishedCoding = false;
function initMap(map_container_div,lat,lng) {
var latlng = new google.maps.LatLng(lat,lng);
var myOptions = {
zoom:12,
center:latlng,
mapTypeId:google.maps.MapTypeId.ROADMAP,
streetViewControl: false
};
var map = new google.maps.Map(document.getElementById(map_container_div), myOptions);
if (!getMap(map_container_div)) {
var mapInfo = {
mapkey:'',
map:'',
geocoder : new google.maps.Geocoder()
};
mapInfo.map = map;
mapInfo.geocoder = new google.maps.Geocoder();
mapInfo.mapKey = map_container_div;
mapHash.push(mapInfo);
}
}
function placeMarker(myAddress, mapId, description, title) {
mapIndex = getMap(mapId)
//alert(myAddress + mapId + map)
mapHash[mapIndex].geocoder.geocode({
'address':myAddress
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
mapIndex = getMap(mapId)
var marker = new google.maps.Marker({
map:mapHash[mapIndex].map,
position:results[0].geometry.location,
title: title
});
bound.extend(results[0].geometry.location);
mapHash[mapIndex].map.fitBounds(bound);
finishedCoding = true;
placeDesc(marker,description,mapId);
}
});
}
function placeDesc(marker,myDesc,mapId) {
mapIndex = getMap(mapId);
var infowindow = new google.maps.InfoWindow({
content: myDesc
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(mapHash[mapIndex],marker);
});
}
function getMap(mapKey) {
for (var i = 0 ; i < mapHash.length ; i++) {
if (mapHash[i].mapKey == mapKey) {
return i;
}
}
return false;
}
function startmap(mapidd,address,description,title,lat,lng) {
initMap(mapidd,lat,lng)
placeMarker(address,mapidd,description,title)
}
by just removeing
body img {
max-width: 520px !important;
height: auto !important;}
from style sheet
http://www.wppassport.com/wp-content/plugins/easyfanpagedesign/default.theme/style.css
your problem is resolved now
Your dialog boxes aren't closing because of a javascript error.
Something is wrong with infowindow.open(mapHash[mapIndex],marker); inside your click listener. It's displaying the window, which makes you think that the error is happening after, but I'm pretty sure it's in the call itself. When I debugged you weren't making an obvious mistake, but I still think that that line of code is the culprit.
I solved this issue myself and am kicking myself for not thinking of this. :)
Just had to add mapHash[mapIndex].map.setZoom(12);
And I removed the following 2 codes:
bound.extend(results[0].geometry.location);
mapHash[mapIndex].map.fitBounds(bound);

Categories