Dragging event not working on React leaflet - reactjs

I'm trying to update the latitude and longitude coordinates after dragging a Marker over an Leaflet map in my React project. This is my map container component:
import React from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import './styles/Map.css';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
//import {MarkerIcon} from './Icon.js';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow
});
L.Marker.prototype.options.icon = DefaultIcon;
class Mapa extends React.Component{
constructor(props) {
super(props);
this.state = {
currentLocation: { lat: -16.399, lng: -71.536 },
zoom: 17,
}
this.updatePosition = this.updatePosition.bind(this);
}
updatePosition = (e) =>{
e.preventDefault();
console.log("hola");
/*this.setState({currentLocation:e.latlng})*/
};
render() {
return (
<MapContainer center={this.state.currentLocation} zoom={this.state.zoom}>
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© <a href='https://osm.org/copyright'>OpenStreetMap</a> contributors" />
<Marker position={this.state.currentLocation} draggable={true} onDragend={this.updatePosition}>
<Popup>{"Latitud: "+this.state.currentLocation.lat}<br /> {"Longitud: "+this.state.currentLocation.lng}</Popup>
</Marker>
</MapContainer>
);
}
}
export default Mapa;
However nothing happened after dragging the Marker, i've tried to change the name of the event, but none is shown on console. Everything else is working fine. Any ideas?

Related

My embeded google map is not displaying in my ReactJS

I am building in ReactJs my intent is to embed a map for directions to a business.
I have zero errors in the console, but yet still no display of the map? I read to change 100% on height and width to 1000px tried that and it did not work.
import React, { Component, useEffect } from 'react'
import { Maps, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';
const mapStyles = {
width: '100%',
height: '100%'
};
export class Googlemap extends Component {
render() {
return (
<Maps
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={
{
lat: 42.338131411433736,
lng: -83.3935704444211
}
}
/>
);
}
}
export default GoogleApiWrapper({
apiKey: 'AIzaSyAxGE47DeXkR5rBP_wnJ_FS815zcWNwFRE'
})(Googlemap);

Is this the correct usage of React Components?

I am new to React. I want to share my components files with you. The code is syntactically correct and executes just fine. I just want to know, if its logically correct and the correct use of concepts such as states.
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function.
What other ways can I improve the code.
// Map.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import GoogleMapReact from 'google-map-react';
function Map(props) {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "123mykey" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
Map.defaultProps = {
center: {
lat: 59.95,
lng: 30.33
},
zoom: 11
};
export default Map
// MapContainer.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import Map from './Map'
class MapContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
center: {
lat: 0, lng: 0
}
}
this.getLocation = this.getLocation.bind(this);
this.showPosition = this.showPosition.bind(this);
}
getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.showPosition);
} else {
console.log("Geolocation is not supported by this browser.");
}
}
showPosition(position) {
this.setState({
center: {
lat: position.coords.latitude,
lng: position.coords.longitude
}
});
}
componentDidMount() {
this.getLocation();
}
render() {
return (
<div className="row">
<div className="col-md-9">
<Map center={this.state.center} />
</div>
<div className="col-md-3 d-sm-none d-md-block d-none d-sm-block">
<h1>Menu</h1>
</div>
</div>
);
}
}
export default MapContainer
Looks fine to me. You only need to import 'bootstrap/dist/css/bootstrap.css'; in your main index.js file.
Everything seems good, you are doing right
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function?
Yeah, Why not ?
What other ways can I improve the code.
there are some minor changes like:
1- you can import Component on top and the class definition would be smaller
2- it is a good practice to use arrow function component definition like this
export default (props) => {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "AIzaSyCV1fQD2VC6HoNbuuSPkE0q_QZvDf117PY" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
generally you are using react in right way, keep going
It looks fine at MapContainer (Example 2) but I propose separate your view based logics and the others. For example, the getLocation function is not based on your view (not depending React component or changing the view) so we can plug out this logic function into an independent function later the showPosition function is going to use that function.

How to add drawing toolbar in Leaflet map(React Application)

This is my Dashnoard.js file, i dont have an html file .My question is how to add the drawing toolbar on the leaflet map.At the moment i have the map only...
Thank you!
import React from 'react'
import { Map, Marker, Popup, TileLayer } from 'react-leaflet'
import { compose } from 'redux'
import "leaflet/dist/leaflet.css";
import L from 'leaflet';
export class Dashboard extends React.Component{
constructor() {
super();
this.state = {
lat: 42.696295,
lng: 23.303643,
zoom: 10,
};
}
render() {
const position = [this.state.lat, this.state.lng]
return(
<div className='dashboard container'>
<Map id="map" style={{ height: "50vh" }} center={position} zoom={13}>
<TileLayer
attribution='© OpenStreetMap contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
</div>
)
} }
export default compose()(Dashboard);
I have successfully initialize the map on the page,but at the next step i cannto initialize na drawing comonent and set to the map.

Pigeon Maps Marker Issue

I am trying to integrate a map in react specifically pigeon-maps since it is an open source.But,I am not able to get the co-ordinates from the map.Can anyone give me some code examples.I have set markers and overlay.I am able to center the map but have no idea how to get the latitude and longitude from the map.
Below is the code for the mapcomponent I am trying to create
import React, { Component } from "react";
import styles from "./mapcomponent.module.css";
import Marker from "pigeon-marker";
import Map from "pigeon-maps";
import Overlay from "pigeon-overlay";
class MapComponent extends Component {
constructor(props) {
super(props);
this.state = { lat: null, long: null };
}
componentWillMount() {
this.setState(
{
lat: Number(this.props.lat),
long: Number(this.props.long)
},
() => {
console.log("HERE", this.state.lat, this.state.long);
}
);
}
render() {
return (
<div className={styles.container} width="500px" height="500px">
<Map center={[this.state.lat, this.state.long]} zoom={12}>
<Marker anchor={[this.state.lat, this.state.long]} payload={1} />
<Overlay
anchor={[this.state.lat, this.state.long]}
offset={[120, 79]}
>
<img src="pigeon.jpg" width={240} height={158} alt="" />
</Overlay>
</Map>
</div>
);
}
}
export default MapComponent;
Can anyone help me to and extend marker and manipulate its value
We have to provide the latitude and longitude to plot the marker on map or you can get latitude and longitude from the map events (like onclick)

material-ui card with openlayers map inside?

I'm trying to place an openlayers map inside a material-ui card component. I've tried placing a div containing the map inside the card text and the card media sections.
Can anyone help me figure out the correct way to put a map inside the card?
import React, {PropTypes} from 'react'
import {connect} from 'react-redux'
import 'openlayers/dist/ol.css';
import ol from 'openlayers';
import {Card, CardActions, CardHeader, CardMedia} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
import Paper from 'material-ui/Paper'
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import '../components/tap_events'
import styles from '../styles/ExportInfo.css'
import {updateExportInfo} from '../actions/exportsActions.js';
class ExportInfo extends React.Component {
constructor(props) {
super(props)
getChildContext() {
return {muiTheme: getMuiTheme(baseTheme)};
}
componentDidMount() {
this._initializeOpenLayers()
}
_initializeOpenLayers() {
const scaleStyle = {
background: 'white',
};
this._map = new ol.Map({
controls: [
new ol.control.ScaleLine(),
new ol.control.Attribution({
collapsible: false,
collapsed: false,
}),
new ol.control.Zoom({
className: styles.olZoom
})
],
interactions: ol.interaction.defaults({
keyboard: false,
altShiftDragRotate: false,
pinchRotate: false
}),
layers: [
// Order matters here
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'infoMap',
view: new ol.View({
projection: "EPSG:3857",
center: [110, 0],
zoom: 2.5,
minZoom: 2.5,
maxZoom: 22,
})
});
}
render() {
const providers = this.props.providers;
console.log("this is it"+providers[0])
return (
<div className={styles.wholeDiv}>
<div className={styles.root}>
<Paper className={styles.paper} zDepth={2} rounded>
<div className={styles.mapCard}>
<Card >
<CardHeader
title="Selected Area of Interest"
actAsExpander={true}
showExpandableButton={true}
/>
<CardMedia expandable={true}>
<div id="infoMap" className={styles.map} ref="olmap">
</div>
</CardMedia>
</Card>
</div>
</Paper>
</div>
</div>
)
}
}
ExportInfo.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
}
export default (ExportInfo)
The id of your div (summaryMap) doesn't match target field in olmap configuration ('infoMap') both of them should be the same.
Additionally instead of calling _initializeOpenLayers in componentDidMount. I would recommend using ref callback and initialize target with actual control instead of string.
<div id="summaryMap" className={styles.map} ref={olmapDiv => this. _initializeOpenLayers(olmapDiv)}>
</div>

Resources