How to make all markers appear in the bounding rectangle
Closed this issue · 2 comments
Ynsinan commented
I don't want to manually enter a center coordinate and zoom ratio.What I want is for the screen to adjust the zoom ratio according to the markers. Automatically fit them all on the screen.
Thank you very much in advance
TrackingMap.tsx
import { useEffect, useRef, useState } from 'react';
//Third Party imports
import 'leaflet/dist/leaflet.css';
import { MapContainer, TileLayer } from 'react-leaflet';
import L from 'leaflet';
//Components imports
import Routing from './Routing';
//Utils import
import { MapWithPopupdatav2 } from './fakeData2';
import { eachPointforRouting } from 'types/Map';
import { getCenterMapCoordinates } from 'utils/getCenterMapCoordinates';
import { getBounds } from 'geolib';
import { useMap } from 'react-leaflet';
type centerMapProps = {
latitude: number;
longitude: number;
};
type DefaultMapWithPopupProps = {
// dataSource: RootMapWithPopupData;
height?: string;
width?: string;
};
const TrackingMap = ({ height }: DefaultMapWithPopupProps) => {
const bounds: any = [];
const mapRef = useRef();
const [markersDataSource, setMarkersDataSource] = useState(
MapWithPopupdatav2.data.map(item => item.gridData.data.map(item => item))
);
const [routeWayColor, setRouteWayColor] = useState<string[]>(
MapWithPopupdatav2.data.map(item => item.color)
);
const [dataForRouting, setDataForRouting] = useState<eachPointforRouting[][]>(
MapWithPopupdatav2.data.map(eachPoint =>
eachPoint.gridData.data.map(point =>
L.latLng(point.latitude, point.longitude)
)
)
);
const markersLatLon: centerMapProps[][] = MapWithPopupdatav2.data.map(
eachPoint =>
eachPoint.gridData.data.map(point => ({
latitude: point.latitude,
longitude: point.longitude,
}))
);
//We convert the structure that contains an array and an object in an array to an object in a single array
//Currently only used here. Function needs to be moved to utils if it needs to be used elsewhere
// - Yunus İNAN
function centerMapDataCalculate(data: centerMapProps[][]) {
let newArray: any = [];
data.forEach(item => {
item.map(point => {
newArray.push(point);
});
});
return newArray;
}
const markersCoordinatesForMapCentering =
centerMapDataCalculate(markersLatLon);
const centerValues: centerMapProps | any = getCenterMapCoordinates(
markersCoordinatesForMapCentering
);
return (
<MapContainer
center={[centerValues.latitude, centerValues.longitude]}
zoom={9}
scrollWheelZoom={true}
style={{ height: `${height}` }}
ref={mapRef}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{dataForRouting.map((eachPoint, index) => {
return (
<Routing
key={index}
eachPoint={eachPoint}
dataSource={markersDataSource[index]}
color={routeWayColor[index]}
bounds={bounds}
/>
);
})}
</MapContainer>
);
};
export default TrackingMap;
Routing.tsx
import { useEffect } from 'react';
//Third Party İmports
import L from 'leaflet';
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css';
import 'leaflet-routing-machine';
import { useMap } from 'react-leaflet';
//Components
//Utils import
import { RoutingPropsforTrackingMap } from 'types/Map';
L.Marker.prototype.options.icon = L.icon({
iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
});
const Routing = ({
eachPoint,
dataSource,
color,
bounds,
}: RoutingPropsforTrackingMap) => {
const map = useMap();
useEffect(() => {
if (!map) return;
const routingControl = L.Routing.control({
waypoints: eachPoint,
createMarker: function (
waypointIndex: any,
waypoint: any,
numberOfWaypoints: any
) {
return L.marker(waypoint.latLng).bindPopup(
`<p><b>Location Code:</b>${dataSource[waypointIndex].locationCode}</p>
<p><b>Location Type:</b>${dataSource[waypointIndex].locationType}</p>
<p><b>Visit Order:</b>${dataSource[waypointIndex].visitOrder}</p>
`
);
},
lineOptions: {
styles: [
{
color: color,
opacity: 1,
weight: 7,
},
],
},
addWaypoints: false,
draggableWaypoints: false,
fitSelectedRoutes: false,
showAlternatives: true,
}).addTo(map);
map.fitBounds(bounds.getBounds());
return () => map.removeControl(routingControl);
}, [map]);
return null;
};
export default Routing;
FakeData.ts
export const MapWithPopupdatav2 = {
data: [
{
id: 1,
vehicleCode: 'Vehicle39',
vehicleId: 39,
color: '#00ff00',
gridData: {
currentPage: 1,
firstRowOnPage: 1,
kind: 0,
lastRowOnPage: 15,
pageCount: 1,
pageSize: 10000,
totalRowCount: 15,
data: [
{
distanceMatrixId: 245046421,
duration: 618000,
endDate: '2019-09-24T11:44:39',
latitude: 13.74355389,
locationCode: 'S1R1037',
locationName: '',
locationType: 'RCM',
longitude: 100.5035463,
planDayId: 183,
planResultId: 116894,
serviceType: 'RCM Replenish',
startDate: '2019-09-24T11:34:21',
status: 'To Do',
vehicleCode: 'Vehicle39',
vehicleId: 39,
visitOrder: 1,
},
{
distanceMatrixId: 189364956,
duration: 1074000,
endDate: '2019-09-24T12:05:35',
latitude: 13.74364101,
locationCode: 'S1A2275',
locationName: '',
locationType: 'RCM',
longitude: 100.5014584,
planDayId: 183,
planResultId: 116906,
serviceType: 'Fix',
startDate: '2019-09-24T11:47:41',
status: 'To Do',
vehicleCode: 'Vehicle39',
vehicleId: 39,
visitOrder: 2,
},
{
distanceMatrixId: 189452735,
duration: 618000,
endDate: '2019-09-24T12:47:52',
latitude: 13.74557352,
locationCode: 'S1R2054',
locationName: '',
locationType: 'RCM',
longitude: 100.5000613,
planDayId: 183,
planResultId: 116891,
serviceType: 'RCM Replenish',
startDate: '2019-09-24T12:37:34',
status: 'To Do',
vehicleCode: 'Vehicle39',
vehicleId: 39,
visitOrder: 3,
},
],
},
},
{
id: 2,
vehicleCode: 'Vehicle24',
vehicleId: 24,
color: '#ff0000',
gridData: {
currentPage: 1,
firstRowOnPage: 1,
kind: 0,
lastRowOnPage: 6,
pageCount: 1,
pageSize: 10000,
totalRowCount: 6,
data: [
{
distanceMatrixId: 245857071,
duration: 696000,
endDate: '2019-09-24T12:13:45',
latitude: 14.11781576,
locationCode: '0405',
locationName: 'Branch48',
locationType: 'Branch',
longitude: 100.6180874,
planDayId: 183,
planResultId: 117530,
serviceType: 'Cash pickup & Delivery',
startDate: '2019-09-24T12:02:09',
status: 'To Do',
vehicleCode: 'Vehicle24',
vehicleId: 24,
visitOrder: 1,
},
{
distanceMatrixId: 276074744,
duration: 696000,
endDate: '2019-09-24T14:11:36',
latitude: 13.89500694,
locationCode: '0022',
locationName: 'Branch10',
locationType: 'Branch',
longitude: 100.6078357,
planDayId: 183,
planResultId: 117529,
serviceType: 'Cash pickup & Delivery',
startDate: '2019-09-24T14:00:00',
status: 'To Do',
vehicleCode: 'Vehicle24',
vehicleId: 24,
visitOrder: 2,
},
{
distanceMatrixId: 242141750,
duration: 696000,
endDate: '2019-09-24T16:11:36',
latitude: 13.98929965,
locationCode: '0610',
locationName: 'Branch70',
locationType: 'Branch',
longitude: 100.6185016,
planDayId: 183,
planResultId: 117528,
serviceType: 'Cash pickup & Delivery',
startDate: '2019-09-24T16:00:00',
status: 'To Do',
vehicleCode: 'Vehicle24',
vehicleId: 24,
visitOrder: 3,
},
],
},
},
{
id: 3,
vehicleCode: 'Vehicle36',
vehicleId: 24,
color: '#b200ff',
gridData: {
currentPage: 1,
firstRowOnPage: 1,
kind: 0,
lastRowOnPage: 28,
pageCount: 1,
pageSize: 10000,
totalRowCount: 28,
data: [
{
distanceMatrixId: 245046567,
duration: 1074000,
endDate: '2019-09-24T11:38:01',
latitude: 13.74467119,
locationCode: 'S1A4960',
locationName: '',
locationType: 'ATM',
longitude: 100.5839852,
planDayId: 183,
planResultId: 117282,
serviceType: 'Fix',
startDate: '2019-09-24T11:20:07',
status: 'To Do',
vehicleCode: 'Vehicle36',
vehicleId: 36,
visitOrder: 1,
},
{
distanceMatrixId: 189328693,
duration: 444000,
endDate: '2019-09-24T11:49:35',
latitude: 13.74646852,
locationCode: 'S1A7396',
locationName: '',
locationType: 'ATM',
longitude: 100.5736933,
planDayId: 183,
planResultId: 117281,
serviceType: 'ATM Replenish',
startDate: '2019-09-24T11:42:11',
status: 'To Do',
vehicleCode: 'Vehicle36',
vehicleId: 36,
visitOrder: 2,
},
{
distanceMatrixId: 191205228,
duration: 1074000,
endDate: '2019-09-24T12:14:55',
latitude: 13.7470292,
locationCode: 'S1A9243',
locationName: '',
locationType: 'RCM',
longitude: 100.5794979,
planDayId: 183,
planResultId: 117280,
serviceType: 'Fix',
startDate: '2019-09-24T11:57:01',
status: 'To Do',
vehicleCode: 'Vehicle36',
vehicleId: 36,
visitOrder: 3,
},
],
},
},
{
id: 4,
vehicleCode: 'Vehicle30',
vehicleId: 30,
color: '#209ff3',
gridData: {
currentPage: 1,
firstRowOnPage: 1,
kind: 0,
lastRowOnPage: 23,
pageCount: 1,
pageSize: 10000,
totalRowCount: 23,
data: [
{
distanceMatrixId: 271855562,
duration: 618000,
endDate: '2019-09-24T12:46:37',
latitude: 14.0661598,
locationCode: 'S1R2206',
locationName: '',
locationType: 'RCM',
longitude: 100.6293817,
planDayId: 183,
planResultId: 117165,
serviceType: 'RCM Replenish',
startDate: '2019-09-24T12:36:19',
status: 'To Do',
vehicleCode: 'Vehicle30',
vehicleId: 30,
visitOrder: 1,
},
{
distanceMatrixId: 245814193,
duration: 1074000,
endDate: '2019-09-24T11:18:01',
latitude: 14.10503655,
locationCode: 'S1C2293',
locationName: '',
locationType: 'ATM',
longitude: 100.6886859,
planDayId: 183,
planResultId: 117170,
serviceType: 'Fix',
startDate: '2019-09-24T11:00:07',
status: 'To Do',
vehicleCode: 'Vehicle30',
vehicleId: 30,
visitOrder: 2,
},
{
distanceMatrixId: 273658538,
duration: 444000,
endDate: '2019-09-24T11:32:59',
latitude: 14.0756659,
locationCode: 'S1C1902',
locationName: '',
locationType: 'ATM',
longitude: 100.6875185,
planDayId: 183,
planResultId: 117169,
serviceType: 'ATM Replenish',
startDate: '2019-09-24T11:25:35',
status: 'To Do',
vehicleCode: 'Vehicle30',
vehicleId: 30,
visitOrder: 3,
},
{
distanceMatrixId: 272746632,
duration: 618000,
endDate: '2019-09-24T11:47:01',
latitude: 14.06629306,
locationCode: 'S1R2650',
locationName: '',
locationType: 'RCM',
longitude: 100.684938,
planDayId: 183,
planResultId: 117168,
serviceType: 'RCM Replenish',
startDate: '2019-09-24T11:36:43',
status: 'To Do',
vehicleCode: 'Vehicle30',
vehicleId: 30,
visitOrder: 4,
},
],
},
},
],
};
// export interface Datum2 {
// distanceMatrixId: number;
// duration: number;
// endDate: Date;
// latitude: number;
// locationCode: string;
// locationName: string;
// locationType: string;
// longitude: number;
// planDayId: number;
// planResultId: number;
// serviceType: string;
// startDate: string;
// status: string;
// vehicleCode: string;
// vehicleId: number;
// visitOrder: number;
// }
// export interface GridData {
// currentPage: number;
// firstRowOnPage: number;
// kind: number;
// lastRowOnPage: number;
// pageCount: number;
// pageSize: number;
// totalRowCount: number;
// data: Datum2[];
// }
// export interface Datum {
// id: number;
// vehicleCode: string;
// vehicleId: number;
// color: string;
// gridData: GridData;
// }
// export interface RootObject {
// data: Datum[];
// }
Ynsinan commented
I solved the problem
TrackingMap.tsx Changes
{dataForRouting.map((eachPoint, index) => {
return (
<Routing
key={index}
eachPoint={eachPoint}
dataSource={markersDataSource[index]}
color={routeWayColor[index]}
bounds={markersCoordinatesForMapCentering}
/>
);
})}
Routing.tsx Changes
adding the addTo(map) under
if (bounds.length && bounds.length > 0) {
bounds.forEach(marker => {
markerBounds.extend([marker.latitude, marker.longitude]);
});
map.fitBounds(markerBounds);
}
curtisy1 commented
Glad to hear you solved it! I'll go ahead and close this issue for now