Edit marker size and popup box size - javascript

I managed to get the marker and the popup box to appear in the Mapbox API
However, I don't seem to be able to edit their size and popup size.
for (let i = 0; i < locations.length; i++) {
let location = locations[i];
let marker = new mapboxgl.Marker({ color: '#FF8C00' });
marker.setLngLat(location.coordinates);
let popup = new mapboxgl.Popup({ offset: 40 });
popup.setHTML(location.description);
marker.setPopup(popup);
// Display the marker.
marker.addTo(map);
// Display the popup.
popup.addTo(map);
}

Mapbox ususally recommends to use the Annotation Plugin to create markers and interact with these.
However, if you would like to stick to the example you have presented, you could follow this Mapbox example in which custom icons are used for the marker symbol. The size of these icons can be adjusted with the iconSize property:
<script>
mapboxgl.accessToken = 'access_token';
var geojson = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {
'message': 'Foo',
'iconSize': [60, 60]
},
'geometry': {
'type': 'Point',
'coordinates': [-66.324462890625, -16.024695711685304]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Bar',
'iconSize': [50, 50]
},
'geometry': {
'type': 'Point',
'coordinates': [-61.2158203125, -15.97189158092897]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Baz',
'iconSize': [40, 40]
},
'geometry': {
'type': 'Point',
'coordinates': [-63.29223632812499, -18.28151823530889]
}
}
]
};
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-65.017, -16.457],
zoom: 5
});
// add markers to map
geojson.features.forEach(function(marker) {
// create a DOM element for the marker
var el = document.createElement('div');
el.className = 'marker';
el.style.backgroundImage =
'url(https://placekitten.com/g/' +
marker.properties.iconSize.join('/') +
'/)';
el.style.width = marker.properties.iconSize[0] + 'px';
el.style.height = marker.properties.iconSize[1] + 'px';
el.addEventListener('click', function() {
window.alert(marker.properties.message);
});
// add marker to map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);
});
</script>

Related

Mapbox problem with creating PopUp for each cluster/marker with dynamic data

I have a problem where I am fetching my data from my API using WordPress. I have multiple clusters/markers on my map. But I am not able to create for each location a PopUp marker with the data coming from the API. I am facing some scoping issue where I want to have one popup dynamically show the data based ont he clicked marker if that makes sense.
Is there a trick on how to solve this?
import mapboxgl from 'mapbox-gl';
import MapboxLanguage from '#mapbox/mapbox-gl-language';
import apiFetch from '#wordpress/api-fetch';
(() => {
const mapContainer = document.querySelector('[data-gewoon-wonen]');
if (!mapContainer) {
return;
}
mapboxgl.accessToken = process.env.MAP_TOKEN_KEY;
const center = [4.387733, 51.862419];
const locations = {
type: 'FeatureCollection',
features: []
};
apiFetch({ path: '/wp-json/wp/v2/map?_embed' }).then((maps) => {
maps.forEach((item) => {
const {
id,
title: { rendered: title },
_embedded,
acf
} = item;
const image =
_embedded && _embedded['wp:featuredmedia'][0]?.source_url;
const {
map_location_subtitle: subtitle,
map_location_delivery: delivery,
map_location_project: project,
map_location_content: description,
map_location_coordinates_lat: lat,
map_location_coordinates_lng: lng,
map_location_status: status,
map_location_website: website
} = acf;
const getStatus = (currentStatus) => {
let statusObj = {
bouwfase: 'marker-gray',
planfase: 'marker-bright-pink',
opgeleverd: 'marker-bright-blue',
default: ''
};
let icon = statusObj[currentStatus] || statusObj['default'];
return icon;
};
const object = {
type: 'Feature',
properties: {
id,
status,
image,
icon: getStatus(status),
title,
subtitle,
project,
website,
delivery,
description
},
geometry: {
type: 'Point',
coordinates: [lng, lat]
}
};
locations.features.push(object);
});
});
const map = new mapboxgl.Map({
container: mapContainer,
style: 'mapbox://styles/theme/clcz9eocm000p14o3vh42tqfj',
center,
zoom: 10,
minZoom: 10,
maxZoom: 18,
attributionControl: false,
cooperativeGestures: true
});
map.addControl(
new MapboxLanguage({
defaultLanguage: 'mul'
})
);
map.on('load', () => {
// Add a new source from our GeoJSON data and
// set the 'cluster' option to true. GL-JS will
// add the point_count property to your source data.
map.addSource('locations', {
type: 'geojson',
// Point to GeoJSON data. This example visualizes all M1.0+ locations
// from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.
data: locations,
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'locations',
filter: ['has', 'point_count'],
paint: {
// Use step expressions (https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
'circle-color': [
'step',
['get', 'point_count'],
'#51bbd6',
100,
'#f1f075',
750,
'#f28cb1'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
});
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'locations',
filter: ['has', 'point_count'],
layout: {
'text-field': ['get', 'point_count_abbreviated'],
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12
}
});
map.addLayer({
id: 'unclustered-point',
type: 'circle',
source: 'locations',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#11b4da',
'circle-radius': 4,
'circle-stroke-width': 1,
'circle-stroke-color': '#fff'
}
});
// inspect a cluster on click
map.on('click', 'clusters', (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ['clusters']
});
const clusterId = features[0].properties.cluster_id;
map.getSource('locations').getClusterExpansionZoom(
clusterId,
(err, zoom) => {
if (err) return;
map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
}
);
});
// When a click event occurs on a feature in
// the unclustered-point layer, open a popup at
// the location of the feature, with
// description HTML from its properties.
map.on('click', 'unclustered-point', (e) => {
const coordinates = e.features[0].geometry.coordinates.slice();
const mag = e.features[0].properties.mag;
const tsunami =
e.features[0].properties.tsunami === 1 ? 'yes' : 'no';
// Ensure that if the map is zoomed out such that
// multiple copies of the feature are visible, the
// popup appears over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(
`magnitude: ${mag}<br>Was there a tsunami?: ${tsunami}`
)
.addTo(map);
});
map.on('mouseenter', 'clusters', () => {
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'clusters', () => {
map.getCanvas().style.cursor = '';
});
});
})();

Mapbox GL snap GPS coordinates do road

I use Mapbox to show on map the path that the user traveled (with my app on phone). My application saves the GPS position regularly, which I then show on the map with the help of Mapbox GL.
<script>
mapboxgl.accessToken = 'pk.XXX';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [aa.AAA, bb.BBB],
zoom: 18
});
var popup = new mapboxgl.Popup()
.setText("XXX YYY")
.addTo(map);
var marker = new mapboxgl.Marker()
.setLngLat([aa.AAA, bb.BBB])
.addTo(map)
.setPopup(popup);
map.on('load', function () {
map.addSource('route', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [
[xx.XXX,yy.YYY],
[xx.XXX,yy.YYY],
[xx.XXX,yy.YYY]
}
}
});
map.addLayer({
'id': 'route',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#888',
'line-width': 8
}
});
});
</script>
I would like Mapbox to snap the position to the road on the map. Something like "snap-to-road" in Google Maps.
I know that Mapbox has something called "map matching". Only I want to list many intermediate points (not just the beginning and the end), and I would like everyone with them to be snaped to the road on the map.
Is something like this possible? Maybe there are some other mapping solutions that can do that?
Take a look at my solution below. It uses Mapbox map matching, then extracts the tracepoints from the response object and draws them on the map.
To make it work on your end, just replace <ACCESS_TOKEN> with your Mapbox access token.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map Matched Coordinates</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = '<ACCESS_TOKEN>';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-117.17292,32.71256],
zoom: 15
});
map.on('load', function () {
// map matching request
var matched_coordinates = [];
// Create
let xhr = new XMLHttpRequest();
// GET REQUEST
xhr.open('GET', 'https://api.mapbox.com/matching/v5/mapbox/driving/' +
'-117.17282,32.71204;-117.17288,32.71225;-117.17293,32.71244;-117.17292,32.71256;-117.17298,32.712603;-117.17314,32.71259;-117.17334,32.71254' +
'?access_token=<ACCESS_TOKEN>' +
'&geometries=geojson');
// After Response is received
xhr.onload = function() {
if (xhr.status != 200) {
// NOT SUCCESSFUL
} else {
// SUCCESSFUL
var response = JSON.parse(xhr.response);
var tracepoints = response["tracepoints"];
for(var i = 0; i < tracepoints.length; i++){
matched_coordinates.push(tracepoints[i]["location"]);
}
map.addSource('route', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': matched_coordinates
}
}
});
map.addLayer({
'id': 'route',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#888',
'line-width': 8
}
});
}
}
xhr.send();
});
</script>
</body>
</html>

Mapbox GL JS get features within geoson boundary

Below is a complete minimal example of a dot layer on top of a choropleth layer. You simply need to add an access token and it will work. When a user clicks within one of the choropleth boundaries I would like to get a list of the points within that boundary. This is so that I can use this data to populate an element elsewhere on the page. I am aware that some boundaries overlap, but I am not worried about how this is handled.
<head>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.js"></script>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.css"
rel="stylesheet"
/>
</head>
<body>
<div id="map" style="width: 800px; height: 800px;"></div>
<script>
mapboxgl.accessToken =
"your token here";
const geojson_url =
"https://opendata.arcgis.com/datasets/d4d519d1d1a1455a9b82331228f77489_4.geojson";
fetch(geojson_url)
.then(res => res.json())
.then(geojson => {
const data = [
{ lat: "52.04009", long: "-0.52926" },
{ lat: "51.45906", long: "-2.60329" },
{ lat: "51.24257", long: "-0.58795" },
{ lat: "51.51161", long: "-0.11625" },
{ lat: "51.38113", long: "-2.36011" },
{ lat: "51.449824", long: "-2.60034" },
{ lat: "52.04009", long: "-0.52926" },
{ lat: "51.06386", long: "-2.90667" },
{ lat: "50.72623", long: "-3.5222" }
];
const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/light-v10",
zoom: 5.5,
center: [-2.2, 53]
});
map.on("load", function() {
// choropleth
geojson.features = geojson.features.map(feature => {
feature["id"] = feature.properties.objectid;
return feature;
});
map.addSource("leps", {
type: "geojson",
data: geojson
});
map.addLayer({
id: "leps-fills",
type: "fill",
source: "leps",
paint: {
"fill-color": "green",
"fill-opacity": 0.5
}
});
map.on("click", "leps-fills", function(e) {
// using this event, I would like to find all the points within the clicked boundary
console.log("list of points here");
});
// point data layers
// create points geojson data
const pointMapGeojson = {
type: "FeatureCollection",
features: data.map((g, i) => {
return {
type: "Feature",
properties: g,
id: i,
geometry: {
type: "Point",
coordinates: [g.long, g.lat]
}
};
})
};
map.addSource("point_layer", {
type: "geojson",
data: pointMapGeojson
});
map.addLayer({
id: "point_layer",
type: "circle",
source: "point_layer",
layout: {
visibility: "visible"
}
});
});
});
</script>
</body>
You may look at Turf.js. It provides a function to find any points within the polygon. https://turfjs.org/docs/#pointsWithinPolygon
Here is the example:
mapboxgl.accessToken = 'pk.eyJ1IjoicGFybmRlcHUiLCJhIjoiY2l6dXZ5OXVkMDByZDMycXI2NGgyOGdyNiJ9.jyTchGQ8N1gjPdra98qRYg';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
center: [-46.6062, -23.5513],
zoom: 11
});
map.on('load', function () {
var points = turf.points([
[-46.6318, -23.5523],
[-46.6246, -23.5325],
[-46.6062, -23.5513],
[-46.663, -23.554],
[-46.643, -23.557]
]);
var searchWithin = turf.polygon([[
[-46.653,-23.543],
[-46.634,-23.5346],
[-46.613,-23.543],
[-46.614,-23.559],
[-46.631,-23.567],
[-46.653,-23.560],
[-46.653,-23.543]
]]);
// Find point within polygon
var ptsWithin = turf.pointsWithinPolygon(points, searchWithin);
// Draw polygon
map.addLayer({
'id': 'searchWithin',
'type': 'fill',
'source': {
'type': 'geojson',
'data': searchWithin
},
'layout': {},
'paint': {
'fill-color': '#525252',
'fill-opacity': 0.5
}
});
// Draw all points
map.addLayer({
'id': 'points',
'type': 'circle',
'source': {
'type': 'geojson',
'data': points
},
'layout': {},
'paint': {
'circle-radius': 5,
'circle-color': 'red',
'circle-opacity': 1
}
});
// Draw points within polygon feature
map.addLayer({
'id': 'ptsWithin',
'type': 'circle',
'source': {
'type': 'geojson',
'data': ptsWithin
},
'layout': {},
'paint': {
'circle-radius': 5,
'circle-color': 'blue',
'circle-opacity': 1
}
});
});
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; };
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://npmcdn.com/#turf/turf/turf.min.js'></script>
<div id='map'></div>

OpenLayers 4 zoom to cluster

Im using OpenLayers 4 and have a layer with an ol.source.Cluster as source. When I click on a clustered point I want to zoom in to the extent of the original points that makes up the cluster. My problem is that I can not find these original points anywhere.
I have tried to calculate an extent from the distance I use on the cluster but the result is not satisfying.
Any idea how to determine which the original points behind a cluster point are?
<html>
<head>
<title>Cluster</title>
<link rel="stylesheet" href="https://openlayers.org /en/v4.1.1/css/ol.css" type="text/css">
<script src="https://openlayers.org/en/v4.1.1/build/ol.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<script>
var geojsonObject = {
'type': 'FeatureCollection',
'crs': {
'type': 'name',
'properties': {
'name': 'EPSG:3857'
}
},
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0]
}
}, {
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [9, 9]
}
},{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [10, 10]
}
}]
};
var source = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
});
var clusterSource = new ol.source.Cluster({
source: source,
distance: 30
});
var layer = new ol.layer.Vector({
source: clusterSource
});
var select = new ol.interaction.Select({
layers: [layer]
});
var view = new ol.View({
center: [5, 5],
zoom: 20
});
var map = new ol.Map({
target: 'map',
layers: [new ol.layer.Tile({
source: new ol.source.OSM()
}),layer],
view: view
});
map.addInteraction(select);
var selectedFeatures = select.getFeatures();
selectedFeatures.on('add', function(event) {
// event.target only contains the clustered point
var feature = event.target.item(0);
});
</script>
</body>
</html>
I found the answer myself in a OpenLayers example.
In the selected feature function you can do
var originalFeatures = feature.get('features');
To get the original features, and then in my case to zoom to the extent
var extent = new ol.extent.createEmpty();
originalFeatures.forEach(function(f, index, array){
ol.extent.extend(extent, f.getGeometry().getExtent());
});
map.getView().fit(extent, map.getSize());
You can get the features in the cluster from:
source.getFeatures()
You can get the extent from:
source.getExtent()
Where source is an instance of ol.source.Cluster

Mapbox search, open popup/tooltip and change the custom marker image

I have a mapbox map with custom marker images and a search field - when there is a full match between the search string and the marker's feature.properties - the map is zoomed in to the coordinates of the matched marker - in this case I failed to achieve two things:
The popup/tooltip of the matched marker to appear open;
and
To change the matched marker's custom image.
Thanks in advance for any help!
Here is the code:
L.mapbox.accessToken = 'pk.eyJ1IjoibmFkaiIsImEiOiJjaW43a2hyOXYwMDJrd29semd6bmZha2JuIn0.nE1hjNjGG2rlxm_oMrysyg';
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38.13455657705411, -94.5703125], 4);
var myLayer = L.mapbox.featureLayer().addTo(map);
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
properties: {
id: 1,
'title': 'Washington, D.C.',
"cityName": "washington",
"icon": {
"iconUrl": "https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png",
"iconSize": [50, 50],
"iconAnchor": [25, 25],
"popupAnchor": [0, -25],
"className": "dot"
}
},
geometry: {
type: 'Point',
coordinates: [-77.03201, 38.90065]
}
}, {
type: 'Feature',
properties: {
id: 2,
'title': 'Chicago, M',
"cityName": "chicago",
"icon": {
"iconUrl": "https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png",
"iconSize": [50, 50],
"iconAnchor": [25, 25],
"popupAnchor": [0, -25],
"className": "dot"
}
},
geometry: {
type: 'Point',
coordinates: [-87.71484375, 41.80407814427234]
}
},
{
type: 'Feature',
properties: {
id: 3,
'title': 'Dallas, T',
"cityName": "dallas",
"icon": {
"iconUrl": "https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png",
"iconSize": [50, 50],
"iconAnchor": [25, 25],
"popupAnchor": [0, -25],
"className": "dot"
}
},
geometry: {
type: 'Point',
coordinates: [-96.85546875, 32.80574473290688]
}
}
]
};
var myLayer = L.mapbox.featureLayer().addTo(map);
myLayer.on('layeradd', function(e) {
var marker = e.layer,
feature = marker.feature;
marker.setIcon(L.icon(feature.properties.icon));
});
myLayer.setGeoJSON(geojson);
// Search by city name
$('#searchByName').keyup(cityMapSearch);
function cityMapSearch() {
var searchString = $('#searchByName').val().toLowerCase();
myLayer.setFilter(showCity);
function showCity(feature) {
if (feature.properties.cityName == searchString) {
map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], 17);
} else {
return feature.properties.cityName
.toLowerCase()
.indexOf(searchString) !== -1;
}
return true;
}
}
#map {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.search-field {
position: absolute;
right: 0;
bottom: 15px;
width: 250px;
height: 30px;
font-size: 12px;
text-align: left;
padding: 5px;
z-index: 100;
}
<link href="https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.js"></script>
<div id='map'></div>
<input type="text" id="searchByName" class="search-field" placeholder="Washington, Chicago or Dallas">
And a Fiddle
Here's my solution which will zoom to, change the icon for, and open the popup of a feature that matches search field input. I used the .eachLayer() method to loop through myLayer's features and test if they matched the search string. I also simplified the showCity() function you included. I'm not sure why, but for some reason the search() function would zoom to but not .openPopup() or .setIcon() when .eachLayer() came before .setFilter(). Hope this helps!
/* Goal: When full match between search string and feature:
1. Open tooltip of matched marker
2. Change the matched marker's custom image
*/
L.mapbox.accessToken = 'your_access_token';
//Create map object, set base tiles and view
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38.13455657705411, -94.5703125], 4);
//Create an empty feature layer and add it to the map
var myLayer = L.mapbox.featureLayer().addTo(map);
//Define GeoJSON data
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
properties: {
id: 1,
'title': 'Washington, D.C.',
'cityName': 'washington',
'icon': {
'iconUrl': 'https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png',
'iconSize': [50, 50],
'iconAnchor': [25, 25],
'popupAnchor': [0, -25],
'className': 'dot'
}
},
geometry: {
type: 'Point',
coordinates: [-77.03201, 38.90065]
}
},
{
type: 'Feature',
properties: {
id: 2,
'title': 'Chicago, M',
'cityName': 'chicago',
'icon': {
'iconUrl': 'https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png',
'iconSize': [50, 50],
'iconAnchor': [25, 25],
'popupAnchor': [0, -25],
'className': 'dot'
}
},
geometry: {
type: 'Point',
coordinates: [-87.71484375, 41.80407814427234]
}
},
{
type: 'Feature',
properties: {
id: 3,
'title': 'Dallas, T',
'cityName': 'dallas',
'icon': {
'iconUrl': 'https://www.mapbox.com/mapbox.js/assets/images/astronaut2.png',
'iconSize': [50, 50],
'iconAnchor': [25, 25],
'popupAnchor': [0, -25],
'className': 'dot'
}
},
geometry: {
type: 'Point',
coordinates: [-96.85546875, 32.80574473290688]
}
}
]
};
//Set layer icons, create custom tooltips, populate myLayer with geojson data
myLayer.on('layeradd', function(e) {
var marker = e.layer,
feature = marker.feature;
marker.setIcon(L.icon(feature.properties.icon));
var content = '<h2>' + feature.properties.title + '</h2><p>' + feature.properties.cityName + '</p>';
marker.bindPopup(content);
});
myLayer.setGeoJSON(geojson);
// Compare the 'cityName' property of each marker to the search string, seeing whether the former contains the latter.
function search() {
//Get the value of the search input field
var searchString = $('#search').val().toLowerCase();
//Set filter needs to be declared first
myLayer.setFilter(function(feature){
//Return features whose city name contains the search string
return feature.properties.cityName
.toLowerCase()
.indexOf(searchString) !== -1;
});
//Loop through each layer
myLayer.eachLayer(function(marker) {
//If user search input matches the feature's city name
if (marker.feature.properties.cityName === searchString) {
//Update icon url
marker.setIcon(L.icon({iconUrl: 'https://www.mapbox.com/jobs/img/astro3.svg'}));
//Zoom in and center on matching feature
map.setView([marker.feature.geometry.coordinates[1], marker.feature.geometry.coordinates[0]], 17);
//Open feature popup
marker.openPopup();
}
});
}
//Event listener for user keyup within search field
$('#search').keyup(search);

Categories

Resources