Show markers behind polygons - javascript

I have created circle (type polygon, with computed coordinates by this formula - still not sure if this is best way to render circle...)
and some markers, representing cities.
I prefer markers, because they are html elements and I can style them.
Circle serves as a radius for selecting cities.
My question is, how can I position these markers behind circle? Circle is part of canvas, and markers are separated divs, so there won't help any z-index.
Or should I create those markers somehow as points in canvas?
Looking exactly for this behaviour, only in mapboxgl.

Here is an example: https://jsfiddle.net/kmandov/vzc0o86g/
You can use turf-circle to create a circle using a specified radius and units. Turf-circle generates a geojson object that can be added to its own layer.
var center = {
"type": "Feature",
"properties": {
"marker-color": "#0f0"
},
"geometry": {
"type": "Point",
"coordinates": [-77.1117, 38.8739]
}
};
var lasso = turf.circle(center, 5, 20, 'kilometers');
Then you add it to its own layer. I've called it lasso:
map.addSource('lasso', {
'type': 'geojson',
'data': lasso
});
map.addLayer({
'id': 'lasso',
'type': 'fill',
'source': 'lasso',
'paint': {
'fill-color': '#f1f075',
'fill-opacity': 0.8
}
});
Then you add the layer containing the stations by specifying the layer above(example). This will make sure that the lasso layer is above the stations layer:
map.addLayer({
'id': 'stations',
'type': 'circle',
'source': 'stations',
'paint': {
'circle-color': '#feb24c',
'circle-opacity': 1,
'circle-radius': 5
}
}, 'lasso'); // lasso is the layer above

Related

Activate mapbox draw tool only within layer boundary

I have a geojson mapbox tileset visualized on a map. I am currently able to draw shapes such as polygons,polylines and add points to the map. But I now want to limit the draw tool to only allow drawing within the boundaries of the geojson layer. How would I do this? What I currently has, lets the cursor change to a pan symbol when it's outside of the map, and to a crosshair symbol when inside the map.
But once I click the draw tool buttons, it overrides this and lets the user draw anywhere they want.
mapboxgl.accessToken = config.MAPBOX_PUBLIC;
const map = new mapboxgl.Map({
attributionControl: false,
container: "map", // container ID
style: "mapbox://styles/mapbox/outdoors-v10",
center: [-69.45, 45.07], // starting position [lng, lat]
zoom: 8, // starting zoom
});
export function makeClickableArea() {
map.on("load", () => {
map.addSource('maine', {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
// These coordinates outline Maine.
'coordinates': [
[
[-67.13734, 45.13745],
[-66.96466, 44.8097],
[-68.03252, 44.3252],
[-69.06, 43.98],
[-70.11617, 43.68405],
[-70.64573, 43.09008],
[-70.75102, 43.08003],
[-70.79761, 43.21973],
[-70.98176, 43.36789],
[-70.94416, 43.46633],
[-71.08482, 45.30524],
[-70.66002, 45.46022],
[-70.30495, 45.91479],
[-70.00014, 46.69317],
[-69.23708, 47.44777],
[-68.90478, 47.18479],
[-68.2343, 47.35462],
[-67.79035, 47.06624],
[-67.79141, 45.70258],
[-67.13734, 45.13745]
]
]
}
}
});
// Add a new layer to visualize the polygon.
map.addLayer({
'id': 'maine',
'type': 'fill',
'source': 'maine', // reference the data source
'layout': {},
'paint': {
'fill-color': '#0080ff', // blue color fill
'fill-opacity': 0.5
}
});
// Add a black outline around the polygon.
map.addLayer({
'id': 'outline',
'type': 'line',
'source': 'maine',
'layout': {},
'paint': {
'line-color': '#000',
'line-width': 3
}
});
});
changeMouseSymbol();
}
// add the draw tool
function changeMouseSymbol() {
const modes = MapboxDraw.modes;
var draw = new MapboxDraw({
displayControlsDefault: false,
// Select which mapbox-gl-draw control buttons to add to the map.
controls: {
point: true,
line_string: true,
polygon: true,
},});
map.addControl(draw);
map.on("mouseover", "maine", () => {
map.getCanvas().style.cursor = "crosshair";
});
map.on("mouseleave", "maine", () => {
map.getCanvas().style.cursor = "";
});
}

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 display database values on mapbox?

I am using Mapbox and I created a database with values like (longitude and latitude), I want to display the data in the form of polygon on my map.
As you can see I want to put the the longitude and latitude from my database to the coordinates on my code but I don't know how to retrieve it from my database.
map.on('load', function() {
map.addSource('maine', {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[]
]
}
}
});
map.addLayer({
'id': 'maine',
'type': 'fill',
'source': 'maine',
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
});
this is my database which is in the file api.php:
I don't know how to retrieve it from your database either, because you haven't provided any details. But generally speaking, your approach will be:
provide an API that provides access to the data in some form (such as CSV) via URL (example.com/mydatabase/points.csv)
fetch the CSV in the client, and transform it to GeoJSON. (If your back end can generate GeoJSON directly, you can save this step)
add it to the Mapbox map as a GeoJSON source layer

Data-driven cluster colour with mapboxgl

I am trying to draw circle which colour depends on a "group" attribute in my geojson. I followed a simple example with these colours:
map.addSource("data", {
type: "geojson",
data: url,
cluster: true,
clusterMaxZoom: 12, // Max zoom to cluster points on
clusterRadius: 20 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
'id': 'population',
'type': 'circle',
'source': 'data',
'paint': {
// make circles larger as the user zooms from z12 to z22
'circle-radius': {
'base': 1.75,
'stops': [[12, 2], [22, 180]]
},
// color circles by ethnicity, using a match expression
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
'circle-color': {
'property': 'group',
'type': 'categorical',
stops: [
['1', 'rgba(252,141,98,0.5)'],
['2', 'rgba(141,160,203,0.5)'],
['3', 'rgba(141,160,203,0.5)'],
['4', 'rgba(141,160,203,0.5)'],
['5', 'rgba(141,160,203,0.5)'],
['6', 'rgba(141,160,203,0.5)'],
//'4', '#3bb2d0',
/* other 'rgba(102,194,165,0.1)'*/
]
}
}
},'3d-buildings');
Now I would also like my clusters to follow some kind of colour-pattern. For instance, if the clusters contains a majority of group 1 then it does get the colour of group 1. Same for groupe 2 and so on.
But all I for the cluster points is black dots. I would very much like to know if there is a way to do better than that.
I have been following this example and updated it with the additional "type":"categorical" as required by the new versions of mapboxgl.
My data is a geojson that goes like this:
{"type": "FeatureCollection", "features": [{"id": 1, "type": "Feature", "properties": {"group":1}, "geometry": {"type": "Point", "coordinates": [17.8304903812012, 59.1886524824444]}}
Would anyone know how to achieve that with mapbox?
Edit:
Two images to show the problems that I currently have. The first image is basically my non-clustered visualization where you see two different colours based on the two groups.
The second image, is the clustered version, which only display black clusters. I would like for clusters with a majority of group 1 to be orange and for clusters with a majority of group 2 to be green.
Edit
Now I have also seen that I might have to do that with supercluster, but the only proper example that I have found is broken (stops working when we zoom too much and the points are always clustered). Also it seems that this is using old mapbox features that are now deprecated. Would someone know how to make this work easily on the provided example?

defining a polygon fill color based on geojson with mapbox

I am using a mapbox example in order to create multiple polygons on a map, and I have pop-up event for each. My problem is that I need to set each polygon's fill color differently based on it's geojson properties.
This is my example.
I am using the following javascript code:
mapboxgl.accessToken = 'pk.eyJ1IjoibWFoYW5tZWhydmFyeiIsImEiOiJ6SDdSWldRIn0.8zUNm01094D1aoSeHpWYqA';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [51.40545845031738,
35.75069181054449],
zoom: 10
});
map.on('load', function (e) {
// Add a layer showing the state polygons.
map.addLayer({
'id': 'states-layer',
'type': 'fill',
'source': {
'type': 'geojson',
'data': 'geojson.js'
},
'paint': {
'fill-color': 'rgba(200, 100, 240, 0.4)',
'fill-outline-color': 'rgba(200, 100, 240, 1)'
}
});
// When a click event occurs on a feature in the states layer, open a popup at the
// location of the click, with description HTML from its properties.
map.on('click', 'states-layer', function (e) {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
//.setHTML(e.features[0].properties.name)
.setHTML("<h1>"+e.features[0].properties.userone+"</h1>"+e.features[0].properties.name)
.addTo(map);
});
// Change the cursor to a pointer when the mouse is over the states layer.
map.on('mouseenter', 'states-layer', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'states-layer', function () {
map.getCanvas().style.cursor = '';
});
});
Here it loads the colors all the same
'paint': {
'fill-color': 'rgba(200, 100, 240, 0.4)',
'fill-outline-color': 'rgba(200, 100, 240, 1)'
}
On my geojson file I have a key for color:
"type": "Feature",
"properties": {
"userone":"پیروزی",
"name":"North Dafkota",
"featureclass":"Admin-1 scale rank",
"color":"red"
}
I want to use it to define the polygons fill color.
If you just want to use a color that you define in geojson feature properties. Then you could use the layers identity property like this:
map.addLayer({
'id': 'states-layer',
'type': 'fill',
'source': {
'type': 'geojson',
'data': 'geojson.js'
},
'paint': {
'fill-color': {
type: 'identity',
property: 'color',
},
'fill-outline-color': 'rgba(200, 100, 240, 1)'
}
});
Also see: https://www.mapbox.com/mapbox-gl-js/style-spec/#function-type
And: https://www.mapbox.com/mapbox-gl-js/style-spec/#types-color

Categories