How to get the markers details in the drawn polygon? - javascript

The markers will be added dynamically using firebase.
map.loadImage(
AddressIcon,
function(error, image) {
if (error) throw error;
map.addImage(id + 'address', image);
map.addSource(id + 'point', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
features
]
}
});
map.addLayer({
'id': id + "addresses-layer",
'type': 'symbol',
'source': id + 'point',
'layout': {
'icon-image': id + 'address',
'icon-size': 1
}
});
});
draw = new MapboxDraw({
displayControlsDefault: false,
userProperties: true,
controls: {
polygon: true,
trash: true
},
});
map.addControl(draw, 'bottom-left');
map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.FullscreenControl());
map.on('draw.create', updateDrawArea);
map.on('draw.delete', updateDrawArea);
map.on('draw.update', updateDrawArea);
const updateDrawArea = (e) => {
var data = draw.getAll();
console.log(data);
}
I have the polygon drawing system on the map. I need to get all of the added layers/markers after draw the polygon around the markers. I need to do this using mapbox-gl-js if possible. If not is there any alternatives?

Yes, it is possible through Turf.js.
Turf.js exposes functions such as pointsWithinPolygon, that allow us to specify marker points and polygon coordinates, and returns a list of markers that inside the specified polygon.
For example:
var pointsWithinPolygon = require("#turf/points-within-polygon")
const turf = require('#turf/turf');
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]
]]);
var ptsWithin = turf.pointsWithinPolygon(points, searchWithin);
console.log(ptsWithin)
You can refer to this tutorial that explains how we can use turf.js along-side mapbox-gl-draw.

Related

Data driven styling errors using client-side join - Mapbox GL JS

I have implemented a client-side join from a GitHub based CSV to a Mapbox tileset using a Papa-parse promise function, similar to how it is implemented in: Data Joins : Mapbox JS.
The promise is fulfilled and the data is stored correctly, the outlines of the regions I am trying to visualise show, but there is an issue with data-driven styling with the "interpolate", ['linear'] parameters I am trying to use, from my past experience. The 'accessibilityOutline' ID layer shows its data correctly, so it is confusing to why this is happening.
An error keeps coming up declaring
"Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values."
I am wondering if anyone else has had this problem, and the way it was overcome. Any help would be grateful.
The code implemented is below, this is all based off the link above. The data is read in correctly and through debug testing I can see that all the data is in the correct format as the
dynamicTyping: true,
is present in the Papa.parse function. However, mapbox looks like it is unable to read this data.
function papaPromise(url) {
return new Promise(function(resolve,reject) {
Papa.parse(url, {
download: true,
header: true,
skipEmptyLines: true,
complete: resolve,
dynamicTyping: true,
});
});
}
const accessibilityCSV = papaPromise("some random url of data");
const mapContainer = useRef();
useEffect(() => {
const map = new mapboxgl.Map({
container: mapContainer.current,
style: "mapbox://styles/mapbox/outdoors-v11",
center: [-2.597, 53.39],
zoom: 9.5,
});
map.on("load", () => {
accessibilityCSV.then(function (results) {
console.log(results.data);
results.data.forEach((row) => {
map.setFeatureState({
source: 'lsoa_ultra_generalised-3gznbd',
sourceLayer: 'lsoa_ultra_generalised-3gznbd',
id: row.lsoa_code
}, {
lsoa_name: row.lsoa_name,
Total_LSOA_population: row.Total_LSOA_population,
LSOA_population_low_income: row.LSOA_population_low_income,
airport_jt60: row.airport_jt60,
airport_jt90: row.airport_jt90,
seaport_jt60: row.seaport_jt60,
seaport_jt90: row.seaport_jt90,
city_jt60: row.city_jt60,
city_jt90: row.city_jt90,
visitor_attraction_jt60: row.visitor_attraction_jt60,
visitor_attraction_jt90: row.visitor_attraction_jt90,
beach_jt60: row.beach_jt60,
beach_jt90: row.beach_jt90,
national_park_jt60: row.national_park_jt60,
national_park_jt90: row.national_park_jt90,
biz_60: row.biz_60,
biz_90: row.biz_90,
NPIER_60: row.nPIER_60,
NPIER_90: row.nPIER_90,
uni_places_60: row.uni_places_60,
uni_places_90: row.uni_places_90
},
);
});
});
map.addSource('northOutline', {
type: "vector",
url: "vectorURL"
})
map.addSource("accessibilitySource", {
type: "vector",
url: "vectorURL",
promoteId: 'LSOA11CD'
});
map.addLayer({
id: 'accessibility',
type: 'fill',
source: 'accessibilitySource',
'source-layer': 'lsoa_ultra_generalised-3gznbd',
paint: {
"fill-color":[
"interpolate",
['linear'],
['number', ["feature-state","Total_LSOA_population"]],
0,
"#fee5d9",
2075,
"#fcae91",
4150,
"#fb6a4a",
6225,
"#de2d26",
8300,
"#a50f15",
/* other */, "#ccc",
],
},
});
map.addLayer({
id:'accessibilityOutline',
type:'line',
source: 'accessibilitySource',
'source-layer': 'lsoa_ultra_generalised-3gznbd',
paint: {
"line-color": '#000000'
},
});

MaxBounds and custom asymmetric padding in Mapbox GL

I have a Mapbox GL JS app, where over a map I display some widgets. To make sure nothing on the map will be hidden by them I've added some padding using map.setPadding(). It's an asymmetric one (left is larger than right in my case). It works as intended for things like fitBounds and animation but I also need to set up maxBounds of the map so the user won't pan out of the desired viewport. Unfortunately that doesn't work well with custom padding. When I draw the bounds and use showPadding I can see that those lines won't align. The problem grows bigger the bigger I make the difference between the paddings.
I was wondering if anybody had similar issues or can lead me to a solution where I can have map clamped to some bounds while still being able to use custom padding like I described above.
Here's an example of the issue: https://jsfiddle.net/1ysrgkcL/45/ Notice how the thick black rectangle doesn't align with the padding lines.
I ran into same problem earlier and i fix it using:
fitBounds as it add's the amount of padding(in pixels) to the given bounds.
requestAnimationFrame: In its callback i received the getBounds and set it as max bounds(trick)
Updated code snippet:
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiYnBhY2h1Y2EiLCJhIjoiY2lxbGNwaXdmMDAweGZxbmg5OGx2YWo5aSJ9.zda7KLJF3TH84UU6OhW16w';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-73.9774108244587, 40.820698485268366],
zoom: 11.6
});
map.on('load', function () {
const padding = { left: 300, right: 100, top: 100, bottom: 30 }; //<--- padding
const bounds = {
"n": 40.896790957065434,
"s": 40.76021859203365,
"e": -73.85756962495667,
"w": -74.09102645202957
}
const maxBounds = [[bounds.w, bounds.s], [bounds.e, bounds.n]];
//<---- notice here--->
map.fitBounds(maxBounds, {
padding, //<--- used here
linear: true,
duration: 0
});
map.showPadding = true
//<---- notice here--->
requestAnimationFrame(() => {
const getBoundsFromViewport = map.getBounds();
map.setMaxBounds(getBoundsFromViewport);
});
const boundsRect = [
[bounds.e, bounds.n],
[bounds.w, bounds.n],
[bounds.w, bounds.s],
[bounds.e, bounds.s],
[bounds.e, bounds.n]
]
map.on('click', (e) => console.log('##', e.lngLat.toArray()))
map.addLayer({
'id': 'bounds',
'type': 'line',
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'LineString',
'coordinates': boundsRect
}
}
},
'paint': {
'line-color': '#000000',
'line-width': 10
},
'layout': {}
});
});
</script>
And it will like charm in your case too. Attaching screenshot:
Give it a try!

Hide / Remove Specific GoogleMapsOverlay From Google Map

I have used geojson files into google map by multi selection . but when i try to remove overlay , it is not working .this is my code to used for add and remove.
i need to know how to remove selected geojson file from map
var deckOverlay ;
deckOverlay = new deck.GoogleMapsOverlay({
layers: [
new deck.GeoJsonLayer({
id: 'layerId',
data: 'path of geojson file',
filled: true,
pointRadiusMinPixels: 2,
opacity: 0.5,
pointRadiusScale: 2000,
getFillColor: f => (f.properties.COLOR),
wireframe: true,
pickable: true,
}), +
new deck.ArcLayer({
id: 'arcs',
data: Layer_Id,
dataTransform: d => d.features.filter(f => f.properties.scalerank < 4),
getSourcePosition: f => [-0.4531566, 51.4709959], // London
getTargetPosition: f => f.geometry.coordinates,
getSourceColor: [0, 128, 200],
getTargetColor: [200, 0, 80],
getWidth: 1
})
]
});
if (checked) {
deckOverlay.setMap(map); // Set multiple overlays working
}
else {
deckOverlay.setMap(null); // Remove Option Not Working
deckOverlay = null;
}
By using Data Layer .
To load map
map.data.loadGeoJson(Layer_Id);
To Remove Specific Layer
map.data.forEach(function (feature) {
if (feature.getProperty('myprop') == myprop) {
map.data.remove(feature);
}
});
To Remove All Layers
map.data.forEach(function (feature) {
map.data.remove(feature);
});
FYI , use color codes as HEX in json file not RGB or RGBA

How to pass a variable containing coordinates in to geojson 'coordinates' field?

I am trying to plot a polygon on mapboxgl by passing a variable that contains an array of coordinates after some mathematical calculations, into the field 'coordinates' of the map.addLayer function. Not sure if this is the correct way.
Did not manage to display the polygon with no error message.
map.addLayer({
'id' : "layer1",
'type': 'fill',
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [variable]
}
}
},
'layout': {},
'paint': {
'fill-color': '#cb4b16',
'fill-opacity': 0.8
}
});
Here are the coordinates generated:
[103.7721606585124334, 1.3885039360043285],[103.7721665513856095, 1.3885034225235453],[103.7721723986707616, 1.3885023864315598],[103.7721781772912948, 1.3885008318173533],[103.7721838644416437, 1.3884987648162785],[103.7721894376772411, 1.3884961935858440],[103.7721948750030521, 1.3884931282735218],[103.7722001549604443, 1.3884895809766988],[103.7722052567118425, 1.3884855656949355],[103.7722101601229525, 1.3884810982747144],[103.7722148458422566, 1.3884761963469021],[103.7722192953773686, 1.3884708792571681],[103.7722234911679919, 1.3884651679896367],[103.7722274166552694, 1.3884590850840712],[103.7722310563470955, 1.3884526545469213],[103.7722343958792663, 1.3884459017565793],[103.7722374220721804, 1.3884388533632233],[103.7722401229828222, 1.3884315371836418],[103.7722424879519423, 1.3884239820914532],[103.7722445076460787, 1.3884162179031552],[103.7722461740944340, 1.3884082752604512],[103.7722474807202815, 1.3884001855093238],[103.7722484223669852, 1.3883919805763247],[103.7722489953182929, 1.3883836928425759],[103.7722491973130161, 1.3883753550159763],[103.7722490275539826, 1.3883670000021182],[103.7722484867111490, 1.3883586607744245],[103.7722475769189714, 1.3883503702440168],[103.7722463017679928, 1.3883421611298310],[103.7722446662906464, 1.3883340658294905],[103.7722426769414170, 1.3883261162914475],[103.7722403415713615, 1.3883183438888969],[103.7722376693971000, 1.3883107792959604],[103.7722346709645080, 1.3883034523666304],[103.7722313581070068, 1.3882963920169498],[103.7722277438989522, 1.3882896261108932],[103.7722238426039496, 1.3882831813504006],[103.7722196696186501, 1.3882770831699975],[103.7722152414119137, 1.3882713556364161],[103.7722105754598374, 1.3882660213536144],[103.7722056901768184, 1.3882611013735697],[103.7722006048428227, 1.3882566151131959],[103.7721953395273573, 1.3882525802777126],[103.7721899150101876, 1.3882490127907725],[103.7721843526994405, 1.3882459267316163],[103.7721786745469927, 1.3882433342795102],[103.7721729029619269, 1.3882412456656776],[103.7721670607220545, 1.3882396691329237],[103.7721611708840044, 1.3882386109031029],[103.7721552566923151, 1.3882380751525645],[103.7721493414875624, 1.3882380639956715],[103.7721434486143863, 1.3882385774764547],[103.7721376013292343, 1.3882396135684403],[103.7721318227087011, 1.3882411681826468],[103.7721261355583522, 1.3882432351837215],[103.7721205623227547, 1.3882458064141561],[103.7721151249969438, 1.3882488717264783],[103.7721098450395516, 1.3882524190233012],[103.7721047432881534, 1.3882564343050645],[103.7720998398770433, 1.3882609017252856],[103.7720951541577392, 1.3882658036530979],[103.7720907046226273, 1.3882711207428320],[103.7720865088320039, 1.3882768320103633],[103.7720825833447265, 1.3882829149159288],[103.7720789436529003, 1.3882893454530787],[103.7720756041207295, 1.3882960982434207],[103.7720725779278155, 1.3883031466367768],[103.7720698770171737, 1.3883104628163583],[103.7720675120480536, 1.3883180179085468],[103.7720654923539172, 1.3883257820968449],[103.7720638259055619, 1.3883337247395489],[103.7720625192797144, 1.3883418144906763],[103.7720615776330106, 1.3883500194236753],[103.7720610046817029, 1.3883583071574241],[103.7720608026869797, 1.3883666449840237],[103.7720609724460132, 1.3883749999978818],[103.7720615132888469, 1.3883833392255756],[103.7720624230810245, 1.3883916297559833],[103.7720636982320030, 1.3883998388701690],[103.7720653337093495, 1.3884079341705096],[103.7720673230585788, 1.3884158837085525],[103.7720696584286344, 1.3884236561111032],[103.7720723306028958, 1.3884312207040397],[103.7720753290354878, 1.3884385476333696],[103.7720786418929890, 1.3884456079830503],[103.7720822561010436, 1.3884523738891068],[103.7720861573960462, 1.3884588186495994],[103.7720903303813458, 1.3884649168300025],[103.7720947585880822, 1.3884706443635839],[103.7720994245401585, 1.3884759786463856],[103.7721043098231775, 1.3884808986264303],[103.7721093951571731, 1.3884853848868042],[103.7721146604726385, 1.3884894197222875],[103.7721200849898082, 1.3884929872092275],[103.7721256473005553, 1.3884960732683838],[103.7721313254530031, 1.3884986657204899],[103.7721370970380690, 1.3885007543343224],[103.7721429392779413, 1.3885023308670763],[103.7721488291159915, 1.3885033890968972],[103.7721547433076807, 1.3885039248474356],[103.7721606585124334, 1.3885039360043285]
As you can see in the docs you are doing it the correct way assuming variable is an array of the coordinates you posted.
Here is a fiddle with I think is the desired result.
It is using mapbox v1.3.1. For some reason the snippet errored here on StackOverflow.
Thanks to #rafaelcastrocouto for the access token ^^
Seems like your polygon data is working just fine.
You can use the example below to figure out if your points are properly structured.
mapboxgl.accessToken = 'pk.eyJ1IjoiZmFyYWRheTIiLCJhIjoiTUVHbDl5OCJ9.buFaqIdaIM3iXr1BOYKpsQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [103.7721606585124334, 1.3883539360043285],
zoom: 18
});
map.on('load', () => {
map.addLayer({
'id' : "layer1",
'type': 'fill',
'layout': {},
'paint': {
'fill-color': '#cb4b16',
'fill-opacity': 0.8
},
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [[
[103.7721606585124334, 1.3885039360043285],
[103.7721665513856095, 1.3885034225235453],
[103.7721723986707616, 1.3885023864315598],
[103.7721781772912948, 1.3885008318173533],
[103.7721838644416437, 1.3884987648162785],
[103.7721894376772411, 1.3884961935858440],
[103.7721948750030521, 1.3884931282735218],
[103.7722001549604443, 1.3884895809766988],
[103.7722052567118425, 1.3884855656949355],
[103.7722101601229525, 1.3884810982747144],
[103.7722148458422566, 1.3884761963469021],
[103.7722192953773686, 1.3884708792571681],
[103.7722234911679919, 1.3884651679896367],
[103.7722274166552694, 1.3884590850840712],
[103.7722310563470955, 1.3884526545469213],
[103.7722343958792663, 1.3884459017565793],
[103.7722374220721804, 1.3884388533632233],
[103.7722401229828222, 1.3884315371836418],
[103.7722424879519423, 1.3884239820914532],
[103.7722445076460787, 1.3884162179031552],
[103.7722461740944340, 1.3884082752604512],
[103.7722474807202815, 1.3884001855093238],
[103.7722484223669852, 1.3883919805763247],
[103.7722489953182929, 1.3883836928425759],
[103.7722491973130161, 1.3883753550159763],
[103.7722490275539826, 1.3883670000021182],
[103.7722484867111490, 1.3883586607744245],
[103.7722475769189714, 1.3883503702440168],
[103.7722463017679928, 1.3883421611298310],
[103.7722446662906464, 1.3883340658294905],
[103.7722426769414170, 1.3883261162914475],
[103.7722403415713615, 1.3883183438888969],
[103.7722376693971000, 1.3883107792959604],
[103.7722346709645080, 1.3883034523666304],
[103.7722313581070068, 1.3882963920169498],
[103.7722277438989522, 1.3882896261108932],
[103.7722238426039496, 1.3882831813504006],
[103.7722196696186501, 1.3882770831699975],
[103.7722152414119137, 1.3882713556364161],
[103.7722105754598374, 1.3882660213536144],
[103.7722056901768184, 1.3882611013735697],
[103.7722006048428227, 1.3882566151131959],
[103.7721953395273573, 1.3882525802777126],
[103.7721899150101876, 1.3882490127907725],
[103.7721843526994405, 1.3882459267316163],
[103.7721786745469927, 1.3882433342795102],
[103.7721729029619269, 1.3882412456656776],
[103.7721670607220545, 1.3882396691329237],
[103.7721611708840044, 1.3882386109031029],
[103.7721552566923151, 1.3882380751525645],
[103.7721493414875624, 1.3882380639956715],
[103.7721434486143863, 1.3882385774764547],
[103.7721376013292343, 1.3882396135684403],
[103.7721318227087011, 1.3882411681826468],
[103.7721261355583522, 1.3882432351837215],
[103.7721205623227547, 1.3882458064141561],
[103.7721151249969438, 1.3882488717264783],
[103.7721098450395516, 1.3882524190233012],
[103.7721047432881534, 1.3882564343050645],
[103.7720998398770433, 1.3882609017252856],
[103.7720951541577392, 1.3882658036530979],
[103.7720907046226273, 1.3882711207428320],
[103.7720865088320039, 1.3882768320103633],
[103.7720825833447265, 1.3882829149159288],
[103.7720789436529003, 1.3882893454530787],
[103.7720756041207295, 1.3882960982434207],
[103.7720725779278155, 1.3883031466367768],
[103.7720698770171737, 1.3883104628163583],
[103.7720675120480536, 1.3883180179085468],
[103.7720654923539172, 1.3883257820968449],
[103.7720638259055619, 1.3883337247395489],
[103.7720625192797144, 1.3883418144906763],
[103.7720615776330106, 1.3883500194236753],
[103.7720610046817029, 1.3883583071574241],
[103.7720608026869797, 1.3883666449840237],
[103.7720609724460132, 1.3883749999978818],
[103.7720615132888469, 1.3883833392255756],
[103.7720624230810245, 1.3883916297559833],
[103.7720636982320030, 1.3883998388701690],
[103.7720653337093495, 1.3884079341705096],
[103.7720673230585788, 1.3884158837085525],
[103.7720696584286344, 1.3884236561111032],
[103.7720723306028958, 1.3884312207040397],
[103.7720753290354878, 1.3884385476333696],
[103.7720786418929890, 1.3884456079830503],
[103.7720822561010436, 1.3884523738891068],
[103.7720861573960462, 1.3884588186495994],
[103.7720903303813458, 1.3884649168300025],
[103.7720947585880822, 1.3884706443635839],
[103.7720994245401585, 1.3884759786463856],
[103.7721043098231775, 1.3884808986264303],
[103.7721093951571731, 1.3884853848868042],
[103.7721146604726385, 1.3884894197222875],
[103.7721200849898082, 1.3884929872092275],
[103.7721256473005553, 1.3884960732683838],
[103.7721313254530031, 1.3884986657204899],
[103.7721370970380690, 1.3885007543343224],
[103.7721429392779413, 1.3885023308670763],
[103.7721488291159915, 1.3885033890968972],
[103.7721547433076807, 1.3885039248474356],
[103.7721606585124334, 1.3885039360043285]
]]
}
}
}
});
});
#map {
width: 100vw;
height: 100vh;
}
<script src="https://npmcdn.com/#turf/turf#5.1.6/turf.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.css" rel="stylesheet" type="text/css">
<div id="map"></div>

mapbox ForEach function

When pulling in data from a geojson file that is stored online. The forEach function can not read the features I have set in the geojson file. Below is part of the code.
map.on('load', function() {
// Add a GeoJSON source containing place coordinates and information.
map.addSource('orders', {
type: 'geojson',
data: ordersjson,
});
map.addLayer({
id: "layerID",
type: "symbol",
source: 'orders',
layout: {
"icon-image": "circle" + "-15",
"icon-allow-overlap": true,
},
});
map.getLayer('layerID').features.forEach(function(feature) {
var earthquakeID = feature.properties['primary ID']
});
The layer itself does not have any data at all. What you need is to get the source that holds the data. The layer is just for style definitions.
What you want is something like this:
map.getSource('orders')._data.features.forEach(function(feature) {
// do something
});

Categories