add multiple geoJSON sources with mapbox GL Js - mapbox

I am trying to add another source with a new layer to the map with the type geoJSON on the map (mapbox).
I am getting the error message
ERROR Error: There is already a source with this ID
How can I add another geo-source in typescript with a new map.addSource besides an existing geo-source?
First geo-source:
map.addSource("polygon", create(coordinates, 0.5, 64));
map.addLayer({
"id": "polygon",
"type": "fill",
"source": "polygon",
"layout": {},
"paint": {
'fill-color': {
type: 'identity',
property: 'color',
},
'fill-outline-color': 'rgba(200, 100, 240, 1)',
"fill-opacity": 0.090
}
});
in method:
return {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [ret]
}
}]
}
};
second source:
map.addSource('places', {
'type': 'geojson',
'data': activitiesPlaces
});
var activitiesPlaces = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {
'name': valuesName
},
'geometry': {
'type': 'Point',
'coordinates':
valuesLon,
valuesLat
}
}
]
};
calling this source gives me the error message

The first argument to the Map#addSource method specifies a source ID for the particular source. Each source ID in a map style must be unique, as noted in the API reference here:
Parameters
id (string) The ID of the source to add. Must not conflict with existing sources.
So, specifying unique source IDs for each source added to the map will resolve the error.

Instead of adding multiple sources, you should try adding multiple layers.
map.addLayer({
id: 'features-fill',
type: 'fill',
source: 'features',
paint: {'fill-color': 'red', 'fill-opacity': 0.6}
});
map.addLayer({
id: 'features-fill-1',
type: 'fill',
source: 'features',
paint: {'fill-color': 'blue', 'fill-opacity': 0.8}
});
UPDATE:
map.once('load', function loaded() {
map.batch(function batch() {
features.forEach(function eachFilter(feature, index) {
var id = 'feature-' + index;
map.addSource(id, {type: 'geojson', data: feature});
map.addLayer({
id: id + '-fill',
type: 'fill',
source: id,
paint: {'fill-color': 'red', 'fill-opacity': 0.6}
});
});
});
});
Check out this issue: https://github.com/mapbox/mapbox-gl-js/issues/1484

Related

How to change styles/properties of features by data from extra json file? (MapBox GL)

So far I have a map (MapBox GL) that draws counties with borders.
map.addSource('states', {
'type': 'geojson',
'data': '/geojson/county_boundaries.geojson'
});
map.addLayer({ // adding borders:
'id': 'state-borders',
'type': 'line',
'source': 'states',
'layout': {},
'paint': {
'line-color': '#627BC1',
'line-width': 2
}
});
This county_borders.geojson has items (features) with parameter 'name'.
...
"features": [
{ "type": "Feature", "id": 8, "properties": { "name": "New York", ...
I have another stats.json file with properties for most of the features, where 'name' is the main key.
"New York": {
"Population": "500123",
"Food Consumption Level": "3",
"Color": "#e67800"
},
I am new to MapBox, and with so many parameters-based functions I am getting lost. Please help me to change the fill color of all states with the Color from stats.json file by looking up their names ("New York" etc). I suppose I need to iterate through all the features and set their filling somehow.
The only way I have found to fill the states with the same default color is like this:
map.addLayer({
'id': 'state-fills',
'type': 'fill',
'source': 'states',
'layout': {},
'paint': {
'fill-color': '#627BC1',
'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
0.5
]
}
});
It is working to fill all the states. But not what I need. I would like to dynamically modify color of each state runtime, without changing original geojson file. (Other params in data.json I show in popup, which works fine with this extra file approach.)
Instead of adding your original GeoJSON file as a source to your map, you can add the stats to the GeoJSON with Javascript before adding the source:
var geojson = addStats(originalGeojson, stats);
map.addSource('states', {
'type': 'geojson',
'data': geojson
});
function addStats(geojson, stats) {
geojson.features.forEach((feature) => {
var statsForFeature = stats[feature.properties.name];
if (statsForFeature) {
// add stats to the feature's properties
feature.properties = Object.assign(feature.properties, statsForFeature);
}
});
return geojson;
}
After that, you can use data-driven styling with layer type 'fill' to color your features:
map.addLayer({ // adding borders:
'id': 'state-borders',
// use type 'fill'
'type': 'fill',
'source': 'states',
'layout': {},
'paint': {
'fill-outline-color': '#627BC1',
// use data-driven styling
'fill-color': ['get', 'Color'],
},
});
Here is a working example demonstrating this technique: https://jsfiddle.net/0s17mqvh/

Adding wmts layer to mapbox gl from geoserver

I'm trying to add wmts layer from geoserver 2.18. My code:
window.mymap.addSource(
"mvt-test-source", {
"type": "vector",
"tiles": [
"http://localhost:8080/geoserver/gwc/service/wmts?SERVICE=WMTS&&VERSION=1.0.0&REQUEST=GetTile&layer=mapbox:roads4326&TILEMATRIX=EPSG:4326:{z}&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL={x}&TILEROW={y}"
],
"minZoom": 0,
"maxZoom": 14
});
window.mymap.addLayer(
{
'id': 'my_mvt_layer',
'type': 'line',
'source': 'mvt-test-source',
'source-layer': 'mapbox:roads4326',
"visibility": "visible",
'paint': {
'line-color': 'Red',
'line-width': 7
}
}
);
There are no errors in browser, but layer don't appear on the map.
What could be the reason?
When I try to use wms service - all work fine. Next code with wms format:
window.mymap.addSource("wms-test-source", {
"type": 'raster',
"tiles": [
"http://localhost:8080/geoserver/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&&version=1.1.1&request=GetMap&srs=EPSG:900913&transparent=true&width=256&height=256&layers=mapbox:roads4326"
],
'tileSize': 256
});
window.mymap.addLayer(
{
"id": 'wms-test-layer',
"type": 'raster',
"source": 'wms-test-source',
"paint": {
}
}
);
Your visibility property should not be added that way. Add it like so:
window.mymap.addLayer(
{
'id': 'my_mvt_layer',
'type': 'line',
'source': 'mvt-test-source',
'source-layer': 'mapbox:roads4326',
'layout':{
"visibility": "visible",
}
'paint': {
'line-color': 'Red',
'line-width': 7
}
}
);

How to remove specific feature in feature collection under geojson source in a places layer?

I got this:
map.addLayer({
"id": "places",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": features
}
},
"layout": {
"icon-image": "{icon}-15",
"text-field": "{title}",
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
"text-offset": [0, 0.6],
"text-anchor": "top"
}
});
Where features is array of objects like this:
{
"id": SOME_ID,
"type": "Feature",
"properties": {
"title": SOME_TITLE,
"icon": "monument"
},
"geometry": {
"type": "Point",
"coordinates": SOME_COORDINATES
}
}
I want to delete this specific feature, NOT THE WHOLE places LAYER, how can it be done?
I have tried to create for each feature, a designated layer with predefined ID, but
when tried to remove it using map.removeLayer(SOME_ID) this told me that the
layer id does not exist.
How to delete specific geojson feature from feature collection in mapbox, without delete the wole
layer, just the json data?
If you want to hide the feature on the map, then you don't have to remove it from the source. You can filter this feature out using filter, so it wouldn't be rendered on the map.
Consider example:
map.addLayer({
id: 'points',
type: 'circle',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
id: 1,
properties: {},
geometry: {
type: 'Point',
coordinates: [127.61718749999999, 66.51326044311185]
}
},
{
type: 'Feature',
id: 2,
properties: {},
geometry: {
type: 'Point',
coordinates: [79.1015625, 72.50172235139388]
}
},
{
type: 'Feature',
id: 3,
properties: {},
geometry: {
type: 'Point',
coordinates: [61.17187499999999, 31.952162238024975]
}
}
]
}
},
filter: ['!=', '$id', 3]
});
This will render all features except feature with id=3.
You can also set this kind of filters using map.setFilter method.
map.setFilter('my-layer', ['==', 'name', 'USA']);
Edit:
If you really want to remove a specific feature from the source, you can filter this feature from the features array and update the source using setData:
map.getSource('places').setData({
"type": "FeatureCollection",
features
});

how to set different pattern on each wall with mapbox-gl-js

I use fill-extrusion layer to add building on the map, but how to paint the wall with different color/pattern?
i try to use self-host sprite, but failed, according to chrome developer tool, sprite#2x.json,sprite#2x.png loaded success.
var map = new mapboxgl.Map({
container: 'map',
style: {
"version": 8,
sprite: "http://localhost:8000/map/sprite",
sources: {
maine: {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'id': 1,
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[-68.13534351262877, 45.137451890638886],
[-68.13334151262877, 45.137451890638886],
[-68.13334151262877, 45.139421890638886],
[-68.13534351262877, 45.139421890638886],
[-68.13534351262877, 45.137451890638886]
]
]
},
"properties": {
"height": 60,
"min_height": 30
}
}]
}
}
},
layers: [{
'id': 'maine2',
'source': 'maine',
'layout': {},
"type": "fill-extrusion",
'paint': {
'fill-extrusion-color': '#f00',
'fill-extrusion-pattern': 'wall',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'min_height'
},
'fill-extrusion-opacity': 1
}
}]
},
center: [-68.13734351262877, 45.137451890638886],
zoom: 15,
pitch: 60,
});
more details about question 2:
sprite#2x.json, sprite#2x.png loaded success, but nothing show on the screen, but it shows a red cube when i comment the fill-extrusion-pattern line
I use fill-extrusion layer to add building on the map, but how to paint the wall with different color/pattern?
This is not possible with Mapbox-GL-JS.
(You should post your other question separately, with more details.)

Mapbox GL Issue with Updating Line Display

I have a line that is drawn on the map. It is initially created in the IF section of the following code, and it is updated in the ELSE section. However, the UI is never update with the setData(). I have similar code with a polygon and it works fine. What is wrong?
if (!moDistanceSource) {
moDistanceSource = {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': [[-120, 49], [-118, 40]]
}
}]
};
moMap.addSource('DistanceSource', {
"type": "geojson",
"data": moDistanceSource
});
moMap.addLayer({
'id': 'DistanceLayer',
'type': 'line',
'source': 'DistanceSource',
'layout': {
"line-join": "round",
"line-cap": "round"
},
'paint': {
"line-color": "#888",
"line-width": 3
}
});
console.log('add distance layer');
}
else {
moDistanceSource.features[0].geometry.coordinates = [[-110,59],[-108,50]];
console.log('maDistancePoints', maDistancePoints);
moMap.getSource('DistanceSource').setData(moDistanceSource);
}