I'm doing something using Geolocation API and ReactJS, and I'm storing location as a state variable, since the component changes location as the web page moves around or as the user randomly changes location.
So the component looks like this:
var GeoComp = React.createClass({
setPosition: function(position){
var lat = position.coords.latitude;
var longitude = position.coords.longitude;
this.setState({longitude: {longitude}, latitude: {lat}});
this.setState({statusText: 'Successfully found you at ' + this.state.longitude + ',' + this.state.latitude});
},
getInitialState: function(){
return {longitude: 0, latitude: 0, placeName: '', statusText: 'Locating you....'};
},
componentDidMount: function(){
if (!navigator.geolocation){
this.setState({statusText: 'Your browser does not support geolocation...'});
}
else{
navigator.geolocation.getCurrentPosition(this.setPosition, this.errorPosition);
}
}
......
But the problem I'm running into is extracting the double from longitude and latitude variables. React stores them as objects. How can I actually store the doubles and pass them to child components?
I'm sorry -- the problem was poor syntax when setting up initialState:
this.setState({longitude: longitude, latitude: lat});
as opposed to
this.setState({longitude: {longitude}, latitude: {lat}});
It's a n00b mistake about how React syntax works :-/
Related
I am trying make a multi colored polyline. I have been able to do it successfully before with Vue.js but now we are adding it to react native app and its not working as i expected in React js.
I am making multiple polylines, each line (segment) has multiple points. I have a structure like this:
groups: [ { key: 'BLUE', cordinates: [] }, key: 'GREEN', cordinates: [] ];
Now each key represent a color and cordinates is an array of cordinates. Now when I loop it like this:
{
this.state.groups.map((group, index) => {
return (
<Polyline
key={index}
coordinates={group.Points}
strokeColor={
group.Key === "GREEN" ? "#0F0" : "#000"
// "#000"
// group.Key === "G"
} // fallback for when `strokeColors` is not supported by the map-provider
strokeColors={[
'#7F0000',
'#00000000', // no color, creates a "long" gradient between the previous and next coordinate
'#B24112',
'#E5845C',
'#238C23',
'#7F0000'
]}
strokeWidth={6}
/>
);
})
}
The problem is it works! perfectly but it doesnt draw the last polyline which is being updated. So for example there are 10 segments in this polyline. Now after 3 are drawn and loop is on 4th segment, its pushing each cordinate in the last group with a delay of 30 ms. I added delay to show it animated. Now it won't draw on map untill all cordinates of the 4th segments are pushed. When its done, and 5th segment is started, 4th segment shows perfectly but now 5th segment stops working.
I know that points are being perfectly added because I have added a Camera as well and I change its center to be last point that was pushed in groups/segments.
Group/Segments loop:
addPoint(group, point) {
var data = this.state.data;
if (group <= (data.length - 1)) {
var g = data[group];
// console.log('g', g);
if (point <= (g.Item2.length - 1)) {
var p = g.Item2[point];
var {groups} = this.state;
// console.log('groups,', groups);
groups[group].Points = groups[group].Points.concat({
longitude: p.longitude,
latitude: p.latitude,
});
this.MapView.animateCamera({
center: {
latitude: p.latitude,
longitude: p.longitude,
},
duration: 100,
zoom: 15,
});
point++;
setTimeout(() => {
this.addPoint(group, point);
}, 300);
} else {
point = 0;
group++;
if (group < this.state.data.length - 1) {
var key = this.state.data[group].Item1;
console.log('key', key);
var groups = this.state.groups.concat({
Key: key,
Points: [],
});
this.setState({
groups: groups,
})
}
setTimeout(() => {
this.addPoint(group, point);
}, 300);
}
} else {
console.log('last group reached');
}
}
Is there any solution for this?
I figured it out. The problem was whenever I updated the coordinates array of any polyline, it had to re-render whole thing which was performance wise very poor decision.
I solved it by making a custom polyline component which maintains its own coordinates array. Implemented an inner timeout function which pushes coordinates incrementally. This solved the problem and its now super easy to use.
You can read more about this here: multi colored gradient polyline using google maps on react native
I am making an react native android application in which i am using google maps.I am also using markers in now google maps.Now the data in markers array are added during runtime.The format for markers array is like this.
markers: [{
title: 'hello',
coordinates: {
latitude: 3.148561,
longitude: 101.652778
},
},
{
title: 'hello',
coordinates: {
latitude: 3.149771,
longitude: 101.655449
},
}]
But since i am adding data during run time .I have put marker : [] in state .
After fetching latitude and longitude of every location in markers array like this.
var lat = _location.lat
var long = _location.lng
const array = [...this.state.markers_two];
array[i] = { ...array[i], title:location};
array[i] = { ...array[i], coordinates: {latitude:lat,longitude:long}};
this.setState({ markers_two: array });
But above does not works.I also tried like this.
var arr = this.state.markers_two
arr.push({title:location,coordinates:{latitude:lat,longitude:long}})
this.setState({ markers_two: arr });
But this also does not works.So what i am doing wrong?How can i add all the recieved location data in markers array?
Delete this question please, someone has helped me on another thread.
I am trying to generate markers at certain times in my app so that it will show a blank map at launch, but then sometime later, markers can show up and disappear at certain times.
My state variables are set up like this:
class Map extends Component {
state = {
markers: [{
key: null,
contactName: null,
location: null,
}]
}
The code I am trying to generate the markers with is as follows:
renderMarker = ({ key, contactName, location }) => {
console.log('renderMarker: ' + key + ', ' + contactName + ', ' + location);
return this.state.markers.map(Marker => (
<MapView.Marker
key = { key }
coordinate = {{
latitude: location[0],
longitude: location[1]
}}
//image = { carIcon }
title = { contactName } />
))
}
The console.log in there is generating the correct data, so it is returning for example:
renderMarker: 389djhJHDjdkh392sdk, Steve, -30.498767387,120.4398732
My render function looks like this:
render() {
return (
<MapContainer>
<MapView
style = { styles.map }
region = { this.state.mapRegion }
showsUserLocation = { true }
followUserLocation = { true }
onRegionChangeComplete = { this.onRegionChangeComplete.bind(this) }>
</MapView>
</MapContainer>
)
}
But nothing shows up on the map. I have been scouring the interwebs but I can't find a followable example. Do I need to add something to my render() function to make this work? My thoughts were I won't need to because renderMarker is doing that work.
Any ideas guys?
I need to update the state with immutability helper update function but I cannot do it properly. Please help me do it.
Besides you can tell me how to make it without update function. It is all okay.
My initial state object is
state = {
markers: [
{
key: 1,
latlng: {
latitude: 40.3565,
longitude: 27.9774
}
}
]
And my jsonResponse is:
[{"latlng":{"latitude":"40.3565","longitude":"27.9774"}},{"latlng":{"latitude":"40.3471","longitude":"27.9598"}},{"latlng":{"latitude":"40","longitude":"27.9708"}}]
Now I want to add all data from responseJson to state with ummutable helper update function or without it how can I do it.
First, edit your respone:
let response = [{"latlng":{"latitude":"40.3565","longitude":"27.9774"}},{"latlng":{"latitude":"40.3471","longitude":"27.9598"}},{"latlng":{"latitude":"40","longitude":"27.9708"}}]
response = response.reduce((prev,curr,index)=>{
curr.key = index;
prev.concat(curr)
},[]);
Secondly, create your initial state on your reducer like this:
state = Map({
markers: List()
})
Finally, edit your reducer:
[FETCH_MARKERS_SUCCESS]: (state, action) => state.merge(action.payload, {loading: false}),
I'm trying to show all users geolocation from a web site in a map. Through google maps API documentation I've got a way to show my location as user. But, how I make it for show all geolocation from the registered people on the website?
<div id="map"></div>
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
var infoWindow = new google.maps.InfoWindow({map: map});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
}
</script>
Create objects of the google.maps.Marker() type, set a position using the setPosition function of it and add it to your map using the setMap function.
Example (Lat/Lng is the center of Germany - insert your users coordinates there):
var marker=new google.maps.Marker();
// use your registered user coordinates here
marker.setPosition(new google.maps.LatLng(48.14544, 8.19208));
marker.setMap(map);
Additionally you can use boundaries to make your map autozoom to get every marker visible:
var bounds=new google.maps.LatLngBounds();
...
bounds.extend(marker.getPosition());
...
map.fitBounds(bounds);