How do I generate several different MapBox maps - javascript

I'm trying to build a website where a user types in a city and venue and a bunch of venues load up with maps in each venue container. What happens is that only the markers show up and only the last venue on the list shows the actual map, the other map containers are blank.
Picture on what happens.
Code that I tried:
mapboxgl.accessToken = 'ACCESSTOKEN123';
let maps = {}, markers = {};
export function loadVenues(venues, container) {
container.innerHTML = "";
venues.forEach(venue => {
const {
name,
id,
lat,
lng
} = venue;
// ADDING VENUE
container.innerHTML += `
<div class="col">
<div class="venue" id="venue${id}">
<h3 class="card-title">${name}</h3>
<div class="map-content">
<div id=${id} class='venue-map'></div>
<button class="btn btn-secondary rounded-circle venue-point">
<img src="./style/images/icons8_next_page_100px.png" alt="">
</button>
</div>
</div>
</div>
`;
// MAKING MAP
maps = {
...maps,
["map" + id]: (new mapboxgl.Map({
container: id,
center: [lng, lat],
style: 'mapbox://styles/mapbox/dark-v10',
zoom: 15
}))
};
// MAKING MARKER
markers = {
...markers,
["marker" + id]: (new mapboxgl.Marker({
color: "#5B43EF",
})
.setLngLat([lng, lat])
.addTo(maps["map" + id]))
};
});
}

Do you have a JSFiddle or JSbin where you're testing this? If so, can you please post it here along with your question? It seems as though there may be an issue with your forEach loop.

Related

Jquery : 'types' can only be used in a .ts file

I am working on Jquery project using Leaflet map . My project is getting data json coordinates for flights position . My code below is working fine , but the problem is l have repeat markers on map while data is updating . l did some steps to remove previous markers position then shows new markers position, but l have error 'types' can only be used in a .ts file.
markers repeated on map while data is updating
My code
$(document).ready(function () {
var heading ;
coords: L.Marker[]
var type ;
// map initializing
var coords = [33,44]; // the geographic center of our map
var zoomLevel = 6 // the map scale.
var map = L.map('map').setView(coords, zoomLevel);
L.tileLayer('https://{s}.tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png', {
attribution: 'Map data ©',
maxZoom: 18
}).addTo(map);
// Aircraft data
setInterval(function(){
$.ajax('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', {
type: 'GET',
dataType: 'jsonp',
timeout: 5000
}).done(function (data, textStatus, jqXHR) {
// Error is here ------------ under marker //
coords ? coords.forEach((marker:marker) => {
marker.remove();
}) : '';
coords = [];
Object.keys(data)
.map(key => data[key])
.map((position) => ({
lat: position[1],
lng: position[2],
callSign: position[13],
heading: position[3],
AircraftType: position[8]
})).filter(position => position.lat && position.lng && position.callSign
&& position.heading
&& position.AircraftType).forEach(i => {
console.log(i.lat, i.lng, i.heading)
coords.push( new L.Marker([i.lat, i.lng], {
icon: new L.DivIcon({
html: ` <div style="width:120px;";>
<div class="temp-${i.heading} ${type}"></div>
<span style="color:white;background-color: midnightblue;margin: 4px;padding: 4px;border-radius: 3px;">
${i.callSign}
</span
></div>`
})
}).addTo(marker))
})
},5000)
});
Looks like you are using a type here:
coords ? coords.forEach((marker:marker) => {
The first marker is your variable and the second one after the colon is the type used in TypeScrypt. Try removing the colon and the marker there.
coords ? coords.forEach((marker) => {

ArcGIS 4.8 JS: State is not showing selected when hover or click

I'm using ArcGis 4.8 Javascript library. and I'm stuck on one point. I'm creating map with US states' layers and want to show highlight when hover or click on any state on map. But unfortunately, I'm not able to found any way how we can achieve this.
Below is the code which I write.
<!DOCTYPE html>
<html>
<head>
<title>Hosted Feature layer</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css">
</head>
<body>
<!-- Main content -->
<section class="content pp-dashboard">
<!-- Small boxes (Stat box) -->
<div class="row">
<div class="col-lg-12">
<div id="viewDiv" style="height: 800px;"></div>
<div id="searching">
<input type="text" name="name" id="searchInput">
<input type="submit" name="Search" id="searchBtn">
</div>
</div>
</div>
<!-- /.row -->
</section>
<script src="https://js.arcgis.com/4.8/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/Legend",
"esri/layers/GraphicsLayer",
"esri/Graphic",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
], function(
Map, MapView, FeatureLayer, Legend, GraphicsLayer, Graphic, on, dom
) {
let tempGraphicsLayer = new GraphicsLayer();
var filteredGeometries;
var searchInput = dom.byId("searchInput");
var povLayer = new FeatureLayer({
url: "https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_States_Generalized/FeatureServer/0",
outFields: ["*"]
});
var map = new Map({
basemap: "dark-gray",
layers: [povLayer]
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-99.244309, 40.004476],
zoom: 5
});
view.on('click', (event) => {
view.hitTest(event)
.then((res) => {
console.log("length",res.results);
if (res.results.length > 1) {
return
}
let clickedResultData = res['results'][0];
let stateCode = clickedResultData["graphic"]['attributes']['state_abbr'];
let stateName = clickedResultData["graphic"]['attributes']['state_name'];
console.log("clickedResultData", clickedResultData);
});
});
view.ui.add("searching", "bottom-right");
/******************************************************************
*
* Add layers to layerInfos on the legend
*
******************************************************************/
var legend = new Legend({
view: view,
layerInfos: [
{
layer: povLayer,
title: "Poverty in the southeast U.S."
}]
});
view.ui.add(legend, "top-right");
});
</script>
</body>
</html>
In my code, I'm using FeatureLayer to read US states from FeatureLayer url. and all the states are drawing something like this.
Now my requirement is that, when user click on any state on map then that state should highlight and when user click on another state then previous selected state should de-select and newly selected state should show highlight.
I found a way to show highlight state when hover/click on any state on map. Below is the full code.
<!DOCTYPE html>
<html>
<head>
<title>Hosted Feature layer</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css">
</head>
<body>
<!-- Main content -->
<section class="content pp-dashboard">
<!-- Small boxes (Stat box) -->
<div class="row">
<div class="col-lg-12">
<div id="viewDiv" style="height: 800px;"></div>
<div id="searching">
<input type="text" name="name" id="searchInput">
<input type="submit" name="Search" id="searchBtn">
</div>
</div>
</div>
<!-- /.row -->
</section>
<script src="https://js.arcgis.com/4.8/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/Legend",
"esri/layers/GraphicsLayer",
"esri/Graphic",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
], function(
Map, MapView, FeatureLayer, Legend, GraphicsLayer, Graphic, on, dom
) {
let highlight;
let tempGraphicsLayer = new GraphicsLayer();
var filteredGeometries;
var searchInput = dom.byId("searchInput");
var povLayer = new FeatureLayer({
url: "https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/USA_States_Generalized/FeatureServer/0",
outFields: ["*"]
});
var map = new Map({
basemap: "dark-gray",
layers: [povLayer]
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-99.244309, 40.004476],
zoom: 5
});
view.on("pointer-move", eventHandler);
view.on("pointer-down", eventHandler);
view.on("click", eventHandler);
function eventHandler(event) {
// the hitTest() checks to see if any graphics in the view
// intersect the given screen x, y coordinates
view.hitTest(event)
.then((res) => {
console.log("length",res.results);
if (res.results.length < 1) {
return
}
view.graphics.removeAll();
// create a new selected graphic
let selectedGraphic = new Graphic({
geometry: res.results[0].graphic.geometry,
attributes: res.results[0].graphic.attributes,
symbol: {
type: "simple-fill",
// style: "polygon",
color: "orange",
// size: "12px", // pixels
outline: { // autocasts as new SimpleLineSymbol()
color: [255, 255, 0],
width: 2 // points
}
}
});
// add the selected graphic to the view
// this graphic corresponds to the row that was clicked
view.graphics.add(selectedGraphic);
});
}
var legend = new Legend({
view: view,
layerInfos: [{
layer: povLayer,
title: "Poverty in the southeast U.S."
}]
});
view.ui.add(legend, "top-right");
});
</script>
</body>
</html>
I think this will help anyone.

I want to access database from google maps API to show Markers as per database longitude latitude value

var demoCtrl = this;
NgMap.getMap().then(function(map) {
demoCtrl.map = map;
});
demoCtrl.stores = {
foo: { position:[41, -87]},
bar:{ position:[41, -83]}
};
demoCtrl.showStore = function(evt, storeId) {
demoCtrl.store = demoCtrl.stores[storeId];
demoCtrl.map.showInfoWindow('foo', this);
};
demoCtrl.mouseover = function() {
console.log('mouseover');
};
above is the code of javascript for google maps api
<info-window id="foo" on-mouseover="demoCtrl.mouseover()">
<div ng-non-bindable="">
Lat: {{anchor.getPosition().lat()}}<br/>
Lng: {{anchor.getPosition().lng()}}<br/>
<ul>
<li ng-repeat='item in demoCtrl.store.items'>{{item}}</li>
</ul>
</div>
</info-window>
<marker ng-repeat="(id, store) in demoCtrl.stores" id="{{id}}"
position="{{store.position}}"
on-click="demoCtrl.showStore(event, id)"></marker>
<info-window id="bar" on-mouseover="demoCtrl.mouseover()">
<div ng-non-bindable="">
Lat: {{anchor.getPosition().lat()}}<br/>
Lng: {{anchor.getPosition().lng()}}<br/>
</div>
</info-window>
<marker position="41, -79" on-click="demoCtrl.map.showInfoWindow('bar')" />
Here i want my custom value of longitude and latitude from my database i am getting value from database but i am unable to show it on Map can anyone help how to get value on Map.

I cannot display google map markers

I cannot display google map markers on map. What's wrong? it is been a day :( Am I doing something wrong? please help It is really annoying and I am newbie to angular. I am able to display complete map but markers are not displayed :(
var appa = angular.module('appa',['firebase','uiGmapgoogle-maps']);
appa.controller('mainCtrl', function($firebaseObject,$scope) {
const rootRef = firebase.database().ref();
this.object = $firebaseObject(rootRef);
$scope.markers = [];
var mark =
{
lat: 51.2019053,
lng: 4.404418,
message: "I want to travel here!",
focus: true,
draggable: false
};
var marker = new google.maps.Marker(mark);
$scope.markers.push(marker);
console.log(mark);
$scope.map = {
center:
{
latitude: 51.219053, longitude: 4.404418 },
zoom: 14
};
});
<body ng-app="appa">
<div id="map_canvas" ng-controller="mainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom">
<marker>
<marker ng-repeat=" pos in markers" position="{{pos.lat}},{{pos.lng}}"></marker>
</ui-gmap-google-map>
</div>
Totally not an expert on this but ...
According to https://angular-ui.github.io/angular-google-maps/#!/api/marker should you use <ui-gmap-marker /> and not <marker /> and even if there is such a thing as <marker /> it looks like you have an open tag for marker with another open tag inside but this time close. I am referring to this part:
<marker>
<marker ng-repeat=" pos in markers" position="{{pos.lat}},{{pos.lng}}"></marker>
should't this be just:
<marker ng-repeat=" pos in markers" position="{{pos.lat}},{{pos.lng}}"></marker>
or according to the docs:
<ui-gmap-marker
idKey='{expression}'
coords='{expression}'
click='{expression}'
options='{expression}'
events='{expression}'
control='{expression}'
>
</ui-gmap-marker>
?

Google Map Marker and nested JSON to show data in Map Infowindow

I am using Google Map to show some places and users in it via the info window.
Google Map Script:
<script>
var markers = [
['<p>New York</p> <p>More information</p>', 40.769090, -74.002740],
['<p>Washington, Finland</p> <p>More information</p>', 38.908127, -77.034863],
];
function initializeMaps() {
var myOptions = {
zoom: 3,
center: new google.maps.LatLng(40.769090, -74.002740),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var image = 'img/logos.png';
var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
var infowindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < markers.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i][1], markers[i][2]),
map: map,
icon: image
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(markers[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}}</script>
The Script for Map Info window
<script>
var success = function(data) {
$(".ID").append(data.sessions[0].ID);
$(".Users").append(data.sessions[0].Users);
$.each(data.sessions[0].Location, function(i, value){
$(".Location").append('<li>' + value.name + '</li>');
})
}
$.getJSON("sample.json", success);
</script>
The JSON file:
{"sessions":[
{
"ID":"123",
"Users":"4",
"Location":
{ "New York": [
{ "id": 1, "name": "Mat" },
{ "id": 2, "name": "Cat" }
],
"Washington": [
{ "id": 1, "name": "Rat" },
{ "id": 2, "name": "Sat" }
]
}
},
{
"ID":"456",
"Users":"1",
"Location":
{ "New York": [
{ "id": 1, "name": "Bat" }
]
}
}]}
The HTML:
<div id="map_canvas"></div>
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">More Details</h3>
</div>
<div class="modal-body">
<p class="ID">ID</p>
<ul class="Location"></ul>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary">Save changes</button>
</div>
</div>
The problem I am facing is to show a specific user in its respective place.
For example when I click new york in the marker, it should show me the info window with two sessions and its details (according to the JSON file). I am not sure how to deal with marker ID and Nested JSON. Please help.
There are a few problems in your yode you have to fix.
First:
<script>
var success = function(data) {
$(".ID").append(data.sessions[0].ID);
$(".Users").append(data.sessions[0].Users);
$.each(data.sessions[0].Location, function(i, value){
$(".Location").append('<li>' + value.name + '</li>');
})
}
$.getJSON("sample.json", success);
</script>
That Script is loading when calling the page. So it puts the values for the modal in it at the beginning. So there are always the same information in it.
Good way should be to load the JSON File in the beginning and write it in a global variable.
When pushing the "More Information" button in your marker, you should call a javascript function with an id of the pushed city as parameter (not name, they aren't unique).
You have to put that id instead of the city name in your json.
Now the javascript function, which is called after pushing the "more information" button, should go in an iterative way (for each oder for) over the different sessions in your json and should look for an Location with the matching id. When the id matches, append the data to the model.
The usage of nested JSON is really easy.
When you want to get the information of Mat in New york in the first session, you have to use the following code:
data.sessions[0].Location.NewYork[0]
Have a look, that you better write the identifiers without a space.
So you can write a for construct like :
for(var i = 0; i<data.sessions.length;i++){
var locations = data.sessions[i].Location;
if ('Washington' in locations) {
//Code to add it in your city information window
console.log(locations.Washington);
}
}
the variable id is the passed parameter of the clicked marker.
You also should check your whole code, there are a few parts you should better change (The model won't really work with more than 1 Session)

Categories