How do i set event inside setHtml on Mapbox GL JS? - javascript

I am having problems with following example :
mapboxgl.accessToken = 'pk.eyJ1IjoicGFwYWJ1Y2t0IiwiYSI6ImNqa2k3azQ1dzA1Zmgza3B1czIxOGhhaW4ifQ.h5OT3NaQf0vcxx3g1q1cXw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 5,
center: [-77.04, 38.907],
});
map.on('load', function() {
map.addLayer({
"id": "places",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"id" : 1,
"name" :"My Icon",
"icon": "theatre"
},
"geometry": {
"type": "Point",
"coordinates": [-77.038659, 38.931567]
}
}]
}
},
"layout": {
"icon-image": "ferry-15",
"icon-allow-overlap": true
}
});
map.on('click', 'places', function (e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var id = e.features[0].properties.id;
var name = e.features[0].properties.name;
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML("<table>" +
"<tr>" +
"<td>ID</td>" +
"<td>:</td>" +
"<td>"+id+"</td>" +
"</tr>" +
"<tr>" +
"<td>Name</td>" +
"<td>:</td>" +
"<td>"+name+"</td>" +
"</tr>" +
"</table>" +
"<button type='button' onclick='"+alert("Success")+"'>This Button</button>"
)
.addTo(map);
});
map.on('mouseenter', 'places', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'places', function () {
map.getCanvas().style.cursor = '';
});
});
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>WEBAPP</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
<div id='map'></div>
</body>
</html>
My problem is,i don't know this is bug,or i wrote the wrong code. The result i was expecting was when i clicked ship icon,and click the button called "This Button" ,an alert showed . But in this code,when i clicked ship icon,an alert shows,then popup . although i already set onclick event inside setHtml.
How do i fix this ? Thank you

The way you're concatenation your HTML string is problematic. When you add the +alert("Success")+"
You're actually calling the function alert before rendering it as an HTML string
if you replace it with
"<button type='button' onclick=alert('Success')>This Button</button>"
You'll see it works, as the string is construct corrected.
I recommend you to replace the concatenation with template literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
It is much cleaner
Example:
.setHTML(`<table>
<tr>
<td>ID</td>
<td>:</td>
<td>${id}</td>
</tr>
<tr>
<td>Name</td>
<td>:</td>
<td>${name}</td>
</tr>
</table>
<button type="button" onclick="alert('Success on ${name} ${id})">This Button</button>`)
mapboxgl.accessToken = 'pk.eyJ1IjoicGFwYWJ1Y2t0IiwiYSI6ImNqa2k3azQ1dzA1Zmgza3B1czIxOGhhaW4ifQ.h5OT3NaQf0vcxx3g1q1cXw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 5,
center: [-77.04, 38.907],
});
map.on('load', function() {
map.addLayer({
"id": "places",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"id" : 1,
"name" :"My Icon",
"icon": "theatre"
},
"geometry": {
"type": "Point",
"coordinates": [-77.038659, 38.931567]
}
}]
}
},
"layout": {
"icon-image": "ferry-15",
"icon-allow-overlap": true
}
});
map.on('click', 'places', function (e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var id = e.features[0].properties.id;
var name = e.features[0].properties.name;
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(`<table>
<tr>
<td>ID</td>
<td>:</td>
<td>${id}</td>
</tr>
<tr>
<td>Name</td>
<td>:</td>
<td>${name}</td>
</tr>
</table>
<button type="button" onclick="alert('Success on ${name}')">This Button</button>`)
.addTo(map);
});
map.on('mouseenter', 'places', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'places', function () {
map.getCanvas().style.cursor = '';
});
});
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>WEBAPP</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
<div id='map'></div>
</body>
</html>

Related

Mapbox popup ReferenceError: features is not defined

I'm trying to display 3 fields properties from a geojson data that is loaded from a file. The data is loaded an added to the map. And the markers/points are display on the HTML page. BUt then I click on a marker/point nothing happens. Around .setLngLat(features.geometry.coordinates) I get an ReferenceError: features is not defined I'm not sure what I've missed or needed to do for it to be available to the current scope.
I would very much appreciate any hints or tips to resolve this.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'/>
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no'/>
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.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 = 'pk.myaccesstoken';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [10.600, 55.900],
zoom: 6.0,
hash: true
});
map.on('load', function () {
// Add a layer showing the places.
map.addSource('markers', {
type: 'geojson',
data: '{% static 'json/architecture_map.geojson'%}'
});
map.addLayer({
"id": "places",
"source": "markers",
"type": "circle",
"paint": {
"circle-radius": 5,
"circle-color": "#fb05ff"
}
});
map.on('click', function (e) {
var f = map.queryRenderedFeatures(e.point, {layers: ['places']});
if (f.length) {
var feature = f[0];
new mapboxgl.Popup()
.setLngLat(features.geometry.coordinates)
.setHTML(ProjectPopup(feature))
.addTo(map);
}
});
function ProjectPopup(feature){
var html = '';
html += "<div>";
html += "<h2>" + feature.properties.project + "</h2>";
html += "<p>" + feature.properties.image + "</p>";
html += "<a>" + feature.properties.slug + "</a>";
html += "</div>";
return html;
}
// Change the cursor to a pointer when the mouse is over the places layer.
map.on('mouseenter', 'places', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'places', function () {
map.getCanvas().style.cursor = '';
});
});
</script>
</body>
</html>
Sample of the geojson file.
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"features": [
{
"type": "Feature",
"properties": {
"image": "project01.JPG",
"project": "Project Title",
"slug": "project-title"
},
"geometry": {
"type": "Point",
"coordinates": [
9.932241438432886,
57.04649628721196
]
}
}
]
}
First of all your provided geojson is not a valid one. You can check your geojson here: http://geojsonlint.com/
Second your "not defined" error might just be a typo. You defined your variable like this:
var feature = f[0];
But using is like this:
new mapboxgl.Popup()
.setLngLat(features.geometry.coordinates)
.setHTML(ProjectPopup(feature))
.addTo(map);
}
You notice that features is not the same as your defined variable named feature thus resulting in undefined.
I corrected your mistake. See here:
https://jsfiddle.net/andi_lo/xzrzzzsc

World map that links to url when click on country specific layer

I am trying to make a map of the world using Mapbox that will have a different layer for each country. I want to use it to where when a country's layer is clicked on, it will link to a specific url on my website for that country. I know I need to use on('click') to do this, but cant figure out how. In this map so far I have a layer (would this be a vector tile) for Chile, so I would want the click on the layer 'chile' to link to a url to an external webpage about Chile. I have played around with it for days and have nothing. I apologize I have very little code experience but appreciate any help! This is the base of what I have from Mapbox:
<html>
<head>
<meta charset='utf-8' />
<title>Points on a map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user- scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.31.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.31.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 = 'pk.eyJ1IjoidHJla3dpdGh0YXlsb3IiLCJhIjoiY2owZTB0OWkyMDE2bDMycWw1N3J2OHZpZyJ9.jDMCcXBCjsbQ-Vh973LQZA'; // replace this with your access token
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/trekwithtaylor/cj0h4jjwe003w2sultexx0ds4'
});
</script>
</body>
</html>
Conceptually, what you need to do is listen for the click event, use Map#queryRenderedFeatures to figure out what country the user clicked on, and then open the web page associated with that country.
I threw together a quick demo which adapts the "Create a hover effect" to also respond to click events. I hope this is helpful for you!
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.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 = 'pk.eyJ1IjoibHVjYXN3b2oiLCJhIjoiY2l5Nmg4cWU1MDA0ejMzcDJtNHJmZzJkcyJ9.WhcEdTYQH6sSw2pm0RSP9Q';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-100.486052, 37.830348],
zoom: 2
});
map.on('load', function () {
map.addSource("states", {
"type": "geojson",
"data": "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_admin_1_states_provinces.geojson"
});
map.addLayer({
"id": "state-fills",
"type": "fill",
"source": "states",
"layout": {},
"paint": {
"fill-color": "#627BC1",
"fill-opacity": 0.5
}
});
map.addLayer({
"id": "state-borders",
"type": "line",
"source": "states",
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2
}
});
map.addLayer({
"id": "state-fills-hover",
"type": "fill",
"source": "states",
"layout": {},
"paint": {
"fill-color": "#627BC1",
"fill-opacity": 1
},
"filter": ["==", "name", ""]
});
// When the user moves their mouse over the page, we look for features
// at the mouse position (e.point) and within the states layer (states-fill).
// If a feature is found, then we'll update the filter in the state-fills-hover
// layer to only show that state, thus making a hover effect.
map.on("mousemove", function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ["state-fills"] });
if (features.length) {
map.getCanvas().style.cursor = 'pointer';
map.setFilter("state-fills-hover", ["==", "name", features[0].properties.name]);
} else {
map.setFilter("state-fills-hover", ["==", "name", ""]);
map.getCanvas().style.cursor = '';
}
});
// Reset the state-fills-hover layer's filter when the mouse leaves the map
map.on("mouseout", function() {
map.getCanvas().style.cursor = 'auto';
map.setFilter("state-fills-hover", ["==", "name", ""]);
});
map.on("click", function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ["state-fills"] });
if (features.length) {
window.location = 'https://en.wikipedia.org/wiki/' + features[0].properties.name
}
});
});
</script>
</body>
</html>

Google Maps JS API / GeoJSON import - infowindows not showing up when API Key is inserted

here is some code for a simple map that gets data from a geoJson variable. My problem is that the infowindows associated with markers won't show up. The strange thing is that if I remove the API Key script, everything seems to work correctly.
<!DOCTYPE html>
<html>
<head>
<title>Google Maps geoJson infowindow test</title>
<style type="text/css">
html, body, #map-canvas {
width: 100%;
height: 500px;
margin: 0px;
padding: 0px
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false&libraries=drawing"></script>
<script type="text/javascript">
var map;
var marker;
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();
function initialize() {
// Create a simple map.
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 14,
center: new google.maps.LatLng(-27.779627,153.236112)
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Load the associated GeoJSON
var data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [153.236112, -27.779627]
},
"properties": {
"name": "[153.236112, -27.779627]",
"description": "Timestamp: 16:37:16.293"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [153.230447, -27.777501]
},
"properties": {
"name": "[153.230447, -27.777501]",
"description": "Timestamp: 16:37:26.298"
}
}
]
}
map.data.addGeoJson(data)
// Set mouseover event for each feature.
map.data.addListener('click', function(event) {
infowindow.setContent(event.feature.getProperty('name')+"<br>"+event.feature.getProperty('description'));
infowindow.setPosition(event.latLng);
infowindow.setOptions({pixelOffset: new google.maps.Size(0,-34)});
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="content"></div>
<table border="1">
<tr>
<td>
<div id="map-canvas" style="width:580px;height:620px;"></div>
</td>
<td valign="top" style="width:150px; text-decoration: underline; color: #4444ff;">
<div id="side_bar"></div>
</td>
</tr>
</table>
<div id="info"></div>
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY_SECRET_KEY&callback=initialize">
</script>
</body>
</html>
Code to remove to make it work locally:
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY_SECRET_KEY&callback=initialize">
</script>
Please need some advice. Thanks.
You are including the API twice, once with the drawing library and once with the callback function. Only include the API once, combine all the parameters (including your API key) as described in the documentation.
code snippet:
var map;
var marker;
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();
function initialize() {
// Create a simple map.
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 14,
center: new google.maps.LatLng(-27.779627, 153.236112)
});
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Load the associated GeoJSON
var data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [153.236112, -27.779627]
},
"properties": {
"name": "[153.236112, -27.779627]",
"description": "Timestamp: 16:37:16.293"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [153.230447, -27.777501]
},
"properties": {
"name": "[153.230447, -27.777501]",
"description": "Timestamp: 16:37:26.298"
}
}]
}
map.data.addGeoJson(data)
// Set mouseover event for each feature.
map.data.addListener('click', function(event) {
infowindow.setContent(event.feature.getProperty('name') + "<br>" + event.feature.getProperty('description'));
infowindow.setPosition(event.latLng);
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, -34)
});
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
width: 100%;
height: 500px;
margin: 0px;
padding: 0px
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?callback=initialize&libraries=drawing"></script>
<div id="content"></div>
<table border="1">
<tr>
<td>
<div id="map-canvas" style="width:580px;height:620px;"></div>
</td>
<td valign="top" style="width:150px; text-decoration: underline; color: #4444ff;">
<div id="side_bar"></div>
</td>
</tr>
</table>
<div id="info"></div>

Leaflet does not mark point with geojsonFeatures?

I'm starting on Leaflet API and I hope to add some geometry points to a customer map using GeoJson data. Currently, I used the geojsonFeaturetype present here http://leafletjs.com/examples/quick-start.html
But, when I follow such steps to add the features, the ones does not appears. Below is my html page and code.
<html><head>
<title>Leaflet Quick Start Guide Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css">
</head>
<body class="">
<div id="mapid" style="width: 600px; height: 400px; position: relative;" class="leaflet-container leaflet-fade-anim" tabindex="0"></div>
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src="https://raw.github.com/calvinmetcalf/leaflet-ajax/master/dist/leaflet.ajax.min.js"></script>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/edsonbarboza/ciqb82pfe000dc1nliqy8sljp/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZWRzb25iYXJib3phIiwiYSI6ImNpbTJjMWRuczA5NGx1MGtzbmN6c3NjOHMifQ.FvAMXzmnQ0TIJDDsV6rXAw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.satelity'
}).addTo(mymap);
var myStyle = {
"color": "#ff7800",
"weight": 5,
"opacity": 0.65
};
//L.marker([51.51, -0.09]).addTo(mymap)
var geojsonFeature = {
"type": "Feature",
"properties": {
"name": "Coors Field",
"amenity": "Baseball Stadium",
"popupContent": "This is where the Rockies play!"
},
"geometry": {
"type": "Point",
"coordinates": [51.51, -0.09]
}
};
var myLayer = L.geoJson().addTo(mymap);
myLayer.addData(geojsonFeature);
<!-- var geojsonLayer = new L.GeoJSON.AJAX("geojson_data.json", {style:myStyle}); -->
<!-- geojsonLayer.addTo(mymap); -->
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
</script>
Thanks for any help.
You must invert the coordinates in the geometry.
var geojsonFeature = {
"type": "Feature",
"properties": {
"name": "Coors Field",
"amenity": "Baseball Stadium",
"popupContent": "This is where the Rockies play!"
},
"geometry": {
"type": "Point",
"coordinates": [-0.09, 51.51]
}
};
Here is your sample with correction
This is specified here

highlight feature with click in mapbox gl

I have a geojson layer of streets that are highlighted when moused-over.
My objective is now to highlight individual streets red with a click event. Only one street should be able to be highlighted at a time, and should remain highlighted until a different street is clicked.
Any idea as to what needs to be added to the following code?
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.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 = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v8',
center: [37.625224, 55.744537,],
zoom: 13
});
map.on('style.load', function () {
map.addSource('streets', {
"type": "geojson",
"data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
});
map.addLayer({
"id": "m_streets",
"type": "line",
"source": "streets",
"interactive": true,
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-opacity": 0.0,
"line-width": 2.5
}
});
map.addLayer({
"id": "route-hover",
"type": "line",
"source": "streets",
"layout": {},
"paint": {
"line-color": "#f48024",
"line-opacity": 0.9,
"line-width": 2.5
},
"filter": ["==", "rd_name", ""]
});
map.addLayer({
"id" : "street_toggle",
"source": "streets",
"type": "line",
"layout": {"line-join": "round",
"line-cap": "round"},
"paint": {
"line-color": "#FF0000",
"line-opacity": 0.9,
"line-width:": 3.5
}
});
map.on('mousemove', function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["m_streets"]
}, function (err, features) {
if (!err && features.length) {
map.setFilter('route-hover', ['==', 'rd_name', features[0].properties.rd_name]);
} else {
map.setFilter('route-hover', ['==', 'rd_name', '']);
}
});
});
map.on('click', function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["street_toggle"]
}, function (err, features) {
if (!err && features.length) {
map.setFilter('street_toggle', ['==', 'rd_name', features[0].properties.rd_name]);
} else {
map.setFilter('street_toggle', ['==', 'rd_name', '']);
}
});
});
});
//.addTo(map);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.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 = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v8',
center: [37.625224, 55.744537, ],
zoom: 13
});
map.on('style.load', function() {
map.addSource('streets', {
"type": "geojson",
"data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
});
map.addLayer({
"id": "m_streets",
"type": "line",
"source": "streets",
"interactive": true,
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-opacity": 0.0,
"line-width": 2.5
}
});
map.addLayer({
"id": "route-hover",
"type": "line",
"source": "streets",
"layout": {},
"paint": {
"line-color": "#f48024",
"line-opacity": 0.9,
"line-width": 2.5
},
"filter": ["==", "rd_name", ""]
});
map.addLayer({
"id": "street_toggle",
"source": "streets",
"type": "line",
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#FF0000",
"line-opacity": 0.9,
"line-width:": 3.5
}
});
map.on('mousemove', function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["m_streets"]
}, function(err, features) {
if (!err && features.length) {
map.setFilter('route-hover', ['==', 'rd_name', features[0].properties.rd_name]);
} else {
map.setFilter('route-hover', ['==', 'rd_name', '']);
}
});
});
map.on('click', function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["street_toggle"]
}, function(err, features) {
if (!err && features.length) {
map.setFilter('street_toggle', ['==', 'rd_name', features[0].properties.rd_name]);
} else {
map.setFilter('street_toggle', ['==', 'rd_name', '']);
}
});
});
});
//.addTo(map);
</script>
</body>
</html>
If you take a look at the console output when running your code, you should see this error message:
layers.street_toggle.paint.line-width:: unknown property "line-width:"
Because of this error, the street_toggle layer is not being added to the map and the click interaction is not working.
To fix the problem, please change the "line-width:" key to "line-width"(remove the spurious colon inside the quotes)
#Lucas features At() must be a depreciated method? His colon did throw a bug, but it doesn't help him select a road segment, at least at v0.16, right? I use queryRenderedFeatures()
note: I really wish this method had a optional radius parameter - you really have to click precisely on the line.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.16.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.16.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 = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v8',
center: [37.625224, 55.744537,],
zoom: 13
});
map.on('style.load', function () {
map.addSource('streets', {
"type": "geojson",
"data": "https://iskandarblue.github.io/mapbox/data/simplify_prototype.geojson"
});
map.addLayer({
"id": "m_streets",
"type": "line",
"source": "streets",
"interactive": true,
"layout": {},
"paint": {
"line-color": "red",
// "line-opacity": 0.0,
"line-width": 2.5
}
});
map.on('click', function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['m_streets'] });
if (!features.length) {
return;
}
if (typeof map.getLayer('selectedRoad') !== "undefined" ){
map.removeLayer('selectedRoad')
map.removeSource('selectedRoad');
}
var feature = features[0];
//I think you could add the vector tile feature to the map, but I'm more familiar with JSON
console.log(feature.toJSON());
map.addSource('selectedRoad', {
"type":"geojson",
"data": feature.toJSON()
});
map.addLayer({
"id": "selectedRoad",
"type": "line",
"source": "selectedRoad",
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "yellow",
"line-width": 8
}
});
});
});
</script>
</body>
</html>

Categories

Resources