Pigeon Maps Marker Issue - reactjs

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)

Related

Google Map React component loses data when placed into divs

I have a working GoogleMapReact component that takes latitude and longitude, and places markers on the map. The problem I face is I need to style the Marker component and when I place it into DIV or any other html element, all markes lose their coordinates and are just in vertical row on the map.
Here is the code:
import React, { useState } from "react";
import GoogleMapReact from "google-map-react";
import getCenter from "geolib/es/getCenter";
import Marker from "../components/Marker";
function MapMe1({ searchResults }) {
//transform the search results object into {latitude,longitude} format
const coordinates = searchResults.map((result) => ({
longitude: result.long,
latitude: result.lat,
}));
const center = getCenter(coordinates);
const [viewport, setViewport] = useState({
width: "600px",
height: "max-height: 75%",
center: { lat: center.latitude, lng: center.longitude },
zoom: 11,
});
return (
<GoogleMapReact
//mapContainerStyle={containerStyle}
bootstrapURLKeys={{ key: process.env.google_maps_key }}
{...viewport}
onViewportChange={(nextViewport) => setViewport(nextViewport)}
>
{searchResults.map((result) => (
// It works, but if I wrap this in <div> lat and lng no longer available...
<Marker
lat={result.lat}
lng={result.long}
offsetLeft={-20}
offsetTop={-10}
titles={result.title}
/>
))}
</GoogleMapReact>
);
}
export default MapMe1;
I want to style the marker to show a tooltip but for some reason is the Marker component loses all data. Why is this happening?

Dragging event not working on React leaflet

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?

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 pass the data from one Component to another component

I have created two components. one is for the map and other one is for some inputs. I have two inputs to get the latitude and longitude. I am passing the longitude and latitude which i got from the user, to my other component using longitude= {this.state.longitude} latitude = {this.state.latitude}. If user haven't input the longitude and latitude or user clear the input it should show these coordinates lat: 22.5726, lng: 88.3639. how can i do it ? so far this is what i have done. when i pass the coordinates it doesn't show the place.what have i done wrong? And also i want to know how i can show the default coordinates when user clear the input? when i console.log this.props.latitude i get following error TypeError: Cannot read property 'latitude' of undefined. I think My data is not passing Properly to my map Component !if anyone knows how to fix this please tell!
this is my file structure.
MainFolder
|
|__ navigation.js
|
|__ right folder
| |
| |__form.js(this is where i have two inputs)
| |
| |__ MapContainerFolder
| |
| |__MapContainer.js
|
|
|__ left folder
|
|__left.js
In my Form component i have below code
<MapContainer
longitude= {this.state.longitude}
latitude = {this.state.latitude}
/>
in my navigation.js i have this
<form/>
<left/>
this is my mapContainer.js
import React, { Component } from "react";
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
export class MapContainer extends Component {
render() {
const style = {
width: '24%',
height: '65%'
}
return (
<Map
style={style}
google={this.props.google}
zoom={14}
initialCenter={{
lat: 22.5726,
lng: 88.3639
}}
center={{
lat:this.props.longitude,
lng:this.props.latitude
}}
>
<Marker onClick={this.onMarkerClick}
name={'Current location'} />
<InfoWindow onClose={this.onInfoWindowClose}>
<div>
</div>
</InfoWindow>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: ("my api key")
})(MapContainer)
In your MapcContainer class, you need to define your initail state based on the props you pass to this component from outside and set a default for them. Since I don't have a Google API key, I'm going to demonstrate your example in Leaflet, but I'm sure you'll get the idea.
const { Map: LeafletMap, TileLayer, Marker, Popup } = window.ReactLeaflet
class App extends React.Component {
constructor(props) {
super(props);
const lat = this.props.latitude || 51.505;
const lng = this.props.longitude || -0.091;
this.state = {
center: [lat,lng],
zoom: 13
};
}
render() {
return (
<div>
<LeafletMap center={this.state.center} zoom={this.state.zoom}>
<TileLayer
attribution='&copy OpenStreetMap contributors'
url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<Marker position={this.state.center}>
<Popup>Hello World!
</Popup>
</Marker>
</Map>
</div>
);
}
}
const rootElement = document.getElementById("root");
const Wrapper = () => <App latitude={51.505} longitude={-0.091} />;
ReactDOM.render(<Wrapper />, rootElement);

react-leaflet get current latlng onClick

I would be realy happy if some one could help me...
I've installed react-leaflet on my react project and the map component is loaded successfully, i need to get current latlng and show it in the Popup when i click on map but I don't know how to :(
please... please... help me...
this is my code
import React from 'react'
import { Map as LeafletMap, TileLayer, Marker, Popup } from 'react-leaflet';
class Mapp extends React.Component {
componentDidMount() {
}
render() {
return (
<LeafletMap
center={[35.755229,51.304470]}
zoom={16}
maxZoom={20}
attributionControl={true}
zoomControl={true}
doubleClickZoom={true}
scrollWheelZoom={true}
dragging={true}
animate={true}
easeLinearity={0.35}
>
<TileLayer
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
<Marker position={[35.755229,51.304470]}
draggable={true}
>
<Popup >
Popup for any custom information.
</Popup>
</Marker>
</LeafletMap>
);
}
}
export default Mapp;
Here is an example on how to display maker position in popup once map is clicked:
class MapExample extends Component {
constructor(props) {
super(props);
this.state = {
currentPos: null
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
this.setState({ currentPos: e.latlng });
}
render() {
return (
<div>
<Map center={this.props.center} zoom={this.props.zoom} onClick={this.handleClick}>
<TileLayer
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{ this.state.currentPos && <Marker position={this.state.currentPos} draggable={true}>
<Popup position={this.state.currentPos}>
Current location: <pre>{JSON.stringify(this.state.currentPos, null, 2)}</pre>
</Popup>
</Marker>}
</Map>
</div>
)
}
}
Explanation:
currentPos state is used to keep marker position
event.latLng property of Map.onClick event handler returns mouse event location
Here is a demo for your reference
What did you try to achieve that?
This will be the start:
Use the click (see https://leafletjs.com/reference-1.4.0.html#map-click) event from the LeafletMap component and call your function, like:
<LeafletMap
center={[35.755229,51.304470]}
zoom={16}
maxZoom={20}
attributionControl={true}
zoomControl={true}
doubleClickZoom={true}
scrollWheelZoom={true}
dragging={true}
animate={true}
easeLinearity={0.35}
onclick={this.handleClick}>
>
...
</LeafletMap>
In your handleClick function you get the information of lat and lng like this:
handleClick = (e) => {
const { lat, lng } = e.latlng;
console.log(lat, lng);
}
From here on, you can create your marker / popup with the information you were looking for.
Additional hint: Please make sure your code is wrapped in correctly in your post..
If you work with react-leaflet version 3.x this does not work. In this case, use the useMapEvents hook in a dummy component that you add to the map. For example, if you want to console.log the clicked position:
const LocationFinderDummy = () => {
const map = useMapEvents({
click(e) {
console.log(e.latlng);
},
});
return null;
};
Then use the LocationFinderDummy in the map as follows:
<MapContainer
center={[0, 0]}
zoom={6}>
<LocationFinderDummy />
</MapContainer>

Resources