I am really confused with all the documentation of Mapbox GL combined with the react-mapbox-gl doc.
I don't understand how can my users add custom markers/icons (what's the difference between markers and icons?) to their map, which will be stored in the database, then loaded from the db to their map when they come back.
Has it something to do with geoJSON ? What is a geoJSON used for?
Thanks in advance for lighting my path in the dark :)
EDIT: Ok, so here is my code, but it does not create markers onClick:
`onMapClick(map, e) {
console.log(e.point);
console.log(e.lngLat);
const features = map.queryRenderedFeatures(e.point);
console.log(features)
const xCoordinate = e.lngLat.lng;
const yCoordinate = e.lngLat.lat;
const data = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [yCoordinate, xCoordinate]
},
properties: {
title: features[0].properties.name,
description: features[0].properties.maki
}
}]
};
this.setState({geoJson: data});
}
render() {
let feat = this.state.geoJson.features ? this.state.geoJson.features : null;
return (
containerStyle={styles.map}
onClick={(map, e) => this.onMapClick(map,e)}>
id="marker"
layout={{ "icon-image": "harbor-15" }}>
{feat && feat.map((marker, index) => {
console.log(marker);
return (
coordinates={marker.geometry.coordinates}/>)
}
)}
);
}`
PS: I have no idea why the code does not show properly.....
I handled adding custom icons just by keeping an array of coordinates in state. Then I rendered a feature with my icon's SymbolLayer for each pair. In order to render the point as my image, I used the images prop on the Layer, which should look like ['image-id', 'image-url']. Here is a version with 5 points already added, but you will need to change url for Icon:
import React from "react";
import Icon from "./form.png";
import ReactMapboxGl, { Layer, Feature, ZoomControl } from "react-mapbox-gl";
const Map = ReactMapboxGl({
accessToken: ""
});
class MapWithIcons extends React.Component {
state = {
points: [
[-87.6309729, 41.76716449],
[-87.63097366, 41.76668286],
[-87.63095643, 41.76619789],
[-87.63095245, 41.76578],
[-87.63094033, 41.76561825]
],
zoom: [15],
center: [-87.63097788775872, 41.767174164037044]
};
handleClick = (map, ev) => {
const { lng, lat } = ev.lngLat;
var { points } = this.state;
points = [...points, [lng, lat]];
const zoom = [map.transform.tileZoom + map.transform.zoomFraction];
this.setState({
points,
zoom,
center: map.getCenter()
});
};
render() {
const { points, zoom, center } = this.state;
const image = new Image(20, 30);
image.src = Icon;
const images = ["myImage", image];
return (
<Map
style={style}
zoom={zoom}
center={center}
containerStyle={{ height: 315, width: 308 }}
onClick={this.handleClick}
>
<Layer
type="symbol"
id="points"
layout={{ "icon-image": "myImage", "icon-allow-overlap": true }}
images={images}
>
{points.map((point, i) => <Feature key={i} coordinates={point} />)}
</Layer>
</Map>
);
}
}
Closing the issue, the question was answered
Most helpful comment
I handled adding custom icons just by keeping an array of coordinates in state. Then I rendered a feature with my icon's SymbolLayer for each pair. In order to render the point as my image, I used the images prop on the Layer, which should look like ['image-id', 'image-url']. Here is a version with 5 points already added, but you will need to change url for Icon: