Only rendering Mapbox features once, when showing multiple world copies? [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm working on this Mapbox map, and shows features using geojson/FeatureCollection (basically something like this).
If you zoom all the way out, the map will show multiple world copies (which I want), but it will also show each feature on ALL world copies (don't want this!). What should I do so that the mapbox only displays the features on ONE of the world copies?
The example linked above also has the same issue (as you can see in the image below).
Sample code showcasing the issue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add multiple geometries from one GeoJSON source</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 = 'pk.eyJ1Ijoic2h1YmhhbW1laHJhIiwiYSI6ImNqempxZWNqeDBicnMzbnFpaTZ6amVmYjQifQ.US2y0mYyWtRABvxzfpBWrw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/outdoors-v11',
center: [-121.403732, 40.492392],
zoom: 10
});
map.on('load', function () {
map.addSource('national-park', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[-121.353637, 40.584978],
[-121.284551, 40.584758],
[-121.275349, 40.541646],
[-121.246768, 40.541017],
[-121.251343, 40.423383],
[-121.32687, 40.423768],
[-121.360619, 40.43479],
[-121.363694, 40.409124],
[-121.439713, 40.409197],
[-121.439711, 40.423791],
[-121.572133, 40.423548],
[-121.577415, 40.550766],
[-121.539486, 40.558107],
[-121.520284, 40.572459],
[-121.487219, 40.550822],
[-121.446951, 40.56319],
[-121.370644, 40.563267],
[-121.353637, 40.584978]
]
]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.415061, 40.506229]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.505184, 40.488084]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.354465, 40.488737]
}
}
]
}
});
map.addLayer({
'id': 'park-boundary',
'type': 'fill',
'source': 'national-park',
'paint': {
'fill-color': '#888888',
'fill-opacity': 0.4
},
'filter': ['==', '$type', 'Polygon']
});
map.addLayer({
'id': 'park-volcanoes',
'type': 'circle',
'source': 'national-park',
'paint': {
'circle-radius': 6,
'circle-color': '#B42222'
},
'filter': ['==', '$type', 'Point']
});
});
</script>
</body>
</html>

I don't think this is possible. Geographically, what you're asking for doesn't really make sense. Your point has the same location as the map tile underneath it, so to have the basemap display but not your point, on the basis of the user having effectively rotated the map is...weird.
Your best workaround would be to use a Marker rather than a symbol layer. Each Marker is a single DOM element so only ever displayed once.

Related

How to add symbol on line center, and make the arrow aligns to line end point in Mapbox

I have created the map with Mapbox, but I had a few problems. When I try to Place the icon in the center of the line and add the arrow to the line endpoint, it always fails.
I added Markers on Jorge Chavez International Airport(LIM) & Alejandro Velasco Astete International Airport (CUZ)
const marker1 = new mapboxgl.Marker({ color: '#5C7F74',scale:'0.8'})
.setLngLat([-77.11174632225463, -12.02384281134897])
.addTo(map);
const marker3 = new mapboxgl.Marker({ color: '#8BAAA1',scale:'0.5'})
.setLngLat([-70.15810500000016,-15.469970999998012])
.addTo(map);
then add a line to map, So far it's okay but I don't know how to build new layers, add arrows aligns to the line endpoint, or add a symbol on line center
map.on('load', () => {
map.addSource('route', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [
[-70.15810500000016,-15.469970999998012],[-77.10670100000081,-12.030560999998116]
]
}
}
});
map.addLayer({
'id': 'route',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round',
'line-miter-limit': 2
},
'paint': {
'line-color': '#888',
'line-width': 3,
'line-dasharray':[2,2]
}
});
});

How to add Images inside a custom container on Mapbox?

I want to add images to Mapbox in a similar style as follow:
I am not sure how to go about doing this since Mapbox doesn't really offer many options when adding an image to the map. I have tried adding a custom marker with an image inside it and that works but then I lose layer features such as hiding etc. Any ideas on how this can be done?
You can load an image and then use it as part of a symbol layer. You can see it in one of the official examples.
map.on('load', function () {
map.loadImage(
'https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png',
function (error, image) {
if (error) throw error;
map.addImage('cat', image);
map.addSource('point', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0]
}
}
]
}
});
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'point',
'layout': {
'icon-image': 'cat',
'icon-size': 0.25
}
});
}
);
});

Edit Polygon Added with map.addLayer in Mapbox

I want to edit polygon which i have added using map.addLayer() on mapbox.
the code:
map.addLayer({
'id': 'maine'+id,
'type': 'fill',
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': coords
}
}
},
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
Mapbox GL Drawing Library is used to draw/edit the shapes.
You have added the polygon as a map layer. Editing the layer in drawing mode directly seems not possible. Here is a possible way
You need to hide the layer first.
Get the Polygon data from layer source
Init the drawing mode and add a new polygon to drawing manager with the polygon data
Once the editing finished, update the layer source with the edited polygon data from drawing manager
Remove the polygon from the drawing manager
Show the updated layer
You need to use the add method to draw an existing shape.
draw.add({
'id': 'polygon-3355',
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Polygon',
'coordinates': [[[-67.13734351262877, 45.137451890638886],
[-66.96466, 44.8097],
[-68.03252, 44.3252],
[-69.06, 43.98],
[-70.11617, 43.68405],
[-70.64573401557249, 43.090083319667144],
[-70.75102474636725, 43.08003225358635],
[-70.79761105007827, 43.21973948828747],
[-70.98176001655037, 43.36789581966826],
[-70.94416541205806, 43.46633942318431],
[-71.08482, 45.3052400000002],
[-70.6600225491012, 45.46022288673396],
[-70.30495378282376, 45.914794623389355],
[-70.00014034695016, 46.69317088478567],
[-69.23708614772835, 47.44777598732787],
[-68.90478084987546, 47.184794623394396],
[-68.23430497910454, 47.35462921812177],
[-67.79035274928509, 47.066248887716995],
[-67.79141211614706, 45.702585354182816],
[-67.13734351262877, 45.137451890638886]]]
}
});
Library Link:
https://github.com/mapbox/mapbox-gl-draw
API Methods Reference:
https://github.com/mapbox/mapbox-gl-draw/blob/master/docs/API.md
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Show drawn polygon area</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>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
.calculation-box {
height: 75px;
width: 150px;
position: absolute;
bottom: 40px;
left: 10px;
background-color: rgba(255, 255, 255, .9);
padding: 15px;
text-align: center;
}
p {
font-family: 'Open Sans';
margin: 0;
font-size: 13px;
}
</style>
<script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.js'></script>
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.css' type='text/css'/>
<div id='map'></div>
<div class='calculation-box'>
<p>Draw a polygon using the draw tools.</p>
<div id='calculated-area'></div>
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZWRlbnJheWdhcmRuZXIiLCJhIjoiRlZRVlhqOCJ9.tDrWaeNRbMCtXAovQLYuzA';
/* eslint-disable */
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v8',
center: [-70.11617, 43.68405],
zoom: 5
});
var draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
polygon: true,
trash: true
}
});
map.addControl(draw);
map.on('draw.create', updateArea);
map.on('draw.delete', updateArea);
map.on('draw.update', updateArea);
draw.add({
'id': 'polygon-3355',
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Polygon',
'coordinates': [[[-67.13734351262877, 45.137451890638886],
[-66.96466, 44.8097],
[-68.03252, 44.3252],
[-69.06, 43.98],
[-70.11617, 43.68405],
[-70.64573401557249, 43.090083319667144],
[-70.75102474636725, 43.08003225358635],
[-70.79761105007827, 43.21973948828747],
[-70.98176001655037, 43.36789581966826],
[-70.94416541205806, 43.46633942318431],
[-71.08482, 45.3052400000002],
[-70.6600225491012, 45.46022288673396],
[-70.30495378282376, 45.914794623389355],
[-70.00014034695016, 46.69317088478567],
[-69.23708614772835, 47.44777598732787],
[-68.90478084987546, 47.184794623394396],
[-68.23430497910454, 47.35462921812177],
[-67.79035274928509, 47.066248887716995],
[-67.79141211614706, 45.702585354182816],
[-67.13734351262877, 45.137451890638886]]]
}
});
function updateArea(e) {
var data = draw.getAll();
var answer = document.getElementById('calculated-area');
if (data.features.length > 0) {
var area = turf.area(data);
// restrict to area to 2 decimal points
var rounded_area = Math.round(area*100)/100;
answer.innerHTML = '<p><strong>' + rounded_area + '</strong></p><p>square meters</p>';
} else {
answer.innerHTML = '';
if (e.type !== 'draw.delete') alert("Use the draw tools to draw a polygon!");
}
}
</script>
</body>
</html>

Unable to add floors in Mapbox GL

I want to add 2 or 3 floors for each building using MapBox GL, but when i try using the addlayer, the colours are getting overriden but no layers or floors are added. Been stuck with this for some time now.
I want 3d extrusions of floors in a building.
Tried putting this into a button click as well, but still it is not returning expected results.
<!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.39.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/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.eyJ1IjoiZGFuc3dpY2siLCJhIjoiY2l1dTUzcmgxMDJ0djJ0b2VhY2sxNXBiMyJ9.25Qs4HNEkHubd4_Awbd8Og';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-87.61694, 41.86625],
zoom: 15.99,
pitch: 40,
bearing: 20
});
map.on('load', function() {
map.addLayer({
'id': 'room-extrusion10',
'type': 'fill-extrusion',
'source': 'composite',
'source-layer': 'building',
'paint': {
'fill-extrusion-color': 'blue',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'max_height'
},
'fill-extrusion-opacity': 1
}
});
map.addLayer({
'id': 'room-extrusion11',
'type': 'fill-extrusion',
'source': 'composite',
'source-layer': 'building',
'paint': {
'fill-extrusion-color': 'red',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'min_height'
},
'fill-extrusion-opacity': 1
}
},'room-extrusion10');
});
</script>
</body>
</html>
fill-extrusion-height and fill-extrusion-base are the paint properties that control the lower and upper height (in meters) of a fill-extrusion feature. In your example these are styled with identity functions based on building height data from OpenStreetMap (in the Mapbox Streets data source), causing them to imitate real-world building shapes (as best as they are mapped). In order to create a fill-extrusion layer that spans only one floor you'd want fill-extrusion-height: 3 (or however tall, in meters, you perceive one story to be) and fill-extrusion-base: 0 for the first floor; the second would be height=6 and base=3, and so forth.
Note that in all released versions of Mapbox GL JS, multiple fill-extrusion layers don't render correctly with respect to each other. This is fixed in master and will be included in the next release this month.

Filling color to polygons using Mabox-gl-js

I've countries GeoJson with a geometry of type polygon. Each polygon has only one property name (name is the country name). each polygon represents a country.
Now I want to paint each polygon with different color depending on the value of the name property, but this is not working properly.
See this JS bin Demo
map.on('load', function () {
map.addLayer({
'id': 'maine',
'type': 'fill',
'layout': {},
'paint': {
'fill-color': {
property: 'name',
stops: [
['Albania', '#F2F12D'],
['Algeria', '#7A4900'],
['Australia', '#63FFAC'],
["South Africa", "#4FC601"],
["South Korea", "#3B5DFF"],
]
},
'fill-opacity': 0.8
},
'source': {
'type': 'vector',
'url': 'mapbox://saurabhp.countries_tileset'
},
"source-layer": "countries",
});
});
Every thing in your code was perfect, the only thing which you have missed out is type: 'categorical' inside the fill-color, You need to specify the type
Checkout this link for more details run the below code snippet to see the demo
mapboxgl.accessToken = 'pk.eyJ1Ijoic2F1cmFiaHAiLCJhIjoiY2l6OWRwM2JlMDAxZTJ3b2ZwejAzdzhpdSJ9.nc4cEdRwhErEg2wuUkABbw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-1.41, 6.32],
zoom: 5
});
map.on('load', function () {
map.addLayer({
'id': 'maine',
'type': 'fill',
'layout': {},
'paint': {
'fill-color': {
property: 'name',
type: 'categorical',
stops: [
['Albania', '#F2F12D'],
['Algeria', '#7A4900'],
['Australia', '#63FFAC'],
["South Africa", "#4FC601"],
["South Korea", "#3B5DFF"],
]
},
'fill-opacity': 0.8
},
'source': {
'type': 'vector',
'url': 'mapbox://saurabhp.countries_tileset'
},
"source-layer": "countries",
});
});
<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>
</body>
</html>

Categories