I am using google-map-react to render a google map, for a path, using GPS positions. At the moment, I am rendering a path in a single colour.
I would like to change the colour of the line, based on speed. Is there a way to update the colour of the path samples, based on some criteria?
At the moment, I only see how to set the colour for the whole path:
var flightPath = new maps.Polyline(
{
path: path,
geodesic: true,
strokeColor: "#FF0033",
strokeOpacity: 2,
strokeWeight: 4
});
flightPath.setMap(map);
With path being specified as:
const path = places ? places.map((event) => {
return {
lat: event.position.lat,
lng: event.position.lng
}
}) : [];
Is it possible to set each event in the path's colour?
Related
I am having an array of polygon coordinates which are being mapped and displayed on the map.
Secondly, I have a mouseenter and mouseout event which takes in the particular lat and lng coordinate of a particular polygon and zooms over them to focus on them.
Now what I want to achieve is that, anytime I mouse over any polygon from the list on the table, I want the strokeColor of that particular polygon to change. My current logic only changes the strokeColor of every polygon, which is not what I want.
My code is explained below:
This is the mouse-enter function
const handleRowHover = (event, props) => {
console.log("event", event);
console.log("props", props);
setCenter({
lat: props?.data?.geoData?.point?.coordinates?.[1],
lng: props?.data?.geoData?.point?.coordinates?.[0],
});
setZoomLevel(18);
setMapColor("red");
};
This is the mapped list of polygons from an API endpoint
{allFarmsPolygons.map((poly) => (
<Polygon paths={poly} options={options} />
))}
This is the react google maps api options
const options = {
fillColor: "rgb(128,128,128, 0.5)",
fillOpacity: 1,
strokeColor: center ? mapColor : "#066344",
strokeOpacity: 10,
strokeWeight: 2,
clickable: true,
draggable: false,
editable: false,
geodesic: false,
zIndex: 2,
};
Please any help or hint would be much appreciated. If additional info is needed, I can provide them.
I have tried putting the strokeColor into state, but it just applies to every polygon on the iteration. I want it to apply to only the particular polygon being mouse entered. I am using material-table to display the names of each polygon by the way.
I am currently trying to change the color of the default marker on the map. The library that is being used is #react-google-maps/api.
This is the load handler for the markers:
const markerLoadHandler = (marker, mPos) => {
return { [mPos.index]: marker }
}
I am mapping markers to the map.
{roadParamData.map((mPos) => {
const RightNorth = parseFloat(mPos.RightRutLat)
const RightEast = parseFloat(mPos.RightRutLon)
return (
<MarkerF
onLoad={(marker) => markerLoadHandler(marker, mPos)}
key={mPos.index}
position={{ lat: RightNorth, lng: RightEast }}
label={{text: mPos.RightRut, color: colors.white}}
//icon={{fillColor: colors.blue_02}}
icon={{
//path: window.google.maps.SymbolPath.CIRCLE,
path: "M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z",
fillColor: colors.blue_02,
fillOpacity: 1.0,
strokeWeight: 0,
scale: 1.0
}}
/>
)
})}
When I'm using the default icon label text is correctly aligned.
But when I use the custom marker the labels get misaligned but I can change the color of the marker without problems.
Should I try using customer marker? If so how can I make sure labels are aligned correctly if default marker color can't be changed.
I am trying to adapt the example Display HTML clusters with custom properties for react-map-gl.
I got basic clusters without custom styling working (adapted from Create and style clusters):
<ReactMapGL ref={mapRef}>
<Source id="poi-modal-geojson" type="geojson" data={pointsToGeoJSONFeatureCollection(points)}
cluster={true}
clusterMaxZoom={14}
clusterRadius={50}
>
<Layer {...{
id: 'clusters',
type: 'circle',
source: 'poi-modal-geojson',
filter: ['has', 'point_count'],
paint: {
'circle-color': [
'step',
['get', 'point_count'],
'#51bbd6',
100,
'#f1f075',
750,
'#f28cb1'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
}} />
<Layer {...{
id: 'unclustered-point',
type: 'circle',
source: 'poi-modal-geojson',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#11b4da',
'circle-radius': 4,
'circle-stroke-width': 1,
'circle-stroke-color': '#fff'
}
}} />
</Source>
</ReactMapGL>
Here, pointsToGeoJSONFeatureCollection(points: any[]): GeoJSON.FeatureCollection<GeoJSON.Geometry> is a function returning a GeoJSON (adapted from here).
However, I need more complex styling of markers and I am trying to adapt Display HTML clusters with custom properties without success so far. I mainly tried to adapt updateMarkers() and to call it inside useEffect():
const mapRef: React.Ref<MapRef> = React.createRef();
const markers: any = {};
let markersOnScreen: any = {};
useEffect(() => {
const map = mapRef.current.getMap();
function updateMarkers() {
const newMarkers: any = {};
const features = map.querySourceFeatures('poi-modal-geojson');
// for every cluster on the screen, create an HTML marker for it (if we didn't yet),
// and add it to the map if it's not there already
for (const feature of features) {
const coords = feature.geometry.coordinates;
const props = feature.properties;
if (!props.cluster) continue;
const id = props.cluster_id;
let marker = markers[id];
if (!marker) {
let markerProps = {
key: 'marker' + id,
longitude: coords[0],
latitude: coords[1],
className: 'mapboxgl-marker-start'
}
const el = React.createElement(Marker, markerProps, null),
marker = markers[id] = el;
}
newMarkers[id] = marker;
if (!markersOnScreen[id]) {
// TODO re-add
// marker.addTo(map);
}
}
// for every marker we've added previously, remove those that are no longer visible
for (const id in markersOnScreen) {
if (!newMarkers[id]) delete markersOnScreen[id];
}
markersOnScreen = newMarkers;
}
// after the GeoJSON data is loaded, update markers on the screen on every frame
map.on('render', () => {
if (!map.isSourceLoaded('poi-modal-geojson')) return;
updateMarkers();
});
}, [points]);
Unfortunately, the Marker created using React.createElement() isn't displayed I am not sure what is the right approach to create Marker elements in updateMarkers() or if my approach is completely wrong.
There is a great article on marker clustering which uses the supercluster and use-supercluster libraries and it makes clustering really easy not only for map box but for other map libraries as well, you can find it here.
You just have to convert your points into GeoJSON Feature objects in order to pass them to the useSupercluster hook and for the calculations to work. It will return an array of points and clusters depending on your current viewport, and you can map through it and display the elements accordingly based on the element.properties.cluster flag.
The properties property of the GeoJSON Feature object can be custom so you can pass whatever you need to display the markers later on when you get the final cluster array.
I am using Leaflet in a cross-platform mobile app.
I want the user to see his/her movement on the map in real time.
I also want to hold their longitude and latitude separately as global variables for I need this information to make a calculation later on.
Below is what I have so far:
map.locate({
watchPosition:true,
maxZoom:16
});
function onLocationFound(e)
{
var radius = e.accuracy / 2;
L.circle(e.latlng, radius,
{
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 400
}).addTo(map);
}
map.on('locationfound', onLocationFound);
I believe the "watchPosition:true" enables the map to keep on watching the user.
I just could not figure out how to extract the longitude and latitude information .
Thanks in advance
The Leaflet map.locate option is just watch:
If true, starts continuous watching of location changes (instead of detecting it once) using W3C watchPosition method.
function onLocationFound(e)
{
var radius = e.accuracy / 2;
userLat = e.latlng.lat;
userLng = e.latlng.lng;
movingCircle.setLatLng(e.latlng);
movingCircle.redraw();
}
var userLocation = map.locate
({
watch:true,
maxZoom:16,
enableHighAccuracy: true
});
var userLat;
var userLng;
enter code here
var movingCircle = L.circle([0,0], 20,
{color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
draggable: true }).addTo(map);
I am currently working on a project that has to display geojson data on a map.
I am using the leaflet-directive for AngularJS and it works fine.
My map is correctly displayed with the geojson data.
ANGULAR CONTROLLER
angular.extend($scope, {
intersection: {
lat: 50.891,
lng: 4.258,
zoom: 14
},
defaults: {
scrollWheelZoom: false
},
geojson : {},
layers: {
baselayers: {
xyz: {
name: 'OpenStreetMap (XYZ)',
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
type: 'xyz'
}
},
overlays: {}
}
});
$scope.$watch("intersection.zoom", function(zoom) {
if(zoom > 17){
$scope.layers.overlays = {
wms: {
name: 'intersectionDraw',
type: 'wms',
visible: true,
url: 'img/map.png'
}
}
};
});
Now I would like to add a feature. I would like to display a png drawing when my zoom reaches the max zoom.For the moment, my code is displaying the png in mosaic. I want this png to get the full height and width of my map and see only this. There is no need to zoom more on this png but if I zoom out the "normal" map will be shown again
The mosaic PNG
Use a L.ImageOverlay. See Leaflet single picture and https://github.com/Leaflet/Leaflet/blob/master/debug/map/image-overlay.html