Vanilla Javascript for creating an array from an array of objects - javascript

var cityMarkers = [
{
id: "bliss",
name: "Principality of Bliss",
icon: cityIcon,
coords: [-90.19, -76.90]
},
{
id: "cantonia",
name: "Grand City of Cantonia",
icon: cityIcon,
coords: [-39.513421, -69.09375]
},
{
id: "mithril",
name: "Grand City of Mithril ",
icon: cityIcon,
coords: [42, -102.5]
}];
I have the above in a separate file for referencing from my app.js file.
cityMarkers.forEach(function(item) {
var marker = L.marker(item.coords, {icon : item.icon});
marker.bindTooltip("<b>" + item.name + "<b>", {permanent: true, offset:
[60, 0]});
This will make the markers and the other properties, but it won't put them on the map. An array handles placing them on the map, so this doesn't help me much with what I am really trying to do.
This is a map based on the leaflet library. I am trying to assign a variable to each city with the id. Then, after the markers are made and attached to their variables, I want to make an array out of those names to function as the data layer. I admit that I am out of my depth, here. Any guidance would be most appreciated. I linked the documentation below in case anyone wants it.
https://leafletjs.com/reference-1.3.4.html
I did research the question, but I was unable to find any results that answered what I think I am asking. I would highly prefer a nudge over a flat answer. I don't understand how to instantiate the variables and bind them to the markers. Thank you for your time.

Instead of adding the markers directly to the map, add them to a L.layerGroup. You can add the layerGroup to the map and remove it again at will.
var lg = new L.layerGroup();
cityMarkers.forEach(function(item) {
var marker = L.marker(item.coords, {icon : item.icon});
marker.bindTooltip("<b>" + item.name + "<b>", {permanent: true, offset:
[60, 0]})
.addTo(lg)});
lg.addTo(map); // Add the layerGroup the map
lg.removeFrom(map); // Remove the layerGroup from the map

I think you can try adding .addTo(map)
cityMarkers.forEach(function(item) {
var marker = L.marker(item.coords, {icon : item.icon});
marker
.bindTooltip("<b>" + item.name + "<b>", {permanent: true, offset: [60, 0]})
.addTo(map);
Demo for adding multiple markers to leaflet.

Related

How to select the POI map using the H.ui.MapSettingsControl?

I'm using the HERE JS library for mapping. I'd like to add an option into the MapSettingsControl to select the POI Map, as shown at https://developer.here.com/documentation/map-tile/dev_guide/topics/example-poi-tile.html
It seems you need to append "&pois" to the tile requests in order to get this.
I've followed the example in How do I get a Terrain Map in UI Controls HERE Maps v3.1 to create a new selectable map style in the MapSettingsControl.
However, it seems you can only select the map style name and cannot append arguments. Specifically, I cannot see a way of appending the &pois argument to the tile request to get the POI tiles.
Any suggestions?
Ah, I found the answer, but it's a bit fiddly.
var maptypes = platform.createDefaultLayers();
var poi = platform.createDefaultLayers({pois:true});
ui.removeControl("mapsettings");
// create custom one
var ms = new H.ui.MapSettingsControl( {
baseLayers : [ {
label:"Normal", layer: maptypes.vector.normal.map
},
{
label:"POI", layer: poi.raster.normal.map
},
],
layers : [{
label: "layer.traffic", layer: maptypes.vector.normal.traffic
},
{
label: "layer.incidents", layer: maptypes.vector.normal.trafficincidents
}
]
});
ui.addControl("customized",ms);

How to add google maps marker from array (javascript)?

I hope for a bit support about my following javascript code:
// Initialize Firebase
var config = {
apiKey : "AIzaSyBRC2kza6jhghEFNr5dteVpw2kB9mxqrU8",
authDomain : "formulaire-7fba1.firebaseapp.com",
databaseURL : "https://formulaire-7fba1.firebaseio.com",
projectId : "formulaire-7fba1",
storageBucket : "formulaire-7fba1.appspot.com",
messagingSenderId: "548100244430"
};
firebase.initializeApp(config);
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 3,
styles: [{
featureType: 'poi',
stylers: [{ visibility: 'off' }] // Turn off points of interest.
}, {
featureType: 'transit.station',
stylers: [{ visibility: 'off' }] // Turn off bus stations, train stations, etc.
}],
disableDoubleClickZoom: true
});
}
// Loop through users in order with the forEach() method. The callback
// provided to forEach() will be called synchronously with a DataSnapshot
// for each child:
var query = firebase.database().ref("client").orderByKey();
query.once("value").then(function(snapshot) {
var position = [];
snapshot.forEach(function(childSnapshot) {
// key will be "ada" the first time and "alan" the second time
var key = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
position.push(childData.lat + " " + childData.lng);
console.log(position);
});
});
I'm trying to get the array, that's filled with GPS position as a strings, into the google map, as markers. Tried several methods but none works. Can anyone can give me a tip or an direction?
Thanks!
If position is the array that will hold your coordinates. You need to make sure the array elements inside follow a latLng object or what the marker.position property would recognize. Usually it would follow this format:
var latLngObj = {lat: -25.363, lng: 131.044};
You can use your forEach loop to already add a marker per iteration. Before/Aftter pushing the coordinates to the position array do something like:
var marker = new google.maps.Marker({
position: {lat: childData.lat, lng:childData.lng},
map: map
});
I'm not sure how childData actually looks like, as you didn't give that info, but assuming it's a double like -25.363 and not a string, then it will be fine.
You might also want to define your map variable globally so that your functions can recognize it at the part of map: map as you're only defining the map variable inside your initMap function.
Here's the documentation that may guide you on how to add a marker to the map. Just use an iteration (e.g. for loop) to add multiple markers. You'll also see how to delete them in the same documentation.
Also found a relevant stackoverflow post on properly looping to create your markers.
Hope that helps!

Displaying Map with Leaflet-Heat.js

I am currently working on a web application where I'm trying to display a heat map using the library called Leaflet.heat. It works with the Leaflet Javascript library to create an overlay heat map that looks pretty good. I feel like I'm pretty much there but having one last bit of trouble with array format and can't figure out what is wrong. Let me share the code that I have right now.
var mymap;
var marker = [];
var heatMapArr = [];
window.onload = function() {
alert("in initial func");
uponPageLoadDefault();
};
function uponPageLoadDefault()
{
//initial default page load
var branches = new L.LayerGroup();
var items = JSON.parse('${branches}');
var j = 0;
for(var i = 0; i < items.length; i++)
{
var LamMarker = new L.marker([items[i].lat, items[i].lon]);
//GOT RID OF FUNCTION CALL.
var heatMapPoint = {
lat: items[i].lat,
lon: items[i].lon,
intensity: items[i].tranCount
};
heatMapArr.push(heatMapPoint);
LamMarker.bindPopup("<b>" + items[i].branchName + "</b><br>" + items[i].branchAdd + "</br><br>" + items[i].branchCity + "</br><br>" + items[i].branchSt + "</br><br>" + items[i].branchZip + "</br><br>TranCount: " + items[i].tranCount).addTo(branches);
marker.push(LamMarker);
}
mbAttr = 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoidGFzdHlicm93bmllcyIsImEiOiJjaXgzZWxkaHowMWZhMnlvd2wzNHllaGwxIn0.0RSZEhtR0OBLMbwjqFfBkg';
var outdoors = L.tileLayer(mbUrl, {id: 'mapbox.outdoors', attribution: mbAttr});
var heatmap = L.heatLayer(heatMapArr, {radius: 6, blur: 8,maxZoom: 8});
var map = L.map('map', {
center: [39.73, -104.99],
zoom: 10,
layers: [outdoors, branches, heatmap]
});
var baseLayers = {
"Outdoors": outdoors
};
var overlays = {
"Branches": branches,
"HeatMap": heatmap
};
L.control.layers(baseLayers, overlays).addTo(map);
So basically I am trying to use the heat map display as a possible overlay that the user can select. The Leaflet-heat library tutorial is located at https://github.com/Leaflet/Leaflet.heat/ and it explains what needs to be done in order for the library to work.
Anyway, I have a list of items with latitude, longitude, and intensity amount, so I'm trying to use that, its called items. I iterate through that, pushing the select information into my heat map array. At this point I should be almost all set besides adding the overlays and creating the map. When I run the program, the map displays but the overlay icon is absent so there is an issue.
In the website tutorial they use a separate Javascript file which has an array of objects to create their heat map. I tried this with my program and then everything worked, which quickly led me to believe there's a problem with my array of objects, probably some minor formatting thing.......I am using another function to create an object with the data I have, so it will be in the same format as the website example.
I tried to use alert and other statements and compare my array to theirs but it hasn't yielded anything useful so I wanted to post my issue here on Stack to get some feedback from others on what could be wrong. I think its something really small that I may not be seeing.
Any feed back is greatly appreciated and certainly let me know if there's any questions.
Thanks!

Javascript If-Else Statement in For Loop

I'm trying to use JavaScript and the Google Maps API to plot a number of markers on a map; I have a large array of objects containing key-value pairs as follows:
xyz: [ { name: 'abc', loc: { lat: 0.000000, lng: 0.000000 } }, ... , ... ]
I have a For-Loop that iterates through this array and plots a marker at xyz.loc for each object in the array (see below). Now, I'm trying to change the icon used for each marker based on the xyz.name property.
I've defined two different custom marker icons and their associated shape (xyzMarkerIcon1, xyzMarkerIcon2 and xyzMarkerShape) and I'm trying to switch which one is used using an If-Else statement as follows:
var xyzMarkerIcon = {};
for (i in xyz) {
if (xyz[i].name = 'abc') {
xyzMarkerIcon = xyzMarkerIcon1
}
else {
xyzMarkerIcon = xyzMarkerIcon2
}
xyzMarkerArray[i] = new google.maps.Marker({
map: map,
position: xyz[i].loc,
icon: xyzMarkerIcon,
shape: xyzMarkerShape,
});
}
The For-loop works fine, but the If-Else statement seems to be overlooked after the first iteration; all of the objects in the array are plotted successfully but all using the first instance of xyzMarkerIcon.
I feel like this should be a simple enough problem, but I just can't figure it out! Thanks for your help!
You forgot the == 'abc'
var xyzMarkerIcon = {};
for (i in xyz) {
if (xyz[i].name == 'abc') {
xyzMarkerIcon = xyzMarkerIcon1
}
else {
xyzMarkerIcon = xyzMarkerIcon2
}
xyzMarkerArray[i] = new google.maps.Marker({
map: map,
position: xyz[i].loc,
icon: xyzMarkerIcon,
shape: xyzMarkerShape,
});
}

Markerclusterer customization google maps

I have a basic markerclusterer example which works very well.
var center = new google.maps.LatLng(37.4419, -122.1419);
var options = {
'zoom': 13,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), options);
var markers = [];
for (var i = 0; i < 100; i++) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude);
var marker = new google.maps.Marker({'position': latLng});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
What I would like to do is cluster the markers by country and then once you click on it they are still clustered until on3 further click. Currently they are clustered until you are down to one result. I have thousands of markers and would like them visible after one country click and then one more click.
I looked for a solution online and found this http://google-maps-utility-library-v3.googlecode.com/svn/tags/markermanager/1.0/examples/google_northamerica_offices.html
which is produced using this
var officeLayer = [
{
"zoom": [0, 3],
"places": [
{ "name": "US Offices", "icon": ["us", "flag-shadow"], "posn": [40, -97] },
{ "name": "Canadian Offices", "icon": ["ca", "flag-shadow"], "posn": [58, -101] }
]
},
...
};
function setupOfficeMarkers() {
allmarkers.length = 0;
for (var i in officeLayer) {
if (officeLayer.hasOwnProperty(i)) {
var layer = officeLayer[i];
var markers = [];
for (var j in layer["places"]) {
if (layer["places"].hasOwnProperty(j)) {
var place = layer["places"][j];
var icon = getIcon(place["icon"]);
var title = place["name"];
var posn = new google.maps.LatLng(place["posn"][0], place["posn"][1]);
var marker = createMarker(posn, title, getIcon(place["icon"]));
markers.push(marker);
allmarkers.push(marker);
}
}
mgr.addMarkers(markers, layer["zoom"][0], layer["zoom"][1]);
}
}
mgr.refresh();
updateStatus(mgr.getMarkerCount(map.getZoom()));
}
I'm not sure how to implement this into what I've currently got and if i need to include any other scripts/ libraries also.
You are looking at two totally different libraries, there. Your question is about the MarkerClusterer library, but your example solution is about the MarkerManager library.
The MarkerClusterer library automatically clumps markers together based on an algorithm that tries to decide when too markers would be so close together that you can't visibly distinguish one from another. You don't really have a lot of control over when and how it decides to merge markers together this way, so this library is idea when it doesn't matter to you how they get merged, as long as merging happens. Since you want to merge markers together by political boundaries (countries) and not by proximity to each other, this is not the library for you.
The MarkerManager library does not automatically merge markers together at all. What it does do is to selectively hide and reveal markers based on the zoom level of the current map viewport. What you would need to do is do your own merging, and then add to the MarkerManager all of the merged markers, as well as the detail markers, and the zoom levels where you want each marker to be visible. Doing your own merging means you will need an alternate way of determining which country each marker point falls within. Hopefully, you already know (or can get) that information, because it's not automatically provided by any of these libraries.
tl;dr - use the MarkerManager library and not the MarkerClusterer library for grouping by countries, and it's up to you to identify the location for each country and which marker goes with which one.

Categories

Resources